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