Skip to content

Commit a81ac42

Browse files
committed
don’t compute z twice
1 parent e578c54 commit a81ac42

File tree

1 file changed

+28
-54
lines changed

1 file changed

+28
-54
lines changed

src/transforms/group.js

Lines changed: 28 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import {group as grouper, sort, sum, InternSet} from "d3";
2-
import {defined} from "../defined.js";
3-
import {valueof, maybeZ, maybeInput, maybeTransform, maybeValue, maybeLazyChannel, lazyChannel, first, identity, take, maybeTuple, labelof, maybeColor} from "../mark.js";
1+
import {group as grouper, sort, sum} from "d3";
2+
import {valueof, maybeColor, maybeInput, maybeTransform, maybeTuple, maybeLazyChannel, lazyChannel, first, identity, take} from "../mark.js";
43

54
// Group on {z, fill, stroke}.
65
export function groupZ(outputs, options) {
@@ -27,25 +26,22 @@ export function group(outputs, options = {}) {
2726
}
2827

2928
function groupn(
30-
x, // optionally group on x (either a value or {value, domain})
31-
y, // optionally group on y (either a value or {value, domain})
29+
x, // optionally group on x
30+
y, // optionally group on y
3231
{
3332
data: reduceData = reduceIdentity,
3433
...outputs
3534
} = {}, // channels to aggregate
3635
{
3736
domain,
3837
// normalize, TODO
39-
// weight, TODO
38+
z,
39+
fill,
40+
stroke,
4041
...options
4142
} = {}
4243
) {
4344

44-
// Implicit firsts.
45-
if (outputs.z === undefined && options.z != null) outputs = {...outputs, z: reduceFirst};
46-
if (outputs.fill === undefined && maybeColor(options.fill)[0]) outputs = {...outputs, fill: reduceFirst};
47-
if (outputs.stroke === undefined && maybeColor(options.stroke)[0]) outputs = {...outputs, stroke: reduceFirst};
48-
4945
// Reconstitute the outputs.
5046
outputs = Object.entries(outputs).map(([name, reduce]) => {
5147
const reducer = maybeReduce(reduce);
@@ -66,32 +62,19 @@ function groupn(
6662
};
6763
});
6864

69-
// Handle per-dimension domains.
70-
// TODO This should be derived from the scale’s domain instead.
71-
// let xdomain, ydomain;
72-
// ({value: x, domain: xdomain} = {domain, ...maybeValue(x)});
73-
// ({value: y, domain: ydomain} = {domain, ...maybeValue(y)});
74-
75-
// Handle both x and y being undefined.
76-
// TODO Move to group? Needs to handle per-dimension domain with default.
77-
// ([x, y] = maybeTuple(x, y));
78-
79-
// Determine the z dimension (subgroups within x and y), if any. Note that
80-
// this requires that the z dimension be defined deterministically.
81-
const z = maybeZ(options);
82-
8365
// const m = maybeNormalize(normalize); // TODO
8466
// const [BL, setBL] = lazyChannel(`${labelof(weight, "Frequency")}${m === 100 ? " (%)" : ""}`);
8567
const [BX, setBX] = maybeLazyChannel(x);
8668
const [BY, setBY] = maybeLazyChannel(y);
87-
// const [BZ, setBZ] = maybeLazyChannel(z);
88-
// const [vfill] = maybeColor(fill);
89-
// const [vstroke] = maybeColor(stroke);
90-
// const [BF = fill, setBF] = maybeLazyChannel(vfill);
91-
// const [BS = stroke, setBS] = maybeLazyChannel(vstroke);
92-
const xdefined = defined1; // TODO BX && maybeDomain(xdomain);
93-
const ydefined = defined1; // TODO BY && maybeDomain(ydomain);
69+
const [BZ, setBZ] = maybeLazyChannel(z);
70+
const [vfill] = maybeColor(fill);
71+
const [vstroke] = maybeColor(stroke);
72+
const [BF = fill, setBF] = maybeLazyChannel(vfill);
73+
const [BS = stroke, setBS] = maybeLazyChannel(vstroke);
9474
return {
75+
z: BZ,
76+
fill: BF,
77+
stroke: BS,
9578
...options,
9679
...BX && {x: BX},
9780
...BY && {y: BY},
@@ -100,15 +83,17 @@ function groupn(
10083
const X = valueof(data, x);
10184
const Y = valueof(data, y);
10285
const Z = valueof(data, z);
86+
const F = valueof(data, vfill);
87+
const S = valueof(data, vstroke);
10388
// const W = valueof(data, weight); // TODO
10489
const groupFacets = [];
10590
const groupData = [];
10691
// const BL = setBL([]);
10792
const BX = X && setBX([]);
10893
const BY = Y && setBY([]);
109-
// const BZ = Z && setBZ([]);
110-
// const BF = F && setBF([]);
111-
// const BS = S && setBS([]);
94+
const BZ = Z && setBZ([]);
95+
const BF = F && setBF([]);
96+
const BS = S && setBS([]);
11297
// let n = W ? sum(W) : data.length; // TODO
11398
let i = 0;
11499
for (const output of outputs) {
@@ -117,10 +102,10 @@ function groupn(
117102
for (const facet of facets) {
118103
const groupFacet = [];
119104
// if (normalize === "facet") n = W ? sum(facet, i => W[i]) : facet.length; // TODO
120-
for (const [, I] of groups(facet, Z, defined1)) {
105+
for (const [, I] of groups(facet, Z)) {
121106
// if (normalize === "z") n = W ? sum(I, i => W[i]) : I.length; // TODO
122-
for (const [y, fy] of groups(I, Y, ydefined)) {
123-
for (const [x, f] of groups(fy, X, xdefined)) {
107+
for (const [y, fy] of groups(I, Y)) {
108+
for (const [x, f] of groups(fy, X)) {
124109
// const l = W ? sum(f, i => W[i]) : f.length; // TODO
125110
groupFacet.push(i++);
126111
groupData.push(reduceData.reduce(f, data));
@@ -130,9 +115,9 @@ function groupn(
130115
for (const output of outputs) {
131116
output.reduce(f);
132117
}
133-
// if (Z) BZ.push(Z[f[0]]);
134-
// if (F) BF.push(F[f[0]]);
135-
// if (S) BS.push(S[f[0]]);
118+
if (Z) BZ.push(Z[f[0]]);
119+
if (F) BF.push(F[f[0]]);
120+
if (S) BS.push(S[f[0]]);
136121
}
137122
}
138123
}
@@ -143,13 +128,6 @@ function groupn(
143128
};
144129
}
145130

146-
function maybeDomain(domain) {
147-
if (domain === undefined) return defined1;
148-
if (domain === null) return () => false;
149-
domain = new InternSet(domain);
150-
return ([key]) => domain.has(key);
151-
}
152-
153131
// function maybeNormalize(normalize) {
154132
// if (!normalize) return;
155133
// if (normalize === true) return 100;
@@ -160,12 +138,8 @@ function maybeDomain(domain) {
160138
// throw new Error("invalid normalize");
161139
// }
162140

163-
function defined1([key]) {
164-
return defined(key);
165-
}
166-
167-
export function groups(I, X, defined = defined1) {
168-
return X ? sort(grouper(I, i => X[i]), first).filter(defined) : [[, I]];
141+
export function groups(I, X) {
142+
return X ? sort(grouper(I, i => X[i]), first) : [[, I]];
169143
}
170144

171145
function maybeReduce(reduce) {

0 commit comments

Comments
 (0)