Skip to content

Commit 94b22a7

Browse files
committed
impr: enhance ChartJs component with theme handling and data updates
!nuf
1 parent a1efc6d commit 94b22a7

2 files changed

Lines changed: 29 additions & 6 deletions

File tree

frontend/src/ts/components/common/ChartJs.tsx

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,23 @@ import {
88
ScaleChartOptions,
99
} from "chart.js";
1010
import chartTrendline from "chartjs-plugin-trendline";
11-
import { createEffect, JSXElement, onCleanup, onMount } from "solid-js";
11+
import { createDeferred, JSXElement, onCleanup, onMount } from "solid-js";
1212

1313
import { Theme } from "../../constants/themes";
14+
import { createEffectOn } from "../../hooks/effects";
1415
import { useRefWithUtils } from "../../hooks/useRefWithUtils";
1516
import { getTheme } from "../../states/theme";
1617

18+
function getThemeHash(): string {
19+
return Object.values(getTheme()).join("");
20+
}
21+
1722
Chart.register(chartTrendline);
1823
type 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(() => {

frontend/src/ts/components/pages/AboutPage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export function AboutPage(): JSXElement {
105105
{({ speedHistogramData }) => (
106106
<>
107107
<ChartJs
108+
name="SpeedHistogram"
108109
type="bar"
109110
data={{
110111
labels: speedHistogramData()?.labels ?? [],

0 commit comments

Comments
 (0)