From fedc87b4169866e1baff4835b00e5ad858ea16b9 Mon Sep 17 00:00:00 2001 From: stockiNail Date: Mon, 11 Apr 2022 15:28:33 +0200 Subject: [PATCH 01/14] Enable box annotation label as label sub-element --- src/types/box.js | 100 +++++++++++++++++++++++++++------------------ src/types/label.js | 7 ++++ 2 files changed, 67 insertions(+), 40 deletions(-) diff --git a/src/types/box.js b/src/types/box.js index af77f9ed3..08dd5d0e9 100644 --- a/src/types/box.js +++ b/src/types/box.js @@ -1,6 +1,6 @@ import {Element} from 'chart.js'; import {toPadding, toRadians} from 'chart.js/helpers'; -import {drawBox, drawLabel, getRelativePosition, measureLabelSize, resolveBoxProperties, toPosition, inBoxRange, rotated, translate, getElementCenterPoint} from '../helpers'; +import {drawBox, getRelativePosition, measureLabelSize, resolveBoxProperties, toPosition, inBoxRange, rotated, translate, getElementCenterPoint} from '../helpers'; export default class BoxAnnotation extends Element { @@ -20,32 +20,16 @@ export default class BoxAnnotation extends Element { ctx.restore(); } - drawLabel(ctx) { - const {x, y, width, height, options} = this; - const {label, borderWidth} = options; - const halfBorder = borderWidth / 2; - const position = toPosition(label.position); - const padding = toPadding(label.padding); - const labelSize = measureLabelSize(ctx, label); - const labelRect = { - x: calculateX(this, labelSize, position, padding), - y: calculateY(this, labelSize, position, padding), - width: labelSize.width, - height: labelSize.height - }; - - ctx.save(); - translate(ctx, this.getCenterPoint(), label.rotation); - ctx.beginPath(); - ctx.rect(x + halfBorder + padding.left, y + halfBorder + padding.top, - width - borderWidth - padding.width, height - borderWidth - padding.height); - ctx.clip(); - drawLabel(ctx, labelRect, label); - ctx.restore(); - } - resolveElementProperties(chart, options) { - return resolveBoxProperties(chart, options); + const properties = resolveBoxProperties(chart, options); + const {x, y} = properties; + properties.elements = [{ + type: 'label', + optionScope: 'label', + properties: resolveLabelElementProperties(chart, properties, options) + }]; + properties.initProperties = {x, y}; + return properties; } } @@ -63,7 +47,11 @@ BoxAnnotation.defaults = { borderWidth: 1, display: true, label: { - borderWidth: undefined, + backgroundColor: 'transparent', + borderWidth: 0, + callout: { + display: false, + }, color: 'black', content: null, display: false, @@ -109,31 +97,63 @@ BoxAnnotation.descriptors = { } }; -function calculateX(box, labelSize, position, padding) { - const {x: start, x2: end, width: size, options} = box; - const {xAdjust: adjust, borderWidth} = options.label; - return calculatePosition({start, end, size}, { +function calculateX({properties, options}, labelSize, position, padding) { + const {x: start, x2: end, width: size} = properties; + return calculatePosition({start, end, size, borderWidth: options.borderWidth}, { position: position.x, padding: {start: padding.left, end: padding.right}, - adjust, borderWidth, + adjust: options.label.xAdjust, size: labelSize.width }); } -function calculateY(box, labelSize, position, padding) { - const {y: start, y2: end, height: size, options} = box; - const {yAdjust: adjust, borderWidth} = options.label; - return calculatePosition({start, end, size}, { +function calculateY({properties, options}, labelSize, position, padding) { + const {y: start, y2: end, height: size} = properties; + return calculatePosition({start, end, size, borderWidth: options.borderWidth}, { position: position.y, padding: {start: padding.top, end: padding.bottom}, - adjust, borderWidth, + adjust: options.label.yAdjust, size: labelSize.height }); } function calculatePosition(boxOpts, labelOpts) { - const {start, end} = boxOpts; - const {position, padding: {start: padStart, end: padEnd}, adjust, borderWidth} = labelOpts; + const {start, end, borderWidth} = boxOpts; + const {position, padding: {start: padStart, end: padEnd}, adjust} = labelOpts; const availableSize = end - borderWidth - start - padStart - padEnd - labelOpts.size; - return start + borderWidth / 2 + adjust + padStart + getRelativePosition(availableSize, position); + return start + borderWidth / 2 + adjust + getRelativePosition(availableSize, position); +} + +function getBox(properties, padding, borderWidth) { + const {x, y, width, height} = properties; + const halfBorder = borderWidth / 2; + return { + x: x + halfBorder + padding.left, + y: y + halfBorder + padding.top, + width: width - borderWidth - padding.width, + height: height - borderWidth - padding.height + }; +} + +function resolveLabelElementProperties(chart, properties, options) { + const label = options.label; + const position = toPosition(label.position); + const padding = toPadding(label.padding); + const labelSize = measureLabelSize(chart.ctx, label); + const borderWidth = options.borderWidth; + const x = calculateX({properties, options}, labelSize, position, padding); + const y = calculateY({properties, options}, labelSize, position, padding); + const width = labelSize.width + padding.width; + const height = labelSize.height + padding.height; + return { + x, + y, + x2: x + width, + y2: y + height, + width, + height, + centerX: x + width / 2, + centerY: y + height / 2, + box: getBox(properties, padding, borderWidth) + }; } diff --git a/src/types/label.js b/src/types/label.js index abdf792ce..ad50561aa 100644 --- a/src/types/label.js +++ b/src/types/label.js @@ -24,6 +24,13 @@ export default class LabelAnnotation extends Element { translate(ctx, this.getCenterPoint(), options.rotation); drawCallout(ctx, this); drawBox(ctx, this, options); + if (this.box) { + const {x, y, width, height} = this.box; + // clip + ctx.beginPath(); + ctx.rect(x, y, width, height); + ctx.clip(); + } drawLabel(ctx, getLabelSize(this), options); ctx.restore(); } From d274cbee275a3491cf994b13d1f714b415031c1d Mon Sep 17 00:00:00 2001 From: stockiNail Date: Mon, 11 Apr 2022 15:56:05 +0200 Subject: [PATCH 02/14] overrides label default because box label can have different behaviors --- src/types/box.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/types/box.js b/src/types/box.js index 08dd5d0e9..93be39b6c 100644 --- a/src/types/box.js +++ b/src/types/box.js @@ -50,7 +50,7 @@ BoxAnnotation.defaults = { backgroundColor: 'transparent', borderWidth: 0, callout: { - display: false, + display: false }, color: 'black', content: null, @@ -137,6 +137,8 @@ function getBox(properties, padding, borderWidth) { function resolveLabelElementProperties(chart, properties, options) { const label = options.label; + label.backgroundColor = 'transparent'; + label.callout.display = false; const position = toPosition(label.position); const padding = toPadding(label.padding); const labelSize = measureLabelSize(chart.ctx, label); From 2c92e986db5017c69b29e60f69bab9ec5463c343 Mon Sep 17 00:00:00 2001 From: stockiNail Date: Mon, 11 Apr 2022 19:09:14 +0200 Subject: [PATCH 03/14] adds bounding box to clip the box label --- src/annotation.js | 6 +++--- src/types/box.js | 29 +++++++++++++++-------------- src/types/label.js | 6 +++--- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/annotation.js b/src/annotation.js index 45d25ab69..a49e40b2f 100644 --- a/src/annotation.js +++ b/src/annotation.js @@ -160,10 +160,10 @@ function draw(chart, caller, clip) { }); } -function drawElements(ctx, elements, caller) { +function drawElements(ctx, elements, caller, parent) { for (const el of elements) { if (el.options.drawTime === caller) { - el.draw(ctx); + el.draw(ctx, parent); } } } @@ -171,7 +171,7 @@ function drawElements(ctx, elements, caller) { function drawSubElements(ctx, elements, caller) { for (const el of elements) { if (isArray(el.elements)) { - drawElements(ctx, el.elements, caller); + drawElements(ctx, el.elements, caller, el); } } } diff --git a/src/types/box.js b/src/types/box.js index 93be39b6c..35b2f57da 100644 --- a/src/types/box.js +++ b/src/types/box.js @@ -20,6 +20,20 @@ export default class BoxAnnotation extends Element { ctx.restore(); } + getBoundingBox() { + const {x, y, width, height} = this.getProps('x', 'y', 'width', 'height'); + const label = this.options.label; + const padding = toPadding(label.padding); + const borderWidth = this.options.borderWidth; + const halfBorder = borderWidth / 2; + return { + x: x + halfBorder + padding.left, + y: y + halfBorder + padding.top, + width: width - borderWidth - padding.width, + height: height - borderWidth - padding.height + }; + } + resolveElementProperties(chart, options) { const properties = resolveBoxProperties(chart, options); const {x, y} = properties; @@ -124,17 +138,6 @@ function calculatePosition(boxOpts, labelOpts) { return start + borderWidth / 2 + adjust + getRelativePosition(availableSize, position); } -function getBox(properties, padding, borderWidth) { - const {x, y, width, height} = properties; - const halfBorder = borderWidth / 2; - return { - x: x + halfBorder + padding.left, - y: y + halfBorder + padding.top, - width: width - borderWidth - padding.width, - height: height - borderWidth - padding.height - }; -} - function resolveLabelElementProperties(chart, properties, options) { const label = options.label; label.backgroundColor = 'transparent'; @@ -142,7 +145,6 @@ function resolveLabelElementProperties(chart, properties, options) { const position = toPosition(label.position); const padding = toPadding(label.padding); const labelSize = measureLabelSize(chart.ctx, label); - const borderWidth = options.borderWidth; const x = calculateX({properties, options}, labelSize, position, padding); const y = calculateY({properties, options}, labelSize, position, padding); const width = labelSize.width + padding.width; @@ -155,7 +157,6 @@ function resolveLabelElementProperties(chart, properties, options) { width, height, centerX: x + width / 2, - centerY: y + height / 2, - box: getBox(properties, padding, borderWidth) + centerY: y + height / 2 }; } diff --git a/src/types/label.js b/src/types/label.js index ad50561aa..edfb8d1d5 100644 --- a/src/types/label.js +++ b/src/types/label.js @@ -15,7 +15,7 @@ export default class LabelAnnotation extends Element { return getElementCenterPoint(this, useFinalPosition); } - draw(ctx) { + draw(ctx, parent) { const options = this.options; if (!options.content) { return; @@ -24,8 +24,8 @@ export default class LabelAnnotation extends Element { translate(ctx, this.getCenterPoint(), options.rotation); drawCallout(ctx, this); drawBox(ctx, this, options); - if (this.box) { - const {x, y, width, height} = this.box; + if (parent && 'getBoundingBox' in parent) { + const {x, y, width, height} = parent.getBoundingBox(); // clip ctx.beginPath(); ctx.rect(x, y, width, height); From 4c82b88de813a199d5ab732bd3a49f62a052e2de Mon Sep 17 00:00:00 2001 From: stockiNail Date: Tue, 12 Apr 2022 09:50:29 +0200 Subject: [PATCH 04/14] fixes call to getProps --- src/types/box.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/box.js b/src/types/box.js index 35b2f57da..1bd0e2f15 100644 --- a/src/types/box.js +++ b/src/types/box.js @@ -21,7 +21,7 @@ export default class BoxAnnotation extends Element { } getBoundingBox() { - const {x, y, width, height} = this.getProps('x', 'y', 'width', 'height'); + const {x, y, width, height} = this.getProps(['x', 'y', 'width', 'height']); const label = this.options.label; const padding = toPadding(label.padding); const borderWidth = this.options.borderWidth; From 9a15346f826e9d9cb530329c5b6f29d0242ebed9 Mon Sep 17 00:00:00 2001 From: stockiNail Date: Tue, 12 Apr 2022 10:32:48 +0200 Subject: [PATCH 05/14] fixes check if display is disabled --- src/types/box.js | 17 ++++++++++------- src/types/label.js | 2 +- test/fixtures/box/label-dynamic.js | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/types/box.js b/src/types/box.js index 1bd0e2f15..7bf3be69f 100644 --- a/src/types/box.js +++ b/src/types/box.js @@ -36,13 +36,16 @@ export default class BoxAnnotation extends Element { resolveElementProperties(chart, options) { const properties = resolveBoxProperties(chart, options); - const {x, y} = properties; - properties.elements = [{ - type: 'label', - optionScope: 'label', - properties: resolveLabelElementProperties(chart, properties, options) - }]; - properties.initProperties = {x, y}; + const label = options.label; + if (label && label.content) { + const {x, y} = properties; + properties.elements = [{ + type: 'label', + optionScope: 'label', + properties: resolveLabelElementProperties(chart, properties, options) + }]; + properties.initProperties = {x, y}; + } return properties; } } diff --git a/src/types/label.js b/src/types/label.js index edfb8d1d5..0e7c508bd 100644 --- a/src/types/label.js +++ b/src/types/label.js @@ -17,7 +17,7 @@ export default class LabelAnnotation extends Element { draw(ctx, parent) { const options = this.options; - if (!options.content) { + if (!options.display || !options.content) { return; } ctx.save(); diff --git a/test/fixtures/box/label-dynamic.js b/test/fixtures/box/label-dynamic.js index d99e14c5d..45b13f6c2 100644 --- a/test/fixtures/box/label-dynamic.js +++ b/test/fixtures/box/label-dynamic.js @@ -31,7 +31,7 @@ module.exports = { content: 'This is dynamic!', }, enter({element}) { - element.options.label.display = true; + element.elements[0].options.display = true; return true; } }, From 30ea10b2f5d9150d83a0ccb1940a10b4099d1562 Mon Sep 17 00:00:00 2001 From: stockiNail Date: Tue, 12 Apr 2022 20:47:56 +0200 Subject: [PATCH 06/14] creates always the label sub element --- src/types/box.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/types/box.js b/src/types/box.js index 7bf3be69f..1bd0e2f15 100644 --- a/src/types/box.js +++ b/src/types/box.js @@ -36,16 +36,13 @@ export default class BoxAnnotation extends Element { resolveElementProperties(chart, options) { const properties = resolveBoxProperties(chart, options); - const label = options.label; - if (label && label.content) { - const {x, y} = properties; - properties.elements = [{ - type: 'label', - optionScope: 'label', - properties: resolveLabelElementProperties(chart, properties, options) - }]; - properties.initProperties = {x, y}; - } + const {x, y} = properties; + properties.elements = [{ + type: 'label', + optionScope: 'label', + properties: resolveLabelElementProperties(chart, properties, options) + }]; + properties.initProperties = {x, y}; return properties; } } From 7567865075a63129b2fe22732b51b1042a4e3e4d Mon Sep 17 00:00:00 2001 From: stockiNail Date: Tue, 12 Apr 2022 20:48:40 +0200 Subject: [PATCH 07/14] adds note about breaking change to migration guide --- docs/guide/migrationV2.md | 14 ++++++++++++++ docs/samples/interaction.md | 20 ++++++++++---------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/docs/guide/migrationV2.md b/docs/guide/migrationV2.md index c28a5c0e9..67f06ebf5 100644 --- a/docs/guide/migrationV2.md +++ b/docs/guide/migrationV2.md @@ -20,6 +20,20 @@ A number of changes were made to the configuration options passed to the plugin ## Elements +In `chartjs-plugin-annotation` plugin version 2 the label of box annotation is a sub-element. This has changed how to access to the label options. Now the label options are at `element.elements[0].options`. The following example shows how to show and hide the label when the mouse is hovering the box: + +```javascript +type: 'box', +enter: function({element}) { + element.elements[0].options.display = true; + return true; +}, +leave: function({element}) { + element.elements[0].options.display = false; + return true; +}, +``` + `chartjs-plugin-annotation` plugin version 2 hides the following methods in the `line` annotation element because they should be used only internally: * `intersects` diff --git a/docs/samples/interaction.md b/docs/samples/interaction.md index bb86a323d..e260d6281 100644 --- a/docs/samples/interaction.md +++ b/docs/samples/interaction.md @@ -30,16 +30,16 @@ const annotation1 = { borderColor: 'rgb(255, 245, 157)', borderWidth: 2, enter: function({element}) { - console.log(element.options.label.content + ' entered'); - element.options.label.font.size = 14; + console.log(element.elements[0].options.content + ' entered'); + element.elements[0].options.font.size = 14; return true; }, click: function({element}) { - console.log(element.options.label.content + ' clicked'); + console.log(element.elements[0].options.content + ' clicked'); }, leave: function({element}) { - console.log(element.options.label.content + ' left'); - element.options.label.font.size = 12; + console.log(element.elements[0].options.content + ' left'); + element.elements[0].options.font.size = 12; return true; }, label: { @@ -68,16 +68,16 @@ const annotation2 = { borderColor: 'rgb(165, 214, 167)', borderWidth: 2, enter: function({element}) { - console.log(element.options.label.content + ' entered'); - element.options.label.font.size = 14; + console.log(element.elements[0].options.content + ' entered'); + element.elements[0].options.font.size = 14; return true; }, click: function({element}) { - console.log(element.options.label.content + ' clicked'); + console.log(element.elements[0].options.content + ' clicked'); }, leave: function({element}) { - console.log(element.options.label.content + ' left'); - element.options.label.font.size = 12; + console.log(element.elements[0].options.content + ' left'); + element.elements[0].options.font.size = 12; return true; }, label: { From 60e1ae387b7219574eeb2688e326b9ec4944ea25 Mon Sep 17 00:00:00 2001 From: stockiNail Date: Tue, 12 Apr 2022 20:50:00 +0200 Subject: [PATCH 08/14] adds elements to definition type --- types/element.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/types/element.d.ts b/types/element.d.ts index 399043db9..d6480a27e 100644 --- a/types/element.d.ts +++ b/types/element.d.ts @@ -9,5 +9,6 @@ export interface AnnotationElement { centerY: number, height: number, width: number, + elements?: AnnotationElement[], options: AnnotationOptions } From e93ff34008d9f5724fb51f539a60ab96d0573f0d Mon Sep 17 00:00:00 2001 From: stockiNail Date: Wed, 13 Apr 2022 10:37:38 +0200 Subject: [PATCH 09/14] apply review about fast path to the label sub element --- docs/guide/migrationV2.md | 6 +++--- docs/samples/interaction.md | 20 ++++++++++---------- src/types/box.js | 4 ++++ test/fixtures/box/label-dynamic.js | 2 +- types/element.d.ts | 2 +- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/docs/guide/migrationV2.md b/docs/guide/migrationV2.md index 67f06ebf5..7ebdc5b5f 100644 --- a/docs/guide/migrationV2.md +++ b/docs/guide/migrationV2.md @@ -20,16 +20,16 @@ A number of changes were made to the configuration options passed to the plugin ## Elements -In `chartjs-plugin-annotation` plugin version 2 the label of box annotation is a sub-element. This has changed how to access to the label options. Now the label options are at `element.elements[0].options`. The following example shows how to show and hide the label when the mouse is hovering the box: +In `chartjs-plugin-annotation` plugin version 2 the label of box annotation is a sub-element. This has changed how to access to the label options. Now the label options are at `element.label.options`. The following example shows how to show and hide the label when the mouse is hovering the box: ```javascript type: 'box', enter: function({element}) { - element.elements[0].options.display = true; + element.label.options.display = true; return true; }, leave: function({element}) { - element.elements[0].options.display = false; + element.label.options.display = false; return true; }, ``` diff --git a/docs/samples/interaction.md b/docs/samples/interaction.md index e260d6281..15ef272d9 100644 --- a/docs/samples/interaction.md +++ b/docs/samples/interaction.md @@ -30,16 +30,16 @@ const annotation1 = { borderColor: 'rgb(255, 245, 157)', borderWidth: 2, enter: function({element}) { - console.log(element.elements[0].options.content + ' entered'); - element.elements[0].options.font.size = 14; + console.log(element.label.options.content + ' entered'); + element.label.options.font.size = 14; return true; }, click: function({element}) { - console.log(element.elements[0].options.content + ' clicked'); + console.log(element.label.options.content + ' clicked'); }, leave: function({element}) { - console.log(element.elements[0].options.content + ' left'); - element.elements[0].options.font.size = 12; + console.log(element.label.options.content + ' left'); + element.label.options.font.size = 12; return true; }, label: { @@ -68,16 +68,16 @@ const annotation2 = { borderColor: 'rgb(165, 214, 167)', borderWidth: 2, enter: function({element}) { - console.log(element.elements[0].options.content + ' entered'); - element.elements[0].options.font.size = 14; + console.log(element.label.options.content + ' entered'); + element.label.options.font.size = 14; return true; }, click: function({element}) { - console.log(element.elements[0].options.content + ' clicked'); + console.log(element.label.options.content + ' clicked'); }, leave: function({element}) { - console.log(element.elements[0].options.content + ' left'); - element.elements[0].options.font.size = 12; + console.log(element.label.options.content + ' left'); + element.label.options.font.size = 12; return true; }, label: { diff --git a/src/types/box.js b/src/types/box.js index 1bd0e2f15..5739bc5ce 100644 --- a/src/types/box.js +++ b/src/types/box.js @@ -34,6 +34,10 @@ export default class BoxAnnotation extends Element { }; } + get label() { + return this.elements && this.elements[0]; + } + resolveElementProperties(chart, options) { const properties = resolveBoxProperties(chart, options); const {x, y} = properties; diff --git a/test/fixtures/box/label-dynamic.js b/test/fixtures/box/label-dynamic.js index 45b13f6c2..8125c5832 100644 --- a/test/fixtures/box/label-dynamic.js +++ b/test/fixtures/box/label-dynamic.js @@ -31,7 +31,7 @@ module.exports = { content: 'This is dynamic!', }, enter({element}) { - element.elements[0].options.display = true; + element.label.options.display = true; return true; } }, diff --git a/types/element.d.ts b/types/element.d.ts index f1c72a7b8..557aa4aa4 100644 --- a/types/element.d.ts +++ b/types/element.d.ts @@ -12,6 +12,6 @@ export interface AnnotationBoxModel { } export interface AnnotationElement extends AnnotationBoxModel { - elements?: AnnotationElement[], + label?: AnnotationElement, options: AnnotationOptions } From 2ac57137334c5ef7562a46b73ce18e25c34e8f6a Mon Sep 17 00:00:00 2001 From: stockiNail Date: Wed, 13 Apr 2022 11:18:23 +0200 Subject: [PATCH 10/14] apply review --- src/annotation.js | 19 +++++++++---------- src/types/label.js | 8 ++++---- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/annotation.js b/src/annotation.js index a49e40b2f..c65765cd3 100644 --- a/src/annotation.js +++ b/src/annotation.js @@ -143,7 +143,6 @@ function draw(chart, caller, clip) { } drawElements(ctx, visibleElements, caller); - drawSubElements(ctx, visibleElements, caller); if (clip) { unclipArea(ctx); @@ -160,18 +159,18 @@ function draw(chart, caller, clip) { }); } -function drawElements(ctx, elements, caller, parent) { +function drawElements(ctx, elements, caller) { for (const el of elements) { if (el.options.drawTime === caller) { - el.draw(ctx, parent); + el.draw(ctx); } - } -} - -function drawSubElements(ctx, elements, caller) { - for (const el of elements) { - if (isArray(el.elements)) { - drawElements(ctx, el.elements, caller, el); + if (el.elements && el.elements.length) { + const box = 'getBoundingBox' in el ? el.getBoundingBox() : undefined; + for (const sub of el.elements) { + if (sub.options.drawTime === caller) { + sub.draw(ctx, box); + } + } } } } diff --git a/src/types/label.js b/src/types/label.js index 0e7c508bd..240ad30b4 100644 --- a/src/types/label.js +++ b/src/types/label.js @@ -1,6 +1,6 @@ import {Element} from 'chart.js'; import {drawBox, drawLabel, measureLabelSize, getChartPoint, toPosition, setBorderStyle, getSize, inBoxRange, isBoundToPoint, resolveBoxProperties, getRelativePosition, translate, rotated, getElementCenterPoint} from '../helpers'; -import {toPadding, toRadians, distanceBetweenPoints} from 'chart.js/helpers'; +import {toPadding, toRadians, distanceBetweenPoints, isObject} from 'chart.js/helpers'; const positions = ['left', 'bottom', 'top', 'right']; @@ -15,7 +15,7 @@ export default class LabelAnnotation extends Element { return getElementCenterPoint(this, useFinalPosition); } - draw(ctx, parent) { + draw(ctx, box) { const options = this.options; if (!options.display || !options.content) { return; @@ -24,8 +24,8 @@ export default class LabelAnnotation extends Element { translate(ctx, this.getCenterPoint(), options.rotation); drawCallout(ctx, this); drawBox(ctx, this, options); - if (parent && 'getBoundingBox' in parent) { - const {x, y, width, height} = parent.getBoundingBox(); + if (isObject(box)) { + const {x, y, width, height} = box; // clip ctx.beginPath(); ctx.rect(x, y, width, height); From 015190bcaaf6a155c623db839fbf1fcc5c7f8a6a Mon Sep 17 00:00:00 2001 From: stockiNail Date: Wed, 13 Apr 2022 11:26:47 +0200 Subject: [PATCH 11/14] fixes CC --- src/annotation.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/annotation.js b/src/annotation.js index c65765cd3..7c7f9865a 100644 --- a/src/annotation.js +++ b/src/annotation.js @@ -164,12 +164,16 @@ function drawElements(ctx, elements, caller) { if (el.options.drawTime === caller) { el.draw(ctx); } - if (el.elements && el.elements.length) { - const box = 'getBoundingBox' in el ? el.getBoundingBox() : undefined; - for (const sub of el.elements) { - if (sub.options.drawTime === caller) { - sub.draw(ctx, box); - } + drawSubElements(ctx, el, caller); + } +} + +function drawSubElements(ctx, el, caller) { + if (el.elements && el.elements.length) { + const box = 'getBoundingBox' in el ? el.getBoundingBox() : undefined; + for (const sub of el.elements) { + if (sub.options.drawTime === caller) { + sub.draw(ctx, box); } } } From cf006f2df763bfde1d3de0a8f5eb99d13ace3e8a Mon Sep 17 00:00:00 2001 From: stockiNail Date: Wed, 13 Apr 2022 11:30:51 +0200 Subject: [PATCH 12/14] fixes CC 2 --- src/annotation.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/annotation.js b/src/annotation.js index 7c7f9865a..acbe5c422 100644 --- a/src/annotation.js +++ b/src/annotation.js @@ -164,17 +164,17 @@ function drawElements(ctx, elements, caller) { if (el.options.drawTime === caller) { el.draw(ctx); } - drawSubElements(ctx, el, caller); + if (el.elements && el.elements.length) { + drawSubElements(ctx, el, caller); + } } } function drawSubElements(ctx, el, caller) { - if (el.elements && el.elements.length) { - const box = 'getBoundingBox' in el ? el.getBoundingBox() : undefined; - for (const sub of el.elements) { - if (sub.options.drawTime === caller) { - sub.draw(ctx, box); - } + const box = 'getBoundingBox' in el ? el.getBoundingBox() : undefined; + for (const sub of el.elements) { + if (sub.options.drawTime === caller) { + sub.draw(ctx, box); } } } From eb0b54adad5be3ee8fa6a4612c5a41b8fbb8c81d Mon Sep 17 00:00:00 2001 From: stockiNail Date: Wed, 13 Apr 2022 13:16:17 +0200 Subject: [PATCH 13/14] changes the elements draw --- src/annotation.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/annotation.js b/src/annotation.js index acbe5c422..fa00ad07c 100644 --- a/src/annotation.js +++ b/src/annotation.js @@ -142,7 +142,10 @@ function draw(chart, caller, clip) { clipArea(ctx, chartArea); } - drawElements(ctx, visibleElements, caller); + const todraw = drawElements(ctx, visibleElements, caller); + for (const item of todraw) { + item.element.draw(ctx, item.box); + } if (clip) { unclipArea(ctx); @@ -160,21 +163,23 @@ function draw(chart, caller, clip) { } function drawElements(ctx, elements, caller) { + const todraw = []; for (const el of elements) { if (el.options.drawTime === caller) { - el.draw(ctx); + todraw.push({element: el}); } if (el.elements && el.elements.length) { - drawSubElements(ctx, el, caller); + drawSubElements(ctx, el, caller, todraw); } } + return todraw; } -function drawSubElements(ctx, el, caller) { +function drawSubElements(ctx, el, caller, todraw) { const box = 'getBoundingBox' in el ? el.getBoundingBox() : undefined; for (const sub of el.elements) { if (sub.options.drawTime === caller) { - sub.draw(ctx, box); + todraw.push({element: sub, box}); } } } From 2ba2aab24220a096f8ee6018320af3a092b210a4 Mon Sep 17 00:00:00 2001 From: stockiNail Date: Wed, 13 Apr 2022 15:44:10 +0200 Subject: [PATCH 14/14] apply review --- src/annotation.js | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/annotation.js b/src/annotation.js index fa00ad07c..7568c06d4 100644 --- a/src/annotation.js +++ b/src/annotation.js @@ -135,17 +135,16 @@ export default { }; function draw(chart, caller, clip) { - const {ctx, chartArea} = chart; + const {ctx, canvas, chartArea} = chart; const {visibleElements} = chartStates.get(chart); + let box = {x: 0, y: 0, width: canvas.width, height: canvas.height}; if (clip) { clipArea(ctx, chartArea); + box = {x: chartArea.left, y: chartArea.top, width: chartArea.width, height: chartArea.height}; } - const todraw = drawElements(ctx, visibleElements, caller); - for (const item of todraw) { - item.element.draw(ctx, item.box); - } + drawElements(ctx, visibleElements, caller, box); if (clip) { unclipArea(ctx); @@ -162,24 +161,18 @@ function draw(chart, caller, clip) { }); } -function drawElements(ctx, elements, caller) { - const todraw = []; +function drawElements(ctx, elements, caller, area) { for (const el of elements) { if (el.options.drawTime === caller) { - todraw.push({element: el}); + el.draw(ctx); } if (el.elements && el.elements.length) { - drawSubElements(ctx, el, caller, todraw); - } - } - return todraw; -} - -function drawSubElements(ctx, el, caller, todraw) { - const box = 'getBoundingBox' in el ? el.getBoundingBox() : undefined; - for (const sub of el.elements) { - if (sub.options.drawTime === caller) { - todraw.push({element: sub, box}); + const box = 'getBoundingBox' in el ? el.getBoundingBox() : area; + for (const sub of el.elements) { + if (sub.options.drawTime === caller) { + sub.draw(ctx, box); + } + } } } }