ECharts 在省份地图上定制自定义图标
原型上有个生态分布的板块,就像是每个国家想把国旗插到月球啊,北极,南极之类的,然后点击右侧的 lenged 能够打开关闭相应的部分。具体情况如下:
![](http://img.22family.com/blog/GSU25ATJ%28KX8%7BHNEL2RR8GL.png)
要想实现这个功能需要以下几个步骤:
引入 echarts
npm install --save echarts
然后在文件中引入
import echarts from "echarts";
注册该省份的地图
我这里需要使用的是四川地图,那么以四川地图为例:
import echarts from "echarts";
const sichuanJson = require("@/assets/maps/sichuan.json");
echarts.registerMap("sichuan", sichuanJson);
使用自定义的 series
这种功能,我们首先想到的就是从 echarts 的 series 里查看有没有没自定义的 type,果然我们找到了 custom,做了如下设置:
series: [
{
name: '电信,
type: 'custom', //配置显示方式为用户自定义
coordinateSystem: 'geo',
itemStyle: {
normal: {
color: '#61a0a8',
},
},
renderItem(params: any, api: any) {
//具体实现自定义图标的方法
return {
type: 'image',
style: {
image: 'imageSrc', // 自定义的图片地址
x: api.coord([v.data[params.dataIndex].value[0], v.data[params.dataIndex].value[1]])[0], // 数据的设置
y: api.coord([v.data[params.dataIndex].value[0], v.data[params.dataIndex].value[1]])[1],
},
};
},
data: v.data,
};
];
但是我们这里有三个运营商,不可能一个一个的写,还是用遍历的方式生成 series
import dianxinImage from "@/assets/images/u2169.png";
import yidongImage from "@/assets/images/u2189.png";
import liantongImage from "@/assets/images/u2205.png";
const seriesList = [
{
name: "电信",
image: dianxinImage,
color: "#61a0a8",
data: [
{
name: "dianxin",
value: [104.06, 30.67, 2]
}
]
},
{
name: "联通",
image: liantongImage,
color: "#2f4554",
data: [
{
name: "liantong",
value: [101.72, 31.93, 2]
},
{
name: "liantong",
value: [105.04, 29.59, 2]
}
]
},
{
name: "移动",
image: yidongImage,
color: "#c23531",
data: [
{
name: "yidong",
value: [104.73, 31.48, 2]
},
{
name: "yidong",
value: [105.97, 31.75, 2]
}
]
}
];
const series = seriesList.map((v: any) => {
return {
name: v.name,
type: "custom", //配置显示方式为用户自定义
coordinateSystem: "geo",
itemStyle: {
normal: {
color: v.color
}
},
renderItem(params: any, api: any) {
//具体实现自定义图标的方法
return {
type: "image",
style: {
image: v.image,
x: api.coord([
v.data[params.dataIndex].value[0],
v.data[params.dataIndex].value[1]
])[0],
y: api.coord([
v.data[params.dataIndex].value[0],
v.data[params.dataIndex].value[1]
])[1]
}
};
},
data: v.data
};
});
配置 geo
因为我们的 series 中使用的 coordinateSystem 为 geo, 那么不注册 geo 的话会出现一个错误:api.coord is not a function,所以配置 geo 必不可少
geo: {
//引入四川省的地图
map: 'sichuan',
label: {
emphasis: {
show: true,
},
},
// roam: true,
zoom: 1,
itemStyle: {
normal: {
borderColor: '#387ba7',
shadowColor: 'rgba(0, 0, 0, 0.5)',
shadowBlur: 10,
shadowOffsetX: 10,
},
emphasis: {
areaColor: '#b3f3f3',
},
},
// regions: [
// //对不同的区块进行着色
// {
// name: '成都市',
// itemStyle: {
// normal: {
// areaColor: '#2b97df',
// },
// },
// },
// ],
},
添加 legend
如果不添加 legend,那么久不能实现在右侧点击来开启隐藏某个 series 的功能, 所以设置这个也必不可少
legend: {
type: 'plain',
show: true,
orient: 'vertical',
top: 'middle',
right: 0,
data: [
{
name: '电信',
textStyle: {
color: '#61a0a8',
},
},
{
name: '联通',
textStyle: {
color: '#2f4554',
},
},
{
name: '移动',
textStyle: {
color: '#c23531',
},
},
],
},
最终结果
最后的成品就是如下图:
![](http://img.22family.com/blog/finally.png)
最后代码
只是一个 option 的代码模块,熟悉 echarts 的人知道其余部分的
import dianxinImage from "@/assets/images/u2169.png";
import yidongImage from "@/assets/images/u2189.png";
import liantongImage from "@/assets/images/u2205.png";
const seriesList = [
{
name: "电信",
image: dianxinImage,
color: "#61a0a8",
data: [
{
name: "dianxin",
value: [104.06, 30.67, 2]
}
]
},
{
name: "联通",
image: liantongImage,
color: "#2f4554",
data: [
{
name: "liantong",
value: [101.72, 31.93, 2]
},
{
name: "liantong",
value: [105.04, 29.59, 2]
}
]
},
{
name: "移动",
image: yidongImage,
color: "#c23531",
data: [
{
name: "yidong",
value: [104.73, 31.48, 2]
},
{
name: "yidong",
value: [105.97, 31.75, 2]
}
]
}
];
const series = seriesList.map((v: any) => {
return {
name: v.name,
type: "custom", //配置显示方式为用户自定义
coordinateSystem: "geo",
itemStyle: {
normal: {
color: v.color
}
},
renderItem(params: any, api: any) {
//具体实现自定义图标的方法
return {
type: "image",
style: {
image: v.image,
x: api.coord([
v.data[params.dataIndex].value[0],
v.data[params.dataIndex].value[1]
])[0],
y: api.coord([
v.data[params.dataIndex].value[0],
v.data[params.dataIndex].value[1]
])[1]
}
};
},
data: v.data
};
});
const option = {
tooltip: {
show: true,
trigger: "item",
triggerOn: "click",
formatter: "名称:{b}<br />坐标:{c}"
},
legend: {
type: "plain",
show: true,
orient: "vertical",
top: "middle",
right: 0,
data: [
{
name: "电信",
textStyle: {
color: "#61a0a8"
}
},
{
name: "联通",
textStyle: {
color: "#2f4554"
}
},
{
name: "移动",
textStyle: {
color: "#c23531"
}
}
]
},
series,
geo: {
//引入四川省的地图
map: "sichuan",
label: {
emphasis: {
show: true
}
},
// roam: true,
zoom: 1,
itemStyle: {
normal: {
borderColor: "#387ba7",
shadowColor: "rgba(0, 0, 0, 0.5)",
shadowBlur: 10,
shadowOffsetX: 10
},
emphasis: {
areaColor: "#b3f3f3"
}
}
// regions: [
// //对不同的区块进行着色
// {
// name: '成都市',
// itemStyle: {
// normal: {
// areaColor: '#2b97df',
// },
// },
// },
// ],
}
};
export { option };
还是写上其余部分的
import { option } from "./chartsConfig";
import echarts from "echarts";
// 注册四川地图
const sichuanJson = require("@/assets/maps/sichuan.json");
echarts.registerMap("sichuan", sichuanJson);
echarts.init("某个Dom元素");
echarts.setOption(option);