From f6e5d4166f320afb8e7a5c20adde92b767c8eb58 Mon Sep 17 00:00:00 2001 From: HARPER Jon Date: Fri, 13 Dec 2024 10:57:12 +0100 Subject: [PATCH 1/4] Don't update dynamiccssrules on translations, add chromium workaround Signed-off-by: HARPER Jon --- .../network-area-diagram-viewer.ts | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts index 00830257..585af7dc 100644 --- a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts +++ b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts @@ -48,6 +48,18 @@ export type OnToggleNadHoverCallbackType = ( equipmentType: string ) => void; +// update css rules when zoom changes by this amount. This allows to not +// update when only translating (when translating, round errors lead to +// epsilon changes in the float values), or not too often a bit when smooth +// scrolling (the update may be entirely missed when smooth scrolling if +// you don't go over the threshold but that's ok, the user doesn't see rule +// threshold values so he will continue to zoom in or out to trigger the +// rule update. Using a debounce that ensure the last update is done +// eventually may be even worse as it could introduce flicker after the +// delay after the last zoom change. We need a value that gives good +// performance but doesn't change the user experience +const dynamicCssRulesUpdateThreshold = 0.01; + export class NetworkAreaDiagramViewer { container: HTMLElement; svgContent: string; @@ -73,6 +85,7 @@ export class NetworkAreaDiagramViewer { onSelectNodeCallback: OnSelectNodeCallbackType | null; dynamicCssRules: CSS_RULE[]; onToggleHoverCallback: OnToggleNadHoverCallbackType | null; + previousMaxDisplayedSize: number; constructor( container: HTMLElement, @@ -113,6 +126,7 @@ export class NetworkAreaDiagramViewer { this.onMoveTextNodeCallback = onMoveTextNodeCallback; this.onSelectNodeCallback = onSelectNodeCallback; this.onToggleHoverCallback = onToggleHoverCallback; + this.previousMaxDisplayedSize = 0; } public setWidth(width: number): void { @@ -171,6 +185,14 @@ export class NetworkAreaDiagramViewer { this.svgDraw?.viewbox(viewBox); } + public setPreviousMaxDisplayedSize(previousMaxDisplayedSize: number): void { + this.previousMaxDisplayedSize = previousMaxDisplayedSize; + } + + public getPreviousMaxDisplayedSize(): number { + return this.previousMaxDisplayedSize; + } + public getDynamicCssRules() { return this.dynamicCssRules; } @@ -1371,6 +1393,15 @@ export class NetworkAreaDiagramViewer { public checkAndUpdateLevelOfDetail(svg: SVGSVGElement) { const maxDisplayedSize = this.getCurrentlyMaxDisplayedSize(); + const previousMaxDisplayedSize = this.getPreviousMaxDisplayedSize(); + // in case of bad or unset values NaN or Infinity, this condition is skipped and the function behaves as if zoom changed + if ( + Math.abs(previousMaxDisplayedSize - maxDisplayedSize) / previousMaxDisplayedSize < + dynamicCssRulesUpdateThreshold + ) { + return; + } + this.setPreviousMaxDisplayedSize(maxDisplayedSize); // We will check each dynamic css rule to see if we crossed a zoom threshold. If this is the case, we // update the rule's threshold status and trigger the CSS change in the SVG. this.getDynamicCssRules().forEach((rule) => { @@ -1388,5 +1419,28 @@ export class NetworkAreaDiagramViewer { this.updateSvgCssDisplayValue(svg, rule.cssSelector, rule.aboveThresholdCssDeclaration); } }); + //Workaround chromium (tested on edge and google-chrome 131) doesn't + //redraw things with percentages on viewbox changes but it should, + //force it. Firefox does correctly redraw, but we force for everyone to + //have the same behavior everywhere and detect problems more easily. + //we can't use innerHtml+='' on the