rtgk-screen-web/pages/reports/equipmentCurve/index.js

593 lines
16 KiB
JavaScript

import React, { useRef, useEffect, useState, useMemo } from "react";
import * as echarts from "echarts";
import { SearchOutlined } from "@ant-design/icons";
import _, { indexOf } from "lodash";
import moment from "moment";
import "antd/dist/antd.css";
import { Select, Button, DatePicker, Checkbox, message, Spin } from "antd";
import {
getFactory,
getEquipType,
getEquip,
getEquipmentLocation,
getEquipmentLocationEchart,
} from "../../../reportUtils/getQueryData";
const { Option } = Select;
import theme from "../../../reportUtils/theme.json";
function EquipmentCurve() {
const dataZoomRef = useRef();
let refinput = useRef();
echarts.registerTheme("black", theme);
// 设备类型集合
const [equipType, setEquipType] = useState([]);
// 车间集合
const [factory, setFactory] = useState([]);
// 设备集合
const [equip, setEquip] = useState([]);
//设备类型值
const [equipTypeValue, setEquipTypeValue] = useState("");
//车间值
const [factoryValue, setFactoryValue] = useState("");
//设备值
const [equipValue, setEquipValue] = useState("");
// 点位集合
const [locations, setLocations] = useState([]);
// 点位变化值
const [locationValue, setLocationValue] = useState([]);
// 时间变化值
const [dateValue, setDateValue] = useState("");
// 存放chartData
const [chartData, setChartData] = useState({});
// 存放chartref
const [chartRef, setChartRef] = useState([]);
const [spin, setSpin] = useState(false);
const equipTypeChange = (value) => {
setEquipTypeValue(value);
};
const factoryChange = (value) => {
setFactoryValue(value);
};
const equipChange = (value = "") => {
if (value && equipValue !== value) {
setLocationValue([]);
setChartData({});
setChartRef([]);
getEquipmentLocation(value).then((data) => {
let locationArr = data
.sort((a, b) => (a.iotfieldsort > b.iotfieldsort ? 1 : -1))
.map((item) => {
return {
label: item.iotfielddescribe,
value: item.iotField,
};
});
setLocations(locationArr);
});
} else {
setLocationValue([]);
setChartData({});
setChartRef([]);
setLocations([]);
}
setEquipValue(value);
};
const locationChange = (checkValue) => {
setLocationValue(checkValue);
if (checkValue.length > 0) {
doSearch(checkValue);
} else {
setChartRef([]);
}
};
const dateChange = (date, dateString) => {
setDateValue(dateString);
};
const handleCancelClick = () => {
setLocationValue([]);
setChartRef([]);
};
const handleClick = () => {
if (!equipValue) {
message.warning("请选择需要查询的设备!");
} else if (!dateValue) {
message.warning("请选择需要查询的时间!");
} else if (locationValue.length === 0) {
message.warning("请勾选需要查询的点位!");
} else {
setSpin(true);
doSearch();
}
};
// 查询设备类型,查询车间,
useEffect(() => {
getEquipType().then((data) => {
setEquipType(data);
});
getFactory().then((data) => {
setFactory(data);
});
}, []);
// 查询设备 监听设备类型
useEffect(() => {
getEquip({ equipTypeValue, factoryValue }).then((data) => {
setEquip(data);
setEquipValue("");
setLocations([]);
setLocationValue([]);
setChartData({});
setChartRef([]);
});
}, [equipTypeValue, factoryValue]);
useEffect(() => {
let dataZoomChart = echarts.init(dataZoomRef.current);
dataZoomChart.clear();
if (locationValue.length > 0) {
if (!dataZoomRef.current) {
return;
}
let dataZoomData = {};
let flag = true;
for (let i = 0; i < locationValue.length; i++) {
if (flag && chartData[locationValue[i]]) {
dataZoomData = chartData[locationValue[i]];
flag = false;
}
}
let dataZoomChart = echarts.init(dataZoomRef.current);
let option = {
xAxis: {
type: "category",
data: dataZoomData["times"] || [],
},
yAxis: {
type: "value",
scale: true,
},
legend: {
show: false,
height: "10",
width: "2000",
},
dataZoom: {
top: "10",
left: "0",
type: "slider",
width: "92%",
height: "30px",
},
series: [
{
data: dataZoomData["values"] || [],
type: "line",
},
],
};
dataZoomChart.setOption(option);
// 动态生成echart
let childsEchart = [];
for (let i = 0; i < chartRef.length; i++) {
if (!chartData[chartRef[i]]) {
break;
}
let dom = document.getElementById(chartRef[i]);
let echatItem = echarts.init(dom, "black");
let optionItem = {
grid: {
top: "30",
height: "125",
},
title: {
text: `${chartData[chartRef[i]]["title"]}`,
x: "center",
y: "top",
textAlign: "left",
},
tooltip: {
trigger: "axis",
axisPointer: {
// link: null,
animation: true,
type: "cross",
},
formatter: function (params) {
//在此处直接用 formatter 属性
let showdata = params[0];
// 根据自己的需求返回数据
return `
<div>时间:${showdata.axisValueLabel}</div>
<div>数据:<a style="color: #00E8D7">${showdata.data}</a></div>
`;
},
},
xAxis: {
type: "category",
data: chartData[chartRef[i]]["times"],
},
yAxis: {
type: "value",
},
legend: {
show: false,
height: "10",
width: "2000",
},
dataZoom: {
type: "inside",
zoomOnMouseWheel: false,
},
series: [
{
symbol: "circle",
symbolSize: 5,
data: chartData[chartRef[i]]["values"],
type: "line",
},
],
};
echatItem.setOption(optionItem);
childsEchart.push(echatItem);
}
echarts.connect([dataZoomChart].concatchildsEchart);
}
}, [chartRef]);
return (
<div>
<Spin spinning={spin}>
<div className="header">
<div className="search">
<div className="workShop">
<span>车间:</span>&nbsp;
<Select
allowClear
size="small"
style={{ width: 120 }}
onChange={factoryChange}
value={factoryValue}
>
{factory.map((item) => {
return (
<Option value={item.code} key={item.gid}>
{item.name}
</Option>
);
})}
</Select>
</div>
<div className="equipType">
<span>设备类型:</span>&nbsp;
<Select
allowClear
size="small"
style={{ width: 120 }}
onChange={equipTypeChange}
value={equipTypeValue}
>
{equipType.map((item) => {
return (
<Option value={item.equipTypeGid} key={item.gid}>
{item.name}
</Option>
);
})}
</Select>
</div>
<div className="equipNo">
<span>设备编号:</span>&nbsp;
<Select
showSearch
allowClear
size="small"
onChange={equipChange}
optionFilterProp="children"
style={{ width: 150 }}
value={equipValue}
filterOption={(input, option) =>
option.children.toLowerCase().includes(input.toLowerCase())
}
>
{equip.map((item) => {
return (
<Option
value={item.serialNumber}
key={item.serialNumber + item.name}
>
{item.name}
</Option>
);
})}
</Select>
</div>
<div className="equipDate">
<span>查询日期:</span>&nbsp;
<DatePicker
style={{ width: 150 }}
size="small"
onChange={dateChange}
/>
</div>
<div>
<Button
type="primary"
icon={<SearchOutlined />}
size="small"
shape="round"
onClick={handleClick}
>
查询
</Button>
</div>
</div>
</div>
<div className="dataZoom">
<div className="zoomTitle">时间窗口选择框:</div>
<div
className="zoomContent"
ref={dataZoomRef}
style={{
width: "90%",
height: "150px",
overflow: "hidden",
}}
></div>
</div>
<div className="toolBar flex flex-row">
<div className=" text-xs ">
{locations.length > 0 ? (
<Button
type="primary"
className="ml-2 mt-2"
size="small"
onClick={handleCancelClick}
>
取消全选
</Button>
) : (
<></>
)}
</div>
<div className="legend overflow-y-auto h-32 ">
<Checkbox.Group
ref={refinput}
value={locationValue}
options={locations}
onChange={locationChange}
/>
</div>
</div>
<div className="flex h-2"></div>
<div className="content ">
{chartRef.map((item) => {
return (
<div
id={item}
key={item}
style={{
width: "100%",
height: "200px",
marginBottom: "16px",
}}
></div>
);
})}
</div>
</Spin>
<div className={spin ? "mask" : "unmask"}></div>
<style jsx>{`
.ant-checkbox-group-item {
width: 200px !important;
}
* {
margin: 0;
padding: 0;
}
.header {
position: relative;
width: 100%;
height: 35px;
box-shadow: 5px 2px 20px -4px rgb(0, 0, 0, 0.3);
}
.search {
display: flex;
height: 35px;
margin: auto 15px;
}
.search div {
line-height: 35px;
margin-right: 20px;
}
.search .workShop {
margin-left: 15px;
}
.search .equipDate {
margin-right: 80px;
}
.dataZoom {
position: relative;
width: 100%;
height: 50px;
overflow: hidden;
}
.zoomTitle {
position: absolute;
top: 50%;
left: 10px;
margin-top: -8px;
}
.zoomContent {
position: absolute;
top: -2px;
left: 140px;
bottom: 0;
right: 0;
}
.content {
width: 100%;
height: 66vh;
overflow-y: auto;
overflow-x: hidden;
box-sizing: border-box;
}
.toolBar {
position: relative;
border-width: 1px 0 1px 0;
border-color: #d3d3d3;
background: #f8f8f8;
min-height: 32px;
}
.legend {
font-size: 12px;
color: white;
padding-left: 6%;
display: flex;
position: relative;
flex-wrap: wrap;
}
.mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 200;
}
.unmask {
display: none;
}
`}</style>
</div>
);
function doSearch(checkValue) {
let _locationValue = ``;
if (checkValue) {
_locationValue = checkValue;
} else {
_locationValue = locationValue;
}
let params = {
workCenterCode:`${factoryValue}`,
startTime: `${dateValue} 00:00:00`,
endTime: `${dateValue} 23:59:59`,
equipCode: equipValue,
fields: _locationValue,
};
getEquipmentLocationEchart(params).then((data) => {
if (data && data.length > 0) {
createCharts();
}
else{
createChartsEmp();
message.warning("未能查询到数据!");
}
setSpin(false);
function createChartsEmp() {
let locationsValues = _.cloneDeep(locations);
let processData = {};
let commonTimes = [];
_locationValue.map(key=> {
if (key !== "time") {
if (!processData.hasOwnProperty(key)) {
let index = _.findIndex(locationsValues, function (o) {
return o.value === key;
});
let title = index >= 0 ? locationsValues[index]["label"] : "";
processData[key] = {
title: title,
key: key,
times: [],
values: [],
};
}
// processData[key]["values"].push([]);
}
// let time = moment(data[i]["time"]).format("YYYY-MM-DD HH:mm:ss");
// commonTimes.push(time);
})
let domCharts = [];
commonTimes = _.reverse(commonTimes);
for (let key in processData) {
processData[key]["times"] = commonTimes;
}
for (let i = 0; i < _locationValue.length; i++) {
if (processData[_locationValue[i]]) {
domCharts.push(_locationValue[i]);
}
}
setChartData(processData);
setChartRef(domCharts);
}
function createCharts() {
let locationsValues = _.cloneDeep(locations);
let processData = {};
let commonTimes = [];
for (let i = 0; i < data.length; i++) {
for (let key in data[i]) {
if (key !== "time") {
if (!processData.hasOwnProperty(key)) {
let index = _.findIndex(locationsValues, function (o) {
return o.value === key;
});
let title = index >= 0 ? locationsValues[index]["label"] : "";
processData[key] = {
title: title,
key: key,
times: [],
values: [],
};
}
processData[key]["values"].push(data[i][key]);
}
}
let time = moment(data[i]["time"]).format("YYYY-MM-DD HH:mm:ss");
commonTimes.push(time);
}
let domCharts = [];
commonTimes = _.reverse(commonTimes);
for (let key in processData) {
processData[key]["times"] = commonTimes;
}
for (let i = 0; i < _locationValue.length; i++) {
if (processData[_locationValue[i]]) {
domCharts.push(_locationValue[i]);
}
}
_locationValue.map(x=>{
if(domCharts.indexOf(x)===-1){
domCharts.push(x);
let index = _.findIndex(locationsValues, function (o) {
return o.value === x;
});
let title = index >= 0 ? locationsValues[index]["label"] : "";
processData[x] = {
title: title,
key: x,
times: [],
values: [],
};
processData[x]["times"] = commonTimes;
}
})
setChartData(processData);
setChartRef(domCharts);
}
});
}
}
export default EquipmentCurve;