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

Annotations that are following current Y values should not overlap #895

Open
davidnir1 opened this issue Jun 5, 2023 · 10 comments
Open

Comments

@davidnir1
Copy link

davidnir1 commented Jun 5, 2023

Feature Proposal

When two plots have very close Y values, the annotations are overlapping and can hide each other, for example in our app:
image

Possible Implementation

Instead of overlapping, they should be on top of each other (ordered by y values), for example (source):
image

Thanks!

@LeeLenaleee LeeLenaleee transferred this issue from chartjs/Chart.js Jun 5, 2023
@stockiNail
Copy link
Collaborator

@davidnir1 may I ask you if you are using annotations or the annotations you are referring to are the tooltip labels? If you are using annotation plugin, can you share a sample?

@stockiNail
Copy link
Collaborator

@davidnir1 anyway, if you are using the annotation plugin, the labels can be overlapped.
See discussion #880
You can use y/xAdjust options to manually change the label position. They can be scriptable.

@KseniaKeren
Copy link

@davidnir1 anyway, if you are using the annotation plugin, the labels can be overlapped. See discussion #880 You can use y/xAdjust options to manually change the label position. They can be scriptable.

Hi, in this example you reffered to i`m not sure what is x,x2, y,y2 ,Here is an example on how we add annotation (using annotations plugin):
image

which means I can only control yValue for the location of the annotation, however I find it difficult to identify collisions because I have cases of multiple y scales whos values are totally different and yet there may be collision between the annotations because the chart is normalized.

@stockiNail
Copy link
Collaborator

@KseniaKeren you are right writing that it is not simple.
Anyway, to do that, you could implement beforeDraw hook (https://www.chartjs.org/chartjs-plugin-annotation/latest/guide/configuration.html#hooks) at annotation level where you can have the element to draw with its dimension (https://www.chartjs.org/chartjs-plugin-annotation/latest/guide/types/label.html#element).
Furthermore, due to the fact you need to compare the dimension with other annotations, the PR #892 sounds to be needed.

@stockiNail
Copy link
Collaborator

i`m not sure what is x,x2, y,y2

@KseniaKeren sorry, I forgot to explain better the above doubt.
Every annotation is an Chart.js element which is taking care to draw what is requested by the config.
Every annotation element has got a set of properties and there are some of them related to the dimension of the element (and then of the annotation.
All annotation elements are mapped in a rectangle, which contains x and y (left-top edge) and x2 and y2 (right bottom edge).
Furthermore the element has got the width and height properties.
The element are available on scriptable options (https://www.chartjs.org/chartjs-plugin-annotation/latest/guide/options.html#option-context) and hooks (draw and event).

See elements diagrams:

Annotation type Diagram
box image
ellipse image
label image
line image
point image
polygon image

@KseniaKeren
Copy link

KseniaKeren commented Jun 6, 2023

@stockiNail Thank you very much for the explanation ,your thorough explanations and thoughtful suggestions have greatly improved my understanding.
is there a way to add the beforeDraw hook to the annotation level? because when I try to add it I get a ts error

image

also I wanted to see the elements x2 y2 values but when I print the annotation element to the console these are the fields I have

image

@stockiNail
Copy link
Collaborator

@KseniaKeren I think you are still using the annotation plugin version1.x.
The element properties normalization (with those properties) is available since version 2.x.
The beforeDraw hook is available from version 2.2.0.

@stockiNail
Copy link
Collaborator

@davidnir1 @KseniaKeren here is a codepen with a sample how to avoid label overlapping: https://codepen.io/stockinail/pen/xxQKPKv
It could be a starting point for custom logic.

@KseniaKeren
Copy link

@stockiNail Thank you very much, I looked into the code and it seems to be very helpful for us. Also I updated our version and now we indeed have the beforeDraw hook. a challenge we encountered now is about how to access other annotations in the chart. I wonder if there is a way to access them in the chart context that comes as a parameter to the beforeDraw hook? we cannot use the custom plugin you written cause our annotations are always shown the only thing we change in the app is the x value (kind of progress bar of a clip that constantly moving) , so we cannot seem to find a way to access all other annotations. We used to access them via chart.options.plugins.annotation.annotations[i] in order to change the yValue each time the current x changed, but this is the inner propeties of the annotation and they do not include the x x2 y y2 properties.

@stockiNail
Copy link
Collaborator

@KseniaKeren to get all annotation elements there is a "private" method which can be removed if and when #892 will be approved and merged.
After that PR, you could get a method in the plugin to get all visible annotations.

// get annotation plugin instance
import annotationPlugin from 'chartjs-plugin-annotation';
....
const myLineChart = new Chart(ctx, config);
// get all annotation elements
const elements = annotationPlugin.getAnnotations(myLineChart);

If you cannot wait for that PR, you can have a look to the discussion (previously mentioned) #880 (reply in thread) where the sample is using the private and undocumented function.
But pay attention, because this will be removed by above mentioned PR.

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

3 participants