import React , { useEffect , useRef , useState } from 'react' ; import { Spin , Layout as AntdLayout , Drawer } from 'antd' ; import _ from 'lodash' ; import { RightOutlined , UpOutlined } from '@ant-design/icons' ; import Layout from '../layouts/layout' ; import { CodeLoading } from '../components/common/CodeLoading' ; import { ConfigPanel } from '../components/config-panel' ; import { Canvas } from '../components/canvas' ; import { DARK_THEME , LIGHT_THEME } from '../theme/default' ; import { ConfigProps } from '../types' ; import { getDevice } from '../utils/windowUtils' ; import './index.less' ; Spin . setDefaultIndicator ( < CodeLoading />); const DEFAULT_CONFIG = { seriesCount : 3 , showAxisTitle : true } ; const Page = ( ) => { const themeType = useRef < string > ( ) ; /** 加载状态 */ const [ loading , setLoading ] = useState ( true ) ; /** 主题 */ const [ theme , setTheme ] = useState ( LIGHT_THEME ) ; /** 其他和主题无关的配置项 */ const [ config , setConfig ] = useState ( DEFAULT_CONFIG ) ; /** 侧边栏是否缩进状态 */ const [ configPanelCollapse , setConfigPanelCollapse ] = useState ( false ) ; useEffect ( ( ) => { setTimeout ( ( ) => setLoading ( false ) , 100 ) ; } , [ ] ) ; useEffect ( ( ) => { const observer = new MutationObserver ( ( [ record ] ) => { if ( record . target . nodeName === 'BODY' && record . attributeName === 'data-theme' ) { if ( themeType . current !== document . body . dataset . theme ) { themeType . current = document . body . dataset . theme ; const { colors10 , colors20 } = theme ; setTheme ( _ . merge ( { } , theme , themeType . current === 'dark' ? DARK_THEME : LIGHT_THEME , { colors10 , colors20 } ) ) ; } } } ) ; observer . observe ( document . body , { attributes : true } ) ; } , [ ] ) ; param args const onConfigChange = ( value ) => { setConfig ( _ . merge ( { } , config , value ) ) ; } ; param value const onThemeChange = value => { setTheme ( _ . merge ( { } , theme , value ) ) ; } ; return ( < Spin spinning = { loading } > < Layout mainStyle = { { display : 'flex' , width : '100%' , margin : '0 auto' } } > < Canvas theme = { theme } { ... config } /> { getDevice ( ) === 'pc' ? ( < AntdLayout . Sider collapsed = { configPanelCollapse } theme = "light" width = { 360 } collapsible trigger = { null } > < RightOutlined className = "sider-trigger" onClick = { ( ) => setConfigPanelCollapse ( old => ! old ) } /> < ConfigPanel config = { { ... config , theme } } onChange = { onConfigChange } onThemeChange = { onThemeChange } / > < /AntdLayout.Sider>) : (<Drawer visible={configPanelCollapse} forceRender placement="bottom" closable className="mobile-sider" onClose={() => setConfigPanelCollapse(false)}> < UpOutlined className = "sider-trigger" onClick = { ( ) => setConfigPanelCollapse ( old => ! old ) } /> < ConfigPanel config = { { ... config , theme } } onChange = { onConfigChange } onThemeChange = { onThemeChange } / > < /Drawer>)} < /Layout> < /Spin>); } ; export default Page ;