瀏覽代碼

设备状态信号机:饼图与侧栏展示"正常"段(浅蓝)

  DeviceStatusPie 之前在有故障时会过滤掉"正常",导致信号机即使
  绝大多数设备在线,圆环和侧栏也只看得到几个故障类型。本次让正常
  段始终参与渲染:

  - 侧栏:第一行固定显示"正常: N",其下跟随活跃故障项
  - 圆环:正常段按真实比例占大头(浅蓝 #5EC8FF),故障段保底
    10° 弧长,多出的角度从正常段扣除,保持总和不变
  - 检测器/红绿灯 mock 不含"正常",不受影响
画安 1 天之前
父節點
當前提交
7703482c83
共有 3 個文件被更改,包括 31 次插入15 次删除
  1. 29 13
      src/components/ui/DeviceStatusPie.vue
  2. 1 1
      src/components/ui/DeviceStatusTabs.vue
  3. 1 1
      src/mock/api.js

+ 29 - 13
src/components/ui/DeviceStatusPie.vue

@@ -70,19 +70,19 @@ export default {
     totalFaults() {
       return this.activeFaults.reduce((sum, item) => sum + Number(item.value), 0);
     },
-    // 饼图实际渲染的数据
+    // 饼图实际渲染的数据:正常段(若有)+ 活跃故障段,按真实比例分布
     pieData() {
-      if (this.activeFaults.length > 0) {
-        return this.activeFaults;
-      }
-      // 无故障,用正常项颜色画整圆
+      const normal = this.chartData.filter(item => item.name.indexOf('正常') !== -1 && Number(item.value) > 0);
+      const segments = [...normal, ...this.activeFaults];
+      if (segments.length > 0) return segments;
+      // 兜底:数据里既无正常也无故障,用正常项颜色画整圆
       const normalItem = this.chartData.find(item => item.name.indexOf('正常') !== -1);
-      return [{ name: '正常', value: 1, color: normalItem ? normalItem.color : '#A0E551' }];
+      return [{ name: '正常', value: 1, color: normalItem ? normalItem.color : '#5EC8FF' }];
     },
-    // 右侧面板:有故障显示故障项,无故障只显示正常
+    // 右侧面板:始终把"正常"放在第一行(若数据里有),其后跟随活跃故障
     panelData() {
-      if (this.activeFaults.length > 0) return this.activeFaults;
-      return this.chartData.filter(item => item.name.indexOf('正常') !== -1);
+      const normal = this.chartData.filter(item => item.name.indexOf('正常') !== -1);
+      return [...normal, ...this.activeFaults];
     }
   },
   watch: {
@@ -103,14 +103,30 @@ export default {
       if (!segments || !segments.length) return;
 
       const data = this.pieData;
-      const total = data.reduce((sum, item) => sum + Number(item.value), 0) || 1;
-      let currentOffset = 0;
+      const totalValue = data.reduce((sum, item) => sum + Number(item.value), 0) || 1;
+      const lengths = data.map(item => this.circumference * (Number(item.value) / totalValue));
 
+      // 故障段保底弧长:避免数量极小(如 1/980)时圆环上几乎看不到
+      // 仅当存在"正常"段可被扣减时启用,从正常段里把多出的弧长扣掉,保持总和不变
+      const normalIdx = data.findIndex(item => item.name.indexOf('正常') !== -1);
+      if (normalIdx >= 0) {
+        const minLen = this.circumference * (10 / 360); // 每段至少 10°
+        let extra = 0;
+        for (let i = 0; i < data.length; i++) {
+          if (i === normalIdx) continue;
+          if (lengths[i] > 0 && lengths[i] < minLen) {
+            extra += (minLen - lengths[i]);
+            lengths[i] = minLen;
+          }
+        }
+        lengths[normalIdx] = Math.max(0, lengths[normalIdx] - extra);
+      }
+
+      let currentOffset = 0;
       data.forEach((item, index) => {
         const segment = segments[index];
         if (!segment) return;
-        const percent = item.value / total;
-        const strokeLength = this.circumference * percent;
+        const strokeLength = lengths[index];
 
         segment.style.stroke = item.color;
         segment.style.strokeDasharray = `${strokeLength} ${this.circumference - strokeLength}`;

+ 1 - 1
src/components/ui/DeviceStatusTabs.vue

@@ -25,7 +25,7 @@ const defaultMockStatusData = {
     centerTitle: '98%',
     centerSubTitle: '980/1000',
     chartData: [
-        { name: '正常', value: 980, color: '#A0E551' },
+        { name: '正常', value: 980, color: '#5EC8FF' },
         { name: '故障', value: 0, color: '#D03030' }
     ]
   },

+ 1 - 1
src/mock/api.js

@@ -1129,7 +1129,7 @@ export async function apiGetDeviceFaultStatus() {
   const smTotal = snap.total
   const smFaultTotal = snap.faultTotal
   const smFaultList = [
-    { name: '正常', value: Math.max(0, smTotal - smFaultTotal), color: '#A0E551' },
+    { name: '正常', value: Math.max(0, smTotal - smFaultTotal), color: '#5EC8FF' },
     { name: '控制板报警', value: snap.ctrlBoard, color: '#FF7878' },
     { name: '相位板报警', value: snap.phaseBoard, color: '#E66565' },
     { name: '检测板报警', value: snap.detBoard, color: '#CC4848' },