viewof Plot

Following the pattern in Exploring viewof, this notebook is an attempt to add viewof functionality to a Plot.

The plot notebook cell does not give an error, but doesn’t dispatch the input event and value attached to the plot’s SVG rectangles…

Debugging shows the rect element does have the click event properly assigned to it:

Is this possible?

Use case is for filtering; a la vega-lite.

1 Like

When you define a cell using

viewof plot = ...

any other cell that depends on plot will react to changes in the value of plot. You’re not setting the value of plot in your code, though, you’re changing the value of child. You can still add the event listeners directly to the bars but should modify the value of plot and dispatch the event from there.

Putting that all together, you should have the following block in your loop:

child.addEventListener("click", (e) => {
  plot.value = aParm;
  plot.dispatchEvent(new CustomEvent("input"));
});
1 Like

To complement Mark’s explanation, here’s a code that just reads the index (i) of the rect and returns the associated datum.

viewof plot = {
  const data = [
    { x: "A", y: 20 },
    { x: "B", y: 30 }
  ];
  
  const plot = Plot.plot({
    height: 100,
    width: 100,
    marks: [Plot.barY(data, { x: "x", y: "y" })]
  });

  d3.select(plot)
    .selectAll("rect")
    .on("click", function (event, i) {
      plot.value = data[i];
      plot.dispatchEvent(new CustomEvent("input"));
    });

  return plot;
}

Thanks. That works quite well for the barY mark and a 1:1 reference into the original data. I think faceting would be challenging with this approach.

The logic was attempting to use the href (html anchor element) as a container and make the pattern applicable to all charts by referencing a generic ‘child’ object hosted by the href which has the associated data regardless of plot transformations.

Ultimately, a function that would viewof-a-fy any plot with hrefs formatted as in the example was the goal.
Or more succinctly, make any plot broadcast the plot component a user clicks on; the href was being used as one possibility.

Any thoughts on that possibility?

My suggestion works with faceting, as i is the index into the data.

Closer to your approach is Mike Freeman’s tooltip plugin—where the “title” channel (rather than “href”) is used to store the information that gets displayed on mouseover (rather than on click): Plot Tooltip / Mike Freeman / Observable

And yes, ultimately we’ll want something native that allows the user to select/point/click/capture a subset of the data—with a click or a more complex interaction mechanisms (such as brush, lasso…). There are a few open issues already in the repo.

Ahhhh! :grinning: The svg rectangles are created in data order, not the display layout order (left to right/top to bottom; or visa-versa). Therefore, you’re correct that the indexing into the data will work with faceting as well.

I’ve combined both your recommendation and Mike’s tooltip; with a d3.shuffle of the data to illustrate your explanation.
See: viewof Plot / Mario Delgado / Observable