3

It is my first time working with Chartjs, and I'm not really a pro in React either. I am trying to implement a bar chart that should take its data possibly from CONSTs that are calculater using numbers provided by user inputs. This is how the chart works right now. The values in data are harcoded, and I don't know how to make them dynamic.

  constructor(props) {
    super(props);

    this.state = {
            chartData:{},
      visitors: "",
      conversion: 4,
      value: "",

            smileeconversion: "",
            smileevalue: "",

            swcost: "",
            labourcost: "",
            roi: ""
    };
  }

    componentWillMount(){
    this.getChartData();
  }

      getChartData(){
    // Ajax calls here
    this.setState({
      chartData:{
        labels: ['Before', 'After'],
        datasets:[
          {
            label:'Population',
            data:[
              617594,
              181045,
            ],
            backgroundColor:[
              'rgba(255, 99, 132, 0.6)',
              'rgba(54, 162, 235, 0.6)',
              'rgba(255, 206, 86, 0.6)',
              'rgba(75, 192, 192, 0.6)',
              'rgba(153, 102, 255, 0.6)',
              'rgba(255, 159, 64, 0.6)',
              'rgba(255, 99, 132, 0.6)'
            ]
          }
        ]
      }
    });
  }

this is the chart component:

import React, {Component} from 'react';
import {Bar, Line, Pie} from 'react-chartjs-2';

class Chart extends Component{
  constructor(props){
    super(props);
    this.state = {
      chartData:props.chartData

    }
  }

  static defaultProps = {
    displayTitle:true,
    displayLegend: true,
    legendPosition:'right',
    location:'City'
  }

  render(){
    return (
      <div className="chart">
        <Bar
          data={this.state.chartData}
          options={{
            title:{
              display:this.props.displayTitle,
              text:'Return of investments',
              fontSize:25
            },
            legend:{
              display:this.props.displayLegend,
              position:this.props.legendPosition
            }
          }}
        />
      </div>
    )
  }
}

export default Chart;

and its parent component:

 <Chart chartData={this.state.chartData} location="Massachusetts" legendPosition="bottom"/>
6
  • So far as I can see do you only load the chartData once. ComponentWillMount is only called once. You can use setstate when a user updates an input field, en call the getChartData function. Commented Sep 20, 2018 at 12:07
  • U are talking about "The values in data are harcoded, and I don't know how to make them dynamic". Are you talking about data:[ 617594, 181045, ], ? Commented Sep 20, 2018 at 12:09
  • Where will this dynamic data come from? In the AJAX calls? If so, I recommend searching for "AJAX ReactJS" in the Search box at the top of this page. It looks like many people have asked about this topic, and gotten excellent answers. Good luck! Commented Sep 20, 2018 at 12:32
  • @StephanHovius yes, this is what I meant, sorry if I'm not saying it correctly. Commented Sep 20, 2018 at 13:13
  • @AndyTaton no, I am not using Ajax, the basics of the app is that it calculates the return of investments based on numbers that the users write in inputs. After that it compares two values and illustrates it with a bar chart. Commented Sep 20, 2018 at 13:14

1 Answer 1

1

This is a slightly different approach, but I think it's simpler than what you're doing:

Stop using state

Try passing arrays as parameters into your function, and then send the parameters directly to the chart data object, and then initiating the chart directly from inside the function (I avoid using React state in this case because it has a lag, and Chart.js wants to initiate instantly).

Here's a small example:

let barChart;
let newLabels = ["Label1", "Label2", "Label3"];
let newData = ["Data1", "Data2", "Data3"];

createBarChart = (labels, data) => {

    let ctx = "bar_l1_chart";

    barChart = new Chart(ctx, {
        type: 'horizontalBar',
        data: {
            labels: [labels],
            datasets: [{
                label: 'Sentiment',
                data: [data],
            }]
        },
    });
};
this.createBarChart(newLabels, newData);

Now you just update the "newLabels" or "newData" arrays, and re-call the function. A good way to do that is with React state managers, like:

componentWillRecieveProps(newProps){
     if(newProps.labels && newProps.data) {
          if(barChart){barChart.destroy()};
          this.createBarChart(newProps.labels, newProps.data)
     }
}

You will also need to "destroy()" the chart, before you recreate it. Hopefully this is helpful!

Sign up to request clarification or add additional context in comments.

1 Comment

how to add multiple datasets dynamically any idea about that ? datasets: [{ label: 'Sentiment', data: [data], }] this i should get label and data dynamically ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.