vue疫情大屏数据展示+数据导出+地图图片下载

December 17, 2023
测试
测试
测试
测试
21 分钟阅读

不废话,先上效果图 审美有限 下午5点开工 去掉吃饭时间 我的审美也只能让我做到这一步哈哈 有需要可以去github下载 github上代码是不加注释的 看注释在这个文章 github地址 https://github.com/dmhsq/vue-epidemic–big-screen

在这里插入图片描述
在这里插入图片描述

本来是想做那种科技风的,怎奈审美有限,又不想用别人的图片哈哈 下载的疫情地图如下

在这里插入图片描述
在这里插入图片描述

vue疫情大屏数据展示

  • 页面布局
    • 页面代码(非全部代码)
    • 地图绘制说明
  • 数据获取
    • 配置代理(解决跨域)
    • 页面数据说明
    • 发送请求
    • 处理数据
  • 图形绘制
    • 左上柱状图
    • 左下折线图
    • 右上饼图绘制
    • 左下表格
      • 表格导出功能
  • 全部代码

页面布局

使用了element的布局 官网手册地址

在这里插入图片描述
在这里插入图片描述

将页面分成三部分 第一部分就是左侧两个图 第二部分就是中间部分 第三部分就是右侧图和表格

页面代码(非全部代码)

在这里插入图片描述
在这里插入图片描述

地图绘制说明

地图那一块我是直接复制之前写过的代码 所以看之前那个文章就行 vue疫情图

代码都一模一样的 没有改

数据获取

数据的获取和之前的疫情图一样 文章跳转:vue疫情图 地图那一块我是直接复制之前写过的代码 所以看之前那个文章就行 vue疫情图

这里再讲一次(看过的可以忽略)

配置代理(解决跨域)

生成环境记得配置nginx

在这里插入图片描述
在这里插入图片描述

在vue.config.js中

devServer: {
    proxy: {
      "/api": { //发送请求时/api会被识别成https://www.ncovchina.com/data 下面一样
        target: "https://www.ncovchina.com/data",
        changeOrigin: true,
        pathRewrite: {
          "^/api": ""
        }
      },
      "/ans": {
        target: "https://api.inews.qq.com/newsqa/v1/query/inner/publish/modules/list?modules=chinaDayList,chinaDayAddList,nowConfirmStatis,provinceCompare",
        changeOrigin: true,
        pathRewrite: {
          "^/ans": ""
        }
      }
    },
    host: "0.0.0.0",//地址
    port: 8083,//端口
  }

这样就配置完成了 记得重启项目

页面数据说明

data() {
    return {
      nowTime:"",//现在时间
      txdata:[],//腾讯疫情网数据
      heal: 0,//治愈
      dead: 0,//死亡
      chinaTotal: 0,//中国总确诊
      chinaAdd: 0,//新增
      chinaNow: 0,//现存
      datas: [],//中国疫情网数据
      lastTime: "",//最后更新时间
      check: 0,//当前地图选择 新增/总/现存
      isLoading: false,//是否正在加载
      isChina: false,//是否为中国数据 (这里没有用,后面拓展全球地图再用)
      timer:"",//定时器,实时获取时间
      tables:[]//表格数据
    };
  },

发送请求

axios.post(`/api/getDisease.html`)
 axios.post('ans')

这里其实是请求了https://www.ncovchina.com/data/getDisease.html 将https://www.ncovchina.com/data/getDisease.html复制到地址栏也能查看数据

为什么会有两个地址 因为中国疫情网没有历史数据所以找了腾讯的 大家也可以自己找接口 腾讯疫情网 :https://news.qq.com/zt2020/page/feiyan.htm#/?nojump=1 中国疫情网:https://www.ncovchina.com/data.html 可以尝试只用腾讯疫情网的 我是懒得改

处理数据

getTx(){
      return new Promise(resolve => {
        axios.post('ans').then(res=>{
          console.log(res.data.data.chinaDayAddList);
          resolve(res.data.data.chinaDayAddList);
        })
      })
    },
    
axios.post(`/api/getDisease.html`).then(res => {
        let data = JSON.parse(res.data.data);
        let dss = data.areaTree[0].children;//通过查看数据得知我们需要的数据所在地
        this.datas = dss;
        console.log(data)
        this.chinaTotal = data.chinaTotal.confirm;//获取累计确诊
        this.chinaAdd = data.chinaAdd.confirm;//新增
        this.chinaNow = data.chinaTotal.nowConfirm;//现存
        this.heal = data.chinaTotal.heal;//治愈
        this.dead = data.chinaTotal.dead;//死亡
        this.lastTime = data.lastUpdateTime;//最后更新时间
        this.isLoading = false;//加载结束
        let vm = this;
        this.getTx().then(ress=>{//获取历史数据
          vm.txdata = ress;
          this.setChartTwo();//绘制左下
        })
        this.setEcs(this.check);
        let citys = [];
        dss.forEach(item=>{//处理数据
          item.children.forEach((items,index)=>{
            if(items.name =="境外输入"){
              item.children[index].name = item.name+items.name;
            }
            if(items.name =="地区待确认"){
              item.children[index].name = items.name+"("+item.name+")";
            }
            item.children[index].sf = item.name;
          })
          citys= citys.concat(item.children);
        });
        console.log(citys);
        this.tables = citys;//表格数据获取
        this.setChartThree();//绘制右上饼图
        this.setChartOne();//绘制左上柱状图 我是先做的右边的图
      });

图形绘制

看之前得对echarts有点了解 不了解可以百度 或者去echarts官网查看 https://echarts.apache.org/zh/index.html

左上柱状图

解释看代码后的注释

setChartOne(){
      let city = [];//城市名
      let adds = [];//新增
      let now = [];//现存
      // let sum = [];
      // let heal = [];
      // let dead = [];
      for(let i=0;i<7;i++){//添加数据 只添加前几个 有需要修改for循环次数
        let datas = this.datas[i];
        city.unshift(datas.name);
        adds.unshift(datas.today.confirm);
        now.unshift(datas.total.nowConfirm);
        // sum.unshift(datas.total.confirm);
        // heal.unshift(datas.total.heal);
        // dead.unshift(datas.total.dead);
      }

      let option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {            // 坐标轴指示器,坐标轴触发有效
            type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
          }
        },
        legend: {
          //原本是五个,数据太大删除了几个,可以在底部全部源码找到 或者顶部github地址下载
          // ['新增', '现存', '累计确诊', '累计治愈', '死亡']
          data: ['新增', '现存'],//
          textStyle:{
            color:"black"
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true,
          textStyle:{
            color:"black"
          }
        },
        xAxis: {
          type: 'value',
          axisLabel: {
            color: "black" //刻度线标签颜色
          }
        },
        yAxis: {
          type: "category",
          data: city,
          axisLabel: {
            color: "black" //刻度线标签颜色
          }
        },
        series: [
          {
            name: '新增',
            type: 'bar',
            stack: '总量',
            textStyle:{
              color:"black"
            },
            label: {
              textStyle:{
                color:"black"
              },
              show: true,
              position: 'insideRight'
            },
            data: adds //数据 新增
          },
          {
            name: '现存',
            type: 'bar',
            stack: '总量',
            label: {
              show: true,//显示数据
              position: 'insideRight'
            },
            data: now//数据 现存
          }
        ]
      };
      let myChart = echarts.init(this.$refs.chartOne);
      myChart.setOption(option);
    },

左下折线图

代码和左上柱状图类似

setChartTwo() {
      let datas = this.txdata.slice(-7);
      let dates = [];
      let confirm = [];
      datas.forEach(item => {
        dates.push(item.date);
        confirm.push(item.confirm);
      });
      console.log(dates);
      let option = {
        title: {
          text: "新增速率",
          subtext: "来源自腾讯疫情网",
          left: "center",
          textStyle: {
            color: "black" //标题颜色
          },
          subtextStyle: {
            color: "black" //副标题颜色
          }
        },
        xAxis: {
          type: "category",
          boundaryGap: false,
          data: dates,
          axisLabel: {
            color: "black" //刻度线标签颜色
          }
        },
        yAxis: {
          type: "value",
          axisLabel: {
            color: "black" //刻度线标签颜色
          }
        },
        series: [
          {
            data: confirm,
            label: {
              show: true,
              color: "black"
            },
            type: "line",
            areaStyle: {}
          }
        ]
      };

      let myChart = echarts.init(this.$refs.chartTwo);
      myChart.setOption(option);
    },

右上饼图绘制

代码解释看上面两个图的绘制解释 看完你就懂这个了 不再解释(我是懒蛋哈士奇)

setChartThree() {
      let datas = [
        { value: this.chinaAdd, name: "新增" },
        { value: this.chinaNow, name: "现存" },
        { value: this.dead, name: "累计死亡" },
        { value: this.heal, name: "累计治愈" },
        { value: this.chinaTotal, name: "累计确诊" }
      ];
      let names = ["新增", "现存", "累计死亡", "累计治愈", "累计确诊"];
      let option = {
        title: {
          text: "疫情数据",
          subtext: "来自疫情网",
          left: "center",
          textStyle: {
            color: "black"
          }
        },
        tooltip: {
          trigger: "item",
          formatter: "{a} <br/>{b} : {c} ({d}%)"
        },
        legend: {
          type: "scroll",
          orient: "vertical",
          textStyle: {
            color: "black"
          },
          right: 10,
          top: 20,
          bottom: 20,
          data: names
        },
        series: [
          {
            name: "数据",
            type: "pie",
            radius: "55%",
            center: ["40%", "50%"],
            data: datas,
            itemStyle: {
              normal: {
                label: {
                  show: true,
                  formatter: "{b} : {c}"
                },
                labelLine: { show: true }
              }
            },
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: "rgba(0, 0, 0, 0.5)"
              }
            }
          }
        ]
      };
      let myChart = echarts.init(this.$refs.chartThree);
      myChart.setOption(option);
    },

左下表格

代码定位

在这里插入图片描述
在这里插入图片描述

使用了element的表格 官网手册 : element表格

 <el-table
              id="out-table"//表格id
              v-loading="isLoading"//绑定加载
              height="45vh"//高度
              :data="tables"//数据绑定
              style="width: 100%"
              :default-sort="{ prop: 'total.nowConfirm', order: 'descending' }"
            >//默认排序total.nowConfirm 降序
              <el-table-column prop="sf" label="省份" sortable width="80">
              </el-table-column>
              <el-table-column prop="name" label="城市" sortable width="150">
              </el-table-column>
              <el-table-column
                prop="today.confirm"
                label="新增"
                sortable
                width="100"
              >
              </el-table-column>
              <el-table-column
                prop="total.nowConfirm"
                label="现存"
                width="100"
                sortable
              >
              </el-table-column>
              <el-table-column
                prop="total.grade"
                label="区域风险"
                width="120"
                sortable
              >
              </el-table-column>
              <el-table-column
                prop="total.confirm"
                label="总确诊"
                width="100"
                sortable
              >
              </el-table-column>
              <el-table-column
                prop="total.heal"
                label="治愈"
                width="100"
                sortable
              >
              </el-table-column>
              <el-table-column
                prop="total.dead"
                label="死亡"
                width="100"
                sortable
              >
              </el-table-column>
            </el-table>

表格导出功能

<el-button type="info" @click="exportExcel">导出数据</el-button>
exportExcel() {
      /* out-table关联导出的dom节点  */
      let wbdom = XLSX.utils.table_to_book(document.querySelector("#out-table"));//这里导出id为out-table的
      /* get binary string as output */
      let wbout = XLSX.write(wbdom, {
        bookType: "xlsx",//导出格式
        bookSST: true,
        type: "array"
      });
      try {
        FileSaver.saveAs(
          new Blob([wbout], { type: "application/octet-stream" }),
          "疫情数据.xlsx"//导出文件名
        );
      } catch (e) {
        if (typeof console !== "undefined") console.log(e, wbout);
      }
      return wbout;
    },

全部代码

太多不再展示 有需要去github下载 github地址 https://github.com/dmhsq/vue-epidemic–big-screen 下载地址 https://github.com/dmhsq/vue-epidemic–big-screen/archive/main.zip

  大家好,我是代码哈士奇,是一名软件学院网络工程的学生,因为我是“狗”,狗走千里吃肉。想把大学期间学的东西和大家分享,和大家一起进步。但由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!暂时只在csdn这一个平台进行更新,博客主页:https://blog.csdn.net/qq_42027681。

未经本人允许,禁止转载

在这里插入图片描述
在这里插入图片描述

后续会推出

前端:vue入门 vue开发小程序 等 后端: java入门 springboot入门等 服务器:mysql入门 服务器简单指令 云服务器运行项目 python:推荐不温卜火 一定要看哦 一些插件的使用等

大学之道亦在自身,努力学习,热血青春

继续阅读

更多来自我们博客的帖子

如何安装 BuddyPress
由 测试 December 17, 2023
经过差不多一年的开发,BuddyPress 这个基于 WordPress Mu 的 SNS 插件正式版终于发布了。BuddyPress...
阅读更多
Filter如何工作
由 测试 December 17, 2023
在 web.xml...
阅读更多
如何理解CGAffineTransform
由 测试 December 17, 2023
CGAffineTransform A structure for holding an affine transformation matrix. ...
阅读更多