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


    这个作业属于哪个课程 2020春S班 (福州大学)
    这个作业要求在哪里 结对第二次作业——某次疫情统计可视化的实现)
    结对学号 041701320、221701117
    这个作业的目标 疫情统计可视化的实现
    作业正文 结对第二次作业——某次疫情统计可视化的实现
    其他参考文献 CSDN、百度、echarts

    1.Github仓库地址和代码规范链接

    Github仓库地址
    代码风格

    2.成品展示

    • 显示现有确诊、现有重症、现有疑似、累计确诊、累计死亡、累计治愈人数
      此处输入图片的描述
    • 地图可视化,不同颜色代表大概人数区间,颜色深浅表示疫情严重程度
      此处输入图片的描述
      此处输入图片的描述
    • 显示某区间的省份
      此处输入图片的描述
    • 鼠标移动到省份高亮,显示具体疫情情况
      此处输入图片的描述
    • 全国nCov总数量曲线图
      此处输入图片的描述
    • 全国nCov新增量曲线图
      此处输入图片的描述
    • 全国确诊、疑似、治愈、死亡人数折线图,可选择日期。根据tag的值判断日期,过滤json数据,获取对于日期的情况。
      此处输入图片的描述
    • 拓展功能:新闻快讯
      此处输入图片的描述
    • 动图gif展示

    3.结对过程

    此处输入图片的描述
    此处输入图片的描述
    此处输入图片的描述

    4.描述设计实现过程

    • 设计实现过程

      • 功能1:地图可视化
          ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari 等),底层依赖矢量图形库ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。
          我们用echarts实现地图的可视化,配置option,使用series选项添加数据,引入中国地图map。用tooltip提示框组件配置,来实现当鼠标移到对应省份块时,显示出该省份的具体数据。用visualMap视觉映射组件配置,来实现不同颜色深浅表示人数区间,颜色深表示疫情严重程度。
    • 功能结构图
      此处输入图片的描述

    5.代码说明

    1. series选项配置中国地图

          <script src="echarts.js"></script>
          <script src="map/js/china.js"></script>
          <script>
            var myChart = echarts.init(document.getElementById('main'))
            myChart.setOption({
              backgroundColor: '#404a59', // 图标区域背景
              title: {
                // 标题设置
                text: '新型冠状病毒全国分布图',
                left: 'center',
                textStyle: {
                  fontSize: 28,
                  color: '#fff'
                }
              },
              series: [
                {
                  type: 'map', // 图标类型为 地图
                  map: 'china' // 展示中国地图
                }
              ]
            })
          </script>
      
    2. series 选项添加数据

          fetch('http://127.0.0.1:8088/api/data')
            .then(res => res.json())
            .then(res => {
              // console.log(res, 1111)
              let listByCountry = res.getListByCountryTypeService1
              let fitlerlistByCountry = []
              for (let i = 0; i < listByCountry.length; i++) {
                let item = listByCountry[i]
                fitlerlistByCountry.push({
                  name: item.provinceShortName,
                  value: item.confirmedCount,
                  suspectedCount: item.suspectedCount,
                  deadCount: item.deadCount
                })
              }
              console.log(fitlerlistByCountry, '后台接口数据')
              // 指定图表的配置项和数据
              myChart.setOption({
                // ...,
                series: [
                  {
                    type: 'map', // 图标类型为 地图
                    map: 'china' // 展示中国地图
                    data: fitlerlistByCountry, // 地图注入疫情数据 [{name: '湖北',value: 59864, ...}, ...]
                    label: {
                      // 覆盖物设置
                      show: true,
                      fontSize: '10',
                      color: 'rgba(0, 0, 0, 0.7)'
                    }
                  }
                ]
              })
            })
      
    3. tooltip提示框组件配置实现当鼠标移到对应省份块时,显示出该省份的具体数据

         tooltip: {
         triggerOn: 'mousemove', // 触发tooltip的条件 'click|mousemove'
         formatter: function(params) {
           // console.log(params) // 数据格式化
           return `地区:${params.name}<br/> 确诊人数:${params.value}<br/>疑似人数:${params.data?.suspectedCount}<br/>`
         }
       }
      
    4. visualMap视觉映射组件配置

         visualMap: {
         type: 'piecewise', // 是否连续
         pieces: [ // 分段的图注 数据设置
           { gte: 10000 }, // (10000, Infinity]
           { gte: 1000, lte: 9999 }, // (1000, 999]
           { gte: 100, lte: 999 }, // (100, 999]
           { gte: 10, lte: 99 }, // (10, 99]
           { gte: 1, lte: 9 } // (1, 9]
         ],
         textStyle: { // 文本样式设置
           color: '#fff'
         },
         left: 'left',
         top: 'bottom',
         text: ['高', '低'], // 取值范围的文字
         inRange: { // 分段的图注 颜色设置
           color: ['#ffaa85', '#ff7b69', '#cc2929', '#8c0d0d', '#660208']
         },
         showLabel: true // 是否显示每项的文本标签
       }
      
    5. 爬取丁香园网站

        function crawlerData() {
        // superagent模拟浏览器去请求丁香园网站 获取数据
        var targetUrl = 'https://ncov.dxy.cn/ncovh5/view/pneumonia'
        superagent
          .get(targetUrl)
          .then(result => {
            // console.log(result) // 爬取回来的html字符串
          })
          .catch(err => {
            console.log(err)
          })
      }
      
    6. 通过 cheerios 筛选获取数据

      // 3.1 封装eval解析js字符串函数
      let originDataObj = {}
      // 封装执行js字符串函数
      function evalJsStr() {
        if (arguments.length <= 0) return
        for (let i = 0; i < arguments.length; i++) {
          let params = arguments[i].replace(/window/gi, 'originDataObj')
          eval(params)
        }
      }
      // 3.2 获取数据
      const $ = cheerio.load(result.text)
      // 1.1 获取省
      const $provinceStr = $('#getListByCountryTypeService1').html()
      // 1.2.获取省和地级市
      const $provinceAndCityStr = $('#getAreaStat').html()
      // 1.3.统计数据
      const $getStatisticsStr = $('#getStatisticsService').html()
      // 全国所有省数据
      // 2. 执行函数获取数据
      evalJsStr($provinceStr, $provinceAndCityStr, $getStatisticsStr)
      console.log(originDataObj)
      
    7. 将爬取的 json 数据写入本地文件中存储

        fs.writeFile(path.join(__dirname, './data.json'), JSON.stringify(originDataObj), err => {
        if (err) throw err
        console.log('数据写入成功')
      })
      
    8. 创建 express 服务器将爬取的数据通过接口响应

        // 1. 引入模块
        const fs = require('fs')
        const path = require('path')
        const express = require('express')
        const cors = require('cors')
        // 2. 创建服务器应用
        const app = express()
        app.use(cors())
        // 3. 监听请求
        app.get('/api/data', (req, res) => {
          // 3.1 读取本地数据
          fs.readFile(path.join(__dirname, './data.json'), 'utf8', (err, data) => {
            if (err) throw err
            res.send(data)
          })
          // 3.2 响应数据
        })
        // 4. 分配端口号启动服务
        app.listen(8088, () => {
          console.log('服务启动了 http://127.0.0.1:8088')
        })
      

    6.心路历程和收获

    杨鑫杰的心路历程和收获:

    1. 《构建之法》第四、五章阅读总结
      • 软件团队的模式
          主治医师模式、明星模式、社区模式、业余剧团模式、秘密团队、特工团队、交响乐团模式、爵士乐模式、功能团队模式、官僚模式
      • 开发流程
        • 写了再改模式
        • 瀑布模型(Waterfall Model) 是一个项目开发架构,开发过程是通过设计一系列阶段顺序展开的,从系统需求分析开始直到产品发布和维护,每个阶段都会产生循环反馈,因此,如果有信息未被覆盖或者发现了问题,那么最好 “返回”上一个阶段并进行适当的修改,项目开发进程从一个阶段“流动”到下一个阶段,这也是瀑布模型名称的由来。
          瀑布模型的适用范围:产品的定义非常稳定但正确性非常重要、产品模块之间的接口能很好地定性定义和验证、使用的技术很成熟、子团队不能做到频繁的交流。
        • 瀑布模型的变形:生鱼片模型(各个相邻模块像生鱼片那样部分重叠)以及大瀑布带着小瀑布(各个子系统统一到最后进行系统测试)
      • 统一流程RUP
          统一流程Rational Unified Process,团队的各种成员在一个复杂的软件项目中的不同阶段做不同的事。这些不同类型的工作在RUP中叫做规程或者工作流。
          简介:业务建模、需求、分析和设计、实现、测试、部署、配置和变更管理、项目管理。
          分为四个阶段:初始阶段(达到生命周期目标里程碑)、细化阶段(达到生命周期结构里程碑)、构造阶段(达到初始功能里程碑)、交付阶段(达到产品发布里程碑)
    2. 心路历程和收获
        这次作业对我来说难度挺大的,因为有太多东西不会了,什么爬虫啊,各种前端框架啊,自己一个也嘛不会,每次实践作业都要被自己菜到。
        对这次作业,我首先是专注于怎么实现地图可视化,以及其颜色深浅、高亮、显示信息等方面。我知道echarts能够实现,以前也稍微用过echarts,但就只会做一些简单的柱状图、折线图、饼状图,像地图这样的刚开始就不知道怎么弄。我先是跟着B站视频,学习用echarts实现大数据可视化,和学习用node来爬虫。
      此处输入图片的描述
        但是!后来还是没有能实现,因为cheerio和express下载了用不知道哪里出了问题始终会报错,所以我们后来就使用了静态的数据。虽然最后没能实现爬虫很闹心,但是爬虫的大体方法也算是基本了解了,也算有点收获吧。但关键是创建express服务器一直弄不好,我echarts实现显示数据的时候是用的fetch方法请求的url就没有。
      此处输入图片的描述
        然后我就问了几个同学,因为用的方法不同,都没有得到解决。后来一个朋友扔给我用layui框架来实现地图可视化的教程视频。layui采用自身模块规范编写的前端 UI框架,听闻门槛极低,我就重新跟着视频学习用layui来实现。通过get获取数据,其中数据接口是通过“天行数据”网站直接搜索api获取。
      此处输入图片的描述
      此处输入图片的描述
        总的来说,这次作业的收获是,更加熟悉github的分支、merge、pull request的使用,学习了echarts实现大数据可视化,了解了前端框架layui,了解了api、js、json的引用。

    yjc的心路历程和收获:

      说实话,这周的课多,作业多而杂,相当累!现在是凌晨我还要继续赶工,累是我最大的感受。当初刚开始的时候,心想,天哪,还要爬虫,还要各种。。简直刁钻,刻薄。现在终于也要结束了,也收心了,终于结束了要。
      前端我用了简单的semanticUI设计了简单的访问页面,semanticUI我第一次从B站学的视频,一步步跟着做。

    感觉确实方便很多,之前写前端,都是挠破头皮,各种布置css,用了semanticUI真的方便,希望以后多学一些前端框架长长见识,什么layui等等。说实话现在已经一点多了,我还在写收获,不过啃着辣条,还算开心的一件事。这次是我所有作业交的最晚的一次,我到现在还没写完代码,我心累,想想自己以后多少日夜都要这样日夜奔波,于是加深了我考别的研的信心和勇气哈哈。我觉得我说了一些没头没脑的收获,之所以会这样,是因为,我为了获取json数据,各个省份的变量赋值,等等,我一遍一遍的敲过去,这种无脑操作最为致命,可我还不知道怎么做才能更简便一些。

    大晚上的写这种代码,让我心情极度烦躁。好了不说烦躁了。接下来说一说,我开发过程遇到的困难和如何(没)解决的。
      首先回到前端,多个js的冲突问题让我心累。因为适当的引用了js文件,但是命名冲突导致代码不执行,图片显示不出来,可是js他又无法编译,看哪里代码写错了,烦的要死。然后就是,当初当然是想玩玩爬虫爬一下数据,可是他太难了,只能用别人的接口。在github上也看了很多人的代码,看了大神的操作,感觉自己很卑微,那时候,即使给了我API我都不会用。在这期间,我原本想着用springboot在做个简单的后端开发框架,结果,因为springboot我们也没学过,项目出了bug我到现在还没解决好(dbq)。
      关键是,在这次作业的过程中,知识盲区特别大,问别人,问同学,解决了一些的问题,可是重头戏也不怎么会,说起来,我可是“仰天长啸出门去,我辈岂是蓬蒿人”的优秀少年,怎么能被这个困难打倒,重新拾起勇气,再战再战。
      js文件的先后问题,也会有影响,这个我之前也迷茫了很久,才知道。还有文件路径问题,一般来说是相对html文件的,如果在一个js文件中想要引入某个文件,这个时候的路径是相对引入这个js文件的html文件的路径来算的,这个我之前也搞错了。我之前引用json文件一直没反应,

    后来借鉴网上的办法解决了,之前没有设置请求所以,jsonn文件都导不进去,很烦。在写json筛选器的时候,json内容如下:
    为了获取各个省份的信息,忙活了好久,一直显示不出想要获取的值,后来一开窍就搞好了呜呜呜。
    页面跳转获取参数,然后将数据替换,就可以了。很简单吧!
    过滤器,获取某天的疫情信息信息。
    这个是对strong等标签的数值的更新,借鉴了github上的代码。
  • 相关阅读:
    RedisTemplate实现事物问题剖析和解决
    PO BO VO DTO POJO DAO概念及其作用(附转换图)
    Java 应用程序设计规范
    Java web url 规范
    Java 中 Map与JavaBean实体类之间的相互转化
    使用Java 8中的Stream
    [转]http://lua-users.org/wiki/LpegTutorial
    [转]LUA元表
    LPEG
    [转]LUA 学习笔记
  • 原文地址:https://www.cnblogs.com/fzu-yxj/p/12495565.html
Copyright © 2020-2023  润新知