reactjs React ChartJS,空白白色(无错误)

falq053o  于 2023-03-29  发布在  React
关注(0)|答案(1)|浏览(127)

我试图在react页面中显示SPY的每日回报,并将其显示在ChartJS图形上。我使用的是Chart JS和Alphavantage的API调用。我使用以下代码。我没有收到任何错误,但我看到的只是一个空白的白色屏幕。
我已经输入了我的API密钥。

import React, { useEffect, useState } from "react";
import { Chart } from "chart.js";

const SPYChart = () => {
  const [chartData, setChartData] = useState({});

  useEffect(() => {
    const fetchSPYData = async () => {
      const response = await fetch(
        "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=SPY&outputsize=compact&apikey=<My Api has been inserted>"
      );
      const data = await response.json();
      const dailyReturns = calculateDailyReturns(data["Time Series (Daily)"]);
      const labels = Object.keys(dailyReturns);
      const values = Object.values(dailyReturns);
      setChartData({
        labels: labels,
        datasets: [
          {
            label: "Daily Percentage Returns of SPY",
            data: values,
            borderColor: "#3e95cd",
            fill: false,
          },
        ],
      });
    };

    const calculateDailyReturns = (data) => {
      const closePrices = Object.values(data).map((item) =>
        parseFloat(item["4. close"])
      );
      const dailyReturns = {};
      for (let i = 1; i < closePrices.length; i++) {
        const todayReturn =
          (closePrices[i] - closePrices[i - 1]) / closePrices[i - 1];
        dailyReturns[Object.keys(data)[i]] = todayReturn;
      }
      return dailyReturns;
    };

    fetchSPYData();
  }, []);

  useEffect(() => {
    const ctx = document.getElementById("SPYChart");
    new Chart(ctx, {
      type: "line",
      data: chartData,
      options: {
        responsive: true,
        title: {
          display: true,
          text: "Daily Percentage Returns of SPY",
        },
        scales: {
          xAxes: [
            {
              type: "time",
              time: {
                unit: "day",
                displayFormats: {
                  day: "MMM D",
                },
              },
              ticks: {
                maxTicksLimit: 10,
              },
            },
          ],
          yAxes: [
            {
              ticks: {
                callback: function (value, index, values) {
                  return (value * 100).toFixed(2) + "%";
                },
              },
            },
          ],
        },
      },
    });
  }, [chartData]);

  return (
    <div>
      <canvas id="SPYChart" width="100" height="100"></canvas>
    </div>
  );
};

export default SPYChart;

我尝试输入基本的样板线图Chart JS代码,它已经工作了。所以我知道问题出在这里的代码上,而不是react应用程序的其他部分。当我注解掉这段代码时,我得到了我期望的显示(减去图形)。

mwg9r5ms

mwg9r5ms1#

你忽略了一些重要的问题。
1.我不知道你使用的chart.js的版本。但是在v4中,你需要注册可注册项:

import { Chart, registerables } from "chart.js";
    ...
    Chart.register(...registerables);
    ...

1.在react中,我们使用ref来访问canvas元素:

import { useRef } from react;

function MyChart() {
  const [canvasElRef, setCanvasElRef] = useRef(null)

  ...

  return (
    <canvas ref={canvasElRef} />
  )
}
  1. chart.js的canvas元素需要一个 Package 器,canvas元素必须有一个初始尺寸来维持响应大小(不要忘记chart选项中的maintainAspectRatio: false
function MyChart() {
  ...  
    options: {
      responsive: true,
      maintainAspectRatio: false,
      ...
    }
  ...

  return (
    <div style={{ width: "100vw", height: "100vh" }}>  <--- use your own styling
      <canvas ref={canvasElRef} width="600" height="350" />
    </div>
  );
}

1.在创建Chart示例之前,您需要确保data和canvas元素可用。在这里,您必须将示例保持为ref,以便在卸载/清理过程发生时,我们可以将其用作销毁图表示例的参考

const [chartRef, setChartRef] = useRef(null)

  ...

  useEffect(() => {
    if (chartData && canvasElRef.current) {
      chartRef.current = new Chart(canvasElRef.current, {

      }
    }

    return () => {
      if (chartRef.current) {
        chartRef.current.destroy();
        chartRef.current = null;
      }
    }
  }

1.在v4中,标题现在是plugins的一部分:

options: {
    ...
    plugins: {
      title: {
        display: true,
        text: "Daily Percentage Returns of SPY",
      },
    },
  }
  1. Chartjs moment adapter是使用时间序列图时最重要的东西。所以你需要在导入chart.js后再导入它
import { useCallback, useEffect, useState, useRef } from "react";
import { ChartData, Chart, registerables } from "chart.js";
import "chartjs-adapter-moment";  <---- import here

Chart.register(...registerables);

最后,您可以检查最终代码here

相关问题