Commit 3f662052 authored by 陈龙's avatar 陈龙

feat: 完善移动端适配

parent 6a5da773
......@@ -146,6 +146,7 @@
},
"dependencies": {
"@babel/plugin-proposal-private-methods": "^7.18.6",
"@wisdom-components/VmsVideo": "1.1.13",
"@wisdom-components/basictable": "^1.5.14",
"@wisdom-components/ec_historyview": "^1.4.3",
"@wisdom-components/empty": "^1.3.9",
......@@ -153,8 +154,8 @@
"@wisdom-components/loadbox": "1.1.4",
"@wisdom-components/timerangepicker": "^1.3.4",
"@wisdom-components/videoslidermodal": "1.1.2",
"@wisdom-components/VmsVideo": "1.1.13",
"@wisdom-utils/utils": "0.0.46",
"antd-mobile": "5.10.4",
"classnames": "^2.2.6",
"cross-spawn": "^7.0.3",
"echarts": "^5.4.0",
......
......@@ -32,6 +32,7 @@
"test": "echo \"Error: run tests from root\" && exit 1"
},
"dependencies": {
"@babel/runtime": "^7.17.9"
"@babel/runtime": "^7.17.9",
"antd-mobile": "5.10.4"
}
}
......@@ -24,9 +24,13 @@ path: /
<code src="./demos/index.js">
## 移动端
<code src="./demos/mobile.js">
## 多图表
<code src="./demos/GridDemo.js">
[//]: # (<code src="./demos/GridDemo.js">)
## API
......
......@@ -32,7 +32,7 @@ const SimgleChart = memo((props) => {
showBoxOption,
};
return optionGenerator(dataSource, null, contrast, contrastOption, smooth, config);
}, [dataSource, smooth, curveCenter]);
}, [dataSource, smooth, curveCenter,chartType]);
useEffect(() => {
chartRef.current?.resize?.();
......
......@@ -13,6 +13,7 @@ const deviceParams = [
// deviceCode: 'EGBF00000002',
// deviceCode: 'EGBF00000018',
deviceCode: 'XMYL00000345',
// deviceCode: 'XMYL00000000',
// deviceCode: 'EGBF00000014',
// sensors: '今日供水量,今日用电量,1#水箱液位,是否在线',
sensors: '进水压力',
......@@ -32,9 +33,6 @@ const Demo = () => {
<div style={{height: 700}}>
<HistoryView deviceParams={deviceParams} defaultModel="curve"/>
</div>
<div style={{height: 300}}>
<MobileHistoryChart deviceParams={deviceParams} chartType={'boxChart'}/>
</div>
</div>
);
......
import React from 'react';
import {MobileHistoryChart} from "../mobile";
const deviceParams = [
/* {
deviceCode: 'EGBF00000141',
sensors: '今日供水量,今日用电量',
deviceType: '二供泵房',
pointAddressID: 208,
}, */
{
deviceCode: 'EGBF00000141',
sensors: '今日供水量',
deviceType: '二供泵房',
pointAddressID: 208,
},
];
const Demo = () => {
return (
<div>
<div style={{height: 400}}>
<MobileHistoryChart deviceParams={deviceParams}/>
</div>
</div>
);
};
export default Demo;
......@@ -199,3 +199,9 @@
opacity: 1;
}
}
.@{history-view}-item {
display: flex;
align-items: center;
margin-bottom: 10px;
}
import React, {useEffect, useMemo, useState, useContext} from 'react';
import GridChart from "./GridChart";
import {ConfigProvider} from "antd";
import {Selector, Checkbox, Space} from 'antd-mobile/es';
import moment from "moment";
import {getDeviceAlarmScheme, getHistoryInfo} from "./apis";
import SimgleChart from "./SingleChart";
import {handlePx} from "./utils";
import styles from './index.less';
// deviceAlarmSchemes 用来获取对应的 方案的最大值/最小值 标记状态
// dataSource 获取的报警信息
// deviceParams,
// defaultDate,
// {
// deviceCode: 'XMYL00000345',
// sensors: '进水压力',
// deviceType: '熊猫压力表',
// pointAddressID: 4,
// },
//{
// "isDilute": true, // 抽稀
// "zoom": "30",// 抽稀
// "unit": "min",// 抽稀
// "ignoreOutliers": false, // 滤波
// "dateFrom": "2023-07-09 16:38:32",
// "dateTo": "2023-07-10 16:38:32",
// "acrossTables": [
// {
// "deviceCode": "XMYL00000297",
// "sensors": "进水压力,是否在线",
// "deviceType": "熊猫压力表"
// }
// ],
// "isBoxPlots": true // 箱线图
// }
const DATE_FORMAT = 'YYYY-MM-DD';
const DATE_FORMAT = 'YYYY-MM-DD HH:mm:ss';
const MobileHistoryChart = (
{
date = {
dateFrom: moment().format(`${DATE_FORMAT} 00:00:00`),
dateTo: moment().format(`${DATE_FORMAT} 23:59:59`)
dateFrom: moment().subtract(1, 'days').format(`${DATE_FORMAT}`),
dateTo: moment().format(`${DATE_FORMAT}`)
},// 默认当天
deviceParams = [], // 设备参数,必传
chartType='lineChart', // lineChart boxChart
ignoreOutliers = true, // 滤波
chartType = 'lineChart', // lineChart boxChart
// ignoreOutliers = true, // 滤波
isDilute = true, // 抽稀去重
needMarkLine = true,
showBoxOption = true, // 开启箱线图配置,默认开启
chartGrid = true, // 开启网格
...rest
}
) => {
const [deviceAlarmSchemes, setDeviceAlarmSchemes] = useState(null);
const [chartDataSource, setChartDataSource] = useState(null);
const [options, setOptions] = useState({
curveCenter: true,
ignoreOutliers: true
});
const checkBoxOptions = useMemo(() => {
return Object.keys(options).reduce((final, cur) => {
if (options[cur]) final.push(cur);
return final
}, []);
}, [options]);
const [lineType, setLineType] = useState([chartType]);
const {getPrefixCls} = useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls('history-view');
const isBoxPlots =
......@@ -87,7 +72,7 @@ const MobileHistoryChart = (
let _params = {
...date,
isBoxPlots,
ignoreOutliers,
ignoreOutliers: options.ignoreOutliers,
isDilute,
...thinKey,
acrossTables
......@@ -139,20 +124,57 @@ const MobileHistoryChart = (
});
}
useEffect(() => {
getDataSource();
getScheme();
}, [])
return deviceAlarmSchemes && chartDataSource ? <SimgleChart
showBoxOption={showBoxOption}
curveCenter={true}
chartGrid={chartGrid}
prefixCls={prefixCls}
dataSource={chartDataSource}
chartType={isBoxPlots ? chartType : null}
deviceAlarmSchemes={deviceAlarmSchemes}
/> : null
useEffect(() => {
getDataSource();
}, [options.ignoreOutliers])
return deviceAlarmSchemes && chartDataSource ? <div style={{}}>
{
chartDataSource.length === 1 ? <div className={styles[`${prefixCls}-item`]}>
<span style={{fontSize: handlePx(16)}}>曲线形态:</span>
<Selector
options={[
{label: '线形图', value: 'lineChart'},
{label: '箱线图', value: 'boxChart'}
]}
defaultValue={lineType}
onChange={(arr, extend) => setLineType(arr)}
/>
</div> : ''
}
<div className={styles[`${prefixCls}-item`]}>
<span style={{fontSize: handlePx(16)}}>曲线设置:</span>
<Checkbox.Group
value={checkBoxOptions}
onChange={val => {
let _arr = Object.keys(options);
let _options = _arr.reduce((final, cur) => {
final[cur] = !!val.includes(cur);
return final;
}, {})
setOptions(_options);
}}
>
<Space direction='horizontal'>
<Checkbox value='curveCenter'>曲线居中</Checkbox>
<Checkbox value='ignoreOutliers'>滤波</Checkbox>
</Space>
</Checkbox.Group>
</div>
<div style={{height: rest.height || '10rem', width: rest.width || '100%'}}>
<SimgleChart
showBoxOption={showBoxOption}
curveCenter={options.curveCenter}
showGridLine={chartGrid}
prefixCls={prefixCls}
dataSource={chartDataSource}
chartType={isBoxPlots ? lineType[0] : null}
deviceAlarmSchemes={deviceAlarmSchemes}
/>
</div>
</div> : null
}
export {
MobileHistoryChart
}
\ No newline at end of file
......@@ -2,7 +2,7 @@ import moment from 'moment';
import _, {isArray} from 'lodash';
/** 轴宽度, 用于计算多轴显示时, 轴线偏移和绘图区域尺寸 */
const axisWidth = 40;
const AXIS_WIDTH = 40;
const COLOR = {
NORMAL: '#1685FF',
UPER: '#fa8c16',
......@@ -13,6 +13,7 @@ const COLOR = {
LOWLOWER: '#FF0000',
AVG: '#00B8B1',
};
const isMobile = () => {
const userAgent = navigator.userAgent.toLowerCase();
if (
......@@ -23,7 +24,42 @@ const isMobile = () => {
return true;
}
return false;
};
const returnRem = (num, base = 375) => num * (base / 375);
export const handlePx = (num, unit = '') => {
const _isMobile = isMobile();
const _base = document.body.clientWidth;
let _num = _isMobile ? `${returnRem(num, _base)}` : `${num}`;
return unit ? `${_num}${unit}` : Number(_num);
};
const PC_OPTION = {
markPoint: {
padding: [2, 12],
lineHeight: 22,
backgroundColor:
window.globalConfig &&
window.globalConfig &&
window.globalConfig.variableTheme?.primaryColor
? window.globalConfig.variableTheme.primaryColor
: '#0087F7',
borderWidth: 1
},
fontSize: 16,
fontColor: "#ffffff",
dataZoomHeight: 28
}
const MOBILE_OPTION = {
markPoint: {
padding: [2, 6],
lineHeight: 18,
backgroundColor: 'rgba(255,255,255,0.6)',
borderWidth: 0
},
fontSize: handlePx(12),
fontColor: "#0087F7",
dataZoomHeight: 20
}
const currentOption = isMobile() ? MOBILE_OPTION : PC_OPTION;
/**
* 图表系列名称格式化
*
......@@ -149,6 +185,7 @@ export const alarmMarkLine = (dataItem, index, dataSource, schemes) => {
};
export const minMaxMarkPoint = (dataItem, index, dataSource) => {
const _isMobile = isMobile();
// 只有一个数据曲线时显示markline
if (!dataItem || dataSource.length !== 1) return {};
const data = [];
......@@ -159,26 +196,18 @@ export const minMaxMarkPoint = (dataItem, index, dataSource) => {
symbolOffset: [0, '50%'],
label: {
formatter: '{b|{b} }{c|{c}}',
backgroundColor:
window.globalConfig &&
window.globalConfig &&
window.globalConfig.variableTheme?.primaryColor
? window.globalConfig.variableTheme.primaryColor
: '#0087F7',
...currentOption["markPoint"],
borderColor: '#ccc',
borderWidth: 1,
borderRadius: 4,
padding: [2, 10],
lineHeight: 22,
position: 'top',
distance: 10,
rich: {
b: {
color: '#fff',
color: currentOption['fontColor'],
},
c: {
color: '#fff',
fontSize: 16,
color: currentOption['fontColor'],
fontSize: currentOption["fontSize"],
fontWeight: 700,
},
},
......@@ -252,162 +281,90 @@ export const offlineArea = (dataItem) => {
data: datas,
};
};
/**
* 图表配置项生成
*
* @param {any} dataSource 数据源
* @param {any} cusOption 自定义属性
* @param {any} contrast 是否为同期对比
* @param {any} contrastOption 同期对比周期配置, day|month
* @param {any} smooth Ture/false, 曲线/折线
* @param {any} config 额外配置信息
*/
const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth, config) => {
const needUnit = _.get(config, 'needUnit', false);
const curveCenter = _.get(config, 'curveCenter', false);
const nameWithSensor = _.get(config, 'nameWithSensor', true);
const showGridLine = _.get(config, 'showGridLine', true);
const showMarkLine = _.get(config, 'showMarkLine', false);
const showPoint = _.get(config, 'showPoint', false);
const deviceAlarmSchemes = _.get(config, 'deviceAlarmSchemes', []);
const chartType = _.get(config, 'chartType', null);
// const justLine = _.get(config, 'justLine', false);
const showBoxOption = _.get(config, 'showBoxOption', false);
// 自定义属性
const restOption = _.pick(cusOption, ['title', 'legend']);
// 一种指标一个y轴
const yAxisMap = new Map();
dataSource.forEach((item, index) => {
const {sensorName, unit} = item;
const key = sensorName;
if (!yAxisMap.has(key)) {
const i = yAxisMap.size;
const axis = {
type: 'value',
name: needUnit ? unit : null,
position: i % 2 === 0 ? 'left' : 'right',
offset: Math.floor(i / 2) * axisWidth,
axisLabel: {
formatter: (value) => (value > 100000 ? `${value / 1000}k` : value),
},
axisLine: {
show: true,
},
nameTextStyle: {
align: i % 2 === 0 ? 'right' : 'left',
},
minorTick: {
lineStyle: {
color: '#e2e2e2',
},
},
minorSplitLine: {
lineStyle: {
color: '#e2e2e2',
type: 'dashed',
},
},
};
yAxisMap.set(key, axis);
}
// 曲线居中
if (curveCenter && item.dataModel && item.dataModel.length > 0) {
const [min, max] = minMax(item);
const axis = yAxisMap.get(key);
axis.min = axis.min === void 0 ? min : Math.min(min, axis.min);
axis.max = axis.max === void 0 ? max : Math.max(max, axis.max);
}
// 网格显示
const axis = yAxisMap.get(key);
decorateAxisGridLine(axis, showGridLine);
});
const yAxis = yAxisMap.size > 0 ? [...yAxisMap.values()] : {type: 'value'};
// 根据y轴个数调整边距
const leftNum = Math.ceil(yAxisMap.size / 2);
const rightNum = Math.floor(yAxisMap.size / 2);
const grid = {
top: needUnit ? 80 : 60,
left: 10 + leftNum * axisWidth,
right: rightNum === 0 ? 20 : rightNum * axisWidth,
bottom: 60,
};
const headTemplate = (param) => {
if (!param) return '';
const {name, axisValueLabel, axisType, axisValue} = param;
const timeFormat = '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: 5px; padding-bottom: 5px;">${text}</div>`;
};
const seriesTemplate = (param, unit) => {
if (!param) return '';
const {value, encode} = param;
// const val = value[encode.y[0]];
const _unit = unit || 'Mpa';
const color = '#008CFF';
if (!isArray(value))
return ` <div style="display: flex; align-items: center;">
<span>${isMobile() ? '实际值' : param.seriesName}</span><span style="display:inline-block;">:</span>
<span style="color:${color};margin: 0 5px 0 auto;">${value?.toFixed(3) ?? '-'}</span>
<span style="font-size: 12px;">${_unit}</span>
const headTemplate = (param) => {
if (!param) return '';
const {name, axisValueLabel, axisType, axisValue} = param;
const timeFormat = '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>`;
};
const seriesTemplate = (param, unit) => {
if (!param) return '';
const {value, encode} = param;
// const val = value[encode.y[0]];
const _unit = unit || 'Mpa';
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="display:inline-block;">:</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>${isMobile() ? '实际值' : param.seriesName}</span><span style="display:inline-block;">:</span>
<span style="color: ${COLOR.AVG};margin: 0 5px 0 auto;">${value[1] ?? '-'}</span>
<span style="font-size: 12px;">${_unit}</span>
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="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 5px 0 auto;">${value[1] ?? '-'}</span>
<span style="font-size: 12px;">${_unit}</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 5px 0 auto;">${value[2] ?? '-'}</span>
<span style="font-size: 12px;">${_unit}</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 5px 0 auto;">${value[3] ?? '-'}</span>
<span style="font-size: 12px;">${_unit}</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 5px 0 auto;">${value[4] ?? '-'}</span>
<span style="font-size: 12px;">${_unit}</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>
`;
};
const tooltipAccessor = (unit) => {
return {
formatter: function (params, ticket, callback) {
let tooltipHeader = '';
let tooltipContent = '';
if (isArray(params)) {
tooltipHeader = headTemplate(params[0]);
params.forEach((param) => {
tooltipContent += seriesTemplate(param, unit);
});
} else {
tooltipHeader = headTemplate(params);
tooltipContent += seriesTemplate(params, unit);
}
return `
};
const tooltipAccessor = (unit) => {
return {
formatter: function (params, ticket, callback) {
let tooltipHeader = '';
let tooltipContent = '';
if (isArray(params)) {
tooltipHeader = headTemplate(params[0]);
params.forEach((param) => {
tooltipContent += seriesTemplate(param, unit);
});
} else {
tooltipHeader = headTemplate(params);
tooltipContent += seriesTemplate(params, unit);
}
return `
<div>
${tooltipHeader}
<div>${tooltipContent}</div>
</div>
`;
},
};
},
};
};
const returnXAxis = ({
dataSource,
contrast,
contrastOption,
nameWithSensor,
showMarkLine,
deviceAlarmSchemes,
showPoint,
restOption,
smooth
}) => {
// 根据"指标名称"分类yAxis
const yAxisInterator = (() => {
const map = new Map();
......@@ -475,21 +432,177 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
.map((item) => item.data?.[item.data.length - 1]?.[0])
.filter((item) => item !== undefined),
);
let xAxis = {type: 'time', min, max};
return {xAxis: {type: 'time', min, max}, series};
}
const handleDefault = (config, cusOption) => {
const needUnit = _.get(config, 'needUnit', false);
const curveCenter = _.get(config, 'curveCenter', false);
const nameWithSensor = _.get(config, 'nameWithSensor', true);
const showGridLine = _.get(config, 'showGridLine', true);
const showMarkLine = _.get(config, 'showMarkLine', false);
const showPoint = _.get(config, 'showPoint', false);
const deviceAlarmSchemes = _.get(config, 'deviceAlarmSchemes', []);
const chartType = _.get(config, 'chartType', null);
// const justLine = _.get(config, 'justLine', false);
const showBoxOption = _.get(config, 'showBoxOption', false);
// 自定义属性
const restOption = _.pick(cusOption, ['title', 'legend']);
return {
needUnit,
curveCenter,
nameWithSensor,
showGridLine,
showMarkLine,
showPoint,
deviceAlarmSchemes,
chartType,
showBoxOption,
restOption
}
}
const handleYAxis = ({dataSource, needUnit, curveCenter, showGridLine}) => {
// 一种指标一个y轴
const yAxisMap = new Map();
dataSource.forEach((item, index) => {
const {sensorName, unit} = item;
const key = sensorName;
if (!yAxisMap.has(key)) {
const i = yAxisMap.size;
const axis = {
type: 'value',
name: needUnit ? unit : null,
position: i % 2 === 0 ? 'left' : 'right',
offset: Math.floor(i / 2) * AXIS_WIDTH,
axisLabel: {
formatter: (value) => (value > 100000 ? `${value / 1000}k` : value),
},
axisLine: {
show: true,
},
nameTextStyle: {
align: i % 2 === 0 ? 'right' : 'left',
},
minorTick: {
lineStyle: {
color: '#e2e2e2',
},
},
minorSplitLine: {
lineStyle: {
color: '#e2e2e2',
type: 'dashed',
},
},
};
yAxisMap.set(key, axis);
}
// 曲线居中
if (curveCenter && item.dataModel && item.dataModel.length > 0) {
const [min, max] = minMax(item);
const axis = yAxisMap.get(key);
axis.min = axis.min === void 0 ? min : Math.min(min, axis.min);
axis.max = axis.max === void 0 ? max : Math.max(max, axis.max);
}
// 网格显示
const axis = yAxisMap.get(key);
decorateAxisGridLine(axis, showGridLine);
});
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};
}
const assignOptions = (restOption, xAxis, legendData) => {
restOption.dataZoom = [
{
show: true,
bottom: 10,
start: 0,
end: 100,
height: currentOption['dataZoomHeight'],
type: 'inside',
zoomOnMouseWheel: true,
},
{
show: true,
bottom: 10,
start: 0,
end: 100,
height: currentOption['dataZoomHeight'],
type: 'slider',
zoomOnMouseWheel: true,
},
];
xAxis.minInterval = 3600 * (1 * 1000);
if (legendData) {
restOption.legend = {
// orient: 'vertical',
data: legendData,
itemGap: 10,
padding: [0, 0, 0, 200],
textStyle: {
width: 120,
overflow: 'truncate',
},
}
}
};
/**
* 图表配置项生成
*
* @param {any} dataSource 数据源
* @param {any} cusOption 自定义属性
* @param {any} contrast 是否为同期对比
* @param {any} contrastOption 同期对比周期配置, day|month
* @param {any} smooth Ture/false, 曲线/折线
* @param {any} config 额外配置信息
*/
const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth, config) => {
const {
needUnit,
curveCenter,
nameWithSensor,
showGridLine,
showMarkLine,
showPoint,
deviceAlarmSchemes,
chartType,
showBoxOption,
restOption
} = handleDefault(config, cusOption);
const {leftNum, rightNum, yAxis} = handleYAxis({dataSource, needUnit, curveCenter, showGridLine});
const grid = {
top: needUnit ? 80 : 60,
// top: 200,
left: 10 + leftNum * AXIS_WIDTH,
right: rightNum === 0 ? 20 : rightNum * AXIS_WIDTH,
bottom: 60,
};
let {xAxis, series} = returnXAxis({
dataSource,
contrast,
contrastOption,
nameWithSensor,
showMarkLine,
deviceAlarmSchemes,
showPoint,
smooth,
restOption
});
decorateAxisGridLine(xAxis, showGridLine);
const tooltipTimeFormat = !contrast
? 'YYYY-MM-DD HH:mm:ss'
: contrastOption === 'day'
? 'HH:mm'
: 'DD HH:mm';
let tooltip = {
timeFormat: tooltipTimeFormat,
// trigger: 'axis',
// axisPointer: {
// type: 'cross'
// }
};
// 增加箱线图的逻辑,单曲线才存在
let tooltip = {};
// 增加箱线图的逻辑,单曲线才存在该逻辑
if (chartType && showBoxOption) {
if (chartType === 'boxChart') {
const otherData =
......@@ -497,17 +610,12 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
const {firstPV, lastPV, maxPV, minPV, pt} = item;
return [moment(pt).valueOf(), firstPV, lastPV, 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'};
decorateAxisGridLine(xAxis, showGridLine);
let unit = '';
series = series.map((item) => {
if (item.unit) unit = item.unit;
let _item = {...item, symbol: 'none'};
/* _item.data = _item?.data?.map(d => {
return d[1] || null
}) || [];*/
return _item;
return {...item, symbol: 'none'};
});
series.push({
type: 'candlestick',
......@@ -522,7 +630,8 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
},
});
tooltip = tooltipAccessor(unit);
} else {
}
if (chartType === 'lineChart') {
let _maxData = [];
let _minData = [];
let _currentYear = moment().format('YYYY');
......@@ -572,55 +681,40 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
${headTemplate(e[0])}
<div>
<div style="display: flex; align-items: center;">
<span>${
isMobile() ? '当前值' : 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 5px 0 auto;">${
<span style="color: ${COLOR.NORMAL};margin: 0 ${handlePx(5, 'px')} 0 auto;">${
e[0]?.value?.[1] ?? '-'
}</span>
<span style="font-size: 12px;">${_unit}</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 5px 0 auto;">${
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${
e[1]?.value?.[1] ?? '-'
}</span>
<span style="font-size: 12px;">${_unit}</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 5px 0 auto;">${
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${
_maxValues[e[2].dataIndex] ?? '-'
}</span>
<span style="font-size: 12px;">${_unit}</span>
<span style="font-size: ${handlePx(12, 'px')};">${_unit}</span>
</div>
</div>
</div>`;
},
};
}
} else {
tooltip = tooltipAccessor();
}
restOption.dataZoom = [
{
show: true,
bottom: 10,
start: 0,
end: 100,
height: 28,
type: 'inside',
zoomOnMouseWheel: true,
},
{
show: true,
bottom: 10,
start: 0,
end: 100,
height: 28,
type: 'slider',
zoomOnMouseWheel: true,
},
];
xAxis.minInterval = 3600 * 1 * 1000;
tooltip.timeFormat = tooltipTimeFormat;
let _legendData = series.filter(item => !['最大值', '最小值'].includes(item.name)).map(item => item.name);
assignOptions(restOption, xAxis, _legendData);
debugger
return {
yAxis,
grid,
......
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