chartjs / chartjs-plugin-annotation

Annotation plugin for Chart.js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Get other annotations width from an annotation scriptable option.

zk118 opened this issue · comments

commented

Hey, thank's for this usefull plugin !

I would like to get the width of an annotation from within another annotation scriptable option (to place the 2nd annotation next to the first relative to the width of the 1st annotation).

I want to accomplish something like that:

annotation1: {
	type: 'label',
	xValue: () => 0,
	yValue: () => 1,
	content: () => "Annotation 1",
	padding: 5,
	color: 'black',
},

annotation2: {
	type: 'label',
	xValue: () => 0,
	yValue: () => 1,
	xAjust: (cxt) => {
		return ctx.chart.options.plugins.annotation.annotations.annotation1.width
	},
	content: () => "Annotation 2",
	padding: 5,
	color: 'black',
}

But the problem is ctx.chart.options.plugins.annotation.annotations.annotation1.width doesn't exists.
Is it possible to achieve ?

Thanks in advance.

@evenmind the width of an annotation is a property of the annotation elements which are NOT exported (and then NOT exposed).
There is a workaround to access to the elements but not documented and let me call it "private".
Let me ask you if the center of the first label must be the point you selected or not. If not, you could use position option to align them.
Make sense for you?

commented

@stockiNail thank you for fast reply.
In fact, I need them to be aligned next to each other, the 2nd one starts where the 1st finish, and so on for the 3rd, 4th etc.
If I have the center point of 1st annotation, I could calculate the end of 1st annotation: x + (x + center)*2, but how can I access the center point ?

If you have to add more than 2 labels, it's not possible, because the position option enable you to decide, depending the point, if you want the label all on the right or on the left (or top or bottom).
But with more than 2, it' not possible by position.

I could calculate the end of 1st annotation: x + (x + center)*2, but how can I access the center point ?

As said, the x, y, x2, y2, width, height, centerX and centerY are all properties of the annotation elements which are not officially exposed. :(
See #775 (reply in thread) to see how to access to the "private" state (and then elements). Be aware it could be removed any time.

In the next version, there will be 2 new hooks which can help you on that: #744

Setting the z options (to be sure that the labels are draw in the right order), you could take the width (storing it in a variable) and change accordingly all the other labels (accessing to the element).

Anyway, even accessing to the loaded elements, you don't know the width of the label you want to change therefore it's quite difficult I guess.

commented

I will check the private state in the meantime the next version is live, thanks.

I think we could add the loaded elements to the element context in order to address this use case (and also others).
@kurkle what do you think?

commented

I get undefined for window['chartjs-plugin-annotation']

I get undefined for window['chartjs-plugin-annotation']

Can you provide a sample to reproduce the issue?

commented

I literally just

annotation2: {
	type: 'label',
	xValue: () => 0,
	yValue: () => 1,
	xAjust: (cxt) => {
		console.log(window['chartjs-plugin-annotation'])
	},
	content: () => "Annotation 2",
	padding: 5,
	color: 'black',
}

and get undefined. Maybe this is because I'm using vue-chartjs wrapper and it does not inject 'chartjs-plugin-annotation' in the window ?

Maybe this is because I'm using vue-chartjs wrapper and it does not inject 'chartjs-plugin-annotation' in the window ?

Yes, I think so. I think you are importing the plugin, something like:

import annotationPlugin from 'chartjs-plugin-annotation';

If yes, use annotationPlugin instance instead

commented

If yes, use annotationPlugin instance instead

Works ! Thank you.

@evenmind just FYI, I have submitted a PR #869 which is adding the elements to the context. In this way, you will not need to use the undocumented API but you can use the elements in the context.
Panned for version 3.0.