数据可视化-ECharts简单案例-广州市各区人口密度地图可视化
广州市各区人口密度地图可视化-ECharts
1. 项目需求
使用ECharts完成广州市各区人口密度的地图可视化
2. 实现方式
1. 引入js文件
2. 加载数据
这里使用json数据直接加入到js中,实际工作中可能向服务器请求数据。
点击查看数据
``` var data = [{ name: '荔湾区', value: 123.83 }, { name: '越秀区', value: 103.87 }, { name: '海珠区', value: 181.9 }, { name: '天河区', value: 224.18 }, { name: '白云区', value: 374.3 }, { name: '黄埔区', value: 126.44 }, { name: '番禺区', value: 265.84 }, { name: '花都区', value: 164.24 }, { name: '南沙区', value: 84.66 }, { name: '从化区', value: 71.77 }, { name: '增城区', value: 146.63 }]; var data2 = [{ name: '荔湾区', value: (123.83 / 59.10) }, { name: '越秀区', value: (103.87 / 33.80) }, { name: '海珠区', value: (181.9 / 90.40) }, { name: '天河区', value: (224.18 / 96.33) }, { name: '白云区', value: (374.3 / 795.79) }, { name: '黄埔区', value: (126.44 / 484.17) }, { name: '番禺区', value: (265.84 / 786.15) }, { name: '花都区', value: (164.24 / 970.04) }, { name: '南沙区', value: (84.66 / 527.65) }, { name: '从化区', value: (71.77 / 1974.50) }, { name: '增城区', value: (146.63 / 1616) }].map(function (item) { item.value = item.value.toFixed(4) return item }); ```3. 配置ECharts中的option
通过setOption来进行ECharts的配置
<div id="container" style="height: 100%"></div>
<button id="shiftToMap">切换至地图</button>
<button id="shiftToBar">切换至柱图</button>
<button id="shiftToRose">切换至玫瑰图</button>
<button id="shiftToScatter">切换至气泡图</button>
var dom = document.getElementById('container');
var myChart = echarts.init(dom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
//地图json链接
var ROOT_PATH = 'https://geo.datav.aliyun.com/areas_v3/bound/440100_full.json';
var option;
myChart.showLoading();
//获取地图对象
$.get(ROOT_PATH, function (gzJson) {
myChart.hideLoading();
echarts.registerMap('GZ', gzJson, {});
let currentOption = mapOption;
myChart.setOption(currentOption);
});
//地图配置
const mapOption = {
title: {
text: "广州各地区常住人口可视化图例"
},
//地图的配置选项
visualMap: {
left: 'right',
min: 50,
max: 400,
inRange: {
color: ['#313695', '#4575b4', '#74add1',
'#abd9e9', '#e0f3f8', '#ffffbf', '#fee090',
'#fdae61', '#f46d43', '#d73027', '#a50026'
]
},
text: ['High', 'Low'],
calculable: true
},
//调整大小和方向
grid:{
width:'90%',
top:'10%',
left:'center',
bottom:'10%'
},
tooltip: {},
//显示工具箱
toolbox: {
show: true,
left: 'left',
top: 'bottom',
feature: {
dataView: {
readOnly: false
},
restore: {},
saveAsImage: {}
}
},
//数据配置
series: [{
name: '常住人口(万人)',
id: 'population',
type: 'map',
roam: true,
map: 'GZ',
animationDurationUpdate: 1000, //添加动画效果更加流程
universalTransition: true,
data: data
}]
};
4. 展示结果
如图所示,鼠标移入高亮展示,并显示对应信息
3. 项目拓展
在地图的基础上,增加柱状图、玫瑰图、气泡图等。
所有代码:
点击查看代码
<!DOCTYPE html>
<html lang="zh-CN" style="height: 100%">
<head>
<meta charset="utf-8">
<link rel="shortcut icon"
href="https://fastly.jsdelivr.net/gh/apache/echarts-website@asf-site/zh/images/favicon.png?_v_=20200710_1">
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
button {
right: 0;
font-size: 14px;
line-height: 30px;
text-align: center;
width: 100px;
height: 30px;
border-radius: 5px;
position: fixed;
cursor: pointer;
background-color: rgb(51, 174, 236);
border: none;
transition: all .3s;
}
#shiftToMap {
top: 0;
}
#shiftToBar {
top: 50px;
}
#shiftToRose {
top: 100px;
}
#shiftToScatter {
top: 150px;
}
button:hover {
color: #fff;
background-color: rgb(8, 104, 189);
}
</style>
</head>
<body style="height: 100%; margin: 0">
<div id="container" style="height: 100%">
</div>
<button id="shiftToMap">切换至地图</button>
<button id="shiftToBar">切换至柱图</button>
<button id="shiftToRose">切换至玫瑰图</button>
<button id="shiftToScatter">切换至气泡图</button>
<script type="text/javascript" src="https://fastly.jsdelivr.net/npm/jquery"></script>
<script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5.3.2/dist/echarts.min.js"></script>
<script type="text/javascript">
var dom = document.getElementById('container');
var myChart = echarts.init(dom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
//地图json链接
var ROOT_PATH = 'https://geo.datav.aliyun.com/areas_v3/bound/440100_full.json';
var option;
//两个数据 分别是常住人口数和人口密度
var data = [{
name: '荔湾区',
value: 123.83
}, {
name: '越秀区',
value: 103.87
}, {
name: '海珠区',
value: 181.9
}, {
name: '天河区',
value: 224.18
}, {
name: '白云区',
value: 374.3
}, {
name: '黄埔区',
value: 126.44
}, {
name: '番禺区',
value: 265.84
}, {
name: '花都区',
value: 164.24
}, {
name: '南沙区',
value: 84.66
}, {
name: '从化区',
value: 71.77
}, {
name: '增城区',
value: 146.63
}];
var data2 = [{
name: '荔湾区',
value: (123.83 / 59.10)
}, {
name: '越秀区',
value: (103.87 / 33.80)
}, {
name: '海珠区',
value: (181.9 / 90.40)
}, {
name: '天河区',
value: (224.18 / 96.33)
}, {
name: '白云区',
value: (374.3 / 795.79)
}, {
name: '黄埔区',
value: (126.44 / 484.17)
}, {
name: '番禺区',
value: (265.84 / 786.15)
}, {
name: '花都区',
value: (164.24 / 970.04)
}, {
name: '南沙区',
value: (84.66 / 527.65)
}, {
name: '从化区',
value: (71.77 / 1974.50)
}, {
name: '增城区',
value: (146.63 / 1616)
}].map(function (item) {
item.value = item.value.toFixed(4)
return item
});
var data4 =[{
name: '荔湾区',
value: 59.10
}, {
name: '越秀区',
value: 33.80
}, {
name: '海珠区',
value: 90.40
}, {
name: '天河区',
value: 96.33
}, {
name: '白云区',
value: 795.79
}, {
name: '黄埔区',
value: 484.17
}, {
name: '番禺区',
value: 786.15
}, {
name: '花都区',
value: 970.04
}, {
name: '南沙区',
value: 527.65
}, {
name: '从化区',
value: 974.50
}, {
name: '增城区',
value: 1616
}];
data.sort(function (a, b) {
return a.value - b.value;
})
data2.sort(function (a, b) {
return a.value - b.value;
})
//从data和data1截取出数据作为散点图数据
//散点图数据
var data3 = getScatterData()
function getScatterData() {
console.log(data);
console.log(data4);
data3 = []
for (let i = 0; i < data.length; i++) {
console.log(data4[i].value);
console.log(getYaxisFromData(data4[i].name));
let arr = [data4[i].value, getYaxisFromData(data4[i].name), getSizeFromData2(data4[i].name), data4[i].name,
i]
data3.push(arr)
}
console.log(data3);
return data3
}
function getYaxisFromData(data_name){
for(let i=0;i<data.length;i++){
if(data_name ==data[i].name){
return data[i].value;
}
}
}
function getSizeFromData2(data_name){
for(let i=0;i<data2.length;i++){
if(data_name ==data2[i].name){
return data2[i].value;
}
}
}
//获取按钮对象
var btnMap = document.querySelector('#shiftToMap')
var btnBar = document.querySelector('#shiftToBar')
var btnRose = document.querySelector('#shiftToRose')
var btnScatter = document.querySelector('#shiftToScatter')
myChart.showLoading();
//获取地图对象
$.get(ROOT_PATH, function (gzJson) {
myChart.hideLoading();
echarts.registerMap('GZ', gzJson, {});
let currentOption = mapOption;
myChart.setOption(currentOption);
});
//地图配置
const mapOption = {
title: {
text: "广州各地区常住人口可视化图例"
},
visualMap: {
left: 'right',
min: 50,
max: 400,
inRange: {
color: ['#313695', '#4575b4', '#74add1',
'#abd9e9', '#e0f3f8', '#ffffbf', '#fee090',
'#fdae61', '#f46d43', '#d73027', '#a50026'
]
},
text: ['High', 'Low'],
calculable: true
},
grid:{
width:'90%',
top:'10%',
left:'center',
bottom:'10%'
},
tooltip: {},
toolbox: {
show: true,
left: 'left',
top: 'bottom',
feature: {
dataView: {
readOnly: false
},
restore: {},
saveAsImage: {}
}
},
series: [{
name: '常住人口(万人)',
id: 'population',
type: 'map',
roam: true,
map: 'GZ',
animationDurationUpdate: 1000,
universalTransition: true,
data: data
}]
};
//柱形图配置
const barDoubleOption = {
title: {
text: "广州各地区常住人口可视化图例"
},
legend: {
top:20,
data: ['常住人口数(万人)', '人口密度(百人/km²)']
},
grid: [{
top: 100,
width: '45%',
left: '5%',
containLabel: true
},
{
top: 100,
width: '45%',
left: '50%',
containLabel: true
}],
xAxis: [{
type: 'value'
}, {
gridIndex: 1,
type: 'value'
}],
yAxis: [{
name: '常住人口数(万人)',
type: 'category',
nameTextStyle: {
fontSize: 20
},
axisLabel: {
rotate: 10
},
data: data.map(function (item) {
return item.name;
})
}, {
gridIndex: 1,
name: '人口密度(百人/km²)',
type: 'category',
nameTextStyle: {
fontSize: 20
},
axisLabel: {
rotate: 10
},
data: data2.map(function (item) {
return item.name;
})
}],
toolbox: {
feature: {
saveAsImage: {},
dataZoom: {},
}
},
tooltip: {
trigger: 'item'
},
animationDurationUpdate: 1000,
series: [{
type: 'bar',
id: 'population',
name: '常住人口数(万人)',
data: data.map(function (item) {
return item.value;
}),
universalTransition: true
}, {
xAxisIndex: 1,
yAxisIndex: 1,
type: 'bar',
id: 'density',
left: 'right',
name: '人口密度(百人/km²)',
data: data2.map(function (item) {
item.value = item.value * 100
return item;
}),
universalTransition: true
}]
};
//玫瑰图配置
const roseOption = {
title: {
text: '南丁格尔玫瑰图\n常住人口数和人口密度',
subtext: '',
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
left: 'center',
bottom: 100,
data: data.map(function (item) {
return item.name;
})
},
animationDurationUpdate: 1000,
toolbox: {
show: true,
feature: {
mark: {
show: true
},
dataView: {
show: true,
readOnly: false
},
restore: {
show: true
},
saveAsImage: {
show: true
}
}
},
series: [{
id: 'population',
name: '常住人口数(万人)',
type: 'pie',
radius: [20, 140],
center: ['25%', '50%'],
roseType: 'angle',
universalTransition: true,
itemStyle: {
borderRadius: 5
},
label: {
show: false
},
emphasis: {
label: {
show: true
}
},
data: data.sort()
}, {
id: 'density',
name: '人口密度(百人/km²)',
type: 'pie',
universalTransition: true,
radius: [20, 140],
center: ['75%', '50%'],
roseType: 'area',
itemStyle: {
borderRadius: 5
},
emphasis: {
label: {
show: true
}
},
data: data2
}]
}
//气泡图配置
const scatterOperation = {
backgroundColor: new echarts.graphic.RadialGradient(0.3, 0.3, 0.8, [{
offset: 0,
color: '#f1c4cd'
}, {
offset: 1,
color: '#cdd0d5'
}]),
title: {
text: '气泡图\n气泡大小与人口密度成正比',
subtext:''
},
xAxis: {
name: '面积/km²',
nameTextStyle: {
fontWeight: 'bolder',
fontSize: 18,
}
},
yAxis: {
name: '人口数量/万人',
nameTextStyle: {
fontWeight: 'bolder',
fontSize: 18,
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
emphasis: {
focus: 'series',
label: {
show: true,
formatter: function (param) {
return [param.data[2],param.data[3]];
},
position: 'top'
}
},
grid: {
left: '20%',
right: '20%',
top: '20%',
bottom: '20%'
},
toolbox: {},
series: [{
symbolSize: function (data) {
return Math.sqrt(data[2] * 3000);
},
data: data3,
type: 'scatter',
itemStyle: {
color: function (params) {
console.log(params)
var colorList = [
'#fee090', '#f4ce69', '#f46d43', '#fdae61',
'#abd9e9', '#f0d695', '#8076a3', '#ec9bad', '#ed5a65', '#a50026', '#5a1216',
];
return colorList[params.data[4]]
}
}
}]
}
//按钮监听事件
btnMap.addEventListener('click', () => {
currentOption = mapOption
myChart.setOption(currentOption, true);
});
btnBar.addEventListener('click', () => {
currentOption = barDoubleOption
myChart.setOption(currentOption, true);
});
btnRose.addEventListener('click', () => {
currentOption = roseOption
myChart.setOption(currentOption, true);
});
btnScatter.addEventListener('click', () => {
currentOption = scatterOperation
myChart.setOption(currentOption, true);
});
if (option && typeof option === 'object') {
myChart.setOption(option);
}
window.addEventListener('resize', myChart.resize);
</script>
</body>
</html>
4. 随笔总结
本文是对ECharts应用的简单尝试,但也具有一定的参考价值,在后续开发中可以此为作为模板继续开发拓展功能。
对于地图的可视化,可以不局限于广州城市,这里留下地图可视化数据下载链接以供学习:阿里云DataV。