ソースを参照

[Feat 2771] 可配置首页开发全矿井通风检测的图表

houzekong 9 ヶ月 前
コミット
40c6cdbad6

+ 83 - 0
src/components/chart/Chart.vue

@@ -0,0 +1,83 @@
+<template>
+  <div ref="chartRef" :style="{ height, width }"></div>
+</template>
+<script lang="ts">
+  import { defineComponent, PropType, ref, Ref, reactive, watchEffect } from 'vue';
+  import { useECharts } from '/@/hooks/web/useECharts';
+  import { EChartsOption } from 'echarts';
+  import { assign } from 'lodash-es';
+
+  // 这是一个仅提供基础功能的chart组件,数据需要自己处理,该组件仅用来挂载echart、处理事件等
+  export default defineComponent({
+    name: 'ChartBaisc',
+    props: {
+      /** 图表配置 */
+      option: {
+        type: Object,
+        default: () => ({}),
+      },
+      width: {
+        type: String as PropType<string>,
+        default: '100%',
+      },
+      height: {
+        type: String as PropType<string>,
+        default: 'calc(100vh - 78px)',
+      },
+    },
+    setup(props) {
+      const chartRef = ref<HTMLDivElement | null>(null);
+      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+      const option: EChartsOption = reactive({
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow',
+            label: {
+              show: true,
+              backgroundColor: '#333',
+            },
+          },
+        },
+        grid: {
+          left: 60,
+          right: 50,
+          bottom: 50,
+        },
+        xAxis: {
+          type: 'category',
+          data: [],
+        },
+        yAxis: {
+          type: 'value',
+          nameTextStyle: {
+            fontSize: 14,
+          },
+        },
+        series: [
+          {
+            name: 'bar',
+            type: 'bar',
+            showBackground: true,
+            backgroundStyle: {
+              color: 'rgba(220, 220, 220, 0.8)',
+            },
+            data: [],
+          },
+        ],
+      });
+
+      watchEffect(() => {
+        props.option && initCharts();
+      });
+
+      function initCharts() {
+        if (props.option) {
+          assign(option, props.option);
+        }
+        setOptions(option, false);
+      }
+      return { chartRef };
+    },
+  });
+</script>

+ 9 - 8
src/views/vent/home/configurable/components/DeviceWarning.vue

@@ -20,7 +20,7 @@
       <div class="timeline-item__label">{{ item.label }}</div>
       <div :class="`timeline-item__value_${item.color}`">{{ item.count }}</div>
     </div>
-    <div class="position-absolute timeline-component"></div>
+    <div class="timeline-component"></div>
   </div>
 </template>
 <script lang="ts" setup>
@@ -119,16 +119,16 @@
     background-image: url('@/assets/images/home-container/configurable/warn_icon_1.png');
   }
   .timeline-item__icon {
-    width: 54px;
-    height: 45px;
-    margin: 0 50px 0 50px;
+    width: 33px;
+    height: 35px;
+    margin-left: 50px;
     background-repeat: no-repeat;
+    background-position: center center;
   }
   .timeline-item__dot {
-    position: absolute;
     width: 10px;
     height: 10px;
-    left: 7px;
+    margin-left: 70px;
     background-color: @vent-gas-primary-bg;
     border-radius: 5px;
     position: relative;
@@ -145,7 +145,7 @@
   }
   .timeline-item__label {
     width: 100px;
-    margin-left: 100px;
+    margin-left: 70px;
   }
   .timeline-item__value_red {
     color: red;
@@ -169,10 +169,11 @@
     position: relative;
   }
   .timeline-component {
+    position: absolute;
     width: 2px;
     height: 180px;
     top: 20px;
-    left: 170px;
+    left: 162px;
     background-image: @vent-configurable-home-timeline;
   }
 </style>

+ 130 - 49
src/views/vent/home/configurable/components/MonitorCenter.vue

@@ -44,46 +44,18 @@
       </div>
     </div>
   </div>
-  <!-- <div class="justify-end monitor-center w-300px">
-    <div class="flex">
-      <Pie
-        class="w-50% text-center"
-        :option="chartOption"
-        :chart-data="[
-          {
-            value: 70,
-            name: 'A',
-          },
-          {
-            value: 30,
-            name: 'B',
-          },
-        ]"
-        height="100px"
-      />
-      <Pie
-        class="w-50% text-center"
-        :option="chartOption"
-        :chart-data="[
-          {
-            value: 70,
-            name: 'A',
-          },
-          {
-            value: 30,
-            name: 'B',
-          },
-        ]"
-        height="100px"
-      />
+  <div class="monitor-center flex flex-wrap w-240px ml-166px">
+    <div v-for="(item, i) in chartOptions" :key="`vhccmc-${i}`" class="w-100px m-10px">
+      <Chart class="w-100% m-auto" height="100px" :option="item.option" />
+      <div class="monitor-center__chart_title">{{ item.title }}</div>
     </div>
-  </div> -->
+  </div>
 </template>
 <script lang="ts" setup>
   import { onMounted, ref } from 'vue';
   import { list as cfgList } from '@/views/vent/deviceManager/configurationTable/configuration.api';
   import { list } from '@/views/vent/deviceManager/deviceTable/device.api';
-  import Pie from '/@/components/chart/Pie.vue';
+  import Chart from '/@/components/chart/Chart.vue';
   import { EChartsOption } from 'echarts';
   // import mapComponent from './components/3Dmap/index.vue';
 
@@ -128,28 +100,131 @@
     });
   }
 
-  // 图标相关
-  const chartOption: EChartsOption = {
-    series: [
+  // 图表相关
+  const chartOptions = [
+    { title: '外部漏风率', option: getChartOption(40) },
+    { title: '有效风量率', option: getChartOption(30) },
+    { title: '灵敏度A', option: getChartOption(20) },
+    { title: '灵敏度B', option: getChartOption(50) },
+  ];
+
+  function getChartOption(percent: number): EChartsOption {
+    const data = [
+      // 最下面的一环
       {
-        type: 'pie',
-        radius: ['50%', '75%'],
-        center: ['50%', '55%'],
-        data: [],
-        labelLine: { show: false },
+        // 中间展示数据的一环
+        name: 'root',
+        value: 100,
+        // itemStyle: item1,
+        children: [
+          {
+            value: percent,
+            name: 'node-0',
+            children: [
+              {
+                name: 'leaf-0-0',
+                value: percent,
+              },
+            ],
+          },
+          {
+            name: 'node-1',
+            value: 100 - percent,
+            itemStyle: {
+              color: 'transparent',
+            },
+            children: [
+              {
+                name: 'leaf-1-0',
+                value: 100 - percent,
+              },
+            ],
+          },
+        ],
+      },
+    ];
+
+    return {
+      title: {
+        text: percent + '%',
+        left: 'center',
+        top: 'center',
+        textStyle: {
+          color: '#0afff0',
+        },
+      },
+      grid: {
+        show: false,
+      },
+      xAxis: { show: false },
+      yAxis: { show: false },
+      series: {
+        startAngle: 270,
+        // radius: ['60%', '90%'],
+        nodeClick: false,
+        type: 'sunburst',
+        sort: undefined,
+        emphasis: {
+          focus: 'none',
+        },
         label: {
           show: false,
-          // formatter: '{b} \n ({d}%)',
-          // color: '#B1B9D3',
         },
+        labelLine: { show: false },
+        levels: [
+          {},
+          {
+            radius: ['60%', '65%'],
+            // 最靠内测的第一层
+            itemStyle: {
+              color: '#0afff0',
+            },
+          },
+          {
+            radius: ['70%', '90%'],
+            itemStyle: {
+              color: {
+                type: 'linear',
+                x: 0,
+                y: 0,
+                x2: 0,
+                y2: 1,
+                colorStops: [
+                  {
+                    offset: 0,
+                    color: '#55fdbf', // 0% 处的颜色
+                  },
+                  {
+                    offset: 0.6,
+                    color: '#4bcbff', // 0% 处的颜色
+                  },
+                  {
+                    offset: 1,
+                    color: '#56e6ff', // 100% 处的颜色
+                  },
+                ],
+              },
+              borderWidth: 0,
+            },
+          },
+          {
+            radius: ['95%', '100%'],
+            itemStyle: {
+              color: '#0afff0',
+            },
+          },
+        ],
         itemStyle: {
-          shadowBlur: 20,
-          shadowColor: '#259bcf',
+          borderWidth: 0,
+        },
+        tooltip: {
+          show: false,
         },
+        silent: true,
+        data,
       },
-    ],
-    color: ['#d9a1ff', '#00d1ff', '#82fe78'],
-  };
+    };
+  }
 
   onMounted(() => {
     fetchConfig();
@@ -196,4 +271,10 @@
       flex-basis: 20%;
     }
   }
+
+  .monitor-center__chart_title {
+    width: 100%;
+    text-align: center;
+    border-bottom: 1px solid @vent-configurable-home-light-border;
+  }
 </style>