From c867429efd18dced47468de60b21bb82cee43be1 Mon Sep 17 00:00:00 2001 From: stockiNail Date: Wed, 15 Mar 2023 15:58:26 +0100 Subject: [PATCH 1/4] Add loaded elements to annotation context --- src/elements.js | 5 +++-- test/specs/annotation.spec.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/elements.js b/src/elements.js index 08db4604a..749ec0112 100644 --- a/src/elements.js +++ b/src/elements.js @@ -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); @@ -142,9 +142,10 @@ 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, + elements, id: annotation.id, type: 'annotation' })); diff --git a/test/specs/annotation.spec.js b/test/specs/annotation.spec.js index 6d1d49b35..10a146911 100644 --- a/test/specs/annotation.spec.js +++ b/test/specs/annotation.spec.js @@ -211,4 +211,33 @@ 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 annCount = 5; + const counts = []; + const annotations = []; + for (let i = 0; i < annCount; i++) { + annotations.push({ + type: 'label', + content: 'test', + display(context) { + expect(context.elements.length).toBe(annCount); + counts.push(context.elements.filter((e) => e && e.options).length); + } + }); + } + acquireChart({ + type: 'line', + options: { + plugins: { + annotation: { + annotations + } + } + } + }); + expect(counts).toEqual([0, 1, 2, 3, 4]); + }); + }); }); From 53c66fbed6544aefee5fb0bcfc78876ac57c5919 Mon Sep 17 00:00:00 2001 From: stockiNail Date: Wed, 15 Mar 2023 17:27:38 +0100 Subject: [PATCH 2/4] added types and doc --- docs/guide/options.md | 1 + types/events.d.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/docs/guide/options.md b/docs/guide/options.md index eae6097d9..03290ac0e 100644 --- a/docs/guide/options.md +++ b/docs/guide/options.md @@ -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. The array could contain `undefined` items, during the annotations initialization phase, for elements not created yet. * `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. diff --git a/types/events.d.ts b/types/events.d.ts index 5dfb63fe1..996d29664 100644 --- a/types/events.d.ts +++ b/types/events.d.ts @@ -4,6 +4,7 @@ import { AnnotationElement } from './element'; export interface EventContext { chart: Chart, element: AnnotationElement, + elements: AnnotationElement[], id: string, type: string } @@ -15,6 +16,7 @@ export interface EventContext { export interface PartialEventContext { chart: Chart, element?: Partial, + elements?: AnnotationElement[], id?: string, type?: string } From d5483d2fdba51086a62cdbf7a93e8773deb64246 Mon Sep 17 00:00:00 2001 From: stockiNail Date: Thu, 16 Mar 2023 10:41:07 +0100 Subject: [PATCH 3/4] read only elements --- docs/guide/options.md | 2 +- src/elements.js | 4 +++- test/specs/annotation.spec.js | 35 +++++++++++++++++++++++++++++++---- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/docs/guide/options.md b/docs/guide/options.md index 03290ac0e..e40427d5a 100644 --- a/docs/guide/options.md +++ b/docs/guide/options.md @@ -116,7 +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. The array could contain `undefined` items, during the annotations initialization phase, for elements not created yet. +* `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. diff --git a/src/elements.js b/src/elements.js index 749ec0112..d3dd19e90 100644 --- a/src/elements.js +++ b/src/elements.js @@ -145,7 +145,9 @@ function resolveObj(resolver, defs) { function getContext(chart, element, elements, annotation) { return element.$context || (element.$context = Object.assign(Object.create(chart.getContext()), { element, - elements, + get elements() { + return elements.filter((el) => el && el.options); + }, id: annotation.id, type: 'annotation' })); diff --git a/test/specs/annotation.spec.js b/test/specs/annotation.spec.js index 10a146911..fb11e4e05 100644 --- a/test/specs/annotation.spec.js +++ b/test/specs/annotation.spec.js @@ -214,16 +214,15 @@ describe('Annotation plugin', function() { describe('context', function() { it('should contain the loaded elements', function() { - const annCount = 5; const counts = []; const annotations = []; - for (let i = 0; i < annCount; i++) { + for (let i = 0; i < 5; i++) { annotations.push({ type: 'label', content: 'test', display(context) { - expect(context.elements.length).toBe(annCount); - counts.push(context.elements.filter((e) => e && e.options).length); + expect(context.elements.length).toBe(i); + counts.push(i); } }); } @@ -239,5 +238,33 @@ describe('Annotation plugin', function() { }); 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]); + }); + }); }); From 8d361897460d8d2dd32e6c9841fac8e70f6ccacf Mon Sep 17 00:00:00 2001 From: stockiNail Date: Tue, 23 May 2023 10:21:18 +0200 Subject: [PATCH 4/4] added test cases modifying the annotations --- test/specs/annotation.spec.js | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/specs/annotation.spec.js b/test/specs/annotation.spec.js index fb11e4e05..90c9c5dc0 100644 --- a/test/specs/annotation.spec.js +++ b/test/specs/annotation.spec.js @@ -266,5 +266,39 @@ describe('Annotation plugin', function() { 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]); + }); + }); });