300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > vue 里怎么使用 echarts 实现地图自动轮播功能 自定义 tooltip 悬浮位置提示

vue 里怎么使用 echarts 实现地图自动轮播功能 自定义 tooltip 悬浮位置提示

时间:2021-11-02 01:47:41

相关推荐

vue 里怎么使用 echarts 实现地图自动轮播功能 自定义 tooltip 悬浮位置提示

要实现的功能

比如:我们要实现白云地图24镇街的常住人口统计展示,然后需要我们实现 1s 自动轮播一次地区,自定义标签样式,自定义悬浮样式。

准备工作

1、安装依赖

npm i echarts -s

2、准备 24 镇街的 geoJson 数据

关于怎么获取 24 镇街的 geoJson 数据,请参考我之前的一篇博客:怎么获取echarts需要的geoJson数据去渲染地图:以广州市白云区24镇街为例

3、准备一份配置 24 镇街的文件

我们新建文件440111.config.js,在里面添加一些配置参数用于数据展示的方便,比如我配置了几个:

/*** 1)4个镇:江高镇、人和镇、太和镇、钟落潭镇;* 2)20个街:龙归街、大源街、三元里街、松洲街、景泰街、同德街、黄石街、棠景街、新市街、同和街、京溪街、永平街、嘉禾街、均禾街、石井街、金沙街、云城街、鹤龙街、白云湖街、石门街;* */ export const BAIYUN_CONFIG = ['江高镇','人和镇','太和镇','钟落潭镇','龙归街','大源街','三元里街','松洲街','景泰街','同德街','黄石街','棠景街','新市街','同和街','京溪街','永平街','嘉禾街','均禾街','石井街','金沙街','云城街','鹤龙街','白云湖街','石门街'];/*** SUCCESS_STYLE:绿色样式:'江高镇','太和镇','景泰街','黄石街','棠景街','京溪街','永平街','均禾街','石井街','金沙街';* WARNING_STYLE:橙色样式:'人和镇','嘉禾街','三元里街','石门街','新市街','大源街','松洲街';* ERROR_STYLE:红色样式:'钟落潭镇','同德街','云城街','鹤龙街','白云湖街','龙归街','同和街';* */ export const SUCCESS_STYLE = ['江高镇','太和镇','景泰街','黄石街','棠景街','京溪街','永平街','均禾街','石井街','金沙街'];export const WARNING_STYLE = ['人和镇','嘉禾街','三元里街','石门街','新市街','大源街','松洲街'];export const ERROR_STYLE = ['钟落潭镇','同德街','云城街','鹤龙街','白云湖街','龙归街','同和街'];// 测试数据export const MapData = [{id: "jianggao",name: "江高镇",value: 883945},{id: "renhe",name: "人和镇",value: 4567992},{id: "taihe",name: "太和镇",value: 4567323},{id: "zhongluotan",name: "钟落潭镇",value: 497863},{id: "longgui",name: "龙归街",value: 3486257},{id: "dayuan",name: "大源街",value: 897435},{id: "sanyuanli",name: "三元里街",value: 46809544},{id: "songzhou",name: "松洲街",value: 123403},{id: "jingtai",name: "景泰街",value: 342256677},{id: "tongde",name: "同德街",value: 234677},{id: "huangshi",name: "黄石街",value: 976542},{id: "tangjing",name: "棠景街",value: 33456},{id: "xinshi",name: "新市街",value: 3455602},{id: "tonghe",name: "同和街",value: 487654},{id: "jingxi",name: "京溪街",value: 3876735},{id: "yongping",name: "永平街",value: 6677544},{id: "jiahe",name: "嘉禾街",value: 34526784},{id: "junhe",name: "均禾街",value: 8756534},{id: "shijing",name: "石井街",value: 22},{id: "jinsha",name: "金沙街",value: 3352256},{id: "yuncheng",name: "云城街",value: 335677},{id: "helong",name: "鹤龙街",value: 334225},{id: "baiyunhu",name: "白云湖街",value: 34556},{id: "shimen",name: "石门街",value: 1354667}];

4、准备工具方法添加千分位

新建文件utils.js,添加千分位函数:

// 数字加千位分隔符export function numToThsSprtr (num) {let res = num.toString().replace(/\d+/, function (n) {// 先提取整数部分return n.replace(/(\d)(?=(\d{3})+$)/g, function ($1) {return $1 + ',';});})return res;}

代码实现

1、自定义标签

我们配置标签的相应样式,我们利用 formatter,以及 rich 去处理,具体可以参考:/zh/option.html#series-map.label.formatter,backgroundColor 可以使用背景图片。

label: {show: true,color: "#fff",textAlign: "center",// {a}:系列名。{b}:数据名。{c}:数据值。formatter: (params) => {let richName = "";if (SUCCESS_STYLE.includes(params.name)) {richName = "success";} else if (WARNING_STYLE.includes(params.name)) {richName = "warning";} else if (ERROR_STYLE.includes(params.name)) {richName = "error";}return `{${richName}|${params.name}}`;},rich: {success: {fontSize: "0.0729rem",padding: [4, 7],borderWidth: 2, // 图形描边的宽度。borderColor: "#fff", // 边框颜色backgroundColor: 'green', // 背景色},warning: {fontSize: "0.0729rem",padding: [4, 7],borderWidth: 2, // 图形描边的宽度。borderColor: "#fff", // 边框颜色backgroundColor: 'orange', // 背景色},error: {fontSize: "0.0729rem",padding: [4, 7],borderWidth: 2, // 图形描边的宽度。borderColor: "#fff", // 边框颜色backgroundColor: 'red', // 背景色},},},

怎么处理标签名重叠问题?

如果大家出现下面这种标签名重叠的问题,那应该怎么去处理?

这里我们可以参考 github 上面 echarts 的问题 4379 进行相应的处理:中国地图,省份名称重叠 #4379

问题的描述:

两种方式处理重叠

第一种:在 geoJson 数据中添加 cp 属性数据。

"properties": {"name": "白云湖街","cp": [113.23196411132812, 23.24386977767157]}

第二种:echarts.getMap(‘china’) 后修改已经加载的地图的数据。

var chinaMapInfoObj = document.getElementById(‘mianid‘’);var chinaMap = echarts.init(chinaMapInfoObj);var chinaEchartsObj = echarts.getMap('china');var geoJSONChina = chinaEchartsObj.geoJson;var allDefProvince = geoJSONChina.features;for(var i=0,len=allDefProvince.length; i<len; i++){var sglProvinceProperties = allDefProvince[i].properties;var sglProvinceName = sglProvinceProperties.name;switch(sglProvinceName){case '新疆':sglProvinceProperties.cp[0]=87.617733;sglProvinceProperties.cp[1]=41.792818;break;case '青海'://def:101.778916,36.623178sglProvinceProperties.cp[0]=97.617733;sglProvinceProperties.cp[1]=36.623178;break;case '江苏'://def:118.767413,32.041544sglProvinceProperties.cp[0]=119.767413;sglProvinceProperties.cp[1]=33.041544;break;}}option.echarts.registerMap('china', geoJSONChina, {});

怎么确定中心点的坐标

可以去查看这个我写的这一篇博客里的确定边界汇聚点部分,里面有介绍怎么处理。怎么获取 echarts 需要的 geoJson 数据去渲染地图:以广州市白云区24镇街为例

大致就是把矩形左上方的点放到新的位置中心,就可以得到大概的坐标。

得到坐标之后,可能有点不太精确,可以自己合适的调整数据,达到自己想要的位置就行。

比如:现在松洲街同德街,挡住了,需要把它进行移动,

这里我们采用第一种方式,修改 geojson 数据,我们给松洲街添加 cp 坐标数据,我们发现就不会被遮住了,其他也是同样的原理

"properties": {"name": "松洲街","cp": [113.21036999511719, 23.15851026498019]}

2、自定义悬浮提示

这里我们主要需要处理的就是 position 跟样式 formatter。这里的位置需要计算一下 (point:鼠标位置) 跟(contentSize:dom 的尺寸),找到合适的显示位置。具体的可以参考:

提示框浮层的位置提示框浮层内容格式器,支持字符串模板和回调函数两种形式

tooltip: {show: true,trigger: "item",// point:鼠标位置 contentSize:dom 的尺寸position: (point, params, dom, rect, size) => {return [point[0] - 20, point[1] - size.contentSize[1] - 15];},extraCssText: "box-shadow: none", // 额外样式formatter: (param) => {let data = `<div class="map-tooltips"><div class="name">${param.name}常住人口</div><div class="value"><span class="num">${numToThsSprtr(param.value || 0)}</span><span class="unit">人</span></div></div>`;return data;},},

3、自动轮播功能

我们可以通过 dispatchAction 实现轮播高亮提示效果。这里需要注意的就是轮播到最后一个时的状态处理。这里就不具体展开逻辑,看完整代码就行,有注释。

具体的配置参考:/zh/api.html#action

高亮指定的数据图形。

// 如果要高亮系列:dispatchAction({type: 'highlight',// 用 index 或 id 或 name 来指定系列。// 可以使用数组指定多个系列。seriesIndex?: number | number[],seriesId?: string | string[],seriesName?: string | string[],// 数据项的 index,如果不指定也可以通过 name 属性根据名称指定数据项dataIndex?: number | number[],// 可选,数据项名称,在有 dataIndex 的时候忽略name?: string | string[],});

取消高亮指定的数据图形。

// 如果要取消高亮系列:dispatchAction({type: 'downplay',// 用 index 或 id 或 name 来指定系列。// 可以使用数组指定多个系列。seriesIndex?: number | number[],seriesId?: string | string[],seriesName?: string | string[],// 数据项的 index,如果不指定也可以通过 name 属性根据名称指定数据项dataIndex?: number | number[],// 可选,数据项名称,在有 dataIndex 的时候忽略name?: string | string[],})

指定系列中的数据图形,根据 tooltip 的配置项显示提示框。

dispatchAction({type: 'showTip',// 系列的 index,在 tooltip 的 trigger 为 axis 的时候可选。seriesIndex?: number,// 数据项的 index,如果不指定也可以通过 name 属性根据名称指定数据项dataIndex?: number,// 可选,数据项名称,在有 dataIndex 的时候忽略name?: string,,// 本次显示 tooltip 的位置。只在本次 action 中生效。// 缺省则使用 option 中定义的 tooltip 位置。position: number[] | string | Function,})

隐藏提示框。

dispatchAction({type: 'hideTip'})

4、大屏自适应方案

这个可以参考我的另外一篇:使用 sass + rem + flexible.js 实现大屏自适应

完整代码

<template><div ref="geoTwoDimensionalMapChart" class="geo-two-dimensional-map-chart"></div></template><script>import * as echarts from "echarts";// 白云区 geojson 数据import baiyunGeoJson from "@/assets/mapData/440111.json";// 24 镇街数据import {BAIYUN_CONFIG,SUCCESS_STYLE,WARNING_STYLE,ERROR_STYLE,MapData} from "@/assets/mapData/440111.config.js";// 工具方法import {numToThsSprtr} from "@/utils/utils.js";export default {name: "geoTwoDimensionalMapChart",data() {return {myChart: null,interval: 1000, // 时间间隔毫秒数index: 0, // 播放所在下标timer: null,option: {series: [{type: "map",map: "白云区",data: [],layoutCenter: ["50%", "50%"], // 属性定义地图中心在屏幕中的位置layoutSize: "99%", // 定义地图的大小label: {show: true,color: "#fff",textAlign: "center",// {a}:系列名。{b}:数据名。{c}:数据值。formatter: (params) => {let richName = "";if (SUCCESS_STYLE.includes(params.name)) {richName = "success";} else if (WARNING_STYLE.includes(params.name)) {richName = "warning";} else if (ERROR_STYLE.includes(params.name)) {richName = "error";}return `{${richName}|${params.name}}`;},rich: {success: {fontSize: "0.0729rem",padding: [4, 7],borderWidth: 2, // 图形描边的宽度。borderColor: "#fff", // 边框颜色backgroundColor: 'green', // 背景色},warning: {fontSize: "0.0729rem",padding: [4, 7],borderWidth: 2, // 图形描边的宽度。borderColor: "#fff", // 边框颜色backgroundColor: 'orange', // 背景色},error: {fontSize: "0.0729rem",padding: [4, 7],borderWidth: 2, // 图形描边的宽度。borderColor: "#fff", // 边框颜色backgroundColor: 'red', // 背景色},},},itemStyle: {borderWidth: 2, // 图形描边的宽度。borderColor: "#ddd", // 图形描边的颜色。areaColor: '#ccc',shadowColor: '#eee',shadowBlur: 10,shadowOffsetX: 0,shadowOffsetY: 2},// 点击选择样式select: {label: {color: "#fff",},itemStyle: {borderWidth: 2, // 图形描边的宽度。borderColor: "#ddd", // 图形描边的颜色。areaColor: '#ccc',}},emphasis: {// 当鼠标放上label: {color: "#fff",},itemStyle: {borderWidth: 2,borderColor: "#000",areaColor: 'blue',},},}],tooltip: {show: true,trigger: "item",// point:鼠标位置 contentSize:dom 的尺寸position: (point, params, dom, rect, size) => {return [point[0] - 20, point[1] - size.contentSize[1] - 15];},extraCssText: "box-shadow: none", // 额外样式formatter: (param) => {let data = `<div class="map-tooltips"><div class="name">${param.name}常住人口</div><div class="value"><span class="num">${numToThsSprtr(param.value || 0)}</span><span class="unit">人</span></div></div>`;return data;},},},};},mounted() {// 初始化渲染this.initRender();// 设置轮播this.setIntervalMyChart();// resize 事件监听window.addEventListener("resize", this.handleResize);},destroyed() {clearInterval(this.timer);window.removeEventListener("resize", this.handleResize);},methods: {// 初始化渲染initRender() {// 注册地图名字和数据echarts.registerMap("白云区", baiyunGeoJson);let chartDom = this.$refs.geoTwoDimensionalMapChart;this.myChart = echarts.init(chartDom);this.option.series[0].data = MapData;this.myChart.setOption(this.option);// 激活高亮跟提示console.log('initRender', this.index);this.dispatchActionChart("highlight", this.index);this.dispatchActionChart("showTip", this.index);// 鼠标划入this.mouseEvents();},// 鼠标划入mouseEvents() {this.myChart.on("mouseover", () => {// 停止定时器,清除之前的高亮clearInterval(this.timer);this.dispatchActionChart("downplay", this.index);});// 鼠标划出重新定时器开始this.myChart.on("mouseout", () => {clearInterval(this.timer);// 启动轮播this.setIntervalMyChart();});},// 设置轮播setIntervalMyChart() {const dataLength = BAIYUN_CONFIG.length;// 每隔 interval 进行一次切换this.timer = setInterval(() => {// 清除高亮跟提示this.dispatchActionChart("downplay", this.index);this.dispatchActionChart("hideTip", this.index);// 索引增加this.index++;// 激活高亮跟提示this.dispatchActionChart("highlight", this.index);this.dispatchActionChart("showTip", this.index);if (this.index === dataLength - 1) {// 需要对最后一个进行清除,对第一个进行激活let tempTimer = setTimeout(() => {this.dispatchActionChart("downplay", dataLength - 1);this.dispatchActionChart("highlight", this.index);clearTimeout(tempTimer);}, this.interval);this.index = -1;}}, this.interval);},/*** @description 控制高亮跟提示* @param {String} type (highlight:高亮(反:downplay);showTip:显示提示(反:hideTip))* @param {Number} dataIndex 数据项的 index* */ dispatchActionChart(type, dataIndex) {this.myChart.dispatchAction({type: type,seriesIndex: 0,dataIndex: dataIndex,});},// resize 事件handleResize() {this.myChart.resize();},},};</script><style lang="scss" scoped>@import "@/assets/scss/utils.scss";.geo-two-dimensional-map-chart {width: 100%;height: p2r(730);::v-deep .map-tooltips {min-width: p2r(160);position: relative;text-align: center;padding-top: p2r(10);.name {font-size: p2r(16);font-weight: 400;color: green;line-height: p2r(22);margin-bottom: p2r(8);}.value {color: green;.num {font-size: p2r(26);font-weight: bold;line-height: p2r(26);}.unit {font-size: p2r(14);}}}}</style>

参考资料

echarts 图表行为 actionecharts 标签内容格式器series-map.label.formatterecharts 提示框浮层的位置echarts 提示框浮层内容格式器,支持字符串模板和回调函数两种形式中国地图,省份名称重叠 #4379怎么获取 echarts 需要的 geoJson 数据去渲染地图:以广州市白云区24镇街为例使用 sass + rem + flexible.js 实现大屏自适应

vue 里怎么使用 echarts 实现地图自动轮播功能 自定义 tooltip 悬浮位置提示 自定义 label 标签位置样式?

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。