Sfoglia il codice sorgente

驾驶舱图表修改

xujunjie 2 anni fa
parent
commit
3ca0da61d1

+ 248 - 209
src/components/ChartUtils/utils.js

@@ -43,146 +43,184 @@ const computePrefixExpression = (function() {
   };
 })();
 
-const getFunctionValue = child => {
-  let data = {};
-  data.data = [];
-  let expression = child.tempExpression;
-  let first = child.data[0];
-  let indexArr = child.indexArr;
-  first.data.forEach(item => {
-    // firstDevice.device
-    let resObj = {
-      [first.device.deviceName]: item,
-    };
-    let htime = item.htime;
-    for (let i = 1; i < child.data.length; i++) {
-      let element = child.data[i];
-      // deviceName = element.name
-      let result = element.data.find(item => item.htime === htime);
-      if (!result) return;
-      resObj[element.device.deviceName] = result;
+export async function getOptions(values, datas, formula, projectId) {
+  let allDatas = getAllParams(datas, formula);
+
+  let optionsData = getOptionsData(datas, formula, values);
+
+  // 请求接口
+  const { plcData, formData } = await queryData(values, allDatas, projectId);
+
+  optionsData = optionsData.map(item => {
+    const paramsInfo = item.paramsInfo;
+    let res;
+    if (paramsInfo.data_type == 0) {
+      // plc数据
+      res = findPlcData(paramsInfo, plcData, values.timeType);
+    } else if (paramsInfo.data_type == 1) {
+      // form数据
+      res = findFormData(paramsInfo, formData, values.timeType);
+    } else if (paramsInfo.data_type == 2) {
+      // 获取公式的值
+      res = getFormulaData(item.paramsInfo, plcData, formData, values.timeType);
     }
-    Object.keys(resObj).forEach(key => {
-      var result = indexArr.find(item => key === item.deviceName);
-      if (result) expression[result.index] = resObj[key].val;
-    });
-    // console.log(expression);
-    data.data.push({
-      htime: moment(htime).format('YYYY-MM-DD HH:mm:ss'),
-      val: computePrefixExpression([...expression]),
+    return { ...item, ...res };
+  });
+  return {
+    ...values,
+    data: optionsData,
+  };
+}
+
+// 根据表单的数据项获取请求参数
+function getFormParams(datas, projectId) {
+  let params = {};
+  datas.forEach(item => {
+    if (!params[item.data_name]) params[item.data_name] = [];
+    params[item.data_name].push(item.data_title);
+  });
+  return Object.keys(params).map(data_name => ({
+    formName: data_name,
+    titles: params[data_name],
+    projectId,
+  }));
+}
+
+async function queryData(values, datas, projectId) {
+  let plcDatas = [],
+    formDatas = [];
+  datas.forEach(item => {
+    if (item.data_type == 0) {
+      plcDatas.push(item);
+    } else {
+      formDatas.push(item);
+    }
+  });
+
+  // 根据params获取form的数据
+  var formData = await getFormData(values, formDatas, projectId);
+  var plcData = await getPlcData(values, plcDatas);
+  if (values.timeType) {
+    // 获得时间轴全集
+    let times = getTimes(plcData[0]?.data, formData[0]?.data);
+
+    // 根据时间全集补填数据
+    formatData(plcData, times);
+    formatData(formData, times);
+  }
+  return {
+    plcData,
+    formData,
+  };
+}
+
+// 根据时间进行格式化数据
+function formatData(datas, times) {
+  datas.forEach(item => {
+    // 默认数据
+    let newItemData = [];
+    let i = 0;
+    times.forEach(t => {
+      if (item.data[i]?.htime != t) {
+        // 空缺时间要补0
+        newItemData.push({
+          htime: t,
+          val: 0,
+        });
+      } else {
+        newItemData.push(item.data[i]);
+        i++;
+      }
     });
-    // console.log(indexArr, resObj, expression);
-    //  indexArr   resObj     expression
+    // 使用新值
+    item.data = newItemData;
+  });
+}
+function getTimes(plcTimes = [], formTimes = []) {
+  let times = {};
+
+  plcTimes.forEach(item => {
+    times[item.htime] = true;
+  });
+  formTimes.forEach(item => {
+    times[item.htime] = true;
   });
-  data.name = child.name;
+  return Object.keys(times).sort((a, b) => new Date(a) - new Date(b));
+}
+async function getFormData(values, datas, projectId) {
+  let arrtData = values.data || [];
+  const params = getFormParams(datas, projectId);
+  if (!values.timeType) {
+    // 请求最新数据
+    return await getFormCurrentData(params, values);
+  } else {
+    // 请求历史数据
+    return await getFormHistoryData(params, values);
+  }
+}
+// 请求表单最新数据
+async function getFormCurrentData(params, values) {
+  const { timeType, date } = values;
+  let data = [];
+  for (let i = 0; i < params.length; i++) {
+    const resData = await queryFormCurrentData(params[i]);
+    data = [...data, ...resData];
+  }
   return data;
-};
+}
+
+// 请求表单历史数据
+async function getFormHistoryData(params, values) {
+  const { timeType, date } = values;
+  let sTime, eTime;
+  let data = [];
+  // -1为自选日期  从date内获取时间
+  if (timeType == -1) {
+    let clear = { hour: 0, minute: 0, second: 0, millisecond: 0 };
+    eTime = moment(date[1])
+      .set(clear)
+      .format('YYYY-MM-DD HH:mm:ss');
+    sTime = moment(date[0])
+      .set(clear)
+      .format('YYYY-MM-DD HH:mm:ss');
+  } else {
+    let currentDate = moment();
+    eTime = currentDate.format('YYYY-MM-DD HH:mm:ss');
+    sTime = currentDate.add(-1 * timeType, 'hour').format('YYYY-MM-DD HH:mm:ss');
+  }
 
-/**
- * 获取图表的options
- * @param {object} values 表单数据
- * @param {array} datas 数据项
- * @param {array} formula 数据公式
- * @returns
- */
-export async function getPlcOptions(values, datas, formula) {
+  for (let i = 0; i < params.length; i++) {
+    const resData = await queryFormHistoryData({ ...params[i], eTime, sTime });
+    data = [...data, ...resData];
+  }
+  return data;
+}
+async function getPlcData(values, datas) {
   let arrtData = values.data || [];
   let params = getSingleData(datas);
-  let multiParams = getFormula(formula);
   if (!values.timeType) {
     let res = await getData(params, values);
-    for (let i = 0; i < multiParams.length; i++) {
-      let device = multiParams[i].paramsDevice;
-      let indexArr = multiParams[i].indexArr;
-      let tempExpression = [...multiParams[i].expression];
-      let formulaRes = await getData(device, values);
-      formulaRes.data.map(res => {
-        let temp = device.find(child => child.deviceName === res.alias);
-        console.log(temp);
-        if (temp) {
-          var indexObj = indexArr.find(item => item.deviceName === temp.deviceName);
-          if (indexObj) {
-            tempExpression[indexObj.index] = res.val;
-          }
-        }
-      });
-      let tempValue = computePrefixExpression([...tempExpression]);
-      multiParams[i].formatExpression = tempExpression;
-      multiParams[i].value = tempValue;
-    }
-    let resData = res.data.map((item, index) => {
-      let attrDataItem = arrtData[index + formula.length] || {};
-      return {
-        ...attrDataItem,
-        name: item.alias,
-        value: item.val * 1,
-      };
-    });
-    let formulaData = multiParams.map((item, index) => {
-      let attrDataItem = arrtData[index] || {};
-      return {
-        ...attrDataItem,
-        name: item.FormulaName,
-        value: item.value * 1,
-      };
-    });
-
-    return {
-      ...values,
-      data: [...resData, ...formulaData],
-    };
+    return res.data;
   } else {
     let singleData = [];
     for (let i = 0; i < params.length; i++) {
       const item = params[i];
       let res = await getData(item, values);
-      let attrDataItem = arrtData[i + multiParams.length] || {};
       singleData.push({
-        ...attrDataItem,
+        paramsInfo: item,
         name: item.deviceName,
         data: (res.data || []).map(item => {
           return {
-            val: item.val,
+            val: Number(item.val),
             htime: moment(item.htime_at).format('YYYY-MM-DD HH:mm:ss'),
           };
         }),
       });
     }
-
-    let firstHTimeArr = [];
-    let formulaData = [];
-    for (let i = 0; i < multiParams.length; i++) {
-      const element = multiParams[i];
-      let indexArr = element.indexArr;
-      let tempExpression = [...element.expression];
-      let device = element.paramsDevice;
-      let child = {};
-      child.tempExpression = tempExpression;
-      child.name = element.FormulaName;
-      child.data = [];
-      child.indexArr = indexArr;
-      for (let j = 0; j < device.length; j++) {
-        const tempDevice = device[j];
-        let res = await getData(tempDevice, values);
-        child.data.push({
-          data: res.data,
-          device: tempDevice,
-        });
-      }
-      formulaData.push(child);
-    }
-
-    let data = [];
-
-    formulaData.map((item, index) => {
-      let attrDataItem = arrtData[index] || {};
-      data.push({ ...attrDataItem, ...getFunctionValue(item) });
-    });
-
-    values.data = [...singleData, ...data];
-    return values;
+    return singleData;
   }
 }
+
 // 根据数据项获取请求参数
 function getSingleData(datas) {
   let params = [];
@@ -197,29 +235,65 @@ function getSingleData(datas) {
   });
   return params;
 }
-// 根据公式获得请求参数
-function getFormula(formula) {
-  let params = [];
-  formula.forEach(item => {
-    let tempItem = item;
-    let tempDeviceArr = [];
-    let indexArr = [];
-    item.Device.map(device => {
-      if (device.Id && device.ItemAlias && device.ItemName) {
-        tempDeviceArr.push({
-          deviceName: device.ItemAlias,
-          deviceId: String(device.PlcDeviceId),
-          deviceItems: device.ItemName,
-        });
+function findPlcData(paramsInfo, plcData, timeType) {
+  // 实时数据与历史数据结构不一致  需判断
+  if (timeType) {
+    return plcData.find(resItem => resItem.paramsInfo.deviceName == paramsInfo.seq);
+  } else {
+    let res = plcData.find(resItem => resItem.alias == paramsInfo.seq);
+    return {
+      name: res.alias,
+      value: res.val,
+    };
+  }
+}
+function findFormData(paramsInfo, formData, timeType) {
+  // 实时数据与历史数据结构不一致  需判断
+  if (timeType) {
+    return formData.find(resItem => resItem.name == paramsInfo.data_title);
+  } else {
+    let res = formData.find(resItem => resItem.title == paramsInfo.data_title);
+    return {
+      name: res.title,
+      value: res.value,
+    };
+  }
+}
 
-        indexArr.push({ index: device.index, deviceName: device.ItemAlias });
+function getAllParams(datas, formula) {
+  let allDatas = [...datas];
+  formula.forEach(f => {
+    f.params.forEach(params => {
+      if (params.data_type == 0) {
+        if (!datas.find(item => item.seq == params.seq)) {
+          allDatas.push(params);
+        }
+      } else {
+        if (!datas.find(item => item.data_title == params.data_title)) {
+          allDatas.push(params);
+        }
       }
     });
-    tempItem.paramsDevice = tempDeviceArr;
-    tempItem.indexArr = indexArr;
-    params.push(tempItem);
   });
-  return params;
+  return allDatas;
+}
+
+function getOptionsData(datas, formula, values) {
+  let valuesData = values.data || [];
+
+  let optionsData = [];
+  formula.forEach((item, index) => {
+    var arrData = valuesData[index] || {};
+    item.data_type = 2;
+    arrData.paramsInfo = item;
+    optionsData.push(arrData);
+  });
+  datas.forEach((data, index) => {
+    var arrData = valuesData[index + formula.length] || {};
+    arrData.paramsInfo = data;
+    optionsData.push(arrData);
+  });
+  return optionsData;
 }
 
 var DATA_CACHE = {};
@@ -239,9 +313,7 @@ async function getData(params, values) {
   }
   if (!DATA_CACHE[key]) {
     if (!timeType) {
-      DATA_CACHE[key] = await getDeviceRealData({
-        ...params,
-      });
+      DATA_CACHE[key] = await getDeviceRealData(params);
     } else {
       if (timeType != -1) {
         let currentDate = moment();
@@ -262,84 +334,51 @@ async function getData(params, values) {
   return DATA_CACHE[key];
 }
 
-// 获取表单的options
-export async function getFormOptions(values, datas, projectId) {
-  let arrtData = values.data || [];
-  const params = getFormParams(datas, projectId);
-  if (!values.timeType) {
-    // 请求最新数据
-    let data = await getFormCurrentData(params, values);
-    let resData = data.map((item, index) => {
-      let attrDataItem = arrtData[index] || {};
+function getFormulaData(formula, plcData, formData, timeType) {
+  let expression = [...formula.expression];
+  let resDatas = formula.params.map(params => {
+    let res;
+    if (params.data_type == 0) {
+      res = findPlcData(params, plcData, timeType);
       return {
-        ...attrDataItem,
-        name: item.title,
-        value: item.value * 1,
+        ...params,
+        ...res,
       };
-    });
-    return {
-      ...values,
-      data: resData,
-    };
-  } else {
-    // 请求历史数据
-    let data = await getFormHistoryData(params, values);
-    values.data = data.map((item, i) => {
-      let attrDataItem = arrtData[i] || {};
+    } else {
+      res = findFormData(params, formData, timeType);
       return {
-        ...attrDataItem,
-        ...item,
+        ...params,
+        ...res,
       };
-    });
-
-    return values;
-  }
-}
-
-// 根据表单的数据项获取请求参数
-function getFormParams(datas, projectId) {
-  let params = {};
-  datas.forEach(item => {
-    if (!params[item.data_name]) params[item.data_name] = [];
-    params[item.data_name].push(item.data_title);
+    }
   });
-  return Object.keys(params).map(data_name => ({
-    formName: data_name,
-    titles: params[data_name],
-    projectId,
-  }));
-}
-
-// 请求表单最新数据
-async function getFormCurrentData(params, values) {
-  const { timeType, date } = values;
-  let data = [];
-  for (let i = 0; i < params.length; i++) {
-    const resData = await queryFormCurrentData(params[i]);
-    data = [...data, ...resData];
-  }
-  return data;
-}
 
-// 请求表单历史数据
-async function getFormHistoryData(params, values) {
-  const { timeType, date } = values;
-  let sTime, eTime;
-  let data = [];
-  // -1为自选日期  从date内获取时间
-  if (timeType == -1) {
-    let clear = { hour: 0, minute: 0, second: 0, millisecond: 0 };
-    eTime = moment(date[1]).set(clear) * 1;
-    sTime = moment(date[0]).set(clear) * 1;
+  if (timeType) {
+    let optionsData = [];
+    // 获取时间
+    let time = resDatas[0].data.map(item => item.htime);
+    time.forEach((htime, index) => {
+      resDatas.forEach(params => {
+        // 根据index去替换表达式中对应的值
+        expression[params.index] = params.data[index].val || 0;
+      });
+      optionsData.push({
+        htime: moment(htime).format('YYYY-MM-DD HH:mm:ss'),
+        val: computePrefixExpression([...expression]),
+      });
+    });
+    return {
+      data: optionsData,
+      name: formula.FormulaName,
+    };
   } else {
-    let currentDate = moment();
-    eTime = currentDate * 1;
-    sTime = currentDate.add(-1 * timeType, 'hour') * 1;
-  }
-
-  for (let i = 0; i < params.length; i++) {
-    const resData = await queryFormHistoryData({ ...params[i], eTime, sTime });
-    data = [...data, ...resData];
+    resDatas.forEach(params => {
+      // 根据index去替换表达式中对应的值
+      expression[params.index] = params.value || 0;
+    });
+    return {
+      value: computePrefixExpression([...expression]),
+      name: formula.FormulaName,
+    };
   }
-  return data;
 }

+ 1 - 1
src/models/dataMeterNew.js

@@ -68,7 +68,7 @@ export default {
         config_json: [],
       },
     },
-    chartConfigList: false,
+    chartConfigList: [],
     realProgress: {},
     progress: {},
     // currentChart: {}

+ 39 - 33
src/pages/Mobile/DataMeter/Chart.js

@@ -1,11 +1,11 @@
 import React, { useState, useEffect, useRef } from 'react';
-import echarts from 'echarts';
 import { connect } from 'dva';
 import moment from 'moment';
 import style from './Chart.less';
-import { getPlcOptions, getFormOptions } from '@/components/ChartUtils/utils';
+import { Card, Empty } from 'antd';
+import { getOptions } from '@/components/ChartUtils/utils';
 const dataCache = {};
-console.log(style);
+
 function DataCenter(props) {
   const [chart, setChart] = useState();
   const [timer, setTimer] = useState();
@@ -14,7 +14,13 @@ function DataCenter(props) {
   const iframeRef = useRef();
   const signalRef = useRef();
   const [loading, setLoading] = useState(false);
-  const { chartConfigList, dispatch ,location:{query:{projectId}}} = props;
+  const {
+    chartConfigList,
+    dispatch,
+    location: {
+      query: { projectId },
+    },
+  } = props;
   // const { projectId } = props.location; //?
   // const projectId = 92;
 
@@ -43,11 +49,12 @@ function DataCenter(props) {
   }, [chartOptions]);
 
   useEffect(() => {
-    chartConfigList && handleClickTabs(chartConfigList[0].id);
+    if (chartConfigList && chartConfigList.length > 0) {
+      handleClickTabs(chartConfigList[0].id);
+    }
   }, [chartConfigList]);
 
   const getOptionsForConfig = item => {
-    console.log(item);
     setChartOptions(item);
     clearTimeout(timer);
     let t = setTimeout(() => {
@@ -60,17 +67,11 @@ function DataCenter(props) {
     let datas = chartOptions.configs;
     let values = chartOptions.options;
     let formula = JSON.parse(chartOptions.formula || '[]');
+    if (!datas) return;
     setLoading(true);
     try {
-      if (chartOptions.source === 0) {
-        // plc渲染数据
-        let options = await getPlcOptions(values, datas, formula);
-        iframeRef.current.contentWindow.render(options);
-      } else {
-        // 图表渲染数据
-        let options = await getFormOptions(values, datas, projectId);
-        iframeRef.current.contentWindow.render(options);
-      }
+      let options = await getOptions(values, datas, formula, projectId);
+      iframeRef.current.contentWindow.render(options);
     } catch (error) {
       console.log(error);
     }
@@ -79,27 +80,32 @@ function DataCenter(props) {
 
   return (
     <div className={style.body}>
-      <div className={style.title}>数据项</div>
-      <div className={style.listWrapper}>
-        <div className={style.list}>
+      <Card title="数据项" bodyStyle={{ padding: 0 }}>
+        <ul className={style.list}>
           {(chartConfigList || []).map(item => (
-            <div key={item.id} onClick={() => handleClickTabs(item.id)} className={style.listItem}>
+            <li
+              key={item.id}
+              style={{
+                border: chartOptions.id == item.id ? '1px solid #008dff' : '1px solid #fff',
+              }}
+              onClick={() => handleClickTabs(item.id)}
+            >
               {item.name}
-            </div>
+            </li>
           ))}
-        </div>
-      </div>
-      <div className={style.title}>图表</div>
-      <div className={style.chartWrapper} style={{ height: '43vh' }}>
-        <div style={{ paddingTop: '0.3rem', paddingRight: '0.6rem', overflow: 'hidden' }}>
-          <iframe
-            ref={iframeRef}
-            style={{ width: '100%', height: '43vh', border: 'none' }}
-            onLoad={renderChart}
-            srcDoc={chartOptions?.template?.Content}
-          ></iframe>
-        </div>
-      </div>
+        </ul>
+        {chartConfigList.length == 0 && (
+          <Empty style={{ color: '#fff', fontSize: 20, marginTop: 40 }} />
+        )}
+      </Card>
+      <Card title="图表" bodyStyle={{ paddingBottom: 0 }}>
+        <iframe
+          ref={iframeRef}
+          style={{ width: '100%', height: 'calc(50vh - 80px)', border: 'none' }}
+          onLoad={renderChart}
+          srcDoc={chartOptions?.template?.Content}
+        ></iframe>
+      </Card>
     </div>
   );
 }

+ 31 - 4
src/pages/Mobile/DataMeter/Chart.less

@@ -1,7 +1,18 @@
 .body {
   background-color: #0d1a2b;
   color: #fff;
-  height: 100%;
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  :global {
+    .ant-card {
+      background: transparent;
+      flex: 1;
+    }
+    .ant-card-head {
+      color: #fff;
+    }
+  }
 }
 
 .title {
@@ -16,8 +27,24 @@
 
 .list {
   display: flex;
-  justify-content: center;
+  justify-content: space-evenly;
   flex-wrap: wrap;
+  height: 100%;
+  max-height: calc(50vh - 74px);
+  overflow-y: auto;
+  padding: 10px;
+  margin: 0;
+  li {
+    width: 100%;
+    padding: 6px;
+    text-align: center;
+    color: #fff;
+    font-size: 14px;
+    margin-bottom: 10px;
+    &:last-child {
+      margin-bottom: 0;
+    }
+  }
 }
 
 .listItem {
@@ -29,6 +56,6 @@
   padding: 5px 0px;
 }
 
-.chartWrapper{
-	height: 40vh;
+.chartWrapper {
+  height: 40vh;
 }