结对第二次作业—某次疫情统计可视化的实现
这个作业属于哪个课程 | <软件工程2020春|W班 (福州大学)> |
---|---|
这个作业要求在哪里 | <作业要求的链接> |
结对学号 | 041701602、221701140 |
这个作业的目标 | 实现原型设计中的部分功能 |
作业正文 | 就是这里 |
其他参考文献 | <构建之法现代软件工程第3版> |
1.源代码和代码规范
Github仓库
代码规范
2.成品展示
主界面,可以通过地图的颜色分布来确认全国疫情情况,鼠标放到省份上可以查看具体数据
3.结对过程描述
事前准备的时候研究了一会github多人协作
开始讨论代码怎么写,但是一个很不巧的地方,这次我们组队的两个人都不是很懂什么是爬虫,也都属于不擅长后端的类型,于是我们在决定是否使用爬虫之前先去询问了一些学长
既然很简单,那就用吧
然后对于爬虫的使用就研究了一段时间,基础的使用确实很简单
但是很快遇到了新的问题,丁香园的数据是用echarts展示的,这个我们爬不了
于是又去询问学长这个东西有没有办法做
学长提出了一个办法是这样的
说实话太麻烦了,让人有点怀疑我们剩下的几天内做得出来么
但是后来试了试,这个方法是没法取出echarts里的数据的,说实话松了一口气还好这条路走不通(
于是我们的思路就像陷入泥潭一样,在各种到底有没有办法完成这个作业的不安情绪中,两天很快过去了并且毫无进展,这两天我们的主要工作是搜寻有没有好爬取的网站
直到离交作业只剩下两天了才找到天行的API
这些问题都解决了之后,后面的部分基本就很顺利了
4.设计实现过程
1.前端:前端其实上一次作业已经完成了echarts部分的静态页面,所以这次实现起来很简单,这次的工作主要是把剩下的页面写好
2.后端:基于JAVAEE开发,从网上找到接口后爬取需要的信息
3.前后端交互:通过接口交互
5.功能结构图
6.代码说明
前端CSS样式
td { text-align:center; }
table { width:366px; }
#container2{
border-radius:5px;
-webkit-box-shadow: 3px 3px 6px rgba(55,55,55,0.2);
-moz-box-shadow: 3px 3px 6px rgba(55,55,55,0.2);
box-shadow: 3px 3px 6px rgba(55,55,55,0.2);
}
.td1{
font-size:18px;
font-weight:700;
}
.td2 {
font-size:16px;
font-weight:600;
}
.td3 {
font-size:8px;
font-weight:500;
}
echarts地图
var option = {
tooltip: {
formatter: function (params) {
var info = '' + params.name
+ '
确诊:' + params.value + '
'
return info;
},
fontSize:"12px",
backgroundColor: "rgba(55,55,55,0.8)",//提示标签背景颜色
textStyle: { color: "#fff" }, //提示标签字体颜色
/* triggerOn: 'click', */
enterable:true
},
series: [
{
name: '中国',
type: 'map',
mapType: 'china',
label: {
normal: {
show: true,//显示省份标签
textStyle:{ fontSize:8 }
},
emphasis: {
enterable:true,
// textStyle:{color:"#800080"}
}
},
itemStyle: {
normal: {
borderWidth: .15,//区域边框宽度
// borderColor: '#009fe8',//区域边框颜色
// areaColor:"#ffefd5",//区域颜色
color:function(params){
if(params.value == 0){
return "#FFFFFF";
}else if(params.value >0 && params.value <10){
return "#FAEBD2";
}else if(params.value >=10 && params.value<100 ){
return "#E9A188";
}else if(params.value >=100 && params.value<500 ){
return "#D56355";
}else if(params.value >=500 && params.value<1000 ){
return "#BB3937";
}else if(params.value >=1000 && params.value<10000 ){
return "#772627";
}else{
return "#480f10";
}
}
},
emphasis: {
borderWidth: .5,
borderColor: "#FF0000",
areaColor: "#ffdead",
}
},
data: dataMap
}
]
};
var myChart = echarts.init(document.getElementById('container'));
myChart.setOption(option);
myChart.on('click', function (params) {
window.location.href = 'area.jsp?province='+params.name;
});
···
后端代码,通过正则表达式筛选需要的数据
public Province findProvince(String date,String prov) {
String jsonResult = request(httpUrl,key + "&" + date);
Province province =new Province();
Pattern p = Pattern.compile("\"provinceShortName\":\"" + prov + ".*?\"locationId\":.*?,\"");
Pattern psn = Pattern.compile("(\"provinceShortName\":\")([\\u4E00-\\u9FA5]*)");
Pattern ccf = Pattern.compile("(currentConfirmedCount\":)([0-9]+)");
Pattern cf = Pattern.compile("(confirmedCount\":)([0-9]+)");
Pattern sc = Pattern.compile("(suspectedCount\":)([0-9]+)");
Pattern cc = Pattern.compile("(curedCount\":)([0-9]+)");
Pattern dc = Pattern.compile("(deadCount\":)([0-9]+)");
Matcher m = p.matcher(jsonResult);
while(m.find()){
Matcher m2 = psn.matcher(m.group());
while(m2.find()) {
province.setName(m2.group(2));
}
m2 = ccf.matcher(m.group());
while(m2.find()) {
province.setCurrentConfirmed(Integer.parseInt(m2.group(2)));
}
m2 = cf.matcher(m.group());
while(m2.find()) {
province.setConfirmed(Integer.parseInt(m2.group(2)));
}
m2 = sc.matcher(m.group());
while(m2.find()) {
province.setSuspected(Integer.parseInt(m2.group(2)));
}
m2 = cc.matcher(m.group());
while(m2.find()) {
province.setCured(Integer.parseInt(m2.group(2)));
}
m2 = dc.matcher(m.group());
while(m2.find()) {
province.setDead(Integer.parseInt(m2.group(2)));
}
}
return province;
}
public String request(String httpUrl, String httpArg) {
BufferedReader reader = null;
String result = null;
StringBuffer sbf = new StringBuffer();
httpUrl = httpUrl + "?" + httpArg;
try {
URL url = new URL(httpUrl);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setRequestMethod("GET");
InputStream is = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String strRead = null;
while ((strRead = reader.readLine()) != null) {
sbf.append(strRead);
sbf.append("\r\n");
}
reader.close();
result = sbf.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
爬取的数据的储存
public class Province {
private String name;
private int currentConfirmed;//现存确诊
private int confirmed;//累计确诊
private int suspected;//疑似患者
private int cured;//累计治愈
private int dead;//累计死亡
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getCurrentConfirmed() {
return currentConfirmed;
}
public void setCurrentConfirmed(int currentConfirmed) {
this.currentConfirmed = currentConfirmed;
}
public int getConfirmed() {
return confirmed;
}
public void setConfirmed(int confirmed) {
this.confirmed = confirmed;
}
public int getSuspected() {
return suspected;
}
public void setSuspected(int suspected) {
this.confirmed = suspected;
}
public int getCured() {
return cured;
}
public void setCured(int cured) {
this.confirmed = cured;
}
public int getDead() {
return dead;
}
public void setDead(int dead) {
this.confirmed = dead;
}
}
7.心路历程和收获
041701602
这次的后端代码其实不是很难,但是爬到这份数据的过程实在是太艰辛了,一开始走了歪路浪费了好多时间,这次作业没有展示PSP表格,如果展示出来就能看到学习新技术的时间真是难以想象的长...
下次一定先做好事先调查少走点歪路
GITHUB好多ERROR,从项目开始到结束几乎没有成功PUSH过,网上能找到的方法都试了一遍,但是不知道遇到了什么问题,最后都是手动代码发给队友再PUSH到仓库上的,10次COMMIT是肯定达不到了。希望下次作业能搞懂git的原理吧
221701140
这次作业我主要做的前端,深深的感受到了不会用ps会给自己增添多少麻烦(而且做出来的东西也有点瑕疵),原型替我在页面布局上省了很多力气,图片的位置和大小直接套用原型的数据就好。
在后端的事情上面没帮上多少忙,挺惭愧的,希望下次自己能多做点事。
8.队友互评
041701602:
队友很好,很多次出问题的时候都能想到一些解决方法,省了很多事。
221701140:
队友很好,教了我很多东西,让我提升很大。