@@ -4,22 +4,20 @@ import * as echarts from 'echarts';
4
4
import { cloneDeep , merge } from 'lodash' ;
5
5
import React , { useEffect , useImperativeHandle , useRef , useState } from 'react' ;
6
6
7
- import { useAsync , useResize , useStorage } from '@react-devui/hooks' ;
7
+ import { useAsync , useResize } from '@react-devui/hooks' ;
8
8
import { getClassName } from '@react-devui/utils' ;
9
9
10
- import { STORAGE_KEY } from '../../config/storage' ;
11
10
import chartTheme from './theme.json' ;
12
11
13
- echarts . registerTheme ( 'light' , chartTheme . light ) ;
14
- echarts . registerTheme ( 'dark' , merge ( cloneDeep ( chartTheme . light ) , chartTheme . dark ) ) ;
15
-
16
12
export interface AppChartProps < O extends echarts . EChartsOption > extends Omit < React . HTMLAttributes < HTMLDivElement > , 'children' > {
17
13
aOption : O | null ;
14
+ aRenderer ?: 'canvas' | 'svg' ;
18
15
}
19
16
20
17
function Chart < O extends echarts . EChartsOption > ( props : AppChartProps < O > , ref : React . ForwardedRef < echarts . ECharts > ) : JSX . Element | null {
21
18
const {
22
19
aOption,
20
+ aRenderer = 'canvas' ,
23
21
24
22
...restProps
25
23
} = props ;
@@ -35,17 +33,48 @@ function Chart<O extends echarts.EChartsOption>(props: AppChartProps<O>, ref: Re
35
33
36
34
const async = useAsync ( ) ;
37
35
38
- const themeStorage = useStorage < AppTheme > ( ...STORAGE_KEY . theme ) ;
39
-
40
36
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
+ } , [ ] ) ;
41
56
42
57
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 ;
44
73
setInstance ( instance ) ;
45
74
return ( ) => {
46
75
instance ?. dispose ( ) ;
47
76
} ;
48
- } , [ themeStorage . value ] ) ;
77
+ } , [ aRenderer , theme ] ) ;
49
78
50
79
useEffect ( ( ) => {
51
80
if ( instance && aOption ) {
0 commit comments