2017-10-04 43 views
0

我正在使用react-chartjs-2爲我的應用程序創建折線圖。React Chart.js onClick自定義圖例

對於這個程序,我做了一個傳奇的定製,我可以使用這個生成它們:

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

首先,這是一個正確的做法? 我不得不在組件內部創建一個內聯條件來防止圖表爲空。

其次,我如何以及在哪裏可以爲每個圖例添加一個onClick事件?

我很迷茫,有沒有更好的方法來做這個傳奇定製?

回答

1

如果您給ref一個回調,那麼您將不會得到空值。這樣做一個內聯ref會導致第一個渲染爲null,然後第二個渲染將會有這個元素。

所以,你應該改變你的裁判到:

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

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

對於添加click事件處理程序,如果你不能因爲某些原因添加onClick ATTRIB,那麼你可以將其設置在insertLegends方法:

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

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

謝謝!但我有一個問題,我怎樣才能調用我的方法insertLegends?用這種方法,我的這個在applyRef裏面是未定義的。 –

+0

我弄清楚如何使用參考文獻來結合你的想法。我要發佈它。非常感謝! =) –

+0

@ItaloBorges您需要在構造函數中綁定'applyRef'。 'this.applyRef = this.applyRef.bind(this);' –

0

經過一番麻煩和研究之後,我想出瞭如何添加圖例並控制裏面的點擊。

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

修訂

@Chase DeAnda的commect後,我改變了一點點根據他的考慮:

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

夫妻點:String refs將很快被棄用,所以你應該使用ref回調來設置refs。您應該創建一個用於處理click事件的類方法,並將其傳遞給事件偵聽器,而不是在componentDidMount方法中全部內聯執行。 –

+0

@ChaseDeAnda,我剛剛更新了我的代碼與您的考慮。更好的方法!謝謝! –