众所周知,用echarts上官网
Documentation - Apache EChartsecharts.apache.org/zh/tutorial.html#5%20%E5%88%86%E9%92%9F%E4%B8%8A%E6%89%8B%20ECharts
根据教程npm安装
npm install echarts --save
然后在需要使用的页面引入
import * as echarts from 'echarts'
下面重点来了,echarts官方建议使用百度地图的方式展示中国地图,但是好多项目场景都百度地图都不符合,只有通过JSON数据生成的地图可以符合。
(或者是可以通过贴图、图层方式实现地图的areaStyle , 但是官网一无例子 二无教程,还是我太菜了)
这里通过JSON数据生成地图,这种方式的重点是去找china.json , 可以通过github去搜索或者通过阿里云DataV
github方式请小伙伴们自行搜索,主要是最近tz又双叒叕过期了,难受啊
下面是DataV地址链接,可根据需要自行选择下载
阿里云 DataV - 数据可视化平台datav.aliyun.com/portal/school/atlas/area_selector
如下图, 怒赞一波大厂(牛批!)
然后本地获取一下JSON数据,这里需要对echarts注册一下,附一下教程截图
这里的GeoJSON链接略坑,兴冲冲的点过去, 纳尼???
效果图如下,后面上一下主要代码
这里我觉得UI的visualMap位置设计的不好,要是我直接就放左下角了
主要代码如下(给新手们提醒一下axios也是需要npm安装+引入的呦)
initMapChart() {
// 这里提一下china.json是放在public下的city文件夹的, 所以这里可以直接/city/china.json
// 此时部署到服务器根目录是没有问题的,如果部署到二级目录 比如/demo/下这里会报错
// 比较简单的方式是直接在根目录拷贝一份city/china.json
// 因为在项目中使用了process.env.NODE_ENV所以这里暂不做兼容判断 简单直接拷贝一份完事
axios.get("/city/china.json").then((res) => {
console.log(res);
echarts.registerMap("china", { geoJSON: res.data });
let myChart = echarts.init(document.getElementById("mapChart"));
let arr = [
{
name: "北京市",
value: 54,
},
{
name: "天津市",
value: 13,
},
{
name: "上海市",
value: 40,
},
{
name: "重庆市",
value: 75,
},
{
name: "河北省",
value: 13,
},
{
name: "河南省",
value: 83,
},
{
name: "云南省",
value: 11,
},
{
name: "辽宁省",
value: 19,
},
{
name: "黑龙江省",
value: 15,
},
{
name: "湖南省",
value: 69,
},
{
name: "安徽省",
value: 60,
},
{
name: "山东省",
value: 39,
},
{
name: "新疆省",
value: 4,
},
{
name: "江苏省",
value: 31,
},
{
name: "浙江省",
value: 104,
},
{
name: "江西省",
value: 36,
},
{
name: "湖北省",
value: 1052,
},
{
name: "广西省",
value: 33,
},
{
name: "甘肃省",
value: 7,
},
{
name: "山西省",
value: 9,
},
{
name: "内蒙古省",
value: 7,
},
{
name: "陕西省",
value: 22,
},
{
name: "吉林省",
value: 4,
},
{
name: "福建省",
value: 18,
},
{
name: "贵州省",
value: 5,
},
{
name: "广东省",
value: 98,
},
{
name: "青海市",
value: 1,
},
];
let option = {
visualMap: {
type: "piecewise",
show: true,
min: 0,
max: 1000000,
left: "28%",
bottom: "25%",
showLabel: true,
// text: ["高", "低"],
textStyle: {
color: "#ffffff",
},
pieces: [
// 图例颜色
{
min: 10000,
max: 999999,
label: ">10000",
color: "#A9251B",
symbol: "roundRect",
},
{
min: 1000,
max: 9999,
label: "1000-9999",
color: "#D5514D",
symbol: "roundRect",
},
{
min: 100,
max: 999,
label: "100-999",
color: "#E57C6D",
symbol: "roundRect",
},
{
min: 10,
max: 99,
label: "10-99",
color: "#F19D8A",
symbol: "roundRect",
},
{
min: 1,
max: 9,
label: "1-9",
color: "#FBE6DC",
symbol: "roundRect",
},
{
value: 0,
label: "0",
color: "#ffffff",
symbol:
"image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAeCAMAAAAB8C7XAAAAeFBMVEUAAADBIhzAIh+/ISDBHSHDHh6jMyHAISDAISC/ISDAIR/AISDAHiG/IR+6RjG+IiC/IiHAICC/IR/AISG+ISG+Ix+/ICDAIiC+IB/AIBzCHh68JRa/IiHAIB+/ISC9IiK/Hx+/IiC+IiK+Ih++ICDCJB/BJB+/ISDiIZL9AAAAJ3RSTlMALfv3HQwG0secl4NTQQPkvLWoo2xpZWFYJBkR693CkIx4WktHMjGv/nLNAAAAp0lEQVQoz4XNVwrEMAxFUcUlvfcyvWn/OxxBMASPxNyPBL9jMPwrNJ9gcwfTLfQt52ueRgqpeLQ0rJnGgP4BHtJNcqE7BNQJvRy0EgwSLBJAJUEnwSSBkQDO/l6XOyTe3lrYexxX1bzAte5TlWT9XFg4FNGs+xJ+SgnuwJQTGA42xYB7pGDhhjiw8ERMWbAKY2CLUYcsZIhvFgrEkYVQYw5s9QR8/tNf+EUpppEdkKMAAAAASUVORK5CYII=",
},
],
},
geo: {
map: "china",
zoom: 1.7,
top: "30%",
label: {
show: true,
fontSize: "14",
color: "#00D9A9",
},
},
series: [
{
type: "map",
geoIndex: 0,
data: arr,
},
],
};
myChart.setOption(option);
});
},
这里说一个坑了我1个多小时的坑,即渲染数据arr的每一项的name都要与china.json中的城市名称一致,否则无法渲染色块。
这里也有两种实现方式(细微区别) :
1、使用geo组件 ,需要在series中设置geoIndex (上面的代码就是这种方式)
2、使用series的type: 'map', 需要设置map: 'china' , 这里的china就是echarts.registerMap所注册的名字
剩下的大同小异,echarts项目做多了就会发现很多配置都有共通点。这里就不放代码了,放张图意思一下吧。
这个是在gallery里看来的湖北地图示例
where is gallery ? oh its here
最后总结一下: 官方文档才是第一权威,百度的好多是5年前的代码 早就过时了, CSDN ? 那是什么???我还是继续攒钱买新的tz google吧。
更新一下产品2.0,领导一句话: 要3D效果,要小红旗 对 就是CSDN上那个!
so 2.0更新内容,区域颜色径向渐变 + 地图堆叠实现2.5D立体效果 + scatter实现清零板块放置小红旗
效果图如下
下面是主要代码,有三点需要注意
1、这里是把series的map作为上层(它的zlevel为1,),geo渲染的map作为底层(它的zlevel为0)在底层地图上渲染阴影 实现2.5D ; 因为visualMap是需要渲染在series上的(这块不太确定,目前在官方没找到visualMap可以选择geo渲染), scatter的小红旗zlevel为3
2、目前发现在visualMap中的pieces中使用symbol时 series中的type: scatter中的symbol会失效, 而且pieces中设置symbol也会有问题这里不细说了 已去github提了issue 等待回复中
3、出于业务考虑 这里再开头先销毁了一下echarts对象,当然也可以创建一个全局的echarts 然后只更新options 。 一切已实际业务为准
initMapChart(mapData = []) {
if (this.mapChart) {
this.mapChart.dispose()
}
// 后面反应过来,这里的china.json 可以直接import引入,不需要和echarts官网例子一致, 使用也会更方便
axios.get("/city/china.json").then((res) => {
console.log(res);
echarts.registerMap("china", { geoJSON: res.data });
this.mapChart = echarts.init(document.getElementById("mapChart"));
// 目标数据格式
// let arr = [
// {
// name: "北京市",
// value: 54,
// }
// ];
// 找出数据中所有数据为0 的坐标 用于0数据小红旗的渲染
let markPointData = [], brr = [];
for (let i of mapData) {
if (i.value == 0) {
brr.push(i.name)
}
}
for (let j of brr) {
for(let k of res.data.features) {
if (j == k.properties.name) {
markPointData.push({
name: j,
value: k.properties.center
})
}
}
}
console.log('markPointData:', markPointData)
let option = {
visualMap: {
type: "piecewise",
show: true,
min: 0,
max: 1000000,
left: "27%",
bottom: "25%",
showLabel: true,
itemWidth: 12,
itemHeight: 12,
zlevel: 2,
// seriesIndex: 0,
// text: ["高", "低"],
textStyle: {
// color: "#ffffff",
color: "#06fcff"
},
pieces: [
// 图例颜色
{
min: 10000,
max: 999999,
label: ">10000",
color: "#A9251B",
// symbol: "roundRect",
},
{
min: 1000,
max: 9999,
label: "1000-9999",
// symbol: "roundRect",
color: '#D5514D',
},
{
min: 100,
max: 999,
label: "100-999",
// symbol: "roundRect",
color: '#E57C6D',
},
{
min: 10,
max: 99,
label: "10-99",
// symbol: "roundRect",
color: '#F19D8A',
},
{
min: 1,
max: 9,
label: "1-9",
// symbol: "roundRect",
color: '#FBE6DC',
},
{
value: 0,
label: "0",
// color: "#ffffff",
color: { // 径向渐变
type: 'radial',
x: 0.5,
y: 0.5,
r: 0.5,
colorStops: [{
offset: 0, color: '#040E3B' // 0% 处的颜色
}, {
offset: 1, color: '#082750' // 100% 处的颜色
}],
global: false, // 缺省为 false
},
// symbol: "image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAeCAMAAAAB8C7XAAAAeFBMVEUAAADBIhzAIh+/ISDBHSHDHh6jMyHAISDAISC/ISDAIR/AISDAHiG/IR+6RjG+IiC/IiHAICC/IR/AISG+ISG+Ix+/ICDAIiC+IB/AIBzCHh68JRa/IiHAIB+/ISC9IiK/Hx+/IiC+IiK+Ih++ICDCJB/BJB+/ISDiIZL9AAAAJ3RSTlMALfv3HQwG0secl4NTQQPkvLWoo2xpZWFYJBkR693CkIx4WktHMjGv/nLNAAAAp0lEQVQoz4XNVwrEMAxFUcUlvfcyvWn/OxxBMASPxNyPBL9jMPwrNJ9gcwfTLfQt52ueRgqpeLQ0rJnGgP4BHtJNcqE7BNQJvRy0EgwSLBJAJUEnwSSBkQDO/l6XOyTe3lrYexxX1bzAte5TlWT9XFg4FNGs+xJ+SgnuwJQTGA42xYB7pGDhhjiw8ERMWbAKY2CLUYcsZIhvFgrEkYVQYw5s9QR8/tNf+EUpppEdkKMAAAAASUVORK5CYII=",
// symbol: "roundRect",
},
],
},
geo: {
map: "china",
zoom: 1.7,
top: "30%",
zlevel: 0,
label: {
show: false,
},
itemStyle: {
areaColor: '#07183F',
shadowColor: '#1863DE',
shadowOffsetY: 15,
shadowOffsetX: 2,
},
},
series: [
{
type: "map",
map: 'china',
zoom: 1.7,
top: "30%",
zlevel: 1,
label: {
show: true,
fontSize: "14",
color: "#00D9A9",
},
itemStyle: {
// areaColor: '#07183F',
// areaColor: { // 单向渐变
// type: 'linear',
// x: 0,
// y: 0,
// x2: 0,
// y2: 1,
// colorStops: [{
// offset: 0, color: '#040E3B' // 0% 处的颜色
// }, {
// offset: 1, color: '#144975' // 100% 处的颜色
// }],
// global: false // 缺省为 false
// },
areaColor: { // 径向渐变
type: 'radial',
x: 0.5,
y: 0.5,
r: 0.5,
colorStops: [{
offset: 0, color: '#040E3B' // 0% 处的颜色
}, {
offset: 1, color: '#082750' // 100% 处的颜色
}],
global: false // 缺省为 false
},
borderWidth: 2,
borderColor: '#3680A8',
shadowColor: '#3680A8',
// shadowOffsetY: 15,
// shadowOffsetX: 0,
},
// geoIndex: 0,
data: mapData,
},
{
type: 'scatter',
coordinateSystem: 'geo',
symbol: 'image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAeCAMAAAAB8C7XAAAAeFBMVEUAAADBIhzAIh+/ISDBHSHDHh6jMyHAISDAISC/ISDAIR/AISDAHiG/IR+6RjG+IiC/IiHAICC/IR/AISG+ISG+Ix+/ICDAIiC+IB/AIBzCHh68JRa/IiHAIB+/ISC9IiK/Hx+/IiC+IiK+Ih++ICDCJB/BJB+/ISDiIZL9AAAAJ3RSTlMALfv3HQwG0secl4NTQQPkvLWoo2xpZWFYJBkR693CkIx4WktHMjGv/nLNAAAAp0lEQVQoz4XNVwrEMAxFUcUlvfcyvWn/OxxBMASPxNyPBL9jMPwrNJ9gcwfTLfQt52ueRgqpeLQ0rJnGgP4BHtJNcqE7BNQJvRy0EgwSLBJAJUEnwSSBkQDO/l6XOyTe3lrYexxX1bzAte5TlWT9XFg4FNGs+xJ+SgnuwJQTGA42xYB7pGDhhjiw8ERMWbAKY2CLUYcsZIhvFgrEkYVQYw5s9QR8/tNf+EUpppEdkKMAAAAASUVORK5CYII=',
symbolSize: 12, //图形大小
zlevel: 3,
label: {
show: false,
},
data: markPointData
}
],
};
this.mapChart.setOption(option);
});
},