结对第2次——疫情统计可视化的实现
结对第二次作业
| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/fzu/2020SpringW | 
|---|---|
| 这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzu/2020SpringW/homework/10456 | 
| 结对学号 | 221701332 221701330 | 
| 这个作业的目标 | 疫情统计化实现 | 
| 作业正文 | 。。。 | 
| 其他参考文献 | 。。。 | 
一,Github仓库地址和代码规范链接
二,成品演示
- 
主页面
- 
鼠标移过高亮且显示详细信息
- 
输入日期准备查询
- 
点击查询弹出提示
- 
显示查询的日期数据
- 
鼠标放置在右下角颜色位置,符合条件的省份高亮
- 
点击保存为图片
- 
点击切换数据视图
- 
数据视图
- 
点击任意省份之后的详情页面
三,结对讨论过程
*其实大部分交流用的是屏幕分享,因为有许多东西还需要请教
这样交流比较方便快捷


四,描述设计实现过程
| 前端 | 
|---|
- 因为作业题目有提示使用echarts,所以就下载了echarts.js并且跟着百度去学习该如何去做。去学习怎么制作图表,怎么高亮显示,怎样点击跳转。。。慢慢的就完成了前端的制作。前端是使用jsp去制作页面,加以javascript完成。数据通过调用后端的函数来获取。至于日期则设置一个参数来获取输入框的信息然后重新跳转该页面去实现。
| 后端 | 
|---|
- 首先数据部分,我们没有采取网络爬虫去获取数据,而是用助教给的数据。因此只需要读取该日志即可获得数据。然后写一个province类储存省份信息,读取日志名即日期(做折线图有用),再一个个处理日志数据,将读取的数据存入province对象列表中。最后只要前端需要便直接将列表传过去即可。之后为了做具体省份的具体信息,再设一个可以返回province对象即可。
五,关键代码
<%
    String date = null;
    int ip = 0,sp = 0,cure = 0,dead = 0;
    String ipresult = null,spresult = null,cureresult = null,deadresult = null;
    date = request.getParameter("date");
<<<<<<< HEAD
    List<Province> provinces = getlog.log(date);//输入日期返回当前日期的省份列表数据
    List<Province> provinceYes = getlog.logYesterday(date);//输入日期返回前一天的省份列表数据
    for(Province province : provinces)
    {
        if(province.getProvince().equals("全国"))
        {
            ip = province.getIp();
            sp = province.getSp();
            cure = province.getCure();
            dead = province.getDead();
        }
    }
        for(Province province : provinceYes)
    {
        if(province.getProvince().equals("全国"))
        {
            if((ip - province.getIp())>0) ipresult = "+"+((ip - province.getIp())+"");
            else if((ip - province.getIp())==0) ipresult = "无变化";
            else ipresult = (ip - province.getIp())+"";
            if((sp - province.getSp())>0) spresult = "+"+((sp - province.getSp())+"");
            else if((sp - province.getSp())==0) spresult = "无变化";
            else spresult = (sp - province.getSp())+"";
            if((cure - province.getCure())>0) cureresult = "+"+((cure - province.getCure())+"");
            else if((cure - province.getCure())==0) cureresult = "无变化";
            else cureresult = (cure - province.getCure())+"";
            if((dead - province.getDead())>0) deadresult = "+"+((dead - province.getDead())+"");
            else if((dead - province.getDead())==0) deadresult = "无变化";
            else deadresult = (dead - province.getDead())+"";
        }
    }
=======
    List<Province> provinces = getlog.log(date);//输入日期返回当前日期的省份列表的相关数据
>>>>>>> f4d47d29505967076a370a17727503ff2d1afb5f
%>
<script>
    function date() {
        var content = document.getElementById("time");//input的id
        $("time").val();
        window.alert(content.value);
        window.location.href = "index.jsp?&date="+content.value;
    }
    var myChart = echarts.init(document.getElementById('china-map'));
    var option = {
        title : {
            text: '全国疫情地图',
            x:'center'
        },
        tooltip : {//提示框组件
            trigger: 'item',//数据项图形触发,主要在散点图,饼图等无类目轴的图表中使用
            formatter:'{a}<br>地区:{b}<br>确诊:{c}人'
        },
        legend: {
            orient: 'horizontal',//图例的排列方向
            x:'left',//图例的位置
            data:['患者']
        },
        visualMap: {//颜色的设置  dataRange
            x: 'left',
            y: 'center',
            splitList: [
                {start: 10000},
                {start: 1000, end: 9999},
                {start: 100, end: 999},
                {start: 10, end: 99},
                {start: 1, end: 9},
                {start: 0, end: 0}
            ],
        },
        toolbox: {//工具栏
            show: true,
            orient : 'vertical',//工具栏 icon 的布局朝向
            x: 'right',
            y: 'center',
            feature : {//各工具配置项
                mark : {show: true},
                dataView : {show: true, readOnly: false},//数据视图工具,可以展现当前图表所用的数据,编辑后可以动态更新。
                restore : {show: true},//配置项还原。
                saveAsImage : {show: true}//保存为图片。
            }
        },
        roamController: {//控制地图的上下左右放大缩小 图上没有显示
            show: true,
            x: 'right',
            mapTypeControl: {
                'china': true
            }
        },
        series : [
            {
                name: '地区状况',
                type: 'map',
                mapType: 'china',
                roam: false,//是否开启鼠标缩放和平移漫游
                itemStyle:{//地图区域的多边形 图形样式
                    normal:{//是图形在默认状态下的样式
                        label:{
                            show:true,//是否显示标签
                            textStyle: {
                                color: "rgb(249, 249, 249)"
                            }
                        }
                    },
                    emphasis:{//是图形在高亮状态下的样式,比如在鼠标悬浮或者图例联动高亮时
                        label:{show:true}
                    }
                },
                top:"3%",//组件距离容器的距离
                data:[
                    <%
                        for(Province province : provinces)
                        {
                            if(!province.getProvince().equals("全国"))
                            {
                    %>
                    {name:'<%=province.getProvince()%>', value: <%=province.getIp()%>},
                    <%}}%>
                ]
            }
        ]
    };
    myChart.setOption(option);
    myChart.on('click', function (params){
        var name = params.name;
        location.href = "line.jsp?&province="+name;
    });
</script>
script type = "text/javascript">
    //指定图标的配置和数据
    var option = {
        title:{
            text:'折线图'
        },
        tooltip : {//提示框组件。
            trigger: 'item',
            formatter:'{a}<br>时间:{b}<br>确诊:{c}人'
        },
        legend:{},
        xAxis:{
            data:[
                 <% for(String Date : date){ %>
                 "<%=Date%>",
                <% } %>
                 ]
        },
        yAxis:{
        },
        series:[{
            name:'<%=pro%>地区确诊人数',
            type:'line',
            data:[
                <% for(String Date : date){ %>
                "<%=getlog.log(pro,Date).getIp()%>",
                <% } %>
            ]
        }]
    };
    var myChart = echarts.init(document.getElementById('chart1'));
    myChart.setOption(option);
</script>
  public static void InformationProcessing(String Path,List<Province> proList,Province allpro) //日志信息处理
    {
        int people;
        String pattern = ".*//.*";
        String pattern0 = "(\\d+)";
        String pattern0_1 = ".*感染患者.*";
        String pattern0_2 = ".*疑似患者.*";
        String pattern1 = ".*新增.*";
        String pattern2 = ".*流入.*";
        String pattern3 = ".*死亡.*";
        String pattern4 = ".*治愈.*";
        String pattern5 = ".*确诊感染.*";
        String pattern6 = ".*排除.*";
        Pattern number = Pattern.compile(pattern0); // 创建 Pattern 对象
        try
        {
            File file = new File(Path);
            if(!file .exists()){}
            BufferedReader br = new BufferedReader(new FileReader(file));
            String str;
            while ((str = br.readLine()) != null)
            {
                Matcher num = number.matcher(str); // 现在创建 matcher 对象
                String arrays[] = str.split(" ");
                if(Pattern.matches(pattern,str)) continue; // 跳过注释内容
                for (Province province1 : proList) {
                    if (arrays[0].equals(province1.getProvince())&&num.find())
                    {
                        people = Integer.valueOf(num.group(0));
                        if(Pattern.matches(pattern1,str)) // 新增
                        {
                            if(Pattern.matches(pattern0_1,str)) // 新增感染患者
                            {
                                province1.setIp(province1.getIp() + people);
                                allpro.setIp(allpro.getIp() + people);
                            }
                            else if(Pattern.matches(pattern0_2,str)) //新增疑似患者
                            {
                                province1.setSp(province1.getSp() + people);
                                allpro.setSp(allpro.getSp() + people);
                            }
                        }
                        else if(Pattern.matches(pattern2,str)) //从省一流入省二
                        {
                            for (Province province2 : proList) {
                                if (arrays[3].equals(province2.getProvince()))
                                {
                                    if(Pattern.matches(pattern0_1,str))
                                    {
                                        province1.setIp(province1.getIp() - people);
                                        province2.setIp(province2.getIp() + people);
                                    }
                                    else if(Pattern.matches(pattern0_2,str))
                                    {
                                        province1.setSp(province1.getSp() - people);
                                        province2.setSp(province2.getSp() + people);
                                    }
                                }
                            }
                        }
                        else if(Pattern.matches(pattern3,str)) //死亡 dead+n,ip-n
                        {
                            province1.setDead(province1.getDead() + people);
                            province1.setIp(province1.getIp() - people);
                            allpro.setDead(allpro.getDead() + people);
                            allpro.setIp(allpro.getIp() - people);
                        }
                        else if(Pattern.matches(pattern4,str)) //治愈 cure+n,ip-n
                        {
                            province1.setCure(province1.getCure() + people);
                            province1.setIp(province1.getIp() - people);
                            allpro.setCure(allpro.getCure() + people);
                            allpro.setIp(allpro.getIp() - people);
                        }
                        else if(Pattern.matches(pattern5,str)) //确诊感染 sp-n,ip+n
                        {
                            province1.setIp(province1.getIp() + people);
                            province1.setSp(province1.getSp() - people);
                            allpro.setIp(allpro.getIp() + people);
                            allpro.setSp(allpro.getSp() - people);
                        }
                        else if(Pattern.matches(pattern6,str)) //排除 sp-n
                        {
                            province1.setSp(province1.getSp() - people);
                            allpro.setSp(allpro.getSp() - people);
                        }
                    }
                }
            }
        } catch (IOException  e) {
            e.printStackTrace();
        }
    }
    public static List<Province> province(String date)
    {
        String[] Provinces = { "北京","天津","上海","重庆","河北","河南","云南","辽宁","黑龙江","湖南","安徽","山东",
                "新疆","江苏","浙江","江西","湖北","广西","甘肃","山西","内蒙古","陕西","吉林","福建","贵州","广东",
                "青海","西藏","四川","宁夏","海南","台湾","香港","澳门","南海诸岛"};
        List<Province> proList = new ArrayList<>();
        List<String> listFileName;
        Province allpro = new Province("全国"); // 创建全国对象
        proList.add(allpro);
        for(String pro:  Provinces)
        {
            Province provin = new Province(pro);
            proList.add(provin);
        }
        File file = new File(getlog.class.getClassLoader().getResource("../../log").getPath());
        try
        {
            String path = file.getAbsolutePath();
            listFileName = getAllFileName();
            for(String name : listFileName)
            {
                if(date==null)
                {
                    InformationProcessing(path+"/"+name+".log.txt",proList,allpro);
                    continue;
                }
                else if (listFileName.get(0).compareTo(date) > 0) break; //若输入日期小于最旧的日志
                else if(name.compareTo(date) > 0) break;
                InformationProcessing(path+"/"+name+".log.txt",proList,allpro);
            }
        }catch(Exception e){}
        return proList;
    }
六,《构建之法》阅读心得,心路历程以及对队友的评价
阅读心得
- 
构建之法第四章提到两人合作开发,按照作业要求使用Git分支,建立一条dev分支,让队友和自己在dev分支上开发,开发结束后再合并到main分支。第一次接触这样的结对编程,感到新颖的同时也很陌生,相信在以后的实践中对这种合作开发会有更多经验。 
- 
在第五章提到的团队合作和流程这个对于我们接下来的团队项目将很有帮助。作为一个团队,要有一致的目标、明确的分工。首先这一点是最为关键的,在团队中要时刻注意和保持。这样才能发挥最大的团队效率。 
心路历程
221701330
- 这次的作业总体来说不难,但是如果真的要扩展许多功能就比较困难了。在实现的过程中遇到许多问题,
 但是在队友和百度的帮助下,总算度过难关。可喜可贺!
221701332
- 第一次看到这次作业感觉非常难,与队友讨论完也认清自己的任务,
 代码虽然不多,但是小BUG还是很多,因为自己能力不足,很多时候
 还是在查文档和看大佬代码中学习。在查找很多资料后逐渐掌握,这
 也算学到一种新的技能。
对队友的评价
221701330
- 我的队友代码规范,能够虚心学习,交流起来也很流畅。和他的合作
 是一次成功的合作。
221701332
- 他是个靠谱的队友,能一起合作是我的荣幸,他的部分我完全不用担心,
 都能做好,对我的部分也能提出一些建议,是个有实力有配合的队友。
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号