大数据可视化统计2020年世界疫情练习(vue3+Echarts)保姆级

一、创建vue3项目

使用 npm init vite@latest来创建项目

 npm init vite@latest

根据给出提示依次输入

可得到以下内容

二、创建所需文件夹及文件+模块引入

(一)、创建所需文件夹及文件

文件夹下有多余的文件一定要删除

1.打开“src”文件夹,在里面打开"components"文件夹,然后在该文件夹下创建"counepidemic.vue"文件 + "epidemicEch"文件夹,

2.在"epidemicEch"文件夹下创建“coun.vue”文件

3.在src文件夹下创建“router”文件夹,在该文件夹下创建“index.js”文件

4.在src文件夹下创建“vuexm”文件夹,在该文件夹下创建“index.vue”文件

5.在src文件夹下的assets文件夹下创建“json”文件夹

(二)、模块引入

分别输入以下两个命令下载“路由配置”模块和“Echarts图表”模块

路由配置:

npm install vue-router

Echarts图表

npm install echarts

三、路由配置

1、打开src文件夹下的“router”文件夹,

2、打开该文件夹下的“index.js”文件

index.js文件,代码如下

import {createRouter,createWebHashHistory} from 'vue-router'
const routes=[
    {
        path:'/index',
        name:'index',
        component:()=>import('../vuexm/index.vue')
    },
    {
        path:'/',
        redirect:'/index'
    }
]
const router=createRouter({
    history:createWebHashHistory(),
    routes
})
export default router

3、打开src文件夹下的“vuexm”文件夹,

4、打开该文件夹下的“index.vue”文件

index.vue文件,代码如下

<script setup>
import { ref,reactive } from "vue";
import counepidemic from '../components/counepidemic.vue'
</script>

<template>
    <div style="text-align: center; font-size: 30px;">2020年世界疫情统计</div>
    <div>
            <counepidemic />
    </div>
</template>

<style scoped>

</style>

5、打开如图所示的“main.js”文件

main.js文件,代码如下

import { createApp } from 'vue'
// import './style.css'
import App from './App.vue'
import router from './router/index.js'

createApp(App).use(router).mount('#app')

6.打开“src”文件夹,在里面打开"components"文件夹,然后在该文件夹下打开"counepidemic.vue"文件

counepidemic.vue文件,代码如下

<script setup>
import { ref,reactive } from "vue";
import count from './epidemicEch/coun.vue'
</script>

<template>
        <count />
</template>

<style scoped>

</style>

这里为了省去手动进入网页,如图进入“vite.config.js”文件,然后进行编译

“vite.config.js”文件,代码如下

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vite.dev/config/
export default defineConfig({
  server:{
    open:true
  },
  plugins: [vue()],
})

四、获取json数据

提取码:KITE

2020年世界疫情json数据官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘123云盘为您提供2020年世界疫情json数据最新版正式版官方版绿色版下载,2020年世界疫情json数据安卓版手机版apk免费下载安装到手机,支持电脑端一键快捷安装https://www.123684.com/s/wN86Vv-R0LD3?提取码:KITE

把json数据文件放入“src”文件夹下的“assets”文件夹下的“json”文件夹里

五、开始编写可视化

1、打开“src”文件夹下的“components”文件夹

2、打开“components”文件夹下的“epidemicEch”文件夹

3、打开“epidemicEch”文件夹下的“coun.vue”文件

“coun.vue”文件,代码如下

<script setup>
// 引入Vue响应式函数和生命周期钩子
import { ref, onMounted, onBeforeUnmount } from "vue";
// 引入ECharts库和疫情数据集
import * as echarts from 'echarts';
import vcount from '../../assets/json/countrydata.json';

// 控制台输出原始数据结构
console.log("世界2020年疫情统计数据:",vcount);

// 图表DOM引用和ECharts实例
const chartRef = ref(null);
let myChart = null;


//  数据处理函数:将原始JSON数据转换为图表需要的格式
//  @returns {Object} 包含日期、累计确诊、当前确诊数据的对象
 
const processData = () => {
  return vcount.RECORDS.reduce((acc, curr) => {
    // 日期格式转换:将数字日期转换为YYYY-MM-DD格式
    const dateStr = curr.dateId.toString();
    const formattedDate = `${dateStr.slice(0,4)}-${dateStr.slice(4,6)}-${dateStr.slice(6,8)}`;
    
    // 存储结构化数据,保留原始数据维度
    acc.dates.push({
      date: formattedDate,        // 完整日期
      country: curr.countryName,  // 国家名称
      continent: curr.continent   // 所属大洲
    });
    
    // 累计确诊数据(带元数据)
    acc.confirmed.push({
      value: parseInt(curr.confirmedCount),
      country: curr.countryName,
      continent: curr.continent
    });
    
    // 当前确诊数据(带元数据)
    acc.current.push({
      value: parseInt(curr.currentConfirmedCount),
      country: curr.countryName,
      continent: curr.continent
    });

    return acc;
  }, { dates: [], confirmed: [], current: [] }); // 初始值包含三个数据集合
};


// 自定义Tooltip格式化函数
// @param {Array} params - ECharts提示框参数数组
// @returns {string} HTML格式的提示框内容
 
const tooltipFormatter = (params) => {
  const dataPoint = params[0];
  return `
    <div style="padding: 10px; background: #fff; border-radius: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.1)">
      <div style="font-size: 14px; color: #666; margin-bottom: 8px">
        ${dataPoint.axisValueLabel} <!-- 显示x轴值(月-日) -->
      </div>
      <div style="display: flex; align-items: center; margin-bottom: 4px">
        <span style="display: inline-block; width: 48px; color: #999">国家:</span>
        <span style="color: #5470c6; font-weight: 500">${dataPoint.data.country}</span>
      </div>
      <div style="display: flex; align-items: center; margin-bottom: 12px">
        <span style="display: inline-block; width: 48px; color: #999">大洲:</span>
        <span style="color: #91cc75; font-weight: 500">${dataPoint.data.continent}</span>
      </div>
      ${params.map(item => `
        <div style="display: flex; align-items: center; margin: 4px 0">
          ${item.marker} <!-- ECharts颜色标记 -->
          <span style="margin-left: 6px; color: #666">${item.seriesName}:</span>
          <span style="margin-left: 8px; font-weight: 500">${item.data.value} 例</span>
        </div>
      `).join('')}
    </div>
  `;
};


//  初始化ECharts图表配置

const initChart = () => {
  if (!chartRef.value) return;
  
  // 获取处理后的结构化数据
  const { dates, confirmed, current } = processData();
  
  // ECharts配置项
  const option = {
    title: {
      text: '世界疫情趋势分析',
      left: 'center',
      textStyle: {
        fontSize: 18,
        color: '#333'
      }
    },
    tooltip: {
      trigger: 'axis',          // 触发类型为坐标轴触发
      formatter: tooltipFormatter, // 使用自定义提示框
      backgroundColor: 'transparent',
      borderWidth: 0,
      extraCssText: 'box-shadow: 0 4px 12px rgba(0,0,0,0.12);' // 自定义阴影效果
    },
    legend: {
      data: ['累计确诊', '当前确诊'], // 图例项
      top: 40,                      // 距离顶部距离
      itemWidth: 16,                // 图例标记宽度
      itemHeight: 8,                // 图例标记高度
      textStyle: {
        color: '#666'
      }
    },
    xAxis: {
      type: 'category',
      data: dates.map(d => ({
        value: d.date.split('-').slice(1).join('-'), // 显示月-日格式
        country: d.country,
        continent: d.continent
      })),
      axisLabel: {
        rotate: 45,                 // 标签旋转角度
        formatter: (params) => params.value,
        margin: 15,                 // 标签与轴线间距
        color: '#666'
      },
      axisLine: {
        lineStyle: {
          color: '#eee'             // 轴线颜色
        }
      }
    },
    yAxis: {
      type: 'value',
      name: '病例数',              // 坐标轴名称
      nameTextStyle: {
        color: '#666',
        padding: [0, 0, 10, 0]     // 名称位置偏移
      },
      axisLabel: {
        color: '#666'
      },
      splitLine: {
        lineStyle: {
          color: '#f5f5f5'         // 分割线颜色
        }
      }
    },
    series: [
      { // 累计确诊折线图配置
        name: '累计确诊',
        type: 'line',
        data: confirmed,
        smooth: true,              // 平滑曲线
        symbol: 'circle',          // 数据点形状
        symbolSize: 8,
        lineStyle: {
          color: '#5470c6',        // 线条颜色
          width: 3
        },
        areaStyle: {               // 区域填充样式
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: '#5470c620' }, // 渐变起始颜色
            { offset: 1, color: '#5470c605' }  // 渐变结束颜色
          ])
        },
        emphasis: {                // 高亮样式
          focus: 'series',
          itemStyle: {
            color: '#5470c6',
            borderWidth: 2
          }
        }
      },
      { // 当前确诊柱状图配置
        name: '当前确诊',
        type: 'bar',
        data: current,
        itemStyle: {
          color: '#91cc75',        // 柱条颜色
          borderRadius: [2, 2, 0, 0] // 顶部圆角
        },
        barWidth: '40%',           // 柱条宽度
        emphasis: {
          itemStyle: {
            color: '#82c061'       // 高亮颜色
          }
        }
      }
    ],
    dataZoom: [{                  // 内置型数据区域缩放
      type: 'inside',
      start: 0,
      end: 100,
      zoomLock: true              // 锁定选择区域不可拉伸
    }],
    grid: {                       // 图表布局配置
      top: 100,                   // 距离顶部距离
      bottom: 80,                // 留出x轴标签空间
      left: 60,                  // y轴标签空间
      right: 30
    }
  };

  // 初始化ECharts实例并设置配置
  myChart = echarts.init(chartRef.value);
  myChart.setOption(option);
};

// 生命周期管理
onMounted(() => {
  initChart();
  // 添加窗口resize监听,自适应图表大小
  window.addEventListener('resize', () => myChart?.resize());
});

onBeforeUnmount(() => {
  // 组件卸载前移除监听并销毁实例
  window.removeEventListener('resize', () => myChart?.resize());
  myChart?.dispose();
});
</script>

<template>
  <!-- 图表容器 -->
  <div class="chart-container">
    <!-- ECharts DOM元素,通过ref绑定 -->
    <div ref="chartRef" style="width: 100%; height: 640px;"></div>
  </div>
</template>

<style scoped>
/* 容器样式 */
.chart-container {
  padding: 24px;                 /* 内边距 */
  background: white;             /* 背景色 */
  border-radius: 8px;            /* 圆角半径 */
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); /* 阴影效果 */
  transition: box-shadow 0.3s;  /* 过渡动画 */

  /* 悬停效果 */
  &:hover {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  }
}
</style>

最后,如图打开App.vue文件

App.vue文件,代码如下

<script setup>
import {ref,reactive} from 'vue'
</script>

<template>
<router-view />
</template>

<style scoped>

</style>

六、验证结果

输入"npm run dev"命令验证结果

npm run dev

结果如下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值