@@ -8,17 +8,23 @@ import {
88 ScaleChartOptions ,
99} from "chart.js" ;
1010import chartTrendline from "chartjs-plugin-trendline" ;
11- import { createEffect , JSXElement , onCleanup , onMount } from "solid-js" ;
11+ import { createDeferred , JSXElement , onCleanup , onMount } from "solid-js" ;
1212
1313import { Theme } from "../../constants/themes" ;
14+ import { createEffectOn } from "../../hooks/effects" ;
1415import { useRefWithUtils } from "../../hooks/useRefWithUtils" ;
1516import { getTheme } from "../../states/theme" ;
1617
18+ function getThemeHash ( ) : string {
19+ return Object . values ( getTheme ( ) ) . join ( "" ) ;
20+ }
21+
1722Chart . register ( chartTrendline ) ;
1823type ChartJSProps <
1924 T extends ChartType = ChartType ,
2025 TData = DefaultDataPoint < T > ,
2126> = {
27+ name : string ;
2228 type : T ;
2329 data : ChartData < T , TData > ;
2430 options ?: ChartOptions < T > ;
@@ -32,28 +38,44 @@ export function ChartJs<T extends ChartType, TData = DefaultDataPoint<T>>(
3238 const [ canvasRef , canvasEl ] = useRefWithUtils < HTMLCanvasElement > ( ) ;
3339
3440 let chart : Chart < T , TData > | undefined ;
41+ let theme = "" ;
3542
3643 onMount ( ( ) => {
3744 const canvas = canvasEl ( ) ;
3845 if ( canvas === undefined ) return ;
46+ if ( chart !== undefined ) return ;
47+
3948 chart = new Chart ( canvas . native , {
4049 type : props . type ,
4150 data : props . data ,
4251 options : addColorsToOptions ( props . options as ChartOptions < T > , getTheme ) ,
4352 } ) ;
44-
53+ theme = getThemeHash ( ) ;
4554 props . onChartInit ?.( chart ) ;
4655 } ) ;
4756
48- createEffect ( ( ) => {
57+ const updateChart = ( data : ChartData < T , TData > ) : void => {
4958 if ( ! chart ) return ;
5059
51- chart . config . type = props . type ;
52- chart . data = props . data ;
60+ chart . data = data ;
61+
5362 if ( props . options ) {
5463 chart . options = addColorsToOptions ( props . options , getTheme ) ;
5564 }
56- chart . update ( ) ;
65+
66+ chart . update ( "none" ) ;
67+ } ;
68+
69+ const deferredData = createDeferred ( ( ) => props . data , { timeoutMs : 500 } ) ;
70+
71+ createEffectOn ( deferredData , ( data ) => updateChart ( data ) ) ;
72+
73+ createEffectOn ( getTheme , ( ) => {
74+ if ( ! chart ) return ;
75+ const newTheme = getThemeHash ( ) ;
76+ if ( theme === newTheme ) return ;
77+ theme = newTheme ;
78+ updateChart ( deferredData ( ) ) ;
5779 } ) ;
5880
5981 onCleanup ( ( ) => {
0 commit comments