前言 本案例,如之前的几篇博客一样,依旧是使用ECharts来实现图表的展示。世界疫情的展示使用了世界地图和南丁格尔玫瑰图的形式来展示。使用Ajax和js后台处理数据和引入。
ECharts参考官网:ECharts官网地址
1.项目展示与示意图 该项目目前已经上传gitee。点击访问
以下是项目截图:
文章图片
2.页面布局 页面布局比之前中国实时展示的要简单许多。由于篇幅原因(可视化大屏建议宽高100%),只能使用两个图,于是页面布局非常简单。主要三部分,标题、全球地区累计确诊分布地图、海外疫情前二十玫瑰图。
页面布局图此处省略。
3.实现 3.1 插件引入
世界地图需要引入ECharts 4.8或者4.0以上的map插件支持,这些插件都可以去官方下载(注意ECharts5.0最新版本中不支持map地图插件,最好下载4.x版本的,写着使用的是4.8版本的)。Ajax请求需要使用JQuery.js插件支持。
可以使用vs.code也可以直接使用IDEA组织代码管理。
插件引入代码:
src="https://www.it610.com/article/js/echarts.min.js">
src="https://www.it610.com/article/js/world.js">
src="https://www.it610.com/article/js/jquery.min.js">
3.2 前端布局
前端布局非常简单,直接贴代码:
src="https://www.it610.com/article/js/world01.js">
3.3 世界地区确诊分布地图的实现
该功能先使用ECharts的世界地图插件,生成后,在js代码中注入数据,设置数据渲染,图例,颜色块等。下面将会讲解和贴该部分的代码,数据的渲染和处理将会在第四章中描述。
注意:由于地图数据来源于官方,所以国家的name都会是英文的。需要配置国家别名转换,将英文名转换成中文。(这一步比较复杂,部分国家翻译可能不准确,写者将会上传自己转换集)
实现示意图:
文章图片
js代码:
function getWorldMap(data){
var myChart = echarts.init(
document.getElementById('left1'), 'white', {renderer: 'canvas'});
letnameComparison = {
'Canada':'加拿大',
'Russia':'俄罗斯',
'China':'中国',
'United States':'美国',
'Singapore Rep.':'新加坡',
'Dominican Rep.':'多米尼加',
'Palestine':'巴勒斯坦',
'Bahamas':'巴哈马',
'Timor-Leste':'东帝汶',
'Afghanistan':'阿富汗',
'Guinea-Bissau':'几内亚比绍',
"C?ted'Ivoire":'科特迪瓦',
'Siachen Glacier':'锡亚琴冰川',
"Br. Indian Ocean Ter.":'英属印度洋领土',
'Angola':'安哥拉',
'Albania':'阿尔巴尼亚',
'United Arab Emirates':'阿联酋',
'Argentina':'阿根廷',
'Armenia':'亚美尼亚',
'French Southern and Antarctic Lands':'法属南半球和南极领地',
'Australia':'澳大利亚',
'Austria':'奥地利',
'Azerbaijan':'阿塞拜疆',
'Burundi':'布隆迪',
'Belgium':'比利时',
'Benin':'贝宁',
'Burkina Faso':'布基纳法索',
'Bangladesh':'孟加拉',
'Bulgaria':'保加利亚',
'The Bahamas':'巴哈马',
'Bosnia and Herz.':'波斯尼亚和黑塞哥维那',
'Belarus':'白俄罗斯',
'Belize':'伯利兹',
'Bermuda':'百慕大',
'Bolivia':'玻利维亚',
'Brazil':'巴西',
'Brunei':'文莱',
'Bhutan':'不丹',
'Botswana':'博茨瓦纳',
'Central African Rep.':'中非共和国',
'Switzerland':'瑞士',
'Chile':'智利',
'Ivory Coast':'象牙海岸',
'Cameroon':'喀麦隆',
'Dem. Rep. Congo':'刚果(金)',
'Congo':'刚果(布)',
'Colombia':'哥伦比亚',
'Costa Rica':'哥斯达黎加',
'Cuba':'古巴',
'N. Cyprus':'北塞浦路斯',
'Cyprus':'塞浦路斯',
'Czech Rep.':'捷克',
'Germany':'德国',
'Djibouti':'吉布提',
'Denmark':'丹麦',
'Algeria':'阿尔及利亚',
'Ecuador':'厄瓜多尔',
'Egypt':'埃及',
'Eritrea':'厄立特里亚',
'Spain':'西班牙',
'Estonia':'爱沙尼亚',
'Ethiopia':'埃塞俄比亚',
'Finland':'芬兰',
'Fiji':'斐济',
'Falkland Islands':'福克兰群岛',
'France':'法国',
'Gabon':'加蓬',
'United Kingdom':'英国',
'Georgia':'格鲁吉亚',
'Ghana':'加纳',
'Guinea':'几内亚',
'Gambia':'冈比亚',
'Guinea Bissau':'几内亚比绍',
'Eq. Guinea':'赤道几内亚',
'Greece':'希腊',
'Greenland':'格林纳达',
'Guatemala':'危地马拉',
'French Guiana':'法属圭亚那',
'Guyana':'圭亚那',
'Honduras':'洪都拉斯',
'Croatia':'克罗地亚',
'Haiti':'海地',
'Hungary':'匈牙利',
'Indonesia':'印度尼西亚',
'India':'印度',
'Ireland':'爱尔兰',
'Iran':'伊朗',
'Iraq':'伊拉克',
'Iceland':'冰岛',
'Israel':'以色列',
'Italy':'意大利',
'Jamaica':'牙买加',
'Jordan':'约旦',
'Japan':'日本本土',
'Kazakhstan':'哈萨克斯坦',
'Kenya':'肯尼亚',
'Kyrgyzstan':'吉尔吉斯斯坦',
'Cambodia':'柬埔寨',
'Korea':'韩国',
'Kosovo':'科索沃',
'Kuwait':'科威特',
'Lao PDR':'老挝',
'Lebanon':'黎巴嫩',
'Liberia':'利比里亚',
'Libya':'利比亚',
'Sri Lanka':'斯里兰卡',
'Lesotho':'莱索托',
'Lithuania':'立陶宛',
'Luxembourg':'卢森堡',
'Latvia':'拉脱维亚',
'Morocco':'摩洛哥',
'Moldova':'摩尔多瓦',
'Madagascar':'马达加斯加',
'Mexico':'墨西哥',
'Macedonia':'马其顿',
'Mali':'马里',
'Myanmar':'缅甸',
'Montenegro':'黑山',
'Mongolia':'蒙古',
'Mozambique':'莫桑比克',
'Mauritania':'毛里塔尼亚',
'Malawi':'马拉维',
'Malaysia':'马来西亚',
'Namibia':'纳米比亚',
'New Caledonia':'新喀里多尼亚',
'Niger':'尼日尔',
'Nigeria':'尼日利亚',
'Nicaragua':'尼加拉瓜',
'Netherlands':'荷兰',
'Norway':'挪威',
'Nepal':'尼泊尔',
'New Zealand':'新西兰',
'Oman':'阿曼',
'Pakistan':'巴基斯坦',
'Panama':'巴拿马',
'Peru':'秘鲁',
'Philippines':'菲律宾',
'Papua New Guinea':'巴布亚新几内亚',
'Poland':'波兰',
'Puerto Rico':'波多黎各',
'Dem. Rep. Korea':'朝鲜',
'Portugal':'葡萄牙',
'Paraguay':'巴拉圭',
'Qatar':'卡塔尔',
'Romania':'罗马尼亚',
'Rwanda':'卢旺达',
'W. Sahara':'西撒哈拉',
'Saudi Arabia':'沙特阿拉伯',
'Sudan':'苏丹',
'S. Sudan':'苏丹',
'Senegal':'塞内加尔',
'Solomon Is.':'所罗门群岛',
'Sierra Leone':'塞拉利昂',
'El Salvador':'萨尔瓦多',
'Somaliland':'索马里兰',
'Somalia':'索马里',
'Serbia':'塞尔维亚',
'Suriname':'苏里南',
'Slovakia':'斯洛伐克',
'Slovenia':'斯洛文尼亚',
'Sweden':'瑞典',
'Swaziland':'斯威士兰',
'Syria':'叙利亚',
'Chad':'乍得',
'Togo':'多哥',
'Thailand':'泰国',
'Tajikistan':'塔吉克斯坦',
'Turkmenistan':'土库曼斯坦',
'East Timor':'东帝汶',
'Trinidad and Tobago':'特里尼达和多巴哥',
'Tunisia':'突尼斯',
'Turkey':'土耳其',
'Tanzania':'坦桑尼亚',
'Uganda':'乌干达',
'Ukraine':'乌克兰',
'Uruguay':'乌拉圭',
'Uzbekistan':'乌兹别克斯坦',
'Venezuela':'委内瑞拉',
'Vietnam':'越南',
'Vanuatu':'瓦努阿图',
'West Bank':'西岸',
'Yemen':'也门',
'South Africa':'南非',
'Zambia':'赞比亚',
'Zimbabwe':'津巴布韦',
'C?te d\'\Ivoire':'科特迪瓦'
};
// var option代表定义一个名为option的变量,后面花括号里的代表我们需要作图的参数设置
var option = {
// 默认的颜色数组 (如果不明确设置每个数据项的颜色,则会采用默认的数组
// 此处的颜色为十六进制表示,也可以使用rgb来表示。简单地理解就是一串字符就代表一个颜色,挑选喜欢的颜色可以自行搜索颜色
//"color": ["#ac6767","#1d953f","#6950a1","#918597"],
title:{
text:'\n\n全球地区累计确诊分布',
left:'center',
textStyle: {
fontSize: 27,
color: 'black'
},
},
tooltip: {
trigger: 'item',
formatter: '{a}
{b} : {c} ({d}%)'
},
visualMap:{ //左侧小导航图标
show:true,
x:'left',
y:'bottom',
textStyle:{
fontSize:15,
},
splitList:[
{start:1,end: 9},
{start:10,end:99},
{start:100,end:999},
{start:1000,end:9999},
{start:10000,end:99999},
{start:100000,end:999999},
{start:1000000,end:9999999},
{start:10000000}],color:['#2F0000','#4D0000','#600000','#750000','#930000','#AE0000','#CE0000','#FF9797']
},
tooltip: {// 鼠标悬浮,单击产生的效果(在网页上可以动态显示)
show: true,
trigger: "item",
triggerOn: "mousemove|click",
axisPointer: {
type: "line"
},
textStyle: {
"fontSize": 14
},
"borderWidth": 0
},series: [{
// 图标类型为 地图
type:'map',
name:'累计确诊人数',
nameMap: nameComparison,
roam:false,//禁用拖动和缩放
label: {
show: false,
position: "top",
margin: 8
},
mapType: 'world',// 地图类型为 世界地图
// data里的每一个{}中,是一项数据整体,标明了该项数据的名称,值,以及颜色等参数。注意:此处的字符串需要加双引号""(输入法切换至英文状态)"zoom": 1,
// 去除各个国家上的小红点
showLegendSymbol: false,
itemStyle:{//图形样式
normal:{
borderWidth: .3,//区域边框宽度
borderColor:'#009fe8',//区域边框颜色
areaColor:'#ffefd5',//区域颜色
},
emphasis:{//鼠标滑过地图高亮的相关设置
borderWidth: .5,
borderColor:'#4b0082',
areaColor:'#fff',
}
},
data: [{name:'中国',value:chinaConfirm}], //数据***关键***
}],
};
//世界个国家数据注入
var countries = data;
for(var country of countries){
//console.log(country);
option.series[0].data.push({
name:country.name,
value:country.confirm
})
}myChart.setOption(option);
}
3.4 海外疫情前二十南丁格尔玫瑰图实现
该部分使用了Gallery社区的开源作品。由于更换了网站名,没有找到以前引用的作者。该社区链接:Gallery开源社区 该社区内有许多基于ECharts实现的图表,复制即可实现,开箱食用,注入数据即可完成渲染。
【数据可视化|基于ECharts数据可视化案例--世界疫情实时展示】海外疫情前二十玫瑰图主要摘取了世界疫情确诊前二十的国家,以半径为判定标准(半径值取决于该国家确诊人数),该国家的确诊人数越多则半径越长。此外每片扇区的颜色不同,以红色衰减。图例则显示这二十个国家的确诊人数和死亡人数,这部分是使用了echarts的formatter回调函数写的。
该功能数据的引入使用的是Array数组引入,部分代码冗余,有待优化。关于数据爬取和处理,在下面的第四章中描述。
海外疫情前二十的效果图:
文章图片
js实现:
function getNightingaleRose(countryName,countryConfirm,countryDead){//南丁格尔玫瑰图
var myChart = echarts.init(document.getElementById('left2'),'white');
var legenddata = https://www.it610.com/article/[
{name:countryName[0],Confirmed:countryConfirm[0],Dead:countryDead[0]},
{name:countryName[1],Confirmed:countryConfirm[1],Dead:countryDead[1]},
{name:countryName[2],Confirmed:countryConfirm[2],Dead:countryDead[2]},
{name:countryName[3],Confirmed:countryConfirm[3],Dead:countryDead[3]},
{name:countryName[4],Confirmed:countryConfirm[4],Dead:countryDead[4]},
{name:countryName[5],Confirmed:countryConfirm[5],Dead:countryDead[5]},
{name:countryName[6],Confirmed:countryConfirm[6],Dead:countryDead[6]},
{name:countryName[7],Confirmed:countryConfirm[7],Dead:countryDead[7]},
{name:countryName[8],Confirmed:countryConfirm[8],Dead:countryDead[8]},
{name:countryName[9],Confirmed:countryConfirm[9],Dead:countryDead[9]},
{name:countryName[10],Confirmed:countryConfirm[10],Dead:countryDead[10]},
{name:countryName[11],Confirmed:countryConfirm[11],Dead:countryDead[11]},
{name:countryName[12],Confirmed:countryConfirm[12],Dead:countryDead[12]},
{name:countryName[13],Confirmed:countryConfirm[13],Dead:countryDead[13]},
{name:countryName[14],Confirmed:countryConfirm[14],Dead:countryDead[14]},
{name:countryName[15],Confirmed:countryConfirm[15],Dead:countryDead[15]},
{name:countryName[16],Confirmed:countryConfirm[16],Dead:countryDead[16]},
{name:countryName[17],Confirmed:countryConfirm[17],Dead:countryDead[17]},
{name:countryName[18],Confirmed:countryConfirm[18],Dead:countryDead[18]},
{name:countryName[19],Confirmed:countryConfirm[19],Dead:countryDead[19]},
],option = {
dataset: {
source: [['Country','Confirmed','SQRT','Dead'],
[countryName[0],countryConfirm[0],Math.sqrt(countryConfirm[0]),countryDead[0]],
[countryName[1],countryConfirm[1],Math.sqrt(countryConfirm[1]),countryDead[1]],
[countryName[2],countryConfirm[2],Math.sqrt(countryConfirm[2]),countryDead[2]],
[countryName[3],countryConfirm[3],Math.sqrt(countryConfirm[3]),countryDead[3]],
[countryName[4],countryConfirm[4],Math.sqrt(countryConfirm[4]),countryDead[4]],
[countryName[5],countryConfirm[5],Math.sqrt(countryConfirm[5]),countryDead[5]],
[countryName[6],countryConfirm[6],Math.sqrt(countryConfirm[6]),countryDead[6]],
[countryName[7],countryConfirm[7],Math.sqrt(countryConfirm[7]),countryDead[7]],
[countryName[8],countryConfirm[8],Math.sqrt(countryConfirm[8]),countryDead[8]],
[countryName[9],countryConfirm[9],Math.sqrt(countryConfirm[9]),countryDead[9]],
[countryName[10],countryConfirm[10],Math.sqrt(countryConfirm[10]),countryDead[10]],
[countryName[11],countryConfirm[11],Math.sqrt(countryConfirm[11]),countryDead[11]],
[countryName[12],countryConfirm[12],Math.sqrt(countryConfirm[12]),countryDead[12]],
[countryName[13],countryConfirm[13],Math.sqrt(countryConfirm[13]),countryDead[13]],
[countryName[14],countryConfirm[14],Math.sqrt(countryConfirm[14]),countryDead[14]],
[countryName[15],countryConfirm[15],Math.sqrt(countryConfirm[15]),countryDead[15]],
[countryName[16],countryConfirm[16],Math.sqrt(countryConfirm[16]),countryDead[16]],
[countryName[17],countryConfirm[17],Math.sqrt(countryConfirm[17]),countryDead[17]],
[countryName[18],countryConfirm[18],Math.sqrt(countryConfirm[18]),countryDead[18]],
[countryName[19],countryConfirm[19],Math.sqrt(countryConfirm[19]),countryDead[19]],
]
},
toolbox: {
show: true,
feature: {
mark: {show: true},
dataView: {show: true, readOnly: false},
magicType: {
show: true,
type: ['pie', 'funnel']
},
//restore: {show: true},
saveAsImage: {show: true}
}
},
title: {
text: '海外疫情前二十玫瑰图',
//subtext: '\n\t\t\t\t\t\t使用秀秀的数据\n\n——by Krystal1',
x: '50%',
y: '50',
textStyle:{
fontSize:27,
fontWeight:'bold',
fontFamily:'Microsoft YaHei',
color:'#000'
},
subtextStyle:
{
fontStyle:'italic',
fontSize:14
}
},
legend: {
x: 'right',//水平位置,【left\center\right\数字】
y: '150',//垂直位置,【top\center\bottom\数字】
align:'left',//字在图例的左边或右边【left/right】
orient:'vertical',//图例方向【horizontal/vertical】
icon: "circle",//图例形状【circle\rect\roundRect\triangle\diamond\pin\arrow\none】
textStyle://图例文字
{
fontFamily:'微软雅黑',
color:'#000',},
data: countryName,
formatter: function(params){
//console.log('图例参数',params)
for (var i=0;
i3000000)
{return params.data[0]+'\n'+params.data[1]+"例"+'\n'+"死亡"+params.data[3]+"例";
}
else{return "";
}
},
},
},
},
},
{
name:'透明圆圈',
type:'pie',
radius: [10,27],
center: ['35%', '65%'],
itemStyle: {
color: 'rgba(250, 250, 250, 0.3)',
},
data:[
{value:10,name:''}
]
},
{
name:'透明圆圈',
type:'pie',
radius: [10,35],
center: ['35%', '65%'],
itemStyle: {
color: 'rgba(250, 250, 250, 0.3)',
},
data:[
{value:10,name:''}
]
}
]
};
myChart.setOption(option);
}
4.数据爬取与处理 该部分采用Ajax实现。数据的获取函数以每秒钟执行一次来实现实时获取。数据主要来源于腾讯。网址:腾讯新闻
js代码:
function getData(){
$.ajax({//中国数据单独获取,获取后直接赋值
url:'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5',
data:{
name:'disease_h5'
},
dataType:'jsonp',
success:function(res){
var data = https://www.it610.com/article/JSON.parse(res.data);
var chinaArray = data.areaTree[0];
chinaConfirm = chinaArray.total.confirm;
//console.log("中国人数"+chinaConfirm)
}
});
$.ajax({//全球各国数据获取,存入data传入函数
type:'post',
url:'https://api.inews.qq.com/newsqa/v1/automation/foreign/country/ranklist',
dataType:'json',
success:function(res){
var data = https://www.it610.com/article/res.data;
getWorldMap(data);
var countries = data;
var count=0;
//计数,取前20个国家
//存储前20个国家的数据(name,confirm,dead)
var countryName = [];
var countryConfirm = [];
var countryDead = [];
for(var country of countries){
//console.log(country);
if(count==20){
break;
}else{
countryName[count]=country.name
countryConfirm[count]=country.confirm
countryDead[count]=country.dead
count++
}
}
getNightingaleRose(countryName,countryConfirm,countryDead);
}
});
}
getData();
//执行数据获取
setInterval(getData,1000);
//每1s查询获取一次数据
后记 该案例实现在写者的毕业设计中,只因论文中实现篇幅较大不足以添加,故记录于此。其中,海外疫情前二十的实现借助了开源社区Gallery的大神作品,其余皆为原创,部分代码有待优化,欢迎指出。
欢迎大家指点学习,欢迎私信写者。
推荐阅读
- 数据可视化|数据可视化-监控大屏呈现和拓扑图绘制工具总结
- 前端开发|数据可视化大屏-Vue项目
- #|1 一文详细阐述UI设计颜色搭配,受益匪浅~
- QT|QT-数据可视化大屏1
- 大屏云|数据可视化大屏 - 大屏云极简使用手册
- 数据可视化|数据大屏 - guandata智能数据可视化分析
- 阿里云大数据认证——使用DataV制作实时销售数据可视化大屏-课堂笔记
- #|2 数据可视化大屏 - 布局
- chrome|Chrome速度无人能敌(Safari也甘拜下风)