d3工具提示栏,用于在Y轴上的鼠标悬停时提供多个折线图(提供的代码)

时间:2019-12-18 21:05:40

标签: javascript d3.js

我正在尝试为多折线图实现鼠标悬停时的工具提示。 我遵循了this example中的代码,并尝试对其进行更改,以使我看到给定的Y值悬停时各行的X值,但是我无法使其正常工作。

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

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

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

谢谢

1 个答案:

答案 0 :(得分: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] + ")";
        });
      });

Fully working codesandbox here