From 9eece99629af920f7588c1a216f61698abf9edad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 16 Aug 2023 17:23:19 +0200 Subject: [PATCH 1/2] expose a deduplicated ordinal domain closes #1812 --- src/scales/ordinal.js | 1 + test/scales/scales-test.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/scales/ordinal.js b/src/scales/ordinal.js index 2e7dd0c0de..9cbbb62749 100644 --- a/src/scales/ordinal.js +++ b/src/scales/ordinal.js @@ -15,6 +15,7 @@ export const ordinalImplicit = Symbol("ordinal"); function createScaleO(key, scale, channels, {type, interval, domain, range, reverse, hint}) { interval = maybeRangeInterval(interval, type); if (domain === undefined) domain = inferDomain(channels, interval, key); + domain = [...new InternSet(domain)]; if (type === "categorical" || type === ordinalImplicit) type = "ordinal"; // shorthand for color schemes if (reverse) domain = reverseof(domain); scale.domain(domain); diff --git a/test/scales/scales-test.js b/test/scales/scales-test.js index 2303cfc2ef..146e0e1a92 100644 --- a/test/scales/scales-test.js +++ b/test/scales/scales-test.js @@ -2102,6 +2102,36 @@ it("plot(…).scale(name).apply and invert return the expected functions", () => ]); }); +it("plot(…).scale(name) returns a deduplicated ordinal domain", () => { + const letters = "abbbcaabbcc"; + const plot = Plot.dotX(letters).plot({x: {domain: letters}}); + scaleEqual(plot.scale("x"), { + align: 0.5, + bandwidth: 0, + domain: ["a", "b", "c"], + padding: 0.5, + range: [20, 620], + round: true, + step: 200, + type: "point" + }); +}); + +it("plot(…).scale(name) returns a deduplicated ordinal/temporal domain", () => { + const dates = ["2001", "2002", "2004", "2004"].map(d3.isoParse); + const plot = Plot.dotX(dates).plot({x: {type: "point", domain: dates}}); + scaleEqual(plot.scale("x"), { + align: 0.5, + bandwidth: 0, + domain: dates.slice(0, 3), + padding: 0.5, + range: [20, 620], + round: true, + step: 200, + type: "point" + }); +}); + // Given a plot specification (or, as shorthand, an array of marks or a single // mark), asserts that the given named scales, when materialized from the first // plot and used to produce a second plot, produce the same output and the same From ed1f30af02027430c380abb2b3fccb2958e35ced Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Wed, 16 Aug 2023 08:49:07 -0700 Subject: [PATCH 2/2] =?UTF-8?q?use=20scale=E2=80=99s=20deduplicated=20doma?= =?UTF-8?q?in?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/scales/ordinal.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/scales/ordinal.js b/src/scales/ordinal.js index 9cbbb62749..caf18a4e13 100644 --- a/src/scales/ordinal.js +++ b/src/scales/ordinal.js @@ -15,10 +15,9 @@ export const ordinalImplicit = Symbol("ordinal"); function createScaleO(key, scale, channels, {type, interval, domain, range, reverse, hint}) { interval = maybeRangeInterval(interval, type); if (domain === undefined) domain = inferDomain(channels, interval, key); - domain = [...new InternSet(domain)]; if (type === "categorical" || type === ordinalImplicit) type = "ordinal"; // shorthand for color schemes if (reverse) domain = reverseof(domain); - scale.domain(domain); + domain = scale.domain(domain).domain(); // deduplicate if (range !== undefined) { // If the range is specified as a function, pass it the domain. if (typeof range === "function") range = range(domain);