Reputation: 757
I'm trying to grab the line value at that exact point of time (x-axis) however same tick gives me different values depends from which side I'm hovering over, if its from the left it says current data at index[123]: 10586174, if I hover from the right it says current data at index[124]: 10586174. It is only a pixel difference as line stroke-width is only 3px but the values are different. It is very inconsistent and one tick should only return one value related to that date.
//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;
}
})
Upvotes: 2
Views: 511
Reputation: 386
I can suggest this approach, when you are creating ticks, you can add data-attribute with a value, like
d3.selectAll(".xAxis .tick text")
.attr("dy", "25px")
.style("color", "#65757E")
.style("text-transform", "uppercase")
// here
.attr("dataValue", (d) => d);
and then when you are handle mousemove
, you will take not a position because it can be inconsistent with your tick values, but attribute value that are belong to the target tick.
Inside event listener:
const currentDate = event.target
.closest("g")
.querySelector("text")
.getAttribute("dataValue");
Now because you have exact date, you can find in your dataset this value index (or just value),
// 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");
});
If you need grab it from comparisonData
as well, you can do the same manipulation, or better to merge them [...lineChartData.values, ...comparisonData.values]
findIndex of the same date, and do calculations.
Here is fork with changes: https://codesandbox.io/s/kind-morning-91fg8?file=/src/LineChart.js:9398-9533
Upvotes: 2