简体   繁体   English

React Chart.js onClick获得自定义图例

[英]React Chart.js onClick for custom legends

I'm using react-chartjs-2 to create a Line chart for my application. 我正在使用react-chartjs-2为我的应用程序创建一个折线图。

For this app, I did a legend customisation and I could generate them using this: 对于此应用程序,我进行了图例自定义,可以使用以下命令生成它们:

// Chart component
<Line ref={ (chart) => chart ? this.insertLegends(chart) : null }
      data={this.state.chart} 
      options={this.state.options}  
/>

// Method which insert the html content
insertLegends(chart) {
   this.refs.chartLegendContainerGlobal.innerHTML = chart.chart_instance.generateLegend();
}

First, is this a right approach? 首先,这是正确的方法吗? I had to create an inline condition inside the component to prevent chart to be null. 我必须在组件内部创建一个内联条件,以防止图表为空。

Second, how and where can I put an onClick event for each legend? 其次,如何为每个图例放置onClick事件?在哪里?

I'm very lost on this, is there a better way to do this legend customisation?? 我对此非常迷失,是否有更好的方法来进行此图例定制?

If you give the ref a callback, then you won't get a value of null. 如果给ref回调,则不会得到null值。 Doing an inline ref like this causes the first render to be null and then the second render will have the element. 像这样进行内联引用会导致第一个渲染为null,然后第二个渲染将具有元素。

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: 对于添加单击事件处理程序,如果由于某种原因无法添加onClick属性,则可以在insertLegends方法中进行设置:

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

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

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: @Chase DeAnda交流之后,我根据他的考虑做了一些改动:

// 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();
}

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

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