Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Prevent visual refresh glitches in NAD by applying debounce only during zoom operations #138

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export class NetworkAreaDiagramViewer {
onSelectNodeCallback: OnSelectNodeCallbackType | null;
dynamicCssRules: CSS_RULE[];
onToggleHoverCallback: OnToggleNadHoverCallbackType | null;
isZooming: boolean;

constructor(
container: HTMLElement,
Expand Down Expand Up @@ -113,6 +114,7 @@ export class NetworkAreaDiagramViewer {
this.onMoveTextNodeCallback = onMoveTextNodeCallback;
this.onSelectNodeCallback = onSelectNodeCallback;
this.onToggleHoverCallback = onToggleHoverCallback;
this.isZooming = false;
}

public setWidth(width: number): void {
Expand Down Expand Up @@ -254,6 +256,7 @@ export class NetworkAreaDiagramViewer {
this.onToggleHoverCallback?.(false, null, '', '');
});
}

this.svgDraw.on('panStart', function () {
if (drawnSvg.parentElement != undefined) {
drawnSvg.parentElement.style.cursor = 'move';
Expand Down Expand Up @@ -287,18 +290,26 @@ export class NetworkAreaDiagramViewer {
// (we have to do this instead of using panzoom's 'zoom' event to have accurate viewBox updates)
const targetNode: SVGSVGElement = this.svgDraw.node;
// Callback function to execute when mutations are observed
const observerCallback = (mutationList: MutationRecord[]) => {
const handleViewBoxChange = (mutationList: MutationRecord[]) => {
for (const mutation of mutationList) {
if (mutation.attributeName === 'viewBox') {
this.checkAndUpdateLevelOfDetail(targetNode);
}
}
};

// Create a debounced version of the observer callback to limit the frequency of calls when the 'viewBox' attribute changes,
// particularly during zooming operations, improving performance and avoiding redundant updates.
const debouncedObserverCallback = debounce(observerCallback, 50);
const observer = new MutationObserver(debouncedObserverCallback);
// Determine if the callback should be debounced based on zoom activity.
// Debouncing is applied only during zoom operations to improve performance by reducing redundant updates.
// For other actions, debouncing is avoided to prevent issues such as visible refresh glitches in the NAD when moving nodes.
const debouncedHandleViewBoxChange = debounce(handleViewBoxChange, 50);
const observerCallback = (mutationList: MutationRecord[]) => {
if (this.isZooming) {
debouncedHandleViewBoxChange(mutationList);
} else {
handleViewBoxChange(mutationList);
}
};
const observer = new MutationObserver(observerCallback);
observer.observe(targetNode, { attributeFilter: ['viewBox'] });
}

Expand Down Expand Up @@ -330,13 +341,30 @@ export class NetworkAreaDiagramViewer {
}

private enablePanzoom() {
this.svgDraw?.panZoom({
const panZoomInstance = this.svgDraw?.panZoom({
panning: true,
zoomMin: 0.5 / this.ratio, // maximum zoom OUT ratio (0.5 = at best, the displayed area is twice the SVG's size)
zoomMax: 20 * this.ratio, // maximum zoom IN ratio (20 = at best, the displayed area is only 1/20th of the SVG's size)
zoomFactor: 0.2,
margins: { top: 0, left: 0, right: 0, bottom: 0 },
});

// Set zooming state when zooming begins
panZoomInstance?.on('zoom', () => {
this.isZooming = true;
});

// Handle touch-based zoom ending
panZoomInstance?.on('pinchZoomEnd', () => {
this.isZooming = false;
});

// Handle mouse-based panning and zoom ending
panZoomInstance?.on('panEnd', () => {
if (this.isZooming) {
this.isZooming = false;
}
});
}

private disablePanzoom() {
Expand Down
Loading