D3 折线图悬停时相同的勾号给出不同的值

D3 line chart same tick on hover gives different values

我试图在那个确切的时间点(x 轴)获取线值,但是相同的勾号给我不同的值取决于我悬停在哪一侧,如果它从左边开始,它表示当前index[123] 处的数据:10586174,如果我将鼠标悬停在右侧,它会显示 index[124] 处的当前数据:10586174。这只是像素差异,因为线条笔划宽度仅为 3px,但值不同。这是非常不一致的,一个报价单应该 return 一个与该日期相关的值。

CodeSandbox

//Set up interactions
    d3.selectAll(".xAxis > .tick")
      .style("color", "#65757E")
      .on("mousemove", function (event) {
        event.path[0].style.stroke = "#0D2633";
        d3.select("line").style("z-index", 0);
        const mousePosition = d3.pointer(event, svg.node()); // gets [x,y]
        const currentDate = xScale.invert(mousePosition[0]); // converts x to current date

        const bisect = d3.bisector((d) => new Date(d.date)); // create a bisector

        const index_currentData = bisect.right(
          lineChartData.values[0].dataset,
          currentDate
        );

        if (index_currentData < lineChartData.values[0].dataset.length) {
          console.log(
            `Current data at index[${index_currentData}]: ${lineChartData.values[0].dataset[index_currentData].value}`
          );

        const comparisonDate = xScale2.invert(mousePosition[0]); // converts x to comparison date

        const index_comparisonData = bisect.right(
          comparisonData.values[0].dataset,
          comparisonDate
        );

        if (index_comparisonData < comparisonData.values[0].dataset.length) {
          const tooltipComparisonValue =
            comparisonData.values[0].dataset[index_comparisonData].value;
        }
      })

我可以建议这种方法, 创建刻度时,您可以添加带有值的数据属性,例如

    d3.selectAll(".xAxis .tick text")
      .attr("dy", "25px")
      .style("color", "#65757E")
      .style("text-transform", "uppercase")
      // here
      .attr("dataValue", (d) => d);

然后当你处理 mousemove 时,你不会选择一个位置,因为它可能与你的分时值不一致,而是属于目标分时的属性值。

内部事件侦听器:

        const currentDate = event.target
          .closest("g")
          .querySelector("text")
          .getAttribute("dataValue");

现在因为你有确切的日期,你可以在你的数据集中找到这个值索引(或只是值),

// find index by comparing the date
const findIndexOfHoveredTick = lineChartData.values[0].dataset.findIndex(
  (d) => new Date(d.date).toString() === currentDate
);

// here you can apply this index to find object inside dataset
lineChartData.values.forEach((value) => {
  console.log(value.dataset[findIndexOfHoveredTick], "Line Value");
});

如果你也需要从comparisonData抓取,你可以做同样的操作,或者更好地合并它们[...lineChartData.values, ...comparisonData.values]找到相同日期的索引,并进行计算。

这是有改动的分支:https://codesandbox.io/s/kind-morning-91fg8?file=/src/LineChart.js:9398-9533