Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get the chart instance #81

Open
hy0ug0 opened this issue Aug 4, 2017 · 8 comments
Open

Get the chart instance #81

hy0ug0 opened this issue Aug 4, 2017 · 8 comments

Comments

@hy0ug0
Copy link

hy0ug0 commented Aug 4, 2017

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.

@hkfrei
Copy link

hkfrei commented Aug 8, 2017

I have exactly the same problem, would be great to have access to the Chart instance.

@aomran
Copy link
Collaborator

aomran commented Aug 16, 2017

If you EmberChart.extend you can then this.get('chart') -- or am I misunderstanding the problem?

@hy0ug0
Copy link
Author

hy0ug0 commented Aug 17, 2017

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...

@aomran
Copy link
Collaborator

aomran commented Aug 26, 2017

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?

@hy0ug0
Copy link
Author

hy0ug0 commented Aug 30, 2017

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.

@ghost
Copy link

ghost commented Aug 1, 2019

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.

@queenvictoria
Copy link

queenvictoria commented Apr 26, 2020

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

@LaSylv
Copy link

LaSylv commented Apr 26, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants