欢迎来到SeinoNana的博客

雨下整夜,我的爱溢出就像雨水。院子落叶,跟我的思念厚厚一叠。几句是非,也无法将我的热情冷却,你出现在我诗的每一页
扩大
缩小
返回顶部

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

这个作业属于哪个课程 班级的链接
这个作业要求在哪里 作业要求
结对学号 221701125 & 221701126
这个作业的目标 实现通过地图的形式来直观显示
疫情的大致分布情况,还可以查
看具体省份的疫情统计情况;点
击某个省份显示该省疫情的具体
情况;学习与队友进行合作;学
习使用github进行团队合作;学
习如何进行前后端数据交互。
作业正文 正文
其他参考文献 echarts官网 W3Cschool教程

1、仓库地址&代码规范

Github仓库地址

代码规范

2、展示作品

(1)首页如图所示,上半部分显示整体疫情,下半部分以中国地图来显示整体疫情,地图根据疫情显示不同颜色

img

(2)当鼠标移动到中国地图的某个省份,将会出现浮动窗口显示该省份的疫情,并且该省份地图会高亮显示。

2

(3)地图左边可查看根据确诊人数显示的不同颜色深浅,例如将鼠标移到100-999的部分,符合该部分的省份都将高亮显示

3

(4)鼠标点击100-999的图标,将重置所有疫情符合100-999的省份为白色,其他部分的颜色功能相同,点击即重置为白色,再次点击又会重新显示出颜色。

4

(5)中间的输入框可选择日期

5

(6)选择日期后,整个界面将统计该日期的疫情,地图的颜色也会根据疫情人数有所改变

6

(7)点击地图上某个省份,跳转到新页面显示该省份的疫情界面

7

(8)将鼠标移动到折线图上,将会跳出浮动窗显示具体数据(新增确诊趋势、新增疑似趋势、治愈趋势、死亡趋势)

8

(9)9.1折线图上方有四个标题,点击某个标题可隐藏该折线图,再次点击又可显示

9

(10)中间的输入框可选择日期,选择后将显示该省份该日期的具体疫情(现有确诊、累计确诊、累计治愈、累计死亡)

10

(11)折线图右上方有个下载的图标,点击可下载折线图界面

11

3、结对讨论过程描述

刚拿到题目后,和队友进行讨论,总结了以下问题:

(1)该用什么语言来写,需要能支持服务器(javaee还是php)?

(2)后端数据怎么获取?怎么处理?怎么统计?

(3)后端接口要如何返回数据?

(4)前端如何接收后端传来的数据?

(5)前端界面要如何规划?每个界面要如何划分模块?

(6)前端中国地图要如何绘制?前端折线图要如何绘制?

(7)前端如何实现不同省份不同疫情要显示不同颜色?鼠标移动如何显示浮窗?颜色高亮?

(8)前端如何实现日期选择?

经过讨论,并且上网查找资料后,基本解决了所有问题:

用javaee来做这个项目

后端读取日志文件,并写算法统计数据,讲数据封装到哈希表

后端接口返回int []类型的数组

前端用jsp来写,可直接写java代码调用后端接口传数据

前端首页和折线图页面都分为上下两部分,上半部分显示疫情数字,下半部分显示图表

中国地图和折线图都用echarts来绘制

echarts可设置不同数量显示不同颜色,中国地图echarts自带浮窗和显示高亮

前端日期选择用HTML5中的input标签,将属性type设置为date

echarts的用法可在官网找到使用教程

两人结对讨论截图:

21

22

23

4、设计实现过程

设计实现过程:后端处理数据后,前端调用后端接口获取数据,填充到echarts显示,中国地图点击某省份,跳转到折线图时,应该在跳转的URL后添加参数省份的id,调用方法request.getParameter()可获取input输入选择的日期,根据不同日期做相应的计算显示数据。

功能结构图:

5、关键代码

Entry.java 读取日志文件,处理数据,封装到哈希表中

   /*
    * 处理每一个文件
    */
      public static void solveTheFile(String[] fileList) {
      	Province nationwide = map.get("全国");
      	// TODO Auto-generated method stub
      	for(String aFile : fileList) {
      		String fileDate = aFile.substring(0, aFile.indexOf("."));
  		Date nationwideDate = new Date();
  		nationwideDate.setDate(fileDate);
  		
  		try {
      		File file = new File(path + "\\" + aFile);
      		InputStreamReader inputReader = new InputStreamReader(new FileInputStream(file), "GB2312");
      		BufferedReader bf = new BufferedReader(inputReader);
      		String str;
      		
      		while ((str = bf.readLine()) != null && str.indexOf("//") != 0) {
      			if(str.length() == 0)
      				continue;
      			String[] information = str.split("\\s+");
      			String provinceName = information[0];//先取到省份
      			int number = getNumber(information);//取出各行人数
      			
      			if(map.get(provinceName) != null) {
      				Province province = map.get(provinceName);
      				Map<String, Date> dateMap = province.getDateMap();
      				Date date = new Date();
      				
      				if(dateMap.get(fileDate) != null) {
      					date = province.getDateMap().get(fileDate);
      				}
      				else {
      					date = new Date();
      					date.setDate(fileDate);
      				}
      				
      				switch (information[1]) {
  					case "新增":
  						if(information[2].equals("感染患者")) {
  							int ip = date.getIp();
  							ip += number;
  							date.setIp(ip);
  							
  							int nationwideIp = nationwideDate.getIp();
  							nationwideIp += number;
  							nationwideDate.setIp(nationwideIp);
  						}
  						else {//疑似患者的情况
  							int sp = date.getSp();
  							sp += number;
  							date.setSp(sp);
  							
  							int nationwideSp = nationwideDate.getSp();
  							nationwideSp += number;
  							nationwideDate.setSp(nationwideSp);
  						}
  						break;
  					case "治愈":
  						int cure = date.getCure();
  						int ip1 = date.getIp();
  						cure += number;
  						ip1 -= number;
  						date.setCure(cure);
  						date.setIp(ip1);
  						
  						int nationwideCure = nationwideDate.getCure();
  						nationwideCure += number;
  						nationwideDate.setCure(nationwideCure);
  						break;
  					case "死亡":
  						int dead = date.getDead();
  						int ip2 = date.getIp();
  						dead += number;
  						ip2 -= number;
  						date.setDead(dead);
  						date.setIp(ip2);
  						
  						int nationwideDead = nationwideDate.getDead();
  						nationwideDead += number;
  						nationwideDate.setDead(nationwideDead);
  						break;
  					default:
  						break;
  					}
      				dateMap.put(fileDate, date);
      				nationwide.getDateMap().put(fileDate, nationwideDate);
      			}
      		}			
      		bf.close();		
      	//	bw.close();
      		inputReader.close();
      	
  		} 
      	catch (IOException  e) {
      		e.printStackTrace();
  		}
  	}
  }

index.jsp 首页,调用接口获取数据,在script中绘制中国地图

    var dataMap = [{id:1, name: '北京',value:beijing }, {id:2, name: '天津',value:tianjin}, {id:3, name: '上海',value:shanghai }, {id:4, name: '重庆',value:chongqing }, 
        	{id:5, name: '河北',value:hebei }, {id:6, name: '河南',value:henan }, {id:7, name: '云南',value:yunnan }, {id:8, name: '辽宁',value:liaoning }, 
        	{id:9, name: '黑龙江',value:heilongjiang }, {id:10, name: '湖南',value:hunan }, {id:11, name: '安徽',value:anhui }, {id:12, name: '山东',value:shandong }, 
        	{id:13, name: '新疆',value:xinjiang }, {id:14, name: '江苏',value:jiangsu }, {id:15, name: '浙江',value:zhejiang }, {id:16, name: '江西',value:jiangxi }, 
        	{id:17, name: '湖北',value:hubei }, {id:18, name: '广西',value:guangxi }, {id:19, name: '甘肃',value:gansu }, {id:20, name: '山西',value:shanxi }, 
        	{id:21, name: '内蒙古',value:neimenggu },  {id:22, name: '陕西',value:shanxi2 }, {id:23, name: '吉林',value:jilin }, {id:24, name: '福建',value:fujian }, 
        	{id:25, name: '贵州',value:guizhou }, {id:26, name: '广东',value:guangdong }, {id:27, name: '青海',value:qinghai }, {id:28, name: '西藏',value:xizang }, 
        	{id:29, name: '四川',value:sichuan }, {id:30, name: '宁夏',value:ningxia }, {id:31, name: '海南',value:hainan }, {id:32, name: '台湾',value:"none" }, 
        	{id:33, name: '香港',value:"none"}, {id:34, name: '澳门',value:"none" }]
        // 需要在页面上直接标记出来的城市
        //var specialMap = ['浙江', '云南', '陕西'];
        var specialMap = [];
        // 对dataMap进行处理,使其可以直接在页面上展示
        for (var i = 0; i < specialMap.length; i++) {
            for (var j = 0; j < dataMap.length; j++) {
                if (specialMap[i] == dataMap[j].name) {
                    dataMap[j].selected = true;
                    break;
                }
    		}
    	}
    // 绘制图表,准备数据

    var option = {
        tooltip: {
            formatter: function (params) {
                var info = '<p style="font-size:18px">' + params.name + '</p><p style="font-size:14px">'+'确诊:'+params.value+'人'+'</p>'
                return info;
            },
            //提示标签背景颜色
            backgroundColor:"rgba(0,0,255,0.5)",
            textStyle: { color: "#fff" } //提示标签字体颜色
        },
        series: [
            {
                name: '中国',
                type: 'map',
                mapType: 'china',
                selectedMode: 'multiple',
                label: {
                    normal: {
                        show: true,//显示省份标签
                        // textStyle:{color:"#c71585"}//省份标签字体颜色
                    },
                    emphasis: {
                        show: true,//对应的鼠标悬浮效果
                        //textStyle:{color:"#00FFFF"}
                    }
                },
                itemStyle: {
                    normal: {
                        borderWidth: .5,//区域边框宽度
                        // borderColor: '#009fe8',//区域边框颜色
                        // areaColor:"#ffefd5",//区域颜色
                    },
                    emphasis: {
                        borderWidth: .5,
                        borderColor: '#4b0082',
                        areaColor: "#00FFFF",
                    }
                },
                data: dataMap
            }
        ],
        
    visualMap: {
        show : true,
        x: 'left',
        y: 'bottom',
        splitList: [
            {start: 10000},
            {start: 1000, end: 9999},
            {start: 100, end: 999},
            {start: 10, end: 99},
            {start: 1, end: 9},
            {start: 0, end: 0},
        ],
        color: ['#660208', '#8C0D0D', '#CC2929','#FF7B69' ,'#FFAA85' , '#F8F9FA']
    },
    };
    //初始化echarts实例
    var myChart = echarts.init(document.getElementById('container'));
    //使用制定的配置项和数据显示图表
    myChart.setOption(option);
    myChart.on('click', function (params) {
        console.log(params.data.id);
        window.location.href="statistics.jsp?id="+params.data.id;	
        
    });

statistics.jsp 绘制折线图

   var option = {
  		title: {
  	        text: '<%=province%> 疫情趋势', // 标题名称
  	    },
  	    xAxis: {
  	        type: 'category',
  	        data: ['01-19', '01-20', '01-21', '01-22', '01-23', '01-24', '01-25','01-26','01-27','01-28','01-29','01-30','01-31','02-01','02-02']
  	    },
  	    yAxis: {
  	        type: 'value',
  	        name: '单位:例',
  	    },
  	    tooltip: {
  	        trigger: 'axis'
  	    },
          legend: {
              data: ['新增确诊趋势', '新增疑似趋势', '治愈趋势', '死亡趋势']
          },
          toolbox: {
              feature: {
                  saveAsImage: {}
              }
          },
  	    series: [
  		{
      	name:"新增确诊趋势",
          data: [<%=dateMap.get("2020-01-19")[0]%>, <%=dateMap.get("2020-01-20")[0]%>, 
              <%=dateMap.get("2020-01-21")[0]%>, <%=dateMap.get("2020-01-22")[0]%>,
              <%=dateMap.get("2020-01-23")[0]%>, <%=dateMap.get("2020-01-24")[0]%>,
              <%=dateMap.get("2020-01-25")[0]%>,<%=dateMap.get("2020-01-26")[0]%>,
              <%=dateMap.get("2020-01-27")[0]%>,<%=dateMap.get("2020-01-28")[0]%>,
              <%=dateMap.get("2020-01-29")[0]%>,<%=dateMap.get("2020-01-30")[0]%>,
              <%=dateMap.get("2020-01-31")[0]%>,<%=dateMap.get("2020-02-01")[0]%>,
              <%=dateMap.get("2020-02-02")[0]%>],
          type: 'line',
          
          symbol:'star',//拐点样式
          symbolSize: 5,//拐点大小
          smooth: true,
          itemStyle : {
              normal : {
                  lineStyle:{
                      color:"#EE3B3B",//折线颜色
                      borderColor:'#EE3B3B',
                  }
              }
          },
      },
      {
      	name:"新增疑似趋势",
          data: [<%=dateMap.get("2020-01-19")[1]%>, <%=dateMap.get("2020-01-20")[1]%>, 
              <%=dateMap.get("2020-01-21")[1]%>, <%=dateMap.get("2020-01-22")[1]%>,
              <%=dateMap.get("2020-01-23")[1]%>, <%=dateMap.get("2020-01-24")[1]%>,
              <%=dateMap.get("2020-01-25")[1]%>,<%=dateMap.get("2020-01-26")[1]%>,
              <%=dateMap.get("2020-01-27")[1]%>,<%=dateMap.get("2020-01-28")[1]%>,
              <%=dateMap.get("2020-01-29")[1]%>,<%=dateMap.get("2020-01-30")[1]%>,
              <%=dateMap.get("2020-01-31")[1]%>,<%=dateMap.get("2020-02-01")[1]%>,
              <%=dateMap.get("2020-02-02")[1]%>],
          type: 'line',
          symbol:'star',//拐点样式
          symbolSize: 5,//拐点大小
          smooth: true,
          itemStyle : {
              normal : {
                  lineStyle:{
                      color:"#EE7942",//折线颜色
                      borderColor:'#EE7942',
                  }
              }
          },
      },
      
      {
      	name:"治愈趋势",
          data: [<%=dateMap.get("2020-01-19")[2]%>, <%=dateMap.get("2020-01-20")[2]%>, 
              <%=dateMap.get("2020-01-21")[2]%>, <%=dateMap.get("2020-01-22")[2]%>,
              <%=dateMap.get("2020-01-23")[2]%>, <%=dateMap.get("2020-01-24")[2]%>,
              <%=dateMap.get("2020-01-25")[2]%>,<%=dateMap.get("2020-01-26")[2]%>,
              <%=dateMap.get("2020-01-27")[2]%>,<%=dateMap.get("2020-01-28")[2]%>,
              <%=dateMap.get("2020-01-29")[2]%>,<%=dateMap.get("2020-01-30")[2]%>,
              <%=dateMap.get("2020-01-31")[2]%>,<%=dateMap.get("2020-02-01")[2]%>,
              <%=dateMap.get("2020-02-02")[2]%>],
          type: 'line',
          symbol:'star',//拐点样式
          symbolSize: 5,//拐点大小
          smooth: true,
          itemStyle : {
              normal : {
                  lineStyle:{
                      color:"#20B2AA",//折线颜色
                      borderColor:'#20B2AA',
                  }
              }
          },
      },
      {
      	name:"死亡趋势",
          data: [<%=dateMap.get("2020-01-19")[3]%>, <%=dateMap.get("2020-01-20")[3]%>, 
              <%=dateMap.get("2020-01-21")[3]%>, <%=dateMap.get("2020-01-22")[3]%>,
              <%=dateMap.get("2020-01-23")[3]%>, <%=dateMap.get("2020-01-24")[3]%>,
              <%=dateMap.get("2020-01-25")[3]%>,<%=dateMap.get("2020-01-26")[3]%>,
              <%=dateMap.get("2020-01-27")[3]%>,<%=dateMap.get("2020-01-28")[3]%>,
              <%=dateMap.get("2020-01-29")[3]%>,<%=dateMap.get("2020-01-30")[3]%>,
              <%=dateMap.get("2020-01-31")[3]%>,<%=dateMap.get("2020-02-01")[3]%>,
              <%=dateMap.get("2020-02-02")[3]%>],
          type: 'line',
          symbol:'star',//拐点样式
          symbolSize: 5,//拐点大小
          smooth: true,
          itemStyle : {
              normal : {
                  lineStyle:{
                      color:"#36648B",//折线颜色
                      borderColor:'#36648B',
                  }
              }
          },
      },
      
      ]
  };
  //初始化echarts实例
  var myChart = echarts.init(document.getElementById('container'));
  //使用制定的配置项和数据显示图表
  myChart.setOption(option);

6、心路历程与收获

221701125张家榜:

一开始拿到这个作业我是觉得很困难,因为看到作业要求后,我觉得有很多功能难以实现,并且我也没有学过一些框架,一些技术上的问题难以解决,并且,我也没尝试过用web进行前后端数据交互。不过在后来在实现的过程中,不断上网查找资料解决难题,学习新技术,解决难题。这次作业让我意识到,光靠本科课程所学的知识是远远不够的,还要课外学习常用的技术。在这次作业,我负责写前端,队友负责写后端,最后由我整合,让我体会到团队合作的重要性。
我的队友是一位全能型选手,不管什么难题,只要交给他,他总能高效率地去完成。在此之前,我们经常一起讨论问题,一起分享成果,彼此十分熟悉,配合也很默契。即使这次作业对我来说十分困难,但是只要一想到与他合作,我就信心十足。一个优秀的队友在团队中是十分重要 ,我很庆幸能与他合作。在本次作业中,我们互相帮助,有困难一起解决。我希望今后还能有机会与他在此合作!

221701126 唐靖钧:
这次结对作业中我主要负责后端数据的读取、处理和接口的编写,本来想尝试使用python进行实时数据的爬取,但是由于水平有限,最终还是采用导入静态文件的方式来进行处理,这也是一个遗憾,借此机会也勉励自己一定要努力提升自己的技术,这样未来不会因为某些技术受限而无法实现某些需求。
我们两个人先确定了代码规范,这是编程的基础,也是一个良好习惯的养成,一个好的代码规范在团队协作中起到了至关重要的作用。
接着我们进行需求分析和代码设计,得出结论即为我负责后端读入文件,讲文件中的数据进行处理,接着编写接口返回这些以数组为结构的数据,前端调用我的接口即可绘制地图、折线图等。
无数次的QQ聊天交流,互相汇报两个人的进度以及当前困难遇到的困难,我想团队开发的魅力就体现于此吧。
每完成一个部分就上传至我们两个人的团队仓库,虽然这次结对作业只有两个人,但是也让我感受到团队协作的魅力,同伴需要什么接口,我就提供给他,也让我有了成就感,未来的软工实践团队项目应该会具挑战,但是我认为遇到困难不可怕,大家不沟通不交流才可怕,我也对未来的真正的项目团队协作充满了期待,也具有一定的正向压力。
我认为我的同伴是一个具有领导力的人,他能够清晰的分析任务的需求和所需技术,并且能够进行很好的分工,在我遇到一些困难无法实现的时候,我都会去求助于他,而他也会很耐心的为我找寻解决办法,我认为这次结对作业的核心在于结对,在于同伴,一个优秀的同伴会让自己在开发过程中不会惧怕困难,正如我上面所述,在这次任务中,我遇到了许多后端方面的问题,还有前后端交互的认识障碍,但是我们两个人能够互相帮助,共享资源,也就使得这些技术上的困难没有那么可怕了,我不担心麻烦他,我也希望他也能够在遇到困难时多麻烦我,希望我的同伴在未来的项目实践中能够一帆风顺,将来有机会一定会选择与他再次组队!
23![]

posted @ 2020-03-16 17:34  SeinoNana  阅读(269)  评论(2编辑  收藏  举报