vue 里怎么使用 echarts 实现地图自动轮播功能自定义 tooltip 悬浮位置提示自定义 label 标签位置样式?
Posted 凯小默
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue 里怎么使用 echarts 实现地图自动轮播功能自定义 tooltip 悬浮位置提示自定义 label 标签位置样式?相关的知识,希望对你有一定的参考价值。
要实现的功能
比如:我们要实现白云地图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: 220232
,
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)(?=(\\d3)+$)/g, function ($1)
return $1 + ',';
);
)
return res;
代码实现
1、自定义标签
我们配置标签的相应样式,我们利用 formatter,以及 rich 去处理,具体可以参考:https://echarts.apache.org/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.623178
sglProvinceProperties.cp[0]=97.617733;
sglProvinceProperties.cp[1]=36.623178;
break;
case '江苏'://def:118.767413,32.041544
sglProvinceProperties.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 实现轮播高亮提示效果。这里需要注意的就是轮播到最后一个时的状态处理。这里就不具体展开逻辑,看完整代码就行,有注释。
具体的配置参考:https://echarts.apache.org/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: echarts 实现数据(tooltip)自动轮播插件