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

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/2020SPRINGS/
这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/2020SPRINGS/homework/10460
结对学号 091700410&131700305
这个作业的目标 采用web技术来实现疫情可视化
作业正文 https://www.cnblogs.com/exusiai-blog/p/12507222.html
其他参考文献 CSDN

一、仓库链接和代码规范

github仓库:https://github.com/Exusia-i/InfectStatisticWeb/commits/master
codestyle:https://github.com/Exusia-i/InfectStatistic-main/blob/master/091700410/codestyle.md
已部署到云服务器,网页链接:http://120.78.199.189:8000/index

二、成品展示

  • 该项目采用Django框架开发的。

  • 打开网页首先会看见中国地图和数据,地图下方有一个折线图展示全国疫情发展的规律。

  • 全国地图上使用不同的颜色代表大概确诊人数区间 颜色的深浅表示疫情的严重程度,可以直观了解高危区域; 鼠标移到每个省份会高亮显示; 点击鼠标会显示该省具体疫情情况;

  • 点击省份后进入省份疫情视图,显示该省份对应的感染患者人数、疑似患者人数、治愈人数、死亡人数;下方有折线图显示 该省份到目前为止的新增确诊趋势、新增疑似趋势、治愈趋势和死亡趋势;

  • 可查看具体日期的疫情地图

  • 可切换累计确诊与现有确诊

  • 折线图可切换新增确诊/新增疑似趋势和累计治愈/死亡趋势

  • 一些说明:数据是通过调用api的方式获得的

三、结对过程

拿到题目时便觉得上手有些难度,于是我们两人在当晚就展开了讨论,我们也试过其他的方法比如用jsp和servlet,本来因为时间还有经验等原因我们本来选用html和js,但是为了获取数据的方便和学习新技术最终选择Django架构。
img
我负责样式和python部分,html和js的主要部分由合作伙伴完成,为了把它们放进Django框架也做了一些改动

列好工程框架,讨论具体实现的所需要做的内容和方法,pull和fetch过程产生了不明原因的错误,决定重新fork一次仓库

img

img

四、设计实现过程

  • 一开始的设想是用jsp+servlet来实现,但是做到和后台传输数据的时候发现没有接触过servlet的后端技术,然后就转到了html。我感觉这个作业最难的部分就是后台绑定数据的部分,本来是想用Ajax来实现的,但是由于学习事件很仓促,再加上用Ajax的时候一直没有设置对正确的url,只能放弃Ajax;后面想到了json,但是json需要导入很多jar文件,没有找到对应的教程和对应的jar,也放弃了,最后发现python调用api的方式更容易获取数据,于是采用Django架构。

代码说明

Djiango中实现页面数据的加载

def index(request):
    now_time = time.strftime('%Y-%m-%d', time.localtime(time.time()))  #  获取当前的日期
    context = {}  #  用于在网页中显示数据的字典
    context.update(spider.get_country_data(now_time))  #  传入当前日期,通过get_country_data读取到今日的数据并存储到字典中
    context.update({'time': now_time})
    context_list = []
    for i in range(30):  #  把当前日期及前一个月的日期存储到字典中
        context_list.append(time.strftime('%Y-%m-%d', time.localtime(time.time()-i*3600*24)))
    context.update({'list': context_list})
    spider.get_map_data(now_time)
    return render(request, 'index.html', context)  #  跳转到index.html


def detail(request):
    return render(request, 'detail.html')


def loading(request):
    return render(request, 'loading.html')


def get_by_date(request):
    #  按日期获取地图数据
    now_time = time.strftime('%Y-%m-%d', time.localtime(time.time()))
    map_date = request.GET.get('getByDate')
    #  获取表单传入的日期
    if map_date == '' or map_date == None:
        map_date = now_time
    context = {}
    context.update(spider.get_country_data(now_time))
    context.update({'time': now_time})
    context.update({'map_time': map_date})
    context_list = []
    for i in range(30):
        context_list.append(time.strftime('%Y-%m-%d', time.localtime(time.time() - i * 3600 * 24)))
    context.update({'list': context_list})
    spider.get_province_data(now_time)
    spider.get_map_data(map_date)
    return render(request, 'index.html', context)  #  跳转到index.html

python调用api获取数据,通过写js保存数据

def get_country_data(date):
  #  获取全国数据
  json = requests.get('http://api.tianapi.com/txapi/ncov/index?key=d77a8a4d8661ecfbb26ce6ac02e6ceda&date={0}'.format(date)).json()
  
  return json['newslist'][0]['desc']
  #  返回一个字典
  

def get_map_data(date):
  #  获取地图所需数据
  r = open('./static/js/mapData.js', 'r', encoding='utf-8')
  r.close()
  
  json = requests.get('http://api.tianapi.com/txapi/ncovcity/index?key=d77a8a4d8661ecfbb26ce6ac02e6ceda&date={0}'.format(date)).json()
  w = open('./static/js/mapData.js', 'w', encoding='utf-8')
  #  通过写入JavaScript文件来为echarts地图提供数据
  
  w.writelines('
let mydata = [
')
  for i in range(len(json['newslist'])):
      w.writelines('{
')
      w.writelines("'name': '{0}',
".format(json['newslist'][i]['provinceShortName']))
      w.writelines("'value': '{0}',
".format(json['newslist'][i]['currentConfirmedCount']))
      w.writelines('},
')
  w.writelines('];
')
  w.writelines('
let mydataSec = [
')
  for i in range(len(json['newslist'])):
      w.writelines('{
')
      w.writelines("'name': '{0}',
".format(json['newslist'][i]['provinceShortName']))
      w.writelines("'value': '{0}',
".format(json['newslist'][i]['confirmedCount']))
      w.writelines('},
')
  w.writelines('];
')
  w.writelines('let xA_data = [')
  for i in range(15):
      m = time.strftime('%m-%d', time.localtime(time.time()-(14-i)*3600*24))
      w.writelines("' {0}',".format(m))
  w.writelines('];
')

  w.close()


def get_province_data(date):
  #  获取各省的数据
  j = requests.get(
      'http://api.tianapi.com/txapi/ncovcity/index?key=d77a8a4d8661ecfbb26ce6ac02e6ceda&date={0}'.format(date)).json()
  w = open('./static/json/provinceData.json', 'w', encoding='utf-8')
  json.dump(j,w)
  w.close()

通过这样就可以设置echarts表格的数据,有点繁琐

六、心路历程与结对伙伴评价

  • 心路历程:两次结对作业让我从因为能力不足而畏手畏脚逐渐向敢于尝试的方向发展,因为自我怀疑而产生习得性无助认为自己做不好,但是通过和结对对象的分工合作,我明白结对编程的一大重要意义就是培养结对意识,不能只有一方完成工作,两个人应该团结合作,承担起自己的那份责任,我渐渐地为自己分配一些工作并且实现,无论是从完成积极性和主动学习性上都有了很大程度地提高,不会再拖沓地不去完成,遇到不会的内容不会像从前一样象征性查询两下资料,而是各方面搜集有用的内容来达成目的。本次作业选用的Django框架对我来说是陌生的技术,是为了在完成作业的过程中能够学到更多新的技术。
  • 结对评价:结对伙伴完成自己部分的任务的速度很快,说明他的行动力很强做事不拖沓,然而他的粗枝大叶也给我留了一些坑。
  • 结对伙伴博客:https://www.cnblogs.com/hyyyyz/p/12507509.html
原文地址:https://www.cnblogs.com/exusiai-blog/p/12507222.html