diff --git a/src/transforms/stack.js b/src/transforms/stack.js index 20d7342e03..f1f4e7797d 100644 --- a/src/transforms/stack.js +++ b/src/transforms/stack.js @@ -92,8 +92,8 @@ function stack(x, y = one, kx, ky, {offset, order, reverse}, options) { const Z = valueof(data, z); const compare = order && order(data, X, Y, Z); const n = lengthof(data); - const Y1 = setY1(new Float64Array(n)); - const Y2 = setY2(new Float64Array(n)); + const Y1 = setY1(new Float64Array(n).fill(NaN)); + const Y2 = setY2(new Float64Array(n).fill(NaN)); const facetstacks = []; for (const facet of facets) { const stacks = X ? Array.from(group(facet, (i) => X[i]).values()) : [facet]; @@ -105,8 +105,7 @@ function stack(x, y = one, kx, ky, {offset, order, reverse}, options) { for (const i of stack) { const y = Y[i]; if (y < 0) yn = Y2[i] = (Y1[i] = yn) + y; - else if (y > 0) yp = Y2[i] = (Y1[i] = yp) + y; - else Y2[i] = Y1[i] = yp; // NaN or zero + else if (y >= 0) yp = Y2[i] = (Y1[i] = yp) + y; } } facetstacks.push(stacks); diff --git a/test/output/availability.svg b/test/output/availability.svg index d7b62e3276..0e552df66c 100644 --- a/test/output/availability.svg +++ b/test/output/availability.svg @@ -49,7 +49,7 @@ Apr - + diff --git a/test/output/downloads.svg b/test/output/downloads.svg index 44f6609c2b..5d36dcdcf5 100644 --- a/test/output/downloads.svg +++ b/test/output/downloads.svg @@ -61,7 +61,7 @@ 2022 - + diff --git a/test/output/emptyFacet.svg b/test/output/emptyFacet.svg index 5b48273f27..519d8ac839 100644 --- a/test/output/emptyFacet.svg +++ b/test/output/emptyFacet.svg @@ -24,16 +24,6 @@ TYPE - - - - 0 - - VALUE diff --git a/test/output/integerIntervalArea.html b/test/output/integerIntervalArea.html index d7073c9069..762c0649d0 100644 --- a/test/output/integerIntervalArea.html +++ b/test/output/integerIntervalArea.html @@ -97,8 +97,8 @@ x → - - + + diff --git a/test/output/integerIntervalAreaZ.html b/test/output/integerIntervalAreaZ.html index 400c6b5b66..2b0458ebf9 100644 --- a/test/output/integerIntervalAreaZ.html +++ b/test/output/integerIntervalAreaZ.html @@ -91,9 +91,9 @@ x → - - - + + + diff --git a/test/output/seattlePrecipitationSum.svg b/test/output/seattlePrecipitationSum.svg index bc85171598..625aa63e47 100644 --- a/test/output/seattlePrecipitationSum.svg +++ b/test/output/seattlePrecipitationSum.svg @@ -75,12 +75,6 @@ 31 - - - - - - diff --git a/test/output/stackNaN.svg b/test/output/stackNaN.svg new file mode 100644 index 0000000000..d58b2010e7 --- /dev/null +++ b/test/output/stackNaN.svg @@ -0,0 +1,125 @@ + + + + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + + + ↑ Unemployed (thousands) + + + + 2000 + 2001 + 2002 + 2003 + 2004 + 2005 + 2006 + 2007 + 2008 + 2009 + 2010 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/index.ts b/test/plots/index.ts index c3de1477f8..19bc952011 100644 --- a/test/plots/index.ts +++ b/test/plots/index.ts @@ -299,6 +299,7 @@ import "./single-value-bin.js"; import "./software-versions.js"; import "./sparse-cell.js"; import "./sparse-title.js"; +import "./stack-nan.js"; import "./stacked-bar.js"; import "./stacked-rect.js"; import "./stargazers-binned.js"; diff --git a/test/plots/stack-nan.ts b/test/plots/stack-nan.ts new file mode 100644 index 0000000000..45bb02a84a --- /dev/null +++ b/test/plots/stack-nan.ts @@ -0,0 +1,23 @@ +import * as Plot from "@observablehq/plot"; +import * as d3 from "d3"; +import {test} from "test/plot"; + +test(async function stackNaN() { + const industries = await d3.csv("data/bls-industry-unemployment.csv", d3.autoType); + for (const [i, [, D]] of d3.groups(industries, (d) => d.industry).entries()) { + const lo = Date.UTC(2000 + i, 0, 1, 8); + const hi = Date.UTC(2002 + i, 0, 1, 8); + for (const d of D) { + if (d.date >= lo && d.date < hi) { + d.unemployed = NaN; + } + } + } + return Plot.plot({ + y: {grid: true, label: "Unemployed (thousands)", transform: (d) => d / 1000}, + marks: [ + Plot.areaY(industries, {x: "date", y: "unemployed", fill: "industry", fillOpacity: 0.5}), + Plot.lineY(industries, Plot.stackY({x: "date", y: "unemployed", stroke: "industry"})) + ] + }); +});