You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJs+ChartJs实现COVID-19数据可视化失败求助

问题分析与解决方案

咱们一步步来排查你代码里的问题,帮你搞定Chart.js的渲染问题:

1. 异步数据的时序问题

你在useEffect里先调用异步的getData,紧接着就执行setChart——这时候接口请求还没完成,state还是初始的空对象,所以chart里的state.cases、state.deaths全是undefined。而且useEffect的依赖数组是空的,就算后续接口返回数据更新了state,setChart也不会重新执行,图表永远拿不到有效数据。

2. 接口数据结构不匹配

你调用的接口返回的timeline里,cases、deaths这些字段是以日期为键的对象(比如{"1/22/20": 0, "1/23/20": 0,...}),但你直接把整个对象传给Chart.js的data数组,折线图需要的是数值数组,这也会导致渲染失败。


修复后的完整代码

App组件修改

import React, { useState, useEffect } from "react";
import axios from "axios";
import Chart from "./Chart";

const App = () => {
  const [timelineData, setTimelineData] = useState({});
  const [loading, setLoading] = useState(true);
  const [chartData, setChartData] = useState({});

  // 只负责发起数据请求
  useEffect(() => {
    getData("italy");
  }, []);

  // 监听timelineData变化,数据就绪后整理图表格式
  useEffect(() => {
    if (Object.keys(timelineData).length > 0) {
      // 提取日期作为图表的x轴标签
      const dates = Object.keys(timelineData.cases);
      // 提取对应的数据数组
      const cases = Object.values(timelineData.cases);
      const deaths = Object.values(timelineData.deaths);
      const recovered = Object.values(timelineData.recovered);

      setChartData({
        labels: dates,
        datasets: [
          { 
            label: "Cases", 
            data: cases,
            borderColor: "rgb(255, 99, 132)",
            backgroundColor: "rgba(255, 99, 132, 0.2)"
          },
          { 
            label: "Deaths", 
            data: deaths,
            borderColor: "rgb(54, 162, 235)",
            backgroundColor: "rgba(54, 162, 235, 0.2)"
          },
          { 
            label: "Recovered", 
            data: recovered,
            borderColor: "rgb(75, 192, 192)",
            backgroundColor: "rgba(75, 192, 192, 0.2)"
          }
        ]
      });
      setLoading(false);
    }
  }, [timelineData]);

  const getData = async country => {
    try {
      const res = await axios.get(
        `https://corona.lmao.ninja/v2/historical/${country}`
      );
      setTimelineData(res.data.timeline);
    } catch (error) {
      console.log(error.response);
      setLoading(false); // 请求失败也要更新loading状态,避免页面卡死
    }
  };

  return (
    <div>
      {loading ? "Loading data..." : <Chart chart={chartData} />}
    </div>
  );
};

export default App;

Chart组件优化(可选)

可以加个判断,防止数据未就绪时的报错:

import React from "react";
import { Line } from "react-chartjs-2";

const Chart = ({ chart }) => {
  // 如果图表数据未准备好,返回提示
  if (!chart.labels || chart.datasets.length === 0) {
    return <div>Preparing chart...</div>;
  }

  return (
    <div style={{ height: "400px", width: "800px" }}>
      <Line
        data={chart}
        options={{
          maintainAspectRatio: false,
          title: {
            display: true,
            text: "Covid-19 Timeline",
            fontSize: 25
          },
          legend: {
            display: true,
            position: "top"
          }
        }}
      />
    </div>
  );
};

export default Chart;

关键修复说明

  • 拆分useEffect:一个负责发起请求,另一个监听数据变化,确保数据返回后再生成图表配置,解决时序问题。
  • 适配接口数据结构:把日期对象转成数组作为x轴标签,数值对象转成数组作为折线数据,符合Chart.js的要求。
  • 增加错误处理:请求失败时更新loading状态,避免页面一直显示加载中。
  • 添加配色:给每个数据集设置不同颜色,让可视化效果更清晰,和你期望的效果匹配。

这样修改后,你的折线图应该就能正常渲染出COVID-19的时间线数据了。

内容的提问来源于stack exchange,提问作者Hanzlah Tariq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 06:42:47