From aa75a9d46ee325f0a92e42f733aabb1f92103aeb Mon Sep 17 00:00:00 2001
From: feiyu02 <risaku@163.com>
Date: 星期五, 28 三月 2025 17:44:29 +0800
Subject: [PATCH] 走航融合模块完成

---
 src/components/common/CheckButton.vue             |   70 ++
 src/constant/radio-options/options-jingan.js      |    2 
 src/views/historymode/HistoryMode.vue             |    2 
 src/model/GridDataDetail.js                       |   50 ++
 src/model/SatelliteGrid.js                        |  216 +++++++-
 src/utils/map/grid.js                             |   79 ++
 src/api/gridApi.js                                |   12 
 src/components.d.ts                               |    4 
 src/views/underwaymix/component/GridStyleTool.vue |  106 ++-
 src/views/realtimemode/RealtimeMode.vue           |    2 
 src/components/list/DescriptionsList.vue          |   31 +
 src/components/list/DescriptionsListItem.vue      |   37 +
 src/components/monitor/FactorLegend.vue           |    7 
 src/model/Legend.js                               |   12 
 src/components/monitor/FactorRadio.vue            |    5 
 src/api/index.js                                  |    6 
 src/main.js                                       |    2 
 src/views/underwaymix/UnderwayMixMode.vue         |  637 ++++++++++++------------
 src/components/grid/GridSearch.vue                |  170 +++++-
 src/constant/radio-options/options.js             |    4 
 20 files changed, 986 insertions(+), 468 deletions(-)

diff --git a/src/api/gridApi.js b/src/api/gridApi.js
index 83a8c4d..f9f4dff 100644
--- a/src/api/gridApi.js
+++ b/src/api/gridApi.js
@@ -150,6 +150,16 @@
     });
   },
 
+  mixUnderwayGridData(groupId, dataIdList) {
+    return $http
+      .post(`air/satellite/product/underway/mix`, dataIdList, {
+        params: {
+          groupId
+        }
+      })
+      .then((res) => res.data);
+  },
+
   buildUnderwayHeatmap(groupId, gridDataDetailList, searchLength) {
     return $http
       .post(
@@ -158,7 +168,7 @@
         {
           params: {
             groupId: groupId,
-            searchLength: 4
+            searchLength: searchLength
           }
         }
       )
diff --git a/src/api/index.js b/src/api/index.js
index 2f00044..559cc74 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -1,7 +1,7 @@
 import axios from 'axios';
 import { ElMessage } from 'element-plus';
 
-const debug = false;
+const debug = true;
 
 let ip1 = 'http://47.100.191.150:9029/';
 // console.log(import.meta.env);
@@ -10,8 +10,8 @@
 }
 
 if (debug) {
-  // ip1 = 'http://192.168.0.110:8084/';
-  ip1 = 'http://locahost:8084/';
+  ip1 = 'http://192.168.0.110:8084/';
+  // ip1 = 'http://locahost:8084/';
 }
 
 const $http = axios.create({
diff --git a/src/components.d.ts b/src/components.d.ts
index f0d1927..79e3bc0 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -17,6 +17,8 @@
     CoreMenu: typeof import('./components/core/CoreMenu.vue')['default']
     DataSummary: typeof import('./components/monitor/DataSummary.vue')['default']
     DataTable: typeof import('./components/monitor/DataTable.vue')['default']
+    DescriptionsList: typeof import('./components/list/DescriptionsList.vue')['default']
+    DescriptionsListItem: typeof import('./components/list/DescriptionsListItem.vue')['default']
     DeviceCreate: typeof import('./components/device/DeviceCreate.vue')['default']
     DeviceManage: typeof import('./components/device/DeviceManage.vue')['default']
     ElButton: typeof import('element-plus/es')['ElButton']
@@ -49,6 +51,8 @@
     ElSwitch: typeof import('element-plus/es')['ElSwitch']
     ElTable: typeof import('element-plus/es')['ElTable']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
+    ElTabPane: typeof import('element-plus/es')['ElTabPane']
+    ElTabs: typeof import('element-plus/es')['ElTabs']
     ElText: typeof import('element-plus/es')['ElText']
     FactorCheckbox: typeof import('./components/monitor/FactorCheckbox.vue')['default']
     FactorLegend: typeof import('./components/monitor/FactorLegend.vue')['default']
diff --git a/src/components/common/CheckButton.vue b/src/components/common/CheckButton.vue
index b7e06bb..c2d6715 100644
--- a/src/components/common/CheckButton.vue
+++ b/src/components/common/CheckButton.vue
@@ -4,17 +4,33 @@
     {{ checkValue ? activeText : inactiveText }}
   </el-button> -->
   <el-checkbox
-    v-model="checkValue"
+    ref="checkboxRef"
+    :disabled="loading"
+    :model-value="modelValue"
+    @update:model-value="(e) => emits('update:modelValue', e)"
     @change="handleChange"
     border
     size="small"
-    >{{ activeText }}</el-checkbox
   >
+    <template #default>
+      <el-space>
+        <el-icon v-if="loading" class="is-loading" color="#00fff2"><Loading /></el-icon>
+        {{ activeText }}
+      </el-space>
+    </template>
+  </el-checkbox>
 </template>
 <script setup>
 import { ref, onMounted, onUnmounted, watch } from 'vue';
+// import $ from 'jquery';
 
 const props = defineProps({
+  modelValue: {
+    type: Boolean
+  },
+  loading: {
+    type: Boolean
+  },
   defaultValue: {
     type: Boolean
   },
@@ -28,8 +44,9 @@
   }
 });
 
-const emits = defineEmits(['change']);
+const emits = defineEmits(['change', 'update:modelValue']);
 
+const checkboxRef = ref();
 const checkValue = ref(false);
 
 watch(
@@ -42,6 +59,44 @@
   { immediate: true }
 );
 
+watch(
+  () => props.loading,
+  (nV, oV) => {
+    if (nV != oV) {
+      // setTimeout(() => {
+      //   const e1 = checkboxRef.value.$el.querySelector('.el-checkbox__input');
+      //   console.log(e1);
+
+      //   // e1.classList.toggle('is-disabled');
+      //   e1.classList.toggle('checkbox__input_none');
+      //   const e2 = checkboxRef.value.$el.querySelector('.el-checkbox__label');
+      //   console.log(e2);
+      //   e2.classList.toggle('checkbox__label_nopadding');
+      // }, 500);
+
+      // if (props.id) {
+      //   console.log(
+      //     checkboxRef.value.$el.querySelector('.el-checkbox__input').classList
+      //   );
+      //   console.log(
+      //     checkboxRef.value.$el.querySelector('.el-checkbox__label').classList
+      //   );
+      // }
+    }
+  }
+);
+
+onMounted(() => {
+  if (props.id) {
+    console.log(
+      checkboxRef.value.$el.querySelector('.el-checkbox__input').classList
+    );
+    console.log(
+      checkboxRef.value.$el.querySelector('.el-checkbox__label').classList
+    );
+  }
+});
+
 function handleChange(value) {
   emits('change', value);
 }
@@ -49,6 +104,7 @@
 <style scoped>
 .el-checkbox {
   --el-checkbox-text-color: white;
+  /*--main-color: #00fff2;*/
   --main-color: #23dad1;
   --el-checkbox-checked-text-color: var(--main-color);
   --el-checkbox-checked-input-border-color: var(--main-color);
@@ -65,4 +121,12 @@
 .el-checkbox__input.is-disabled + span.el-checkbox__label {
   color: var(--el-color-primary);
 }
+
+:deep(.checkbox__input_none) {
+  display: none !important;
+}
+
+:deep(.checkbox__label_nopadding) {
+  padding-left: 0px;
+}
 </style>
diff --git a/src/components/grid/GridSearch.vue b/src/components/grid/GridSearch.vue
index c9d90a6..cbb977a 100644
--- a/src/components/grid/GridSearch.vue
+++ b/src/components/grid/GridSearch.vue
@@ -7,31 +7,117 @@
     width="300px"
   >
     <template #default>
-      <el-form
-        :inline="false"
-        ref="formRef"
-        label-position="right"
-        label-width="100px"
-      >
-        <el-form-item label="缃戞牸缂栧彿锛�">
-          <div>
-            {{ data.cellIndex }}
-          </div>
-        </el-form-item>
-        <el-form-item label="缁忕含搴︼細">
-          <div>
-            {{ data.longitude + ', ' + data.latitude }}
-          </div>
-        </el-form-item>
-        <el-form-item label="PM2.5锛�">
-          <div>
-            {{ data.pm25 + ' 渭g/m鲁' }}
-          </div>
-        </el-form-item>
-        <el-form-item label="鍥涜嚦鑼冨洿锛�">
-          <div>/</div>
-        </el-form-item>
-      </el-form>
+      <div v-if="data">
+        <DescriptionsList>
+          <DescriptionsListItem
+            label="缃戞牸缂栧彿"
+            :content="data.gridCell.cellIndex"
+          />
+          <DescriptionsListItem
+            label="缁忕含搴�"
+            :content="data.gridCell.longitude + ', ' + data.gridCell.latitude"
+          />
+          <DescriptionsListItem label="鍥涜嚦鑼冨洿" content="/" />
+        </DescriptionsList>
+
+        <el-tabs v-model="activeName" >
+          <el-tab-pane label="缃戞牸鏁版嵁" name="first">
+            <DescriptionsList>
+              <DescriptionsListItem
+                label="VOC"
+                :content="data.gridDataDetail.voc + ' 渭g/m鲁'"
+              />
+              <DescriptionsListItem
+                label="H2S"
+                :content="data.gridDataDetail.h2s + ' 渭g/m鲁'"
+              />
+              <!-- <DescriptionsListItem label="NO" :content="data.gridDataDetail.no + ' 渭g/m鲁'" /> -->
+              <DescriptionsListItem
+                label="NO2"
+                :content="data.gridDataDetail.no2 + ' 渭g/m鲁'"
+              />
+              <DescriptionsListItem
+                label="CO"
+                :content="data.gridDataDetail.co + ' 渭g/m鲁'"
+              />
+              <DescriptionsListItem
+                label="SO2"
+                :content="data.gridDataDetail.so2 + ' 渭g/m鲁'"
+              />
+              <DescriptionsListItem
+                label="O3"
+                :content="data.gridDataDetail.o3 + ' 渭g/m鲁'"
+              />
+              <DescriptionsListItem
+                label="PM25"
+                :content="data.gridDataDetail.pm25 + ' 渭g/m鲁'"
+              />
+              <DescriptionsListItem
+                label="PM10"
+                :content="data.gridDataDetail.pm10 + ' 渭g/m鲁'"
+              />
+              <DescriptionsListItem
+                label="娓╁害"
+                :content="data.gridDataDetail.temperature + ' 鈩�'"
+              />
+              <DescriptionsListItem
+                label="婀垮害"
+                :content="data.gridDataDetail.humidity + ' %'"
+              />
+              <DescriptionsListItem
+                label="椋庨��"
+                :content="data.gridDataDetail.windSpeed + ' m/s'"
+              />
+              <DescriptionsListItem
+                label="椋庡悜"
+                :content="data.gridDataDetail.windDirection + ' 掳'"
+              />
+            </DescriptionsList>
+          </el-tab-pane>
+          <template v-if="data.gridDataDetail.mixData">
+            <el-tab-pane
+              v-for="(d, i) in data.gridDataDetail.originDataList"
+              :key="i"
+              :label="d.dataId"
+              :name="`origin-${i}`"
+            >
+              <DescriptionsList>
+                <DescriptionsListItem label="VOC" :content="d.voc + ' 渭g/m鲁'" />
+                <DescriptionsListItem label="H2S" :content="d.h2s + ' 渭g/m鲁'" />
+                <!-- <DescriptionsListItem label="NO" :content="d.no + ' 渭g/m鲁'" /> -->
+                <DescriptionsListItem label="NO2" :content="d.no2 + ' 渭g/m鲁'" />
+                <DescriptionsListItem label="CO" :content="d.co + ' 渭g/m鲁'" />
+                <DescriptionsListItem label="SO2" :content="d.so2 + ' 渭g/m鲁'" />
+                <DescriptionsListItem label="O3" :content="d.o3 + ' 渭g/m鲁'" />
+                <DescriptionsListItem
+                  label="PM25"
+                  :content="d.pm25 + ' 渭g/m鲁'"
+                />
+                <DescriptionsListItem
+                  label="PM10"
+                  :content="d.pm10 + ' 渭g/m鲁'"
+                />
+                <DescriptionsListItem
+                  label="娓╁害"
+                  :content="d.temperature + ' 鈩�'"
+                />
+                <DescriptionsListItem
+                  label="婀垮害"
+                  :content="d.humidity + ' %'"
+                />
+                <DescriptionsListItem
+                  label="椋庨��"
+                  :content="d.windSpeed + ' m/s'"
+                />
+                <DescriptionsListItem
+                  label="椋庡悜"
+                  :content="d.windDirection + ' 掳'"
+                />
+              </DescriptionsList>
+            </el-tab-pane>
+          </template>
+        </el-tabs>
+      </div>
     </template>
     <template #footer> </template>
   </CardDialog>
@@ -44,21 +130,27 @@
 
 const dialogVisible = ref(false);
 
+const activeName = ref('first');
+
 const data = computed(() => {
   if (gridStore.selectedGridCellAndDataDetail) {
+    // const { gridCell, gridDataDetail } =
+    //   gridStore.selectedGridCellAndDataDetail;
+    // const res = [];
+    // // 濡傛灉缃戞牸鏁版嵁涓鸿瀺鍚堟暟鎹紝鍒欓渶瑕佸悓姝ュ睍绀哄嚭鍘熷鏁版嵁
+    // if (gridDataDetail.mixData) {
+    // }
     return {
-      cellIndex: gridStore.selectedGridCellAndDataDetail.gridCell.cellIndex,
-      longitude: gridStore.selectedGridCellAndDataDetail.gridCell.longitude,
-      latitude: gridStore.selectedGridCellAndDataDetail.gridCell.latitude,
-      pm25: gridStore.selectedGridCellAndDataDetail.gridDataDetail.pm25
+      gridCell: gridStore.selectedGridCellAndDataDetail.gridCell,
+      gridDataDetail: gridStore.selectedGridCellAndDataDetail.gridDataDetail,
+      extData: gridStore.selectedGridCellAndDataDetail.extData
     };
+    // console.log(gridStore.selectedGridCellAndDataDetail);
+    
+    // return undefined;
+    // return gridStore.selectedGridCellAndDataDetail;
   } else {
-    return {
-      cellIndex: '/',
-      longitude: '/',
-      latitude: '/',
-      pm25: '/'
-    };
+    return undefined;
   }
 });
 
@@ -72,3 +164,11 @@
   { deep: true }
 );
 </script>
+<style scoped>
+:deep(.el-tabs__item){
+  color: rgba(221, 221, 221, 0.806);
+}
+:deep(.is-active){
+  color: #f0ff1d;
+}
+</style>
diff --git a/src/components/list/DescriptionsList.vue b/src/components/list/DescriptionsList.vue
new file mode 100644
index 0000000..4afb85a
--- /dev/null
+++ b/src/components/list/DescriptionsList.vue
@@ -0,0 +1,31 @@
+<template>
+  <div class="title-wrapper">
+    <div v-if="title" class="fy-h2">{{ title }}</div>
+    <slot name="extra"></slot>
+  </div>
+  <table>
+    <tbody>
+      <slot></slot>
+    </tbody>
+  </table>
+</template>
+
+<script>
+export default {
+  props: {
+    title: String
+  }
+};
+</script>
+
+<style scoped>
+.title-wrapper {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+table {
+  width: 100%;
+}
+</style>
diff --git a/src/components/list/DescriptionsListItem.vue b/src/components/list/DescriptionsListItem.vue
new file mode 100644
index 0000000..2aeb245
--- /dev/null
+++ b/src/components/list/DescriptionsListItem.vue
@@ -0,0 +1,37 @@
+<template>
+  <tr>
+    <td v-if="label" class="td-1">{{ label }}</td>
+    <td v-else class="td-1"><slot name="label"></slot></td>
+    <td v-if="content" class="td-2">{{ content }}</td>
+    <td v-else class="td-2"><slot name="content"></slot></td>
+  </tr>
+</template>
+
+<script>
+export default {
+  props: {
+    label: String,
+    content: String
+  }
+};
+</script>
+
+<style scoped>
+tr {
+  font-size: var(--el-font-size-small);
+}
+td {
+  border: 1px solid rgba(255, 255, 255, 0.616);
+  padding: 2px 6px;
+}
+.td-1 {
+  width: 68px;
+  background-color: var(--bg-color-2);
+  color: white;
+}
+
+.td-2 {
+  color: white;
+  /* background-color: var(--el-fill-color-light); */
+}
+</style>
diff --git a/src/components/monitor/FactorLegend.vue b/src/components/monitor/FactorLegend.vue
index b87e4ce..bcd447d 100644
--- a/src/components/monitor/FactorLegend.vue
+++ b/src/components/monitor/FactorLegend.vue
@@ -128,11 +128,12 @@
           ', ' +
           color[3] +
           ')';
+        const { scale = 1, unit = '' } = factorUnit[name];
         legendList.push({
           color: bgColor,
-          min: r[0],
-          max: nextR ? nextR[0] : undefined,
-          unit: factorUnit[name] ? factorUnit[name].unit : ''
+          min: r[0] * scale,
+          max: nextR ? nextR[0] * scale : undefined,
+          unit: unit
         });
       }
 
diff --git a/src/components/monitor/FactorRadio.vue b/src/components/monitor/FactorRadio.vue
index 262228b..c686f68 100644
--- a/src/components/monitor/FactorRadio.vue
+++ b/src/components/monitor/FactorRadio.vue
@@ -26,7 +26,7 @@
   emits: ['change'],
   data() {
     return {
-      radio: defaultOptions(TYPE0)
+      radio: defaultOptions(TYPE0).value
     };
   },
   computed: {
@@ -43,7 +43,8 @@
   },
   methods: {
     handleChange(value) {
-      this.$emit('change', value);
+      const item = this.options.find((v) => v.value == value);
+      this.$emit('change', item.value, item);
       // todo 鍦板浘3d鍥惧儚鍒囨崲灞曠ず鐩戞祴鍥犲瓙
     }
   }
diff --git a/src/constant/radio-options/options-jingan.js b/src/constant/radio-options/options-jingan.js
index 5e65aa2..809e46a 100644
--- a/src/constant/radio-options/options-jingan.js
+++ b/src/constant/radio-options/options-jingan.js
@@ -31,4 +31,4 @@
 ];
 
 // 榛樿閫夐」 PM2.5
-export const default1 = option1[3].value;
+export const default1 = option1[3];
diff --git a/src/constant/radio-options/options.js b/src/constant/radio-options/options.js
index c2ab3ef..785b74e 100644
--- a/src/constant/radio-options/options.js
+++ b/src/constant/radio-options/options.js
@@ -46,7 +46,7 @@
 ];
 
 // 榛樿閫夐」 PM2.5
-export const default1 = option1[5].value;
+export const default1 = option1[5];
 
 export const option2 = [
   {
@@ -77,4 +77,4 @@
 ];
 
 // 榛樿閫夐」 娓╁害
-export const default2 = option2[0].value;
+export const default2 = option2[0];
diff --git a/src/main.js b/src/main.js
index a67936a..559499c 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,5 +1,5 @@
 import './assets/main.css';
-import './lib/jquery-3.5.1.min';
+// import './lib/jquery-3.5.1.min';
 
 import { createApp } from 'vue';
 import { createPinia } from 'pinia';
diff --git a/src/model/GridDataDetail.js b/src/model/GridDataDetail.js
new file mode 100644
index 0000000..cf90202
--- /dev/null
+++ b/src/model/GridDataDetail.js
@@ -0,0 +1,50 @@
+function getGridDataDetailFactorValue(gdd, factorName) {
+  let value;
+  switch (factorName) {
+    case 'VOC':
+      value = gdd.voc;
+      break;
+    case 'H2S':
+      value = gdd.h2s;
+      break;
+    case 'NO':
+      value = gdd.no;
+      break;
+    case 'NO2':
+      value = gdd.no2;
+      break;
+    case 'CO':
+      value = gdd.co;
+      break;
+    case 'SO2':
+      value = gdd.so2;
+      break;
+    case 'O3':
+      value = gdd.o3;
+      break;
+    case 'PM25':
+      value = gdd.pm25;
+      break;
+    case 'PM10':
+      value = gdd.pm10;
+      break;
+    case 'TEMPERATURE':
+      value = gdd.temperature;
+      break;
+    case 'HUMIDITY':
+      value = gdd.humidity;
+      break;
+    case 'WIND_SPEED':
+      value = gdd.windSpeed;
+      break;
+    case 'WIND_DIRECTION':
+      value = gdd.windDirection;
+      break;
+    default:
+      value = gdd.pm25;
+      break;
+  }
+  return Math.round(value * 10) / 10;
+}
+
+export { getGridDataDetailFactorValue };
diff --git a/src/model/Legend.js b/src/model/Legend.js
index 05ee593..1492cbf 100644
--- a/src/model/Legend.js
+++ b/src/model/Legend.js
@@ -10,7 +10,7 @@
   _legend_r: {
     NO: [0, 100, 200, 700, 1200, 2340],
     NO2: [0, 100, 200, 700, 1200, 2340],
-    CO: [0, 5, 10, 35, 60, 90],
+    CO: [0, 5000, 10000, 35000, 60000, 90000],
     H2S: [0, 150, 500, 650, 800, 1600],
     SO2: [0, 150, 500, 650, 800, 1600],
     O3: [0, 160, 200, 300, 400, 800],
@@ -164,10 +164,6 @@
     //   }
     //   max = parseInt(key)
     // }
-    if (name == 'CO') {
-      min *= 1000;
-      max *= 1000;
-    }
 
     return [min, max];
   },
@@ -223,9 +219,6 @@
     for (let i = 0; i < range.length; i++) {
       const d = range[i];
       let d1 = d;
-      if (name == 'CO') {
-        d1 *= 1000;
-      }
       if (data >= d1) {
         selected = i;
       } else {
@@ -262,9 +255,6 @@
     for (let i = 0; i < range.length; i++) {
       const d = range[i];
       let d1 = d;
-      if (name == 'CO') {
-        d1 *= 1000;
-      }
       if (data >= d1) {
         selected = i;
       } else {
diff --git a/src/model/SatelliteGrid.js b/src/model/SatelliteGrid.js
index d6f3c8c..2ca4d43 100644
--- a/src/model/SatelliteGrid.js
+++ b/src/model/SatelliteGrid.js
@@ -1,7 +1,10 @@
 import calculate from '@/utils/map/calculate';
 import gridMapUtil from '@/utils/map/grid';
 import { map, onMapMounted } from '@/utils/map/index_old';
-import { useCloned } from '@vueuse/core';
+import { getGridDataDetailFactorValue } from '@/model/GridDataDetail';
+import { useGridStore } from '@/stores/grid-info';
+
+const gridStore = useGridStore();
 
 /**
  * 鍗槦閬ユ祴缃戞牸绠$悊
@@ -10,6 +13,9 @@
   constructor(name) {
     this.name = name;
   }
+
+  gridGroupId;
+  
   // 榛樿鍦板浘缃戞牸鐩稿叧瀵硅薄
   mapViews;
 
@@ -28,6 +34,14 @@
   firstEvent;
 
   events = new Map();
+
+  selectedFactorType;
+
+  setShowFactorType(e) {
+    this.selectedFactorType = e;
+    this.changeGridColor({ factorName: e.name });
+    this.changeText({ factorName: e.name });
+  }
 
   // 缁樺埗鍖哄幙杈圭晫
   drawDistrict(districtName, isNew) {
@@ -132,8 +146,7 @@
     const data = gridDataDetail.map((v, i) => {
       return {
         lnglat_GD: points[i],
-        // data: v.pm25 ? (v.pm25 + '渭g/m鲁') : ''
-        data: v.pm25 ? v.pm25 : ''
+        data: getGridDataDetailFactorValue(v, this.selectedFactorType.name)
       };
     });
     // return gridMapUtil.drawGridTextLabel(data, textViews, labelsLayer, 'bottom');
@@ -143,8 +156,54 @@
       anchor: 'top-center',
       type: 'data',
       isCustomColor,
-      useColor
+      useColor,
+      factorName: this.selectedFactorType.name
     });
+  }
+
+  changeText({ tags = [], factorName, isCustomColor, useColor, type }) {
+    let { _mapViewsList, _gridDataDetailList } = this._getMapViews(...tags);
+    if (_mapViewsList.length == _gridDataDetailList.length) {
+      _mapViewsList.forEach((v, i) => {
+        if (v.dataTxt) {
+          let dataList = [];
+          if (type == 'data' || type == undefined) {
+            dataList.push({
+              type: 'data',
+              data: _gridDataDetailList[i].map((v) => {
+                return {
+                  data: getGridDataDetailFactorValue(
+                    v,
+                    factorName ? factorName : this.selectedFactorType.name
+                  )
+                };
+              })
+            });
+          }
+          if (type == 'rank' || type == undefined) {
+            dataList.push({
+              type: 'rank',
+              data: _gridDataDetailList[i].map((v) => {
+                return {
+                  data: v.rank ? v.rank : ''
+                };
+              })
+            });
+          }
+
+          dataList.forEach((d) => {
+            gridMapUtil.changeGridText({
+              points: d.data,
+              textViews: d.type == 'data' ? v.dataTxt : v.rankTxt,
+              type: d.type,
+              isCustomColor,
+              useColor,
+              factorName: factorName ? factorName : this.selectedFactorType.name
+            });
+          });
+        }
+      });
+    }
   }
 
   // 缁樺埗鐩戞祴鏁版嵁鎺掑悕鏂囨湰
@@ -152,8 +211,7 @@
     const data = gridDataDetail.map((v, i) => {
       return {
         lnglat_GD: points[i],
-        // data: v.pm25 ? ('鎺掑悕: ' + v.rank) : ''
-        data: v.pm25 ? v.rank : ''
+        data: v.rank ? v.rank : ''
       };
     });
     // return gridMapUtil.drawGridTextLabel(data, textViews, labelsLayer, 'top');
@@ -161,7 +219,8 @@
       points: data,
       textViews,
       anchor: 'bottom-center',
-      type: 'rank'
+      type: 'rank',
+      factorName: this.selectedFactorType.name
     });
   }
 
@@ -196,12 +255,16 @@
     // 鏍规嵁缁樺埗棰滆壊鏂瑰紡缁樺埗缃戞牸
     let resGridViews;
     if (customColor) {
-      resGridViews = gridMapUtil.drawGridColorCustom(res, gridDataDetail);
+      resGridViews = gridMapUtil.drawGridColorCustom(
+        res,
+        gridDataDetail,
+        this.selectedFactorType.name
+      );
     } else {
       resGridViews = gridMapUtil.drawGridColor(
         res,
         gridDataDetail,
-        'PM25',
+        this.selectedFactorType.name,
         style
       );
     }
@@ -301,7 +364,12 @@
   }
 
   deleteTagGrid(tags) {
-    this.changeVisibility({ tags, showGridViews: false });
+    this.changeVisibility({
+      tags,
+      showGridViews: false,
+      showDataTxt: false,
+      showRankTxt: false
+    });
     tags.forEach((t) => {
       this.mapViewsMap.delete(t);
       this.gridDataDetailMap.delete(t);
@@ -316,12 +384,18 @@
       if (showGridViews) {
         // map.add(this.mapViews.lastGridViews);
         _mapViewsList.forEach((v) => {
-          if (v.lastGridViews) map.add(v.lastGridViews);
+          if (v.lastGridViews) {
+            map.add(v.lastGridViews);
+            v.show = true;
+          }
         });
       } else {
         // map.remove(this.mapViews.lastGridViews);
         _mapViewsList.forEach((v) => {
-          if (v.lastGridViews) map.remove(v.lastGridViews);
+          if (v.lastGridViews) {
+            map.remove(v.lastGridViews);
+            v.show = false;
+          }
         });
       }
     }
@@ -329,12 +403,18 @@
       if (showDataTxt) {
         // map.add(this.mapViews.dataTxt);
         _mapViewsList.forEach((v) => {
-          if (v.dataTxt) map.add(v.dataTxt);
+          if (v.dataTxt) {
+            map.add(v.dataTxt);
+            v.show = true;
+          }
         });
       } else {
         // map.remove(this.mapViews.dataTxt);
         _mapViewsList.forEach((v) => {
-          if (v.dataTxt) map.remove(v.dataTxt);
+          if (v.dataTxt) {
+            map.remove(v.dataTxt);
+            v.show = false;
+          }
         });
       }
     }
@@ -342,12 +422,18 @@
       if (showRankTxt) {
         // map.add(this.mapViews.rankTxt);
         _mapViewsList.forEach((v) => {
-          if (v.rankTxt) map.add(v.rankTxt);
+          if (v.rankTxt) {
+            map.add(v.rankTxt);
+            v.show = true;
+          }
         });
       } else {
         // map.remove(this.mapViews.rankTxt);
         _mapViewsList.forEach((v) => {
-          if (v.rankTxt) map.remove(v.rankTxt);
+          if (v.rankTxt) {
+            map.remove(v.rankTxt);
+            v.show = false;
+          }
         });
       }
     }
@@ -373,27 +459,30 @@
   }
 
   changeGridColor({
-    tag,
+    tags = [],
+    factorName,
     useCustomColor,
     opacity,
     zIndex,
     isMixGridHighlight
   }) {
-    let { _mapViewsList, _gridDataDetailList } = this._getMapViews(tag);
+    let { _mapViewsList, _gridDataDetailList } = this._getMapViews(...tags);
     if (_mapViewsList.length == _gridDataDetailList.length) {
       _mapViewsList.forEach((v, i) => {
         if (v.lastGridViews) {
+          if (useCustomColor != undefined) v.useCustomColor = useCustomColor;
           const lastGridDataDetail = _gridDataDetailList[i];
-          if (useCustomColor) {
+          if (v.useCustomColor) {
             gridMapUtil.drawGridColorCustom(
               v.lastGridViews,
-              lastGridDataDetail
+              lastGridDataDetail,
+              factorName ? factorName : this.selectedFactorType.name
             );
           } else {
             gridMapUtil.drawGridColor(
               v.lastGridViews,
               lastGridDataDetail,
-              'PM25',
+              factorName ? factorName : this.selectedFactorType.name,
               { opacity, zIndex, isMixGridHighlight }
             );
           }
@@ -428,9 +517,41 @@
           (v) => v.cellId == cellIndex
         );
         polygon.on(name, (e) => {
-          event(gridCell, gridDataDetail);
+          event({ gridCell, gridDataDetail, polygon, extData: v.extData });
         });
       });
+    });
+  }
+
+  setDefaultGridClickEvent(tags) {
+    this.setGridEvent(
+      tags,
+      'click',
+      ({ gridCell, gridDataDetail, extData }) => {
+        gridStore.selectedGridCellAndDataDetail = {
+          gridCell,
+          gridDataDetail,
+          extData
+        };
+      }
+    );
+
+    //榧犳爣绉诲叆浜嬩欢
+    this.setGridEvent(tags, 'mouseover', ({ polygon }) => {
+      const ext = polygon.getExtData();
+      const originOption = polygon.getOptions();
+      ext.originOption = originOption;
+      polygon.setOptions({
+        strokeWeight: 2,
+        strokeColor: 'red'
+      });
+      polygon.setExtData(ext);
+    });
+
+    //榧犳爣绉诲嚭浜嬩欢
+    this.setGridEvent(tags, 'mouseout', ({ polygon }) => {
+      const ext = polygon.getExtData();
+      polygon.setOptions(ext.originOption);
     });
   }
 
@@ -455,7 +576,7 @@
    * 閲嶅彔鐨勭綉鏍艰繘琛岀洃娴嬫暟鎹潎鍊艰绠楀苟閲嶆柊璁$畻瀵瑰簲棰滆壊锛屽舰鎴愭柊鐨勪竴缁勮瀺鍚堢綉鏍�
    * @param {Array} tags 闇�瑕佽瀺鍚堢殑缃戞牸鏍囩锛屽綋涓虹┖鏃讹紝榛樿铻嶅悎鎵�鏈夌綉鏍�
    */
-  mixGrid(tags, isMixGridHighlight) {
+  mixGrid({ tags, isMixGridHighlight = true }) {
     tags.sort((a, b) => {
       return a < b ? -1 : 1;
     });
@@ -465,7 +586,7 @@
         tags: [mixTag],
         showGridViews: true
       });
-      this.changeGridColor({ tag: mixTag, isMixGridHighlight });
+      this.changeGridColor({ tags: [mixTag], isMixGridHighlight });
     } else {
       // const mixMapViews = this._createNewMapViews();
       // 鏍规嵁鏍囩tag锛岃幏鍙栧搴斿缁勭綉鏍兼暟鎹�
@@ -502,7 +623,7 @@
         if (count > 1) {
           v.res.gridStyle = {
             strokeWeight: 2,
-            strokeColor: 'blue'
+            strokeColor: '#23dad1'
           };
         }
         resGridDataDetail.push(v.res);
@@ -520,8 +641,46 @@
         data: resGridDataDetail,
         grid: {
           style: {
-            isMixGridHighlight:
-              isMixGridHighlight == undefined ? true : isMixGridHighlight
+            isMixGridHighlight
+          }
+        },
+        extData: {
+          name: `璧拌埅铻嶅悎 - ${mixTag}`,
+          type: 1
+        }
+      });
+    }
+
+    return mixTag;
+  }
+
+  mixGrid2({ tags, isMixGridHighlight = true, gridDataDetailList }) {
+    tags.sort((a, b) => {
+      return a < b ? -1 : 1;
+    });
+    const mixTag = tags.join('-');
+    if (this.mapViewsMap.has(mixTag)) {
+      this.changeVisibility({
+        tags: [mixTag],
+        showGridViews: true
+      });
+      this.changeGridColor({ tags: [mixTag], isMixGridHighlight });
+    } else {
+      gridDataDetailList.forEach((gdd) => {
+        // 缃戞牸鏁版嵁鏄瀺鍚堢殑锛屽睍绀洪珮浜殑鏍峰紡
+        if (gdd.mixData) {
+          gdd.gridStyle = {
+            strokeWeight: 2,
+            strokeColor: '#23dad1'
+          };
+        }
+      });
+      this.drawTagGrid({
+        tag: mixTag,
+        data: gridDataDetailList,
+        grid: {
+          style: {
+            isMixGridHighlight
           }
         },
         extData: {
@@ -808,7 +967,8 @@
       }),
       gridPoints: JSON.parse(JSON.stringify(this.mapViews.gridPoints)),
       points: JSON.parse(JSON.stringify(this.mapViews.points)),
-      extData
+      extData,
+      show: true
     };
   }
 }
diff --git a/src/utils/map/grid.js b/src/utils/map/grid.js
index 235b390..dba3ced 100644
--- a/src/utils/map/grid.js
+++ b/src/utils/map/grid.js
@@ -4,6 +4,7 @@
 import { map } from './index_old';
 import calculate from './calculate';
 import { Legend } from '@/model/Legend';
+import { getGridDataDetailFactorValue } from '@/model/GridDataDetail';
 import { getHexColor, getColorBetweenTwoColors } from '../color';
 
 /**
@@ -80,11 +81,7 @@
   });
 }
 
-/**
- * 鏂囨湰鏍囪
- * 鍙慨鏀筽osition
- */
-function textMaker({ position, text, anchor, type, color }) {
+function textMakerStyle({ type, color }) {
   let style = {};
   if (type == 'data') {
     style = {
@@ -111,6 +108,15 @@
       'margin-bottom': '4px'
     };
   }
+  return style;
+}
+
+/**
+ * 鏂囨湰鏍囪
+ * 鍙慨鏀筽osition
+ */
+function textMaker({ position, text, anchor, type, color }) {
+  let style = textMakerStyle({ type, color });
   // eslint-disable-next-line no-undef
   return new AMap.Text({
     text: text,
@@ -280,11 +286,19 @@
     return gridViews;
   },
 
-  drawGridText({ points, textViews, anchor, type, isCustomColor, useColor }) {
+  drawGridText({
+    points,
+    textViews,
+    anchor,
+    type,
+    isCustomColor,
+    useColor,
+    factorName = 'PM25'
+  }) {
     let colorList = [];
     if (useColor) {
       colorList = calGridColor({
-        factorName: 'PM25',
+        factorName,
         data: points.map((p) => p.data),
         isCustomColor: isCustomColor
       });
@@ -305,6 +319,33 @@
     });
     // map.add(_textViews);
     return { textViews: _textViews };
+  },
+
+  changeGridText({
+    points,
+    textViews,
+    type,
+    isCustomColor,
+    useColor,
+    factorName = 'PM25'
+  }) {
+    let colorList = [];
+    if (useColor) {
+      colorList = calGridColor({
+        factorName,
+        data: points.map((p) => p.data),
+        isCustomColor: isCustomColor
+      });
+    }
+    if (textViews) {
+      textViews.forEach((t, i) => {
+        t.setText(points[i].data);
+        t.setStyle(
+          textMakerStyle({ type, color: useColor ? colorList[i] : 'white' })
+        );
+      });
+    }
+    return { textViews };
   },
 
   drawGridTextLabel(points, textViews, labelsLayer, direction) {
@@ -359,11 +400,11 @@
     const res = [];
     // 閬嶅巻鍗槦閬ユ祴鏁版嵁鏁扮粍
     gridDataDetail.forEach((d, i) => {
-      if (d.pm25) {
+      const data = getGridDataDetailFactorValue(d, factorName);
+      if (data) {
         const grid = gridViews[i];
 
         // 鏍规嵁閬ユ祴鏁版嵁璁$畻缃戞牸棰滆壊
-        const data = d.pm25;
         const { color, nextColor, range, nextRange } =
           Legend.getStandardColorAndNext(factorName, data);
         const ratio = (data - range) / (nextRange - range);
@@ -401,26 +442,26 @@
     return res;
   },
 
-  drawGridColorCustom(gridViews, gridDataDetail) {
-
+  drawGridColorCustom(gridViews, gridDataDetail, factorName) {
     var max, min;
     gridDataDetail.forEach((t) => {
-      if (!t.pm25) return;
-      if (!max || t.pm25 > max) {
-        max = t.pm25;
+      const data = getGridDataDetailFactorValue(t, factorName);
+      if (!data) return;
+      if (!max || data > max) {
+        max = data;
       }
-      if (!min || t.pm25 < min) {
-        min = t.pm25;
+      if (!min || data < min) {
+        min = data;
       }
     });
     const res = [];
     // 閬嶅巻鍗槦閬ユ祴鏁版嵁鏁扮粍
     gridDataDetail.forEach((d, i) => {
-      if (d.pm25) {
+      const data = getGridDataDetailFactorValue(d, factorName);
+      if (data) {
         const grid = gridViews[i];
 
         // 鏍规嵁閬ユ祴鏁版嵁璁$畻缃戞牸棰滆壊
-        const data = d.pm25;
         const { color, nextColor, range, nextRange } =
           Legend.getCustomColorAndNext(data, min, max);
         const ratio = (data - range) / (nextRange - range);
@@ -431,7 +472,7 @@
           ratio
         );
         grid.setOptions({
-          fillColor: _color, //澶氳竟褰㈠~鍏呴鑹�
+          fillColor: _color //澶氳竟褰㈠~鍏呴鑹�
           // fillOpacity: style.opacity ? style.opacity : color[3] == 0 ? 0 : 1
         });
 
diff --git a/src/views/historymode/HistoryMode.vue b/src/views/historymode/HistoryMode.vue
index d2a780e..212d022 100644
--- a/src/views/historymode/HistoryMode.vue
+++ b/src/views/historymode/HistoryMode.vue
@@ -81,7 +81,7 @@
       // 鐩戞祴璁惧缂栧彿
       deviceCode: '',
       // 鐩戞祴鍥犲瓙鐨勭被鍨嬬紪鍙�
-      factorType: defaultOptions(TYPE0),
+      factorType: defaultOptions(TYPE0).value,
       // 鐩戞祴鏁版嵁
       factorDatas: new FactorDatas(),
       // 鍐冲畾缁樺埗3D鍥惧舰鏃舵槸鍚︿笌鍘熷浘鍍忓悎骞�
diff --git a/src/views/realtimemode/RealtimeMode.vue b/src/views/realtimemode/RealtimeMode.vue
index 7fce948..240930d 100644
--- a/src/views/realtimemode/RealtimeMode.vue
+++ b/src/views/realtimemode/RealtimeMode.vue
@@ -56,7 +56,7 @@
       deviceType: TYPE0,
       deviceCode: '',
       // 鐩戞祴鍥犲瓙鐨勭被鍨嬬紪鍙�
-      factorType: defaultOptions(TYPE0),
+      factorType: defaultOptions(TYPE0).value,
       // 鏂拌幏鍙栫殑鐩戞祴鏁版嵁
       factorDatas: new FactorDatas(),
       // 鍏ㄩ儴鐩戞祴鏁版嵁
diff --git a/src/views/underwaymix/UnderwayMixMode.vue b/src/views/underwaymix/UnderwayMixMode.vue
index 2ed90d6..8cfb488 100644
--- a/src/views/underwaymix/UnderwayMixMode.vue
+++ b/src/views/underwaymix/UnderwayMixMode.vue
@@ -1,169 +1,146 @@
 <template>
   <!-- <div class="p-events-none m-t-2"> -->
-  <el-row justify="space-between">
+  <el-row class="m-t-2">
+    <FactorRadio @change="handleFactorTypeChange"></FactorRadio>
+  </el-row>
+  <el-row class="m-t-2" justify="space-between">
     <el-row class="wrap">
       <el-col span="2">
-        <el-row>
-          <BaseCard v-show="show" size="medium" direction="left">
-            <template #content>
-              <el-row>
+        <!-- <el-row> -->
+        <BaseCard v-show="show" size="medium" direction="left">
+          <template #content>
+            <!-- <el-row>
                 <el-form :inline="true">
-                  <!-- <el-form-item label="璧拌埅铻嶅悎">
-                    <el-select
-                      v-model="selectedfusionData"
-                      multiple
-                      clearable
-                      @change="handleChange"
-                      placeholder="閫夋嫨浠诲姟"
-                      size="small"
-                      style="width: 160px"
-                      :loading="fusionLoading"
-                    >
-                      <el-option
-                        v-for="(s, i) in fusionDataList"
-                        :key="i"
-                        :label="s.mixDataId"
-                        :value="i"
-                      />
-                    </el-select>
-                  </el-form-item> -->
-                  <!-- <el-form-item>
-                    <el-button
-                      type="primary"
-                      class="el-button-custom"
-                      size="small"
-                      :disabled="
-                        !gridCellList || selectedfusionData.length == 0
-                      "
-                      @click="handleFusionClick"
-                    >
-                      {{ '鍙犲姞璧拌埅' }}
-                    </el-button>
-                  </el-form-item> -->
+                  
                 </el-form>
-              </el-row>
-              <el-row class="m-t-8" justify="space-between">
-                <span>铻嶅悎鍒嗘瀽</span>
-              </el-row>
-              <el-form :inline="false">
-                <el-form-item label="鏃舵绛涢��">
-                  <el-select
-                    v-model="selectedTimeSection"
-                    multiple
-                    clearable
-                    placeholder="閫夋嫨鏃舵"
-                    size="small"
-                    style="width: 300px"
-                  >
-                    <el-option
-                      v-for="(v, i) in timeSectionList"
-                      :key="i"
-                      :label="v"
-                      :value="v"
-                    />
-                  </el-select>
-                </el-form-item>
-                <el-form-item label="鍖哄煙绛涢��">
-                  <el-select
-                    v-model="selectedZone"
-                    multiple
-                    clearable
-                    placeholder="閫夋嫨鍖哄煙"
-                    size="small"
-                    style="width: 300px"
-                  >
-                    <el-option
-                      v-for="(v, i) in zoneList"
-                      :key="i"
-                      :label="v"
-                      :value="v"
-                    />
-                  </el-select>
-                </el-form-item>
-                <el-form-item label="鑳屾櫙绛涢��">
-                  <el-select
-                    v-model="selectedPollutionDegree"
-                    multiple
-                    clearable
-                    placeholder="閫夋嫨鑳屾櫙"
-                    size="small"
-                    style="width: 300px"
-                  >
-                    <el-option
-                      v-for="(v, i) in pollutionDegreeList"
-                      :key="i"
-                      :label="v"
-                      :value="v"
-                    />
-                  </el-select>
-                </el-form-item>
-              </el-form>
-              <div v-if="!gridCellList">
-                <el-icon class="is-loading"><Loading /></el-icon>
-                缃戞牸淇℃伅鍔犺浇涓�...
-              </div>
-              <el-table
-                ref="tableRef"
-                :data="showFusionDataList"
-                table-layout="fixed"
-                size="default"
-                :show-overflow-tooltip="true"
-                border
-                height="50vh"
-                row-class-name="t-row-normal"
-                cell-class-name="t-cell"
-                header-row-class-name="t-header-row"
-                header-cell-class-name="t-header-cell"
-                :highlight-current-row="false"
-                @row-click="handleRowClick"
-                @selection-change="handleSelectionChange"
+              </el-row> -->
+            <el-row justify="space-between">
+              <span>铻嶅悎鍒嗘瀽</span>
+            </el-row>
+            <el-form :inline="false">
+              <el-form-item label="鏃舵绛涢��">
+                <el-select
+                  v-model="selectedTimeSection"
+                  multiple
+                  clearable
+                  placeholder="閫夋嫨鏃舵"
+                  size="small"
+                  style="width: 300px"
+                >
+                  <el-option
+                    v-for="(v, i) in timeSectionList"
+                    :key="i"
+                    :label="v.label"
+                    :value="v.value"
+                  />
+                </el-select>
+              </el-form-item>
+              <el-form-item label="鍖哄煙绛涢��">
+                <el-select
+                  v-model="selectedZone"
+                  multiple
+                  clearable
+                  placeholder="閫夋嫨鍖哄煙"
+                  size="small"
+                  style="width: 300px"
+                >
+                  <el-option
+                    v-for="(v, i) in zoneList"
+                    :key="i"
+                    :label="v.label"
+                    :value="v.value"
+                  />
+                </el-select>
+              </el-form-item>
+              <el-form-item label="鑳屾櫙绛涢��">
+                <el-select
+                  v-model="selectedPollutionDegree"
+                  multiple
+                  clearable
+                  placeholder="閫夋嫨鑳屾櫙"
+                  size="small"
+                  style="width: 300px"
+                >
+                  <el-option
+                    v-for="(v, i) in pollutionDegreeList"
+                    :key="i"
+                    :label="v.label"
+                    :value="v.value"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-form>
+            <el-space v-if="!gridCellList">
+              <el-icon class="is-loading"><Loading /></el-icon>
+              <el-text type="info">缃戞牸淇℃伅鍔犺浇涓�...</el-text>
+            </el-space>
+            <el-table
+              ref="tableRef"
+              :data="showFusionDataList"
+              table-layout="fixed"
+              size="small"
+              :show-overflow-tooltip="true"
+              border
+              height="45vh"
+              row-class-name="t-row-normal"
+              cell-class-name="t-cell"
+              header-row-class-name="t-header-row"
+              header-cell-class-name="t-header-cell"
+              :highlight-current-row="false"
+              @row-click="handleRowClick"
+              @select="handleSelectionChange"
+              @select-all="handleSelectionChange"
+            >
+              <el-table-column width="40" v-if="!gridCellList">
+                <template #default>
+                  <el-icon class="is-loading"><Loading /></el-icon>
+                </template>
+              </el-table-column>
+              <el-table-column
+                v-else
+                type="selection"
+                :selectable="selectable"
+                width="40"
               >
-                <el-table-column width="40" v-if="!gridCellList">
-                  <template #default>
-                    <el-icon class="is-loading"><Loading /></el-icon>
-                  </template>
-                </el-table-column>
-                <el-table-column
-                  v-else
-                  type="selection"
-                  :selectable="selectable"
-                  width="40"
-                />
-                <!-- <el-table-column
+                <!-- <template #header>
+                <span>閫夋嫨</span>
+              </template> -->
+              </el-table-column>
+              <!-- <el-table-column
                   type="index"
                   label="搴忓彿"
                   width="30"
                 /> -->
-                <el-table-column
-                  prop="dataTime"
-                  label="鏃堕棿"
-                  align="center"
-                  :formatter="timeFormatter"
-                  width="120"
-                />
-                <el-table-column
-                  prop="missionCode"
-                  label="浠诲姟缂栧彿"
-                  align="center"
-                  width="150"
-                />
-                <el-table-column
-                  prop="zone"
-                  label="鍖哄煙"
-                  align="center"
-                  width="50"
-                />
-                <el-table-column
-                  prop="pollutionDegree"
-                  label="姹℃煋鑳屾櫙"
-                  align="center"
-                  width="70"
-                />
-              </el-table>
+              <el-table-column
+                prop="dataTime"
+                label="鏃堕棿"
+                align="center"
+                :formatter="timeFormatter"
+                width="100"
+              />
+              <el-table-column
+                prop="missionCode"
+                label="浠诲姟缂栧彿"
+                align="center"
+                width="150"
+              />
+              <el-table-column
+                prop="zone"
+                label="鍖哄煙"
+                align="center"
+                width="50"
+              />
+              <el-table-column
+                prop="pollutionDegree"
+                label="姹℃煋鑳屾櫙"
+                align="center"
+                width="70"
+              />
+            </el-table>
 
-              <div class="m-t-8">鎿嶄綔</div>
-              <el-space class="m-t-8 m-b-8">
-                <!-- <el-button
+            <div class="m-t-8">鎿嶄綔</div>
+            <el-space class="m-t-8 m-b-8">
+              <!-- <el-button
                   type="primary"
                   class="el-button-custom"
                   size="small"
@@ -172,26 +149,34 @@
                 >
                   {{ '鍙犲姞璧拌埅' }}
                 </el-button> -->
-                <CheckButton
-                  active-text="铻嶅悎鍒嗘瀽"
-                  :default-value="false"
-                  @change="handleMixClick"
-                >
-                </CheckButton>
-              </el-space>
-            </template>
-            <template #footer> </template>
-          </BaseCard>
-        </el-row>
+              <el-button
+                type="primary"
+                class="el-button-custom"
+                size="small"
+                @click="handleMixClick"
+              >
+                {{ '铻嶅悎鍒嗘瀽' }}
+              </el-button>
+              <!-- <CheckButton
+                active-text="铻嶅悎鍒嗘瀽"
+                :default-value="false"
+                @change="handleMixClick"
+              >
+              </CheckButton> -->
+            </el-space>
+          </template>
+          <template #footer> </template>
+        </BaseCard>
+        <!-- </el-row> -->
       </el-col>
       <el-col span="2">
-        <el-row>
-          <CardButton
-            name="璧拌埅铻嶅悎"
-            direction="right"
-            @click="() => (show = !show)"
-          ></CardButton>
-        </el-row>
+        <!-- <el-row> -->
+        <CardButton
+          name="璧拌埅铻嶅悎"
+          direction="right"
+          @click="() => (show = !show)"
+        ></CardButton>
+        <!-- </el-row> -->
       </el-col>
     </el-row>
     <GridStyleTool
@@ -204,12 +189,16 @@
 </template>
 
 <script setup>
-import { ref, onMounted, onUnmounted, watch, computed } from 'vue';
+import { ref, toRaw, onMounted, onUnmounted, watch, computed } from 'vue';
 import moment from 'moment';
 import gridApi from '@/api/gridApi';
 import { SatelliteGrid } from '@/model/SatelliteGrid';
 import GridStyleTool from './component/GridStyleTool.vue';
 import { useGridStore } from '@/stores/grid-info';
+import { TYPE0 } from '@/constant/device-type';
+import { defaultOptions } from '@/constant/radio-options';
+import { useMessageBox } from '@/composables/messageBox';
+import { useCloned } from '@vueuse/core';
 
 const gridStore = useGridStore();
 
@@ -225,6 +214,16 @@
 });
 const show = ref(true);
 
+// 鐩戞祴鍥犲瓙鐨勭被鍨嬬紪鍙�
+const factorType = ref(defaultOptions(TYPE0));
+satelliteGrid.setShowFactorType(toRaw(factorType.value));
+
+function handleFactorTypeChange(e, item) {
+  factorType.value = item;
+  console.log(toRaw(factorType.value));
+  satelliteGrid.setShowFactorType(toRaw(factorType.value));
+}
+
 const mission = ref(undefined);
 
 const gridCellList = ref(undefined);
@@ -233,7 +232,7 @@
 const fusionLoading = ref(false);
 const fusionDataList = ref([]);
 const selectedfusionData = ref([]);
-const tableRef = ref()
+const tableRef = ref();
 const selectable = (row) => gridCellList.value;
 
 const gridDataDetailMap = new Map();
@@ -248,10 +247,11 @@
     const hour = moment(e.dayTimePeriodStart).hour();
     const t = e.dayTimePeriod;
     const option = {
+      label: `${t} ${moment(e.dayTimePeriodStart).format('HH:mm')} - ${moment(e.dayTimePeriodEnd).format('HH:mm')}`,
       value: t,
       index: hour
     };
-    if (res.indexOf(option) == -1) {
+    if (!res.find((v) => v.label == option.label)) {
       res.push(option);
     }
   });
@@ -269,7 +269,8 @@
 
   res = res.map((v) => {
     const count = rMap.get(v.value);
-    return `${v.value} (${count})`;
+    v.label = `${v.label} (${count ? count : 0})`;
+    return v;
   });
   return res;
 });
@@ -278,8 +279,12 @@
   let res = [];
   fusionDataList.value.forEach((e) => {
     const t = e.zone;
-    if (res.indexOf(t) == -1) {
-      res.push(t);
+    const option = {
+      label: t,
+      value: t
+    };
+    if (!res.find((v) => v.label == option.label)) {
+      res.push(option);
     }
   });
   const rMap = new Map();
@@ -291,8 +296,9 @@
   });
 
   res = res.map((v) => {
-    const count = rMap.get(v);
-    return `${v} (${count})`;
+    const count = rMap.get(v.value);
+    v.label = `${v.label} (${count ? count : 0})`;
+    return v;
   });
   return res;
 });
@@ -302,10 +308,11 @@
   fusionDataList.value.forEach((e) => {
     const t = e.pollutionDegree;
     const option = {
+      label: t,
       value: t,
       index: e.pollutionDegreeIndex
     };
-    if (res.indexOf(option) == -1) {
+    if (!res.find((v) => v.label == option.label)) {
       res.push(option);
     }
   });
@@ -322,7 +329,8 @@
 
   res = res.map((v) => {
     const count = rMap.get(v.value);
-    return `${v.value} (${count})`;
+    v.label = `${v.label} (${count ? count : 0})`;
+    return v;
   });
   return res;
 });
@@ -395,45 +403,32 @@
 // }
 
 function prepareGrid(gridInfo) {
-  satelliteGrid.gridPrepare(gridInfo, (polygon) => {
-    //榧犳爣绉诲叆浜嬩欢
-    polygon.on('mouseover', () => {
-      polygon.setOptions({
-        //淇敼澶氳竟褰㈠睘鎬х殑鏂规硶
-        strokeWeight: 2,
-        strokeColor: 'red'
-      });
-    });
-    //榧犳爣绉诲嚭浜嬩欢
-    polygon.on('mouseout', () => {
-      polygon.setOptions({
-        strokeWeight: 1,
-        strokeColor: 'white'
-      });
-    });
+  satelliteGrid.gridPrepare(gridInfo, function (polygon) {
+    // const originOption = polygon.getOptions();
+    // //榧犳爣绉诲叆浜嬩欢
+    // polygon.on('mouseover', () => {
+    //   polygon.setOptions({
+    //     //淇敼澶氳竟褰㈠睘鎬х殑鏂规硶
+    //     strokeWeight: 2,
+    //     strokeColor: 'red'
+    //   });
+    // });
+    // //榧犳爣绉诲嚭浜嬩欢
+    // polygon.on('mouseout', () => {
+    //   // polygon.setOptions({
+    //   //   strokeWeight: originOption.strokeWeight,
+    //   //   strokeColor: originOption.strokeColor
+    //   // });
+    //   polygon.setOptions(originOption);
+    // });
   });
-  // satelliteGrid.setGridEvent('click', (gridCell, gridDataDetail) => {
-  //   // const polygon = e.target
-  //   // const { gridCell } = polygon.getExtData();
-  //   // const cellIndex = gridCell.cellIndex;
-  //   gridStore.selectedGridCellAndDataDetail = {
-  //     gridCell,
-  //     gridDataDetail
-  //   };
-  // });
 }
-
-// watch(mission, (nV, oV) => {
-//   if (nV != oV) {
-//     checkUnderwayFusionResult();
-//     search(nV);
-//   }
-// });
 
 watch(
   () => props.groupId,
   (nV, oV) => {
     if (nV != oV) {
+      satelliteGrid.gridGroupId = nV;
       gridApi.fetchGridCell(nV).then((res) => {
         gridCellList.value = res.data;
         prepareGrid(gridCellList.value);
@@ -468,19 +463,18 @@
             type: 0
           }
         });
-        satelliteGrid.setGridEvent(
-          [d.id],
-          'click',
-          (gridCell, gridDataDetail) => {
-            gridStore.selectedGridCellAndDataDetail = {
-              gridCell,
-              gridDataDetail
-            };
-          }
-        );
+        satelliteGrid.setDefaultGridClickEvent([d.id]);
+        // satelliteGrid.setGridEvent(
+        //   [d.id],
+        //   'click',
+        //   (gridCell, gridDataDetail) => {
+        //     gridStore.selectedGridCellAndDataDetail = {
+        //       gridCell,
+        //       gridDataDetail
+        //     };
+        //   }
+        // );
         gridCtrls.value = [satelliteGrid];
-        // gridCtrls.value = Array.from(satelliteGrid.mapViewsMap);
-        // console.log(gridCtrls.value);
       });
     }
   });
@@ -488,35 +482,37 @@
 
 let mixTag;
 function handleMixClick() {
-  mixActive.value = !mixActive.value;
+  // mixActive.value = !mixActive.value;
   const tags = selectedfusionData.value.map((v) => v.id);
   satelliteGrid.changeVisibility({
     showGridViews: false,
     showDataTxt: false,
     showRankTxt: false
   });
-  if (mixActive.value) {
-    mixTag = satelliteGrid.mixGrid(tags);
-    satelliteGrid.setGridEvent(
-      [mixTag],
-      'click',
-      (gridCell, gridDataDetail) => {
-        gridStore.selectedGridCellAndDataDetail = {
-          gridCell,
-          gridDataDetail
-        };
-      }
-    );
+  // if (mixActive.value) {
+  gridApi.mixUnderwayGridData(props.groupId, tags).then((res) => {
+    mixTag = satelliteGrid.mixGrid2({ tags, gridDataDetailList: res.data });
+    satelliteGrid.setDefaultGridClickEvent([mixTag]);
     gridCtrls.value = [satelliteGrid];
-  } else {
-    satelliteGrid.changeVisibility({
-      tags,
-      showGridViews: true
-    });
-  }
+  });
+
+  // satelliteGrid.setGridEvent([mixTag], 'click', (gridCell, gridDataDetail) => {
+  //   gridStore.selectedGridCellAndDataDetail = {
+  //     gridCell,
+  //     gridDataDetail
+  //   };
+  // });
+  // gridCtrls.value = [satelliteGrid];
+  // } else {
+  // satelliteGrid.changeVisibility({
+  //   tags,
+  //   showGridViews: true
+  // });
+  // }
 }
 
 let heatTag;
+const heatMapSearchLength = 4;
 function handleHeatMapClick() {
   heatActive.value = !heatActive.value;
   satelliteGrid.changeVisibility({
@@ -525,34 +521,14 @@
     showRankTxt: false
   });
   if (heatActive.value) {
-    // heatTag = satelliteGrid.drawHeatGrid(mixTag);
-    // satelliteGrid.setGridEvent(
-    //   [heatTag],
-    //   'click',
-    //   (gridCell, gridDataDetail) => {
-    //     gridStore.selectedGridCellAndDataDetail = {
-    //       gridCell,
-    //       gridDataDetail
-    //     };
-    //   }
-    // );
-    // gridCtrls.value = [satelliteGrid];
-
     const data = satelliteGrid.gridDataDetailMap.get(mixTag);
-    gridApi.buildUnderwayHeatmap(3, data, 10).then((res) => {
-      heatTag = satelliteGrid.drawHeatGrid2(mixTag, res.data);
-      satelliteGrid.setGridEvent(
-        [heatTag],
-        'click',
-        (gridCell, gridDataDetail) => {
-          gridStore.selectedGridCellAndDataDetail = {
-            gridCell,
-            gridDataDetail
-          };
-        }
-      );
-      gridCtrls.value = [satelliteGrid];
-    });
+    gridApi
+      .buildUnderwayHeatmap(props.groupId, data, heatMapSearchLength)
+      .then((res) => {
+        heatTag = satelliteGrid.drawHeatGrid2(mixTag, res.data);
+        satelliteGrid.setDefaultGridClickEvent([heatTag]);
+        gridCtrls.value = [satelliteGrid];
+      });
   } else {
     satelliteGrid.changeVisibility({
       tags: [mixTag],
@@ -578,17 +554,18 @@
   console.log(res);
 }
 
-function handleUnderwayClick({ isShow, dataId }) {
+function handleUnderwayClick({ isShow, dataId, done }) {
   underwayVisible.value = !underwayVisible.value;
 
   if (isShow) {
-    draw(dataId);
+    draw(dataId).finally(() => done());
   } else {
     const d = fusionDataList.value.find((v) => v.id == dataId);
     const mission = missionStore.missionList.find((v) => {
       return v.missionCode == d.mixDataId;
     });
     mapLine.hideLine(mission.missionCode);
+    done();
   }
 }
 function handleFusionDelete(index, tag) {
@@ -596,18 +573,31 @@
   if (f) {
     // const i = selectedfusionData.value.indexOf(f);
     // selectedfusionData.value.splice(i, 1);
-    tableRef.value.toggleRowSelection(f, false)
+    tableRef.value.toggleRowSelection(f, false);
   }
 }
 
 function handleSelectionChange(val) {
+  console.log(val);
+
   const deleted = selectedfusionData.value.filter((v) => {
-    return val.indexOf(v) == -1;
+    return !val.find((t) => t.id == v.id);
   });
   const deletedIdList = deleted.map((d) => d.id);
   const added = val.filter((v) => {
-    return selectedfusionData.value.indexOf(v) == -1;
+    return !selectedfusionData.value.find((t) => t.id == v.id);
   });
+
+  if (val.length > 4) {
+    useMessageBox({
+      confirmMsg: '鏈�澶氬厑璁稿悓鏃跺睍绀�4娆¤蛋鑸褰�',
+      confirmTitle: '璧拌埅璁板綍閫夋嫨杩囧璀﹀憡'
+    });
+    added.forEach((a) => {
+      tableRef.value.toggleRowSelection(a, false);
+    });
+    return;
+  }
   // const addedIdList = added.map(d=>d.id)
 
   if (deletedIdList.length > 0) {
@@ -618,9 +608,8 @@
 
   added.forEach((i) => {
     const d = i;
-    gridApi.fetchGridDataDetail(d.id, d.groupId).then((res) => {
-      gridDataDetailMap.set(d.id, res.data);
-      const gdd = res.data;
+    if (gridDataDetailMap.has(d.id)) {
+      const gdd = gridDataDetailMap.get(d.id);
       satelliteGrid.drawTagGrid({
         tag: d.id,
         data: gdd,
@@ -629,21 +618,47 @@
           type: 0
         }
       });
-      satelliteGrid.setGridEvent(
-        [d.id],
-        'click',
-        (gridCell, gridDataDetail) => {
-          gridStore.selectedGridCellAndDataDetail = {
-            gridCell,
-            gridDataDetail
-          };
-        }
-      );
+      satelliteGrid.setDefaultGridClickEvent([d.id]);
+      // satelliteGrid.setGridEvent(
+      //   [d.id],
+      //   'click',
+      //   (gridCell, gridDataDetail) => {
+      //     gridStore.selectedGridCellAndDataDetail = {
+      //       gridCell,
+      //       gridDataDetail
+      //     };
+      //   }
+      // );
       gridCtrls.value = [satelliteGrid];
-    });
+    } else {
+      gridApi.fetchGridDataDetail(d.id, d.groupId).then((res) => {
+        gridDataDetailMap.set(d.id, res.data);
+        const gdd = res.data;
+        satelliteGrid.drawTagGrid({
+          tag: d.id,
+          data: gdd,
+          extData: {
+            name: `璧拌埅缃戞牸 - ${d.mixDataId}`,
+            type: 0
+          }
+        });
+        satelliteGrid.setDefaultGridClickEvent([d.id]);
+        // satelliteGrid.setGridEvent(
+        //   [d.id],
+        //   'click',
+        //   (gridCell, gridDataDetail) => {
+        //     gridStore.selectedGridCellAndDataDetail = {
+        //       gridCell,
+        //       gridDataDetail
+        //     };
+        //   }
+        // );
+        gridCtrls.value = [satelliteGrid];
+      });
+    }
   });
 
-  selectedfusionData.value = val;
+  selectedfusionData.value = useCloned(val).cloned.value;
 }
 
 /**璧拌埅杞ㄨ抗*******************************************************************/
@@ -673,8 +688,6 @@
 const drawMode = ref(0);
 // 鐩戞祴鏁版嵁
 const factorDataMap = new Map();
-// pm2.5
-const factorType = 6;
 
 function fetchMission() {
   missionLoading.value = true;
@@ -698,30 +711,7 @@
 }
 
 function draw(dataId) {
-  if (isUnmounted.value) return;
-
-  // selectedfusionData.value.forEach((i) => {
-  //   const d = fusionDataList.value[i];
-
-  //   const mission = missionStore.missionList.find((v) => {
-  //     return v.missionCode == d.mixDataId;
-  //   });
-
-  //   if (factorDataMap.has(mission.missionCode)) {
-  //     const fd = factorDataMap.get(mission.missionCode);
-  //     drawLine(mission.missionCode, fd);
-  //   } else {
-  //     search(mission).then((res) => {
-  //       const fd = new FactorDatas();
-  //       fd.setData(res.data, drawMode.value, () => {
-  //         fd.refreshHeight(factorType.value);
-  //         factorDataMap.set(mission.missionCode, fd);
-  //         drawLine(mission.missionCode, fd);
-  //       });
-  //     });
-  //   }
-  // });
-
+  if (isUnmounted.value) return Promise.resolve();
   const d = fusionDataList.value.find((v) => v.id == dataId);
   const mission = missionStore.missionList.find((v) => {
     return v.missionCode == d.mixDataId;
@@ -729,12 +719,13 @@
 
   if (factorDataMap.has(mission.missionCode)) {
     const fd = factorDataMap.get(mission.missionCode);
-    drawLine(mission.missionCode, fd);
+    fd.refreshHeight(factorType.value.value);
+    return Promise.resolve(drawLine(mission.missionCode, fd));
   } else {
-    search(mission).then((res) => {
+    return search(mission).then((res) => {
       const fd = new FactorDatas();
       fd.setData(res.data, drawMode.value, () => {
-        fd.refreshHeight(factorType.value);
+        fd.refreshHeight(factorType.value.value);
         factorDataMap.set(mission.missionCode, fd);
         drawLine(mission.missionCode, fd);
       });
@@ -744,9 +735,9 @@
 
 function drawLine(missionCode, fd) {
   // 鍒锋柊鍥句緥
-  const factor = fd.factor[factorType];
+  const factor = fd.factor[factorType.value.value];
   sector.clearSector();
-  fd.refreshHeight(factorType);
+  fd.refreshHeight(factorType.value.value);
   mapLine.drawTagLine(missionCode, fd, factor);
 }
 </script>
diff --git a/src/views/underwaymix/component/GridStyleTool.vue b/src/views/underwaymix/component/GridStyleTool.vue
index 6d16811..7429e04 100644
--- a/src/views/underwaymix/component/GridStyleTool.vue
+++ b/src/views/underwaymix/component/GridStyleTool.vue
@@ -28,6 +28,7 @@
                     type="primary"
                     icon="Close"
                     circle
+                    size="small"
                     @click="handleCloseClick(i, t, value)"
                   />
                   <!-- <el-icon><Close /></el-icon> -->
@@ -37,14 +38,25 @@
                 <!-- <el-text>{{ g.name }}</el-text> -->
                 <!-- <div class="m-t-8">缃戞牸瑕佺礌</div> -->
                 <el-row class="m-t-8" justify="space-between">
+                  <!-- <el-button
+                    type="primary"
+                    class="el-button-custom"
+                    size="small"
+                    @click="gridLoading = !gridLoading"
+                  >
+                    {{ '铻嶅悎鍒嗘瀽' }}
+                  </el-button> -->
                   <CheckButton
+                    :loading="gridLoading"
+                    v-model="value.show"
                     active-text="鏄剧ず缃戞牸"
                     inactive-text="闅愯棌缃戞牸"
-                    :default-value="true"
                     @change="(e) => handleGridClick(e, i, value)"
                   >
                   </CheckButton>
                   <CheckButton
+                    :loading="rankLoading"
+                    v-model="value.showRank"
                     active-text="鏄剧ず鎺掑悕"
                     inactive-text="闅愯棌鎺掑悕"
                     :default-value="false"
@@ -52,6 +64,8 @@
                   >
                   </CheckButton>
                   <CheckButton
+                    :loading="dataLoading"
+                    v-model="value.showData"
                     active-text="鏄剧ず鏁版嵁"
                     inactive-text="闅愯棌鏁版嵁"
                     :default-value="false"
@@ -61,6 +75,8 @@
                 </el-row>
                 <el-row class="m-t-8" justify="space-between">
                   <CheckButton
+                    :loading="colorLoading"
+                    v-model="value.showCustomColor"
                     active-text="缁樺埗瀵规瘮鑹�"
                     inactive-text="缁樺埗鏍囧噯鑹�"
                     :default-value="false"
@@ -68,6 +84,8 @@
                   >
                   </CheckButton>
                   <CheckButton
+                    :loading="heatMapLoading"
+                    v-model="value.showHeatMap"
                     active-text="椋庨櫓鐑姏鍥�"
                     inactive-text="椋庨櫓鐑姏鍥�"
                     :default-value="false"
@@ -75,7 +93,9 @@
                   >
                   </CheckButton>
                   <CheckButton
+                    :loading="underwayLoading"
                     v-if="value.extData.type == 0"
+                    v-model="value.showUnderway"
                     active-text="鏄剧ず璧拌埅杞ㄨ抗"
                     inactive-text="闅愯棌璧拌埅杞ㄨ抗"
                     :default-value="false"
@@ -83,7 +103,9 @@
                   >
                   </CheckButton>
                   <CheckButton
+                    :loading="highlightLoading"
                     v-if="value.extData.type == 1"
+                    v-model="value.highlightFusionGrid"
                     active-text="楂樹寒铻嶅悎缃戞牸"
                     :default-value="true"
                     @change="(e) => handleHighlightGridClick(e, i, value)"
@@ -140,6 +162,14 @@
   }
 });
 
+const gridLoading = ref(false);
+const rankLoading = ref(false);
+const dataLoading = ref(false);
+const colorLoading = ref(false);
+const heatMapLoading = ref(false);
+const underwayLoading = ref(false);
+const highlightLoading = ref(false);
+
 const emits = defineEmits(['showUnderway', 'onDelete']);
 
 const gridCtrlList = computed(() => {
@@ -150,6 +180,7 @@
         return {
           tag: v[0],
           extData: v[1].extData,
+          show: v[1].show,
           opacityValue: 1
         };
       })
@@ -159,61 +190,54 @@
 
 const show = ref(true);
 
-// const gridVisible = ref(false);
-// const rankVisible = ref(false);
-// const dataVisible = ref(false);
-// const isStandardColor = ref(true);
-// const isOpacity = ref(false);
-// const opacityValue = ref(0.7);
-
-// const emits = defineEmits([
-//   'showRank',
-//   'showData',
-//   'changeColor',
-//   'changeOpacity'
-// ]);
 function handleCloseClick(index, t, value) {
   const key = value.tag;
   toRaw(props.gridCtrls[index]).deleteTagGrid([key]);
-  gridCtrlList.value[index].views.splice(t, 1)
-  emits('onDelete', index, key)
+  gridCtrlList.value[index].views.splice(t, 1);
+  emits('onDelete', index, key);
 }
 
 function handleGridClick(e, index, value) {
+  gridLoading.value = true;
   const key = value.tag;
   toRaw(props.gridCtrls[index]).changeVisibility({
     tags: [key],
     showGridViews: e
   });
+  gridLoading.value = false;
 }
 
 function handleRankClick(e, index, value) {
+  rankLoading.value = true;
   const key = value.tag;
   toRaw(props.gridCtrls[index]).changeVisibility({
     tags: [key],
     showRankTxt: e
   });
+  rankLoading.value = false;
 }
 
 function handleDataClick(e, index, value) {
+  dataLoading.value = true;
   const key = value.tag;
   toRaw(props.gridCtrls[index]).changeVisibility({
     tags: [key],
     showDataTxt: e
   });
+  dataLoading.value = false;
 }
 
 function handleColorClick(e, index, value) {
+  colorLoading.value = true;
   const key = value.tag;
   toRaw(props.gridCtrls[index]).changeGridColor({
-    tag: key,
+    tags: [key],
     useCustomColor: e
   });
+  colorLoading.value = false;
 }
 
 function handleOpacityChange(e, index, value) {
-  console.log(e, index, value);
-
   const key = value.tag;
   // value.opacityValue = e;
   toRaw(props.gridCtrls[index]).changeGridOpacity({
@@ -223,18 +247,27 @@
 }
 
 function handleUnderwayClick(e, index, value) {
+  underwayLoading.value = true;
   emits('showUnderway', {
     isShow: e,
-    dataId: value.tag
+    dataId: value.tag,
+    done: () => (underwayLoading.value = false)
   });
 }
 
 function handleHighlightGridClick(e, index, value) {
-  toRaw(props.gridCtrls[index]).mixGrid(value.tag.split('-'), e);
+  highlightLoading.value = true;
+  toRaw(props.gridCtrls[index]).mixGrid({
+    tags: value.tag.split('-'),
+    isMixGridHighlight: e
+  });
+  highlightLoading.value = false;
 }
 
 let heatTag;
+const heatMapSearchLength = 4;
 function handleHeatMapClick(e, index, value) {
+  heatMapLoading.value = true;
   const _satelliteGrid = toRaw(props.gridCtrls[index]);
   _satelliteGrid.changeVisibility({
     showGridViews: false,
@@ -243,24 +276,29 @@
   });
   if (e) {
     const data = _satelliteGrid.gridDataDetailMap.get(value.tag);
-    gridApi.buildUnderwayHeatmap(3, data).then((res) => {
-      heatTag = _satelliteGrid.drawHeatGrid2(value.tag, res.data);
-      _satelliteGrid.setGridEvent(
-        [heatTag],
-        'click',
-        (gridCell, gridDataDetail) => {
-          gridStore.selectedGridCellAndDataDetail = {
-            gridCell,
-            gridDataDetail
-          };
-        }
-      );
-    });
+    gridApi
+      .buildUnderwayHeatmap(_satelliteGrid.gridGroupId, data, heatMapSearchLength)
+      .then((res) => {
+        heatTag = _satelliteGrid.drawHeatGrid2(value.tag, res.data);
+        _satelliteGrid.setDefaultGridClickEvent([heatTag]);
+        // _satelliteGrid.setGridEvent(
+        //   [heatTag],
+        //   'click',
+        //   (gridCell, gridDataDetail) => {
+        //     gridStore.selectedGridCellAndDataDetail = {
+        //       gridCell,
+        //       gridDataDetail
+        //     };
+        //   }
+        // );
+      })
+      .finally(() => (heatMapLoading.value = false));
   } else {
     _satelliteGrid.changeVisibility({
       tags: [value.tag],
       showGridViews: true
     });
+    heatMapLoading.value = false;
   }
 }
 </script>

--
Gitblit v1.9.3