From 02a9cc92c89e6205119f146536ab1fffe28427bc Mon Sep 17 00:00:00 2001 From: VillageR88 Date: Fri, 29 Sep 2023 12:49:45 +0200 Subject: [PATCH 1/2] Add Synchronize graphs on mobile/touch Signed-off-by: VillageR88 --- src/utils/uPlot/mouseZoomPlugin.ts | 35 ++++++++++++++++++------------ 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/utils/uPlot/mouseZoomPlugin.ts b/src/utils/uPlot/mouseZoomPlugin.ts index fd662e28..250b27e6 100644 --- a/src/utils/uPlot/mouseZoomPlugin.ts +++ b/src/utils/uPlot/mouseZoomPlugin.ts @@ -6,6 +6,8 @@ interface WheelZoomPluginOptions { animationDuration?: number; } +const chartInstances: uPlot[] = []; + function wheelZoomPlugin(options: WheelZoomPluginOptions = {}): Plugin { const factor = options.factor || 0.9; @@ -15,8 +17,8 @@ function wheelZoomPlugin(options: WheelZoomPluginOptions = {}): Plugin { let yMax: number; let xRange: number; let yRange: number; - let over = null; - let rect: DOMRect; + let over: HTMLElement | null = null; + let rect: DOMRect | null = null; function isCtrlPressed(e: MouseEvent): boolean { return e.ctrlKey || e.metaKey; @@ -50,6 +52,8 @@ function wheelZoomPlugin(options: WheelZoomPluginOptions = {}): Plugin { return { hooks: { ready(u: uPlot) { + chartInstances.push(u); // Add the current chart instance to the list + xMin = u.scales.x.min ?? 0; xMax = u.scales.x.max ?? 0; yMin = u.scales.y.min ?? 0; @@ -59,7 +63,7 @@ function wheelZoomPlugin(options: WheelZoomPluginOptions = {}): Plugin { over = u.over; rect = over.getBoundingClientRect(); - over.addEventListener('mousedown', (e: MouseEvent) => { + over?.addEventListener('mousedown', (e: MouseEvent) => { if (e.button === 1) { e.preventDefault(); @@ -84,7 +88,7 @@ function wheelZoomPlugin(options: WheelZoomPluginOptions = {}): Plugin { } }); - over.addEventListener('wheel', (e: WheelEvent) => { + over?.addEventListener('wheel', (e: WheelEvent) => { e.preventDefault(); if (!isCtrlPressed(e)) { @@ -94,8 +98,8 @@ function wheelZoomPlugin(options: WheelZoomPluginOptions = {}): Plugin { const cursor = u.cursor; const { left, top } = cursor; - const leftPct = (left || 0) / rect.width; - const btmPct = 1 - (top || 0) / rect.height; + const leftPct = (left || 0) / (rect?.width || 1); + const btmPct = 1 - (top || 0) / (rect?.height || 1); const xVal = u.posToVal(left || 0, 'x'); const yVal = u.posToVal(top || 0, 'y'); const oxRange = (u.scales.x.max || 0) - (u.scales.x.min || 0); @@ -111,15 +115,18 @@ function wheelZoomPlugin(options: WheelZoomPluginOptions = {}): Plugin { let nyMax = nyMin + nyRange; [nyMin, nyMax] = clamp(nyRange, nyMin, nyMax, yRange, yMin, yMax); - u.batch(() => { - u.setScale('x', { - min: nxMin, - max: nxMax, - }); + // Loop through all chart instances and apply the same zoom to each of them + chartInstances.forEach((chartInstance) => { + chartInstance.batch(() => { + chartInstance.setScale('x', { + min: nxMin, + max: nxMax, + }); - u.setScale('y', { - min: nyMin, - max: nyMax, + chartInstance.setScale('y', { + min: nyMin, + max: nyMax, + }); }); }); }); From c4d9fbc5ee7fa308e4d421372279b6a136599be6 Mon Sep 17 00:00:00 2001 From: VillageR88 Date: Fri, 29 Sep 2023 13:22:29 +0200 Subject: [PATCH 2/2] Add Synchronize graphs on mobile/touch Signed-off-by: VillageR88 --- src/utils/uPlot/touchZoomPlugin.ts | 34 ++++++++++++++++-------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/utils/uPlot/touchZoomPlugin.ts b/src/utils/uPlot/touchZoomPlugin.ts index 789b4897..ee8f43a6 100644 --- a/src/utils/uPlot/touchZoomPlugin.ts +++ b/src/utils/uPlot/touchZoomPlugin.ts @@ -8,6 +8,8 @@ interface Point { dy: number; } +const chartInstances: uPlot[] = []; + const touchZoomPlugin = () => { const init = (u: uPlot, _opts: any, _data: any) => { const { over } = u; @@ -56,17 +58,12 @@ const touchZoomPlugin = () => { let rafPending = false; - const zoom = () => { + const zoomCharts = () => { rafPending = false; const left = to.x; const top = to.y; - // non-uniform scaling - // let xFactor = fr.dx / to.dx; - // let yFactor = fr.dy / to.dy; - - // uniform x/y scaling const xFactor = fr.d! / to.d!; const yFactor = fr.d! / to.d!; @@ -81,15 +78,18 @@ const touchZoomPlugin = () => { const nyMin = yVal - btmPct * nyRange; const nyMax = nyMin + nyRange; - u.batch(() => { - u.setScale('x', { - min: nxMin, - max: nxMax, - }); - - u.setScale('y', { - min: nyMin, - max: nyMax, + // Loop through all chart instances and apply the same zoom to each of them + chartInstances.forEach((chartInstance) => { + chartInstance.batch(() => { + chartInstance.setScale('x', { + min: nxMin, + max: nxMax, + }); + + chartInstance.setScale('y', { + min: nyMin, + max: nyMax, + }); }); }); }; @@ -99,7 +99,7 @@ const touchZoomPlugin = () => { if (!rafPending) { rafPending = true; - requestAnimationFrame(zoom); + requestAnimationFrame(zoomCharts); } }; @@ -128,6 +128,8 @@ const touchZoomPlugin = () => { over.addEventListener('touchend', (_e: TouchEvent) => { document.removeEventListener('touchmove', touchmove); }); + + chartInstances.push(u); // Add the current chart instance to the list }; return {