From c5c39c4eae8fbadedc76dfb84beebf51e58bb3c6 Mon Sep 17 00:00:00 2001 From: ania Date: Thu, 23 Apr 2026 13:38:07 +0200 Subject: [PATCH 1/4] Fixed #5, the chart didn't render without dataLabels enabled. --- js/ternary-plot.js | 4 +++- ts/ternary-plot.ts | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/js/ternary-plot.js b/js/ternary-plot.js index 36a7813..5b600af 100644 --- a/js/ternary-plot.js +++ b/js/ternary-plot.js @@ -590,7 +590,9 @@ function TernaryPlotPlugin(H) { e.isInsidePlot = pointInTriangle(px, py, Ax, Ay, Bx, By, Cx, Cy); }); addEvent(Series, 'afterDrawDataLabels', function () { - if (!(this.options.minSize && this.options.maxSize)) { + var _a; + if (!(this.options.minSize && this.options.maxSize) || + !((_a = (this.options.dataLabels)) === null || _a === void 0 ? void 0 : _a.enabled)) { return; } this.points.forEach(point => { diff --git a/ts/ternary-plot.ts b/ts/ternary-plot.ts index 272d7fb..bf1d849 100644 --- a/ts/ternary-plot.ts +++ b/ts/ternary-plot.ts @@ -115,6 +115,7 @@ type TernarySeriesOptions = Highcharts.SeriesOptions & { minSize?: number; maxSize?: number; componentColors?: ComponentColors; + dataLabels?: Highcharts.DataLabelsOptions; }; type TernarySeries = Highcharts.Series & { @@ -1071,7 +1072,10 @@ export default function TernaryPlotPlugin(H: HighchartsPlugin): void { }); addEvent(Series, 'afterDrawDataLabels', function (this: TernarySeries) { - if (!(this.options.minSize && this.options.maxSize)) { + if ( + !(this.options.minSize && this.options.maxSize) || + !(this.options.dataLabels)?.enabled + ) { return; } From 518864a41b19b1ccf5c82502468c17ffa7446b17 Mon Sep 17 00:00:00 2001 From: ania Date: Thu, 23 Apr 2026 17:33:58 +0200 Subject: [PATCH 2/4] Added type for when dataLabels is an array. Updated condition. --- js/ternary-plot.js | 10 +++++++--- ts/ternary-plot.ts | 14 +++++++++----- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/js/ternary-plot.js b/js/ternary-plot.js index 5b600af..33ed8d0 100644 --- a/js/ternary-plot.js +++ b/js/ternary-plot.js @@ -590,9 +590,13 @@ function TernaryPlotPlugin(H) { e.isInsidePlot = pointInTriangle(px, py, Ax, Ay, Bx, By, Cx, Cy); }); addEvent(Series, 'afterDrawDataLabels', function () { - var _a; - if (!(this.options.minSize && this.options.maxSize) || - !((_a = (this.options.dataLabels)) === null || _a === void 0 ? void 0 : _a.enabled)) { + // Data labels can be enabled either as a single object or as an array + // of objects (#5) + const dataLabels = this.options.dataLabels; + const dataLabelsEnabled = Array.isArray(dataLabels) + ? dataLabels.some(d => d.enabled !== false) + : (dataLabels === null || dataLabels === void 0 ? void 0 : dataLabels.enabled) !== false; + if (!(this.options.minSize && this.options.maxSize) || !dataLabelsEnabled) { return; } this.points.forEach(point => { diff --git a/ts/ternary-plot.ts b/ts/ternary-plot.ts index bf1d849..aaeaffc 100644 --- a/ts/ternary-plot.ts +++ b/ts/ternary-plot.ts @@ -115,7 +115,7 @@ type TernarySeriesOptions = Highcharts.SeriesOptions & { minSize?: number; maxSize?: number; componentColors?: ComponentColors; - dataLabels?: Highcharts.DataLabelsOptions; + dataLabels?: Highcharts.DataLabelsOptions | Highcharts.DataLabelsOptions[]; }; type TernarySeries = Highcharts.Series & { @@ -1072,10 +1072,14 @@ export default function TernaryPlotPlugin(H: HighchartsPlugin): void { }); addEvent(Series, 'afterDrawDataLabels', function (this: TernarySeries) { - if ( - !(this.options.minSize && this.options.maxSize) || - !(this.options.dataLabels)?.enabled - ) { + // Data labels can be enabled either as a single object or as an array + // of objects (#5) + const dataLabels = this.options.dataLabels; + const dataLabelsEnabled = Array.isArray(dataLabels) + ? (dataLabels as Highcharts.DataLabelsOptions[]).some(d => d.enabled !== false) + : dataLabels?.enabled !== false; + + if (!(this.options.minSize && this.options.maxSize) || !dataLabelsEnabled) { return; } From 9a5ca51f52e88e88c13392730cddb262854b6043 Mon Sep 17 00:00:00 2001 From: ania Date: Fri, 24 Apr 2026 10:11:12 +0200 Subject: [PATCH 3/4] Added regression test. --- tests/dataLabels.test.ts | 51 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 tests/dataLabels.test.ts diff --git a/tests/dataLabels.test.ts b/tests/dataLabels.test.ts new file mode 100644 index 0000000..eb32c23 --- /dev/null +++ b/tests/dataLabels.test.ts @@ -0,0 +1,51 @@ +import { describe, it, expect } from 'vitest'; + +// Regression test for #5: the afterDrawDataLabels handler must skip +// repositioning when dataLabels is disabled, and must handle both the +// object form and the array form of the dataLabels option. +// +// The condition from the plugin, extracted for unit testing: +// const dl = this.options.dataLabels; +// const labelsEnabled = Array.isArray(dl) +// ? (dl as Highcharts.DataLabelsOptions[]).some(d => d.enabled !== false) +// : dl?.enabled !== false; + +type DL = { enabled?: boolean }; + +function labelsEnabled(dl: DL | DL[] | undefined): boolean { + return Array.isArray(dl) + ? dl.some(d => d.enabled !== false) + : dl?.enabled !== false; +} + +describe('labelsEnabled', () => { + + it('returns true when dataLabels is undefined', () => { + expect(labelsEnabled(undefined)).toBe(true); + }); + + it('returns true when dataLabels has no enabled property', () => { + expect(labelsEnabled({})).toBe(true); + }); + + it('returns true when dataLabels.enabled is true', () => { + expect(labelsEnabled({ enabled: true })).toBe(true); + }); + + it('returns false when dataLabels.enabled is false', () => { + expect(labelsEnabled({ enabled: false })).toBe(false); + }); + + it('returns true when dataLabels is an array with at least one enabled item', () => { + expect(labelsEnabled([{ enabled: false }, { enabled: true }])).toBe(true); + }); + + it('returns true when dataLabels is an array with no explicit enabled property', () => { + expect(labelsEnabled([{}, {}])).toBe(true); + }); + + it('returns false when dataLabels is an array with all items disabled', () => { + expect(labelsEnabled([{ enabled: false }, { enabled: false }])).toBe(false); + }); + +}); From 78b1d5a9f06484178d8bef9fd0993969d2e7e037 Mon Sep 17 00:00:00 2001 From: ania Date: Thu, 30 Apr 2026 00:30:29 +0200 Subject: [PATCH 4/4] Update fix to use H.splat, remove test. --- js/ternary-plot.js | 8 +++---- tests/dataLabels.test.ts | 51 ---------------------------------------- ts/ternary-plot.ts | 8 +++---- 3 files changed, 8 insertions(+), 59 deletions(-) delete mode 100644 tests/dataLabels.test.ts diff --git a/js/ternary-plot.js b/js/ternary-plot.js index 33ed8d0..04bfb20 100644 --- a/js/ternary-plot.js +++ b/js/ternary-plot.js @@ -592,10 +592,10 @@ function TernaryPlotPlugin(H) { addEvent(Series, 'afterDrawDataLabels', function () { // Data labels can be enabled either as a single object or as an array // of objects (#5) - const dataLabels = this.options.dataLabels; - const dataLabelsEnabled = Array.isArray(dataLabels) - ? dataLabels.some(d => d.enabled !== false) - : (dataLabels === null || dataLabels === void 0 ? void 0 : dataLabels.enabled) !== false; + const dataLabelsOption = this.options.dataLabels; + const dataLabelsEnabled = dataLabelsOption === undefined + ? true + : H.splat(dataLabelsOption).some(d => (d === null || d === void 0 ? void 0 : d.enabled) !== false); if (!(this.options.minSize && this.options.maxSize) || !dataLabelsEnabled) { return; } diff --git a/tests/dataLabels.test.ts b/tests/dataLabels.test.ts deleted file mode 100644 index eb32c23..0000000 --- a/tests/dataLabels.test.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { describe, it, expect } from 'vitest'; - -// Regression test for #5: the afterDrawDataLabels handler must skip -// repositioning when dataLabels is disabled, and must handle both the -// object form and the array form of the dataLabels option. -// -// The condition from the plugin, extracted for unit testing: -// const dl = this.options.dataLabels; -// const labelsEnabled = Array.isArray(dl) -// ? (dl as Highcharts.DataLabelsOptions[]).some(d => d.enabled !== false) -// : dl?.enabled !== false; - -type DL = { enabled?: boolean }; - -function labelsEnabled(dl: DL | DL[] | undefined): boolean { - return Array.isArray(dl) - ? dl.some(d => d.enabled !== false) - : dl?.enabled !== false; -} - -describe('labelsEnabled', () => { - - it('returns true when dataLabels is undefined', () => { - expect(labelsEnabled(undefined)).toBe(true); - }); - - it('returns true when dataLabels has no enabled property', () => { - expect(labelsEnabled({})).toBe(true); - }); - - it('returns true when dataLabels.enabled is true', () => { - expect(labelsEnabled({ enabled: true })).toBe(true); - }); - - it('returns false when dataLabels.enabled is false', () => { - expect(labelsEnabled({ enabled: false })).toBe(false); - }); - - it('returns true when dataLabels is an array with at least one enabled item', () => { - expect(labelsEnabled([{ enabled: false }, { enabled: true }])).toBe(true); - }); - - it('returns true when dataLabels is an array with no explicit enabled property', () => { - expect(labelsEnabled([{}, {}])).toBe(true); - }); - - it('returns false when dataLabels is an array with all items disabled', () => { - expect(labelsEnabled([{ enabled: false }, { enabled: false }])).toBe(false); - }); - -}); diff --git a/ts/ternary-plot.ts b/ts/ternary-plot.ts index aaeaffc..4b29fc5 100644 --- a/ts/ternary-plot.ts +++ b/ts/ternary-plot.ts @@ -1074,10 +1074,10 @@ export default function TernaryPlotPlugin(H: HighchartsPlugin): void { addEvent(Series, 'afterDrawDataLabels', function (this: TernarySeries) { // Data labels can be enabled either as a single object or as an array // of objects (#5) - const dataLabels = this.options.dataLabels; - const dataLabelsEnabled = Array.isArray(dataLabels) - ? (dataLabels as Highcharts.DataLabelsOptions[]).some(d => d.enabled !== false) - : dataLabels?.enabled !== false; + const dataLabelsOption = this.options.dataLabels; + const dataLabelsEnabled = dataLabelsOption === undefined + ? true + : H.splat(dataLabelsOption).some(d => d?.enabled !== false); if (!(this.options.minSize && this.options.maxSize) || !dataLabelsEnabled) { return;