这个作业属于哪个课程 | 2020春|S班 (福州大学) |
---|---|
这个作业要求在哪里 | 结对第二次作业——某次疫情统计可视化的实现 |
结对学号 | 221701310 | 221701324 |
这个作业的目标 | 实现通过地图、统计图的形式显示疫情分布情况和具体省份的疫情统计情况。 |
作业正文 | 结对第二次作业——某次疫情统计可视化的实现 |
其他参考文献 | 博客园、百度、CSDN等相关文章 |
1.Github仓库地址和代码规范链接
2.成果展示
3.结对讨论过程描述&附截图
对题目的理解:
一开始还是迷茫,开始联系和上次作业的关系,后面发现关系不太大。分析题目从地图界面和数据两方面着手,商量通过对日志文件的分析创建数据库,然后建立提取所需数据的函数,然后地图和统计图页面调用实现。
困难&解决:
1.一开始题目比较没思路,互相慢慢理清思路就明确分工。
2.线上的交流相当低效,用图片来显示自己的意思会比较直观、容易理解。
3.在网上查阅资料用Echarts构建地图、统计图等。
4.探究对方的需求构建函数,解释功能。
5.因为修改js代码后可以直接用浏览器查看效果,所以忽视了ide本身提供error信息的功能,导致出现意料之外的问题(无法调用已经写好的函数),后来才发现是构建路径的问题。
聊天截图(部分忽略)
4.描述设计实现过程
1.前端:疫情分布情况和具体省份的疫情统计情况的可视化(此时数据为虚构),实现外观后使用相关函数调用后端数据填充echarts组件。
2.后端:实现对日志文件数据的提取并创建数据,根据前端需求构造函数。
3.最后,整合测试。
功能结构图
5.代码说明
点击省份跳转、输入日期点击按钮跳转
- 都是使用window.location.href = "...?..."的样式打开新窗口来实现(以地图页面的代码为例)
//单机省份跳转
myChart.on('click', function (params) {
window.location.href="province.jsp"+"?"+"province="+params.name+"&date="+dateParam;
});
//单机日期按钮跳转
function provinceDump(){
var content = document.getElementById("time");
window.location.href = "Index.jsp"+"?"+"date="+content.value;
}
使用最新的日志的日期当作地图和统计图页面的默认日期
- 如果url中包含日期参数则利用参数作为页面的信息(部分展示)
<%
//获取最新日志的日期作为默认日期
myLogs myLogs = new myLogs();
String date = myLogs.getLatestDate();
//地图页面显示全国信息
String pro="quanguo";
//获取日期参数,存在则用作新日期
String inputDate = request.getParameter("date");
if(inputDate!=null){
date = inputDate;
}
%>
根据日期和省份名获取需要的数据(部分展示)
//获取地图页面各省份确诊感染人数
{name:"安徽",value:<%=tt.ipnum(date,"anhui")%>},
{name:"北京",value:<%=tt.ipnum(date,"beijing")%>},
{name:"重庆",value:<%=tt.ipnum(date,"chongqing")%>},
//下略
//获取日期数组(用于产生折线统计图横轴数据,获取感染人数趋势数组等同理)
<%
ArrayList<String> files = myLogs.getLogsName(date);
%>
//将ArrayList的数据赋值给js的Array
var arr = new Array();
<% for(int i = 0;i<files.size();i++){ %>
var j = '<%=files.get(i)%>';
arr.push(j);
<% } %>
读取日志文件数据(部分展示)
//读取路径下的文件
public void get_Flist() {
File[] flist;
String fname;
File file = new File(logaddr);//获取指定目录下文件
flist = file.listFiles();
int i;
for (i = 0; i < flist.length; i++) {
fname = flist[i].getName();//文件名
//System.out.println(fname);//显示文件名
String Date=fname.substring(0,10);
String alladdr = logaddr + fname;//完整文件路径
Read_txt(alladdr);
.....
}
//读取文本内容
public void Read_txt(String address) {
try {
BufferedReader bf;
bf = new BufferedReader(new InputStreamReader(
new FileInputStream(new File(address)), "UTF-8"));
String rLine = null;
while ((rLine = bf.readLine()) != null) {Deal_txt(rLine);.....}
}
}
//处理文本
public void Deal_txt(String line) {
String[] str = {"(\S+) 新增 感染患者 (\d+)人", "(\S+) 新增 疑似患者 (\d+)人",
"(\S+) 感染患者 流入 (\S+) (\d+)人", "(\S+) 疑似患者 流入 (\S+) (\d+)人",
"(\S+) 死亡 (\d+)人", "(\S+) 治愈 (\d+)人",
"(\S+) 疑似患者 确诊感染 (\d+)人", "(\S+) 排除 疑似患者 (\d+)人"
};//日志可能出现的情况
int num[] = new int[8];//各种人数
String[] txt_str = line.split(" ");//用空格隔开
if (line.matches(str[0])) {//新增感染者
txt_str[3] = txt_str[3].replace("人", "");
num[0] = Integer.valueOf(txt_str[3]);//把人数转化为int类型
for (int i = 0; i < province.length; i++) {
if (txt_str[0].equals(province[i])) {
//System.out.println(province[i]);用来检验输出
person[i][0] += num[0];
person[0][0] += num[0];
break;
}
}
.....
往数据库插入数据(部分展示)
myTool.exeSQL("insert ignore into ip_number values('" + Date + "','" +
person[0][0] + "','" + person[1][0] + "','" + person[2][0] + "','" + person[3][0] + "','" + person[4][0] + "','" +
person[5][0] + "','" + person[6][0] + "','" + person[7][0] + "','" + person[8][0] + "','" + person[9][0] + "','" +
person[10][0] + "','" + person[11][0] + "','" + person[12][0] + "','" + person[13][0] + "','" + person[14][0] + "','" +
person[15][0] + "','" + person[16][0] + "','" + person[17][0] + "','" + person[18][0] + "','" + person[19][0] + "','" +
person[20][0] + "','" + person[21][0] + "','" + person[22][0] + "','" + person[23][0] + "','" + person[24][0] + "','" +
person[25][0] + "','" + person[26][0] + "','" + person[27][0] + "','" + person[28][0] + "','" + person[29][0] + "','" +
person[30][0] + "','" + person[31][0] + "','" + person[32][0] + "','" + person[33][0] + "','" + person[34][0] + "')");
创建从数据库调取所需数据的函数(部分展示)
//ip人数
public int ipnum(String date,String prv){
int num=0;
DBTool myTool=new DBTool();
try
{
Statement s = myTool.c.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE
);
String ipn = "select * from ip_number where Date like '"+date+"'";
ResultSet r = s.executeQuery(ipn);
r.beforeFirst();
if(!r.next())
System.out.println("查无此记录!");
else{
num=Integer.parseInt(r.getString(prv));
}
s.close();
}
catch(Exception e1) {
e1.printStackTrace();
}
return num;
}
//到目前为止新增ip人数数组
public ArrayList<Integer> iptd(String date,String prv) {
ArrayList<Integer> arr=new ArrayList<Integer>();
DBTool myTool=new DBTool();
int num1=0;//最开始一天为0/前一天
int num2=0;//当天
int n;//差
try
{
Statement s = myTool.c.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String SearchStr = "SELECT * FROM `ip_number` WHERE 1 = 1";
ResultSet r = s.executeQuery(SearchStr);
while(r.next()){
String d=r.getString("Date");
if(date.compareTo(d)>=0){
Statement ss = myTool.c.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String ipn = "select * from ip_number where Date like '"+d+"'";
ResultSet rr = ss.executeQuery(ipn);
rr.beforeFirst();
rr.next();
num2=Integer.parseInt(rr.getString(prv));
n=num2-num1;
arr.add(n);
num1=num2;//当天变前天
}
}
r.close();
s.close();
}
catch(Exception e1) {
e1.printStackTrace();
}
return (arr);
}
6.心路历程与收获&队友评价
历程和收获
221701324:通过这两章的学习我明白了代码一定要尽量规范要让别人看懂而不是只有自己能看懂。他对于两个人之间代码沟通很重要,代码风格要尽量做到简明、易读、无二义性。在团队开发中,一个人的能力总是有限的,一个好的团队需要学会分工明确,明确团队的开发流程,互相取长补短,实现一加一大于二的效果。
221701310:团队合作中交流和明确分工很重要,在之后的团队开发中或许需要用到专门的交流工具也说不定。在开始编码前需要先规划好数据库(为了方便数据提取应该如何存放数据等)、方法(参数的格式、返回值)、网页(如何让用户选择日期等)各个部分的大致框架,才能提高开发速度和正确率。不过即使如此也可能在编码过程中发现新的问题,如果重新修改过去的代码代价过大的话,只能找别的解决办法。
队友评价
221701324:又是一次很愉快的结对合作,我们可以很认真的探讨题意,在理清题意后就有了很明确的分工,在“各自为战”的过程中也能为对方答疑解惑,整个过程互相协作,让这次作业更快更好的完成。
221701310:虽然线上的交流不如面对面的交流来的高效,对方还是非常明确的表达了自己的思路以及理解了队友(也就是我)的表述,作业效率也比较高,使得整个开发过程能够轻松、愉快不少,许多问题也得以解决。