소스 검색

reactor:地图动态tooltip;

zhangchong 1 년 전
부모
커밋
b7deea6798

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
public/map-geojson/511502.json


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
public/map-geojson/511503.json


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
public/map-geojson/511504.json


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
public/map-geojson/511523.json


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
public/map-geojson/511524.json


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
public/map-geojson/511525.json


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
public/map-geojson/511526.json


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
public/map-geojson/511527.json


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
public/map-geojson/511528.json


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
public/map-geojson/511529.json


+ 304 - 0
src/utils/tooltip-auto-show-vue.ts

@@ -0,0 +1,304 @@
+// @ts-ignore
+/**
+ * echarts tooltip轮播
+ * @param chart ECharts实例
+ * @param chartOption echarts的配置信息
+ * @param options object 选项
+ * {
+ *  interval    轮播时间间隔,单位毫秒,默认为2000
+ *  loopSeries  boolean类型,默认为false。
+ *              true表示循环所有series的tooltip,false则显示指定seriesIndex的tooltip
+ *  seriesIndex 默认为0,指定某个系列(option中的series索引)循环显示tooltip,
+ *              当loopSeries为true时,从seriesIndex系列开始执行。
+ *  updateData  自定义更新数据的函数,默认为null;
+ *              用于类似于分页的效果,比如总数据有20条,chart一次只显示5条,全部数据可以分4次显示。
+ * }
+ * @returns {{clearLoop: clearLoop}|undefined}
+ */
+export function loopShowTooltip(chart:any, chartOption: any, options: any ) {
+    console.log(chart,chartOption,options)
+    let defaultOptions = {
+      interval: 2000,
+      loopSeries: false,
+      seriesIndex: 0,
+      updateData: null,
+    };
+  
+    if (!chart || !chartOption) {
+      return;
+    }
+  
+    let dataIndex = 0; // 数据索引,初始化为-1,是为了判断是否是第一次执行
+    let seriesIndex = 0; // 系列索引
+    let timeTicket = 0 as any;
+    let seriesLen = chartOption.series.length; // 系列个数
+    let dataLen = 0; // 某个系列数据个数
+    let chartType:any; // 系列类型
+    let first = true;
+    let lastShowSeriesIndex = 0;
+    let lastShowDataIndex = 0;
+  
+    if (seriesLen === 0) {
+      return;
+    }
+  
+    // 待处理列表
+    // 不循环series时seriesIndex指定显示tooltip的系列,不指定默认为0,指定多个则默认为第一个
+    // 循环series时seriesIndex指定循环的series,不指定则从0开始循环所有series,指定单个则相当于不循环,指定多个
+    // 要不要添加开始series索引和开始的data索引?
+  
+    if (options) {
+      options.interval = options.interval || defaultOptions.interval;
+      options.loopSeries = options.loopSeries || defaultOptions.loopSeries;
+      options.seriesIndex = options.seriesIndex || defaultOptions.seriesIndex;
+      options.updateData = options.updateData || defaultOptions.updateData;
+    } else {
+      options = defaultOptions;
+    }
+  
+    // 如果设置的seriesIndex无效,则默认为0
+    if (options.seriesIndex < 0 || options.seriesIndex >= seriesLen) {
+      seriesIndex = 0;
+    } else {
+      seriesIndex = options.seriesIndex;
+    }
+  
+    /**
+     * 清除定时器
+     */
+    function clearLoop() {
+      if (timeTicket) {
+        clearInterval(timeTicket);
+        timeTicket = 0;
+      }
+  
+      chart.off('mousemove', stopAutoShow);
+      zRender.off('mousemove', zRenderMouseMove);
+      zRender.off('globalout', zRenderGlobalOut);
+    }
+  
+    /**
+     * 取消高亮
+     */
+    function cancelHighlight() {
+      /**
+       * 如果dataIndex为0表示上次系列完成显示,如果是循环系列,且系列索引为0则上次是seriesLen-1,否则为seriesIndex-1;
+       * 如果不是循环系列,则就是当前系列;
+       * 如果dataIndex>0则就是当前系列。
+       */
+      let tempSeriesIndex =
+        dataIndex === 0
+          ? options.loopSeries
+            ? seriesIndex === 0
+              ? seriesLen - 1
+              : seriesIndex - 1
+            : seriesIndex
+          : seriesIndex;
+      let tempType = chartOption.series[tempSeriesIndex].type;
+  
+      if (tempType === 'pie' || tempType === 'radar' || tempType === 'map') {
+        chart.dispatchAction({
+          type: 'downplay',
+          seriesIndex: lastShowSeriesIndex,
+          dataIndex: lastShowDataIndex,
+        }); // wait 系列序号为0且循环系列,则要判断上次的系列类型是否是pie、radar
+      }
+    }
+  
+    /**
+     * 自动轮播tooltip
+     */
+    function autoShowTip() {
+      let invalidSeries = 0;
+      let invalidData = 0;
+      function showTip() {
+        // chart不在页面中时,销毁定时器
+        let dom = chart.getDom();
+        if (document !== dom && !document.documentElement.contains(dom)) {
+          clearLoop();
+          return;
+        }
+  
+        // 判断是否更新数据
+        if (
+          dataIndex === 0 &&
+          !first &&
+          typeof options.updateData === 'function'
+        ) {
+          options.updateData();
+          chart.setOption(chartOption);
+        }
+  
+        let series = chartOption.series;
+        let currSeries = series[seriesIndex];
+        if (
+          !series ||
+          series.length === 0 ||
+          !currSeries ||
+          !currSeries.type ||
+          !currSeries.data ||
+          !currSeries.data.length
+        ) {
+          return;
+        }
+  
+        chartType = currSeries.type; // 系列类型
+        dataLen = currSeries.data.length; // 某个系列的数据个数
+  
+        let tipParams:any = {
+          seriesIndex: seriesIndex,
+        };
+        switch (chartType) {
+          case 'pie':
+            // 处理饼图中数据为0或系列名为空的不显示tooltip
+            if (
+              !currSeries.data[dataIndex].name ||
+              currSeries.data[dataIndex].name === '空' ||
+              !currSeries.data[dataIndex].value
+            ) {
+              invalidData += 1;
+              dataIndex = (dataIndex + 1) % dataLen;
+              if (options.loopSeries && dataIndex === 0) {
+                // 数据索引归0表示当前系列数据已经循环完
+                // 无效数据个数个总数据个数相等,则该系列无效
+                if (invalidData === dataLen) {
+                  invalidSeries += 1;
+                }
+  
+                // 新系列,重置无效数据个数
+                invalidData = 0;
+  
+                // 系列循环递增1
+                seriesIndex = (seriesIndex + 1) % seriesLen;
+                // 系列数循环至起始值时重置无效系列数
+                if (seriesIndex === options.seriesIndex) {
+                  if (seriesLen !== invalidSeries) {
+                    // 下一次系列轮回,重置无效系列数
+                    invalidSeries = 0;
+                    showTip();
+                  } else {
+                    // 下一次系列轮回,重置无效系列数
+                    invalidSeries = 0;
+                    clearLoop();
+                  }
+                } else {
+                  showTip();
+                }
+              } else if (!options.loopSeries && dataIndex === 0) {
+                if (dataLen !== invalidData) {
+                  invalidData = 0;
+                  showTip();
+                } else {
+                  invalidData = 0;
+                  clearLoop();
+                }
+              } else {
+                showTip();
+              }
+  
+              return;
+            }
+          // eslint-disable-next-line no-fallthrough
+          case 'map':
+          case 'chord':
+            tipParams.name = currSeries.data[dataIndex].name;
+            break;
+          case 'radar': // 雷达图
+            tipParams.seriesIndex = seriesIndex;
+            // tipParams.dataIndex = dataIndex;
+            break;
+          case 'lines': // 线图地图上的lines忽略
+            dataIndex = 0;
+            seriesIndex = (seriesIndex + 1) % seriesLen;
+            invalidSeries++; // 记录无效系列数,如果无效系列数和系列总数相等则取消循环显示
+            if (seriesLen !== invalidSeries) {
+              showTip();
+            } else {
+              clearLoop();
+            }
+            return;
+          default:
+            tipParams.dataIndex = dataIndex;
+            break;
+        }
+  
+        if (chartType === 'pie' || chartType === 'radar' || chartType === 'map') {
+          if (!first) {
+            cancelHighlight();
+          }
+  
+          // 高亮当前图形
+          chart.dispatchAction({
+            type: 'highlight',
+            seriesIndex: seriesIndex,
+            dataIndex: dataIndex,
+          });
+        }
+  
+        // 显示 tooltip
+        tipParams.type = 'showTip';
+        chart.dispatchAction(tipParams);
+  
+        lastShowSeriesIndex = seriesIndex;
+        lastShowDataIndex = dataIndex;
+  
+        dataIndex = (dataIndex + 1) % dataLen;
+        if (options.loopSeries && dataIndex === 0) {
+          // 数据索引归0表示当前系列数据已经循环完
+          invalidData = 0;
+          seriesIndex = (seriesIndex + 1) % seriesLen;
+          if (seriesIndex === options.seriesIndex) {
+            invalidSeries = 0;
+          }
+        }
+  
+        first = false;
+      }
+  
+      showTip();
+      timeTicket = setInterval(showTip, options.interval);
+    }
+  
+    // 关闭轮播
+    function stopAutoShow() {
+      if (timeTicket) {
+        clearInterval(timeTicket);
+        timeTicket = 0;
+  
+        if (chartType === 'pie' || chartType === 'radar' || chartType === 'map') {
+          cancelHighlight();
+        }
+      }
+    }
+  
+    let zRender = chart.getZr();
+  
+    function zRenderMouseMove(param:any) {
+      if (param.event) {
+        // 阻止canvas上的鼠标移动事件冒泡
+        // param.event.cancelBubble = true;
+      }  
+      stopAutoShow();
+    }
+  
+    // 离开echarts图时恢复自动轮播
+    function zRenderGlobalOut() {
+      // console.log("移出了")
+      // console.log(timeTicket)
+      if (!timeTicket) {
+        autoShowTip();
+      }
+    }
+  
+    // 鼠标在echarts图上时停止轮播
+    chart.on('mousemove', stopAutoShow);
+    zRender.on('mousemove', zRenderMouseMove);
+    zRender.on('globalout', zRenderGlobalOut);
+  
+    autoShowTip();
+  
+    return {
+      clearLoop: clearLoop
+    };
+  }
+

+ 20 - 3
src/views/index/center-map.vue

@@ -18,13 +18,14 @@
   </div>
 </template>
 <script setup lang="ts">
-import { ref, reactive, nextTick, onMounted } from "vue";
+import { ref, nextTick, onMounted } from "vue";
 import { GETNOBASE } from "@/api";
 import { registerMap, getMap } from "echarts/core";
 import { optionHandle, regionCodes } from "./center.map";
 import BorderBox13 from "@/components/datav/border-box-13";
 import type { MapdataType } from "./center.map";
 import signalR from "@/utils/signalR";
+import {loopShowTooltip } from "@/utils/tooltip-auto-show-vue";
 const option = ref({});
 const code = ref("511500"); //100000 代表中国 其他地市是行政编码
 withDefaults(
@@ -82,6 +83,24 @@ const getGeojson = (regionCode: string) => {
     }
   });
 };
+const tooltipTimer = ref<any>(null);
+const centerMapRef = ref<any>(null);
+const tooltipMap = (myChart,option)=>{
+  tooltipTimer.value && tooltipTimer.value.clearLoop(); // this.tooltipTimer 在data里定义
+  tooltipTimer.value = 0;
+  // 调用轮播的方法
+  // myChart为Echarts容器实例
+  tooltipTimer.value = loopShowTooltip(myChart, option, {
+    interval: 5000, // 轮播间隔时间
+    loopSeries: true, // 是否开启轮播循环
+    // shunXu: "daoXu", // 显示顺序
+    // loopSeries: boolean类型,默认为false。true表示循环所有series的tooltip;false则显示指定seriesIndex的tooltip。
+    // seriesIndex: 默认为0,指定某个系列(option中的series索引)循环显示tooltip,当loopSeries为true时,从seriesIndex系列开始执行。
+  });
+};
+setTimeout(() => {
+  tooltipMap(centerMapRef.value!.chart,option.value);
+}, 1000);
 onMounted(() => {
   getData(code.value);
   // 加入分组
@@ -161,8 +180,6 @@ onMounted(() => {
 </style>
 <style lang="scss">
 .chartTooltip {
-  margin: 0;
-  padding: 0;
   position: relative;
   background-color: rgba(0, 0, 0, 0.6);
   border: 1px solid #00f7f6;

+ 2 - 0
src/views/index/center.map.ts

@@ -77,6 +77,7 @@ export const optionHandle = (regionCode: string,
                 top: top,
                 tooltip: {
                     show: true,
+                    position: 'right',
                     formatter: function (params: any) {
                         if (params.data) {
                             // console.log(params); //params是echarts的属性
@@ -221,6 +222,7 @@ export const optionHandle = (regionCode: string,
                 },
             },
         ],
+
         //动画效果
         // animationDuration: 1000,
         // animationEasing: 'linear',

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.