全国疫情数据统计项目实施



一、新建项目

1.新建 COVID-19/ 文件夹

2.项目目录结构如下

COVID-19/
├── css/
│    └── index.css
├── js/
│    └── index.js
├── lib/
├── data/
└── index.html

二、项目依赖库下载

框架 / 库 官网
Layui https://layuion.com/
ECharts https://echarts.apache.org/zh/index.html
jQuery https://jquery.com/

1.Layui 下载

image-20230104100548964

2.ECharts 下载

在线定制: https://echarts.apache.org/zh/builder.html

image-20230104101006657

3.jQuery下载

下载地址:https://jquery.com/download/

image-20230104101228171

4.复制库/框架至项目 COVID-19/lib/ 文件夹

COVID-19/
├── css/
│    └── index.css
├── js/
│    └── index.js
├── lib/
│    ├── layui/*
│    ├── jquery.js
│    └── echarts.min.js
├── data/
└── index.html

三、基础布局

1.index.html添加如下代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>国内疫情地图</title>
  <link rel="stylesheet" href="./lib/layui/css/layui.css">
</head>
<body>
<div class="layui-layout layui-layout-admin">
  <div class="layui-header">
    <div class="layui-logo layui-hide-xs layui-bg-black">layout demo</div>
    <!-- 头部区域(可配合layui 已有的水平导航) -->
    <ul class="layui-nav layui-layout-left">
      <!-- 移动端显示 -->
      <li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft">
        <i class="layui-icon layui-icon-spread-left"></i>
      </li>

      <li class="layui-nav-item layui-hide-xs"><a href="">nav 1</a></li>
      <li class="layui-nav-item layui-hide-xs"><a href="">nav 2</a></li>
      <li class="layui-nav-item layui-hide-xs"><a href="">nav 3</a></li>
      <li class="layui-nav-item">
        <a href="javascript:;">nav groups</a>
        <dl class="layui-nav-child">
          <dd><a href="">menu 11</a></dd>
          <dd><a href="">menu 22</a></dd>
          <dd><a href="">menu 33</a></dd>
        </dl>
      </li>
    </ul>
    <ul class="layui-nav layui-layout-right">
      <li class="layui-nav-item layui-hide layui-show-md-inline-block">
        <a href="javascript:;">
          <img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" class="layui-nav-img">
          tester
        </a>
        <dl class="layui-nav-child">
          <dd><a href="">Your Profile</a></dd>
          <dd><a href="">Settings</a></dd>
          <dd><a href="">Sign out</a></dd>
        </dl>
      </li>
      <li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
        <a href="javascript:;">
          <i class="layui-icon layui-icon-more-vertical"></i>
        </a>
      </li>
    </ul>
  </div>

  <div class="layui-side layui-bg-black">
    <div class="layui-side-scroll">
      <!-- 左侧导航区域(可配合layui已有的垂直导航) -->
      <ul class="layui-nav layui-nav-tree" lay-filter="test">
        <li class="layui-nav-item layui-nav-itemed">
          <a class="" href="javascript:;">menu group 1</a>
          <dl class="layui-nav-child">
            <dd><a href="javascript:;">menu 1</a></dd>
            <dd><a href="javascript:;">menu 2</a></dd>
            <dd><a href="javascript:;">menu 3</a></dd>
            <dd><a href="">the links</a></dd>
          </dl>
        </li>
        <li class="layui-nav-item">
          <a href="javascript:;">menu group 2</a>
          <dl class="layui-nav-child">
            <dd><a href="javascript:;">list 1</a></dd>
            <dd><a href="javascript:;">list 2</a></dd>
            <dd><a href="">超链接</a></dd>
          </dl>
        </li>
        <li class="layui-nav-item"><a href="javascript:;">click menu item</a></li>
        <li class="layui-nav-item"><a href="">the links</a></li>
      </ul>
    </div>
  </div>

  <div class="layui-body">
    <!-- 内容主体区域 -->
    <div style="padding: 15px;">内容主体区域。记得修改 layui.css 和 js 的路径</div>
  </div>

  <div class="layui-footer">
    <!-- 底部固定区域 -->
    底部固定区域
  </div>
</div>
<script src="./lib/layui/layui.js"></script>
<script>
//JS 
layui.use(['element', 'layer', 'util'], function(){
  var element = layui.element
  ,layer = layui.layer
  ,util = layui.util
  ,$ = layui.$;

  //头部事件
  util.event('lay-header-event', {
    //左侧菜单事件
    menuLeft: function(othis){
      layer.msg('展开左侧菜单的操作', {icon: 0});
    }
    ,menuRight: function(){
      layer.open({
        type: 1
        ,content: '<div style="padding: 15px;">处理右侧面板的操作</div>'
        ,area: ['260px', '100%']
        ,offset: 'rt' //右上角
        ,anim: 5
        ,shadeClose: true
      });
    }
  });

});
</script>
</body>
</html>

2.浏览器预览效果

image-20230104102020785

3.修改 index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>国内疫情地图</title>
  <link rel="stylesheet" href="./lib/layui/css/layui.css">
</head>
<body>
<div class="layui-layout layui-layout-admin">
  <div class="layui-header">
    <div class="layui-logo layui-hide-xs layui-bg-black">COVID-19</div>
    <!-- 头部区域(可配合layui 已有的水平导航) -->
    <ul class="layui-nav layui-layout-left">
      <!-- 移动端显示 -->
      <li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft">
        <i class="layui-icon layui-icon-spread-left"></i>
      </li>
    </ul>
    <ul class="layui-nav layui-layout-right">
      <li class="layui-nav-item layui-hide layui-show-md-inline-block">
        <a href="javascript:;">
          <img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" class="layui-nav-img">
          tester
        </a>
        <dl class="layui-nav-child">
          <dd><a href="">Your Profile</a></dd>
          <dd><a href="">Settings</a></dd>
          <dd><a href="">Sign out</a></dd>
        </dl>
      </li>
      <li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
        <a href="javascript:;">
          <i class="layui-icon layui-icon-more-vertical"></i>
        </a>
      </li>
    </ul>
  </div>

  <div class="layui-side layui-bg-black">
    <div class="layui-side-scroll">
      <!-- 左侧导航区域(可配合layui已有的垂直导航) -->
      <ul class="layui-nav layui-nav-tree" lay-filter="test">
        <li class="layui-nav-item layui-this"><a href="map.html">国内疫情地图</a></li>
      </ul>
    </div>
  </div>

  <div class="layui-body">
    <!-- 内容主体区域 -->
    <div style="padding: 15px">
      <!-- 疫情地图 -->
      <div id="main" style="height:600px"></div>
    </div>
  </div>
</div>

<script src="./lib/layui/layui.js"></script>
<script src="./lib/jquery-3.5.1.js"></script>
<script>
  layui.use(['element', 'jquery', 'layer'], function(){
    var element = layui.element;
    var $ = layui.$

    console.log($)
  });
</script>
</body>
</html>

image-20230104102711954

四、地图准备

1.准备div显示地图

<!-- ... -->
  <div class="layui-body">
    <!-- 内容主体区域 -->
    <div style="padding: 15px">
      <!-- 疫情地图 -->
      <div id="main" style="height:600px"></div>
    </div>
  </div>
<!-- ... -->

2.引入Echarts

<script src="./lib/layui/layui.js"></script>
<script src="./lib/jquery-3.5.1.js"></script>
<!-- 引入echarts.min.js -->
<script src="./lib/echarts.min.js"></script>
<!-- 引入china.js -->
<script src="./lib/china.js"></script>

<script src="./lib/index.js"></script>

3.添加地图配置项

修改 index.js

// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById("main"));
// 绘制图表
myChart.setOption({
  tooltip:{
    triggerOn:'mousemove',  // 提示框触发
    enterable:true,
    formatter(item){
      return item.name + ":" + item.value
    }
  },
  visualMap:[{
    orient:"horizontal",
    type:"piecewise",
    bottom:0,
    itemGap:6,
    itemWidth:16,
    itemHeight:10,
    padding:2,
    textStyle:{
      fontSize:10
    },
    pieces:[  // 配置颜色区间
      {
        min:0,
        max:0,
        color:"#ffffff"
      },
      {
        min:1,
        max:10,
        color:"#fdfdcf"
      },
      {
        min:10,
        max:100,
        color:"#fe9e83"
      },
      {
        min:100,
        max:1000,
        color:"#e55a4e"
      },
      {
        min:1000,
        color:"#a42626"
      }
    ]
  }],
  series: [{
    name: '省',
    type: 'map',
    mapType: 'china',
    roam: false,
    zoom: 1.2,
    aspectScale: 0.75,
    top: 60,
    layoutCenter: ['5%', '5%'],
    label: {
      normal: {
        show: true,
        textStyle: {
          fontSize: 10
        }
      },
      itemStyle: {
        normal: {
          normal: {
            areaColor: 'rgba(0,255,236,0)',
            borderColor: 'rgba(0,0,0,0.2)'
          },
          emphasis: {
            areaColor: "rgba(255,180,0,0.8)",
            shadowOffsetX: 0,
            shadowOffsetY: 0,
            shadowBlur: 20,
            borderWidth: 0,
          }
        },
      }
    },
    data:[
      {name:'内蒙古',value:200},
      {name:'北京',value:800}
    ]
  }]
});

layui.use(['element', 'jquery', 'layer'], function(){
  var element = layui.element;
  var $ = layui.$

  console.log($)
});

4.预览效果

image-20230104103549158

五、获取疫情数据

1.保存DataAPI到本地

浏览器打开: https://c.m.163.com/ug/api/wuhan/app/data/list-total,然后按下 ctrl + s 键将数据保存为json文件,然后将 list-total.json 文件复制到项目 data/ 文件夹。

image-20230104103926892

2.使用Ajax数据请求

layui.use(['element', 'jquery', 'layer'], function(){
  var element = layui.element;
  var $ = layui.$

  // 现存确诊
  $.ajax({
    url: './data/list-total.json',
    success(res) {
      let china = res.data.areaTree.find(item => item.name === '中国')
      let citys = china.children
      let arr = citys.map(item => ({
        name: item.name,
        value: item.today.confirm
      }))


      // 基于准备好的dom,初始化echarts实例
      var myChart = echarts.init(document.getElementById("main"));
      // 绘制图表
      myChart.setOption({
        tooltip:{
          triggerOn:'mousemove',  // 提示框触发
          enterable:true,
          formatter(item){
            return item.name + ":" + item.value
          }
        },
        visualMap:[{
          orient:"horizontal",
          type:"piecewise",
          bottom:0,
          itemGap:6,
          itemWidth:16,
          itemHeight:10,
          padding:2,
          textStyle:{
            fontSize:10
          },
          pieces:[  // 配置颜色区间
            {
              min:0,
              max:0,
              color:"#ffffff"
            },
            {
              min:1,
              max:10,
              color:"#fdfdcf"
            },
            {
              min:10,
              max:100,
              color:"#fe9e83"
            },
            {
              min:100,
              max:1000,
              color:"#e55a4e"
            },
            {
              min:1000,
              color:"#a42626"
            }
          ]
        }],
        series: [{
          name: '省',
          type: 'map',
          mapType: 'china',
          roam: false,
          zoom: 1.2,
          aspectScale: 0.75,
          top: 60,
          layoutCenter: ['5%', '5%'],
          label: {
            normal: {
              show: true,
              textStyle: {
                fontSize: 10
              }
            },
            itemStyle: {
              normal: {
                normal: {
                  areaColor: 'rgba(0,255,236,0)',
                  borderColor: 'rgba(0,0,0,0.2)'
                },
                emphasis: {
                  areaColor: "rgba(255,180,0,0.8)",
                  shadowOffsetX: 0,
                  shadowOffsetY: 0,
                  shadowBlur: 20,
                  borderWidth: 0,
                }
              },
            }
          },
          data: arr
        }]
      });
    }
  })
});

image-20230104104911550

六、添加选项卡

1.修改 index.html 页面

  <div class="layui-body">
    <!-- 内容主体区域 -->
    <div style="padding: 15px" class="layui-tab layui-tab-brief" lay-filter="map">
      <ul class="layui-tab-title">
        <li lay-id="today" class="layui-this">现存确诊</li>
        <li lay-id="total">累计确诊</li>
      </ul>
      <div class="layui-tab-content">
        <div class="layui-tab-item layui-show">
          <div id="main" style="height:600px"></div>
        </div>
        <div class="layui-tab-item">
          <div id="allMain" style="height:600px"></div>
        </div>
      </div>
    </div>
  </div>

2.添加监听选项卡切换的事件

  element.on('tab(map)', function(){
    const layId = this.getAttribute('lay-id')
    switch(layId){
      case 'total': // 累计确诊
        console.log('累计确诊')
        break
      case 'today': // 现存确诊
        console.log('现存确诊')
        break
    }
  });

3.完善 index.js

function chinaMap(id, data) {
  // 基于准备好的dom,初始化echarts实例
  var myChart = echarts.init(document.getElementById(id));
  // 绘制图表
  myChart.setOption({
    tooltip:{
      triggerOn:'mousemove',  // 提示框触发
      enterable:true,
      formatter(item){
        return item.name + ":" + item.value
      }
    },
    visualMap:[{
      orient:"horizontal",
      type:"piecewise",
      bottom:0,
      itemGap:6,
      itemWidth:16,
      itemHeight:10,
      padding:2,
      textStyle:{
        fontSize:10
      },
      pieces:[  // 配置颜色区间
        {
          min:0,
          max:0,
          color:"#ffffff"
        },
        {
          min:1,
          max:10,
          color:"#fdfdcf"
        },
        {
          min:10,
          max:100,
          color:"#fe9e83"
        },
        {
          min:100,
          max:1000,
          color:"#e55a4e"
        },
        {
          min:1000,
          color:"#a42626"
        }
      ]
    }],
    series: [{
      name: '省',
      type: 'map',
      mapType: 'china',
      roam: false,
      zoom: 1.2,
      aspectScale: 0.75,
      top: 60,
      layoutCenter: ['5%', '5%'],
      label: {
        normal: {
          show: true,
          textStyle: {
            fontSize: 10
          }
        },
        itemStyle: {
          normal: {
            normal: {
              areaColor: 'rgba(0,255,236,0)',
              borderColor: 'rgba(0,0,0,0.2)'
            },
            emphasis: {
              areaColor: "rgba(255,180,0,0.8)",
              shadowOffsetX: 0,
              shadowOffsetY: 0,
              shadowBlur: 20,
              borderWidth: 0,
            }
          },
        }
      },
      // data:[
      //   {name:'内蒙古',value:200},
      //   {name:'北京',value:800}
      // ]
      data
    }]
  });
}

layui.use(['element', 'jquery', 'layer'], function(){
  var element = layui.element;
  var $ = layui.$

  // 现存确诊
  $.ajax({
    url: './data/list-total.json',
    success(res) {
      let china = res.data.areaTree.find(item => item.name === '中国')
      let citys = china.children
      let arr = citys.map(item => ({
        name: item.name,
        value: item.today.confirm
      }))
      chinaMap('main', arr)
    }
  })

  element.on('tab(map)', function(){
    const layId = this.getAttribute('lay-id')
    switch(layId){
      case 'total': // 累计确诊
        $.ajax({
          url: './data/list-total.json',
          success(res) {
            let china = res.data.areaTree.find(item => item.name === '中国')
            let citys = china.children
            let allArr = citys.map(item => ({
              name: item.name,
              value: item.total.confirm
            }))
            chinaMap('allMain', allArr)
          }
        })
        break
      case 'today': // 现存确诊
        $.ajax({
          url: './data/list-total.json',
          success(res) {
            let china = res.data.areaTree.find(item => item.name === '中国')
            let citys = china.children
            let arr = citys.map(item => ({
              name: item.name,
              value: item.today.confirm
            }))
            chinaMap('main', arr)
          }
        })
        break
    }
  });
});

现存确诊:

image-20230104105617755

累计确诊:

image-20230104105705420

七、拓展 - 世界疫情统计

1.创建 world.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>世界疫情</title>
  <link rel="stylesheet" href="./lib/layui/css/layui.css">
</head>
<body>
<div class="layui-layout layui-layout-admin">
  <div class="layui-header">
    <div class="layui-logo layui-hide-xs layui-bg-black">COVID-19</div>
    <!-- 头部区域(可配合layui 已有的水平导航) -->
    <ul class="layui-nav layui-layout-left">
      <!-- 移动端显示 -->
      <li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft">
        <i class="layui-icon layui-icon-spread-left"></i>
      </li>
    </ul>
    <ul class="layui-nav layui-layout-right">
      <li class="layui-nav-item layui-hide layui-show-md-inline-block">
        <a href="javascript:;">
          <img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" class="layui-nav-img">
          tester
        </a>
        <dl class="layui-nav-child">
          <dd><a href="">Your Profile</a></dd>
          <dd><a href="">Settings</a></dd>
          <dd><a href="">Sign out</a></dd>
        </dl>
      </li>
      <li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
        <a href="javascript:;">
          <i class="layui-icon layui-icon-more-vertical"></i>
        </a>
      </li>
    </ul>
  </div>

  <div class="layui-side layui-bg-black">
    <div class="layui-side-scroll">
      <!-- 左侧导航区域(可配合layui已有的垂直导航) -->
      <ul class="layui-nav layui-nav-tree" lay-filter="test">
        <li class="layui-nav-item"><a href="map.html">国内疫情地图</a></li>
        <li class="layui-nav-item layui-this"><a href="word.html">世界疫情</a></li>
      </ul>
    </div>
  </div>

  <div class="layui-body">
    <!-- 内容主体区域 -->
    <div style="padding: 15px" id="content"></div>
  </div>

  <div class="layui-footer">
    <!-- 底部固定区域 -->
    底部固定区域
  </div>
</div>

<script id="info" type="text/html">
  <!-- ... -->
</script>

<script src="./lib/layui/layui.js"></script>
<script src="./lib/jquery-3.5.1.js"></script>
<script src="./js/index.js"></script>
</body>
</html>

2.创建 js/world.js

layui.use(['element', 'jquery', 'layer', 'laytpl'], function(){
  var element = layui.element;
  var $ = layui.$
  var laytpl = layui.laytpl;

  // 默认的现存确诊
  $.ajax({
    url: './data/list-total.json',
    success(res) {
      var contentView = document.getElementById('content')
      var getTpl = info.innerHTML

      laytpl(getTpl).render({
        list: res.data.areaTree.sort((a, b) => b.total.confirm - a.total.confirm)
      }, function(html){
        contentView.innerHTML = html;
      });
    }
  })
});

3.预览效果

image-20230104110023233