echarts地图制作

  • 离线地图下载地址https://datav.aliyun.com/tools/atlas/index.html

  • echarts文档地址https://echarts.apache.org/zh/option.html

基于VUE编写,其他框架请自行转换,大同小异

基础配置

先让地图内容出来,npm安装步骤省略,请参考官方文档,创建的div必须设置宽度和高度,关于图表的宽高自适应,参考我的另一篇文章

<template><div class="content"><div ref="charts" style="width: 1000px; height: 800px"></div></div>
</template><script>
import * as echarts from "echarts";
import zhongguo from "@/assets/mapJson/data-city.json"
export default {created () {this.$nextTick(() => {this.initCharts();})},methods: {initCharts() {const charts = echarts.init(this.$refs["charts"]);const option = {// 背景颜色backgroundColor: "#404a59",// 提示浮窗样式tooltip: {show: true,trigger: "item",alwaysShowContent: false,backgroundColor: "#0C121C",borderColor: "rgba(0, 0, 0, 0.16);",hideDelay: 100,triggerOn: "mousemove",enterable: true,textStyle: {color: "#DADADA",fontSize: "12",width: 20,height: 30,overflow: "break",},showDelay: 100},// 地图配置geo: {map: "china",label: {// 通常状态下的样式normal: {show: true,textStyle: {color: "#fff",},},// 鼠标放上去的样式emphasis: {textStyle: {color: "#fff",},},},// 地图区域的样式设置itemStyle: {normal: {borderColor: "rgba(147, 235, 248, 1)",borderWidth: 1,areaColor: {type: "radial",x: 0.5,y: 0.5,r: 0.8,colorStops: [{offset: 0,color: "rgba(147, 235, 248, 0)", // 0% 处的颜色},{offset: 1,color: "rgba(147, 235, 248, .2)", // 100% 处的颜色},],globalCoord: false, // 缺省为 false},shadowColor: "rgba(128, 217, 248, 1)",shadowOffsetX: -2,shadowOffsetY: 2,shadowBlur: 10,},// 鼠标放上去高亮的样式emphasis: {areaColor: "#389BB7",borderWidth: 0,},},},};// 地图注册,第一个参数的名字必须和option.geo.map一致echarts.registerMap("china",zhongguo)charts.setOption(option);},},
};
</script>

这是最基础的配置,外加了一些我自己写的样式,使地图美观一些,如果你完全的复制,并且china.json文件也引入了,那么你会看到如下的内容

这其中比较有意思的是,如果你注册地图时,还有option.geo.map的名字用的是china,南海诸岛会如上图以缩略图展示,但是以此之外来命名地图,则不会展示缩略图。

再次声明,如果二者名字不一致,将会导致异常,致使地图无法显示

数据渲染

实际开发中,往往需要将后台的数据渲染到地图里,我们在option里添加series属性,以下是我的两个示例,仅做参考:

series: [{type: "scatter",coordinateSystem: "geo",symbol: "pin",legendHoverLink: true,symbolSize: [60, 60],// 这里渲染标志里的内容以及样式label: {show: true,formatter(value) {return value.data.value[2];},color: "#fff",},// 标志的样式itemStyle: {normal: {color: "rgba(255,0,0,.7)",shadowBlur: 2,shadowColor: "D8BC37",},},// 数据格式,其中name,value是必要的,value的前两个值是数据点的经纬度,其他的数据格式可以自定义// 至于如何展示,完全是靠上面的formatter来自己定义的data: [{ name: "西藏", value: [91.23, 29.5, 2333] },{ name: "黑龙江", value: [128.03, 47.01, 1007] },],showEffectOn: "render",rippleEffect: {brushType: "stroke",},hoverAnimation: true,zlevel: 1,},// {//   type: "effectScatter",//   coordinateSystem: "geo",//   effectType: "ripple",//   showEffectOn: "render",//   rippleEffect: {//     period: 10,//     scale: 10,//     brushType: "fill",//   },//   hoverAnimation: true,//   itemStyle: {//     normal: {//       color: "rgba(255, 235, 59, .7)",//       shadowBlur: 10,//       shadowColor: "#333",//     },//   },//   zlevel: 1,//   data: [//     { name: "西藏", value: [91.23, 29.5, 2333] },//     { name: "黑龙江", value: [128.03, 47.01, 1007] },//   ],// },
],

两种渲染方式如下:

使用备注的部分时,需要在option.tooltip里添加formatter属性,我写的如下:

const option = {// ...tooltip: {// ...formatter(params) {return `地区:${params.name}</br>数值:${params.value[2]}`;}}
}

更多的方式还要自己多试验,这是个费时且需要耐心的活,你甚至可以将柱状图放上去。有更花里胡哨的效果,也请分享给我。

嵌入文字

使用option.graphic可以实现简单的水印效果

const option = {// ...graphic:{// 水印类型type: 'text',// 相对于容器的位置left:'10%',top: '10%',// 样式设置style: {// 文本内容text: "create by cRack_cLick",// 字体粗细、大小、字体font: 'bolder 1.5rem "Microsoft YaHei", sans-serif',// 字体颜色fill: "#fff"}}
}

效果如下:

利用graphic的type=“group”,还可以组合出一些有意思的效果(抄官方文档的效果):

        graphic: {type: "group",rotation: Math.PI / 4,bounding: "raw",left: 110,top: 110,z: 100,children: [{type: "rect",left: "center",top: "center",z: 100,shape: {width: 400,height: 50,},style: {fill: "rgba(0,0,0,0.3)",},},{type: "text",left: "center",top: "center",z: 100,style: {fill: "#ddd",text: "create by cRack_cLick",font: 'bolder 1.5rem "Microsoft YaHei", sans-serif',},},],},

地图下钻

往往还有一种需求,在我们点击一个省的时候,需要切换到这个省的详细地图,甚至还可以下钻到市、县等等。

为了试下点击下钻,我们需要先了解echarts中的点击事件,文档参考

以目前的功能来说,我们暂时不需要加入其它的业务逻辑以及省级的数据渲染,仅仅只做地图的切换,所以点击事件里我们需要实现获取点击的省份名称,然后根据省份名称,来选择地图的JSON文件,最后重新渲染echarts图表,下面是我的简单示例:

// 新增加北京的地图JSON文件
import beijing from "@/assets/mapJson/data-beijing.json";
// ...initCharts(){const charts = echarts.init(this.$refs["charts"]);
// ...
// 注意这里是echarts的实例对象,而不是echarts组件本身。charts.on('click', ({name}) => {if (name === "北京") {// 修改option的配置,可以继续自定义option.geo.zoom = 0.8// 就像上面提到的,这里必须要和注册地图时的名字一致option.geo.map = "beijing"// 注册地图echarts.registerMap("beijing", beijing)// 重新渲染charts.setOption(option, true)}})
}

需要注意的是,在重新setOption的时候,我们加入了第二个参数,按照官方文档的说法:


参数:

调用方式:

chart.setOption(option, notMerge, lazyUpdate);

或者

chart.setOption(option, {notMerge: ...,lazyUpdate: ...,silent: ...
});
  • option

    图表的配置项和数据。

  • notMerge

    可选,是否不跟之前设置的 option 进行合并,默认为 false,即合并。

  • lazyUpdate

    可选,在设置完 option 后是否不立即更新图表,默认为 false,即立即更新。

  • silent

    可选,阻止调用 setOption 时抛出事件,默认为 false,即抛出事件。


第二个从参数设置为true来让图表重新渲染,而不合并配置,当然,这一点具体需要看你显示开发的需求,我在这里仅是为了演示。绝不是偷懒

另外在echarts v3.x的版本里,切换地图默认是有过渡动画的,而v4.x和v5.x的版本里则没有过渡动画,如果知道怎么加上的,可以私信我。

上面虽然可以实现地图切换,但很显然开发中这么写要被打死。下钻三十多个地图要写三十多个if,显然是一种不理智的开发方式。一种方式我们可以通过axios或者ajax异步请求,但是这样需要你在生产环境和运维协商好,否则会导致请求不到JSON文件。

下面是我在前端写的一个简单的工具方法,仅供参考:

import zhongguo from "@/assets/mapJson/data-city.json";
import neimenggu from "@/assets/mapJson/data-neimenggu.json";
import beijing from "@/assets/mapJson/data-beijing.json";
// ...const mapDict = {"北京": "beijing","内蒙古": "neimenggu",// ...
}const mapData = {beijing,neimenggu,// ...
}export function getMap(mapName) {const cityName = mapDict[mapName]if(cityName){return [cityName, mapData[cityName]]}return ['china', zhongguo]
}

需要建立两个字典,一个是汉字和拼音的对照映射,一个是拼音和JSON文件的映射,这个可灵活配置,并非唯一。

优化一下上面的的代码:

// 删除地图json文件的引用,修改为上面的工具方法
import { getMap } from "./maputil";methods: {initCharts() {const charts = echarts.init(this.$refs["charts"]);const option = {// ...};// 不传name默认会返回中国地图const [mapName, mapJson] = getMap();option.geo.map = mapName;// 地图注册,第一个参数的名字必须和option.geo.map一致echarts.registerMap(mapName, mapJson);charts.setOption(option);charts.on("click", ({ name }) => {// 这里和上面一样,其实还可以再优化一下。为了方便阅读,这里不再封装。const [mapName, mapJson] = getMap(name);option.geo.zoom = 0.8;option.geo.map = mapName;echarts.registerMap(mapName, mapJson);charts.setOption(option, true);});}
}

效果如下:

结合水印制作级联效果

现在的地图可以下钻了,但是似乎操作起来还有些别扭。

我们现在想要的效果是:我们需要每下钻一层,水印部分就会加上当前地区的名称。点击水印地区的名称,就会跳转到当前地区的地图,我们要来改造一下echarts示例的click事件。

首先option.graphic的默认值修改为中国地图,这里为了方便阅读,仅使用text格式演示:

// ...
graphic: [{type: "text",left: "10%",top: "10%",style: {text: "中国",font: 'bolder 1.5rem "Microsoft YaHei", sans-serif',fill: "#fff",},},
],

以数组的形势编写后,思路就明显了,只要在click事件的时候,将下钻地图的信息push进来,并且为了防止重合,稍微移动一下定位即可,我的示例如下:

charts.on("click", ({ name }) => {const [mapName, mapJson] = getMap(name);option.geo.zoom = 0.8;option.geo.map = mapName;// 为了重新定位,这里使用了lengthconst idx = option.graphic.length + 1;option.graphic.push({type: "text",left: `${idx * 10}%`,top: "10%",style: {text: name,font: 'bolder 1.5rem "Microsoft YaHei", sans-serif',fill: "#fff",},});echarts.registerMap(mapName, mapJson);charts.setOption(option, true);
});

点击后效果如下:

现在还有问题,就是点击地区名字没有响应,所以我们还要为option.graphic子元素加上click事件

这个click事件功能也类似,获取地图名称,获取地图数据,重新渲染。但是这个click事件需要注意,比如我点击了北京,那么在数组里是需要将密云区的元素删除掉的,同理,点击中国,则后面的元素都要删除。在这里我就不把相同的部分抽离出来了:

// 防止graph里频繁添加click事件,在添加click事件之前先全部清空掉。
charts.off()
charts.on("click", ({name}) => {// 如果option.graphic里已经有了城市名称,则不进行任何操作,防止频繁点击const index = option.graphic.findIndex(i => i.style.text === name);if (!name || index !== -1) returnconst [mapName, mapJson] = getMap(name);option.geo.zoom = 0.8;option.geo.map = mapName;// 为了重新定位,这里使用了lengthconst idx = option.graphic.length + 1;option.graphic.push({type: "text",left: `${idx * 10}%`,top: "10%",style: {text: name,font: 'bolder 1.5rem "Microsoft YaHei", sans-serif',fill: "#fff",},onclick: () => {// 利用函数的作用域,可以直接拿上面的name来用const [grahpName, graphJson] = getMap(name);const index = option.graphic.findIndex(i => i.style.text === name);// 点击元素之后的所有元素全部删除option.graphic.splice(index + 1);// 很多操作重复了,你可以将公共部分抽离出来option.geo.map = mapName;echarts.registerMap(grahpName, graphJson);charts.setOption(option, true);},});echarts.registerMap(mapName, mapJson);charts.setOption(option, true);
});

这里会有个坑,在给graph添加click事件后,点击时会同时触发我们上面charts.on的click事件,想了很久也没有找到好一点的方式来解决这个事件冲突,最后只好判断了一下name是否为空来暂时解决。如果有更好的办法,也请留言。最终效果如下:

至此绘制地图已经完毕,更多是依靠自己的业务需求来进行更灵活的配置和渲染,它的API没有什么太复杂的,只是我们缺少了一点耐心去实验。

visualMap

首先来看效果

增加visualMap来让地图的数据渲染更有层次感,实现起来也很简单,只需要在option里增加visualMap配置即可:

const option = {// ...visualMap: {// 是否展示左下角,即是是false,也仅是不显示,不影响数据的映射show: true,// 上下端文字text: ["高", "低"],// 最小值和最大值,必须指定min: 0,max: 6000,// 位置left: "10%",bottom: "10%",// 是否展示滑块calculable: true,// 指定映射的数据,对应的是option.series,这里根据自己的实际需要进行配置seriesIndex: [0],// 从下到上的颜色inRange: {color: ['#00467F', '#A5CC82'],},//字体颜色textStyle: {color: "#fff",map: "china",},}
}

如果你的代码是跟着我从上面一直写下来的,那么此时你应该发现只是定位的图标变了,相应的地图区域并未变色,所以我们还要把地图的数据映射上去,所以在option.series里再加一个元素,使其type=“map”,内容与geo一致即可,但是要多加data属性,渲染的数据和定位图标一致。并将seriesIndex的索引做好映射,即可实现。

const option = {// ...visualMap: {// 是否展示左下角,即是是false,也仅是不显示,不影响数据的映射show: true,// 上下端文字text: ["高", "低"],// 最小值和最大值,必须指定min: 0,max: 6000,// 位置left: "10%",bottom: "10%",// 是否展示滑块calculable: true,// 指定映射的数据,对应的是option.series,这里根据自己的实际需要进行配置seriesIndex: [0],// 从下到上的颜色inRange: {color: ['#00467F', '#A5CC82'],},//字体颜色textStyle: {color: "#fff",map: "china",},}
}

如果你的代码是跟着我从上面一直写下来的,那么此时你应该发现只是定位的图标变了,相应的地图区域并未变色,所以我们还要把地图的数据映射上去,所以在option.series里再加一个元素,使其type=“map”,内容与geo一致即可,但是要多加data属性,渲染的数据和定位图标一致。并将seriesIndex的索引做好映射,即可实现。

如果出现了缩放重影,说明生成了两个地图组件,需要在新的series里加上geoIndex属性,值是geo里的索引,这样就只会共享一个组件,不会出现缩放重影的问题了

以下为源文档:

默认情况下,map series 会自己生成内部专用的 geo 组件。但是也可以用这个 geoIndex 指定一个 geo组件。这样的话,map 和 其他 series(例如散点图)就可以共享一个 geo组件了。并且,geo组件的颜色也可以被这个 map series 控制,从而用 visualMap来更改。

当设定了 geoIndex 后,series-map.map属性,以及 series-map.itemStyle 等样式配置不再起作用,而是采用 geo中的相应属性。


很多人找我要源码,博主的本意是希望大家可以自己实验,加深印象。就我个人来说,我拿到源码后就懒得去研究了,总觉得自己已经会了。但介于可能很多人还是刚刚接触,对很多内容并不熟悉,所以在这里贴一下源码,只不过因为时间久远,已经找不到写文章时的代码了,这里贴的是从项目里抽出来的代码,可能会有一些冗余,所以大家尽量参考文章来理解:源码地址

教你从零开始画echarts地图相关推荐

  1. 【资源收藏】画街道地图边界

    因为要做街道地图画边界,找了很多资料之后才看到个稍微可靠点的,要注意的是geojson坐标还需要转换一下对应地图坐标系,不然画出来的边界有偏移: 相关资料: 地图数据可视化 支持街道乡镇级行政区域分界 ...

  2. echarts 山东地图_用Python画中国地图,实现各省份数据可视化

    第一步:安装pyecharts pyecharts是一款将python与echarts结合的强大的数据可视化工具,本文使用了0.1.9.4版本 pip install pyecharts==0.1.9 ...

  3. echarts 画中国地图

    数据可视化平台,中国各省数据和坐标 阿里云可视化 效果 使用echart画中国地图,步骤如下 1.安装依赖 npm i echarts@4 创建一个js文件 当你可以访问https请求的时候则使用,如 ...

  4. 关于echarts画中国地图只显示海南诸岛的问题

    有些同学估计跟我遇到过一样的问题 我也不废话 首先js用echarts画中国地图需要俩个js文件 1.china.js 可以去网上找一下 2.echarts-min.js 官网定制自己需要的js文件 ...

  5. echarts地图生成

    echarts地图扩展文件使用geoJson格式. 1.在线生成 http://ecomfe.github.io/echarts-map-tool/  这里可以生成省市区的json,但是最多生成到&q ...

  6. echarts地图边界数据的实时获取与应用,省市区县多级联动【附最新geoJson文件下载】...

    首先,来看下效果图 在线体验地址:https://hxkj.vip/demo/echartsMap/,并提供实时geoJson数据文件下载 echarts官方社区链接地址(可在线编辑):https:/ ...

  7. 高德地图使用、echarts地图等地图设置

    1.高德地图使用 前提准备: 1.打开高德地图开方平台,注册账号: https://console.amap.com/dev/key/app 2.创建一个应用,获取key值. 一.引入相关资源 < ...

  8. echarts 地图geo、geo3D 下穿

    记录贴 echarts地铁图,3D地图的下穿 首先说平面的吧,平面地图的下穿通过echats的点击事件,获取到点击板块的名称,通过名称请求json数据,代码如下 myChart.on('click', ...

  9. 一步一步教你从零开始写C语言链表(超详细)

    STM32 HAL开发完全指南 写文章 一步一步教你从零开始写C语言链表(超详细) 杨源鑫 嵌入式系统工程师.物联网创业合伙人,业务经理兼产品经理 285 人赞同了该文章 为什么要学习链表? 链表主要 ...

  10. python网络爬虫教程-教你从零开始学会写 Python 爬虫

    原标题:教你从零开始学会写 Python 爬虫 写爬虫总是非常吸引IT学习者,毕竟光听起来就很酷炫极客,我也知道很多人学完基础知识之后,第一个项目开发就是自己写一个爬虫玩玩. 其实懂了之后,写个爬虫脚 ...

最新文章

  1. 映射递归循环-约瑟夫环问题递归解法的一点理解
  2. .NET Core实战项目之CMS 第十章 设计篇-系统开发框架设计
  3. hbaseRowkey设计
  4. macbook安装免费vmware fusion
  5. 什么是IPFS - BlockChain Storage 区块链存储 (1)
  6. Oracle Lob介绍
  7. Tomcat部署多个Sring Boot项目时Unable To Register MBean Exception的一种解决方法
  8. 投影向量计算公式的推导
  9. Android facebook集成
  10. 打造百亿量级、亿级日活SDK的十大关键要点
  11. 敏捷转型行动笔记:内部敏捷教练实践
  12. 摄影中的曝光补偿、白加黑减
  13. 敏捷ACP.知识总结.错题回顾
  14. cleanup(cleanup什么意思中文)
  15. 去千户苗寨为什么说不要为了节约钱住普通客栈,而要住商务酒店
  16. 支付宝新移动支付平台解析
  17. gstreamer插件开发指南(一)
  18. 惊了,Alibaba内部“Java学习宝典”,居然系统到P7 ,学到就是赚到
  19. mp3播放器基本完工
  20. 18.10.9 实验吧----分道扬镳

热门文章

  1. chorme流程图设计插件gliffy 的加载
  2. java集成kettle教程(附示例代码)
  3. linux网络适配器驱动程序怎么安装,如何安装网卡驱动_如何重新安装网卡驱动
  4. mysql查看有哪些函数_MySQL函数一览_MySQL函数全部汇总
  5. putty怎么更改为中文_putty中文显示乱码解决方法
  6. linux中的so文件
  7. 电脑微信双开 bat文件
  8. 车牌识别及提取系统MATLAB,车牌识别系统设计及MATLAB仿真
  9. Appium连接教程
  10. 用户故事讲解(看最后的例子,你应该就知道怎么样写用户故事了)