结对第二次作业—某次疫情统计可视化的实现

结对第二次作业—某次疫情统计可视化的实现

这个作业属于哪个课程 <软件工程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 = '<p style="font-size:10px">' + params.name 
            + '</p><p style="font-size:10px">确诊:' + params.value + ' </p>' 
            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:

队友很好,教了我很多东西,让我提升很大。

posted @ 2020-03-14 11:09  苍白之蓝  阅读(143)  评论(0编辑  收藏  举报