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

How to listen for clicks on labels? #2802

Closed
RoxKilly opened this issue Jun 18, 2016 · 15 comments
Closed

How to listen for clicks on labels? #2802

RoxKilly opened this issue Jun 18, 2016 · 15 comments

Comments

@RoxKilly
Copy link

v2.1.6

My use case must be pretty common so I bet it has been solved but I can't find anything in the docs. I have a horizontal bar chart. When the user focuses on a category (clicks the bar), I show detailed info elsewhere in the view.

Often a category has value=0, so there is no bar to click on. Ironically these are the categories most interesting to my user (a low bar means a problem that requires the user's attention) so I still need to give the user a way to show the category details in the view. Any user would expect that he could just click the category name (the yAxis label in my horizontal bar chart) to select that category. So my problem is simple: What's the cleanest way to detect which label was clicked on?

@etimberg
Copy link
Member

There is a method on the scale to go from the pixel to the correct label. I am on mobile so i can't post a fiddle, but the zoom and pan plugin in the chartjs organization uses it

@RoxKilly
Copy link
Author

Thanks. I've just gone through the scales docs and I don't see such a function. Could it be undocumented or am I missing it?

@etimberg
Copy link
Member

I don't think it is currently documented. The bit in the zolm and pan plugin is in panNumericalScale in https://github.com/chartjs/Chart.Zoom.js/blob/master/src/chart.zoom.js

@RoxKilly
Copy link
Author

RoxKilly commented Jun 20, 2016

Thanks for putting me on the right track. The panNumericalScale you linked to uses a getValueForPixel() function that looks promising in Chart.js 2.1.6, on line 9058. However I'm not sure how to call it. I define the chart:

var _Chart = new Chart(this.ctx, {
    type: _type,
    data: _data,
    options: _options
});

I then try to access the function of interest by making one of the following calls inside the onClick callback (e is the MouseEvent) generated by the click:

Chart.getValueForPixel(e.ClientX); // error: ...is not a function
this._Chart.getValueForPixel(e.ClientX); // error: ...is not a function
this._Chart.scale.getValueForPixel(e.ClientX); // error _Chart.scale is undefined

The chart renders normally so I know that Chart.js loaded successfully. I just don't know how to refer to that function

@etimberg
Copy link
Member

Those functions are on a particular scale. Scales can be found in chartInstance.scales which is a map of string scale ID to the scale object. You can find the right scale then call things on it.

@etimberg
Copy link
Member

@RoxKilly did you get this working? If so, can you please close this issue?

@RoxKilly
Copy link
Author

RoxKilly commented Jun 28, 2016

No I haven't gotten it working. Thanks to your help I'm now able to call the function in question with chart.scales[axisName].getValueForPixel(). However I don't get consistent results. To see what I mean, take a look at this plunkr (in file app/app.component.ts).

To see what I'm trying to capture, use the input above the chart to select how many bars you want on the chart, then press the button next to the input. Once the chart is built, click the y-axis labels (not the data bars) and the result of calling getValueForPixel on the y-axis scale will be shown on screen. Notice that:

  • With 2 through 3 bars, clicking the first y-label makes getValueForPixel()==1
  • With 4 through 6 bars, clicking the first y-label makes getValueForPixel()==2
  • With 7 through 9 bars, clicking the first y-label makes getValueForPixel()==3
  • With 10 through 11 bars, clicking the first y-label makes getValueForPixel()==4
  • With 12 through 14 bars, clicking the first y-label makes getValueForPixel()==5

Because I don't have a reliable pattern, I still don't know how to get the text of the yLabel that was clicked.

@etimberg
Copy link
Member

@RoxKilly I got your plunkr working a bit better here. I used Chart.helpers.getRelativePosition to get the position on the canvas because there are a number of cases that need to be handled (device pixel ratio, margins, padding, etc).

It works a bit better :) For some reason the first label is not shown on the first label (index 0). Not sure why.

@RoxKilly
Copy link
Author

Thanks for moving the ball forward on this. I was pretty frustrated before but I'm encouraged now.

@RoxKilly
Copy link
Author

RoxKilly commented Jun 29, 2016

@etimberg Actually, your fix works! Index 0 was not getting printed because I would only print if value was truthy, and zero failed the if(value) check. Changing the check to if(value!==null) fixes that.

Thanks a bunch.

@etimberg
Copy link
Member

@RoxKilly awesome. Glad it works 😄

@RoxKilly
Copy link
Author

I celebrated too soon it seems. The results of getValueForPixel are thrown off when either a title or legend is displayed above the chart. At this plunk, you'll notice that if you click the top half of the first label's vertical span (The span between the two ticks that segment the label), you get the right result (index 0), but if you click the second half, still within the tick marks that demarcate the first label, you get the wrong result (index 1). This can be repeated with the other labels. Although the plunk I linked to doesn't test this, the same problem manifests itself with vertical bars, when clicking the x-labels.

Unless you have another idea this seems to be the end of the road for what I can do without changing the library itself.

@etimberg
Copy link
Member

@RoxKilly sorry about that. There is an error in the function the category scale uses to go backwards. I fixed it in #2870.

I updated your plunk with a hotpatch: http://plnkr.co/edit/GsOi2hX42389VJnuzGhv?p=preview
The patch is in app/main.ts

@RoxKilly
Copy link
Author

A typo on line 7 of your Plunk's app/main.ts file would cause an exception, so the bug remained. I changed

let ScaleConstructor = chart.scaleService...

With

let ScaleConstructor = Chart.scaleService...

by capitalizing the 'c' in "Chart". Initial testing is positive; the fix seems to work with both horizontal and vertical bar charts (the types I can confirm were not working before). Thanks again. Closing.

@etimberg
Copy link
Member

My bad on the typo. Hadn't had coffee yet 😛

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

No branches or pull requests

2 participants