From 223357079431c762dcfcfc925a22ab1c8cd61350 Mon Sep 17 00:00:00 2001 From: Simon Olander Date: Tue, 16 Dec 2025 14:11:20 +0100 Subject: [PATCH 1/2] [FEATURE] updates nearby-series to support logarithmic scaled data This change adds a scaling to the log-base data to convert it to a linear space for nearby series finding. If this is not present and you use a log-based chart, you end up having millions of data points within just a few pixels. --------- Signed-off-by: Simon Olander --- .../src/TimeSeriesTooltip/nearby-series.ts | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/components/src/TimeSeriesTooltip/nearby-series.ts b/components/src/TimeSeriesTooltip/nearby-series.ts index ab8dceb..b2a2f84 100644 --- a/components/src/TimeSeriesTooltip/nearby-series.ts +++ b/components/src/TimeSeriesTooltip/nearby-series.ts @@ -17,7 +17,7 @@ import { formatValue, TimeSeriesValueTuple, FormatOptions, TimeSeries } from '@p import { EChartsDataFormat, OPTIMIZED_MODE_SERIES_LIMIT, TimeChartSeriesMapping, DatapointInfo } from '../model'; import { batchDispatchNearbySeriesActions, getPointInGrid, getClosestTimestamp } from '../utils'; import { CursorCoordinates, CursorData, EMPTY_TOOLTIP_DATA } from './tooltip-model'; - +import {pow} from 'mathjs'; // increase multipliers to show more series in tooltip export const INCREASE_NEARBY_SERIES_MULTIPLIER = 5.5; // adjusts how many series show in tooltip (higher == more series shown) export const DYNAMIC_NEARBY_SERIES_MULTIPLIER = 30; // used for adjustment after series number divisor @@ -47,7 +47,8 @@ export function checkforNearbyTimeSeries( pointInGrid: number[], yBuffer: number, chart: EChartsInstance, - format?: FormatOptions + format?: FormatOptions, + logBase?: number, ): NearbySeriesArray { const currentNearbySeriesData: NearbySeriesArray = []; const cursorX: number | null = pointInGrid[0] ?? null; @@ -96,9 +97,9 @@ export function checkforNearbyTimeSeries( const xValue = nearbyTimeSeries[0]; const yValue = nearbyTimeSeries[1]; - // TODO: ensure null values not displayed in tooltip if (yValue !== undefined && yValue !== null) { + //console.log(cursorY <= yValue + yBuffer, cursorY >= yValue - yBuffer, "cursorY", cursorY ,"yValue", yValue, "yBuffer", yBuffer); if (closestTimestamp === xValue) { if (cursorY <= yValue + yBuffer && cursorY >= yValue - yBuffer) { // show fewer bold series in tooltip when many total series @@ -336,7 +337,22 @@ export function getNearbySeriesData({ const pointInGrid = getPointInGrid(mousePos.plotCanvas.x, mousePos.plotCanvas.y, chart); if (pointInGrid !== null) { const chartModel = chart['_model']; - const yInterval = chartModel.getComponent('yAxis').axis.scale._interval; + const yAxisScale = chartModel.getComponent('yAxis').axis.scale; + const isLogScale = yAxisScale.type === 'log'; + let yInterval = yAxisScale._interval; + + // For logarithmic scales, convert the log interval to actual data range + if (isLogScale && yAxisScale.base) { + const logBase = yAxisScale.base; + const extent = yAxisScale._extent; + // Calculate actual data range from log extent + // extent is in log space (e.g., [0, 2] for 10^0 to 10^2) + const actualMin = Math.pow(logBase, extent[0]); + const actualMax = Math.pow(logBase, extent[1]); + // Use a fraction of the actual range as the interval + yInterval = (actualMax - actualMin) / 100; + } + const totalSeries = data.length; const yBuffer = getYBuffer({ yInterval, totalSeries, showAllSeries }); return checkforNearbyTimeSeries(data, seriesMapping, pointInGrid, yBuffer, chart, format); @@ -439,7 +455,6 @@ export function getYBuffer({ if (showAllSeries) { return yInterval * 10; // roughly correlates with grid so entire canvas is searched } - // never let nearby series range be less than roughly the size of a single tick const yBufferMin = yInterval * 0.3; @@ -448,7 +463,6 @@ export function getYBuffer({ const adjustedBuffer = (yInterval * DYNAMIC_NEARBY_SERIES_MULTIPLIER) / totalSeries; return Math.max(yBufferMin, adjustedBuffer); } - // increase multiplier to expand nearby series range return Math.max(yBufferMin, yInterval * INCREASE_NEARBY_SERIES_MULTIPLIER); } From bcf1287cf544e407bb34edcebbd8272b4faab3d6 Mon Sep 17 00:00:00 2001 From: Simon Olander Date: Thu, 18 Dec 2025 17:48:24 +0100 Subject: [PATCH 2/2] Update nearby-series.ts Resolved linting by removing redundant mathjs dep (replaced with ** operator) Signed-off-by: Simon Olander --- components/src/TimeSeriesTooltip/nearby-series.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/components/src/TimeSeriesTooltip/nearby-series.ts b/components/src/TimeSeriesTooltip/nearby-series.ts index b2a2f84..b17210c 100644 --- a/components/src/TimeSeriesTooltip/nearby-series.ts +++ b/components/src/TimeSeriesTooltip/nearby-series.ts @@ -17,7 +17,7 @@ import { formatValue, TimeSeriesValueTuple, FormatOptions, TimeSeries } from '@p import { EChartsDataFormat, OPTIMIZED_MODE_SERIES_LIMIT, TimeChartSeriesMapping, DatapointInfo } from '../model'; import { batchDispatchNearbySeriesActions, getPointInGrid, getClosestTimestamp } from '../utils'; import { CursorCoordinates, CursorData, EMPTY_TOOLTIP_DATA } from './tooltip-model'; -import {pow} from 'mathjs'; + // increase multipliers to show more series in tooltip export const INCREASE_NEARBY_SERIES_MULTIPLIER = 5.5; // adjusts how many series show in tooltip (higher == more series shown) export const DYNAMIC_NEARBY_SERIES_MULTIPLIER = 30; // used for adjustment after series number divisor @@ -47,8 +47,7 @@ export function checkforNearbyTimeSeries( pointInGrid: number[], yBuffer: number, chart: EChartsInstance, - format?: FormatOptions, - logBase?: number, + format?: FormatOptions ): NearbySeriesArray { const currentNearbySeriesData: NearbySeriesArray = []; const cursorX: number | null = pointInGrid[0] ?? null; @@ -99,7 +98,6 @@ export function checkforNearbyTimeSeries( const yValue = nearbyTimeSeries[1]; // TODO: ensure null values not displayed in tooltip if (yValue !== undefined && yValue !== null) { - //console.log(cursorY <= yValue + yBuffer, cursorY >= yValue - yBuffer, "cursorY", cursorY ,"yValue", yValue, "yBuffer", yBuffer); if (closestTimestamp === xValue) { if (cursorY <= yValue + yBuffer && cursorY >= yValue - yBuffer) { // show fewer bold series in tooltip when many total series @@ -340,19 +338,17 @@ export function getNearbySeriesData({ const yAxisScale = chartModel.getComponent('yAxis').axis.scale; const isLogScale = yAxisScale.type === 'log'; let yInterval = yAxisScale._interval; - // For logarithmic scales, convert the log interval to actual data range if (isLogScale && yAxisScale.base) { const logBase = yAxisScale.base; const extent = yAxisScale._extent; // Calculate actual data range from log extent // extent is in log space (e.g., [0, 2] for 10^0 to 10^2) - const actualMin = Math.pow(logBase, extent[0]); - const actualMax = Math.pow(logBase, extent[1]); + const actualMin = logBase ** extent[0]; + const actualMax = logBase ** extent[1]; // Use a fraction of the actual range as the interval yInterval = (actualMax - actualMin) / 100; } - const totalSeries = data.length; const yBuffer = getYBuffer({ yInterval, totalSeries, showAllSeries }); return checkforNearbyTimeSeries(data, seriesMapping, pointInGrid, yBuffer, chart, format);