import { useState, useEffect, useRef } from 'react' import ReactEChartsCore from 'echarts-for-react/lib/core' import { echarts } from '../echarts' import { LineChart } from 'echarts/charts' import { TitleComponent, TooltipComponent, GridComponent, LegendComponent, LegendScrollComponent, MarkLineComponent, MarkPointComponent, } from 'echarts/components' import { CanvasRenderer } from 'echarts/renderers' import numbro from 'numbro' import merge from 'lodash/merge' import { polylineSeriesMapping } from '../preset' import { defineConfig } from '@/utils/common' import type { EChartsOption, DefaultLabelFormatterCallbackParams } from 'echarts' import type { MyEChartProps } from '../types' // 注册 echarts 组件 echarts.use([ // charts LineChart, // components TitleComponent, TooltipComponent, GridComponent, LegendComponent, LegendScrollComponent, MarkLineComponent, MarkPointComponent, // render CanvasRenderer, ]) function genDefaultOptions(): EChartsOption { const options = { title: { show: false, }, grid: { top: 30, left: '8%', right: '8%', bottom: 30, }, legend: { show: true, type: 'scroll', orient: 'horizontal', textStyle: { fontSize: 10, }, pageIconSize: 12, }, tooltip: { show: true, trigger: 'axis', axisPointer: { type: 'shadow', }, appendToBody: true, confine: true, padding: [8, 12], textStyle: { fontSize: 12, lineHeight: 18, fontWeight: 300, fontFamily: `'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif`, }, formatter: (lines: any) => { const newLines = [...lines] const str: string[] = [] newLines.sort((a, b) => { return b.value - a.value }) newLines.forEach((p) => { const val = typeof p.value === 'number' || p.value ? p.value : '-' const cont = `
${p.marker} ${p.seriesName} ${val}
` str.push(cont) }) str.unshift(`
${newLines[0].axisValue}
`) return str.join('') }, }, xAxis: { type: 'category', triggerEvent: true, axisTick: { alignWithLabel: true, }, }, yAxis: { type: 'value', splitLine: { lineStyle: { width: 0.8, type: 'dashed', }, }, axisLabel: { fontWeight: 'bold', formatter: (value: any) => { let num = numbro(Number(value)).format({ average: true, mantissa: 1, }) if (Number.isNaN(+num)) { num = num.replace(/\.0+/g, '') // 如果是整数,则去除小数位 } else if (Math.abs(+num) === +num) { return +num } return num }, }, }, } return options as any } const YaPolyline: React.FC = (props) => { const { opts = {}, series = {}, containerStyle = {}, mode = 'light', onChartReady, onClick, loading = false, } = props const chartRef = useRef(null) const [chartOptions, setChartOptions] = useState({}) const genOptions = () => { return genDefaultOptions() } useEffect(() => { if (chartRef && chartRef.current) { // get echarts instance const ins = chartRef.current.getEchartsInstance() // click ins.on('click', (params: DefaultLabelFormatterCallbackParams) => onClick && onClick(params)) } }, []) useEffect(() => { if (!!series && Object.keys(series).length) { const defaultStyleOptions = genOptions() const staticsOpts = merge(defaultStyleOptions, opts) const initOptions = { ...staticsOpts, series, } setChartOptions(initOptions) } }, [series]) return ( onChartReady && onChartReady(instance, chartOptions)} opts={{}} /> ) } export function genPolylineSeriesOps(type = 'default') { return defineConfig({ type: 'line', ...polylineSeriesMapping[type], }) } export default YaPolyline