Skip to content

Commit 4395f02

Browse files
authored
universal channel filter (#671)
1 parent 75de2f8 commit 4395f02

File tree

19 files changed

+59
-89
lines changed

19 files changed

+59
-89
lines changed

src/channel.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ import {registry} from "./scales/index.js";
44
import {maybeReduce} from "./transforms/group.js";
55

66
// TODO Type coercion?
7-
export function Channel(data, {scale, type, value, hint}) {
7+
export function Channel(data, {scale, type, value, filter, hint}) {
88
return {
99
scale,
1010
type,
1111
value: valueof(data, value),
1212
label: labelof(value),
13+
filter,
1314
hint
1415
};
1516
}

src/defined.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,6 @@ export function nonempty(x) {
1616
return x != null && `${x}` !== "";
1717
}
1818

19-
export function filter(index, ...channels) {
20-
for (const c of channels) {
21-
if (c) index = index.filter(i => defined(c[i]));
22-
}
23-
return index;
24-
}
25-
2619
export function finite(x) {
2720
return isFinite(x) ? x : NaN;
2821
}

src/marks/area.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ export class Area extends Mark {
1818
super(
1919
data,
2020
[
21-
{name: "x1", value: x1, scale: "x"},
22-
{name: "y1", value: y1, scale: "y"},
23-
{name: "x2", value: x2, scale: "x", optional: true},
24-
{name: "y2", value: y2, scale: "y", optional: true},
21+
{name: "x1", value: x1, filter: null, scale: "x"},
22+
{name: "y1", value: y1, filter: null, scale: "y"},
23+
{name: "x2", value: x2, filter: null, scale: "x", optional: true},
24+
{name: "y2", value: y2, filter: null, scale: "y", optional: true},
2525
{name: "z", value: maybeZ(options), optional: true}
2626
],
2727
options,

src/marks/bar.js

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {create} from "d3";
2-
import {filter} from "../defined.js";
32
import {Mark} from "../plot.js";
43
import {number} from "../options.js";
54
import {isCollapsed} from "../scales.js";
@@ -21,9 +20,8 @@ export class AbstractBar extends Mark {
2120
this.rx = impliedString(rx, "auto"); // number or percentage
2221
this.ry = impliedString(ry, "auto");
2322
}
24-
render(I, scales, channels, dimensions) {
23+
render(index, scales, channels, dimensions) {
2524
const {dx, dy, rx, ry} = this;
26-
const index = filter(I, ...this._positions(channels));
2725
return create("svg:g")
2826
.call(applyIndirectStyles, this)
2927
.call(this._transform, scales, dx, dy)
@@ -76,9 +74,6 @@ export class BarX extends AbstractBar {
7674
_transform(selection, {x}, dx, dy) {
7775
selection.call(applyTransform, x, null, dx, dy);
7876
}
79-
_positions({x1: X1, x2: X2, y: Y}) {
80-
return [X1, X2, Y];
81-
}
8277
_x({x}, {x1: X1, x2: X2}, {marginLeft}) {
8378
const {insetLeft} = this;
8479
return isCollapsed(x) ? marginLeft + insetLeft : i => Math.min(X1[i], X2[i]) + insetLeft;
@@ -105,9 +100,6 @@ export class BarY extends AbstractBar {
105100
_transform(selection, {y}, dx, dy) {
106101
selection.call(applyTransform, null, y, dx, dy);
107102
}
108-
_positions({y1: Y1, y2: Y2, x: X}) {
109-
return [Y1, Y2, X];
110-
}
111103
_y({y}, {y1: Y1, y2: Y2}, {marginTop}) {
112104
const {insetTop} = this;
113105
return isCollapsed(y) ? marginTop + insetTop : i => Math.min(Y1[i], Y2[i]) + insetTop;

src/marks/cell.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@ export class Cell extends AbstractBar {
1515
_transform() {
1616
// noop
1717
}
18-
_positions({x: X, y: Y}) {
19-
return [X, Y];
20-
}
2118
}
2219

2320
export function cell(data, {x, y, ...options} = {}) {

src/marks/dot.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {create, path, symbolCircle} from "d3";
2-
import {filter, positive} from "../defined.js";
3-
import {Mark} from "../plot.js";
2+
import {positive} from "../defined.js";
43
import {identity, maybeNumberChannel, maybeTuple} from "../options.js";
4+
import {Mark} from "../plot.js";
55
import {maybeSymbolChannel} from "../scales/symbol.js";
66
import {applyChannelStyles, applyDirectStyles, applyIndirectStyles, applyTransform, offset} from "../style.js";
77

@@ -22,7 +22,7 @@ export class Dot extends Mark {
2222
[
2323
{name: "x", value: x, scale: "x", optional: true},
2424
{name: "y", value: y, scale: "y", optional: true},
25-
{name: "r", value: vr, scale: "r", optional: true},
25+
{name: "r", value: vr, scale: "r", filter: positive, optional: true},
2626
{name: "rotate", value: vrotate, optional: true},
2727
{name: "symbol", value: vsymbol, scale: "symbol", optional: true}
2828
],
@@ -48,7 +48,7 @@ export class Dot extends Mark {
4848
}
4949
}
5050
render(
51-
I,
51+
index,
5252
{x, y},
5353
channels,
5454
{width, height, marginTop, marginRight, marginBottom, marginLeft}
@@ -57,8 +57,6 @@ export class Dot extends Mark {
5757
const {dx, dy} = this;
5858
const cx = (marginLeft + width - marginRight) / 2;
5959
const cy = (marginTop + height - marginBottom) / 2;
60-
let index = filter(I, X, Y, A, S);
61-
if (R) index = index.filter(i => positive(R[i]));
6260
const circle = this.symbol === symbolCircle;
6361
return create("svg:g")
6462
.call(applyIndirectStyles, this)

src/marks/image.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {create} from "d3";
2-
import {filter, positive} from "../defined.js";
3-
import {Mark} from "../plot.js";
2+
import {positive} from "../defined.js";
43
import {maybeNumberChannel, maybeTuple, string} from "../options.js";
4+
import {Mark} from "../plot.js";
55
import {applyChannelStyles, applyDirectStyles, applyIndirectStyles, applyTransform, applyAttr, offset, impliedString} from "../style.js";
66

77
const defaults = {
@@ -44,8 +44,8 @@ export class Image extends Mark {
4444
[
4545
{name: "x", value: x, scale: "x", optional: true},
4646
{name: "y", value: y, scale: "y", optional: true},
47-
{name: "width", value: vw, optional: true},
48-
{name: "height", value: vh, optional: true},
47+
{name: "width", value: vw, filter: positive, optional: true},
48+
{name: "height", value: vh, filter: positive, optional: true},
4949
{name: "src", value: vs, optional: true}
5050
],
5151
options,
@@ -58,15 +58,12 @@ export class Image extends Mark {
5858
this.crossOrigin = string(crossOrigin);
5959
}
6060
render(
61-
I,
61+
index,
6262
{x, y},
6363
channels,
6464
{width, height, marginTop, marginRight, marginBottom, marginLeft}
6565
) {
6666
const {x: X, y: Y, width: W, height: H, src: S} = channels;
67-
let index = filter(I, X, Y, S);
68-
if (W) index = index.filter(i => positive(W[i]));
69-
if (H) index = index.filter(i => positive(H[i]));
7067
const cx = (marginLeft + width - marginRight) / 2;
7168
const cy = (marginTop + height - marginBottom) / 2;
7269
const {dx, dy} = this;

src/marks/line.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ export class Line extends Mark {
1818
super(
1919
data,
2020
[
21-
{name: "x", value: x, scale: "x"},
22-
{name: "y", value: y, scale: "y"},
21+
{name: "x", value: x, filter: null, scale: "x"},
22+
{name: "y", value: y, filter: null, scale: "y"},
2323
{name: "z", value: maybeZ(options), optional: true}
2424
],
2525
options,

src/marks/link.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {create, path} from "d3";
2-
import {filter} from "../defined.js";
3-
import {Mark} from "../plot.js";
42
import {Curve} from "../curve.js";
3+
import {Mark} from "../plot.js";
54
import {applyChannelStyles, applyDirectStyles, applyIndirectStyles, applyTransform, offset} from "../style.js";
65

76
const defaults = {
@@ -26,10 +25,9 @@ export class Link extends Mark {
2625
);
2726
this.curve = Curve(curve);
2827
}
29-
render(I, {x, y}, channels) {
28+
render(index, {x, y}, channels) {
3029
const {x1: X1, y1: Y1, x2: X2 = X1, y2: Y2 = Y1} = channels;
3130
const {dx, dy} = this;
32-
const index = filter(I, X1, Y1, X2, Y2);
3331
return create("svg:g")
3432
.call(applyIndirectStyles, this)
3533
.call(applyTransform, x, y, offset + dx, offset + dy)

src/marks/rect.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {create} from "d3";
2-
import {filter} from "../defined.js";
3-
import {Mark} from "../plot.js";
42
import {number} from "../options.js";
3+
import {Mark} from "../plot.js";
54
import {isCollapsed} from "../scales.js";
65
import {applyDirectStyles, applyIndirectStyles, applyTransform, impliedString, applyAttr, applyChannelStyles} from "../style.js";
76
import {maybeIdentityX, maybeIdentityY} from "../transforms/identity.js";
@@ -43,11 +42,10 @@ export class Rect extends Mark {
4342
this.rx = impliedString(rx, "auto"); // number or percentage
4443
this.ry = impliedString(ry, "auto");
4544
}
46-
render(I, {x, y}, channels, dimensions) {
45+
render(index, {x, y}, channels, dimensions) {
4746
const {x1: X1, y1: Y1, x2: X2, y2: Y2} = channels;
4847
const {marginTop, marginRight, marginBottom, marginLeft, width, height} = dimensions;
4948
const {insetTop, insetRight, insetBottom, insetLeft, dx, dy, rx, ry} = this;
50-
const index = filter(I, X1, Y2, X2, Y2);
5149
return create("svg:g")
5250
.call(applyIndirectStyles, this)
5351
.call(applyTransform, x, y, dx, dy)

0 commit comments

Comments
 (0)