Chartjs-How to send an array of object as a prop?

1๐Ÿ‘

โœ…

You can create a HighChart wrapper component that can be used for any Highchart graphs.

Note:- every time the data set changes you need to destroy and re-render the graph again in order to make the graph reflect changes.


// @flow
import * as React from "react";
import merge from "lodash/merge";
import Highcharts from "highcharts";
import isEqual from "lodash/isEqual";

export type Props = {
    config?: Object,
    data: Array<any>,
    onRendered?: () => void
};

class HighchartWrapper extends React.PureComponent<Props> {
    container: ?HTMLElement;

    chart: any;

    static defaultProps = {
        config: {},
        onRendered: () => {}
    };

    componentDidMount() {
        this.drawChart(this.props);
    }

    componentWillReceiveProps(nextProps: Props) {
        const data= [...this.props.data];

        if (!isEqual(nextProps.config, this.props.config) || !isEqual(nextProps.data, data)) {
            this.destroyChart();
            this.drawChart(nextProps);
        }
    }

    destroyChart() {
        if (this.chart) { 
           this.chart.destroy();
        }
    }

    componentWillUnmount() {
        this.destroyChart();
    }

    drawChart = (props: Props) => {
        const { config: configProp, data, onRendered } = props;
        if (this.container) {
            let config = merge({}, configProp);

            this.chart = new Highcharts.chart(this.container, { ...{ ...config, ...{ series: [...data] } } }, onRendered);
        }
    };

    render() {
        return <div ref={ref => (this.container = ref)} />;
    }
}

export default HighchartWrapper;

In order use it for BarChart just pass the appropriate bar chart config.


<HighchartWrapper config={{
  chart: {
        type: "bar"
    }
  }}
  data={[]}
>

Edit

import React from "react";
import BarChart from "./BarChart";

export default function App() {
  return (
    <div style={{ width: 400, height: 840 }}>
      <BarChart
        config={{
          chart: {
            height: 840,
            type: "bar"
          },
          xAxis: {
            categories: ["Positive", "Neutral", "Negative" ],
            title: {
              text: null
            }
          },
          yAxis: {
            min: 0,
            title: {
              text: "Population (millions)",
              align: "high"
            },
            labels: {
              overflow: "justify"
            }
          }
        }}
        data={[
          {
            name: "Series Name",
            data: [90, 9, 10]
          }
        ]}
      />
    </div>
  );
}

1๐Ÿ‘

Just add your desired props in at component declaration :

<BarCharts data={this.state.analysis}/> 

And on your BarChart Component you will need to just extract the values from your arrays, this just in case you need the same structure:

...
this.state = {
      data: {
        labels: [
          negative,
          neutral,
          positive
        ],
        datasets: [
          {
            label: "Value plotting",
            backgroundColor: "rgba(255,99,132,0.2)",
            borderColor: "rgba(255,99,132,1)",
            borderWidth: 1,
            hoverBackgroundColor: "rgba(255,99,132,0.4)",
            hoverBorderColor: "rgba(255,99,132,1)",
            data: extractValues(this.props.data)
          }
        ]
      }
...
//This method can be reused in a hook or in a lifecycle method to keep data updated.
const extractValues = (data) => {
  return data.map( d => d.value);
}

0๐Ÿ‘

You can map the array so your code would be:

state={
    analysis: {
      tonal: [],
      anxiety: []
    }
}
Analysis = async () => {
    //some api call

      const {
        ...tonalAnalysis
      } = result.scores;

      const tonalArray = Object.entries(tonalAnalysis).reduce(
        (carry, [tone, value]) => [
          ...carry,
          { tone: tone.toLowerCase(), value: parseInt(value) }
        ],
        []
      );

      this.setState({
        analysis: { ...this.state.analysis, tonal: tonalArray }
      });
      console.log("Tonal array" + JSON.stringify(this.state.analysis.tonal)); //console logs `[{"tone":"negative","value":0},{"tone":"neutral","value":91},{"tone":"positive","value":9}]`
  };

render(){
    return {
      <BarCharts values={this.state.analysis.tonal.map((entry) => entry.value)}/> // confused how to send the values as props here
}

And your barchart would be:

import React from "react";

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

import "./App.css";

class BarCharts extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: {
        labels: [
          negative,
          neutral,
          positive
        ],
        datasets: [
          {
            label: "Value plotting",
            backgroundColor: "rgba(255,99,132,0.2)",
            borderColor: "rgba(255,99,132,1)",
            borderWidth: 1,
            hoverBackgroundColor: "rgba(255,99,132,0.4)",
            hoverBorderColor: "rgba(255,99,132,1)",
            data: props.values //want to use the values here dynamically. Don't want these static values
          }
        ]
      }
    };
  }

  render() {
    const options = {
      responsive: true,
      legend: {
        display: false
      },
      type: "bar"
    };
    return (
      <Bar
        data={this.state.data}
        width={null}
        height={null}
        options={options}
      />
    );
  }
}

export default BarCharts;

Leave a comment