嘿,朋友!今天咱们来聊点有意思的——怎么用ECharts画出你自己的专属地图。是不是觉得听上去挺高大上的?其实啊,只要你掌握了几个关键步骤,这事儿比煮泡面还简单(夸张了点,但真的不难)。
先说点背景知识。你有没有那种客户或老板,非要你做一个”专属区域图表”,比如展示某个省份的销售数据,或者某个城市的人口分布?普通的柱状图、折线图早就看腻了,这时候一张漂亮的自定义地图就能让数据”活”起来。
而ECharts,作为百度开源的可视化神器,支持从GeoJSON加载地图数据,让你能够随心所欲地绘制任何你想要的区域。
什么是GeoJSON?
在动手之前,咱们得先搞明白GeoJSON是个啥东西。GeoJSON是一种基于JSON格式的空间数据交换格式,专门用来描述地理空间信息。
想象一下,你要画一张中国地图,地图上的每一个省份都是一个多边形,每个多边形由一系列经纬度坐标点组成。这些坐标点连起来,就构成了省份的轮廓。GeoJSON就是把这些信息用标准的JSON格式存起来的东西。
一个简单的GeoJSON长这样:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"name": "北京市"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[116.4, 39.9],
[116.5, 40.0],
[116.6, 39.8],
[116.4, 39.9]
]
]
}
}
]
}
你看,它就是一个标准的JSON对象,里面包含了很多”Feature”(特征),每个特征有”properties”(属性,比如名称)和”geometry”(几何信息,就是那些坐标点)。
GeoJSON文件可以从很多地方获取。国家地理信息公共服务平台(天地图)、自然地球(Natural Earth)或者GADM等网站都提供免费的GeoJSON数据下载。
环境搭建
好,理论讲完了,咱们开始动手。第一步是搭建开发环境。
你需要准备的东西不多:
- 一个文本编辑器(VS Code、Sublime Text都行)
- 浏览器(Chrome、Firefox都OK)
- ECharts库(可以从官网下载或CDN引入)
创建一个新项目目录,比如echarts-map-demo,然后在里面创建两个文件:
index.html—— 主页面china.json—— 中国地图的GeoJSON数据
先来看看index.html的最简结构:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ECharts自定义地图示例</title>
<!-- 引入ECharts -->
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<style>
#map-container {
width: 100%;
height: 600px;
}
</style>
</head>
<body>
<div id="map-container"></div>
<script>
// 我们的代码会写在这里
</script>
</body>
</html>
这里用CDN引入了ECharts 5.4.3版本。为什么要用5.x版本?因为5.x对GeoJSON的支持更加完善,而且API也相对稳定。
至于china.json,你可以从天地图或者Apache ECharts官方示例中获取。官方提供了一个比较完整的中国地图数据,可以直接拿来用:
// 下载地址示例(建议保存到本地)
// https://echarts.apache.org/examples/data/asset/geo/china.json
第一步:基础地图渲染
现在,咱们来做最简单的部分——把地图显示出来。
打开index.html,在script标签里写下:
// 初始化ECharts实例
const chartDom = document.getElementById('map-container');
const myChart = echarts.init(chartDom);
// 注册中国地图
fetch('china.json')
.then(response => response.json())
.then(geoJson => {
echarts.registerMap('china', geoJson);
// 配置项
const option = {
series: [{
type: 'map',
map: 'china',
roam: true, // 允许缩放和平移
label: {
show: true // 显示省份名称
},
emphasis: {
label: {
show: true,
fontSize: 12,
fontWeight: 'bold'
}
}
}]
};
myChart.setOption(option);
})
.catch(error => console.error('加载地图数据失败:', error));
// 响应式调整
window.addEventListener('resize', () => {
myChart.resize();
});
运行这段代码,你就能看到一张清晰的中国地图了。每个省份都显示着名称,而且你可以用鼠标缩放、拖动地图。
这里有个小细节想跟你分享:fetch是ES6的API,用于从服务器获取资源。它返回一个Promise对象,所以我们用.then()来处理成功的结果,用.catch()来处理可能的错误。在浏览器环境中,直接这样用完全没问题。如果你需要在更老的浏览器中运行,可能需要引入Polyfill,或者用XMLHttpRequest替代。
第二步:省份高亮效果
基础地图显示出来了,但这还不够。用户肯定想要那种”鼠标悬停到某个省份时,省份会高亮显示”的交互效果。这就是我们接下来要讲的。
其实,ECharts已经内置了emphasis配置项来处理高亮效果。但如果你想定制高亮的样式,比如改变颜色、边框粗细等,就需要更深入地了解它的配置。
const option = {
backgroundColor: '#f5f5f5', // 背景色
series: [{
type: 'map',
map: 'china',
roam: true,
label: {
show: true,
color: '#333'
},
// 默认状态样式
itemStyle: {
areaColor: '#e8e8e8',
borderColor: '#999',
borderWidth: 1
},
// 高亮状态样式
emphasis: {
itemStyle: {
areaColor: '#ff6b6b',
borderColor: '#c92a2a',
borderWidth: 2
},
label: {
show: true,
color: '#fff',
fontWeight: 'bold',
fontSize: 14
}
},
// 选中状态样式(可选)
select: {
itemStyle: {
areaColor: '#4dabf7',
borderColor: '#228be6',
borderWidth: 2
}
}
}]
};
这里我加了几个细节:
backgroundColor设置页面背景色,让地图看起来不那么突兀- 默认状态下,省份用灰色填充,浅灰色边框
- 高亮状态下,变成红色系,边框加粗,文字变白加粗
- 还加了
select配置,当用户点击省份时(如果启用了选框模式),会有蓝色高亮
第三步:省份颜色映射
光有高亮还不够。通常我们需要根据某个数据值来给不同省份染上不同的颜色。比如,展示各省GDP、人口、销售额等。
这就要用到visualMap组件和series.data数组了。
// 模拟各省数据
const provinceData = [
{ name: '广东省', value: 124369 },
{ name: '江苏省', value: 116364 },
{ name: '山东省', value: 101527 },
{ name: '浙江省', value: 82553 },
{ name: '河南省', value: 72253 },
{ name: '四川省', value: 68311 },
{ name: '湖北省', value: 55806 },
{ name: '湖南省', value: 50927 },
{ name: '河北省', value: 49775 },
{ name: '福建省', value: 48810 },
// ... 其他省份
{ name: '北京市', value: 41611 },
{ name: '上海市', value: 44653 },
{ name: '天津市', value: 15695 },
{ name: '重庆市', value: 32847 },
{ name: '陕西省', value: 35104 },
{ name: '辽宁省', value: 33682 },
{ name: '安徽省', value: 47050 },
{ name: '云南省', value: 25669 },
{ name: '山西省', value: 21727 },
{ name: '江西省', value: 33566 },
{ name: '贵州省', value: 23122 },
{ name: '广西壮族自治区', value: 29332 },
{ name: '内蒙古', value: 21491 },
{ name: '吉林省', value: 14155 },
{ name: '黑龙江省', value: 16222 },
{ name: '甘肃省', value: 15359 },
{ name: '海南省', value: 9363 },
{ name: '宁夏回族自治区', value: 4082 },
{ name: '新疆维吾尔自治区', value: 11996 },
{ name: '青海省', value: 2865 },
{ name: '西藏自治区', value: 1643 }
];
const option = {
tooltip: {
trigger: 'item',
formatter: '{b}<br/>数值: {c}'
},
visualMap: {
min: 0,
max: 130000,
left: 'left',
top: 'bottom',
text: ['高', '低'],
calculable: true,
inRange: {
color: ['#fff7ec', '#fdd49e', '#f16913', '#c51919']
},
textStyle: {
color: '#666'
}
},
series: [{
type: 'map',
map: 'china',
roam: true,
label: {
show: true,
fontSize: 10
},
data: provinceData,
emphasis: {
label: {
show: true,
fontSize: 12,
fontWeight: 'bold'
},
itemStyle: {
areaColor: '#ff6b6b',
borderColor: '#c92a2a',
borderWidth: 2
}
}
}]
};
这里有几个关键点想跟你详细解释:
visualMap组件:这是ECharts中专门用来做颜色映射的组件。它会根据数据的最小值和最大值,自动将数据映射到颜色范围上。inRange.color定义了颜色渐变带,从白色到深红色的四级渐变。calculable: true:这个属性会让visualMap的滑块可以拖动,用户能交互式地调整颜色映射的范围。tooltip.formatter:这是悬停提示框的内容模板。{b}代表名称(省份名),{c}代表数值。你可以根据需要自定义显示格式。data数组:每个元素包含name(省份名,必须和GeoJSON中的名称完全一致)和value(数值)。名称不一致的话,该省份就不会显示颜色。
第四步:精确匹配省份名称
这一步特别重要,也是很多初学者踩坑的地方。ECharts在匹配省份名称时,是严格字符串匹配的。这意味着如果你的数据中写的是”广东”,但GeoJSON里写的是”广东省”,那就匹配不上,该省份不会显示颜色,也不会有高亮效果。
所以,在准备数据之前,最好先检查一下GeoJSON文件中每个省份的properties.name字段到底是什么值。
你可以通过这段代码打印出来看看:
fetch('china.json')
.then(response => response.json())
.then(geoJson => {
// 打印所有省份名称,方便核对
geoJson.features.forEach(feature => {
console.log(feature.properties.name);
});
echarts.registerMap('china', geoJson);
// ... 后续代码
});
运行后,在浏览器控制台中你就能看到所有省份的标准名称。把这些名称复制下来,整理成你的数据数组,就能保证100%匹配。
需要注意的是,不同来源的GeoJSON数据,省份命名可能略有差异。比如:
- 有些用”广东省”,有些用”广东”
- 有些用”西藏自治区”,有些用”西藏”
- 有些用”内蒙古自治区”,有些用”内蒙古”
最稳妥的办法是直接用你加载的那个GeoJSON文件里的名称。
第五步:自定义地图区域(非全国地图)
有时候,你可能不需要全国地图,只需要某个省份的地图。比如,你只想看广东省内的各个地级市分布。
这完全没问题!你只需要找到对应的GeoJSON文件,然后注册为自定义地图名即可。
假设你有一个广东省地图的GeoJSON文件,命名为guangdong.json,你可以这样处理:
fetch('guangdong.json')
.then(response => response.json())
.then(geoJson => {
// 注册为自定义地图名
echarts.registerMap('guangdong', geoJson);
const option = {
tooltip: {
trigger: 'item',
formatter: '{b}: {c}'
},
series: [{
type: 'map',
map: 'guangdong', // 这里要用你注册的地图名
roam: true,
label: {
show: true
},
itemStyle: {
areaColor: '#e8e8e8',
borderColor: '#999'
},
emphasis: {
itemStyle: {
areaColor: '#4dabf7'
}
}
}]
};
myChart.setOption(option);
});
这里的关键点是map: 'guangdong',这个字符串必须和你registerMap时用的名字完全一致。
如果你想做多级地图联动(比如先显示全国,点击某个省后切换到该省详细地图),也是可以做到的。思路是监听mapselect或click事件,然后在回调中切换map参数并重新setOption。
第六步:添加数据标注(MarkPoint)
有时候,光有颜色映射还不够直观。你可能想在某些特定位置打上标记,比如省会城市、重要城市等。
ECharts的markPoint配置可以帮你实现:
series: [{
type: 'map',
map: 'china',
roam: true,
data: provinceData,
// 添加标记点
markPoint: {
symbol: 'pin', // 标记形状,可选circle、rect、roundRect、triangle、diamond、pin、arrow
symbolSize: [40, 60], // 标记大小
label: {
show: true,
formatter: '{b}',
color: '#fff'
},
data: [
{ name: '北京', coord: [116.407526, 39.90403] },
{ name: '上海', coord: [121.473701, 31.230416] },
{ name: '广州', coord: [113.264434, 23.129162] },
{ name: '深圳', coord: [114.057868, 22.543099] }
],
emphasis: {
disabled: true // 高亮时不显示标记点,避免遮挡
}
}
}]
markPoint.data数组中的每个元素都有name(标记名称)和coord(经纬度坐标)。坐标可以用高德地图、百度地图等工具查询得到。
如果你希望标记点显示省份数据值而不是固定名称,可以这样写:
data: [
{ name: '北京', value: 41611, coord: [116.407526, 39.90403] },
{ name: '上海', value: 44653, coord: [121.473701, 31.230416] }
]
然后在label.formatter中使用{c}来获取value值。
第七步:气泡地图(Scatter + Map)
有时候,你不仅想在地图上显示颜色,还想用气泡大小来表示数值大小。这种图表叫”气泡地图”。
实现方法是同时使用series数组中的map系列和scatter系列:
”`javascript const option = {
visualMap: {
min: 0,
max: 130000,
left: 'left',
top: 'bottom',
