结对第二次作业——某次疫情统计可视化的实现
1 Github仓库地址和代码规范链接
2 成品展示
3 结对过程
- 3.1 讨论过程
- 刚开始看到作业时两个人感觉很难无从下手(主要两个人代码能力都不强,也没啥开发经验啥的)
- 后来通过网上教学视频渐渐确定怎么解决问题,学习到了Echarts是个很好的东西,对我们来说开发似乎变得简单一些了。
- 我们最后只做了纯前端的部分和部分后端东东,两个人通过qq共同交流代码一步步编程开发
- 3.2 讨论截图
4 设计实现过程及功能结构图
- 设计实现
- 1、确定项目基本结构
使用nodejs运行js脚本,用npm下载需要的包,前端页面使用echarts。
- 2、获取数据
对丁香园的疫情地图查看源代码了解到,其全国疫情数据是存放在网页html代码之中的,因此设计了一个js脚本,将存放数据的部分爬取下来并且存放在data.json文件中。
前端页面通过调用fetch()对data.json访问请求个疫情地图的数据。而省份疫情趋势的数据则不存在于data.json文件中,但其中有各个省份的数据文件链接,其文件格式也是.json文件。因此同样地,我们使用fetch()对数据文件进行跨域访问,获取需要的数据。
- 3、前端
制作一个html网页,使用echarts和表格实现疫情地图和疫情趋势等,其中主要为javaScript代码。
- 4、后台方面
本次没有设计后端,后台需要手动运行js脚本来进行数据更新。
- 功能结构图
5 关键代码
5.1数据爬取
let requests = require('requests')
let fs = require('fs')
let path = require('path')
const cheerio = require('cheerio')
requests('https://ncov.dxy.cn/ncovh5/view/pneumonia?from=timeline&isappinstalled=0')
.on('data', function (chunk) {
let window = {}
const $ = cheerio.load(chunk)
eval($("#getAreaStat").html())
fs.writeFile(path.resolve(__dirname,'data1.json'),
JSON.stringify(window.getAreaStat),
()=>{
console.log("保存成功")
})
})
5.2 可视化地图
let container = document.getElementById('main')
var myChart = echarts.init(container);
fetch('./data.json').then(res=>res.json()).then(res=>{
let data = res.map(r=>{
return{
name:r.provinceShortName,
value:[r.currentConfirmedCount,r.confirmedCount,r.curedCount,r.deadCount,r.statisticsData]
}
})
//fetch('./data.json').then(res=>res.json()).then(data=>{console.log(data)})
// 指定图表的配置项和数据
var option = {
title:{
text:"疫情地图",
textStyle:{
fontSize:30
},
left:"center",
padding:15,
},
visualMap:{
dimension:0,
pieces:[
{gte:10000,color:"#8B0000",label:'>9999'},
{gte:1000,lt:10000,color:"#FF0000",label:'1000-9999'},
{gte:100,lt:1000,color:"#FF4500",label:'100-999'},
{gte:10,lt:100,color:"#FF7F50",label:'10-99'},
{gt:0,lt:10,color:"#F4A460",label:'1-9'},
{value:0,color:"#fff",label:'0'},
]
},
tooltip:{
triggerOn: 'click',
enterable:true,
formatter:function({data}){
//console.log(data)
return `${data.name}<br>
现有确诊:${data.value[0]}<br>
累计确诊:${data.value[1]}<br>
累计治愈:${data.value[2]}<br>
累计死亡:${data.value[3]}<br>
`
}
},
series:[
{
name:"疫情地图",
type:'map',
map:"china",
data
},
]
};
5.3 可视化折线图及表格
let container1 = document.getElementById('detail')
var myChart = echarts.init(container1);
fetch(params.data.value[4]).then(res => res.json()).then(res1 => {
console.log(res1)
var table =document.getElementById("table");
table.innerHTML=`<table border="2px solid red"><tr><td colspan="4">${params.data.name}</td></tr><tr><th>现有确诊</th><th>累计确诊</th><th>累计治愈</th><th>累计死亡</th></tr>
<tr><td>${res1.data[res1.data.length-1].currentConfirmedCount}</td><td>${res1.data[res1.data.length-1].confirmedCount}</td>
<td>${res1.data[res1.data.length-1].curedCount}t</td><td>${res1.data[res1.data.length-1].deadCount}</td></tr></table>`
var option = {
title: {
text: `${params.data.name}近2周疫情趋势图`,
subtext:"单位:例",
textStyle: {
fontSize: 30
},
left: "center",
padding: 5,
},
xAxis: {
data: [res1.data[res1.data.length-14].dateId,
res1.data[res1.data.length-13].dateId,
res1.data[res1.data.length-12].dateId,
res1.data[res1.data.length-11].dateId,
res1.data[res1.data.length-10].dateId,
res1.data[res1.data.length-9].dateId,
res1.data[res1.data.length-8].dateId,
res1.data[res1.data.length-7].dateId,
res1.data[res1.data.length-6].dateId,
res1.data[res1.data.length-5].dateId,
res1.data[res1.data.length-4].dateId,
res1.data[res1.data.length-3].dateId,
res1.data[res1.data.length-2].dateId,
res1.data[res1.data.length-1].dateId,
]
},
yAxis: {
splitNumber: 5
},
legend: {
bottom: 0,
//data:['确诊','疑似','治愈','死亡'],
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
},
},
series: [
{
name: "累计确诊",
type: 'line',
data: [res1.data[res1.data.length-14].confirmedCount,
res1.data[res1.data.length-13].confirmedCount,
res1.data[res1.data.length-12].confirmedCount,
res1.data[res1.data.length-11].confirmedCount,
res1.data[res1.data.length-10].confirmedCount,
res1.data[res1.data.length-9].confirmedCount,
res1.data[res1.data.length-8].confirmedCount,
res1.data[res1.data.length-7].confirmedCount,
res1.data[res1.data.length-6].confirmedCount,
res1.data[res1.data.length-5].confirmedCount,
res1.data[res1.data.length-4].confirmedCount,
res1.data[res1.data.length-3].confirmedCount,
res1.data[res1.data.length-2].confirmedCount,
res1.data[res1.data.length-1].confirmedCount,]
},
{
name: "新增确诊",
type: 'line',
data: [res1.data[res1.data.length-14].confirmedIncr,
res1.data[res1.data.length-13].confirmedIncr,
res1.data[res1.data.length-12].confirmedIncr,
res1.data[res1.data.length-11].confirmedIncr,
res1.data[res1.data.length-10].confirmedIncr,
res1.data[res1.data.length-9].confirmedIncr,
res1.data[res1.data.length-8].confirmedIncr,
res1.data[res1.data.length-7].confirmedIncr,
res1.data[res1.data.length-6].confirmedIncr,
res1.data[res1.data.length-5].confirmedIncr,
res1.data[res1.data.length-4].confirmedIncr,
res1.data[res1.data.length-3].confirmedIncr,
res1.data[res1.data.length-2].confirmedIncr,
res1.data[res1.data.length-1].confirmedIncr,]
},
{
name: "累计治愈",
type: 'line',
data: [res1.data[res1.data.length-14].curedCount,
res1.data[res1.data.length-13].curedCount,
res1.data[res1.data.length-12].curedCount,
res1.data[res1.data.length-11].curedCount,
res1.data[res1.data.length-10].curedCount,
res1.data[res1.data.length-9].curedCount,
res1.data[res1.data.length-8].curedCount,
res1.data[res1.data.length-7].curedCount,
res1.data[res1.data.length-6].curedCount,
res1.data[res1.data.length-5].curedCount,
res1.data[res1.data.length-4].curedCount,
res1.data[res1.data.length-3].curedCount,
res1.data[res1.data.length-2].curedCount,
res1.data[res1.data.length-1].curedCount,]
},
{
name: "累计死亡",
type: 'line',
data: [res1.data[res1.data.length-14].deadCount,
res1.data[res1.data.length-13].deadCount,
res1.data[res1.data.length-12].deadCount,
res1.data[res1.data.length-11].deadCount,
res1.data[res1.data.length-10].deadCount,
res1.data[res1.data.length-9].deadCount,
res1.data[res1.data.length-8].deadCount,
res1.data[res1.data.length-7].deadCount,
res1.data[res1.data.length-6].deadCount,
res1.data[res1.data.length-5].deadCount,
res1.data[res1.data.length-4].deadCount,
res1.data[res1.data.length-3].deadCount,
res1.data[res1.data.length-2].deadCount,
res1.data[res1.data.length-1].deadCount,]
}
]
};
myChart.setOption(option);
6 心路历程与收获及评价结对队友
- 《构建之法》阅读心得
- 构建之法第四章提到了两人合作开发的要求,此次作业中我们两个人并没有做到。虽然这次的作业是两人结对作业,但因为对于GitHub功能的不了解,在使用上屡遇困难,以及许多技术上的不了解,所以我们并没有真正意义上的严格分工,在代码方面上是一起混合完成的,没有具体的分工。当然对于构建之法第五章描述的合作开发和GitHub的分支功能,我们还是很感兴趣,在接下来的团队作业中,一定会着重加强这一方面的学习。
- 心路历程与收获
- 221701428
初次看到作业描述还比较懵逼当中,思索好久不知道咋下手,后来在队友强大的查阅能力我们确定了以Echarts为开发主方向,最后在和队友一起混合开发代码,而并没有明确的分工,因此效率上可能比较低下,希望以后可以慢慢完善结对以及团队开发技能。经过这次结对作业也学会了如何爬取数据以及数据可视化。
- 221701425
本次作业中,我原以为实现疫情地图会很复杂,但在具体查阅了关于echarts的资料后,发现其实也还好。本次作业中遇到的最大困难,无外乎数据的获取,
在查询了许多资料和方法后,采用爬虫获取了一些数据,还用到了fetch()跨域请求数据,这一过程对我来说是全新的体验。在获取数据后也出现了新的烦恼,关于转换数据格式的问题,后面跌跌撞撞也基本解决了。
虽然这次作业中学到了很多放方法,但本次结对作业的最大收获其实还是合作开发能力获得了提升,再也不是一个人闷头写代码,一个人查资料,在合作交流方面上的能力有了显著提升!
- 评价结对队友
- 221701428
他乐于和队友及时进行快速交流,互相不懂的时候一起帮忙解决。他学习能力强,这次作业主要在他帮助下才能共同完成结对作业,非常感谢队友哈哈。
- 221701425
我的队友擅于和人交流,在我困惑的时候给了我很多建议。另外他想法新奇,能够提出独特的观点。最后,很荣幸能够与他合作,希望以后还有机会一起合作。