import { EMPTY_LIST } from '@/common/parameter';
import { Radio } from 'antd';
import * as echarts from 'echarts';
import React, { useEffect, useRef, useState } from 'react';
const ChartComponents: React.FC = ({ dataSource = EMPTY_LIST, loading }: { loading?: boolean; dataSource?: any[] }) => {
const [type, setType] = useState('pow');
const arrRef = useRef([]);
const [optionData, setOptionData] = useState({
tooltip: {
trigger: 'axis',
},
legend: {
orient: 'vertical', // 垂直排列
right: 5, // 距离右侧的距离
top: 10,
data: [],
},
grid: {
left: '1%',
top: '2%',
bottom: '8%',
right: '15%',
containLabel: true,
},
dataZoom: [
{
id: 'dataZoomX',
type: 'slider',
start: 0,
end: 100,
zoomLock: false,
handleSize: '80%', // 设置滑块的大小
top: 'bottom', // 设置滑块的位置
},
],
xAxis: {
type: 'category',
boundaryGap: false,
splitLine: {
show: false,
},
axisLine: {
lineStyle: {
color: '#5c5d89',
},
},
axisTick: {
show: false,
},
axisLabel: {
textStyle: {
color: '#5c5d89',
},
},
data: [],
},
yAxis: [
{
type: 'value',
axisLabel: {
textStyle: {
color: '#a8aab0',
fontStyle: 'normal',
fontFamily: '微软雅黑',
fontSize: 12,
},
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
splitLine: {
show: true,
lineStyle: {
color: '#E5E9ED',
// opacity:0.1
},
},
},
],
series: [],
});
const handleChange = (e: any) => {
setType(e.target.value);
};
// 动态修改max,min.echarts会根据max,min自动设置区间
const updateIntervalToDefaultTenFold = (myChart: any) => {
const axisLabels = myChart.getModel().getComponent('yAxis', 0).axis.scale.getExtent(); // 获取[min,max]
if (axisLabels.length > 0) {
const diff = (axisLabels[1] - axisLabels[0]) / 10;
return {
max: Math.ceil(axisLabels[1] + diff), // 向上取整
min: Math.floor(axisLabels[0] - diff), // 向下取整
};
}
};
const initChart = (legendList: string[], xData: string[], seriesData = []) => {
let myChart = echarts.getInstanceByDom(document.getElementById('echarts-line'));
if (myChart == null) {
// 如果不存在,就进行初始化。
myChart = echarts.init(document.getElementById('echarts-line'));
}
let obj = {
...optionData,
legend: {
...optionData.legend,
data: legendList,
},
dataZoom: [
{
id: 'dataZoomX',
type: 'slider',
start: xData[0],
end: xData[xData.length - 1],
zoomLock: false,
handleSize: '80%', // 设置滑块的大小
top: 'bottom', // 设置滑块的位置
},
],
xAxis: {
...optionData.xAxis,
data: xData,
},
series: seriesData,
};
/**
* 当按钮类型是linear,为 yAxis 或者 yAxis某一项 新增 max,min属性
* 当按钮类型是pow,要删除max,min属性,不然图不会动态变化
* */
if (type === 'linear') {
const { max, min } = updateIntervalToDefaultTenFold(myChart);
obj.yAxis[0]['max'] = max;
obj.yAxis[0]['min'] = min;
} else {
delete obj.yAxis[0]['max']; // 恢复默认间隔
delete obj.yAxis[0]['min']; // 恢复默认间隔
}
setOptionData(obj);
// 绘制图表,第二属性在动态变化时非常有用
myChart.setOption(obj, true);
};
// 自动生成颜色
const generateRandomColor = () => {
const letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 12)];
}
return color;
};
const seriesOption = (legendList: string[], chartData: any, item: string, index: number) => {
let obj = {
name: item,
type: 'line',
data: [],
};
// 在pow模式下,会自动生成颜色,linear模式下颜色不变,和pow模式保持一致
if (type !== 'linear') {
obj['itemStyle.normal.color'] = generateRandomColor();
}
obj.data = chartData[`${'yData' + index}`];
arrRef.current.push(obj);
};
useEffect(() => {
let legendList: string[] = []; // 图例名称,根据实际情况看是否需要过滤
// 因为需要动态生成多个yData,为了方便传参,设置一个对象
let chartData = {
xData: [],
};
arrRef.current = [];
// dataSource是接口返回的内容,根据真实情况做变动
if (dataSource.length) {
dataSource.map((item: any, index: number) => {
legendList.push(item.title.description);
if (index === 0) {
item.values.map((t: any) => {
chartData.xData.push(t.t);
});
}
chartData[`${'yData' + index}`] = []; // 动态生成 yData0,yData1...
item.values.map((v: any) => {
chartData[`${'yData' + index}`].push(v.v);
});
});
legendList.map((item: any, index: number) => {
seriesOption(legendList, chartData, item, index);
});
initChart(legendList, chartData.xData, arrRef.current);
}
}, [dataSource, type]);
useEffect(() => {
handleChange({ target: { value: 'pow' } });
}, [dataSource]);
return (
<div>
<div style={{ marginBottom: 15, width: '100%', textAlign: 'end' }}>
<Radio.Group value={type} buttonStyle="solid" size="small" onChange={handleChange}>
<Radio.Button value="pow">pow</Radio.Button>
<Radio.Button value="linear">linear</Radio.Button>
</Radio.Group>
</div>
<div id={'echarts-line'} style={{ width: '100%', height: '520px' }}></div>
</div>
);
};
export default ChartComponents;
ECharts动态生成yData
最新推荐文章于 2024-07-25 15:19:10 发布