diff --git a/packages/platform/src/app/components/chart/Chart.tsx b/packages/platform/src/app/components/chart/Chart.tsx index dcc7df56..b2806b4b 100644 --- a/packages/platform/src/app/components/chart/Chart.tsx +++ b/packages/platform/src/app/components/chart/Chart.tsx @@ -4,22 +4,20 @@ import * as echarts from 'echarts'; import { cloneDeep, merge } from 'lodash'; import React, { useEffect, useImperativeHandle, useRef, useState } from 'react'; -import { useAsync, useResize, useStorage } from '@react-devui/hooks'; +import { useAsync, useResize } from '@react-devui/hooks'; import { getClassName } from '@react-devui/utils'; -import { STORAGE_KEY } from '../../config/storage'; import chartTheme from './theme.json'; -echarts.registerTheme('light', chartTheme.light); -echarts.registerTheme('dark', merge(cloneDeep(chartTheme.light), chartTheme.dark)); - export interface AppChartProps extends Omit, 'children'> { aOption: O | null; + aRenderer?: 'canvas' | 'svg'; } function Chart(props: AppChartProps, ref: React.ForwardedRef): JSX.Element | null { const { aOption, + aRenderer = 'canvas', ...restProps } = props; @@ -35,17 +33,48 @@ function Chart(props: AppChartProps, ref: Re const async = useAsync(); - const themeStorage = useStorage(...STORAGE_KEY.theme); - const [instance, setInstance] = useState(null); + const [theme, setTheme] = useState(null); + + useEffect(() => { + for (const theme of ['light', 'dark'] as const) { + if (document.body.className.includes(theme)) { + setTheme(theme); + break; + } + } + + const observer = new MutationObserver(() => { + setTheme(document.body.className.includes('dark') ? 'dark' : 'light'); + }); + observer.observe(document.body, { attributeFilter: ['class'] }); + + return () => { + observer.disconnect(); + }; + }, []); useEffect(() => { - const instance = containerRef.current ? echarts.init(containerRef.current, themeStorage.value, { renderer: 'svg' }) : null; + const instance = + containerRef.current && theme + ? echarts.init( + containerRef.current, + JSON.parse( + JSON.stringify(theme === 'light' ? chartTheme.light : merge(cloneDeep(chartTheme.light), chartTheme.dark)).replace( + /var\((.+?)\)/g, + (match, p1) => { + return getComputedStyle(document.body).getPropertyValue(p1); + } + ) + ), + { renderer: aRenderer } + ) + : null; setInstance(instance); return () => { instance?.dispose(); }; - }, [themeStorage.value]); + }, [aRenderer, theme]); useEffect(() => { if (instance && aOption) {