Skip to content

Commit f4a989c

Browse files
Filmbostock
andauthored
stack invalid values as NaN (#2390)
* stack invalids as NaN * consolidate loop; avoid local time * simplify * fill(NaN) --------- Co-authored-by: Mike Bostock <mbostock@gmail.com>
1 parent bcff148 commit f4a989c

10 files changed

Lines changed: 159 additions & 27 deletions

File tree

src/transforms/stack.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ function stack(x, y = one, kx, ky, {offset, order, reverse}, options) {
9292
const Z = valueof(data, z);
9393
const compare = order && order(data, X, Y, Z);
9494
const n = lengthof(data);
95-
const Y1 = setY1(new Float64Array(n));
96-
const Y2 = setY2(new Float64Array(n));
95+
const Y1 = setY1(new Float64Array(n).fill(NaN));
96+
const Y2 = setY2(new Float64Array(n).fill(NaN));
9797
const facetstacks = [];
9898
for (const facet of facets) {
9999
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) {
105105
for (const i of stack) {
106106
const y = Y[i];
107107
if (y < 0) yn = Y2[i] = (Y1[i] = yn) + y;
108-
else if (y > 0) yp = Y2[i] = (Y1[i] = yp) + y;
109-
else Y2[i] = Y1[i] = yp; // NaN or zero
108+
else if (y >= 0) yp = Y2[i] = (Y1[i] = yp) + y;
110109
}
111110
}
112111
facetstacks.push(stacks);

test/output/availability.svg

Lines changed: 1 addition & 1 deletion
Loading

test/output/downloads.svg

Lines changed: 1 addition & 1 deletion
Loading

test/output/emptyFacet.svg

Lines changed: 0 additions & 10 deletions
Loading

test/output/integerIntervalArea.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@
9797
<text transform="translate(620,370)">x →</text>
9898
</g>
9999
<g aria-label="area" fill-opacity="0.7" stroke-width="2" stroke-linejoin="round" stroke-linecap="round">
100-
<path fill="#4269d0" stroke="#4269d0" d="M40,260.625L330,216.875L620,370L620,370L330,370L40,370Z"></path>
101-
<path fill="#efb118" stroke="#efb118" d="M40,260.625L330,20L620,282.5L620,370L330,216.875L40,260.625Z"></path>
100+
<path fill="#4269d0" stroke="#4269d0" d="M40,260.625L330,216.875L330,370L40,370Z"></path>
101+
<path fill="#efb118" stroke="#efb118" d="M330,20L620,282.5L620,370L330,216.875Z"></path>
102102
</g>
103103
<g aria-label="tip" fill="var(--plot-background)" stroke="currentColor" pointer-events="none" text-anchor="start" transform="translate(0.5,0.5)"></g>
104104
</svg>

test/output/integerIntervalAreaZ.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@
9191
<text transform="translate(620,370)">x →</text>
9292
</g>
9393
<g aria-label="area" fill-opacity="0.7" stroke-width="2" stroke-linejoin="round" stroke-linecap="round">
94-
<path fill="#b2df8a" stroke="#a6cee3" d="M40,267.059L233.333,225.882L426.667,370L620,370L620,370L426.667,370L233.333,370L40,370Z"></path>
95-
<path fill="#33a02c" stroke="#a6cee3" d="M40,267.059L233.333,40.588L426.667,287.647L620,370L620,370L426.667,370L233.333,225.882L40,267.059Z"></path>
96-
<path fill="#fb9a99" stroke="#1f78b4" d="M40,267.059L233.333,20L426.667,287.647L620,225.882L620,370L426.667,287.647L233.333,40.588L40,267.059Z"></path>
94+
<path fill="#b2df8a" stroke="#a6cee3" d="M40,267.059L233.333,225.882L233.333,370L40,370Z"></path>
95+
<path fill="#33a02c" stroke="#a6cee3" d="M233.333,40.588L426.667,287.647L426.667,370L233.333,225.882Z"></path>
96+
<path fill="#fb9a99" stroke="#1f78b4" d="M233.333,20L233.333,40.588ZM620,225.882L620,370Z"></path>
9797
</g>
9898
<g aria-label="tip" fill="var(--plot-background)" stroke="currentColor" pointer-events="none" text-anchor="start" transform="translate(0.5,0.5)"></g>
9999
</svg>

test/output/seattlePrecipitationSum.svg

Lines changed: 0 additions & 6 deletions
Loading

test/output/stackNaN.svg

Lines changed: 125 additions & 0 deletions
Loading

test/plots/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ import "./single-value-bin.js";
299299
import "./software-versions.js";
300300
import "./sparse-cell.js";
301301
import "./sparse-title.js";
302+
import "./stack-nan.js";
302303
import "./stacked-bar.js";
303304
import "./stacked-rect.js";
304305
import "./stargazers-binned.js";

test/plots/stack-nan.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import * as Plot from "@observablehq/plot";
2+
import * as d3 from "d3";
3+
import {test} from "test/plot";
4+
5+
test(async function stackNaN() {
6+
const industries = await d3.csv<any>("data/bls-industry-unemployment.csv", d3.autoType);
7+
for (const [i, [, D]] of d3.groups(industries, (d) => d.industry).entries()) {
8+
const lo = Date.UTC(2000 + i, 0, 1, 8);
9+
const hi = Date.UTC(2002 + i, 0, 1, 8);
10+
for (const d of D) {
11+
if (d.date >= lo && d.date < hi) {
12+
d.unemployed = NaN;
13+
}
14+
}
15+
}
16+
return Plot.plot({
17+
y: {grid: true, label: "Unemployed (thousands)", transform: (d) => d / 1000},
18+
marks: [
19+
Plot.areaY(industries, {x: "date", y: "unemployed", fill: "industry", fillOpacity: 0.5}),
20+
Plot.lineY(industries, Plot.stackY({x: "date", y: "unemployed", stroke: "industry"}))
21+
]
22+
});
23+
});

0 commit comments

Comments
 (0)