From e7702d61fa500bd01eed3f9a8767efaf092e5f9b Mon Sep 17 00:00:00 2001 From: Juned Chhipa Date: Wed, 11 Dec 2024 21:12:44 +0530 Subject: [PATCH] fixes #4856; tooltip jump in irregular time series --- src/modules/tooltip/Utils.js | 89 ++++++++++++++---------------------- 1 file changed, 35 insertions(+), 54 deletions(-) diff --git a/src/modules/tooltip/Utils.js b/src/modules/tooltip/Utils.js index 441625478..3acf5063c 100644 --- a/src/modules/tooltip/Utils.js +++ b/src/modules/tooltip/Utils.js @@ -128,72 +128,53 @@ export default class Utils { } closestInMultiArray(hoverX, hoverY, Xarrays, Yarrays) { - let w = this.w - let activeIndex = 0 - let currIndex = null - let j = -1 + const w = this.w - if (w.globals.series.length > 1) { - activeIndex = this.getFirstActiveXArray(Xarrays) - } else { - currIndex = 0 + // Determine which series are active (not collapsed) + const isActiveSeries = (seriesIndex) => { + return ( + w.globals.collapsedSeriesIndices.indexOf(seriesIndex) === -1 && + w.globals.ancillaryCollapsedSeriesIndices.indexOf(seriesIndex) === -1 + ) } - let currX = Xarrays[activeIndex][0] - let diffX = Math.abs(hoverX - currX) + let closestDist = Infinity + let closestSeriesIndex = null + let closestPointIndex = null - // find nearest point on x-axis - Xarrays.forEach((arrX) => { - arrX.forEach((x, iX) => { - const newDiff = Math.abs(hoverX - x) - if (newDiff <= diffX) { - diffX = newDiff - j = iX - } - }) - }) + // Iterate through all series and points to find the closest (x,y) to (hoverX, hoverY) + for (let i = 0; i < Xarrays.length; i++) { + if (!isActiveSeries(i)) { + continue + } - if (j !== -1) { - // find nearest graph on y-axis relevanted to nearest point on x-axis - let currY = Yarrays[activeIndex][j] - let diffY = Math.abs(hoverY - currY) - currIndex = activeIndex - - Yarrays.forEach((arrY, iAY) => { - const newDiff = Math.abs(hoverY - arrY[j]) - if (newDiff <= diffY) { - diffY = newDiff - currIndex = iAY - } - }) - } + const xArr = Xarrays[i] + const yArr = Yarrays[i] - return { - index: currIndex, - j, - } - } + // Ensure both xArr and yArr have equal lengths and valid data + const len = Math.min(xArr.length, yArr.length) - getFirstActiveXArray(Xarrays) { - const w = this.w - let activeIndex = 0 + for (let j = 0; j < len; j++) { + const xVal = xArr[j] + const yVal = yArr[j] - let firstActiveSeriesIndex = Xarrays.map((xarr, index) => { - return xarr.length > 0 ? index : -1 - }) + // Compute Euclidean distance from hover point + const distX = hoverX - xVal + const distY = hoverY - yVal + const dist = Math.sqrt(distX * distX + distY * distY) - for (let a = 0; a < firstActiveSeriesIndex.length; a++) { - if ( - firstActiveSeriesIndex[a] !== -1 && - w.globals.collapsedSeriesIndices.indexOf(a) === -1 && - w.globals.ancillaryCollapsedSeriesIndices.indexOf(a) === -1 - ) { - activeIndex = firstActiveSeriesIndex[a] - break + if (dist < closestDist) { + closestDist = dist + closestSeriesIndex = i + closestPointIndex = j + } } } - return activeIndex + return { + index: closestSeriesIndex, + j: closestPointIndex, + } } closestInArray(val, arr) {