wukai před 1 měsícem
rodič
revize
6b52f498de

+ 14 - 0
src/api/calc/calcStop.js

@@ -8,6 +8,20 @@ export function listCalcStop(query) {
         params: query
     })
 }
+export function gzStop(query) {
+    return request({
+        url: '/calc/calcStop/gz-stop',
+        method: 'get',
+        params: query
+    })
+}
+export function dsStop(query) {
+    return request({
+        url: '/calc/calcStop/ds-stop',
+        method: 'get',
+        params: query
+    })
+}
 export function statCalcStop(query) {
     return request({
         url: '/calc/calcStop/calc',

+ 438 - 0
src/views/calc/calcStop/dsStop.vue

@@ -0,0 +1,438 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="分析天数" prop="remark">
+        <el-select
+            v-model="queryParams.remark"
+            placeholder="请选择分析天数"
+            clearable
+            style="width: 150px;"
+            @change="handleDaysChange"
+        >
+          <el-option label="月(30天)" value="30"></el-option>
+          <el-option label="季度(90天)" value="90"></el-option>
+          <el-option label="半年(180天)" value="180"></el-option>
+          <el-option label="年(365天)" value="365"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="机台号" prop="deviceId">
+        <el-input
+            v-model="queryParams.deviceId"
+            placeholder="请输入机台号"
+            clearable
+            @input="handleDeviceIdChange"
+        />
+      </el-form-item>
+      <el-form-item label="分析结果" prop="result">
+        <el-select
+            v-model="queryParams.result"
+            placeholder="请选择分析结果"
+            clearable
+            style="width: 150px;"
+            @change="handleResultChange"
+        >
+          <el-option label="平稳" value="平稳"></el-option>
+          <el-option label="上升" value="上升"></el-option>
+          <el-option label="明显上升" value="明显上升"></el-option>
+          <el-option label="下降" value="下降"></el-option>
+          <el-option label="明显下降" value="明显下降"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleFilter">搜索</el-button>
+        <el-button icon="Refresh" @click="resetFilter">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 总体统计数据展示 -->
+    <el-card class="statistic-card" v-if="statistics">
+      <div class="statistic-container">
+        <div class="statistic-item">
+          <div class="statistic-label">设备总数:</div>
+          <div class="statistic-value">{{ statistics.totalDevices }}</div>
+        </div>
+        <div class="statistic-divider"></div>
+        <div class="statistic-item" v-for="(count, key) in statistics.trendCounts" :key="key">
+          <div class="statistic-label">{{ key }}:</div>
+          <div class="statistic-value">{{ count }}</div>
+        </div>
+      </div>
+      <!-- 群体分析结果展示 -->
+      <div class="group-analysis" v-if="groupAnalysisResult">
+        <el-alert
+          :title="groupAnalysisResult.message"
+          :type="groupAnalysisResult.type"
+          show-icon
+          :closable="false"
+        />
+      </div>
+    </el-card>
+
+    <el-table v-loading="loading" :data="filteredData" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <!--      <el-table-column label="ID" align="center" prop="id" />-->
+      <el-table-column label="机台号" align="center" prop="deviceId"/>
+      <el-table-column label="数据量" align="center" prop="dataNum"/>
+      <el-table-column label="斜率" align="center" prop="slope">
+        <template #default="scope">
+          {{ (scope.row.slope).toFixed(2) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="标准差" align="center" prop="stdDev">
+        <template #default="scope">
+          {{ (scope.row.stdDev).toFixed(2) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="趋势分析" align="center" prop="result">
+        <template #default="scope">
+          <el-link type="primary" @click="handleResultClick(scope.row)">{{ scope.row.result }}</el-link>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 图表弹窗 -->
+    <el-dialog :title="'设备[' + currentRow.deviceId + ']分析结果详情'" v-model="chartOpen" width="800px" append-to-body>
+      <div style="text-align: center; margin: 20px 0;">
+        <p>设备名称: {{ currentRow.deviceName }}</p>
+        <p>分析结果: {{ currentRow.result }}</p>
+      </div>
+      <div v-if="currentRow.list && currentRow.list.length > 0">
+        <!-- 使用ECharts展示折线图 -->
+        <div ref="chartRef" style="width: 100%; height: 400px;"></div>
+      </div>
+      <div v-else>
+        <p style="text-align: center;">暂无详细数据</p>
+      </div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="closeChart">关 闭</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="CalcStop">
+import {dsStop} from "@/api/calc/calcStop";
+import {getCurrentInstance, reactive, ref, toRefs, watch} from 'vue';
+import * as echarts from 'echarts';
+
+const {proxy} = getCurrentInstance();
+
+const calcStopList = ref([]);
+const filteredData = ref([]);
+const open = ref(false);
+const chartOpen = ref(false);  // 添加图表弹窗状态
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const title = ref("");
+const currentRow = ref({});  // 添加当前行数据
+const chartRef = ref(null);
+const statistics = ref(null); // 添加统计数据
+const groupAnalysisResult = ref(null); // 群体分析结果
+let chartInstance = null;
+
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 1000,
+    deviceId: null,
+    dataDate: null,
+    hour: null,
+    startTime: null,
+    endTime: null,
+    stopType: 2,
+    result: "",  // 设置默认选中值
+    remark: "90" // 默认选中90天(季度)
+  },
+  rules: {}
+});
+
+const {queryParams, form, rules} = toRefs(data);
+
+// 分析天数变化处理
+function handleDaysChange() {
+  getList(); // 分析天数变化时重新从后端获取数据
+}
+
+/** 查询停机数据统计列表 */
+function getList() {
+  loading.value = true;
+  // 将分析天数作为参数传递给后端
+  dsStop(queryParams.value).then(response => {
+    calcStopList.value = response.data;
+    filteredData.value = response.data; // 初始化过滤数据
+    statistics.value = response.statistics; // 保存统计数据
+    // 在数据加载完成后触发一次过滤,确保默认选中项生效
+    filterData();
+    loading.value = false;
+  });
+}
+
+// 计算统计数据
+function calculateStatistics(data) {
+  if (!data || !Array.isArray(data)) {
+    return;
+  }
+
+  // 计算设备总数
+  const totalDevices = data.length;
+
+  // 统计各趋势的数量
+  const trendCounts = {
+    "明显上升": 0,
+    "上升": 0,
+    "平稳": 0,
+    "下降": 0,
+    "明显下降": 0
+  };
+
+  data.forEach(item => {
+    if (trendCounts.hasOwnProperty(item.result)) {
+      trendCounts[item.result]++;
+    }
+  });
+
+  // 只有在没有从后端获取到统计数据时才使用计算的统计数据
+  if (!statistics.value) {
+    statistics.value = {
+      totalDevices,
+      trendCounts
+    };
+  }
+}
+
+// 机台号变化处理
+function handleDeviceIdChange() {
+  filterData();
+}
+
+// 分析结果变化处理
+function handleResultChange() {
+  filterData();
+}
+
+// 过滤数据
+function filterData() {
+  if (!calcStopList.value || !Array.isArray(calcStopList.value)) {
+    filteredData.value = [];
+    return;
+  }
+
+  // 如果没有过滤条件,返回所有数据
+  if (!queryParams.value.deviceId && !queryParams.value.result) {
+    filteredData.value = calcStopList.value;
+    // 重新设置原始统计数据
+    getList();
+    return;
+  }
+
+  filteredData.value = calcStopList.value.filter(item => {
+    // 根据机台号过滤(数字模糊匹配)
+    if (queryParams.value.deviceId &&
+        item.deviceId &&
+        item.deviceId.toString().indexOf(queryParams.value.deviceId) === -1) {
+      return false;
+    }
+
+    // 根据分析结果过滤
+    if (queryParams.value.result &&
+        item.result !== queryParams.value.result) {
+      return false;
+    }
+
+    return true;
+  });
+
+  // 根据过滤后的数据重新计算统计数据
+  calculateStatistics(filteredData.value);
+}
+
+/** 过滤操作 */
+function handleFilter() {
+  getList(); // 点击搜索按钮时重新从后端获取数据
+}
+
+/** 重置过滤操作 */
+function resetFilter() {
+  proxy.resetForm("queryRef");
+  queryParams.value.deviceId = null;
+  queryParams.value.remark = null; // 重置分析天数
+  getList(); // 重置时重新从后端获取数据
+}
+
+/** 处理分析结果点击事件 */
+function handleResultClick(row) {
+  currentRow.value = row;
+  chartOpen.value = true;
+
+  // 在弹窗打开后初始化图表
+  setTimeout(() => {
+    initChart();
+  }, 100);
+}
+
+// 初始化图表
+function initChart() {
+  if (chartRef.value) {
+    // 销毁之前的实例
+    if (chartInstance) {
+      chartInstance.dispose();
+    }
+
+    // 初始化新的实例
+    chartInstance = echarts.init(chartRef.value);
+
+    // 准备数据
+    const dates = currentRow.value.list.map(item => item.date);
+    const times = currentRow.value.list.map(item => item.times);
+
+    // 配置图表选项
+    const option = {
+      title: {
+        text: '停机次数趋势图',
+        left: 'center'
+      },
+      tooltip: {
+        trigger: 'axis'
+      },
+      xAxis: {
+        type: 'category',
+        data: dates,
+        name: '日期'
+      },
+      yAxis: {
+        type: 'value',
+        name: '次数(次)'
+      },
+      series: [{
+        data: times,
+        type: 'line',
+        smooth: true,
+        markPoint: {
+          data: [
+            { type: 'max', name: '最大值' },
+            { type: 'min', name: '最小值' }
+          ]
+        },
+        markLine: {
+          data: [
+            { type: 'average', name: '平均值' }
+          ]
+        }
+      }]
+    };
+
+    // 设置配置项
+    chartInstance.setOption(option);
+  }
+}
+
+/** 关闭图表弹窗 */
+function closeChart() {
+  chartOpen.value = false;
+  // 销毁图表实例
+  if (chartInstance) {
+    chartInstance.dispose();
+    chartInstance = null;
+  }
+}
+
+// 群体分析算法
+function analyzeGroupPattern() {
+  if (!statistics.value || !statistics.value.trendCounts) {
+    groupAnalysisResult.value = null;
+    return;
+  }
+
+  const { trendCounts } = statistics.value;
+
+  // 计算上升趋势的设备数量(包括"上升"和"明显上升")
+  const risingCount = (trendCounts["上升"] || 0) + (trendCounts["明显上升"] || 0);
+
+  // 计算总设备数
+  const totalCount = Object.values(trendCounts).reduce((sum, count) => sum + count, 0);
+
+  // 如果没有设备数据,则不显示分析结果
+  if (totalCount === 0) {
+    groupAnalysisResult.value = null;
+    return;
+  }
+
+  // 计算上升趋势设备占比
+  const risingPercentage = (risingCount / totalCount) * 100;
+
+  // 判断标准:如果超过60%的设备呈现上升趋势,则判断为群体上升现象
+  if (risingPercentage > 60) {
+    groupAnalysisResult.value = {
+      type: "warning",
+      message: `群体分析:${risingPercentage.toFixed(1)}%的设备断纱频次呈上升趋势,判断纱线或环境(温湿度)可能存在质量问题,请重点关注!`
+    };
+  } else {
+    groupAnalysisResult.value = {
+      type: "success",
+      message: `群体分析:当前设备断纱频次趋势正常,无明显群体性质量问题。`
+    };
+  }
+}
+
+// 监听统计数据变化,触发群体分析
+watch(statistics, () => {
+  analyzeGroupPattern();
+}, { deep: true });
+
+getList();
+</script>
+
+<style scoped>
+.statistic-card {
+  margin-bottom: 20px;
+  background-color: #f5f7fa;
+  border: 1px solid #ebeef5;
+  border-radius: 4px;
+}
+
+.statistic-container {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+}
+
+.statistic-item {
+  display: flex;
+  align-items: center;
+  margin-right: 20px;
+  margin-bottom: 10px;
+}
+
+.statistic-label {
+  font-weight: bold;
+  margin-right: 5px;
+  color: #606266;
+}
+
+.statistic-value {
+  font-size: 16px;
+  font-weight: bold;
+  color: #409eff;
+}
+
+.statistic-divider {
+  width: 1px;
+  height: 20px;
+  background-color: #dcdfe6;
+  margin-right: 20px;
+  margin-bottom: 10px;
+}
+
+.group-analysis {
+  margin-top: 15px;
+  padding-top: 15px;
+  border-top: 1px solid #ebeef5;
+}
+</style>

+ 379 - 0
src/views/calc/calcStop/gzStop.vue

@@ -0,0 +1,379 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="分析天数" prop="remark">
+        <el-select
+            v-model="queryParams.remark"
+            placeholder="请选择分析天数"
+            clearable
+            style="width: 150px;"
+            @change="handleDaysChange"
+        >
+          <el-option label="月(30天)" value="30"></el-option>
+          <el-option label="季度(90天)" value="90"></el-option>
+          <el-option label="半年(180天)" value="180"></el-option>
+          <el-option label="年(365天)" value="365"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="机台号" prop="deviceId">
+        <el-input
+            v-model="queryParams.deviceId"
+            placeholder="请输入机台号"
+            clearable
+            @input="handleDeviceIdChange"
+        />
+      </el-form-item>
+      <el-form-item label="分析结果" prop="result">
+        <el-select
+            v-model="queryParams.result"
+            placeholder="请选择分析结果"
+            clearable
+            style="width: 150px;"
+            @change="handleResultChange"
+        >
+          <el-option label="平稳" value="平稳"></el-option>
+          <el-option label="上升" value="上升"></el-option>
+          <el-option label="明显上升" value="明显上升"></el-option>
+          <el-option label="下降" value="下降"></el-option>
+          <el-option label="明显下降" value="明显下降"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleFilter">搜索</el-button>
+        <el-button icon="Refresh" @click="resetFilter">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 总体统计数据展示 -->
+    <el-card class="statistic-card" v-if="statistics">
+      <div class="statistic-container">
+        <div class="statistic-item">
+          <div class="statistic-label">设备总数:</div>
+          <div class="statistic-value">{{ statistics.totalDevices }}</div>
+        </div>
+        <div class="statistic-divider"></div>
+        <div class="statistic-item" v-for="(count, key) in statistics.trendCounts" :key="key">
+          <div class="statistic-label">{{ key }}:</div>
+          <div class="statistic-value">{{ count }}</div>
+        </div>
+      </div>
+    </el-card>
+
+    <el-table v-loading="loading" :data="filteredData" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <!--      <el-table-column label="ID" align="center" prop="id" />-->
+      <el-table-column label="机台号" align="center" prop="deviceId"/>
+      <el-table-column label="数据量" align="center" prop="dataNum"/>
+      <el-table-column label="斜率" align="center" prop="slope">
+        <template #default="scope">
+          {{ (scope.row.slope).toFixed(2) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="标准差" align="center" prop="stdDev">
+        <template #default="scope">
+          {{ (scope.row.stdDev).toFixed(2) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="趋势分析" align="center" prop="result">
+        <template #default="scope">
+          <el-link type="primary" @click="handleResultClick(scope.row)">{{ scope.row.result }}</el-link>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 图表弹窗 -->
+    <el-dialog :title="'设备[' + currentRow.deviceId + ']分析结果详情'" v-model="chartOpen" width="800px"
+               append-to-body>
+      <div style="text-align: center; margin: 20px 0;">
+        <p>设备名称: {{ currentRow.deviceName }}</p>
+        <p>分析结果: {{ currentRow.result }}</p>
+      </div>
+      <div v-if="currentRow.list && currentRow.list.length > 0">
+        <!-- 使用ECharts展示折线图 -->
+        <div ref="chartRef" style="width: 100%; height: 400px;"></div>
+      </div>
+      <div v-else>
+        <p style="text-align: center;">暂无详细数据</p>
+      </div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="closeChart">关 闭</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="CalcStop">
+import {gzStop} from "@/api/calc/calcStop";
+import {getCurrentInstance, reactive, ref, toRefs} from 'vue';
+import * as echarts from 'echarts';
+
+const {proxy} = getCurrentInstance();
+
+const calcStopList = ref([]);
+const filteredData = ref([]);
+const open = ref(false);
+const chartOpen = ref(false);  // 添加图表弹窗状态
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const title = ref("");
+const currentRow = ref({});  // 添加当前行数据
+const chartRef = ref(null);
+const statistics = ref(null); // 添加统计数据
+let chartInstance = null;
+
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 1000,
+    deviceId: null,
+    dataDate: null,
+    hour: null,
+    startTime: null,
+    endTime: null,
+    stopType: 5,
+    result: "明显上升",  // 设置默认选中值
+    remark: "90" // 默认选中90天(季度)
+  },
+  rules: {}
+});
+
+const {queryParams, form, rules} = toRefs(data);
+
+// 分析天数变化处理
+function handleDaysChange() {
+  getList(); // 分析天数变化时重新从后端获取数据
+}
+
+/** 查询停机数据统计列表 */
+function getList() {
+  loading.value = true;
+  gzStop(queryParams.value).then(response => {
+    calcStopList.value = response.data;
+    filteredData.value = response.data; // 初始化过滤数据
+    statistics.value = response.statistics; // 保存统计数据
+    loading.value = false;
+    // 在数据加载完成后触发一次过滤,确保默认选中项生效
+    filterData();
+  });
+}
+
+// 计算统计数据
+function calculateStatistics(data) {
+  if (!data || !Array.isArray(data)) {
+    return;
+  }
+
+  // 计算设备总数
+  const totalDevices = data.length;
+  
+  // 统计各趋势的数量
+  const trendCounts = {
+    "明显上升": 0,
+    "上升": 0,
+    "平稳": 0,
+    "下降": 0,
+    "明显下降": 0
+  };
+  
+  data.forEach(item => {
+    if (trendCounts.hasOwnProperty(item.result)) {
+      trendCounts[item.result]++;
+    }
+  });
+  
+  // 只有在没有从后端获取到统计数据时才使用计算的统计数据
+  if (!statistics.value) {
+    statistics.value = {
+      totalDevices,
+      trendCounts
+    };
+  }
+}
+
+// 机台号变化处理
+function handleDeviceIdChange() {
+  filterData();
+}
+
+// 分析结果变化处理
+function handleResultChange() {
+  filterData();
+}
+
+// 过滤数据
+function filterData() {
+  if (!calcStopList.value || !Array.isArray(calcStopList.value)) {
+    filteredData.value = [];
+    return;
+  }
+
+  // 如果没有过滤条件,返回所有数据
+  if (!queryParams.value.deviceId && !queryParams.value.result) {
+    filteredData.value = calcStopList.value;
+    // 重新设置原始统计数据
+    getList();
+    return;
+  }
+
+  filteredData.value = calcStopList.value.filter(item => {
+    // 根据机台号过滤(数字模糊匹配)
+    if (queryParams.value.deviceId &&
+        item.deviceId &&
+        item.deviceId.toString().indexOf(queryParams.value.deviceId) === -1) {
+      return false;
+    }
+
+    // 根据分析结果过滤
+    if (queryParams.value.result &&
+        item.result !== queryParams.value.result) {
+      return false;
+    }
+
+    return true;
+  });
+  
+  // 根据过滤后的数据重新计算统计数据
+  calculateStatistics(filteredData.value);
+}
+
+/** 过滤操作 */
+function handleFilter() {
+  filterData();
+}
+
+/** 重置过滤操作 */
+function resetFilter() {
+  proxy.resetForm("queryRef");
+  queryParams.value.deviceId = null;
+  queryParams.value.result = "明显上升"; // 重置时也保持默认选中
+  getList(); // 重置时重新从后端获取数据
+}
+
+/** 处理分析结果点击事件 */
+function handleResultClick(row) {
+  currentRow.value = row;
+  chartOpen.value = true;
+
+  // 在弹窗打开后初始化图表
+  setTimeout(() => {
+    initChart();
+  }, 100);
+}
+
+// 初始化图表
+function initChart() {
+  if (chartRef.value) {
+    // 销毁之前的实例
+    if (chartInstance) {
+      chartInstance.dispose();
+    }
+
+    // 初始化新的实例
+    chartInstance = echarts.init(chartRef.value);
+
+    // 准备数据
+    const dates = currentRow.value.list.map(item => item.date);
+    const times = currentRow.value.list.map(item => item.times);
+
+    // 配置图表选项
+    const option = {
+      title: {
+        text: '停机次数趋势图',
+        left: 'center'
+      },
+      tooltip: {
+        trigger: 'axis'
+      },
+      xAxis: {
+        type: 'category',
+        data: dates,
+        name: '日期'
+      },
+      yAxis: {
+        type: 'value',
+        name: '次数(次)'
+      },
+      series: [{
+        data: times,
+        type: 'line',
+        smooth: true,
+        markPoint: {
+          data: [
+            {type: 'max', name: '最大值'},
+            {type: 'min', name: '最小值'}
+          ]
+        },
+        markLine: {
+          data: [
+            {type: 'average', name: '平均值'}
+          ]
+        }
+      }]
+    };
+
+    // 设置配置项
+    chartInstance.setOption(option);
+  }
+}
+
+/** 关闭图表弹窗 */
+function closeChart() {
+  chartOpen.value = false;
+  // 销毁图表实例
+  if (chartInstance) {
+    chartInstance.dispose();
+    chartInstance = null;
+  }
+}
+
+getList();
+</script>
+
+<style scoped>
+.statistic-card {
+  margin-bottom: 20px;
+  background-color: #f5f7fa;
+  border: 1px solid #ebeef5;
+  border-radius: 4px;
+}
+
+.statistic-container {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+}
+
+.statistic-item {
+  display: flex;
+  align-items: center;
+  margin-right: 20px;
+  margin-bottom: 10px;
+}
+
+.statistic-label {
+  font-weight: bold;
+  margin-right: 5px;
+  color: #606266;
+}
+
+.statistic-value {
+  font-size: 16px;
+  font-weight: bold;
+  color: #409eff;
+}
+
+.statistic-divider {
+  width: 1px;
+  height: 20px;
+  background-color: #dcdfe6;
+  margin-right: 20px;
+  margin-bottom: 10px;
+}
+</style>

+ 57 - 10
src/views/dye/hour/calc.vue

@@ -166,7 +166,7 @@
           </el-table>
         </el-card>
       </el-col>
-    </el-row
+    </el-row>
 
         <!-- 分钟级数据弹窗 -->
     <el-dialog
@@ -648,7 +648,8 @@ function initMinuteChart0(minuteData, targetData) {
       xAxis: {
         type: 'category',
         boundaryGap: false,
-        data: timePoints
+        data: timePoints,
+        name: '分钟'
       },
       yAxis: {
         type: 'value',
@@ -659,7 +660,18 @@ function initMinuteChart0(minuteData, targetData) {
         type: 'line',
         data: completeValues,
         smooth: true,
-        showSymbol: false
+        showSymbol: false,
+        markPoint: {
+          data: [
+            { type: 'max', name: '最大值' },
+            { type: 'min', name: '最小值' }
+          ]
+        },
+        markLine: {
+          data: [
+            { type: 'average', name: '平均值' }
+          ]
+        }
       }]
     };
 
@@ -736,7 +748,8 @@ function initMinuteChart1(minuteData, targetData) {
       xAxis: {
         type: 'category',
         boundaryGap: false,
-        data: timePoints
+        data: timePoints,
+        name: '分钟'
       },
       yAxis: {
         type: 'value',
@@ -747,7 +760,18 @@ function initMinuteChart1(minuteData, targetData) {
         type: 'line',
         data: completeValues,
         smooth: true,
-        showSymbol: false
+        showSymbol: false,
+        markPoint: {
+          data: [
+            { type: 'max', name: '最大值' },
+            { type: 'min', name: '最小值' }
+          ]
+        },
+        markLine: {
+          data: [
+            { type: 'average', name: '平均值' }
+          ]
+        }
       }]
     };
 
@@ -808,7 +832,8 @@ function updateChart() {
       xAxis: {
         type: 'category',
         boundaryGap: false,
-        data: hours
+        data: hours,
+        name: '时间'
       },
       yAxis: {
         type: 'value',
@@ -819,7 +844,18 @@ function updateChart() {
         type: 'line',
         data: values,
         smooth: true,
-        showSymbol: false
+        showSymbol: false,
+        markPoint: {
+          data: [
+            { type: 'max', name: '最大值' },
+            { type: 'min', name: '最小值' }
+          ]
+        },
+        markLine: {
+          data: [
+            { type: 'average', name: '平均值' }
+          ]
+        }
       }]
     };
 
@@ -912,7 +948,8 @@ function updateChart1() {
       xAxis: {
         type: 'category',
         boundaryGap: false,
-        data: hours
+        data: hours,
+        name: '时间'
       },
       yAxis: {
         type: 'value',
@@ -923,7 +960,18 @@ function updateChart1() {
         type: 'line',
         data: values,
         smooth: true,
-        showSymbol: false
+        showSymbol: false,
+        markPoint: {
+          data: [
+            { type: 'max', name: '最大值' },
+            { type: 'min', name: '最小值' }
+          ]
+        },
+        markLine: {
+          data: [
+            { type: 'average', name: '平均值' }
+          ]
+        }
       }]
     };
 
@@ -1386,5 +1434,4 @@ const getTableColumnLabel = (list) => {
 const getMinuteTableColumnLabel = (label, unit) => {
   return label + (unit ? ' (' + unit + ')' : '');
 };
-
 </script>