From bd80e5f545f26df616f8751336734043c571c8a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 12 Sep 2023 15:56:29 +0200 Subject: [PATCH] makes {value, scale} channel specification work with the interval transform closes #1329 --- src/transforms/interval.js | 40 +- test/output/intervalScaleOverride.svg | 1078 +++++++++++++++++++++++++ test/plots/index.ts | 1 + test/plots/interval-scale-override.ts | 27 + 4 files changed, 1129 insertions(+), 17 deletions(-) create mode 100644 test/output/intervalScaleOverride.svg create mode 100644 test/plots/interval-scale-override.ts diff --git a/src/transforms/interval.js b/src/transforms/interval.js index a417e83618..8209b478f0 100644 --- a/src/transforms/interval.js +++ b/src/transforms/interval.js @@ -12,7 +12,7 @@ function maybeIntervalValue(value, {interval}) { function maybeIntervalK(k, maybeInsetK, options, trivial) { const {[k]: v, [`${k}1`]: v1, [`${k}2`]: v2} = options; - const {value, interval} = maybeIntervalValue(v, options); + const {value, interval, scale} = maybeIntervalValue(v, options); if (value == null || (interval == null && !trivial)) return options; const label = labelof(v); if (interval == null) { @@ -33,31 +33,37 @@ function maybeIntervalK(k, maybeInsetK, options, trivial) { return maybeInsetK({ ...options, [k]: undefined, - [`${k}1`]: v1 === undefined ? {transform, label} : v1, - [`${k}2`]: v2 === undefined ? {transform: (data) => transform(data).map((v) => interval.offset(v)), label} : v2 + [`${k}1`]: v1 === undefined ? {value: {transform, label}, scale} : v1, + [`${k}2`]: + v2 === undefined + ? {value: {transform: (data) => transform(data).map((v) => interval.offset(v)), label}, scale} + : v2 }); } function maybeIntervalMidK(k, maybeInsetK, options) { const {[k]: v} = options; - const {value, interval} = maybeIntervalValue(v, options); + const {value, interval, scale} = maybeIntervalValue(v, options); if (value == null || interval == null) return options; return maybeInsetK({ ...options, [k]: { - label: labelof(v), - transform: (data) => { - const V1 = map(valueof(data, value), (v) => interval.floor(v)); - const V2 = V1.map((v) => interval.offset(v)); - return V1.map( - isTemporal(V1) - ? (v1, v2) => - v1 == null || isNaN((v1 = +v1)) || ((v2 = V2[v2]), v2 == null) || isNaN((v2 = +v2)) - ? undefined - : new Date((v1 + v2) / 2) - : (v1, v2) => (v1 == null || ((v2 = V2[v2]), v2 == null) ? NaN : (+v1 + +v2) / 2) - ); - } + value: { + label: labelof(v), + transform: (data) => { + const V1 = map(valueof(data, value), (v) => interval.floor(v)); + const V2 = V1.map((v) => interval.offset(v)); + return V1.map( + isTemporal(V1) + ? (v1, v2) => + v1 == null || isNaN((v1 = +v1)) || ((v2 = V2[v2]), v2 == null) || isNaN((v2 = +v2)) + ? undefined + : new Date((v1 + v2) / 2) + : (v1, v2) => (v1 == null || ((v2 = V2[v2]), v2 == null) ? NaN : (+v1 + +v2) / 2) + ); + } + }, + scale } }); } diff --git a/test/output/intervalScaleOverride.svg b/test/output/intervalScaleOverride.svg new file mode 100644 index 0000000000..65f4bc6daa --- /dev/null +++ b/test/output/intervalScaleOverride.svg @@ -0,0 +1,1078 @@ + + + + + + + + + + body_mass_g + culmen_depth_mm + culmen_length_mm + species + + + + + + + + Adelie + Chinstrap + Gentoo + + + species + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/index.ts b/test/plots/index.ts index 35ded36808..be6be97631 100644 --- a/test/plots/index.ts +++ b/test/plots/index.ts @@ -130,6 +130,7 @@ export * from "./infinity-log.js"; export * from "./integer-interval.js"; export * from "./intern-facet.js"; export * from "./interval-aware.js"; +export * from "./interval-scale-override.js"; export * from "./intraday-histogram.js"; export * from "./kitten.js"; export * from "./learning-poverty.js"; diff --git a/test/plots/interval-scale-override.ts b/test/plots/interval-scale-override.ts new file mode 100644 index 0000000000..6222dfaa82 --- /dev/null +++ b/test/plots/interval-scale-override.ts @@ -0,0 +1,27 @@ +import * as Plot from "@observablehq/plot"; +import * as d3 from "d3"; + +export async function intervalScaleOverride() { + const penguins = await d3.csv("data/penguins.csv", d3.autoType); + const dimensions = ["culmen_length_mm", "culmen_depth_mm", "body_mass_g"].map((k) => ({ + dimension: k, + scale: Plot.tickX(penguins, {x: k}) + .plot({x: {range: [70, 520]}}) + .scale("x") + })); + return Plot.plot({ + marginLeft: 120, + marks: [ + dimensions.map(({dimension, scale}) => + Plot.dotY(penguins, { + x: {value: (d) => scale.apply(d[dimension]), scale: null}, + interval: 10, + y: () => dimension, + fill: "black", + fillOpacity: 0.1 + }) + ), + Plot.cell(penguins, Plot.groupX({fillOpacity: "proportion"}, {x: "species", y: () => "species", fill: "species"})) + ] + }); +}