简体   繁体   English

如何使用 API 数据正确更新 React & Chart.js 应用程序中的图表

[英]How to properly update chart in React & Chart.js app using API data

I am receiving data from an API and I want to take that data and have it populate my chart.我正在从 API 接收数据,我想获取该数据并将其填充到我的图表中。 I can see where the API data is being called and is being passed into setState but I cannot seem to correctly take this data and pass it to my chart.我可以看到 API 数据在哪里被调用并被传递到 setState 但我似乎无法正确获取这些数据并将其传递给我的图表。

I have tried using the destroy() and update() methods for Chart.js to no avail.我曾尝试对 Chart.js 使用 destroy() 和 update() 方法,但无济于事。 I'm sure it is just a matter of me not using them correctly within my app.我确定这只是我没有在我的应用程序中正确使用它们的问题。 The code below does not include those methods since I wasn't sure where to use them.下面的代码不包括这些方法,因为我不确定在哪里使用它们。 I have also tried pushing the API data into the data array for the chart with no luck.我还尝试将 API 数据推送到图表的数据数组中,但没有成功。

componentDidMount() {
// create chart 
          new Chart(myChartRef, {
      type: "line",
      data: {
        labels: ["Jan", "Feb", "March"],
        datasets: [
          {
            data: this.state.chartData,
            backgroundColor: gradient,
            pointBackgroundColor: "#fff",
            pointBorderColor: gradient,
            pointRadius: "5",
            hoverBackgroundColor: "#75C6FF",
            hoverBorderColor: gradient
          }
        ]
      },
      options: {
        responsive: true,
        legend: {
          display: false
        },
        scales: {
          xAxes: [
            {
              gridLines: {
                color: "#535356"
              },
              ticks: {
                fontColor: "#87889C"
              }
            }
          ],
          yAxes: [
            {
              gridLines: {
                color: "#535356"
              },
              ticks: {
                fontColor: "#87889C"
              }
            }
          ]
        }
      }
    });
/* fetch API data and use it to set app state (setState) */
    const getChartData = () => {
      fetch(
        "https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC,ETH&tsyms=USD"
      )
        .then(response => {
          return response.json();
        })
        .then(myJson => {
          const bitcoinPrice = myJson.BTC.USD;
          this.setState({ chartData: bitcoinPrice });
          console.log(JSON.stringify(myJson));
        });
    };

    getChartData();
}

In the code I create a new chart once the component is mounted.在代码中,一旦安装了组件,我就会创建一个新图表。 Then I call the API and receive the data which I want to display on my chart.然后我调用 API 并接收我想在图表上显示的数据。 I can see in the React dev tools that the state is being set in my app but the chart does not update.我可以在 React 开发工具中看到状态正在我的应用程序中设置,但图表没有更新。 I assume I need to do something like map the API data into the data array in the chart but I'm not sure how to do this properly and I have had no luck with the other solutions suggested on SO or anywhere else online.我假设我需要做一些事情,比如将 API 数据映射到图表中的数据数组,但我不知道如何正确地做到这一点,而且我对 SO 或其他任何在线地方建议的其他解决方案没有运气。

This is my first React app so I'm not sure if I'm doing something wrong in React or in Chart.js?这是我的第一个 React 应用程序,所以我不确定我是在 React 还是 Chart.js 中做错了什么?

From my experience, you can separate chart component and chart container. 根据我的经验,您可以将图表组件和图表容器分开。 Make fetching in chart container and pass the fetched data as props to your chart component for better organization of code. 在图表容器中进行获取,并将获取的数据作为道具传递给图表组件,以更好地组织代码。

Also you need to check if props are changed with componentWillReceiveProps lifecycle method inside chart component and update the chart accordingly 另外,您还需要检查图表组件内部的componentWillReceiveProps生命周期方法是否更改了道具,并相应地更新了图表

  1. Create a component called ChartContainer.js and pass chartData to ChartComponent as props 创建一个名为ChartContainer.js的组件,并将chartData作为道具传递给ChartComponent
import React, { Component } from 'react';
import ChartComponent from './ChartComponent'

export class ChartContainer extends Component {

  constructor(props) {
    super(props);
    this.state = {
      chartData: []
    }

  componentDidMount() {
    fetch(
        "https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC,ETH&tsyms=USD"
      )
        .then(response => {
          return response.json();
        })
        .then(myJson => {
          const bitcoinPrice = myJson.BTC.USD;
          this.setState({ chartData: bitcoinPrice });
          console.log(JSON.stringify(myJson));
        });
  }

  render() {
    const { chartData } = this.state;
    return (
        <ChartComponent chartData={chartData}/ >
    );
  }

}
  1. Create a component called ChartComponent and get chartData as props. 创建一个名为ChartComponent的组件并获取chartData作为道具。 Also make a state called chart and set the chart to the state and update the chart with componentWillReceiveProps lifecycle to update the chart. 还创建一个名为chart的状态,并将该图表设置为该状态,并使用componentWillReceiveProps生命周期更新该图表以更新该图表。
import React, { Component } from 'react';

export class ChartComponent extends Component {

  constructor(props){
    super(props)
    this.state = { chart : null }
  }

  chart = React.createRef();

  componentDidMount(){
    // pass chartData to Chart below as this.props.chartData
    let theChart = new Chart(...)
    // set chart to state
    this.setState({ chart: theChart })
  }

  componentWillReceiveProps(nextProps, nextContext) {
    // update chart according to prop change
      this.state.chart.data.datasets.forEach((dataset) => {
        dataset.data.push(nextProps.chartData);
      });
      this.state.chart.update();
  }

  render(){
    return (
        <canvas id="myChart" ref={this.chart} />
    );
  }

};

When props changed, ChartComponent is not refreshed.当 props 改变时,ChartComponent 不会刷新。 To make it work use redraw={true}要使其工作,请使用 redraw={true}

<ChartComponent type={chartType} {...someConfig} redraw={true}/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM