Chartjs-React Chart.js onClick for custom legends

1👍

If you give the ref a callback, then you won’t get a value of null. Doing an inline ref like this causes the first render to be null and then the second render will have the element.

So you should change your refs to:

applyRef(ref) {
    this.legend = ref;
}

render() {
    return (
        // Chart component
        <Line ref={this.applyRef}
              data={this.state.chart}
              options={this.state.options}
        />
    )
}

For adding a click event handler, if you can’t add an onClick attrib for some reason, then you can set it in your insertLegends method:

handleClick(e) {
    // Do something here...
}

insertLegends(chart) {
    this.refs.chartLegendContainerGlobal.innerHTML = chart.chart_instance.generateLegend();
    this.refs.chartLegendContainerGlobal.addEventListener('click', this.handleClick);
}

0👍

After some trouble and research, I figure out how to add the legend and control the click inside of it.

// Inside my render method I added a simple ref to my component
<Line ref='chart' data={this.convertData(this.props.data)}  options={this.state.options} />

// Inside this method I'm able to get all the references that 
// I need to inject the html inside a container for the legends and 
// also to assign a click for each legend label
componentDidMount() {
   let legends = this.refs.chart.chart_instance.generateLegend();
   this.refs.chartLegendContainer.innerHTML = legends;

   $(this.refs.chartLegendContainer).find('.legend-item').on('click', (e) => {
      let index = $(e.currentTarget).index();
      this.refs.chart.chart_instance.data.datasets[index].hidden = !this.refs.chart.chart_instance.data.datasets[index].hidden;
      $(e.currentTarget).toggleClass('disable-legend');
      this.refs.chart.chart_instance.update();
   });
}

UPDATED

After the commect of @Chase DeAnda, I changed a little bit based on his considerations:

// Applying the callback function to the ref
<Line ref={this.applyRef} data={this.convertData(this.props.data)}  options={this.state.options} />

// Inside the method I call the method to insert the legends
applyRef(ref) {
   this.legend = ref;
   this.insertLegends();
}

// Generates the legend and added them to my container element
// Also give them the onClick event
insertLegends() {
   let legends = this.legend.chart_instance.generateLegend();
   this.refs.chartLegendContainer.innerHTML = legends;
   $(this.refs.chartLegendContainer).find('.legend-item').on('click', (e) => this.onClickLegend(e));
}

// During onClick I update the chart
onClickLegend(e) {
   let index = $(e.currentTarget).index();
   this.legend.chart_instance.data.datasets[index].hidden = !this.legend.chart_instance.data.datasets[index].hidden;
   $(e.currentTarget).toggleClass('disable-legend');
   this.legend.chart_instance.update();
}

Leave a comment