0

我正在尝试为多折线图实现鼠标悬停的工具提示。我已经按照此示例中的代码进行了更改,并尝试对其进行更改,以便我看到给定悬停 Y 值的行的 X 值,但我无法让它工作。

我的尝试可以在下面找到。

在我的实际实现中,我正在用 Typescript 编写函数“getTotalLength()”和“getPointAtLength()”表示它们在属性 Element 上不存在。
此外,如果您可以在具有悬停 Y 值的行上添加一个文本框,这对我有很大帮助!

https://codesandbox.io/s/modest-minsky-hvsms?fontsize=14&hidenavigation=1&theme=dark

谢谢

4

1 回答 1

0

因此,经过仔细审查,我已经纠正了几个错误。

  1. 您的数据线路径未分配类,因此您需要在dataLine附加它们时为它们分配类,如下所示:
    svg
      .selectAll(".dataLine")
      .data(nestedData)
      .enter()
      .append("path")
      .attr("fill", "none")
      .attr("class", "dataLine")
      .attr("stroke", d => itemMap(d.key).color)
      .attr("stroke-width", d => itemMap(d.key).lineWeight)
      .attr("d", d =>
        d3
          .line()
          .x(d => x(d.xvalue))
          .y(d => y(d.yvalue))(d.values)
      );
  1. 正如上面评论中所指出的,如果您打算使用箭头功能,请停止使用它。一旦你这样做了,你d3.mouse(this)就开始工作了。

  2. 您遵循的示例具有从左到右的路径,而您的路径是从上到下。这需要在坐标方面进行几次更改,以使鼠标悬停线和具有附近文本值的圆圈对齐以正确对齐。正确的代码如下:

      .on("mousemove", function() {
        //@ts-ignore
        var mouse = d3.mouse(this);
        d3.select(".mouse-line").attr("d", () => {
          var d = "M" + plotWidth + "," + mouse[1];
          d += " " + 0 + "," + mouse[1];
          return d;
        });

        d3.selectAll(".mouse-per-line").attr("transform", function(d, i) {
          var yDepth = y.invert(mouse[1]);
          var bisect = d3.bisector(d => d.depth).right;
          var idy = bisect(d.values, yDepth);

          var beginning = 0;
          var end = lines[i].getTotalLength();
          var target = null;

          while (true) {
            target = Math.floor((beginning + end) / 2);
            var pos = lines[i].getPointAtLength(target);
            if (
              (target === end || target === beginning) &&
              pos.y !== mouse[1]
            ) {
              break;
            }
            if (pos.y > mouse[1]) {
              end = target;
            } else if (pos.y < mouse[1]) {
              beginning = target;
            } else {
              break;
            }
          }
          d3.select(this)
            .select("text")
            .text(x.invert(pos.x).toFixed(2));

          return "translate(" + pos.x + "," + mouse[1] + ")";
        });
      });

完全工作的代码框在这里

于 2019-12-24T07:15:42.807 回答