@@ -4,22 +4,20 @@ import * as echarts from 'echarts';
44import { cloneDeep , merge } from 'lodash' ;
55import React , { useEffect , useImperativeHandle , useRef , useState } from 'react' ;
66
7- import { useAsync , useResize , useStorage } from '@react-devui/hooks' ;
7+ import { useAsync , useResize } from '@react-devui/hooks' ;
88import { getClassName } from '@react-devui/utils' ;
99
10- import { STORAGE_KEY } from '../../config/storage' ;
1110import chartTheme from './theme.json' ;
1211
13- echarts . registerTheme ( 'light' , chartTheme . light ) ;
14- echarts . registerTheme ( 'dark' , merge ( cloneDeep ( chartTheme . light ) , chartTheme . dark ) ) ;
15-
1612export interface AppChartProps < O extends echarts . EChartsOption > extends Omit < React . HTMLAttributes < HTMLDivElement > , 'children' > {
1713 aOption : O | null ;
14+ aRenderer ?: 'canvas' | 'svg' ;
1815}
1916
2017function Chart < O extends echarts . EChartsOption > ( props : AppChartProps < O > , ref : React . ForwardedRef < echarts . ECharts > ) : JSX . Element | null {
2118 const {
2219 aOption,
20+ aRenderer = 'canvas' ,
2321
2422 ...restProps
2523 } = props ;
@@ -35,17 +33,48 @@ function Chart<O extends echarts.EChartsOption>(props: AppChartProps<O>, ref: Re
3533
3634 const async = useAsync ( ) ;
3735
38- const themeStorage = useStorage < AppTheme > ( ...STORAGE_KEY . theme ) ;
39-
4036 const [ instance , setInstance ] = useState < echarts . ECharts | null > ( null ) ;
37+ const [ theme , setTheme ] = useState < AppTheme | null > ( null ) ;
38+
39+ useEffect ( ( ) => {
40+ for ( const theme of [ 'light' , 'dark' ] as const ) {
41+ if ( document . body . className . includes ( theme ) ) {
42+ setTheme ( theme ) ;
43+ break ;
44+ }
45+ }
46+
47+ const observer = new MutationObserver ( ( ) => {
48+ setTheme ( document . body . className . includes ( 'dark' ) ? 'dark' : 'light' ) ;
49+ } ) ;
50+ observer . observe ( document . body , { attributeFilter : [ 'class' ] } ) ;
51+
52+ return ( ) => {
53+ observer . disconnect ( ) ;
54+ } ;
55+ } , [ ] ) ;
4156
4257 useEffect ( ( ) => {
43- const instance = containerRef . current ? echarts . init ( containerRef . current , themeStorage . value , { renderer : 'svg' } ) : null ;
58+ const instance =
59+ containerRef . current && theme
60+ ? echarts . init (
61+ containerRef . current ,
62+ JSON . parse (
63+ JSON . stringify ( theme === 'light' ? chartTheme . light : merge ( cloneDeep ( chartTheme . light ) , chartTheme . dark ) ) . replace (
64+ / v a r \( ( .+ ?) \) / g,
65+ ( match , p1 ) => {
66+ return getComputedStyle ( document . body ) . getPropertyValue ( p1 ) ;
67+ }
68+ )
69+ ) ,
70+ { renderer : aRenderer }
71+ )
72+ : null ;
4473 setInstance ( instance ) ;
4574 return ( ) => {
4675 instance ?. dispose ( ) ;
4776 } ;
48- } , [ themeStorage . value ] ) ;
77+ } , [ aRenderer , theme ] ) ;
4978
5079 useEffect ( ( ) => {
5180 if ( instance && aOption ) {
0 commit comments