svgd3.jsplotobservablehq

Observable Plot: Associate path with coresponding mark


When creating a list of marks (e.g. Plot.line) as part of an options object to Plot.plot there seens no way know which mark is responsible for which path object.

I can iterate through all marks and find out where each data point has been rendered and highlight that point (actually rebuilding this d3 example but I'd rather not build all paths myself and instead rely on the abstraction provided by Plot).

What I can't do is identify/select the path object that data point belongs to. If it was possible for each mark to define e.g. a css class to be added to the path this would be fine. So far I have not found any way to do this or something similar.

Relying on the order in the DOM is not an option as that might change (e.g. when using raise())

Using checkIntersection in a listener would only work on closed paths which lines are not and even then I am not sure it would work properly.

Is there any way to set classes or ids in a controlled manner?


Solution

  • Is there any way to set classes or ids in a controlled manner?

    No. There's been some discussion on GitHub about this but, to this point, there's only a top-level className option that allows you to set the class of the whole plot.

    To get around this, I sometimes set the title of the marks and then select based on that title. For example, you might have two rects titled "first" and "second" in a plot:

    plot = Plot.rect(
      [{x1: 0, y1: 0, x2: 1, y2: 1, title: "first"},
      {x1: 1, y1: 1, x2: 2, y2: 2, title: "second"}],
      { x1: "x1", x2: "x2", y1: "y1", y2: "y2", title: "title" }
    ).plot()
    

    Later, you might do something like:

    d3
      .select(plot)
      .selectAll("rect")
      .each(function () {
        let c = d3.select(this);
        let title = c.select("title");
        if (title.text() == "second") {
          c.attr("fill", "#d33");
        }
      })
    

    You'll then find that the second rectangle has changed color.

    You might or might not want the title, which produces a native tooltip. You can always modify or delete it, if you want.

    Here's an Observable notebook that uses a similar trick to produce fancier tooltips:

    https://observablehq.com/@mcmcclur/a-plot-selection-hack