plot
plot copied to clipboard
Filter render transform
Here’s a sketch on a more imperative, lower-level interaction primitive: a filter render transform that you can dynamically update whenever you like. It starts by declaring some filters (and their initial filter state):
const pointerInactive = renderFilter(true);
const pointerContext = renderFilter(false);
const pointerFocus = renderFilter(false);
Then you apply the filters to the desired marks like any other transform:
const plot = Plot.plot({
y: {grid: true},
color: {scheme: "BuRd", symmetric: false},
marks: [
Plot.ruleY([0]),
Plot.lineY(bls, pointerInactive({x: "date", y: "unemployment", z: "division", tip: true})),
Plot.lineY(bls, pointerContext({x: "date", y: "unemployment", z: "division", stroke: "#ccc"})),
Plot.lineY(bls, pointerFocus({x: "date", y: "unemployment", z: "division", stroke: "red"}))
]
});
Lastly here I use an event listener (here driven by the tip mark of the plot itself!) to update the filters:
plot.addEventListener("input", () => {
if (plot.value === null) {
pointerInactive.update(true);
pointerContext.update(false);
pointerFocus.update(false);
} else {
const division = plot.value.division;
pointerInactive.update(false);
pointerContext.update((d) => d.division !== division);
pointerFocus.update((d) => d.division === division);
}
});
https://github.com/observablehq/plot/assets/230541/bfbb8274-05e9-4945-b22d-87ea0ba7b302
TODO
- [ ] Support faceting
- [ ] Incorporate into Plot as a public API
- [ ] Document
- [ ] Test?
Fixes #1857. Related #1574.
Exciting!
To support faceting we only need to re-apply the translate attribute (we can copy it from the old g). https://observablehq.com/@observablehq/filtering-several-charts-1871
I'd like to also support sharing the behavior between charts, but it's a bit more delicate (it needs an invalidation strategy).