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

Add defined and loaded elements to annotation context #869

Merged
merged 6 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/guide/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ In addition to [chart](#chart)

* `id`: the annotation id
* `element`: the annotation element
* `elements`: the array which contains the already created annotation elements.
* `type`: `'annotation'`

The [annotation](#annotation) option context is passed to scriptable options in all other cases, except when resolving `id`, `type` or adjusting scale ranges. The same values resolved in `afterDataLimits` with [chart](#chart) context are again evaluated in `afterUpdate` with [annotation](#annotation) context.
Expand Down
7 changes: 5 additions & 2 deletions src/elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export function updateElements(chart, state, options, mode) {
for (let i = 0; i < annotations.length; i++) {
const annotationOptions = annotations[i];
const element = getOrCreateElement(elements, i, annotationOptions.type);
const resolver = annotationOptions.setContext(getContext(chart, element, annotationOptions));
const resolver = annotationOptions.setContext(getContext(chart, element, elements, annotationOptions));
const properties = element.resolveElementProperties(chart, resolver);

properties.skip = toSkip(properties);
Expand Down Expand Up @@ -142,9 +142,12 @@ function resolveObj(resolver, defs) {
return result;
}

function getContext(chart, element, annotation) {
function getContext(chart, element, elements, annotation) {
return element.$context || (element.$context = Object.assign(Object.create(chart.getContext()), {
element,
get elements() {
return elements.filter((el) => el && el.options);
},
id: annotation.id,
type: 'annotation'
}));
Expand Down
90 changes: 90 additions & 0 deletions test/specs/annotation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,4 +211,94 @@ describe('Annotation plugin', function() {
expect(element.options.drawTime).toBe(chart.options.plugins.annotation.annotations.label.drawTime);
});
});

describe('context', function() {
it('should contain the loaded elements', function() {
const counts = [];
const annotations = [];
for (let i = 0; i < 5; i++) {
annotations.push({
type: 'label',
content: 'test',
display(context) {
expect(context.elements.length).toBe(i);
counts.push(i);
}
});
}
acquireChart({
type: 'line',
options: {
plugins: {
annotation: {
annotations
}
}
}
});
expect(counts).toEqual([0, 1, 2, 3, 4]);
});
it('should contain the loaded elements after update', function() {
const counts = [];
const annotations = [];
for (let i = 0; i < 5; i++) {
annotations.push({
type: 'label',
content: 'test',
display(context) {
expect(context.elements.length).toBe(i);
counts.push(i);
}
});
}
const chart = acquireChart({
type: 'line',
options: {
plugins: {
annotation: {
annotations
}
}
}
});
counts.splice(0, counts.length);
chart.update();
expect(counts).toEqual([0, 1, 2, 3, 4]);
});

it('should contain the loaded elements after reducing annotations and chart update', function() {
const counts = [];
const annotations = [];
for (let i = 0; i < 5; i++) {
annotations.push({
type: 'label',
content: 'test',
display(context) {
const check = context.chart.options.plugins.annotation.annotations.length < 5;
if (check) {
expect(context.elements.length).toBe(i - 2);
counts.push(i);
}
}
});
}
const chart = acquireChart({
type: 'line',
options: {
plugins: {
annotation: {
annotations
}
}
}
});
counts.splice(0, counts.length);
chart.update();
counts.splice(0, counts.length);
chart.options.plugins.annotation.annotations = annotations.slice(2);
chart.update();
expect(counts).toEqual([2, 3, 4]);
});

});
});
2 changes: 2 additions & 0 deletions types/events.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { AnnotationElement } from './element';
export interface EventContext {
chart: Chart,
element: AnnotationElement,
elements: AnnotationElement[],
id: string,
type: string
}
Expand All @@ -15,6 +16,7 @@ export interface EventContext {
export interface PartialEventContext {
chart: Chart,
element?: Partial<AnnotationElement>,
elements?: AnnotationElement[],
id?: string,
type?: string
}
Expand Down
Loading