结对作业2
| 这个作业属于哪个课程 | 2020年春W班(福州大学) |
|---|---|
| 这个作业要求在哪里 | 结对第二次作业——某次疫情统计可视化的实现 |
| 这个作业的目标 | 实现以地图形式展现疫情大致分布情况以及具体省份疫情统计情况 |
| 结对学号 | 221701217 221701229 |
| 作业正文 | 见下方 |
| 其他文献参考 | echart akshare ... |
0.Git仓库链接 代码规范链接
1.成品展示
1.1疫情统计网站入口
1.2疫情统计网站效果展示
gif展示
图片展示
主页中国疫情表格

主页地图效果图

趋势折线图效果图

新闻板效果预览

谣言板效果图

全国各省数据总览

2.结对讨论过程描述和设计实现过程
2.1结对讨论过程
我们组在拿到作业后首先讨论的是是否使用用框架以前后端分离的做法来做这个网站,实际上由于这个网站的功能并不多,代码也不会很多,所以使用html+css+js的方式已经足够方便了。随后是网站前端如何实现及如何向网站注入数据,对于地图及其效果的图像还有折线图仍然使用echarts进行制作,而对于网站数据的处理则采用js对网页进行动态改变;而后是数据的获取,对于数据获取,在作业说明里有说用爬虫,因而我们就采用这种做法;其后则是代码规范的问题,由于作业要求主流代码规范,所以我们从网上找到阿里巴巴的代码规范,而后截取其中的部分代码规范。



2.2设计实现过程
经过讨论,可以得出整个项目的大致结构就是HTML(数据结构排列)+CSS(网页样式)+JS(设计交互效果,处理数据)+PYTHON(爬虫获取数据)
Part1.HTML部分
根据原型展示的网站结构对模拟的数据进行组织排列,方便后续使用CSS和JS对内容修饰和修改。
Part2.CSS部分
根据原型的网站对part1的html进行样式的修改,使其展现样式与原型网站相似
Part3.JS部分
此部分需要分几个更小的部分
3.1 使用echarts与jquery对原型网站的疫情图表,中国地图进行样式上的实现
3.2用js实现从网络获取各省辖区市名称获取,而后对省份的样式实现
3.3调用python爬虫并处理传回的数据
3.4使用js更新网页图表的数据以及谣言板和最新新闻的模块
Part4.PYTHON
制作一个python爬虫实现从网络获取疫情的数据以及新闻和谣言的标题及链接
2.3功能结构图

3.代码说明
此方法用于获取各省辖区市名称来给echarts动态绘制各省地图
function getProvince(province)
{
var url='updated.json';
var requst=new XMLHttpRequest();
requst.open('get',url);
requst.send(null);
requst.onload=function()
{
if (requst.status == 200) {
var json = JSON.parse(requst.responseText);
var provs=json.areaTree[0].children;
for (var p in provs)
{
if(provs[p].name==province)
{
return p.children;
//document.getElementById('demo').innerHTML=province;
}
}
}
}
return null;
}
此方法用于控制图表的切换
function switchChart(id,data)
{
//console.log("id="+id);
//console.log(data[0].confirm);
var len=0;
for(var k in data)len++;
var i=len>=14?(len-14):len-1;
var data1=[];//confirm or heal
var data2=[];//suspect or dead
var chartname;//将要渲染的图表名
if(id=="confirm_sus")
{
chartname="确诊/疑似趋势";
for(;i<len;i++)
{
data1.push(data[i].confirm);
data2.push(data[i].suspect);
}
}
else if(id=="heal_dead")
{
chartname="累计治愈/死亡";
for(;i<len;i++)
{
data1.push(data[i].heal);
data2.push(data[i].dead);
}
}
drawLine(data1,data2,chartname);
}
这段js代码用于获取数据,获取填入图表的数据
var url='../updated.json';
var requst=new XMLHttpRequest();
requst.open('get',url);
requst.send(null);
var dataset ////
requst.onreadystatechange=function()
{
if (requst.status == 200 && requst.readyState == 4 ) {
var json = JSON.parse(requst.responseText);
dataset=json.areaTree[0].children;
var datafortotal=[];
datafortotal.push(json.chinaTotal.nowConfirm);
datafortotal.push(json.chinaAdd.confirm);
datafortotal.push(json.chinaTotal.confirm);
datafortotal.push(json.chinaTotal.heal);
datafortotal.push(json.chinaTotal.dead);
drawTotal(datafortotal);
var dataMap=[];
for (var i in dataset)
{
dataMap.push({"name":dataset[i].name,"value":dataset[i].total.confirm,"suspect":dataset[i].total.suspect,"dead":dataset[i].total.dead,"heal":dataset[i].total.heal});
}
drawChina(dataMap);
drawTable(dataMap);
}
}
var url2='../history.json';
var requst2=new XMLHttpRequest();
requst2.open('get',url2);
requst2.send(null);
var historyjson ; ////
requst2.onreadystatechange=function()
{
if (requst2.status == 200 && requst2.readyState == 4 ) {
historyjson = JSON.parse(requst2.responseText);
//console.log(historyjson);
switchChart("confirm_sus",historyjson);
}
}
此方法用于调用爬虫更新新闻板数据,谣言板与此类似
function initNews()
{
var url='../news.json';
var requst=new XMLHttpRequest();
requst.open('get',url);
requst.send(null);
var newsjson ; ////
requst.onreadystatechange=function()
{
if (requst.status == 200 && requst.readyState == 4 ) {
newsjson = JSON.parse(requst.responseText);
//获取谣言版的所有标签
var news=document.getElementsByName('newsTag');
var len=news.length;
for(var i=0;i<len;i++)
{
console.log(newsjson[i].title);
news[i].href=newsjson[i].sourceUrl;
news[i].innerHTML=newsjson[i].title;
}
}
}
}
此段代码用于动态显示从地图点击省份后显示省份的统计表格
//获取表格的容器
function drawTable(dataMap)
{
div=document.createElement("div");
table = document.createElement("table");
tBody = document.createElement("tBody");
tr = document.createElement("tr");
nameth=document.createElement("th");
nameth.innerHTML="省份";
totalth=document.createElement("th");
totalth.innerHTML="感染总人数";
suspectth=document.createElement("th");
suspectth.innerHTML="疑似人数";
deadth=document.createElement("th");
deadth.innerHTML="死亡人数";
health=document.createElement("th");
health.innerHTML="治愈人数";
tr.appendChild(nameth);
tr.appendChild(totalth);
tr.appendChild(suspectth);
tr.appendChild(deadth);
tr.appendChild(health);
tBody.appendChild(tr);
for(var i in dataMap)
{
ntr=document.createElement("tr");
td1 = document.createElement("td");
td1.innerHTML=dataMap[i].name;
td2 = document.createElement("td");
td2.innerHTML=dataMap[i].value;
td3 = document.createElement("td");
td3.innerHTML=dataMap[i].suspect;
td4 = document.createElement("td");
td4.innerHTML=dataMap[i].dead;
td5 = document.createElement("td");
td5.innerHTML=dataMap[i].heal;
ntr.appendChild(td1);
ntr.appendChild(td2);
ntr.appendChild(td3);
ntr.appendChild(td4);
ntr.appendChild(td5);
tBody.appendChild(ntr);
}
table.appendChild(tBody);
table.className="table table-striped";
div.appendChild(table);
div.style.width="1200px";
div.style.margin="auto";
document.body.appendChild(div);
}
//这段代码动态展示省份的地图
function drawProvince(provName,data)
{
var cityMap=[];
for(var i in data)
{
if(data[i].name==provName)
{
//遍历省份的市列表
var citylist=data[i].children;
for(var j in citylist)
{
cityMap.push({'name':citylist[j].name,'value':citylist[j].total.confirm});
}
break;
}
}
var option = {
title: {
text: provName+'疫情地图',
subtext: '',
textStyle: {
fontSize: '34',
},
x:'center'
},
tooltip: {
formatter: function (params) {
var info = '<p style="font-size:18px;font-weight:bold">' + params.name + '</p><p style="font-size:14px">感染人数'+params.value+'人</p>'
return info;
},
backgroundColor: 'rgba(61,61,61, 0.3)',//提示标签背景颜色
textStyle: { color: "#0A0A0A" } //提示标签字体颜色
},
dataRange: {
x: 'left',
splitList: [
{start:5000},
{start:1000,end:4999},
{start:500,end:999},
{start:100,end:499},
{start:1,end:99},
{start:0,end:0}
],
color: ['#FF0000','#FFF68F','#FFFFFF']
},
series: [
{
name: provName,
type: 'map',
mapType: 'province',
//鼠标点击选中
//selectedMode: 'multiple',
label: {
normal: {
show: true,//显示省份标签
textStyle:{color:"#0A0A0A"}//省份标签字体颜色
},
emphasis: {
show: true,//对应的鼠标悬浮效果
//textStyle:{color:"#800080"}
}
},
itemStyle: {
normal: {
borderWidth: .5,//区域边框宽度
borderColor: '#009fe8',//区域边框颜色
areaColor:"#ffefd5",//区域颜色
},
emphasis: {
borderWidth: .5,
borderColor: '#4b0082',
areaColor: "#9AFF9A",
}
},
data: cityMap
}
]
};
//初始化echarts实例
var myChart = echarts.init(document.getElementById('chinamap'));
myChart.clear();
//使用制定的配置项和数据显示图表
myChart.setOption(option);
}
以下为获取数据的python爬虫代码
import requests
import json
import akshare as ak
#获取今日的累计数据(json格式)
def DownloadData():
url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5' # 腾讯的数据
#假装是浏览器
headers = {
'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36'
}
res=requests.get(url,headers)
res_json=json.loads(res.text)
res_data=json.loads(res_json['data']) # 数据json
file=open('updated.json','w')
file.seek(0)
file.truncate()
file.write(json.dumps(res_data)) #json数据转string存文件
DownloadData()
#获取近一段时间的全国整体数据(DataFrame格式)
epidemic_163_df = ak.epidemic_163(indicator="历史")
history=open('history.json','w')
history.seek(0)
history.truncate()
history.write(epidemic_163_df.to_json(orient="records",force_ascii=False))
#获取新闻
epidemic_dxy_df = ak.epidemic_dxy(indicator="news")
news=open('news.json','w')
news.seek(0)
news.truncate()
news.write(epidemic_dxy_df.to_json(orient="records",force_ascii=False))
#获取谣言
epidemic_baidu_df = ak.epidemic_baidu(indicator="热搜谣言粉碎")
rumor=open('rumor.json','w')
rumor.seek(0)
rumor.truncate()
rumor.write(epidemic_baidu_df.to_json(orient="records",force_ascii=False))
4.心路历程和收获&评价队友
4.1心路历程与收获
221701217
刚开始接触到这个作业时我有点畏惧,对于陌生的从网上用python爬取数据是否能够顺利,项目能否按时完成感到疑惑;但是我的队友在第二天就在网上找到了我跟我一起探讨了如何设计实现这个项目,使我豁然开朗;在网页的实现过程中我遇到问题解不开就找他问,往往能得到满意的答复;我想我们的合作或许已经初步进入到规范阶段了,我感觉我们两人团队模式更接近于功能团队模式。这次作业我的收获不仅仅是对web开发的进一步学习,还有对团队协作分工能力的提高,同时我的伙伴也教给了我很多,十分感谢他。
221701229
还没开始编码的时候,我以为很快就能做完,规划起来感觉也很简单,但是做起来发现我们在于数据的挖掘获取方面真的是很欠缺,程序没了数据就是个没有灵魂的空壳,好在查了许多网站找到了能达到大部分要求的数据,省份显示功能因为历史数据的欠缺没能做出来。
花费了比较多的时间在数据的处理上(没有直接采用寒假作业的成果处理助教提供的日志)。由于没有花多少时间去优化界面,最后做完的时候看了一下真的是文艺复兴。
4.2评价队友
与他合作是我的荣幸,他十分靠谱,实力强劲,我遇到许多问题都是他帮忙解决的,他的部分我根本不用担心,有实力又有配合,这次作业能够比较圆满的完成可以说是抱了他的大腿。 ——221701217
队友对我评价过高了<_>,我觉得我们水平差不多,有的是因为这次编码分工不太细致,我前后端都插了一脚。 ——221701229
浙公网安备 33010602011771号