123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- /*
- //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',
- } = 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 };
- 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;
- option.xAxis.data = xData.map((item) => {
- if (timeFormat > 150 || chartType === 'bar') {
- return `${dayjs(item).format('MM')}月 `;
- }
- if (timeFormat >= 7) {
- return dayjs(item).format('YYYY-MM-DD');
- }
- return dayjs(item).format('HH:mm');
- });
- } else {
- option.xAxis.data = xData || [];
- }
- if (Array.isArray(yName)) {
- if (yName.length > 2) {
- option.grid.right = 120;
- }
- 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 = 30;
- option.yAxis = { ...option.yAxis[0], name: yName };
- option.series = dataList.map((item) => {
- 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 (
- <div className={styles.content}>
- <div
- style={{
- width: chartType === 'gauge' ? '60%' : '100%',
- marginLeft: chartType === 'gauge' ? '20%' : '0',
- height: typeList?.length <= 0 ? '100%' : 'calc(100% - 57px)',
- }}
- ref={chartDomRef}
- />
- {typeList?.length > 0 && (
- <Tabs
- activeKey={curType || typeList[0]}
- onChange={(type) => {
- setCurType(type);
- onChange(type);
- }}
- >
- {typeList.map((item) => (
- <TabPane tab={item} key={item} />
- ))}
- </Tabs>
- )}
- </div>
- );
- };
- export default ChartModule;
- const colors = [
- '#F5A623',
- '#4B9FEC',
- '#91cc75',
- '#5470c6',
- '#fac858',
- '#ee6666',
- '#73c0de',
- '#3ba272',
- '#fc8452',
- '#9a60b4',
- '#ea7ccc',
- ];
- const defaultOption = {
- color: colors,
- tooltip: {
- trigger: 'axis',
- },
- grid: {
- bottom: 30,
- left: 70,
- right: 30,
- },
- xAxis: {
- type: 'category',
- boundaryGap: false,
- axisTick: { show: false },
- nameTextStyle: {
- fontSize: 24,
- },
- axisLabel: {
- fontSize: 24,
- },
- data: [
- '00:00',
- '01:15',
- '02:30',
- '03:45',
- '05:00',
- '06:15',
- '07:30',
- '08:45',
- ],
- },
- yAxis: [
- {
- type: 'value',
- name: '000',
- top: 20,
- nameTextStyle: {
- fontSize: 24,
- // align: 'left',
- padding: [0, 0, 20, 0],
- },
- axisLabel: {
- fontSize: 24,
- },
- axisLine: {
- show: false,
- // lineStyle: {
- // color: colors[0],
- // },
- },
- splitLine: {
- lineStyle: {
- type: 'dashed',
- },
- },
- },
- {
- type: 'value',
- name: '111',
- top: 20,
- position: 'right',
- nameTextStyle: {
- fontSize: 24,
- // align: 'left',
- padding: [0, 0, 20, 0],
- },
- axisLine: {
- show: true,
- lineStyle: {
- color: colors[7],
- },
- },
- splitLine: {
- lineStyle: {
- type: 'dashed',
- },
- },
- },
- {
- type: 'value',
- name: '222',
- top: 20,
- position: 'right',
- offset: 80,
- nameTextStyle: {
- fontSize: 24,
- // align: 'left',
- padding: [0, 0, 20, 0],
- },
- axisLine: {
- show: true,
- lineStyle: {
- color: colors[8],
- },
- },
- splitLine: {
- lineStyle: {
- type: 'dashed',
- },
- },
- },
- ],
- series: [
- {
- data: [820, 932, 901, 934, 1290, 1330, 1320],
- type: 'line',
- name: '进水水量',
- yAxisIndex: 0,
- smooth: 'true',
- // itemStyle:{
- // color:'#be7bbe',
- // },
- showSymbol: false, // 不展示拐点圆圈
- },
- {
- data: [130, 125, 828, 743, 1100],
- name: '预测出水量',
- yAxisIndex: 0,
- type: 'line',
- smooth: 'true',
- lineStyle: {
- normal: {
- width: 4,
- type: 'dashed',
- },
- },
- itemStyle: {
- color: '#be7bbe',
- },
- showSymbol: false, // 不展示拐点圆圈
- },
- {
- data: [820, 772, 901, 934, 1290, 1120, 1320],
- name: '实际出水量',
- yAxisIndex: 0,
- type: 'line',
- smooth: 'true',
- showSymbol: false, // 不展示拐点圆圈
- itemStyle: {
- color: '#50A3C8',
- },
- areaStyle: {
- origin: 'number',
- color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
- {
- offset: 0,
- color: 'rgba(31,114,150,1)',
- },
- {
- offset: 1,
- color: 'rgba(31,114,150,0.3)',
- },
- ]),
- },
- },
- {
- data: [120, 200, 150, 80, 70, 110, 130],
- name: '实际出水量',
- type: 'bar',
- barGap: 0.2,
- barWidth: 30,
- },
- {
- data: [
- {
- value: 19,
- name: '负荷率',
- },
- ],
- name: '负荷率',
- type: 'gauge',
- startAngle: 180,
- endAngle: 0,
- radius: '90%',
- min: 0,
- max: 100,
- splitNumber: 10,
- center: ['50%', '65%'],
- axisLine: {
- lineStyle: {
- width: 40,
- color: [
- [0.33, '#a4f428'],
- [0.66, '#f6a842'],
- [1, '#e02b42'],
- ],
- },
- },
- axisPointer: {
- show: true,
- },
- pointer: {
- icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
- length: '50%',
- width: 8,
- offsetCenter: [0, 0],
- itemStyle: {
- color: 'auto',
- },
- },
- axisTick: {
- show: false,
- },
- splitLine: {
- show: false,
- },
- axisLabel: {
- show: false,
- },
- title: {
- offsetCenter: [0, '25%'],
- fontSize: 24,
- },
- detail: {
- show: false,
- },
- },
- ],
- legend: {
- // 图例配置
- // icon:'arrow',
- // width:'2',
- itemHeight: 0, // 远点宽度为0不显示原点
- // right: '10%',
- data: ['进水水量', '预测出水量', '实际出水量'],
- lineStyle: {},
- textStyle: {
- fontSize: 24,
- },
- },
- // toolbox: {
- // show: true,
- // feature: {
- // // dataZoom: {
- // // yAxisIndex: 'none'
- // // },
- // // dataView: { readOnly: false },
- // // magicType: { type: ['line', 'bar'] },
- // restore: {},
- // saveAsImage: {},
- // },
- // },
- };
|