echarts實現(xiàn)工廠機器狀態(tài)圖(模擬)

echarts實現(xiàn)工廠機器狀態(tài)圖

React中使用echart-for-react 實現(xiàn),前置準備

npm install echarts echarts-for-react  -S  
yarn add echarts echarts-for-react -S

案例中使用了ant,(阿里UI框架) 可裝可不裝
yarn add antd -S

實現(xiàn)如下:

WX20210722-145038@2x.png

index.tsx

// import './index.css';
import React, { Component, useState, useEffect, useRef } from 'react';
import { Card, Row, Col, Space } from 'antd';
import ReactEcharts from 'echarts-for-react';
//圖表函數(shù)
import {
  dataAssembly,
  formattered,
  formatters,
  formateText,
  renderItem,
} from './data';
const D = (props: any) => {
  //三種狀態(tài)的顏色
  const colors: string[] = ['#2f4554', '#d48265', '#c23531'];
  //三種狀態(tài)
  const state: string[] = ['待機', '運行', '宕機'];
  const actionRef = useRef(null);
  useEffect(() => {
    // 獲取圖表實例
    const echarts_instance = actionRef.current.getEchartsInstance();
    //定時器 繪圖
    const t = setInterval(() => {
      const arrData = dataAssembly();
      echarts_instance.setOption({
        series: [
          // 用空bar來顯示三個圖例
          { name: state[0], type: 'bar', data: [] },
          { name: state[1], type: 'bar', data: [] },
          { name: state[2], type: 'bar', data: [] },
          {
            type: 'custom',
            renderItem: renderItem,
            encode: {
              x: [1, 2], // data 中『維度1』和『維度2』對應到 X 軸
              y: 0, // data 中『維度0』對應到 Y 軸
            },
            data: arrData,
          },
        ],
      });
    }, 5000);
    return () => {
      clearInterval(t);
    };
  }, []);
  //繪制圖表
  const echartsDemo = (): {} => {
    //獲取data
    const arrData = dataAssembly();
    return {
      color: colors,
      tooltip: {
        //提示框
        formatter: (params) => {
          //數(shù)據(jù)格式化
          let stateText = formateText(params.color);
          let startTimer = formatters(params.value[1]);
          let endTimer = formatters(params.value[2]);
          //tips展示
          return (
            params.name +
            '    ' +
            `${stateText}時間:` +
            startTimer +
            '~' +
            endTimer
          );
        },
      },
      legend: {
        //圖例
        data: state,
        bottom: '1%',
        selectedMode: false, // 圖例設為不可點擊
        textStyle: {
          color: '#000',
        },
      },
      grid: {
        //繪圖網(wǎng)格
        left: '3%',
        right: '4%',
        top: '1%',
        bottom: '2%',
        containLabel: true,
        height: 500,
      },
      xAxis: {
        type: 'time',
        // interval: 1000, //以一個小時遞增
        min: new Date().getTime() - 1000 * 60 * 60 * 2, //將data里最小時間的整點時間設為min,否則min會以data里面的min為開始進行整點遞增
        splitNumber: 12, //分割段數(shù)
        axisLabel: {
          // margin: 1,
          rotate: 340, //刻度標簽旋轉(zhuǎn)的角度,在類目軸的類目標簽顯示不下的時候可以通過旋轉(zhuǎn)防止標簽之間重疊。
          formatter: formatters(new Date().getTime()),
        },
      },
      yAxis: {
        data: ['設備1', '設備2', '設備3', '設備4'],
      },
      series: [
        // 用空bar來顯示三個圖例
        { name: state[0], type: 'bar', data: [] },
        { name: state[1], type: 'bar', data: [] },
        { name: state[2], type: 'bar', data: [] },
        {
          type: 'custom',
          renderItem: renderItem,
          encode: {
            x: [1, 2], // data 中『維度1』和『維度2』對應到 X 軸
            y: 0, // data 中『維度0』對應到 Y 軸
          },
          data: arrData,
        },
      ],
    };
  };

  return (
    <div>
      <Row gutter={24}>
        <Col span={20}>
          <Card title="設備狀態(tài)圖" className="shadowBox">
            <ReactEcharts
              ref={actionRef}
              option={echartsDemo()}
              style={{ height: '550px' }}
            />
          </Card>
        </Col>
      </Row>
    </div>
  );
};

export default D;

data.ts

import * as echarts from 'echarts';
//數(shù)據(jù)組裝函數(shù)
const dataAssembly = (): void => {
  const assArray: any[] = [];
  //三種狀態(tài)
  const typesStatus = [
    {
      name: '運行',
      color: '#2f4554',
    },
    {
      name: '待機',
      color: '#d48265',
    },
    {
      name: '宕機',
      color: '#c23531',
    },
  ];
  //定義設備
  const categories: string[] = ['設備1', '設備2', '設備3', '設備4'];
  //獲取當前時間
  const nowData: number = new Date().getTime();
  //設置開始時間為過去兩個小時
  const inThePastTime: number = nowData - 1000 * 60 * 60 * 2;
  //組裝基本數(shù)據(jù)
  //時間
  const timerArr: number[] = [];
  //狀態(tài)
  const stateArr: string[] = [];
  const baseAssData = (timer?: number): void => {
    for (let index = 0; index < 24; index++) {
      stateArr.push(typesStatus[Math.floor(Math.random() * 3)]['name']);
      timerArr.push(timer as number + (1000 * 60 * 5) * index);
    }
  };
  // console.log(stateArr);
  // console.log(timerArr);
  baseAssData(inThePastTime);
  //組裝對象數(shù)據(jù)
  const assvalue = () => {
    for (let idx = 0; idx < 4; idx++) {
      for (let i = 0; i < 24; i++) {
        assArray.push({
          //設備名稱
          name: categories[idx],
          value: [
            //設備索引 作為y軸
            idx,
            //狀態(tài)開始時間
            timerArr[i],
            //狀態(tài)結(jié)束時間 i===23時候 ,timerArr[i+1] 不存在的
            i === 23 ? (timerArr[23] + 1000 * 60 * 5) : timerArr[i + 1],
          ],
          //狀態(tài)顏色
          itemStyle: {
            normal: {
              color: typesStatus[Math.floor(Math.random() * 3)]['color']
            }
          }
        })
      }
    }
    return assArray
  }
  return assvalue();
  // console.log(assArray);
}
// 時間格式化
const formattered = (val: number): number => {
  if (parseInt(val) < 10) {
    val = '0' + val;
  }
  return val;
};
const formatters = (value: number) => {
  const date = new Date(value);
  return (
    formattered(date.getHours()) +
    ':' +
    formattered(date.getMinutes()) +
    ':' +
    formattered(date.getSeconds())
  )
}
//狀態(tài)格式化
const formateText = (params: string) => {
  switch (params) {
    case '#2f4554':
      return '運行';
    case '#d48265':
      return '待機';
    case '#c23531':
      return '宕機';
    default:
      break;
  }
}
//坐標封裝函數(shù)抽取  //echarts自己封裝的方法
const renderItem = (params, api) => {
  //開發(fā)者自定義的圖形元素渲染邏輯,是通過書寫 renderItem 函數(shù)實現(xiàn)的
  const categoryIndex = api.value(0); //這里使用 api.value(0) 取出當前 dataItem 中第一個維度的數(shù)值。
  const start = api.coord([api.value(1), categoryIndex]); // 這里使用 api.coord(...) 將數(shù)值在當前坐標系中轉(zhuǎn)換成為屏幕上的點的像素值。
  const end = api.coord([api.value(2), categoryIndex]);
  const height = api.size([0, 1])[1] * 0.6;
  return {
    type: 'rect', // 表示這個圖形元素是矩形。還可以是 'circle', 'sector', 'polygon' 等等。
    shape: echarts.graphic.clipRectByRect(
      {
        // 矩形的位置和大小。
        x: start[0],
        y: start[1] - height / 2,
        width: end[0] - start[0],
        height: height,
      },
      {
        // 當前坐標系的包圍盒。
        x: params.coordSys.x,
        y: params.coordSys.y,
        width: params.coordSys.width,
        height: params.coordSys.height,
      },
    ),
    style: api.style(),
  };
}

export {
  dataAssembly, formattered, formatters, formateText, renderItem
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容