Observable Plot: 将路径与相应的标记关联

huangapple go评论70阅读模式
英文:

Observable Plot: Associate path with coresponding mark

问题

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

你在创建标记列表(例如 Plot.line)作为 Plot.plot 的选项对象的一部分时,无法知道哪个标记对应哪个路径对象。

You can iterate through all marks and find out where each data point has been rendered and highlight that point, but you'd rather not build all paths yourself and instead rely on the abstraction provided by Plot.

你可以遍历所有标记,找出每个数据点被渲染在哪里,并突出显示该点,但你宁愿不自己构建所有路径,而是依赖于Plot提供的抽象。

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

你无法识别/选择数据点所属的路径对象。如果每个标记可以定义一个要添加到路径的CSS类,那将是不错的。到目前为止,你还没有找到任何方法来实现这个或类似的功能。

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

依赖DOM中的顺序不是一个选项,因为它可能会改变(例如,使用raise())。

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

在监听器中使用 checkIntersection 只对闭合路径起作用,而线条不是闭合的,而且即使是闭合的,你也不确定它是否能正常工作。

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

有没有一种有控制的方式来设置类或ID?

英文:

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?

答案1

得分: 1

没有。关于这个问题在GitHub上有一些讨论,但到目前为止,只有一个顶级的className选项,允许您设置整个图的类。

为了绕过这个问题,我有时会设置标记的title,然后基于该标题进行选择。例如,您可能在图中有两个标题为"first"和"second"的rects

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

之后,您可以执行类似以下的操作:

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");
    }
  })

然后您会发现第二个矩形的颜色已经改变。

您可能或可能不想要title,它会产生一个原生工具提示。如果需要,您可以随时修改或删除它。

这是一个使用类似技巧创建更复杂工具提示的Observable笔记本:

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

英文:

> 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

答案2

得分: 0

个体标记的数据(例如,每个数据点的圆的 __data__ 属性)是标记数据的索引。因此,第一个点的数据是0,第二个点的数据是1,依此类推。

对于(多条)线图(以及将数据点分组到一个路径中的任何其他标记),每个路径的数据是对应于该组的标记数据的索引数组。

例如,以下是如何获取多线图中定义单条线的所有点的方法:
https://observablehq.com/@recifs/plot-getting-a-line-s-data

英文:

The individual mark's datum (e.g. the circle’s __data__ property for each data point) is the index into the mark's data. So the first point has datum 0, second point has datum 1, etc.

For a (multi-) line chart (and any other mark that groups data points into one path), the datum of each path is the array of indices into the mark’s data that correspond to the group.

For example, here's how to get all points that define. single line in a multi-line chart:
https://observablehq.com/@recifs/plot-getting-a-line-s-data

huangapple
  • 本文由 发表于 2023年6月6日 04:09:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76409682.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定