| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- "use client"
- import React, {useEffect, useRef} from "react"
- import {
- type ECharts,
- type EChartsCoreOption,
- getInstanceByDom,
- init as echartsInit,
- type SetOptionOpts,
- use as echartsUse
- } from "echarts/core"
- import {BarChart, GaugeChart, LineChart, PieChart, RadarChart, ScatterChart} from "echarts/charts"
- import {
- DatasetComponent,
- GraphicComponent,
- GridComponent,
- LegendComponent,
- TitleComponent,
- ToolboxComponent,
- TooltipComponent,
- VisualMapComponent,
- } from "echarts/components"
- import {CanvasRenderer} from "echarts/renderers"
- echartsUse([
- BarChart,
- LineChart,
- PieChart,
- GaugeChart,
- RadarChart,
- ScatterChart,
- GridComponent,
- TooltipComponent,
- LegendComponent,
- TitleComponent,
- ToolboxComponent,
- VisualMapComponent,
- DatasetComponent,
- GraphicComponent,
- CanvasRenderer,
- ])
- export type EChartProps = {
- option: EChartsCoreOption
- className?: string
- style?: React.CSSProperties
- theme?: "light" | "dark"
- opts?: SetOptionOpts
- }
- export default function EChart({ option, className, style, theme = "light", opts }: EChartProps) {
- const ref = useRef<HTMLDivElement | null>(null)
- const chartRef = useRef<ECharts | null>(null)
- useEffect(() => {
- if (!ref.current) return
- const el = ref.current
- let chart = getInstanceByDom(el)
- if (!chart) {
- chart = echartsInit(el, theme, { renderer: "canvas", locale: "ZH" })
- }
- chartRef.current = chart
- // Apply option
- chart.setOption(option, opts)
- const resize = () => chart && chart.resize()
- window.addEventListener("resize", resize)
- // Resize observer for container changes
- const ro = new ResizeObserver(() => resize())
- ro.observe(el)
- return () => {
- window.removeEventListener("resize", resize)
- ro.disconnect()
- // dispose only if element is being removed to avoid issues in fast refresh
- if (chart && !el.isConnected) {
- chart.dispose()
- chartRef.current = null
- }
- }
- }, [option, theme, opts])
- return <div ref={ref} className={className} style={{ width: "100%", height: 320, ...style }} />
- }
|