/** @format */ import 'echarts/lib/chart/line'; // import 'echarts/lib/chart/pie'; // import 'echarts/lib/chart/gauge'; // import 'echarts/lib/chart/bar'; import 'echarts/lib/component/tooltip'; // import 'echarts/lib/component/toolbox'; import 'echarts/lib/component/title'; import 'echarts/lib/component/legend'; import 'echarts/lib/component/grid'; import echarts from 'echarts/lib/echarts'; import _ from 'lodash'; import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; interface BasicLineChartProps { /** * 容器大小 */ size?: { width: number; height: number }; /** * 配置项 */ option?: Record; /** * 数据源,统一为数组格式 */ data?: Record; } const BasicLineChart = (props: BasicLineChartProps) => { const { size = { height: 500 }, option = {}, data, data: { xData = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'], yData = [[10, 52, 200, 334, 390, 330, 220]], } = {}, } = props; const wrapperRef = useRef(null); const [echartsInc, setEchartsInc] = useState | null>( null, ); function formatSeries( data: Record[] = [], op: Record = {}, ) { // series 模板 const baseSeries = { name: '直接访问', type: 'line', data: [], itemStyle: { color: '#3398DB', borderWidth: 3, opacity: 1, }, smooth: false, label: { show: true, color: '#999', fontWeight: 'normal', align: 'center', fontFamily: 'Microsoft YaHei', fontSize: 12, position: 'top', formatter: '{c}', }, lineStyle: { // color: '#3398DB', type: 'solid', width: 2, }, areaStyle: { opacity: 1, color: { type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: '#3398DB', // 0% 处的颜色 }, { offset: 1, color: 'rgba(9,9,9,0)', // 100% 处的颜色 }, ], global: false, // 缺省为 false }, }, }; const latestSeries = _.mergeWith(baseSeries, op); // 将实例的颜色同线的颜色保持一致 if (op.lineStyle?.color) { latestSeries.itemStyle.color = op.lineStyle.color; } latestSeries.data = data; return latestSeries; } const optionBase = { color: ['#0a73ff', '#945718', '#79daff'], tooltip: { show: true, trigger: 'axis', triggerOn: 'mousemove', axisPointer: { // 坐标轴指示器,坐标轴触发有效 type: 'line', // 默认为直线,可选为:'line' | 'shadow' }, hideDelay: 100, textStyle: { fontFamily: 'Microsoft Yahei', fontWeight: 'normal', fontSize: 14, color: '#fff', }, }, legend: { show: true, padding: 2, itemGap: 5, itemWidth: 6, icon: 'circle', itemHeight: 6, left: 'center', orient: 'horizontal', textStyle: { fontFamily: 'Microsoft Yahei', fontWeight: 'normal', fontSize: 12, color: '#999', }, }, grid: { left: 30, right: 40, bottom: 30, top: 30, containLabel: true, }, xAxis: { type: 'category', show: true, name: '', data: xData, axisTick: { alignWithLabel: true, show: false, }, nameTextStyle: {}, axisLabel: { show: true, color: '#999', fontWeight: 'normal', fontFamily: 'Microsoft YaHei', fontSize: 12, rotate: 0, interval: 0, }, axisLine: { show: false, lineStyle: { color: '#333' }, }, splitLine: { show: false, lineStyle: { color: '#999', type: 'dashed' }, }, }, yAxis: { type: 'value', min: 0, max: 'dataMax', axisTick: { show: false, }, axisLabel: { show: true, color: '#999', fontWeight: 'normal', fontFamily: 'Microsoft YaHei', fontSize: 12, interval: 'auto', formatter: '{value}', }, axisLine: { show: false, lineStyle: { color: '#333' }, }, splitLine: { show: true, lineStyle: { color: '#aaa', type: 'dashed' }, }, name: '', }, series: [], animation: true, animationEasing: 'cubicOut', animationEasingUpdate: 'cubicOut', animationDuration: 500, animationDurationUpdate: 300, }; useLayoutEffect(() => { if (wrapperRef && wrapperRef.current) { const myChart = echarts.init(wrapperRef.current, null, { devicePixelRatio: 2, }); setEchartsInc(myChart); const latestOption = _.mergeWith(optionBase, option); latestOption.series = yData.map( (item: Record[], index: number) => formatSeries(item, option.series && option.series[index]), ); myChart.setOption(latestOption); } }, []); useEffect(() => { if (!echartsInc) { return; } const latestOption = _.mergeWith(optionBase, option); latestOption.series = yData.map( (item: Record[], index: number) => formatSeries(item, option.series && option.series[index]), ); echartsInc.setOption(latestOption, { notMerge: true }); }, [option, data]); useEffect(() => { if (!echartsInc) { return; } echartsInc.resize(); }, [size]); return
; }; export default BasicLineChart;