/* //y轴显示数据 Data:{ type:number, 0(实线) 1虚线(预测) 2(填充) name:string, yIndex:number, //yName的下标索引(第几个y坐标轴) data:string[], } props:{ closeTime:boolen //是否超过7天展示时间 yName:string || string[], //y轴名称 一个或多个 xData:string[], //x轴时间数据 dataList:Data[], //折线的数据列表 currentType:string, //当前选择那个tabs 需要外部更新当前选中type时传入 typeList:string[], //图表下的选择类型列表 onChange:(id:number)=>{} } */ import { Tabs } from 'antd'; import dayjs from 'dayjs'; import * as echarts from 'echarts'; import { useEffect, useRef, useState } from 'react'; import styles from './index.less'; const { TabPane } = Tabs; export const handleExportClick = () => { const canvas = document.getElementsByTagName('canvas'); if (canvas && canvas.length > 0) { return canvas[0].toDataURL('image/png'); } return null; }; // 图表模块 const ChartModule = (props) => { const chartDomRef = useRef(); const chartRef = useRef(); const { yName, closeTime = false, xData, dataList, typeList = [], onChange, currentType, chartType = 'line', legend = {}, } = props; const [curType, setCurType] = useState(currentType); useEffect(() => { chartRef.current = echarts.init(chartDomRef.current); window.addEventListener('resize', resetChart); return () => window.removeEventListener('resize', resetChart); }, []); useEffect(() => { if (!chartRef.current || !dataList || !chartType === 'gauge') { return; } const option = { ...defaultOption }; if (legend) { option.legend.textStyle = { ...option.legend.textStyle, ...legend.textStyle, }; if (legend.right) { option.legend.right = legend.right; } } let series = []; switch (chartType) { case 'gauge': series = option.series[dataList.type]; series.data = [dataList]; for (const key in option) { delete option[key]; } option.series = [series]; break; default: // 超过7天x轴显示年月日,不到7天显示时分 if (!closeTime && xData && xData.length > 1) { const timeFormat = Math.abs( dayjs(xData[xData?.length - 1]).diff(dayjs(xData[0]), 'days'), ) + 1; if (timeFormat > 150 || chartType === 'bar') { option.xAxis.data = xData.map((item) => dayjs(item).format('YYYY-MM'), ); } else if (timeFormat >= 7) { option.xAxis.data = xData.map((item) => dayjs(item).format('YYYY-MM-DD'), ); } else { option.xAxis.data = xData.map((item) => dayjs(item).format('YYYY-MM-DD HH:mm'), ); option.xAxis.axisLabel.formatter = (value) => value?.split(' ')[1]; } } else { option.xAxis.data = xData || []; } if (Array.isArray(yName)) { if (yName.length > 2) { option.grid.right = yName.length * 60; } option.yAxis = yName.map((item, index) => { return { ...option.yAxis[index], name: item }; }); option.series = dataList.map((item) => { return { ...option.series[item.type], name: item.name, data: item.data, yAxisIndex: item.yIndex || 0, }; }); } else { option.grid.right = 60; // 重置grid left 用于比对计算合适宽度 option.grid.left = 70; option.yAxis = { ...option.yAxis[0], name: yName }; option.series = dataList.map((item) => { item.data.forEach((dataItem) => { if (String(dataItem).length * 10 + 40 > option.grid.left) { option.grid.left = String(dataItem).length * 10 + 45; } }); return { ...option.series[item.type], name: item.name, data: item.data, // barWidth: dataList.length >= 4 ? 8 : 20, }; }); } // 柱状图需要开启boundaryGap避免和Y轴重合 if (chartType === 'bar') { option.xAxis.boundaryGap = true; delete option.legend.itemHeight; } else { option.xAxis.boundaryGap = false; option.legend.itemHeight = 0; } option.legend.data = dataList.map((item) => item.name); break; } // console.log(props, JSON.stringify(option)); chartRef.current.clear(); chartRef.current.setOption(option); chartRef.current.resize(); // if (typeList?.length > 0) setCurType(typeList[0]); }, [yName, xData, dataList, typeList, chartType]); useEffect(() => { setCurType(currentType); }, [currentType]); const resetChart = () => { if (chartRef.current) chartRef.current.resize(); }; return (