简体   繁体   English

如何在 React 中将数据传递给 Chart.js 图表

[英]How to pass data to a Chart.js chart in React

I'm working on a project and in this project you can type the amount of money you spent in a week(I have Groceries, Shopping, Health and Home Needs inputs), and it calculates the total amount adding it to a component.我正在做一个项目,在这个项目中,您可以输入一周内花费的金额(我有杂货、购物、健康和家庭需求输入),它会计算将其添加到组件中的总金额。 Another feature inside this project is a chart made with Chart.js and it should display the amounts of money spended with groceries, shopping, health and home needs.该项目的另一个功能是使用 Chart.js 制作的图表,它应该显示在杂货、购物、健康和家庭需求上花费的金额。 But I'm having trouble with this part.但我在这部分遇到了麻烦。 I'm trying to pass the data stored in the controlled inputs by props, but the data is not being displayed in the chart.我正在尝试通过道具传递存储在受控输入中的数据,但数据未显示在图表中。 Can someone help me with that?有人可以帮我吗? Here's the code:这是代码:

 import React from "react";

import Header from "./Header";
import InputComponent from "./InputComponent";
import AmountCard from "./AmountCard";

import BillChart from "./BillsChart";

class SpendsApp extends React.Component {
constructor(props) {
 super(props);
 this.state = {
   groceries: 10,
   shopping: 0,
   health: 0,
   houseNeeds: 0,
   total: 0,
   chartData: []
 };
 this.handleChange = this.handleChange.bind(this);
 this.handleSubmit = this.handleSubmit.bind(this);
}

handleChange(e) {
 const { name, value } = e.target;
 this.setState({
   [name]: value
 });
}

handleSubmit(e) {
 const { groceries, shopping, health, houseNeeds } = this.state;

 const gSum = parseInt(groceries, 10);
 const sSum = parseInt(shopping, 10);
 const hSum = parseInt(health, 10);
 const hnSum = parseInt(houseNeeds, 10);

 this.setState({
   total: gSum + sSum + hSum + hnSum
 });
 e.preventDefault();
}

render() {
 return (
   <div className="main">
     <Header />
     <hr />
     <div>
       <form onSubmit={this.handleSubmit}>
         <div className="input-flex">
           <InputComponent
             handleChange={this.handleChange}
             name="groceries"
             placeholder="Groceries"
           />
           <InputComponent
             handleChange={this.handleChange}
             name="shopping"
             placeholder="Shopping"
           />
           <InputComponent
             handleChange={this.handleChange}
             name="health"
             placeholder="Health"
           />
           <InputComponent
             handleChange={this.handleChange}
             name="houseNeeds"
             placeholder="Home"
           />
         </div>
         <button>Calculate</button>
       </form>
     </div>

     <AmountCard spent={this.state.total} />

     <BillChart spendings={[this.state.chartData]} />
   </div>
 );
}
}

export default SpendsApp;

here's the second one这是第二个

 import React from "react";

import { Bar } from "react-chartjs-2";

class BillsChart extends React.Component {
constructor(props) {
 super(props);
 this.state = {
   chartData: {
     labels: ["Groceries", "Shopping", "Health", "House Needs"],
     datasets: [
       {
         label: "Amount Spent",
         backgroundColor: "green",
         hoverBackgroundColor: "green",
         hoverBorderWidth: 2,
         hoverBorderColor: "#000",
         data: [this.props.spendings]
       }
     ]
   }
 };
}

render() {
 return <Bar onClick={this.props.handleClick} data={this.state.chartData} />;
}
}

export default BillsChart;

Firstly, in your SpendsApp component you have never changed the value of the chartData state.首先,在您的SpendsApp组件中,您从未更改过 chartData state 的值。 You change the number of the total and the other properties but you never change the value of the chartData you pass.您更改了总数和其他属性的数量,但您永远不会更改您传递的 chartData 的值。

You can have something like that你可以有类似的东西

 //code....
  constructor(props) {
    super(props);

    this.state = {
      groceries: 10,
      shopping: 0,
      health: 0,
      houseNeeds: 0,
      total: 0,
      chartData: []
    }
 }



handleSubmit(e) {
   e.preventDefault();
   const { groceries, shopping, health, houseNeeds } = this.state;

   const gSum = parseInt(groceries, 10);
   const sSum = parseInt(shopping, 10);
   const hSum = parseInt(health, 10);
   const hnSum = parseInt(houseNeeds, 10);

  // chartData array elements should be ordered as in your labels in the <BillsChart/>
  // labels: ["Groceries", "Shopping", "Health", "House Needs"] as you have it
  this.setState({
      total: gSum + sSum + hSum + hnSum,
      chartData: [gSum, sSum, hSum, hnSum] 
  });
}

Also another thing is that instead of this:还有一件事是,而不是这个:

<BillChart spendings={[this.state.chartData]} />

try this尝试这个

<BillChart spendings={this.state.chartData} />

The reason for that is because, if you passed correctly the values in the array you will end up in with a two-dismentional array here data: [this.props.spendings] .这样做的原因是,如果你正确传递了数组中的值,你最终会得到一个二维数组data: [this.props.spendings]

If you have already mounted your component you should use componentDidUpdate() to change the state of the <BillChart/> :如果您已经安装了组件,您应该使用componentDidUpdate()来更改<BillChart/>的 state :

componentDidUpdate(prevProps) {
  if (prevProps.spendings !== this.props.spendings) {
     let chartData = this.state.chartData;

     chartData.datasets[0].data = this.props.spendings
     this.setState({chartData});
  }
}

Just write a method upside the render() in BillsChart只需在 BillsChart 中的 render() 上方编写一个方法

    componentDidUpdate(prevProps) {
    if (prevProps.spendings !== this.props.spendings) {

     let {chartData} = this.state;
     chartData.datasets[0].data = this.props.spendings
     this.setState({chartData});

    }
  }

You are setting the prop spending on your BillChart in the render, which is passing an empty array as a prop to the component.您正在渲染中设置 BillChart 的道具spending ,它将一个空数组作为道具传递给组件。

this.state = {
   groceries: 10,
   shopping: 0,
   health: 0,
   houseNeeds: 0,
   total: 0,
   chartData: []
 };


 <BillChart spendings={[this.state.chartData]} />

So when you setState on chartData in your BillsChart component it is setting the data property to that empty array.因此,当您在 BillsChart 组件中对 chartData 设置状态时,它会将 data 属性设置为该空数组。

this.state = {
   chartData: {
     labels: ["Groceries", "Shopping", "Health", "House Needs"],
     datasets: [
       {
         label: "Amount Spent",
         backgroundColor: "green",
         hoverBackgroundColor: "green",
         hoverBorderWidth: 2,
         hoverBorderColor: "#000",
         data: [this.props.spendings]
       }
     ]
   }
 };

You need to setState of chartData to something besides an empty array before you pass it as a prop.在将它作为道具传递之前,您需要将 chartData 的 setState 设置为空数组之外的其他内容。

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

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