Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter render transform #1871

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft

Filter render transform #1871

wants to merge 2 commits into from

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