Bläddra i källkod

perf(components): 优化“折线图”组件 UI与数据显示

wangshun 2 månader sedan
förälder
incheckning
d1db104cbe
1 ändrade filer med 106 tillägg och 43 borttagningar
  1. 106 43
      src/components/LineChart.vue

+ 106 - 43
src/components/LineChart.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { onMounted, ref } from 'vue';
+import { ref } from 'vue';
 import VChart from 'vue-echarts';
 import { LineChart, PieChart } from 'echarts/charts';
 import {
@@ -35,9 +35,10 @@ const list: number[] = [];
 
 interface Props {
   data: MonitoringPointData;
+  monitoringId?: number;
 }
 
-const emit = defineEmits(['editorClick']);
+const emit = defineEmits(['editorClick', 'historicalDataClick']);
 
 const props = defineProps<Props>();
 
@@ -51,48 +52,53 @@ const getCurvedData = () => {
   return list;
 };
 
-const maxValue = 20;
+const getColor = (value: number) => {
+  if (props.data.status === 1) {
+    if (value === 1) {
+      return '#32BAC0';
+    } else if (value === 2) {
+      return 'rgba(50,186,192,0.15)';
+    }
+  }
+
+  if (props.data.status === 2 || props.data.status === 3) {
+    if (value === 1) {
+      return '#F56C6C';
+    } else if (value === 2) {
+      return 'rgba(245,108,108,0.15)';
+    }
+  }
+
+  if (props.data.status === 0 || props.data.status === -1 || !props.data.status) {
+    if (value === 1) {
+      return '#999';
+    } else if (value === 2) {
+      return 'rgba(153,153,153,0.15)';
+    }
+  }
+};
 
 const option = ref({
-  backgroundColor: 'rgba(50, 186, 192, 0.15)',
-  grid: {
-    left: '5%',
-    right: '5%',
-    top: '5%',
-    bottom: '5%',
-    containLabel: true,
-    backgroundColor: 'rgba(50,186,192,0.15)',
-    borderRadius: 8,
-  },
+  backgroundColor: getColor(2),
+
   xAxis: {
     show: false, // 隐藏 X 轴
     type: 'category',
-    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
+    boundaryGap: false, // 关闭首尾留白
   },
   yAxis: {
-    type: 'value',
-    // max: maxValue, // 设置 Y 轴最大值
-    axisLine: { show: false }, // 隐藏轴线
-    axisTick: { show: false }, // 隐藏刻度
-    position: 'left',
-    axisLabel: {
-      show: true,
-      color: '#666',
-      formatter(value: number) {
-        // 只显示最大值标签
-        return value === maxValue ? value : '';
-      },
-    },
-    splitLine: {
-      show: false, // 关闭默认分割线
-    },
+    type: 'value', // 数值轴
+    min: 0, // 最小值
+    max: 100, // 最大值
+    interval: 20, // 刻度间隔
+    show: false, // 隐藏 X 轴
   },
   series: [
     {
       type: 'line',
       data: getCurvedData(),
       symbol: 'none', // 不显示数据点
-      color: '#32BAC0',
+      color: getColor(1),
       lineStyle: {
         width: 2,
       },
@@ -100,41 +106,69 @@ const option = ref({
         // 添加最大值虚线
         silent: true,
         symbol: 'none',
-        label: { show: false },
+
         lineStyle: {
           type: 'dashed',
-          color: '#333',
+          color: 'rgba(151,151,151,0.5)',
           width: 1,
         },
+        label: {
+          show: true, // 必须开启标签
+          position: 'insideStartTop', // 标签位置(左侧上方)
+          formatter: '{c}°C', // 显示值({c} 会自动替换为 yAxis 的值)
+          color: 'rgba(0,0,0,0.5)', // 文字颜色
+          verticalAlign: 'bottom', // 垂直对齐方式
+          offset: [-6, 0], // 微调位置 [水平偏移, 垂直偏移]
+          fontSize: '10px',
+        },
         data: [
           {
-            yAxis: maxValue, // 在最大值位置画线
+            yAxis: props.data.tempUpper, // 在最大值位置画线
           },
         ],
       },
     },
   ],
+  // 关键配置:调整 grid 边距
+  grid: {
+    top: 20, // 上边距为0
+    right: 8, // 右边距为0
+    bottom: 8, // 下边距为0
+    left: 8, // 左边距为0
+    containLabel: false, // 不包含坐标轴标签区域
+  },
 });
 
-onMounted(() => {});
 const editorMonitoring = (id: number) => {
   emit('editorClick', id);
 };
+
+const addHistoricalData = (data: MonitoringPointData) => {
+  emit('historicalDataClick', data);
+};
 </script>
 
 <template>
-  <div class="line-chart-content">
+  <div :class="monitoringId === data.id ? 'line-chart-content choose-content-border' : 'line-chart-content'">
     <AFlex justify="space-between" align="center">
       <div class="line-chart-header-text">{{ data.name }}</div>
       <SvgIcon class="line-chart-header-icon" @click="editorMonitoring(data.id)" name="adjustment" />
     </AFlex>
-    <div style="width: 172px; height: 94px; margin-top: 12px">
-      <VChart class="chart" :option="option" />
+    <div @click="addHistoricalData(data)" class="chart-container" style="cursor: pointer">
+      <VChart class="chart chart-bgc" :option="option" />
     </div>
     <AFlex justify="space-between" align="center" class="line-chart-footer">
       <AFlex align="center">
-        <AFlex justify="center" align="center" class="line-chart-footer-div">
-          <SvgIcon class="line-chart-icon" name="temperature"
+        <AFlex
+          justify="center"
+          align="center"
+          class="line-chart-footer-div"
+          :style="`background:${props.data.status === 0 || props.data.status === -1 || !props.data.status ? '#F0F0F0' : '#f2fcf9'}`"
+        >
+          <SvgIcon
+            class="line-chart-icon"
+            :style="`color:${props.data.status === 0 || props.data.status === -1 || !props.data.status ? '#999' : '#32BAC0'}`"
+            name="temperature"
         /></AFlex>
         <div>
           <span class="line-chart-footer-text">{{ data.temperature }}</span>
@@ -142,8 +176,15 @@ const editorMonitoring = (id: number) => {
         </div>
       </AFlex>
       <AFlex align="center">
-        <AFlex justify="center" align="center" class="line-chart-footer-div"
-          ><SvgIcon class="line-chart-icon" name="humidity"
+        <AFlex
+          justify="center"
+          align="center"
+          class="line-chart-footer-div"
+          :style="`background:${props.data.status === 0 || props.data.status === -1 || !props.data.status ? '#F0F0F0' : '#f2fcf9'}`"
+          ><SvgIcon
+            class="line-chart-icon"
+            :style="`color:${props.data.status === 0 || props.data.status === -1 || !props.data.status ? '#999' : '#32BAC0'}`"
+            name="humidity"
         /></AFlex>
         <div>
           <span class="line-chart-footer-text">{{ data.humidity }}</span>
@@ -155,9 +196,23 @@ const editorMonitoring = (id: number) => {
 </template>
 
 <style lang="scss" scoped>
+/* 确保图表区域继承光标样式 */
+.chart-container :deep(canvas) {
+  cursor: pointer !important;
+}
+
+.chart-bgc {
+  width: 172px;
+  height: 94px;
+  margin-top: 12px; /* 关键:隐藏图表溢出部分 */
+  overflow: hidden;
+  cursor: pointer;
+  border-radius: 8px; /* 圆角 */
+}
+
 .line-chart-icon {
   font-size: 16px;
-  color: var(--antd-color-primary-hover);
+  color: #32bac0;
 }
 
 .line-chart-footer-unit {
@@ -211,4 +266,12 @@ const editorMonitoring = (id: number) => {
   border-radius: 8px;
   box-shadow: 0 2px 6px 0 rgb(0 0 0 / 10%);
 }
+
+.choose-content-border {
+  border: 2px solid var(--antd-color-primary-hover);
+}
+
+.line-chart-content:hover {
+  border: 2px solid var(--antd-color-primary-hover);
+}
 </style>