Commit ef721b5d authored by 李纪文's avatar 李纪文

fix: 修改实时数据数据为0展示--问题

parent 7fa4df59
......@@ -180,7 +180,8 @@
"react-redux": "^8.0.5",
"react-resizable": "^3.0.4",
"react-window": "1.8.9",
"sha1": "^1.1.1"
"sha1": "^1.1.1",
"skmeans": "^0.11.3"
},
"size-limit": [
{
......
import React from 'react';
import React, { useState } from 'react';
import { LimitCurve } from '../index';
import { Button } from 'antd';
const Demos = () => {
const [open, setOpen] = useState(false);
return (
<>
<LimitCurve />
<Button
onClick={() => {
setOpen(true);
}}
>
打开限制曲线
</Button>
<LimitCurve open={open} />
</>
);
};
......
const getDataRanges = (extremes) => {
var ranges = [];
for (var dimension in extremes) {
ranges[dimension] = extremes[dimension].max - extremes[dimension].min;
}
return ranges;
}
const getDataExtremes = (data)=> {
var extremes = [];
for (var i in data) {
var point = data[i];
for (var dimension in point) {
if (!extremes[dimension]) {
extremes[dimension] = { min: 1000, max: 0 };
}
if (point[dimension] < extremes[dimension].min) {
extremes[dimension].min = point[dimension];
}
if (point[dimension] > extremes[dimension].max) {
extremes[dimension].max = point[dimension];
}
}
}
return extremes;
}
const initMeans = (k, dataExtremes, dataRange) => {
if (!k) {
k = 3;
}
const means = [];
while (k--) {
var mean = [];
for (var dimension in dataExtremes) {
mean[dimension] = dataExtremes[dimension].min + Math.random() * dataRange[dimension];
}
means.push(mean);
}
return means;
}
const makeAssignments = (means, data) => {
const assignments = {};
for (var i in data) {
var point = data[i];
var distances = [];
for (var j in means) {
var mean = means[j];
var sum = 0;
for (var dimension in point) {
var difference = point[dimension] - mean[dimension];
difference *= difference;
sum += difference;
}
distances[j] = Math.sqrt(sum);
}
assignments[i] = distances.indexOf(Math.min.apply(null, distances));
}
return assignments;
}
const setup = (data) => {
const dataExtremes = getDataExtremes(data);
const dataRange = getDataRanges(dataExtremes);
const means = initMeans(3, dataExtremes, dataRange);
return makeAssignments(means, data);
}
export default setup;
......@@ -4,23 +4,22 @@ import classNames from 'classnames';
import moment from 'moment';
import { BasicChart } from '@wisdom-components/basicchart';
import { getHistoryInfo } from '../apis';
import { std,median } from 'mathjs';
import { std } from 'mathjs';
import skmeans from 'skmeans';
import './index.less';
const LimitCurve = (props) => {
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls('limit-curve');
const { width, deviceCode, sensors, deviceType, getContainer, title } = props;
const [open, isOpen] = useState(true);
const [open, setOpen] = useState(false);
const [cluster, setCluster] = useState('K-means'); // 聚集算法
const [outlier, setOutlier] = useState(1); // 过滤异常
const [outlier, setOutlier] = useState(3); // 过滤异常
const [curve, setCurve] = useState('特征曲线'); // 曲线类型
const [sensitive, setSensitive] = useState(10); // 敏感度
const [stdVal, setStdVal] = useState(null); // 均方差
const [medianVal, setMedianVal] = useState(null); // 平均值
const [sensorData, setSensorData] = useState([]); // 所有数据
const [chartData, setChartData] = useState([]); // 图表数据
const [timeCycle, setTimeCycle] = useState(60);
const [options, setOptions] = useState({});
const chartRef = useRef(null);
......@@ -31,7 +30,9 @@ const LimitCurve = (props) => {
};
// 取消
const onCancel = () => {};
const onCancel = () => {
setOpen(false);
};
// 获取历史数据
const getSensorsData = async () => {
......@@ -39,8 +40,8 @@ const LimitCurve = (props) => {
isDilute: true,
zoom: '',
unit: '',
dateFrom: moment().subtract(7, 'day').format('YYYY-MM-DD 00:00:00'),
dateTo: moment().format('YYYY-MM-DD 23:59:59'),
dateFrom: moment().subtract(8, 'day').format('YYYY-MM-DD 00:00:00'),
dateTo: moment().subtract(1, 'day').format('YYYY-MM-DD 23:59:59'),
acrossTables: [
{ deviceCode: 'EGBF00000120', sensors: '出水瞬时流量', deviceType: '二供泵房' },
],
......@@ -48,16 +49,80 @@ const LimitCurve = (props) => {
};
const results = await getHistoryInfo(params);
const historyData = results?.data?.[0] || {};
const dataArr = historyData?.dataModel.map((item) => {
return item.pv;
});
setSensorData(() => {
setStdVal(std(dataArr));
setMedianVal(median(dataArr));
return historyData;
});
console.log(historyData, std(dataArr),median(dataArr));
};
// 图表数据处理
const chartDataHandle = (data) => {
const times = moment().subtract(1, 'day').format('YYYY-MM-DD');
const chart = data.map((item) => {
return {
...item,
time: moment(item.pt).format(times + ' HH:mm:ss'),
};
});
return chart;
};
// 聚集方法
const clusteredMothod = () => {};
// 渲染图表
const renderChart = (_chartData) => {
const chartData = _chartData.map((item) => {
return [new Date(item.time).getTime(), item.pv];
});
const clustered = skmeans(chartData, 24);
const { centroids = [] } = clustered;
const _centroids = centroids.sort((a, b) => {
return a[0] - b[0];
});
const option = {
xAxis: {
type: 'time',
axisTick: {
alignWithLabel: true,
},
boundaryGap: false,
splitLine: {
show: true,
lineStyle: {
type: 'dashed',
},
},
},
yAxis: {
type: 'value',
name: 'm',
position: 'left',
alignTicks: true,
axisLine: {
show: true,
},
axisLabel: {
formatter: '{value}',
},
},
series: [
{
symbolSize: 5,
data: _chartData.map((item) => {
return [new Date(item.time).getTime(), item.pv];
}),
type: 'scatter',
},
{
data: centroids.map((item) => {
return [Math.floor(item[0]), item[1]];
}),
type: 'line',
},
],
};
setOptions(option);
};
useEffect(() => {
......@@ -65,55 +130,111 @@ const LimitCurve = (props) => {
}, []);
useEffect(() => {
const {dataModel= []} = sensorData;
const { dataModel = [] } = sensorData;
if (!dataModel.length) return setChartData([]);
const count = Math.floor((24 * 60) / timeCycle);
const times = moment().subtract(1, 'day').format('YYYY-MM-DD');
const _dataModel = dataModel.map((item) => {
return {
...item,
time: moment(item.pt).format(times + ' HH:mm:ss'),
};
});
const _chartData = [];
const _clustered = [];
for (let i = 0; i < count; i++) {
const data = _dataModel.filter((item) => {
const time = new Date(item.time).getTime();
const min = new Date(moment(times + ' 00:00:00').add(i * timeCycle, 'minute')).getTime();
const max = new Date(
moment(times + ' 00:00:00').add((i + 1) * timeCycle, 'minute'),
).getTime();
return time && time >= min && max >= time;
});
const clusteredArr = [];
const dataArr = [];
const pvArr = data.map((item) => {
return item.pv;
// clusteredArr.push([new Date(item.time).getTime(),item.pv])
});
const stdVal = pvArr.length ? std(pvArr) : 0;
const medianVal = pvArr.length ? average(pvArr) : 0;
const range = {
min: medianVal - stdVal*outlier,
min: medianVal + stdVal*outlier,
min: medianVal - outlier * stdVal,
max: medianVal + outlier * stdVal,
};
data.forEach((item) => {
if (item.pv >= range.min && item.pv <= range.max) dataArr.push(item);
clusteredArr.push([new Date(item.time).getTime(), item.pv]);
});
const clustered = clusteredArr.length ? skmeans(clusteredArr, 1) : {};
const { centroids = [] } = clustered;
_chartData.push(...dataArr);
_clustered.push(...centroids);
}
const data = dataModel.map((item) => {
return item.pv >= range.min && item.pv<=range.max;
})
console.log(data);
}, [sensorData, cluster, outlier])
// useEffect(() => {
// const option = {
// xAxis: {},
// yAxis: {},
// series: [
// {
// symbolSize: 20,
// data: [
// [10.0, 8.04],
// [8.07, 6.95],
// [13.0, 7.58],
// [9.05, 8.81],
// [11.0, 8.33],
// [14.0, 7.66],
// [13.4, 6.81],
// [10.0, 6.33],
// [14.0, 8.96],
// [12.5, 6.82],
// [9.15, 7.2],
// [11.5, 7.2],
// [3.03, 4.23],
// [12.2, 7.83],
// [2.02, 4.47],
// [1.05, 3.33],
// [4.05, 4.96],
// [6.03, 7.24],
// [12.0, 6.26],
// [12.0, 8.84],
// [7.08, 5.82],
// [5.02, 5.68],
// ],
// type: 'scatter',
renderChart(_chartData, _clustered);
}, [sensorData, cluster, outlier]);
useEffect(() => {
console.log(chartData);
const _chartData = chartDataHandle(chartData);
const clusteredData = _chartData.map((item) => {
return [new Date(item.time).getTime(), item.pv];
});
const clustered = clusteredData.length ? skmeans(clusteredData, 24) : {};
console.log(clustered);
const { centroids = [] } = clustered;
const _centroids = centroids.sort((a, b) => {
return a[0] - b[0];
});
const option = {
xAxis: {
type: 'time',
// axisTick: {
// alignWithLabel: true,
// },
// boundaryGap: false,
// splitLine: {
// show: true,
// lineStyle: {
// type: 'dashed',
// },
// ],
// };
// setOptions(option);
// }, [sensorData]);
// },
},
yAxis: {
type: 'value',
name: 'm',
position: 'left',
alignTicks: true,
axisLine: {
show: true,
},
axisLabel: {
formatter: '{value}',
},
},
series: [
{
symbolSize: 5,
data: _chartData.map((item) => {
return [new Date(item.time).getTime(), item.pv];
}),
type: 'scatter',
},
{
data: _centroids.map((item) => {
return [new Date(Math.floor(item[0])).getTime(), item[1]];
}),
type: 'line',
},
],
};
setOptions(option);
}, [chartData]);
useEffect(()=>{
setOpen(props.open);
},[props.open])
return (
<>
......@@ -138,8 +259,8 @@ const LimitCurve = (props) => {
options={clusterArr}
optionType={'button'}
value={cluster}
onChange={(value) => {
setCluster(value);
onChange={(e) => {
setCluster(e.target.value);
}}
/>
</span>
......@@ -149,8 +270,8 @@ const LimitCurve = (props) => {
options={outlierArr}
optionType={'button'}
value={outlier}
onChange={(value) => {
setOutlier(value);
onChange={(e) => {
setOutlier(e.target.value);
}}
/>
</span>
......@@ -187,8 +308,8 @@ const LimitCurve = (props) => {
options={chartArr}
optionType={'button'}
value={curve}
onChange={(value) => {
setCurve(value);
onChange={(e) => {
setCurve(e.target.value);
}}
/>
</span>
......@@ -211,7 +332,7 @@ const LimitCurve = (props) => {
const outlierArr = [
{
label: '低',
value: 1,
value: 3,
},
{
label: '中',
......@@ -219,7 +340,7 @@ const outlierArr = [
},
{
label: '高',
value: 3,
value: 1,
},
];
......@@ -241,4 +362,9 @@ const chartArr = [
},
];
// 平均值方法
const average = (arr) => {
return arr.reduce((acc, cur) => acc + cur, 0) / arr.length;
};
export default LimitCurve;
......@@ -212,7 +212,7 @@ const RealTimeInfo = (props) => {
item.type = curData1[0].name || '--';
}
if (curData2.length) {
item.value = curData2[0].pv || '--';
item.value = curData2[0].pv || curData2[0].pv === 0 ? curData2[0].pv : '--';
}
});
return newData;
......
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