这个作业属于哪个课程 | 2020春S班 (福州大学) |
---|---|
这个作业要求在哪里 | 结对第二次作业——某次疫情统计可视化的实现 |
结对学号 | 041701320、221701117 |
这个作业的目标 | 疫情统计可视化的实现 |
作业正文 | 结对第二次作业——某次疫情统计可视化的实现 |
其他参考文献 | CSDN、百度、echarts |
1.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视觉映射组件配置,来实现不同颜色深浅表示人数区间,颜色深表示疫情严重程度。
- 功能1:地图可视化
-
功能结构图
5.代码说明
-
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>
-
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)' } } ] }) })
-
tooltip
提示框组件配置实现当鼠标移到对应省份块时,显示出该省份的具体数据tooltip: { triggerOn: 'mousemove', // 触发tooltip的条件 'click|mousemove' formatter: function(params) { // console.log(params) // 数据格式化 return `地区:${params.name}<br/> 确诊人数:${params.value}<br/>疑似人数:${params.data?.suspectedCount}<br/>` } }
-
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 // 是否显示每项的文本标签 }
-
爬取丁香园网站
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) }) }
-
通过 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)
-
将爬取的 json 数据写入本地文件中存储
fs.writeFile(path.join(__dirname, './data.json'), JSON.stringify(originDataObj), err => { if (err) throw err console.log('数据写入成功') })
-
创建 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.心路历程和收获
杨鑫杰的心路历程和收获:
- 《构建之法》第四、五章阅读总结
- 软件团队的模式
主治医师模式、明星模式、社区模式、业余剧团模式、秘密团队、特工团队、交响乐团模式、爵士乐模式、功能团队模式、官僚模式 - 开发流程
- 写了再改模式
- 瀑布模型(Waterfall Model) 是一个项目开发架构,开发过程是通过设计一系列阶段顺序展开的,从系统需求分析开始直到产品发布和维护,每个阶段都会产生循环反馈,因此,如果有信息未被覆盖或者发现了问题,那么最好 “返回”上一个阶段并进行适当的修改,项目开发进程从一个阶段“流动”到下一个阶段,这也是瀑布模型名称的由来。
瀑布模型的适用范围:产品的定义非常稳定但正确性非常重要、产品模块之间的接口能很好地定性定义和验证、使用的技术很成熟、子团队不能做到频繁的交流。 - 瀑布模型的变形:生鱼片模型(各个相邻模块像生鱼片那样部分重叠)以及大瀑布带着小瀑布(各个子系统统一到最后进行系统测试)
- 统一流程RUP
统一流程Rational Unified Process,团队的各种成员在一个复杂的软件项目中的不同阶段做不同的事。这些不同类型的工作在RUP中叫做规程或者工作流。
简介:业务建模、需求、分析和设计、实现、测试、部署、配置和变更管理、项目管理。
分为四个阶段:初始阶段(达到生命周期目标里程碑)、细化阶段(达到生命周期结构里程碑)、构造阶段(达到初始功能里程碑)、交付阶段(达到产品发布里程碑)
- 软件团队的模式
- 心路历程和收获
这次作业对我来说难度挺大的,因为有太多东西不会了,什么爬虫啊,各种前端框架啊,自己一个也嘛不会,每次实践作业都要被自己菜到。
对这次作业,我首先是专注于怎么实现地图可视化,以及其颜色深浅、高亮、显示信息等方面。我知道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文件一直没反应,