Skip to content

Commit c537262

Browse files
committed
picker: click to update the plot's value
- this initial version works on rects - default picker is d => d (each rect will send its value to the viewof), one can set picker: d => d.x - picker: null will not set onclick - bin transforms set picker = group => groupData (aka "the right thing") - not fully tested with faceting, though it seems to work - added a general mechanism to send the value as an Input event (not sure it's the right thing to do though), better than the async method of #71 - q: should we always send the initial value, and if so what data? a solution to this problem would be to opt in with a global {picker: data} and the picking would only apply to marks that have the same data. test https://observablehq.com/d/f4e32e31ec214e38
1 parent b8e2a42 commit c537262

File tree

3 files changed

+30
-12
lines changed

3 files changed

+30
-12
lines changed

src/mark.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ export class Mark {
4545
})
4646
};
4747
}
48+
update(g, values) {
49+
const svg = g.ownerSVGElement;
50+
console.log(values);
51+
svg.value = values;
52+
svg.dispatchEvent(new CustomEvent('input'));
53+
}
4854
}
4955

5056
// TODO Type coercion?

src/marks/rect.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export class Rect extends Mark {
1616
title,
1717
fill,
1818
stroke,
19+
picker = d => d,
1920
inset = 0,
2021
insetTop = inset,
2122
insetRight = inset,
@@ -38,7 +39,8 @@ export class Rect extends Mark {
3839
{name: "z", value: z, optional: true},
3940
{name: "title", value: title, optional: true},
4041
{name: "fill", value: vfill, scale: "color", optional: true},
41-
{name: "stroke", value: vstroke, scale: "color", optional: true}
42+
{name: "stroke", value: vstroke, scale: "color", optional: true},
43+
{name: "picker", value: picker, optional: true}
4244
],
4345
options
4446
);
@@ -53,7 +55,7 @@ export class Rect extends Mark {
5355
render(
5456
I,
5557
{x, y, color},
56-
{x1: X1, y1: Y1, x2: X2, y2: Y2, z: Z, title: L, fill: F, stroke: S}
58+
{x1: X1, y1: Y1, x2: X2, y2: Y2, z: Z, title: L, fill: F, stroke: S, picker: J}
5759
) {
5860
const {rx, ry} = this;
5961
const index = filter(I, X1, Y2, X2, Y2, F, S);
@@ -64,6 +66,10 @@ export class Rect extends Mark {
6466
.call(g => g.selectAll()
6567
.data(index)
6668
.join("rect")
69+
.call(J ? rect => rect
70+
.on("click", (event, i) => super.update(event.currentTarget, J[i]))
71+
: () => {}
72+
)
6773
.call(applyDirectStyles, this)
6874
.attr("x", i => Math.min(x(X1[i]), x(X2[i])) + this.insetLeft)
6975
.attr("y", i => Math.min(y(Y1[i]), y(Y2[i])) + this.insetTop)

src/transforms/bin.js

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,27 @@ import {bin as binner, cross, group} from "d3";
22
import {valueof, first, second, range, identity, lazyChannel, maybeLazyChannel, maybeTransform, maybeColor, maybeValue, mid, take} from "../mark.js";
33

44
export function binX({x, insetLeft = 1, ...options} = {}) {
5-
const [transform, x1, x2, y, z, fill, stroke] = bin1(x, options);
6-
return {y, x1, x2, ...transform, z, fill, stroke, insetLeft};
5+
const [transform, x1, x2, y, z, fill, stroke, picker] = bin1(x, options);
6+
return {y, x1, x2, ...transform, picker, z, fill, stroke, insetLeft};
77
}
88

99
export function binY({y, insetTop = 1, ...options} = {}) {
10-
const [transform, y1, y2, x, z, fill, stroke] = bin1(y, options);
11-
return {x, y1, y2, ...transform, z, fill, stroke, insetTop};
10+
const [transform, y1, y2, x, z, fill, stroke, picker] = bin1(y, options);
11+
return {x, y1, y2, ...transform, picker, z, fill, stroke, insetTop};
1212
}
1313

1414
export function binR({x, y, ...options} = {}) {
15-
const [transform, x1, x2, y1, y2, r, z, fill, stroke] = bin2(x, y, options);
16-
return {x: mid(x1, x2), y: mid(y1, y2), r, ...transform, z, fill, stroke};
15+
const [transform, x1, x2, y1, y2, r, z, fill, stroke, picker] = bin2(x, y, options);
16+
return {x: mid(x1, x2), y: mid(y1, y2), r, ...transform, picker, z, fill, stroke};
1717
}
1818

1919
export function binFill(options) {
2020
return bin({...options, out: "fill"});
2121
}
2222

2323
export function bin({x, y, insetLeft = 1, insetTop = 1, out, ...options} = {}) {
24-
const [transform, x1, x2, y1, y2, l, z, fill, stroke] = bin2(x, y, options);
25-
return {x1, x2, y1, y2, ...transform, z, fill, stroke, insetLeft, insetTop, [out]: l};
24+
const [transform, x1, x2, y1, y2, l, z, fill, stroke, picker] = bin2(x, y, options);
25+
return {x1, x2, y1, y2, ...transform, picker, z, fill, stroke, insetLeft, insetTop, [out]: l};
2626
}
2727

2828
function bin1(x, {domain, thresholds, normalize, cumulative, ...options} = {}) {
@@ -37,6 +37,7 @@ function bin1(x, {domain, thresholds, normalize, cumulative, ...options} = {}) {
3737
const [vstroke] = maybeColor(stroke);
3838
const [F = fill, setF] = maybeLazyChannel(vfill);
3939
const [S = stroke, setS] = maybeLazyChannel(vstroke);
40+
const [J, setJ] = lazyChannel();
4041
return [
4142
{
4243
...options,
@@ -80,6 +81,7 @@ function bin1(x, {domain, thresholds, normalize, cumulative, ...options} = {}) {
8081
}
8182
binIndex.push(binFacet);
8283
}
84+
setJ(binData);
8385
return {data: binData, index: binIndex};
8486
})
8587
},
@@ -88,7 +90,8 @@ function bin1(x, {domain, thresholds, normalize, cumulative, ...options} = {}) {
8890
Y,
8991
Z,
9092
F,
91-
S
93+
S,
94+
J
9295
];
9396
}
9497

@@ -112,6 +115,7 @@ function bin2(x, y, {domain, thresholds, normalize, ...options} = {}) {
112115
const [vstroke] = maybeColor(stroke);
113116
const [F = fill, setF] = maybeLazyChannel(vfill);
114117
const [S = stroke, setS] = maybeLazyChannel(vstroke);
118+
const [J, setJ] = lazyChannel();
115119
return [
116120
{
117121
...options,
@@ -156,6 +160,7 @@ function bin2(x, y, {domain, thresholds, normalize, ...options} = {}) {
156160
}
157161
binIndex.push(binFacet);
158162
}
163+
setJ(binData);
159164
return {data: binData, index: binIndex};
160165
})
161166
},
@@ -166,7 +171,8 @@ function bin2(x, y, {domain, thresholds, normalize, ...options} = {}) {
166171
L,
167172
Z,
168173
F,
169-
S
174+
S,
175+
J
170176
];
171177
}
172178

0 commit comments

Comments
 (0)