1、題目要求
我們有的是熱情、激情、無限的動力,清明三天放假休息,爲了紀念犧牲的烈士,我們集體決定仿照約翰·霍普金斯大學制作全球疫情發佈圖(WEB版),可以實時訪問。行動起來吧。
2、整體思想
首先需要前幾天的中國疫情地圖可視化的基礎上來進一步實現世界疫情可視化的,由於以前的國內數據有些混亂,這次用到的數據是重新爬取的,將數據庫查詢到的數據通過json形式傳給頁面並進行解析以及世界地圖的對應。整個的框架是簡單的幾個div,大致可分爲標題、世界地圖、全球確診人數及各個國家名單、全球死亡人數及各個國家名單、全球治癒人數及各個國家名單、數據更新時間以及全球疫情確診的整體趨勢。
3、代碼實現
world.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>全球疫情信息可視化</title>
<link href="${pageContext.request.contextPath }/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
<script src="${pageContext.request.contextPath }/js/jquery-1.8.3.min.js"></script>
<script src="${pageContext.request.contextPath }/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/echarts.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/world.js"></script>
</head>
<style>
#title{
background:black;
border: solid 1px;
font-family:"黑體";
text-align:center;
font-color:red;
height:80px;
width:1260px;
float:left;
}
#time{
background:black;
border: solid 1px;
font-family:"黑體";
text-align:center;
font-color:#333;
width:259px;
height:80px;
float:left;
}
#left{
background:black;
overflow-x: auto; overflow-y: auto;
border: solid 1px;
font-family:"黑體";
text-align:center;
font-color:#333;
width:250px;
height:640px;
float:left;
}
#left1{
background:black;
overflow-x: auto; overflow-y: auto;
border: solid 1px;
font-family:"黑體";
text-align:center;
font-color:#333;
width:250px;
height:490px;
float:left;
}
#left2{
background:black;
overflow-x: auto; overflow-y: auto;
border: solid 1px;
font-family:"黑體";
text-align:center;
font-color:#333;
width:250px;
height:140px;
float:left;
}
#right{
background:black;
border: solid 1px;
font-family:"黑體";
text-align:center;
font-color:#333;
width:419px;
height:430px;
float:left;
}
#right1{
background:black;
overflow-x: auto; overflow-y: auto;
border: solid 1px;
font-family:"黑體";
text-align:center;
font-color:#333;
width:205px;
height:440px;
float:left;
}
#right2{
background:black;
overflow-x: auto; overflow-y: auto;
border: solid 1px;
font-family:"黑體";
text-align:center;
font-color:#333;
width:205px;
height:440px;
float:right;
}
#main{
background:black;
border: solid 1px;
font-family:"黑體";
text-align:center;
font-color:#333;
width:850px;
height:640px;
float:left;
}
#line{
background-color:#5c5c5c;
border: solid 1px;
width:419px;
height:210px;
float:left;
}
</style>
<body>
<div>
<div id="title"><span style="color:white;font-size:50px">全球疫情信息可視化</span></div>
<div id="time"><span id="localtime" style="color:white;font-size:27px">當地時間</span></div>
</div>
<div id="left">
<div id="left1"></div>
<div id="left2"></div>
</div>
<div id="main"></div>
<div id="right">
<div id="right1">死亡人數</div>
<div id="right2">治癒人數</div>
</div>
<div id="line"></div>
</body>
<script type="text/javascript">
window.onload = function(){
setInterval("document.getElementById('localtime').innerHTML=new Date().toLocaleString();", 1000);
var dt;
var mydata1 = new Array(0);
$.ajax({
url : "YqServlet?method=everydayinfo",
async : true ,
type : "POST",
dataType : "json",
success : function(data){
dt = data;
var myChart = echarts.init(document.getElementById('line'));
var xd = new Array(0)//長度爲33
var yd = new Array(0)//長度爲33
for(var i=0;i<dt.length;i++){
xd.push(dt[i].date);
yd.push(dt[i].confirmed_num);
}
// 指定圖表的配置項和數據
var option = {
title: {
text: '全球疫情增長趨勢'
},
tooltip: {
show: true,
trigger: 'axis'
},
legend: {
data: ['確診人數']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
type: 'category',
boundaryGap: false,
axisLabel:{
//橫座標上的文字斜着顯示 文字顏色 begin
interval:0,
rotate:40,
margin:1,
textStyle:{color:"#ec6869" }
//橫座標上的文字換行顯示 文字顏色end
},
data: xd
},
yAxis: {
type: 'value'
},
series: [
{
name: '確診人數',
type: 'line',
stack: '總量',
data: yd,
barWidth:20,
barGap:'10%'
}
]
};
// 使用剛指定的配置項和數據顯示圖表。
myChart.setOption(option);
},
error : function() {
alert("請求失敗");
},
});
$.ajax({
url : "YqServlet?method=getWorld",
async : true,
type : "POST",
success : function(data) {
dt = data;
var sum=0;
for(var i=0;i<dt.length;i++)
sum+= parseInt(dt[i].confirmed_num);
var htmltext="<h style='color: white;'>全球確診人數爲:"+"<span style='color: red;font-size:50px'>"+sum+"</span></h>";
htmltext+="<table>"
for(var i=0;i<dt.length;i++)
htmltext+="<tr><td>"+"<span style='color: white;'>"+dt[i].province+"</span></td><td><span style='color: red;'>"+dt[i].confirmed_num+"</span></td></tr>";
htmltext+="</table>";
$("#left1").html(htmltext);
var date="";
date=dt[0].date;
var htmltext="<h style='color: white;font-size:20px'>更新時間:"+"<br>"+"<span style='color: red;font-size:30px'>"+date+"</span></h>";
$("#left2").html(htmltext);
var sum=0;
for(var i=0;i<dt.length;i++)
sum+= parseInt(dt[i].dead_num);
var htmltext="<h style='color: white;'>全球死亡人數爲:"+"<span style='color: red;font-size:50px'>"+sum+"</span></h>";
htmltext+="<table>"
for(var i=0;i<dt.length;i++)
htmltext+="<tr><td>"+"<span style='color: white;'>"+dt[i].province+"</span></td><td><span style='color: red;'>"+dt[i].dead_num+"</span></td></tr>";
htmltext+="</table>";
$("#right1").html(htmltext);
var sum=0;
for(var i=0;i<dt.length;i++)
sum+= parseInt(dt[i].cured_num);
var htmltext="<h style='color: white;'>全球治癒人數爲:"+"<span style='color: red;font-size:50px'>"+sum+"</span></h>";
htmltext+="<table>"
for(var i=0;i<dt.length;i++)
htmltext+="<tr><td>"+"<span style='color: white;'>"+dt[i].province+"</span></td><td><span style='color: red;'>"+dt[i].cured_num+"</span></td></tr>";
htmltext+="</table>";
$("#right2").html(htmltext);
for (var i = 0; i < 202; i++) {
var d = {};
d["name"] = dt[i].province;//.substring(0, 2);
d["value"] = dt[i].confirmed_num;
d["yisi_num"] = dt[i].yisi_num;
d["cured_num"] = dt[i].cured_num;
d["dead_num"] = dt[i].dead_num;
mydata1.push(d);
}
//var mdata = JSON.stringify(mydata1);
var optionMap = {
tooltip : {
formatter : function(params) {
return params.name + '<br/>' + '確診人數 : '
+ params['data']['value'] + '<br/>' + '死亡人數 : '
+ params['data']['dead_num'] + '<br/>' + '治癒人數 : '
+ params['data']['cured_num'];
}//數據格式化
},
//左側小導航圖標
visualMap : {
min : 0,
max : 35000,
text : [ '多', '少' ],
realtime : false,
calculable : true,
inRange : {
color : [ 'lightskyblue', 'yellow', 'orangered' ]
}
},
//配置屬性
series : [ {
type : 'map',
mapType : 'world',
label : {
show : false//是否顯示國家名字
},
data : mydata1,
nameMap : {"Canada": "加拿大",
"Turkmenistan": "土庫曼斯坦",
"Saint Helena": "聖赫勒拿",
"Lao PDR": "老撾",
"Lithuania": "立陶宛",
"Cambodia": "柬埔寨",
"Ethiopia": "埃塞俄比亞",
"Faeroe Is.": "法羅羣島",
"Swaziland": "斯威士蘭",
"Palestine": "巴勒斯坦",
"Belize": "伯利茲",
"Argentina": "阿根廷",
"Bolivia": "玻利維亞",
"Cameroon": "喀麥隆",
"Burkina Faso": "布基納法索",
"Aland": "奧蘭羣島",
"Bahrain": "巴林",
"Saudi Arabia": "沙特阿拉伯",
"Fr. Polynesia": "法屬波利尼西亞",
"Cape Verde": "佛得角",
"W. Sahara": "西撒哈拉",
"Slovenia": "斯洛文尼亞",
"Guatemala": "危地馬拉",
"Guinea": "幾內亞",
"Dem. Rep. Congo": "剛果(金)",
"Germany": "德國",
"Spain": "西班牙",
"Liberia": "利比里亞",
"Netherlands": "荷蘭",
"Jamaica": "牙買加",
"Solomon Is.": "所羅門羣島",
"Oman": "阿曼",
"Tanzania": "坦桑尼亞",
"Costa Rica": "哥斯達黎加",
"Isle of Man": "曼島",
"Gabon": "加蓬",
"Niue": "紐埃",
"Bahamas": "巴哈馬",
"New Zealand": "新西蘭",
"Yemen": "也門",
"Jersey": "澤西島",
"Pakistan": "巴基斯坦",
"Albania": "阿爾巴尼亞",
"Samoa": "薩摩亞",
"Czech Rep.": "捷克",
"United Arab Emirates": "阿拉伯聯合酋長國",
"Guam": "關島",
"India": "印度",
"Azerbaijan": "阿塞拜疆",
"N. Mariana Is.": "北马里亞納羣島",
"Lesotho": "萊索托",
"Kenya": "肯尼亞",
"Belarus": "白俄羅斯",
"Tajikistan": "塔吉克斯坦",
"Turkey": "土耳其",
"Afghanistan": "阿富汗",
"Bangladesh": "孟加拉國",
"Mauritania": "毛里塔尼亞",
"Dem. Rep. Korea": "朝鮮",
"Saint Lucia": "聖盧西亞",
"Br. Indian Ocean Ter.": "英屬印度洋領地",
"Mongolia": "蒙古",
"France": "法國",
"Cura?ao": "庫拉索島",
"S. Sudan": "南蘇丹",
"Rwanda": "盧旺達",
"Slovakia": "斯洛伐克",
"Somalia": "索馬里",
"Peru": "祕魯",
"Vanuatu": "瓦努阿圖",
"Norway": "挪威",
"Malawi": "馬拉維",
"Benin": "貝寧",
"St. Vin. and Gren.": "聖文森特和格林納丁斯",
"Korea": "韓國",
"Singapore": "新加坡",
"Montenegro": "黑山共和國",
"Cayman Is.": "開曼羣島",
"Togo": "多哥",
"China": "中國",
"Heard I. and McDonald Is.": "赫德島和麥克唐納羣島",
"Armenia": "亞美尼亞",
"Falkland Is.": "馬爾維納斯羣島(福克蘭)",
"Ukraine": "烏克蘭",
"Ghana": "加納",
"Tonga": "湯加",
"Finland": "芬蘭",
"Libya": "利比亞",
"Dominican Rep.": "多米尼加",
"Indonesia": "印度尼西亞",
"Mauritius": "毛里求斯",
"Eq. Guinea": "赤道幾內亞",
"Sweden": "瑞典",
"Vietnam": "越南",
"Mali": "馬裏",
"Russia": "俄羅斯",
"Bulgaria": "保加利亞",
"United States": "美國",
"Romania": "羅馬尼亞",
"Angola": "安哥拉",
"Chad": "乍得",
"South Africa": "南非",
"Fiji": "斐濟",
"Liechtenstein": "列支敦士登",
"Malaysia": "馬來西亞",
"Austria": "奧地利",
"Mozambique": "莫桑比克",
"Uganda": "烏干達",
"Japan": "日本",
"Niger": "尼日爾",
"Brazil": "巴西",
"Kuwait": "科威特",
"Panama": "巴拿馬",
"Guyana": "圭亞那",
"Madagascar": "馬達加斯加",
"Luxembourg": "盧森堡",
"American Samoa": "美屬薩摩亞",
"Andorra": "安道爾",
"Ireland": "愛爾蘭",
"Italy": "意大利",
"Nigeria": "尼日利亞",
"Turks and Caicos Is.": "特克斯和凱科斯羣島",
"Ecuador": "厄瓜多爾",
"U.S. Virgin Is.": "美屬維爾京羣島",
"Brunei": "文萊",
"Australia": "澳大利亞",
"Iran": "伊朗",
"Algeria": "阿爾及利亞",
"El Salvador": "薩爾瓦多",
"C?te d'Ivoire": "科特迪瓦",
"Chile": "智利",
"Puerto Rico": "波多黎各",
"Belgium": "比利時",
"Thailand": "泰國",
"Haiti": "海地",
"Iraq": "伊拉克",
"S?o Tomé and Principe": "聖多美和普林西比",
"Sierra Leone": "塞拉利昂",
"Georgia": "格魯吉亞",
"Denmark": "丹麥",
"Philippines": "菲律賓",
"S. Geo. and S. Sandw. Is.": "南喬治亞島和南桑威奇羣島",
"Moldova": "摩爾多瓦",
"Morocco": "摩洛哥",
"Namibia": "納米比亞",
"Malta": "馬耳他",
"Guinea-Bissau": "幾內亞比紹",
"Kiribati": "基里巴斯",
"Switzerland": "瑞士",
"Grenada": "格林納達",
"Seychelles": "塞舌爾",
"Portugal": "葡萄牙",
"Estonia": "愛沙尼亞",
"Uruguay": "烏拉圭",
"Antigua and Barb.": "安提瓜和巴布達",
"Lebanon": "黎巴嫩",
"Uzbekistan": "烏茲別克斯坦",
"Tunisia": "突尼斯",
"Djibouti": "吉布提",
"Greenland": "格陵蘭",
"Timor-Leste": "東帝汶",
"Dominica": "多米尼克",
"Colombia": "哥倫比亞",
"Burundi": "布隆迪",
"Bosnia and Herz.": "波斯尼亞和黑塞哥維那",
"Cyprus": "塞浦路斯",
"Barbados": "巴巴多斯",
"Qatar": "卡塔爾",
"Palau": "帕勞",
"Bhutan": "不丹",
"Sudan": "蘇丹",
"Nepal": "尼泊爾",
"Micronesia": "密克羅尼西亞",
"Bermuda": "百慕大",
"Suriname": "蘇里南",
"Venezuela": "委內瑞拉",
"Israel": "以色列",
"St. Pierre and Miquelon": "聖皮埃爾和密克隆羣島",
"Central African Rep.": "中非",
"Iceland": "冰島",
"Zambia": "贊比亞",
"Senegal": "塞內加爾",
"Papua New Guinea": "巴布亞新幾內亞",
"Trinidad and Tobago": "特立尼達和多巴哥",
"Zimbabwe": "津巴布韋",
"Jordan": "約旦",
"Gambia": "岡比亞",
"Kazakhstan": "哈薩克斯坦",
"Poland": "波蘭",
"Eritrea": "厄立特里亞",
"Kyrgyzstan": "吉爾吉斯斯坦",
"Montserrat": "蒙特塞拉特",
"New Caledonia": "新喀里多尼亞",
"Macedonia": "馬其頓",
"Paraguay": "巴拉圭",
"Latvia": "拉脫維亞",
"Hungary": "匈牙利",
"Syria": "敘利亞",
"Honduras": "洪都拉斯",
"Myanmar": "緬甸",
"Mexico": "墨西哥",
"Egypt": "埃及",
"Nicaragua": "尼加拉瓜",
"Cuba": "古巴",
"Serbia": "塞爾維亞",
"Comoros": "科摩羅",
"United Kingdom": "英國",
"Fr. S. Antarctic Lands": "南極洲",
"Congo": "剛果(布)",
"Greece": "希臘",
"Sri Lanka": "斯里蘭卡",
"Croatia": "克羅地亞",
"Botswana": "博茨瓦納",
"Siachen Glacier": "錫亞琴冰川地區"
},
} ]
};
//初始化echarts實例
var myChart = echarts.init(document.getElementById('main'));
//使用制定的配置項和數據顯示圖表
myChart.setOption(optionMap);
},
error : function() {
alert("請求失敗");
},
dataType : "json"
});
}
</script>
</html>
YqServlet?method=getWorld:(獲取當天數據,傳給頁面經解析後顯示在地圖上)
private void getWorld(HttpServletRequest request, HttpServletResponse response) throws IOException {
// TODO Auto-generated method stub
response.setCharacterEncoding("UTF-8");
Date currentTime=new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String time = formatter.format(currentTime);//獲取當前時間
List<Info> list=get.listAllWorld(time);
Gson gson=new Gson();
String json=gson.toJson(list);
System.out.println(json);
response.getWriter().write(json);
}
YqServlet?method=everydayinfo:(獲取每天確診總人數,實現右下角的增長趨勢功能)
private void everydayinfo(HttpServletRequest request, HttpServletResponse response) throws IOException {
// TODO Auto-generated method stub
response.setCharacterEncoding("UTF-8");
List<Info> list=get.listEverydayInfo();
Gson gson=new Gson();
String json=gson.toJson(list);
System.out.println(json);
response.getWriter().write(json);
}
Get.java:
package com.helloechart;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
public class Get {public List<Info> listAllWorld(String time) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
ArrayList<Info> list = new ArrayList<>();
Connection conn=DBUtil.getConn();
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql="select * from worldinfo where date(Time) = ?";
System.out.println(sql);
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, time);
System.out.println(pstmt);
rs = pstmt.executeQuery();
while (rs.next()) {
Info yq = new Info();
yq.setId(rs.getInt(1));
yq.setDate(rs.getString(8));
yq.setProvince(rs.getString(2));
yq.setConfirmed_num(rs.getString(4));
yq.setYisi_num(rs.getString(5));
yq.setCured_num(rs.getString(6));
yq.setDead_num(rs.getString(7));
list.add(yq);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return list;
}
public List<Info> listEverydayInfo() {
// TODO Auto-generated method stub
ArrayList<Info> list = new ArrayList<>();
Connection conn=DBUtil.getConn();
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql="select * from worldinfo";
System.out.println(sql);
try {
pstmt = conn.prepareStatement(sql);
System.out.println(pstmt);
rs = pstmt.executeQuery();
int t=0;
int sum=0;
String date="";
while (rs.next()) {
t++;
Info yq = new Info();
yq.setDate(rs.getString(8));
if(t==1) {
date= yq.getDate();
}
if(date.equals(yq.getDate())) {
sum+=Integer.parseInt(rs.getString(4));
}
else {
Info info = new Info();
info.setDate(date.substring(0,10));
info.setConfirmed_num(String.valueOf(sum));
list.add(info);
System.out.println(list);
date= yq.getDate();
sum=Integer.parseInt(rs.getString(4));
}
}
Info info = new Info();
info.setDate(date.substring(0,10));
info.setConfirmed_num(String.valueOf(sum));
list.add(info);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return list;
}
}
Info.java:
package com.helloechart;
public class Info {
private int id;
private String city;
private String yisi_num;
private String date;
private String province;
private String confirmed_num;
private String cured_num;
private String dead_num;
private String code;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getYisi_num() {
return yisi_num;
}
public void setYisi_num(String yisi_num) {
this.yisi_num = yisi_num;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getConfirmed_num() {
return confirmed_num;
}
public void setConfirmed_num(String confirmed_num) {
this.confirmed_num = confirmed_num;
}
public String getCured_num() {
return cured_num;
}
public void setCured_num(String cured_num) {
this.cured_num = cured_num;
}
public String getDead_num() {
return dead_num;
}
public void setDead_num(String dead_num) {
this.dead_num = dead_num;
}
}
4、數據庫結構
5、效果展示
全球疫情信息可視化:http://101.200.132.210/World/
6、資源分享
world.js:鏈接:https://pan.baidu.com/s/1eJIDg67lDDuQnal4KMQWAw 提取碼:k12k