Commit 8a303da5 authored by 陈龙's avatar 陈龙

feat: 升级历史曲线

parent 82a9265e
......@@ -16,7 +16,7 @@ const Demo = () => {
},
},
grid: {
right: '20%',
right: '10%',
},
toolbox: {
feature: {
......
......@@ -18,7 +18,7 @@ export const buildDefaultLegend = (option) => {
textStyle: {
padding: [0, 0, 0, 4],
color: '#2d2d2d',
width: 80,
width: 120,
overflow:'truncate'
},
tooltip:{
......
......@@ -30,7 +30,7 @@ path: /
## 多图表
<code src="./demos/GridDemo.js"></code>
<!-- <code src="./demos/GridDemo.js"></code> -->
## API
......
......@@ -29,7 +29,6 @@ const SingleChart = memo((props) => {
showMarkLine: true,
showPoint: true,
chartType,
// justLine,
showBoxOption,
special
};
......
......@@ -4,26 +4,32 @@ import { MobileHistoryChart } from "../mobile";
const deviceParams = [
/*10.182*/
/* {
/* {
deviceCode: 'EGBF00000141',
// sensors: '进水压力,出水瞬时流量,出水累计流量',
sensors: '进水压力',
deviceType: '熊猫二供泵房',
pointAddressID: 208,
},*/
/* {
}, */
/* {
"deviceCode": "SYJ00000008",
"sensors": "瞬时流量",
"deviceType": "水源井"
},*/
},
{
deviceCode: 'EGJZ00000197',
sensors: '进水压力,出水压力,出水瞬时流量,出水累计流量',
// sensors: '1#变频器运行频率',
deviceType: '二供机组',
// pointAddressID: 208,
}
}, */
/* {
deviceCode: 'EGJZ00000198',
sensors: '进水压力,出水压力,出水瞬时流量,出水累计流量',
// sensors: '1#变频器运行频率',
deviceType: '二供机组',
// pointAddressID: 208,
}, */
/* {
// deviceCode: 'EGBF00000002',
// deviceCode: 'EGBF00000018',
......@@ -35,12 +41,12 @@ const deviceParams = [
deviceType: '熊猫压力表',
pointAddressID: 4,
},*/
/* {
{
deviceCode: 'EGJZ00000226',
sensors: '出水压力',
deviceType: '二供机组',
pointAddressID: 4,
},*/
},
/* {
"deviceCode": "LLJ00000055",
"sensors": "正累计流量,瞬时流量",
......@@ -52,51 +58,51 @@ const deviceParams = [
"deviceType": "二供机组"
}*/
// 邳州张楼水厂
/* {
{
"deviceCode": "SC00000023",
"sensors": "瞬时流量",
"deviceType": "水厂"
} */
/* {
},
{
"deviceCode": "JFJ00000001",
"sensors": "沉淀池投矾量瞬时,",
"deviceType": "加矾间"
}*/
/* {
},
{
"deviceCode": "QSBF00000001",
"sensors": "取水浊度",
"deviceType": "取水泵房"
}*/
/* {
},
{
"deviceCode": "SC00000023",
"sensors": "出水瞬时流量",
"deviceType": "水厂"
}*/
// {
// "deviceCode": "XNCDC00000001",
// "sensors": "沉淀池1号进水管流量",
// "deviceType": "絮凝沉淀池"
// }
/* {
},
{
"deviceCode": "XNCDC00000001",
"sensors": "沉淀池1号进水管流量",
"deviceType": "絮凝沉淀池"
},
{
"deviceCode": "LLJ00000001",
"sensors": "瞬时流量",
"deviceType": "流量计"
}*/
},
/*邳州*/
/* {
{
deviceCode: 'EGJZ00000027',
sensors: '2#变频器运行频率',
deviceType: '二供机组',
}*/
},
/*确山*/
/*泵3状态*/
/* {
/* {
// EGJZ00000003
deviceCode: 'EGJZ00000003',
// sensors: '3#频率',
sensors: '出1累计流量',
deviceType: '二供机组',
}*/
} */
];
const Demo = () => {
return (
......
import React, {useContext, useEffect, useMemo, useState, useCallback, useRef} from 'react';
import React, { useContext, useEffect, useMemo, useState, useCallback, useRef } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import {
......@@ -34,10 +34,10 @@ import {
import SingleChart from './SingleChart';
import GridChart from './GridChart';
import './index.less';
import {globalConfig} from 'antd/lib/config-provider';
import { globalConfig } from 'antd/lib/config-provider';
const {RangePicker} = DatePicker;
const {Option} = Select;
const { RangePicker } = DatePicker;
const { Option } = Select;
const startFormat = 'YYYY-MM-DD 00:00:00';
const endFormat = 'YYYY-MM-DD 23:59:59';
......@@ -263,7 +263,7 @@ const OriginMaxDays = 31; // 原始曲线请求数据的最大天数
const CharacteristicMaxDays = null; // 特征曲线或者其他曲线的最大天数
const HistoryView = (props) => {
const [completeInit, setCompleteInit] = useState(false);
const {getPrefixCls} = useContext(ConfigProvider.ConfigContext);
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls('history-view');
const {
title,
......@@ -311,6 +311,14 @@ const HistoryView = (props) => {
const [percent, setPercent] = useState(0);
// 频率指标特殊业务
const [special1, setSpecial1] = useState(null);
// 历史数据相关的特征描述
const deviceConfig = useRef({
oneDevice: deviceParams.length === 1,//单设备
oneSensor: [...new Set(deviceParams.reduce((final, cur) => {
let _sensors = cur.sensors.split(',');
return final.concat(_sensors);
}, []))].length === 1, // 单指标
});
// 选择的时间范围值
const dateRange = useMemo(() => {
if (timeValue === 'customer') {
......@@ -444,13 +452,13 @@ const HistoryView = (props) => {
onContrastChange(contrastOption);
setShowBoxOption(false);
setChartType('lineChart');
onCheckboxChange({target: {value: false}}, 'chartType');
onCheckboxChange({target: {value: false}}, 'ignoreOutliers');
onCheckboxChange({ target: { value: false } }, 'chartType');
onCheckboxChange({ target: { value: false } }, 'ignoreOutliers');
} else {
// 自定义
// 不需要处理
setShowBoxOption(true);
onCheckboxChange({target: {value: true}}, 'chartType');
onCheckboxChange({ target: { value: true } }, 'chartType');
}
};
const onShortcutsChange = (e) => {
......@@ -460,37 +468,37 @@ const HistoryView = (props) => {
switch (_val) {
case '近3天':
_arr = [
{key: 1, value: moment()},
{key: 2, value: moment().subtract(1, 'days')},
{key: 3, value: moment().subtract(2, 'days')},
{ key: 1, value: moment() },
{ key: 2, value: moment().subtract(1, 'days') },
{ key: 3, value: moment().subtract(2, 'days') },
]
break;
case '近7天':
_arr = [
{key: 1, value: moment()},
{key: 2, value: moment().subtract(1, 'days')},
{key: 3, value: moment().subtract(2, 'days')},
{key: 4, value: moment().subtract(3, 'days')},
{key: 5, value: moment().subtract(4, 'days')},
{key: 6, value: moment().subtract(5, 'days')},
{key: 7, value: moment().subtract(6, 'days')},
{ key: 1, value: moment() },
{ key: 2, value: moment().subtract(1, 'days') },
{ key: 3, value: moment().subtract(2, 'days') },
{ key: 4, value: moment().subtract(3, 'days') },
{ key: 5, value: moment().subtract(4, 'days') },
{ key: 6, value: moment().subtract(5, 'days') },
{ key: 7, value: moment().subtract(6, 'days') },
]
break;
case '近3月':
_arr = [
{key: 1, value: moment()},
{key: 2, value: moment().subtract(1, 'months')},
{key: 3, value: moment().subtract(2, 'months')},
{ key: 1, value: moment() },
{ key: 2, value: moment().subtract(1, 'months') },
{ key: 3, value: moment().subtract(2, 'months') },
]
break;
case '近6月':
_arr = [
{key: 1, value: moment()},
{key: 2, value: moment().subtract(1, 'months')},
{key: 3, value: moment().subtract(2, 'months')},
{key: 4, value: moment().subtract(3, 'months')},
{key: 5, value: moment().subtract(4, 'months')},
{key: 6, value: moment().subtract(5, 'months')},
{ key: 1, value: moment() },
{ key: 2, value: moment().subtract(1, 'months') },
{ key: 3, value: moment().subtract(2, 'months') },
{ key: 4, value: moment().subtract(3, 'months') },
{ key: 5, value: moment().subtract(4, 'months') },
{ key: 6, value: moment().subtract(5, 'months') },
]
break;
}
......@@ -553,7 +561,7 @@ const HistoryView = (props) => {
)}
{timeValue === 'contrast' && ( // 同期对比
<>
<Select value={contrastOption} style={{width: 60}} onChange={onContrastChange}>
<Select value={contrastOption} style={{ width: 60 }} onChange={onContrastChange}>
<Option value="day"></Option>
<Option value="month" disabled={lineDataType === '原始曲线'}></Option>
</Select>
......@@ -578,14 +586,14 @@ const HistoryView = (props) => {
picker={contrastOption === 'day' ? undefined : contrastOption}
value={child.value}
onChange={(date, dateString) => onContrastPickerChange(date, dateString, child)}
style={{width: 130, border: !shortcutsValue ? '1px solid #1890ff' : ''}}
style={{ width: 130, border: !shortcutsValue ? '1px solid #1890ff' : '' }}
/>
{datePickerArr.length > 2 && (
<div
className={classNames(`${prefixCls}-contrast-delete`)}
onClick={() => handleDeleteDatePicker(index)}
>
<CloseCircleFilled/>
<CloseCircleFilled />
</div>
)}
</div>
......@@ -594,7 +602,7 @@ const HistoryView = (props) => {
)}
</div>
))}
{datePickerArr.length < 4 && <PlusCircleOutlined onClick={handleAddDatePicker}/>}
{datePickerArr.length < 4 && <PlusCircleOutlined onClick={handleAddDatePicker} />}
</>
)}
</div>
......@@ -664,12 +672,12 @@ const HistoryView = (props) => {
</Checkbox>
{child.tooltip && (
<Tooltip title={child.tooltip}>
<QuestionCircleFilled className={`${prefixCls}-question`}/>
<QuestionCircleFilled className={`${prefixCls}-question`} />
</Tooltip>
)}
{
child.hasSub && child.checked && false ?
<Select style={{width: 80, marginLeft: 10}} value={algorithmValue}
<Select style={{ width: 80, marginLeft: 10 }} value={algorithmValue}
onChange={(e) => setAlgorithmValue(e)}>
<Option value={1}></Option>
<Option value={5}></Option>
......@@ -685,7 +693,7 @@ const HistoryView = (props) => {
return (
<div
className={classNames(`${prefixCls}-cover`)}
style={isChart && isSingle ? {width: '100%'} : {}}
style={isChart && isSingle ? { width: '100%' } : {}}
>
{
isChart ? <>
......@@ -700,7 +708,7 @@ const HistoryView = (props) => {
</Radio.Group>
{/*<Segmented value={lineDataType} options={['特征曲线', '原始曲线']} onChange={switchLineDataType}/>*/}
<Tooltip title={'原始曲线数据量较大,单次查询最多展示1万条数据'}>
<QuestionCircleFilled style={{marginLeft: 6}} className={`${prefixCls}-question`}/>
<QuestionCircleFilled style={{ marginLeft: 6 }} className={`${prefixCls}-question`} />
</Tooltip>
</div>
</> : ''
......@@ -709,14 +717,14 @@ const HistoryView = (props) => {
<>
{
lineDataType !== '原始曲线' ? <>
<div style={{marginLeft: 7}} className={classNames(`${prefixCls}-label`)}>曲线形态</div>
<div style={{ marginLeft: 7 }} className={classNames(`${prefixCls}-label`)}>曲线形态</div>
<Radio.Group
value={chartType}
style={{marginRight: 16}}
style={{ marginRight: 16 }}
onChange={(e) => {
let _value = e.target.value;
setChartType(_value);
onCheckboxChange({target: {value: _value !== 'boxChart'}}, 'chartType');
onCheckboxChange({ target: { value: _value !== 'boxChart' } }, 'chartType');
}}
>
<Radio.Button value={'lineChart'}>线形图</Radio.Button>
......@@ -743,7 +751,7 @@ const HistoryView = (props) => {
{activeTabKey === 'table' && (
<Select
value={dataThinKey}
style={{width: 90}}
style={{ width: 90 }}
onChange={onTimeIntervalChange}
disabled={!dataConfig.dataThin}
>
......@@ -792,7 +800,7 @@ const HistoryView = (props) => {
// data = data.filter(item => item.sensorName !== '是否在线');
const ignoreOutliers = checkboxData.find((item) => item.key === 'ignoreOutliers').checked;
const dataIndexAccess = (dataItem, index) => {
const {stationCode, sensorName} = dataItem;
const { stationCode, sensorName } = dataItem;
return `${stationCode}-${sensorName}-${index}`;
};
......@@ -800,17 +808,24 @@ const HistoryView = (props) => {
if (timeValue === 'contrast') {
format = contrastOption === 'day' ? '2020-01-01 HH:mm:00' : '2020-01-DD HH:mm:00';
}
// 判断是否是单设备,单设备则不显示设备名称
// 处理表头数据
const columnsData = data.map((item, index) => {
const {stationCode, equipmentName, sensorName, unit, dataModel} = item;
const { stationCode, equipmentName, sensorName, unit, dataModel } = item;
const dataIndex = dataIndexAccess(item, index);
let _title = '';
if (deviceConfig.current.oneDevice) {
_title = `${sensorName}${unit ? `(${unit})` : ''}`;
} else {
_title = `${equipmentName}-${sensorName}${unit ? `(${unit})` : ''}`
}
let col = {
title: `${equipmentName}-${sensorName}${unit ? `(${unit})` : ''}`,
title: _title,
dataIndex: dataIndex,
key: dataIndex,
ellipsis: true,
align: 'center',
width:200
};
// 同期对比
if (timeValue === 'contrast' && dataModel[0]) {
......@@ -825,7 +840,7 @@ const HistoryView = (props) => {
// 格式化时间对齐数据, 生成行数
const timeData = {};
const buildDefaultData = (time) => {
const obj = {key: time, time: time};
const obj = { key: time, time: time };
data.forEach((item, index) => {
const dataIndex = dataIndexAccess(item, index);
obj[dataIndex] = '';
......@@ -833,7 +848,7 @@ const HistoryView = (props) => {
return obj;
};
data.forEach((item, index) => {
const {stationCode, sensorName, dataModel} = item;
const { stationCode, sensorName, dataModel } = item;
dataModel &&
dataModel.forEach((data) => {
const formatTime = moment(data.pt).format(format);
......@@ -849,7 +864,7 @@ const HistoryView = (props) => {
// 处理表格数据
data.forEach((child, index) => {
const {dataModel} = child;
const { dataModel } = child;
const dataIndex = dataIndexAccess(child, index);
dataModel &&
dataModel.forEach((value, j) => {
......@@ -898,40 +913,40 @@ const HistoryView = (props) => {
};
const handleDataThinKey = (diffYears, diffDays, diffHours, lineDataType) => {
if (lineDataType === '原始曲线') {
return {unit: '', zoom: ''}
return { unit: '', zoom: '' }
}
// edit by zy 根据选择的时长控制抽稀频度
if (diffYears > 0) {
if (diffYears === 1) return {unit: 'h', zoom: '24'}
return {unit: 'h', zoom: '48'}
if (diffYears === 1) return { unit: 'h', zoom: '24' }
return { unit: 'h', zoom: '48' }
} else if (diffYears === 0 && diffDays > 0) {
if (diffDays > 90) return {unit: 'h', zoom: '24'}
if (diffDays > 30) return {unit: 'h', zoom: '6'}
if (diffDays > 15) return {unit: 'h', zoom: '4'}
if (diffDays > 7) return {unit: 'h', zoom: '1'}
if (diffDays > 3) return {unit: 'min', zoom: '30'}
if (diffDays > 1) return {unit: 'min', zoom: '15'}
if (diffDays === 1) return {unit: 'min', zoom: '5'}
if (diffDays > 90) return { unit: 'h', zoom: '24' }
if (diffDays > 30) return { unit: 'h', zoom: '6' }
if (diffDays > 15) return { unit: 'h', zoom: '4' }
if (diffDays > 7) return { unit: 'h', zoom: '1' }
if (diffDays > 3) return { unit: 'min', zoom: '30' }
if (diffDays > 1) return { unit: 'min', zoom: '15' }
if (diffDays === 1) return { unit: 'min', zoom: '5' }
} else if (diffYears === 0 && diffDays === 0 && diffHours > 0) {
if (diffHours > 12) return {unit: 'min', zoom: '5'}
if (diffHours > 4) return {unit: 'min', zoom: '1'}
if (diffHours > 1) return {unit: 's', zoom: '30'}
if (diffHours > 0) return {unit: 's', zoom: '5'}
return {unit: 's', zoom: '5'}
if (diffHours > 12) return { unit: 'min', zoom: '5' }
if (diffHours > 4) return { unit: 'min', zoom: '1' }
if (diffHours > 1) return { unit: 's', zoom: '30' }
if (diffHours > 0) return { unit: 's', zoom: '5' }
return { unit: 's', zoom: '5' }
} else {
return {unit: '', zoom: ''}
return { unit: '', zoom: '' }
}
};
// 处理接口服务参数的变化
const onChangeParams = (value = {}) => {
const {dateRange, isDilute, ignoreOutliers, zoom, unit} = value;
const { dateRange, isDilute, ignoreOutliers, zoom, unit } = value;
const requestArr = [];
const acrossTables = [];
const zoomArray = [];
deviceParams
.map((item) => {
let _item = {...item};
let _item = { ...item };
// 历史曲线中,是否在线暂时去除,不显示 要显示是否在线解开这里即可 2023-09-15
/* _item.sensors =
item.sensors && !item.sensors.includes('是否在线')
......@@ -971,7 +986,7 @@ const HistoryView = (props) => {
let diffHours = moment(item.dateTo).diff(moment(item.dateFrom), 'hours');
let zoomParam = activeTabKey === 'curve' ? handleDataThinKey(diffYears, diffDays, diffHours, lineDataType) : {};
zoomArray.push(zoomParam);
requestArr.push(getHistoryInfo({...param, ...zoomParam}));
requestArr.push(getHistoryInfo({ ...param, ...zoomParam }));
});
setLoading(true);
Promise.all(requestArr).then((results) => {
......@@ -979,7 +994,7 @@ const HistoryView = (props) => {
if (results.length) {
let data = [];
results.forEach((res, index) => {
const {dateFrom, dateTo} = dateRange?.[index] ?? {};
const { dateFrom, dateTo } = dateRange?.[index] ?? {};
if (res.code === 0 && res.data.length) {
res.data.forEach((d) => {
d.dateFrom = dateFrom || '';
......@@ -1022,7 +1037,7 @@ const HistoryView = (props) => {
useEffect(() => {
if (!completeInit) return;
const {dataThin, ignoreOutliers, zoom, unit} = dataConfig;
const { dataThin, ignoreOutliers, zoom, unit } = dataConfig;
beforChangeParams().finally(() => {
onChangeParams({
isDilute: dataThin,
......@@ -1067,9 +1082,10 @@ const HistoryView = (props) => {
{...tableProps}
pagination={false}
onChange={handleChange}
scroll={{x:'max-content',y:'calc(100% - 40px)'}}
/>
) : (
<PandaEmpty/>
<PandaEmpty />
)}
</div>
</>
......@@ -1107,11 +1123,11 @@ const HistoryView = (props) => {
</div>
{
lineDataType === '原始曲线' && false ?
<div style={{marginTop: 10}}>展示区间:{returnLongestPeriod(chartDataSource)}</div> : ''
<div style={{ marginTop: 10 }}>展示区间:{returnLongestPeriod(chartDataSource)}</div> : ''
}
<div className={`${prefixCls}-content`}>
{!chartDataSource.length ? (
<PandaEmpty/>
<PandaEmpty />
) : grid === true ? (
<GridChart
curveCenter={curveCenter}
......@@ -1129,7 +1145,6 @@ const HistoryView = (props) => {
showGridLine={chartGrid}
prefixCls={prefixCls}
dataSource={chartDataSource}
// justLine={!!checkboxData.find(item => item.key === 'justLine' && item.checked)}
chartType={isBoxPlots ? chartType : null}
contrast={timeValue === 'contrast'}
contrastOption={contrastOption}
......@@ -1152,7 +1167,7 @@ const HistoryView = (props) => {
// 非单曲线、单指标不执行
if (deviceParams?.length !== 1 || (deviceParams?.length === 1 && deviceParams?.[0]?.sensors?.split(',')?.length > 1)) return setCompleteInit(true);
setLoading(true);
const {deviceCode, deviceType, sensors} = deviceParams[0];
const { deviceCode, deviceType, sensors } = deviceParams[0];
let _id = (await getPointAddress({
code: deviceCode
}))?.data?.[0]?.id;
......@@ -1176,7 +1191,7 @@ const HistoryView = (props) => {
return final
}, {});
let _checkboxData = [...checkboxData].map(item => {
let _item = {...item};
let _item = { ...item };
if (_opt[item.label] !== undefined) {
_item.checked = _opt[item.label] === 'true'
}
......@@ -1190,7 +1205,7 @@ const HistoryView = (props) => {
let _statusName = _sensorConfig?.statusName;
if (_statusName) {
let _statusConfig = _res1.data.find(item => item?.name.trim() === _statusName.trim());
let _valDesc = _statusConfig?.valDesc||'';
let _valDesc = _statusConfig?.valDesc || '';
setSpecial1({
name: _statusName,
valDesc: _valDesc.split(';').reduce((final, cur) => {
......@@ -1230,7 +1245,7 @@ const HistoryView = (props) => {
}, [loading])
return (
<div className={classNames(prefixCls, 'wkt-scroll-light')}>
<div className={classNames(`${prefixCls}-spin`)} style={{position: "relative"}}>
<div className={classNames(`${prefixCls}-spin`)} style={{ position: "relative" }}>
{
(loading || percent !== 0) ? <div className={classNames(`${prefixCls}-progressWrapper`)}>
<div className={classNames(`${prefixCls}-contentWrapper`)}>
......@@ -1239,9 +1254,9 @@ const HistoryView = (props) => {
<Progress percent={percent}
steps={20}
className={classNames(`${prefixCls}-progress`, `${prefixCls}-blink-2`)}
showInfo={false}/>
showInfo={false} />
<div className={classNames(`${prefixCls}-tip`)}>加载中...</div>
</> : <Spin spinning={loading || false}/>
</> : <Spin spinning={loading || false} />
}
</div>
......@@ -1261,7 +1276,7 @@ const HistoryView = (props) => {
<div className={`${prefixCls}-extra-right`}>
{activeTabKey === 'table' && (
<Button type="link" onClick={exportExcelBtn}>
<DownloadOutlined/>
<DownloadOutlined />
下载
</Button>
)}
......
import moment from 'moment';
import _, {isArray} from 'lodash';
import _, { isArray } from 'lodash';
import maxIcon from './assets/最大实心.svg';
import minIcon from './assets/最小实心.svg';
import minIconDownArrow from './assets/最小实心箭头朝下.svg';
import lineChart from "@wisdom-components/basicchart/es/LineChart";
import lineChart from '@wisdom-components/basicchart/es/LineChart';
import { offset } from 'highcharts';
/** 轴宽度, 用于计算多轴显示时, 轴线偏移和绘图区域尺寸 */
const AXIS_WIDTH = 40;
......@@ -20,11 +21,7 @@ const COLOR = {
const isMobile = () => {
const userAgent = navigator.userAgent.toLowerCase();
if (
/ipad|iphone|midp|rv:1.2.3.4|ucweb|android|windows ce|windows mobile/.test(
userAgent
)
) {
if (/ipad|iphone|midp|rv:1.2.3.4|ucweb|android|windows ce|windows mobile/.test(userAgent)) {
return true;
}
return false;
......@@ -41,28 +38,26 @@ const PC_OPTION = {
padding: [2, 12],
lineHeight: 22,
backgroundColor:
window.globalConfig &&
window.globalConfig &&
window.globalConfig.variableTheme?.primaryColor
window.globalConfig && window.globalConfig && window.globalConfig.variableTheme?.primaryColor
? window.globalConfig.variableTheme.primaryColor
: '#0087F7',
borderWidth: 1
borderWidth: 1,
},
fontSize: 16,
fontColor: "#ffffff",
dataZoomHeight: 28
}
fontColor: '#ffffff',
dataZoomHeight: 28,
};
const MOBILE_OPTION = {
markPoint: {
padding: [2, 6],
lineHeight: 18,
backgroundColor: 'rgba(255,255,255,0.6)',
borderWidth: 0
borderWidth: 0,
},
fontSize: handlePx(12),
fontColor: "#0087F7",
dataZoomHeight: 20
}
fontColor: '#0087F7',
dataZoomHeight: 20,
};
const currentOption = isMobile() ? MOBILE_OPTION : PC_OPTION;
/**
* 图表系列名称格式化
......@@ -73,7 +68,7 @@ const currentOption = isMobile() ? MOBILE_OPTION : PC_OPTION;
* @returns
*/
const nameFormatter = (data, contrast, contrastOption, nameWithSensor) => {
const {equipmentName, sensorName, unit, dataModel, dateFrom, dateTo} = data;
const { equipmentName, sensorName, unit, dataModel, dateFrom, dateTo } = data;
let name = nameWithSensor ? `${equipmentName}-${sensorName}` : equipmentName;
if (contrast) {
const time = dateFrom.slice(0, contrastOption === 'day' ? 10 : 7).replace(/-/g, '');
......@@ -108,7 +103,7 @@ const dataAccessor = (data, contrast, contrastOption) => {
* @returns Null/areaStyle, 为null显示曲线图, 为areaStyle对象显示为面积图.
*/
const areaStyleFormatter = (data) => {
const {sensorName} = data;
const { sensorName } = data;
return sensorName && sensorName.indexOf('流量') > -1 ? {} : null;
};
......@@ -119,7 +114,7 @@ const areaStyleFormatter = (data) => {
* @returns
*/
const minMax = (data) => {
const {dataModel} = data;
const { dataModel } = data;
let min = Number.MAX_SAFE_INTEGER;
let max = Number.MIN_SAFE_INTEGER;
dataModel.forEach((item) => {
......@@ -150,7 +145,7 @@ const markLineItem = (name, value, color) => {
export const alarmMarkLine = (dataItem, index, dataSource, schemes) => {
// 只有一个数据曲线时显示markline
if (!dataItem || !schemes || dataSource.length !== 1) return {};
const {deviceType, stationCode, sensorName, decimalPoint} = dataItem;
const { deviceType, stationCode, sensorName, decimalPoint } = dataItem;
const curSchemes = schemes.filter(
(item) =>
item.deviceCode === stationCode &&
......@@ -159,7 +154,7 @@ export const alarmMarkLine = (dataItem, index, dataSource, schemes) => {
);
const data = [];
curSchemes.forEach((scheme) => {
const {hLimit, hhLimit, lLimit, llLimit} = scheme;
const { hLimit, hhLimit, lLimit, llLimit } = scheme;
lLimit !== null && lLimit !== void 0 && data.push(markLineItem('低限', lLimit, '#fa8c16'));
hLimit !== null && hLimit !== void 0 && data.push(markLineItem('高限', hLimit, '#fa8c16'));
llLimit !== null && llLimit !== void 0 && data.push(markLineItem('低低限', llLimit, '#FF0000'));
......@@ -204,11 +199,11 @@ export const minMaxMarkPoint = (dataItem, index, dataSource) => {
name: '最大: ',
symbol: `image://${maxIcon}`,
symbolOffset: [0, -16],
}
},
];
return {
label: {
show: false
show: false,
},
symbolSize: [49, 31],
data,
......@@ -251,7 +246,7 @@ export const decorateAxisGridLine = (axis, showGrid) => {
*/
export const offlineArea = (dataItem) => {
if (!dataItem) return {};
const {dataModel} = dataItem;
const { dataModel } = dataItem;
let datas = new Array();
let offlineData = [];
let hasOffline = false;
......@@ -261,7 +256,7 @@ export const offlineArea = (dataItem) => {
{
name: '离线',
xAxis: new Date(item.pt),
label: {show: !datas?.length}
label: { show: !datas?.length },
},
];
hasOffline = true;
......@@ -284,7 +279,7 @@ export const offlineArea = (dataItem) => {
};
// 生成默认legend配置
export const buildDefaultLegend = (option) => {
const {title} = option;
const { title } = option;
let paddingRight = 0;
if (title && title.show) paddingRight = 80; // 给标题留够空间
......@@ -307,50 +302,74 @@ export const buildDefaultLegend = (option) => {
// tooltip 模板
const headTemplate = (param, opt) => {
if (!param) return '';
const {name, axisValueLabel, axisType, axisValue} = param;
const timeFormat = opt && opt.contrast ? (opt.contrastOption === 'day' ? 'HH:mm:ss' : 'DD日HH时') : 'YYYY-MM-DD HH:mm:ss';
const { name, axisValueLabel, axisType, axisValue } = param;
const timeFormat =
opt && opt.contrast
? opt.contrastOption === 'day'
? 'HH:mm:ss'
: 'DD日HH时'
: 'YYYY-MM-DD HH:mm:ss';
const text =
axisType === 'xAxis.time' ? moment(axisValue).format(timeFormat) : name || axisValueLabel;
return `<div style="border-bottom: 1px solid #F0F0F0; color: #808080; margin-bottom:${handlePx(5, 'px')}; padding-bottom: ${handlePx(5, 'px')};">${text}</div>`;
return `<div style="border-bottom: 1px solid #F0F0F0; color: #808080; margin-bottom:${handlePx(
5,
'px',
)}; padding-bottom: ${handlePx(5, 'px')};">${text}</div>`;
};
const seriesTemplate = (param, unit) => {
if (!param || param.seriesName === '自定义') return '';
const {value, encode} = param;
const { value, encode } = param;
// const val = value[encode.y[0]];
const _unit = unit || '';
const color = '#008CFF';
if (!isArray(value))
return ` <div style="display: flex; align-items: center;">
<span style="${isMobile() ? 'width: ' + handlePx(90, 'px') + ';overflow:hidden;text-overflow:ellipsis;white-space:nowrap' : ''}">${param.seriesName}</span>
<span style="${isMobile()
? 'width: ' +
handlePx(90, 'px') +
';overflow:hidden;text-overflow:ellipsis;white-space:nowrap'
: ''
}">${param.seriesName}</span>
<span style="display:inline-block;">:</span>
<span style="color:${color};margin: 0 ${handlePx(5, 'px')} 0 auto;">${value?.toFixed(3) ?? '-'}</span>
<span style="color:${color};margin: 0 ${handlePx(5, 'px')} 0 auto;">${value?.toFixed(3) ?? '-'
}</span>
<span style="font-size: ${handlePx(12, 'px')};">${_unit ?? ''}</span>
</div>`;
return param.componentSubType !== 'candlestick'
? `<div style="display: flex; align-items: center;">
<span style="${isMobile() ? 'width: ' + handlePx(90, 'px') + ';overflow:hidden;text-overflow:ellipsis;white-space:nowrap' : ''}">${param.seriesName}</span><span style="display:inline-block;">:</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${value[1] ?? '-'}</span>
<span style="${isMobile()
? 'width: ' +
handlePx(90, 'px') +
';overflow:hidden;text-overflow:ellipsis;white-space:nowrap'
: ''
}">${param.seriesName}</span><span style="display:inline-block;">:</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${value[1] ?? '-'
}</span>
<span style="font-size: ${handlePx(12, 'px')};">${_unit ?? ''}</span>
</div>`
: `
<div style="display: flex; align-items: center;">
<span>首值</span><span style="display:inline-block;">:</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${value[1] ?? '-'}</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${value[1] ?? '-'
}</span>
<span style="font-size: ${handlePx(12, 'px')};">${_unit ?? ''}</span>
</div>
<div style="display: flex; align-items: center;">
<span>尾值</span><span style="display:inline-block;">:</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${value[2] ?? '-'}</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${value[2] ?? '-'
}</span>
<span style="font-size: ${handlePx(12, 'px')};">${_unit ?? ''}</span>
</div>
<div style="display: flex; align-items: center;">
<span>周期最小值</span><span style="display:inline-block;">:</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${value[3] ?? '-'}</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${value[3] ?? '-'
}</span>
<span style="font-size: ${handlePx(12, 'px')};">${_unit ?? ''}</span>
</div>
<div style="display: flex; align-items: center;">
<span>周期最大值</span><span style="display:inline-block;">:</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${value[4] ?? '-'}</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${value[4] ?? '-'
}</span>
<span style="font-size: ${handlePx(12, 'px')};">${_unit ?? ''}</span>
</div>
`;
......@@ -386,13 +405,15 @@ const handleSpecial1 = (special, dataSource) => {
工频: '#00d0c7',
运行: '#1685ff',
故障: '#ff6b37',
停止: '#666666'
停止: '#666666',
};
let _special1 = special?.special1 ?? {};
let _valDesc = _special1?.valDesc ?? {};
let _data = dataSource.find(item => item.sensorName === _special1.name);
let _data = dataSource.find((item) => item.sensorName === _special1.name);
let _markAreaData = [];
let _pieces = _data?.dataModel?.reduce((final, cur, index) => {
let _pieces =
_data?.dataModel
?.reduce((final, cur, index) => {
let _pt = moment(cur.pt).valueOf();
let _length = final.length;
if (_colorMap[_valDesc[cur.pv]]) {
......@@ -402,7 +423,7 @@ const handleSpecial1 = (special, dataSource) => {
gte: 0,
color: _colorMap[_valDesc[cur.pv]],
value: cur.pv,
text: _valDesc[cur.pv]
text: _valDesc[cur.pv],
});
} else {
if (cur.pv === final[_length - 1].value) {
......@@ -413,16 +434,15 @@ const handleSpecial1 = (special, dataSource) => {
gte: _pt,
color: _colorMap[_valDesc[cur.pv]],
value: cur.pv,
text: _valDesc[cur.pv]
text: _valDesc[cur.pv],
});
}
}
}
return final;
}, [])
.map(item => {
_markAreaData.push(
[
.map((item) => {
_markAreaData.push([
{
xAxis: item.gte,
itemStyle: {
......@@ -433,28 +453,32 @@ const handleSpecial1 = (special, dataSource) => {
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: item.color // 0% 处的颜色
}, {
offset: 1, color: item.color// 100% 处的颜色
}],
global: false // 缺省为 false
}
colorStops: [
{
offset: 0,
color: item.color, // 0% 处的颜色
},
{
offset: 1,
color: item.color, // 100% 处的颜色
},
],
global: false, // 缺省为 false
},
},
name: item.text,
label: {show: true}
label: { show: true },
},
{
xAxis: item.lte,
itemStyle: {
color: item.color
}
}
]
)
color: item.color,
},
},
]);
delete item.value;
return item;
})??[];
}) ?? [];
let _final = {};
if (_markAreaData.length) {
_final.visualMap = {
......@@ -463,16 +487,16 @@ const handleSpecial1 = (special, dataSource) => {
dimension: 0,
seriesIndex: 0,
pieces: _pieces,
}
};
}
if (_pieces.length) {
_final.markArea = {
silent: true,
itemStyle: {
opacity: 0.1
opacity: 0.1,
},
data: _markAreaData
}
data: _markAreaData,
};
}
return _final;
};
......@@ -487,18 +511,18 @@ const returnXAxis = ({
showPoint,
restOption,
smooth,
special
}) => {
special,
}) => {
// 根据"指标名称"分类yAxis
const yAxisInterator = (() => {
const map = new Map();
let current = -1;
const get = (name) => (map.has(name) ? map.get(name) : map.set(name, ++current).get(name));
return {get};
return { get };
})();
let _offlineData = [];
// 生成visualMap、markArea
let {visualMap, markArea} = handleSpecial1(special, dataSource);
let { visualMap, markArea } = handleSpecial1(special, dataSource);
let _filterArr = ['是否在线'];
if (special?.special1?.name) {
_filterArr.push(special.special1.name);
......@@ -512,7 +536,7 @@ const returnXAxis = ({
return !_filterArr.includes(item.sensorName);
})
.map((item, index) => {
const {sensorName, unit} = item;
const { sensorName, unit } = item;
const name = nameFormatter(item, contrast, contrastOption, nameWithSensor);
const data = dataAccessor(item, contrast, contrastOption);
const type = 'line';
......@@ -558,20 +582,29 @@ const returnXAxis = ({
);
return {
xAxis: {
type: 'time', min, max, axisLabel: {
formatter: contrast ? (contrastOption === 'month' ? '{dd}日' : '{HH}:{mm}') : {
type: 'time',
min,
max,
axisLabel: {
formatter: contrast
? contrastOption === 'month'
? '{dd}日'
: '{HH}:{mm}'
: {
year: '{yyyy}',
month: '{MMM}',
day: '{d}日',
hour: '{HH}:{mm}',
minute: '{HH}:{mm}',
second: '{HH}:{mm}:{ss}',
none: '{yyyy}-{MM}-{dd} {hh}:{mm}:{ss}'
}
}
}, series, visualMap
none: '{yyyy}-{MM}-{dd} {hh}:{mm}:{ss}',
},
},
},
series,
visualMap,
};
}
};
const handleDefault = (config, cusOption) => {
const needUnit = _.get(config, 'needUnit', false);
const curveCenter = _.get(config, 'curveCenter', false);
......@@ -597,25 +630,44 @@ const handleDefault = (config, cusOption) => {
chartType,
showBoxOption,
restOption,
special
}
special,
};
};
const handleMaxValue = (value) => {
if (value <= 1) return value;
if (value >= 10000) return `${(value / 1000).toFixed(0)}k`;
return value.toFixed(0);
}
const handleYAxis = ({dataSource, needUnit, curveCenter, showGridLine}) => {
const handleYAxis = ({ dataSource, needUnit, curveCenter, showGridLine }) => {
// 一种指标一个y轴
const yAxisMap = new Map();
// 1. 找出最大值; 2. 计算出y轴最大宽度动态计算偏移距离;
let _maxValueArray = [];
let _offsetValue = [];
dataSource.forEach((item, index) => {
const {sensorName, unit} = item;
let _maxValue = item.dataModel.reduce((final, cur) => {
if (cur.pv > final) final = cur.pv;
return final
}, 0);
_maxValueArray.push(handleMaxValue(_maxValue));
const { sensorName, unit } = item;
const key = sensorName;
if (!yAxisMap.has(key)) {
const i = yAxisMap.size;
let _offset = _maxValueArray[i - 2];
let _baseOffset = _offsetValue[i - 2] ?? 0;
let _finalOffset = (_offset !== undefined ? (_offset === 0 ? 2 : _offset.toString().replaceAll('.','').length) * 10 : 0) + _baseOffset;
_offsetValue.push(_finalOffset);
const axis = {
type: 'value',
name: needUnit ? unit : null,
position: i % 2 === 0 ? 'left' : 'right',
offset: Math.floor(i / 2) * 80,
// offset: _offset !== undefined ? (_offset === 0? 2:_offset.toString().length) * 10 : 0,
offset: _finalOffset,
axisLabel: {
formatter: (value) => (value > 10000 ? `${(value / 1000).toFixed(1)}k` : value.toFixed(1)),
formatter: (value) => {
return handleMaxValue(value);
}
},
axisLine: {
show: true,
......@@ -650,13 +702,13 @@ const handleYAxis = ({dataSource, needUnit, curveCenter, showGridLine}) => {
const axis = yAxisMap.get(key);
decorateAxisGridLine(axis, showGridLine);
});
const yAxis = yAxisMap.size > 0 ? [...yAxisMap.values()] : {type: 'value'};
const yAxis = yAxisMap.size > 0 ? [...yAxisMap.values()] : { type: 'value' };
// 根据y轴个数调整边距
const leftNum = Math.ceil(yAxisMap.size / 2);
const rightNum = Math.floor(yAxisMap.size / 2);
return {leftNum, rightNum, yAxis};
}
return { leftNum, rightNum, yAxis };
};
const assignOptions = (restOption, xAxis, legendData, chartType, contrast, contrastOption) => {
restOption.dataZoom = [
{
......@@ -667,7 +719,7 @@ const assignOptions = (restOption, xAxis, legendData, chartType, contrast, contr
height: currentOption['dataZoomHeight'],
type: 'inside',
zoomOnMouseWheel: true,
filterMode: chartType === 'lineChart' ? 'none' : 'weakFilter'
filterMode: chartType === 'lineChart' ? 'none' : 'weakFilter',
},
{
show: true,
......@@ -683,13 +735,13 @@ const assignOptions = (restOption, xAxis, legendData, chartType, contrast, contr
if (contrastOption === 'day') _formatterStr = 'HH:mm';
if (contrastOption === 'month') _formatterStr = 'MM月DD日 HH时';
}
return moment(e).format(_formatterStr)
}
return moment(e).format(_formatterStr);
},
},
];
xAxis.minInterval = 3600 * (1 * 1000);
if (legendData) {
restOption.legend = {...buildDefaultLegend({}), ...{data: legendData}};
restOption.legend = { ...buildDefaultLegend({}), ...{ data: legendData } };
}
};
......@@ -699,20 +751,22 @@ const returnMaxOrMinNumber = (dataSource, type) => {
let _length = dataSource?.[0]?.dataModel?.length;
let _first = dataSource?.[0]?.dataModel[0]?.pt;
let _last = dataSource?.[0]?.dataModel[_length - 1]?.pt;
return ['展示时段: ', _first, _last, type]
return ['展示时段: ', _first, _last, type];
}
dataSource?.[0]?.dataModel.filter(item => item.pv !== null).forEach(item => {
dataSource?.[0]?.dataModel
.filter((item) => item.pv !== null)
.forEach((item) => {
if (!_obj) {
_obj = item;
} else {
if (type === 'min') {
if (item.pv < _obj.pv) {
_obj = item
_obj = item;
}
}
if (type === 'max') {
if (item.pv > _obj.pv) {
_obj = item
_obj = item;
}
}
}
......@@ -734,16 +788,20 @@ const handleGrid = (dataSource, needUnit, leftNum, rightNum, chartType) => {
let _topForUnit = needUnit ? 20 : 0;
return {
top: _base + _topForUnit,
left: leftNum === 1 ? 10 : leftNum * AXIS_WIDTH,
right: rightNum === 0 ? 20 : rightNum * AXIS_WIDTH,
// left: leftNum === 1 ? 10 : leftNum * AXIS_WIDTH,
left: 10,
// right: rightNum === 0 ? 20 : rightNum * AXIS_WIDTH,
bottom: 60,
containLabel: true
containLabel: true,
};
};
const renderItem = (params, api) => {
let _base = params.dataIndex;
let _baseChartWidth = 10;
let _numberStringWidth = _base === 1 && api.value(3) === 'max' ? String(api.value(4) || 0).length * _baseChartWidth : String(api.value(1)).length * _baseChartWidth;
let _numberStringWidth =
_base === 1 && api.value(3) === 'max'
? String(api.value(4) || 0).length * _baseChartWidth
: String(api.value(1)).length * _baseChartWidth;
let _left = 30;
let _baseWidth = 190 + _numberStringWidth;
let _imgWidth = 45;
......@@ -762,15 +820,15 @@ const renderItem = (params, api) => {
style: {
image: api.value(2),
textVerticalAlign: 'middle',
y: -6
y: -6,
},
position: [_imageX, topValue]
position: [_imageX, topValue],
},
{
type: 'text',
style: {
text: moment(api.value(0)).format('YYYY-MM-DD HH:mm:ss') + ': ',
textVerticalAlign: 'top'
textVerticalAlign: 'top',
},
position: [_timeX, topValue + _trimmer],
},
......@@ -782,12 +840,12 @@ const renderItem = (params, api) => {
fill: _color,
font: 'bolder 16px cursive',
lineWidth: 10,
y: 3
y: 3,
},
position: [_valueX, topValue + _trimmer]
}
]
}
position: [_valueX, topValue + _trimmer],
},
],
};
};
const returnCustomSeries = (dataSource) => {
let _maxNumber = returnMaxOrMinNumber(dataSource, 'max');
......@@ -796,16 +854,16 @@ const returnCustomSeries = (dataSource) => {
// 需要将最大值最小分别传入,后续计算图例位置需要,先min后max
let _max = _maxNumber[1];
let _min = _minNumber[1];
[_maxNumber, _minNumber].forEach(item => {
[_maxNumber, _minNumber].forEach((item) => {
item.push(_min);
item.push(_max);
})
});
return {
name: '自定义',
type: 'custom',
renderItem: renderItem,
data: [_minNumber, _maxNumber],
}
};
};
/**
* 图表配置项生成
......@@ -818,7 +876,15 @@ const returnCustomSeries = (dataSource) => {
* @param {any} config 额外配置信息
*/
const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth, config, lineDataType = '') => {
const optionGenerator = (
dataSource,
cusOption,
contrast,
contrastOption,
smooth,
config,
lineDataType = '',
) => {
const {
needUnit,
curveCenter,
......@@ -830,11 +896,16 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
chartType,
showBoxOption,
restOption,
special
special,
} = handleDefault(config, cusOption);
const {leftNum, rightNum, yAxis} = handleYAxis({dataSource, needUnit, curveCenter, showGridLine});
const { leftNum, rightNum, yAxis } = handleYAxis({
dataSource,
needUnit,
curveCenter,
showGridLine,
});
const grid = handleGrid(dataSource, needUnit, leftNum, rightNum, chartType);
let {xAxis, series, visualMap} = returnXAxis({
let { xAxis, series, visualMap } = returnXAxis({
dataSource,
contrast,
contrastOption,
......@@ -844,7 +915,7 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
showPoint,
smooth,
restOption,
special
special,
});
decorateAxisGridLine(xAxis, showGridLine);
const tooltipTimeFormat = !contrast
......@@ -858,16 +929,16 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
if (chartType === 'boxChart' && lineDataType === '特征曲线') {
const otherData =
dataSource?.[0]?.dataModel.map((item) => {
const {firstPV, lastPV, maxPV, minPV, pt} = item;
const { firstPV, lastPV, maxPV, minPV, pt } = item;
return [moment(pt).valueOf(), firstPV, lastPV, minPV, maxPV];
}) || []; //当存在othersData的时候,只是单曲线
xAxis = {type: 'time'};
xAxis = { type: 'time' };
decorateAxisGridLine(xAxis, showGridLine);
let unit = [];
series = series.map((item) => {
if (item.unit) unit.push(item.unit);
item.areaStyle = null;
return {...item, showSymbol: false};
return { ...item, showSymbol: false };
});
series.push({
type: 'candlestick',
......@@ -898,20 +969,23 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
* 2. 当最大值小于零时(此时,最小值一定小于零);
*/
dataSource?.[0]?.dataModel.forEach((item) => {
const {firstPV, lastPV, maxPV, minPV, pt} = item;
const { firstPV, lastPV, maxPV, minPV, pt } = item;
_maxValues.push(maxPV);
let time = contrast ? moment(pt).format(formatStr) : pt;
_maxData.push([moment(time).valueOf(), (maxPV > 0 ? maxPV - minPV : minPV - maxPV).toFixed(2)]);
_maxData.push([
moment(time).valueOf(),
(maxPV > 0 ? maxPV - minPV : minPV - maxPV).toFixed(2),
]);
_minData.push([moment(time).valueOf(), maxPV > 0 ? minPV : maxPV]);
}); //当存在othersData的时候,只是单曲线
// xAxis = {type: 'category', data: series[0].data.map(item => moment(item[0]).format('YYYY-MM-DD HH:mm:ss'))};
xAxis = {type: 'time'};
xAxis = { type: 'time' };
decorateAxisGridLine(xAxis, showGridLine);
let _unit = '';
series = series.map((item) => {
_unit = item.unit ?? '';
item.areaStyle = null;
return {...item, showSymbol: false};
return { ...item, showSymbol: false };
});
[[..._minData], [..._maxData]].forEach((item, index) => {
series.push({
......@@ -940,22 +1014,35 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
${headTemplate(e[0])}
<div>
<div style="display: flex; align-items: center;">
<span style="${isMobile() ? 'width: ' + handlePx(90, 'px') + ';overflow:hidden;text-overflow:ellipsis;white-space:nowrap' : ''}">${e[0].seriesName
<span style="${isMobile()
? 'width: ' +
handlePx(90, 'px') +
';overflow:hidden;text-overflow:ellipsis;white-space:nowrap'
: ''
}">${e[0].seriesName
}</span><span style="display:inline-block;">:</span>
<span style="color: ${COLOR.NORMAL};margin: 0 ${handlePx(5, 'px')} 0 auto;">${e[0]?.value?.[1] ?? '-'
}</span>
<span style="color: ${COLOR.NORMAL};margin: 0 ${handlePx(
5,
'px',
)} 0 auto;">${e[0]?.value?.[1] ?? '-'}</span>
<span style="font-size: ${handlePx(12, 'px')};">${_unit ?? ''}</span>
</div>
<div style="display: ${lineDataType === '特征曲线' ? 'flex' : 'none'}; align-items: center;">
<div style="display: ${lineDataType === '特征曲线' ? 'flex' : 'none'
}; align-items: center;">
<span>周期最小值</span><span style="display:inline-block;">:</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${e?.[1]?.value?.[1] ?? '-'
}</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(
5,
'px',
)} 0 auto;">${e?.[1]?.value?.[1] ?? '-'}</span>
<span style="font-size: ${handlePx(12, 'px')};">${_unit ?? ''}</span>
</div>
<div style="display: ${lineDataType === '特征曲线' ? 'flex' : 'none'}; align-items: center;">
<div style="display: ${lineDataType === '特征曲线' ? 'flex' : 'none'
}; align-items: center;">
<span>周期最大值</span><span style="display:inline-block;">:</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${_maxValues[e?.[2]?.dataIndex] ?? '-'
}</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(
5,
'px',
)} 0 auto;">${_maxValues[e?.[2]?.dataIndex] ?? '-'}</span>
<span style="font-size: ${handlePx(12, 'px')};">${_unit ?? ''}</span>
</div>
</div>
......@@ -966,13 +1053,18 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
// 单曲线需要标记最大值、最小值的情况下,需要增加自定义的series,将最大最小值显示在图表上
if (dataSource?.[0]?.dataModel?.length && chartType === 'lineChart') {
let _customSeries = returnCustomSeries(dataSource);
series.push(_customSeries)
series.push(_customSeries);
}
} else {
tooltip = tooltipAccessor(series.map(item => item.unit), {contrastOption, contrast});
tooltip = tooltipAccessor(
series.map((item) => item.unit),
{ contrastOption, contrast },
);
}
tooltip.timeFormat = tooltipTimeFormat;
let _legendData = series.filter(item => !['周期最大值', '周期最小值', '自定义'].includes(item.name)).map(item => item.name);
let _legendData = series
.filter((item) => !['周期最大值', '周期最小值', '自定义'].includes(item.name))
.map((item) => item.name);
assignOptions(restOption, xAxis, _legendData, chartType, contrast, contrastOption);
let _options = {
yAxis,
......@@ -983,7 +1075,7 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
visualMap,
...restOption,
};
return _options
return _options;
};
export default optionGenerator;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment