Skip to content

Conversation

mbostock
Copy link
Member

@mbostock mbostock commented Sep 22, 2023

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);
  }
});
Screen.Recording.2023-09-22.at.1.56.03.PM.mov

TODO

  • Support faceting
  • Incorporate into Plot as a public API
  • Document
  • Test?

Fixes #1857.
Related #1574.

@Fil
Copy link
Contributor

Fil commented Sep 23, 2023

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose data (alongside scaled channel values) to the render function

2 participants