show popup once data is loaded

This commit is contained in:
vcoppe committed 2026-10-18 16:27:51 +02:00
1 parent a07da16163
commit f9e8d4c644
1 file changed
+52 -13
@@ -71,6 +71,8 @@ export class ElevationProfile {
*/ */
private _hovered: { index: number; loaded: boolean; point?: SelectionPoint } | null = null; private _hovered: { index: number; loaded: boolean; point?: SelectionPoint } | null = null;
private _loadingHovered = false; private _loadingHovered = false;
/** The last move over the chart, held until the data of its trackpoint is read. */
private _heldMove: MouseEvent | null = null;
private _slicedStatistics: Writable<SlicedStatistics | undefined>; private _slicedStatistics: Writable<SlicedStatistics | undefined>;
private _hoveredPoint: Writable<Coordinates | null>; private _hoveredPoint: Writable<Coordinates | null>;
private _additionalDatasets: Readable<string[]>; private _additionalDatasets: Readable<string[]>;
@@ -199,11 +201,14 @@ export class ElevationProfile {
label: (context: TooltipItem<'line'>) => { label: (context: TooltipItem<'line'>) => {
let point = context.raw as ElevationProfilePoint; let point = context.raw as ElevationProfilePoint;
if (context.datasetIndex === 0) { if (context.datasetIndex === 0) {
if (this._dragging) { this._hoveredPoint.set(
this._hoveredPoint.set(null); this._dragging
} else { ? null
this.hover(point.index); : {
} lat: this._data.lat[point.index],
lng: this._data.lng[point.index],
}
);
return `${i18n._('quantities.elevation')}: ${getElevationWithUnits(point.y, false)}`; return `${i18n._('quantities.elevation')}: ${getElevationWithUnits(point.y, false)}`;
} else if (context.datasetIndex === 1) { } else if (context.datasetIndex === 1) {
return `${get(velocityUnits) === 'speed' ? i18n._('quantities.speed') : i18n._('quantities.pace')}: ${getVelocityWithUnits(point.y, false)}`; return `${get(velocityUnits) === 'speed' ? i18n._('quantities.speed') : i18n._('quantities.pace')}: ${getVelocityWithUnits(point.y, false)}`;
@@ -356,10 +361,31 @@ export class ElevationProfile {
afterEvent: (chart: Chart, args: { event: ChartEvent }) => { afterEvent: (chart: Chart, args: { event: ChartEvent }) => {
if (args.event.type === 'mouseout') { if (args.event.type === 'mouseout') {
this._hovered = null; this._hovered = null;
this._heldMove = null;
this._hoveredPoint.set(null); this._hoveredPoint.set(null);
} }
}, },
}, },
{
// The tooltip only shows a trackpoint once all its data is read: a move to
// another one is held until then, and replayed (see `loadHovered`).
id: 'waitForTrackpoint',
events: ['mousemove'],
beforeEvent: (chart: Chart, args: { event: ChartEvent }) => {
const index = this.indexAt(args.event);
if (index === undefined) {
return;
}
const hovered = this._hovered;
if (hovered?.index === index && hovered.loaded) {
this._heldMove = null;
return;
}
this._heldMove = args.event.native as MouseEvent;
this.hover(index);
return false;
},
},
], ],
}); });
@@ -646,12 +672,25 @@ export class ElevationProfile {
} }
} }
/** The trackpoint that the tooltip shows for an event, `undefined` outside of the chart. */
private indexAt(event: ChartEvent): number | undefined {
const elements = this._chart?.getElementsAtEventForMode(
event as unknown as Event,
'nearest',
{ axis: 'x', intersect: false },
false
);
const element = elements?.find((element) => element.datasetIndex === 0);
// the data of the chart can be decimated: its points are the ones of the elements
const point = element && this._chart?.data.datasets[0].data[element.index];
return (point as ElevationProfilePoint | undefined)?.index;
}
/** /**
* Shows the hovered trackpoint on the map, and reads the rest of its data from the engine for * Reads the data of the hovered trackpoint from the engine, for the tooltip. One trackpoint is
* the tooltip. One trackpoint is read at a time, the last one hovered. * read at a time, the last one hovered.
*/ */
hover(index: number) { hover(index: number) {
this._hoveredPoint.set({ lat: this._data.lat[index], lng: this._data.lng[index] });
if (this._hovered?.index === index) { if (this._hovered?.index === index) {
return; return;
} }
@@ -673,11 +712,11 @@ export class ElevationProfile {
} }
hovered.loaded = true; hovered.loaded = true;
hovered.point = point; hovered.point = point;
const chart = this._chart; // the move that was held can now show the tooltip
if (chart?.tooltip && chart.tooltip.getActiveElements().length > 0) { const move = this._heldMove;
// the tooltip asks its callbacks again (the method is not in the types) this._heldMove = null;
(chart.tooltip as unknown as { update(changed: boolean): void }).update(true); if (move) {
chart.draw(); this._canvas.dispatchEvent(new MouseEvent(move.type, move));
} }
} }
} finally { } finally {