diff --git a/src/modules/blocks/code/code-renderers/RenderCodeChartJS.tsx b/src/modules/blocks/code/code-renderers/RenderCodeChartJS.tsx index de2fa20da..2a48251d6 100644 --- a/src/modules/blocks/code/code-renderers/RenderCodeChartJS.tsx +++ b/src/modules/blocks/code/code-renderers/RenderCodeChartJS.tsx @@ -54,6 +54,26 @@ export const RenderCodeChartJS = React.forwardRef(function RenderCodeChartJS(pro try { const config = JSON.parse(props.chartJSCode) as ChartConfiguration; chartJSFixupGeneratedObject(config); + + // Include zoom plugin options + config.options = config.options || {}; + config.options.plugins = config.options.plugins || []; + config.options.plugins.zoom = { + pan: { + enabled: true, + mode: 'xy', + }, + zoom: { + wheel: { + enabled: false, + }, + pinch: { + enabled: true, + }, + mode: 'xy', + }, + }; + return { chartConfig: config, parseError: null }; } catch (error: any) { return { chartConfig: null, parseError: error.message as string || 'Unknown error.' }; @@ -107,8 +127,7 @@ export const RenderCodeChartJS = React.forwardRef(function RenderCodeChartJS(pro // Omit the background layer if (withBackground) { - // ctx.fillStyle = isDarkMode ? '#171A1C' : '#F0F4F8'; - ctx.fillStyle = isDarkMode ? '#000' : '#FFF'; + ctx.fillStyle = isDarkMode ? '#171A1C' : '#F0F4F8'; ctx.fillRect(0, 0, pngCanvas.width, pngCanvas.height); } diff --git a/src/modules/blocks/code/code-renderers/useDynamicChartJS.ts b/src/modules/blocks/code/code-renderers/useDynamicChartJS.ts index 5153f9022..c41e49fb8 100644 --- a/src/modules/blocks/code/code-renderers/useDynamicChartJS.ts +++ b/src/modules/blocks/code/code-renderers/useDynamicChartJS.ts @@ -16,11 +16,16 @@ const CHARTJS_VERSION = '4.4.4'; const CHARTJS_CDN_URL = `https://cdn.jsdelivr.net/npm/chart.js@${CHARTJS_VERSION}/dist/chart.umd.js`; const CHARTJS_SCRIPT_ID = 'chartjs-cdn'; +// Add constants for the Zoom plugin +const CHARTJS_ZOOM_PLUGIN_VERSION = '2.0.1'; +const CHARTJS_ZOOM_PLUGIN_CDN_URL = `https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom@${CHARTJS_ZOOM_PLUGIN_VERSION}/dist/chartjs-plugin-zoom.min.js`; + // Minimal type definitions for Chart.js - as of 4.4.4 interface ChartConstructorType { defaults: ChartDefaults; + register: (plugin: any) => void; new(context: CanvasRenderingContext2D | HTMLCanvasElement, config: ChartConfiguration): ChartInstanceType; } @@ -42,7 +47,25 @@ interface ChartDefaults { export interface ChartConfiguration { type?: string; data?: any; - options?: ChartDefaults; + options?: ChartDefaults & { + plugins?: { + zoom?: { + pan?: { + enabled: boolean; + mode: string; + }; + zoom?: { + wheel?: { + enabled: boolean; + }; + pinch?: { + enabled: boolean; + }; + mode?: string; + }; + }; + }; + }; // [key: string]: any; } @@ -76,6 +99,13 @@ function _chartJSInitializeDeaults(Chart: ChartConstructorType): ChartConstructo // Change the default padding for the title Chart.defaults.plugins.title.padding = { top: 8, bottom: 16 }; + // Register the Zoom plugin + if ((window as any).ChartZoom) { + Chart.register((window as any).ChartZoom); + } else { + console.warn('[ChartJS] Zoom plugin is not available to register.'); + } + return Chart; } @@ -123,8 +153,14 @@ function loadCDNScript(): Promise { script.async = true; script.onload = () => { - if ((window as any).Chart) resolve(_chartJSInitializeDeaults((window as any).Chart)); - else reject(new Error('Chart.js failed to load.')); + // After Chart.js is loaded, load the Zoom plugin + loadChartJSZoomPlugin().then(() => { + if ((window as any).Chart) resolve(_chartJSInitializeDeaults((window as any).Chart)); + else reject(new Error('Chart.js failed to load.')); + }).catch((error) => { + console.error('[ChartJS] Zoom plugin failed to load:', error); + reject(new Error('Chart.js Zoom plugin failed to load.')); + }); }; script.onerror = () => { @@ -138,6 +174,31 @@ function loadCDNScript(): Promise { return chartJSPromise; } +function loadChartJSZoomPlugin(): Promise { + return new Promise((resolve, reject) => { + // Check if the plugin is already loaded + if ((window as any).ChartZoom) { + resolve(); + return; + } + + const script = document.createElement('script'); + script.src = CHARTJS_ZOOM_PLUGIN_CDN_URL; + script.async = true; + + script.onload = () => { + resolve(); + }; + + script.onerror = () => { + console.error('[ChartJS] Failed to load Chart.js Zoom plugin from CDN.'); + reject(new Error('Failed to load Chart.js Zoom plugin from CDN.')); + }; + + document.head.appendChild(script); + }); +} + // Store: we share the state across multiple useChartJS hooks interface ChartApiStore {