首页 前端知识 Echarts 地图使用,以及tooltip轮播使用

Echarts 地图使用,以及tooltip轮播使用

2024-01-29 13:01:55 前端知识 前端哥 679 511 我要收藏

一,首先下载Echarts

npm install echarts --save

二,引入Echarts

全局引入main.js中

// echarts-4.0
import echarts from 'echarts'
Vue.prototype.$echarts = echarts

// 引入echarts-5.0
import * as echarts from 'echarts'
Vue.prototype.$echarts = echarts

页面使用

let myChart = this.$echarts.init(document.getElementById('map'))

局部引入在页面

import * as echarts from "echarts";

页面使用

let myChart = echarts.init(document.getElementById("map"));

三,使用Echarts地图组件创建地图

注意4.0和5.0区别
5.0之前Echarts是有地图数据的
5.0之后Echarts就取消了地图数据了
这里我用的是4.0的地图然后引用Echarts自带的地图数据

import "../../node_modules/echarts/map/js/china"; // 引入中国地图  注意是4.0才有 不然会报错

使用Echarts地图组件

methods: {
    //中国地图
    chinaMap() {
      let myChart = echarts.init(document.getElementById("map")); // 初始echarts
      let option = {
        // 绘制地图
        tooltip: {
          // 提示框信息配置
          // triggerOn: "click", // 触发方式
          trigger: "item", // 对象
          // backgroundColor:'#6950a1',
          formatter: (params) => {
            // 格式化提示框信息。 若要访问 data中的数据则要用箭头函数
            return `${params.name} <br/> 
                      地区ID: ${
                        this.arrMap.find((item) => item.name === params.name)
                          ?.id ?? 0
                      }`;
          },
        },
        series: [
          // 配置地图
          {
            type: "map", // 类型
            mapType: "china", // 地图名称,要和引入的地图名一致
            roam: true, // 是否开启鼠标缩放和平移漫游
            label: {
              // 地图省份模块配置
              normal: { show: true }, // 是否显示省份名称
              position: "right", // 显示位置
            },
            emphasis: {
              // 高亮状态下的多边形和标签样式。
              label: {
                show: true, // 是否显示标签。
              },
            },
            itemStyle: {
              //地图区域的多边形图形样式
              normal: {
                areaColor: "#2a5caa", //地图区域颜色
                borderColor: "#afb4db", //图形的描边颜色
                borderWidth: 1, //描边线宽。为 0 时无描边
                borderType: "solid", // 边框样式
                opacity: 0.6, // 透明度
              },
            },
            data: this.arrMap, // 提示框的数据源
          },
        ],
      };
      myChart.setOption(option);
    },

地图就出来了
在这里插入图片描述

四,tooltip轮播(Echarts所有组件都可用)

首先创建一个tooltip-auto-show-vue.js文件 放在util中

/**
 * 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, 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;
    let seriesLen = chartOption.series.length; // 系列个数
    let dataLen = 0; // 某个系列数据个数
    let chartType; // 系列类型
    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 = {
          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) {
      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
    };
  }

在页面引用tooltip-auto-show-vue.js

import { loopShowTooltip } from "../util/tooltip-auto-show-vue"; // 文件位置参考自己的位置

在地图的方法里面调用tooltipMap()方法

methods:{
	tooltipMap(myChart,option) {
	      this.tootipTimer && this.tootipTimer.clearLoop(); // this.tootipTimer 在data里定义
	      this.tootipTimer = 0;
	      // 调用轮播的方法
	      // myChart为Echarts容器实例
	      this.tootipTimer = 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系列开始执行。
	      });
	  },
}

这样就可以实现tootip自动轮播了 下面附上全部代码

<template>
	<div class='mapEcharts'>
		<div id="map" style="width: 100%; height: 100%"></div>
	</div>
</template>
<script>
import { chageMapApi } from "../api/getapi.js";
import * as echarts from "echarts";
import "../../node_modules/echarts/map/js/china"; // 引入中国地图
import { loopShowTooltip } from "../util/tooltip-auto-show-vue"; // 文件位置参考自己的位置
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
  data() {
    return {
      arrMap: [], //数据
      tootipTimer: "",
    };
  },
  mounted() {
    this.dataMap();
  },
  methods: {
    //中国地图
    chinaMap() {
      let myChart = echarts.init(document.getElementById("map")); // 初始echarts
      let option = {
        // 绘制地图
        tooltip: {
          // 提示框信息配置
          // triggerOn: "click", // 触发方式
          trigger: "item", // 对象
          // backgroundColor:'#6950a1',
          formatter: (params) => {
            // 格式化提示框信息。 若要访问 data中的数据则要用箭头函数
            return `${params.name} <br/> 
                      地区ID: ${
                        this.arrMap.find((item) => item.name === params.name)
                          ?.id ?? 0
                      }`;
          },
        },
        series: [
          // 配置地图
          {
            type: "map", // 类型
            mapType: "china", // 地图名称,要和引入的地图名一致
            roam: true, // 是否开启鼠标缩放和平移漫游
            label: {
              // 地图省份模块配置
              normal: { show: true }, // 是否显示省份名称
              position: "right", // 显示位置
            },
            emphasis: {
              // 高亮状态下的多边形和标签样式。
              label: {
                show: true, // 是否显示标签。
              },
            },
            itemStyle: {
              //地图区域的多边形图形样式
              normal: {
                areaColor: "#2a5caa", //地图区域颜色
                borderColor: "#afb4db", //图形的描边颜色
                borderWidth: 1, //描边线宽。为 0 时无描边
                borderType: "solid", // 边框样式
                opacity: 0.6, // 透明度
              },
            },
            data: this.arrMap, // 提示框的数据源
          },
        ],
      };
      myChart.setOption(option);
      //tooltip 轮播
      this.tooltipMap(myChart,option)
    },
    //中国地图数据
    dataMap() {
      chageMapApi(
        "http://hhrc.com.cn/api/report/university/city/list",
        "get"
      ).then((res) => {
        let code = res.data.code;
        if (code == 200) {
          this.arrMap = res.data.data;
          this.chinaMap();
        }
      });
    },
    tooltipMap(myChart,option) {
      this.tootipTimer && this.tootipTimer.clearLoop(); // this.tootipTimer 在data里定义
      this.tootipTimer = 0;
      // 调用轮播的方法
      // myChart为Echarts容器实例
      this.tootipTimer = 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系列开始执行。
      });
  },
  },
};
</script>
<style>
.el-header {
  background-color: palegreen;
}
.el-aside {
  background-color: palevioletred;
}
.el-main {
  background-color: #ccc;
}
.el-aside,
.el-container,
.hello,
#app,
html,
body {
  height: 100%;
}
#map {
  /* background: red; */
}
</style>

补充方法
在utli文件中创建tooltip.js文件

export function autoHover(myChart, option, num, time) {
	var defaultData = {
		// 设置默认值
		time: 2000,
		num: 100
	}
	if (!time) {
		time = defaultData.time
	}
	if (!num) {
		num = defaultData.num
	}
	var count = 0
	var timeTicket = null
	timeTicket && clearInterval(timeTicket)
	timeTicket = setInterval(function () {
		myChart.dispatchAction({
			type: 'downplay',
			seriesIndex: 0 // serieIndex的索引值   可以触发多个
		})
		myChart.dispatchAction({
			type: 'highlight',
			seriesIndex: 0,
			dataIndex: count
		})
		myChart.dispatchAction({
			type: 'showTip',
			seriesIndex: 0,
			dataIndex: count
		})
		count++
		if (count >= num) {
			count = 0
		}
	}, time)
	myChart.on('mouseover', function (params) {
		clearInterval(timeTicket)
		myChart.dispatchAction({
			type: 'downplay',
			seriesIndex: 0
		})
		myChart.dispatchAction({
			type: 'highlight',
			seriesIndex: 0,
			dataIndex: params.dataIndex
		})
		myChart.dispatchAction({
			type: 'showTip',
			seriesIndex: 0,
			dataIndex: params.dataIndex
		})
	})

	myChart.on('mouseout', function () {
		timeTicket && clearInterval(timeTicket)
		timeTicket = setInterval(function () {
			myChart.dispatchAction({
				type: 'downplay',
				seriesIndex: 0 // serieIndex的索引值   可以触发多个
			})
			myChart.dispatchAction({
				type: 'highlight',
				seriesIndex: 0,
				dataIndex: count
			})
			myChart.dispatchAction({
				type: 'showTip',
				seriesIndex: 0,
				dataIndex: count
			})
			count++
			if (count >= 17) {
				count = 0
			}
		}, 3000)
	})
}
export default {
	autoHover
}

在页面中使用

import {autoHover } from '../util/tools.js'

在Echarts实例中去使用 适用于地图和折线图亲测有效

autoHover(myChart, this.option, 4, 3000); // 参数分别为:容器,配置,轮播数量,轮播间隔时间
转载请注明出处或者链接地址:https://www.qianduange.cn//article/742.html
标签
ecmascript
评论
会员中心 联系我 留言建议 回顶部
复制成功!