From 4127d7dbc011d9c2661f13bbf00c2d9250d34eff Mon Sep 17 00:00:00 2001 From: kurkle Date: Thu, 30 Dec 2021 09:41:42 +0200 Subject: [PATCH] update --- docs/samples/polygon/basic.md | 2 +- package-lock.json | 24 +++++------ src/annotation.js | 78 +++++++++++++++++------------------ src/helpers/helpers.core.js | 14 +++++++ test/index.js | 2 + test/specs/helpers.spec.js | 20 +++++++++ 6 files changed, 88 insertions(+), 52 deletions(-) create mode 100644 test/specs/helpers.spec.js diff --git a/docs/samples/polygon/basic.md b/docs/samples/polygon/basic.md index 42eb8bae0..56fd2c031 100644 --- a/docs/samples/polygon/basic.md +++ b/docs/samples/polygon/basic.md @@ -132,7 +132,7 @@ const actions = [ } }, { - name: 'Remove a side to annotation 1', + name: 'Remove a side from annotation 1', handler: function(chart) { chart.options.plugins.annotation.annotations.annotation1.sides--; chart.update(); diff --git a/package-lock.json b/package-lock.json index 3d488fee0..0263a4727 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7509,9 +7509,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.29", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.29.tgz", - "integrity": "sha512-N2Jbwxo5Rum8G2YXeUxycs1sv4Qme/ry71HG73bv8BvZl+I/4JtRgK/En+ST/Wh/yF1fqvVCY4jZBgMxnhjtBA==", + "version": "1.4.30", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.30.tgz", + "integrity": "sha512-609z9sIMxDHg+TcR/VB3MXwH+uwtrYyeAwWc/orhnr90ixs6WVGSrt85CDLGUdNnLqCA7liv426V20EecjvflQ==", "dev": true }, "node_modules/elliptic": { @@ -10872,9 +10872,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.2.tgz", - "integrity": "sha512-0gHxuT1NNC0aEIL1zbJ+MTgPbbHhU77eJPuU35WKA7TgXiSNlCAx4PENoMrH0Or6M2H80TaZcWKhM0IK6V8gRw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", + "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -25324,9 +25324,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.29", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.29.tgz", - "integrity": "sha512-N2Jbwxo5Rum8G2YXeUxycs1sv4Qme/ry71HG73bv8BvZl+I/4JtRgK/En+ST/Wh/yF1fqvVCY4jZBgMxnhjtBA==", + "version": "1.4.30", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.30.tgz", + "integrity": "sha512-609z9sIMxDHg+TcR/VB3MXwH+uwtrYyeAwWc/orhnr90ixs6WVGSrt85CDLGUdNnLqCA7liv426V20EecjvflQ==", "dev": true }, "elliptic": { @@ -27850,9 +27850,9 @@ } }, "istanbul-reports": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.2.tgz", - "integrity": "sha512-0gHxuT1NNC0aEIL1zbJ+MTgPbbHhU77eJPuU35WKA7TgXiSNlCAx4PENoMrH0Or6M2H80TaZcWKhM0IK6V8gRw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", + "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", "dev": true, "requires": { "html-escaper": "^2.0.0", diff --git a/src/annotation.js b/src/annotation.js index 730834c2f..b83fb7c64 100644 --- a/src/annotation.js +++ b/src/annotation.js @@ -3,31 +3,22 @@ import {clipArea, unclipArea, isObject, isArray} from 'chart.js/helpers'; import {handleEvent, hooks, updateListeners} from './events'; import {adjustScaleRange, verifyScaleOptions} from './scale'; import {annotationTypes} from './types'; +import {requireVersion} from './helpers'; import {version} from '../package.json'; const chartStates = new Map(); -const versionParts = Chart.version.split('.'); export default { id: 'annotation', version, + beforeRegister() { + requireVersion('3.7', Chart.version); + }, + afterRegister() { Chart.register(annotationTypes); - - // TODO: Remove this workaround when strictly requiring Chart.js v3.7 or newer - if (versionParts[0] === '3' && parseInt(versionParts[1], 10) <= 6) { - // Workaround for https://github.com/chartjs/chartjs-plugin-annotation/issues/572 - Chart.defaults.set('elements.lineAnnotation', { - // label - callout: {}, - font: {}, - padding: 6, - // polygon - point: {}, - }); - } }, afterUnregister() { @@ -158,37 +149,46 @@ function updateElements(chart, state, options, mode) { const elements = resyncElements(state.elements, annotations); for (let i = 0; i < annotations.length; i++) { - const annotation = annotations[i]; - let el = elements[i]; - const elementClass = annotationTypes[resolveType(annotation.type)]; - if (!el || !(el instanceof elementClass)) { - el = elements[i] = new elementClass(); - } - const resolver = annotation.setContext(getContext(chart, el, annotation)); - const opts = resolveAnnotationOptions(resolver); - const properties = el.resolveElementProperties(chart, opts); - const subDefs = properties.elements; + const annotationOptions = annotations[i]; + const element = getOrCreateElement(elements, i, annotationOptions.type); + const resolver = annotationOptions.setContext(getContext(chart, element, annotationOptions)); + const resolvedOptions = resolveAnnotationOptions(resolver); + const properties = element.resolveElementProperties(chart, resolvedOptions); properties.skip = isNaN(properties.x) || isNaN(properties.y); - properties.options = opts; - - if (subDefs) { - const elems = el.elements || (el.elements = []); - elems.length = subDefs.length; - for (let j = 0; j < subDefs.length; j++) { - const def = subDefs[j]; - const subProps = def.properties; - const subClass = annotationTypes[resolveType(def.type)]; - const subEl = elems[j] || (elems[j] = new subClass()); - const subOpts = resolveAnnotationOptions((resolver[def.optionScope]).override(def)); - subProps.options = subOpts; - animations.update(subEl, subProps); - } + properties.options = resolvedOptions; + + if ('elements' in properties) { + updateSubElements(element, properties.elements, resolver, animations); + // Remove the sub-element definitions from properties, so the actual elements + // are not overwritten by their definitions delete properties.elements; } - animations.update(el, properties); + animations.update(element, properties); + } +} + +function updateSubElements(mainElement, definitions, resolver, animations) { + const subElements = mainElement.elements || (mainElement.elements = []); + subElements.length = definitions.length; + for (let j = 0; j < definitions.length; j++) { + const definition = definitions[j]; + const subElementProperties = definition.properties; + const subElement = getOrCreateElement(subElements, j, definition.type); + const subElementOptions = resolveAnnotationOptions((resolver[definition.optionScope]).override(definition)); + subElementProperties.options = subElementOptions; + animations.update(subElement, subElementProperties); + } +} + +function getOrCreateElement(elements, index, type) { + const elementClass = annotationTypes[resolveType(type)]; + let element = elements[index]; + if (!element || !(element instanceof elementClass)) { + element = elements[index] = new elementClass(); } + return element; } function resolveAnnotationOptions(resolver) { diff --git a/src/helpers/helpers.core.js b/src/helpers/helpers.core.js index e78fccea6..6608992b4 100644 --- a/src/helpers/helpers.core.js +++ b/src/helpers/helpers.core.js @@ -25,3 +25,17 @@ export function getElementCenterPoint(element, useFinalPosition) { const {x, y} = element.getProps(['x', 'y'], useFinalPosition); return {x, y}; } + +export function requireVersion(min, ver) { + const parts = ver.split('.'); + let i = 0; + for (const req of min.split('.')) { + const act = parts[i++]; + if (parseInt(req, 10) < parseInt(act, 10)) { + break; + } + if (req > act || (act.length > req.length && act.substr(0, req.length) === req)) { + throw new Error(`Chart.js v${ver} is not supported. v${min} or newer is required.`); + } + } +} diff --git a/test/index.js b/test/index.js index be056fc34..a5e3324b4 100644 --- a/test/index.js +++ b/test/index.js @@ -1,7 +1,9 @@ import {acquireChart, addMatchers, releaseCharts, specsFromFixtures, triggerMouseEvent, afterEvent} from 'chartjs-test-utils'; import {testEvents} from './events'; import {createCanvas} from './utils'; +import * as helpers from '../src/helpers'; +window.helpers = helpers; window.devicePixelRatio = 1; window.acquireChart = acquireChart; window.afterEvent = afterEvent; diff --git a/test/specs/helpers.spec.js b/test/specs/helpers.spec.js new file mode 100644 index 000000000..2ed38ac97 --- /dev/null +++ b/test/specs/helpers.spec.js @@ -0,0 +1,20 @@ +describe('helpers', function() { + + describe('requireVersion', function() { + const requireVersion = window.helpers.requireVersion; + + it('should throw error for too old version', function() { + expect(() => requireVersion('3.7', '2.9.3')).toThrowError(); + expect(() => requireVersion('3.7', '3.6.99-alpha3')).toThrowError(); + expect(() => requireVersion('16.13.2.8', '16.13.2.8-beta')).toThrowError(); + }); + + it('should not throw error for new enough version', function() { + expect(() => requireVersion('3.7', '3.7.0-beta.1')).not.toThrowError(); + expect(() => requireVersion('3.7.1', '3.7.19')).not.toThrowError(); + expect(() => requireVersion('3.7', '4.0.0')).not.toThrowError(); + expect(() => requireVersion('16.13.2', '16.13.3-rc')).not.toThrowError(); + }); + }); + +});