ember-cli-chart
ember-cli-chart copied to clipboard
Get the chart instance
I try to get the Chart instance to be able to use the getElementAtEvent() method. I have this :
onClick: (event, chartElements) => {
this.handleChartClick(event, chartElements);
}
And I want to access my Chart instance in my handleChartClickmethod, how can I do that ? The final purpose is to listen on click in axis labels and get their value.
I have exactly the same problem, would be great to have access to the Chart instance.
If you EmberChart.extend you can then this.get('chart') -- or am I misunderstanding the problem?
Let's say I have a component with this template
{{ember-chart type='horizontalBar' data=barData options=chartOptions width=200 height=200}}
Now in my component.js I want to access the instance of the chart I created in my template, how I would do that ?
Same question apply if I have multiple charts in my template like that
{{ember-chart type='horizontalBar' data=barData options=chartOptions width=200 height=200}}
{{ember-chart type='horizontalBar' data=barData options=chartOptions width=200 height=200}}
How I can access each instance ?
Hoping I'm clear enough...
I assume you want the instance of the chart to react to some kind of event. You can extend this component.
// file: your-app/components/ember-chart.js
import EmberChart from 'ember-cli-chart/components/ember-chart';
export default EmberChart.extend({
doubleClick() {
alert("DoubleClickableComponent was clicked!");
// this.get('chart') should give you the Chartjs instance.
}
});
See ember component event handlers here: https://guides.emberjs.com/v2.14.0/components/handling-events/#toc_event-names
@Hugo-Contreras does this help?
I was trying to handle an event on the Chart y-axis, so I did something like that (which is a bit ugly but working for now):
@readOnly
@computed('data')
chartOptions () {
const componentContext = this;
return {
maintainAspectRatio: false,
onClick: function (event) {
componentContext.handleChartClick(event, this);
}
}
And in my component I have this method to handle the click:
handleChartClick (event, chartInstance) {
const helpers = Chart.helpers;
const eventPosition = helpers.getRelativePosition(event, chartInstance.chart);
const clickY = chartInstance.chart.scales['y-axis-0'].getValueForPixel(eventPosition.y);
const rangeValues = this.get('data.barLabels')[clickY].split('-').map((value) => {
return parseInt(value.trim(), 10);
});
Thank's for your answer ! Might help at some point.
Would be great to have access to the chart instance without extending the component. This seems to be fairly straightforward in the unwrapped library.
My need arises not from event handling, but from using callbacks. I'm creating a custom tick callback for timezone handling. I must reference the displayFormats settings in my callback, ergo I need access to the xAxes object as a whole so I can reference the previously defined property.
For now, I am using the hack above (thanks, Hugo!) but would be cool to have something baked in that's a little less messy.
Thanks @hy0ug0 I have used something similar in my component that has an <EmberChart /> where the calling template has an @onclick={{action "chartClicked"}} argument.
constructor() {
const self = this;
const chartOptions = {
onClick(e, context) {
self.handleClickEvent(e, context, self, this);
}
};
}
handleClickEvent(e, context, self, chartInstance) {
self = self || this;
if ( chartInstance ) {
const activePoints = chartInstance.getElementAtEvent(e);
if ( activePoints.length > 0 ) {
const chartElement = activePoints[0];
const datapoint = chartInstance.config.data.datasets[chartElement._datasetIndex].data[chartElement._index];
// Actions up
self.args.onclick(datapoint);
}
}
}
I was able to have acces to the instance through another ugly hack
<EmberChart
@type="line"
@data={{@model.data}}
@chart={{@model.chart}}
@options={{@model.options}}
></EmberChart>
It works even though it definitely is not clean