This is an automated email from the ASF dual-hosted git repository. zqr10159 pushed a commit to branch 2.0.0 in repository https://gitbox.apache.org/repos/asf/hertzbeat.git
commit 04aa6d5fdff5a8be816052f50561be0bec148709 Author: Logic <[email protected]> AuthorDate: Sun May 31 10:05:13 2026 +0800 fix(web-next): bound topology operator zoom --- web-next/app/topology/page.test.tsx | 3 ++- web-next/app/ui-lab/page.test.tsx | 3 ++- web-next/lib/hertzbeat-2-gap-audit.test.ts | 1 + web-next/lib/hertzbeat-2-gap-audit.ts | 1 + web-next/packages/hertzbeat-ui/src/topology-g6.test.tsx | 15 +++++++++++++-- web-next/packages/hertzbeat-ui/src/topology-g6.tsx | 5 +++-- 6 files changed, 22 insertions(+), 6 deletions(-) diff --git a/web-next/app/topology/page.test.tsx b/web-next/app/topology/page.test.tsx index 5b2c37689a..fc92222fca 100644 --- a/web-next/app/topology/page.test.tsx +++ b/web-next/app/topology/page.test.tsx @@ -884,7 +884,8 @@ describe('topology page', () => { expect(html).toContain('data-hz-topology-g6-wheel-owner="hertzbeat-ui-g6-wheel"'); expect(html).toContain('data-hz-topology-g6-wheel-listener-passive="false-control"'); expect(html).toContain('data-hz-topology-g6-wheel-origin="pointer-clamped"'); - expect(html).toContain('data-hz-topology-g6-wheel-zoom-bounds="0.18-4.8"'); + expect(html).toContain('data-hz-topology-g6-wheel-zoom-bounds="0.18-2.2"'); + expect(html).toContain('data-hz-topology-g6-operator-zoom-growth="bounded-readable-nodes"'); expect(html).toContain('data-hz-topology-g6-keyboard-shortcuts="plus-minus-zero-fit"'); expect(html).toContain('data-hz-topology-g6-keyboard-shortcuts-owner="hertzbeat-ui-g6-keyboard"'); expect(html).toContain('data-hz-topology-g6-keyboard-actions="zoom-in zoom-out reset-view fit-view"'); diff --git a/web-next/app/ui-lab/page.test.tsx b/web-next/app/ui-lab/page.test.tsx index 3093c7c6d8..fe58142a55 100644 --- a/web-next/app/ui-lab/page.test.tsx +++ b/web-next/app/ui-lab/page.test.tsx @@ -2389,7 +2389,8 @@ describe('HertzBeat UI lab page', () => { expect(html).toContain('data-hz-topology-g6-wheel-owner="hertzbeat-ui-g6-wheel"'); expect(html).toContain('data-hz-topology-g6-wheel-listener-passive="false-control"'); expect(html).toContain('data-hz-topology-g6-wheel-origin="pointer-clamped"'); - expect(html).toContain('data-hz-topology-g6-wheel-zoom-bounds="0.18-4.8"'); + expect(html).toContain('data-hz-topology-g6-wheel-zoom-bounds="0.18-2.2"'); + expect(html).toContain('data-hz-topology-g6-operator-zoom-growth="bounded-readable-nodes"'); expect(html).toContain('data-hz-topology-g6-keyboard-shortcuts="plus-minus-zero-fit"'); expect(html).toContain('data-hz-topology-g6-keyboard-shortcuts-owner="hertzbeat-ui-g6-keyboard"'); expect(html).toContain('data-hz-topology-g6-keyboard-actions="zoom-in zoom-out reset-view fit-view"'); diff --git a/web-next/lib/hertzbeat-2-gap-audit.test.ts b/web-next/lib/hertzbeat-2-gap-audit.test.ts index 24dc9a9c1a..b55c6c6bac 100644 --- a/web-next/lib/hertzbeat-2-gap-audit.test.ts +++ b/web-next/lib/hertzbeat-2-gap-audit.test.ts @@ -238,6 +238,7 @@ describe('HertzBeat 2.0 release gap audit', () => { '/topology reuses HzTopologyMetricTable header, row, route, RED cell, badge, and action ownership for edge ranking', '/topology reuses HzTopologyMetricTable graph-first density for compact companion RED ranking', '/topology wires HzTopologyMetricTable render-window companion metadata from the same G6 graph so hidden nodes keep table investigation context', + '/topology exposes windowed API graph RED rankings as a graph-bottom HzTopologyMetricTable so hidden render-window edges stay inspectable after the right rail is removed', '/topology marks HzTopologyMetricTable rows with source and target visibility from the current G6 render window instead of losing hidden-edge context', '/topology exposes HzTopologyMetricTable render-window row count summaries for future visible, partial, and hidden relationship filters', '/topology reuses HzTopologyMetricTable in-page render-window filters so ordinary RED table filtering does not navigate or remount the G6 canvas', diff --git a/web-next/lib/hertzbeat-2-gap-audit.ts b/web-next/lib/hertzbeat-2-gap-audit.ts index ce605d7ade..f1493966a1 100644 --- a/web-next/lib/hertzbeat-2-gap-audit.ts +++ b/web-next/lib/hertzbeat-2-gap-audit.ts @@ -340,6 +340,7 @@ const functionalGaps: HertzBeat2Gap[] = [ '/topology reuses HzTopologyMetricTable header, row, route, RED cell, badge, and action ownership for edge ranking', '/topology reuses HzTopologyMetricTable graph-first density for compact companion RED ranking', '/topology wires HzTopologyMetricTable render-window companion metadata from the same G6 graph so hidden nodes keep table investigation context', + '/topology exposes windowed API graph RED rankings as a graph-bottom HzTopologyMetricTable so hidden render-window edges stay inspectable after the right rail is removed', '/topology marks HzTopologyMetricTable rows with source and target visibility from the current G6 render window instead of losing hidden-edge context', '/topology exposes HzTopologyMetricTable render-window row count summaries for future visible, partial, and hidden relationship filters', '/topology reuses HzTopologyMetricTable in-page render-window filters so ordinary RED table filtering does not navigate or remount the G6 canvas', diff --git a/web-next/packages/hertzbeat-ui/src/topology-g6.test.tsx b/web-next/packages/hertzbeat-ui/src/topology-g6.test.tsx index f8f730f6ec..47bd846a98 100644 --- a/web-next/packages/hertzbeat-ui/src/topology-g6.test.tsx +++ b/web-next/packages/hertzbeat-ui/src/topology-g6.test.tsx @@ -15,6 +15,7 @@ import { clampHzTopologyG6AutoFitZoom, getHzTopologyG6NodeIcon, HZ_TOPOLOGY_G6_AUTO_FIT_MAX_ZOOM, + HZ_TOPOLOGY_G6_MAX_ZOOM, HZ_TOPOLOGY_G6_NODE_ICON_CATALOG, HzTopologyG6Canvas } from './topology-g6'; @@ -373,7 +374,8 @@ describe('@hertzbeat/ui topology G6 canvas', () => { expect(html).toContain('data-hz-topology-g6-auto-fit-max-zoom="1"'); expect(html).toContain('data-hz-topology-g6-auto-fit-growth="no-magnify-small-graphs"'); expect(html).toContain('data-hz-topology-g6-auto-fit-zoom-range-owner="hertzbeat-ui-g6-auto-fit-zoom-range"'); - expect(html).toContain('data-hz-topology-g6-operator-zoom-bounds="0.18-4.8"'); + expect(html).toContain('data-hz-topology-g6-operator-zoom-bounds="0.18-2.2"'); + expect(html).toContain('data-hz-topology-g6-operator-zoom-growth="bounded-readable-nodes"'); expect(html).toContain('data-hz-topology-g6-fit-mode="overflow-only-center"'); expect(clampHzTopologyG6AutoFitZoom(4.8)).toBe(HZ_TOPOLOGY_G6_AUTO_FIT_MAX_ZOOM); expect(clampHzTopologyG6AutoFitZoom(0.72)).toBe(0.72); @@ -396,6 +398,15 @@ describe('@hertzbeat/ui topology G6 canvas', () => { expect(html).toContain('data-hz-topology-g6-reset-behavior="zoom-one-overflow-fit-center"'); }); + it('keeps operator zoom below the giant-node range that can make a small graph fill wide browsers', () => { + const html = renderToStaticMarkup(<HzTopologyG6Canvas graph={graph} />); + + expect(html).toContain('data-hz-topology-g6-operator-zoom-bounds="0.18-2.2"'); + expect(html).toContain('data-hz-topology-g6-wheel-zoom-bounds="0.18-2.2"'); + expect(html).toContain('data-hz-topology-g6-operator-zoom-growth="bounded-readable-nodes"'); + expect(HZ_TOPOLOGY_G6_MAX_ZOOM).toBe(2.2); + }); + it('preserves operator wheel and pan zoom while hover or selection styling updates redraw the G6 graph', () => { const source = String(HzTopologyG6Canvas); const html = renderToStaticMarkup(<HzTopologyG6Canvas graph={graph} selectedNodeId="svc-checkout" />); @@ -1060,7 +1071,7 @@ describe('@hertzbeat/ui topology G6 canvas', () => { expect(html).toContain('data-hz-topology-g6-wheel-owner="hertzbeat-ui-g6-wheel"'); expect(html).toContain('data-hz-topology-g6-wheel-listener-passive="false-control"'); expect(html).toContain('data-hz-topology-g6-wheel-origin="pointer-clamped"'); - expect(html).toContain('data-hz-topology-g6-wheel-zoom-bounds="0.18-4.8"'); + expect(html).toContain('data-hz-topology-g6-wheel-zoom-bounds="0.18-2.2"'); expect(html).toContain('data-hz-topology-g6-keyboard-shortcuts="plus-minus-zero-fit"'); expect(html).toContain('data-hz-topology-g6-keyboard-shortcuts-owner="hertzbeat-ui-g6-keyboard"'); expect(html).toContain('data-hz-topology-g6-keyboard-actions="zoom-in zoom-out reset-view fit-view"'); diff --git a/web-next/packages/hertzbeat-ui/src/topology-g6.tsx b/web-next/packages/hertzbeat-ui/src/topology-g6.tsx index e913a7de1f..4374eb251d 100644 --- a/web-next/packages/hertzbeat-ui/src/topology-g6.tsx +++ b/web-next/packages/hertzbeat-ui/src/topology-g6.tsx @@ -239,7 +239,7 @@ type G6GraphRuntime = { }; export const HZ_TOPOLOGY_G6_MIN_ZOOM = 0.18; -export const HZ_TOPOLOGY_G6_MAX_ZOOM = 4.8; +export const HZ_TOPOLOGY_G6_MAX_ZOOM = 2.2; export const HZ_TOPOLOGY_G6_AUTO_FIT_MAX_ZOOM = 1; type HzTopologyG6ViewportSnapshot = { @@ -1855,6 +1855,7 @@ export function HzTopologyG6Canvas({ data-hz-topology-g6-auto-fit-growth="no-magnify-small-graphs" data-hz-topology-g6-auto-fit-zoom-range-owner="hertzbeat-ui-g6-auto-fit-zoom-range" data-hz-topology-g6-operator-zoom-bounds={`${HZ_TOPOLOGY_G6_MIN_ZOOM}-${HZ_TOPOLOGY_G6_MAX_ZOOM}`} + data-hz-topology-g6-operator-zoom-growth="bounded-readable-nodes" data-hz-topology-g6-fit-mode="overflow-only-center" data-hz-topology-g6-viewport-interaction-state={viewportInteractionState} data-hz-topology-g6-viewport-interaction-owner="hertzbeat-ui-g6-viewport-interaction" @@ -1882,7 +1883,7 @@ export function HzTopologyG6Canvas({ data-hz-topology-g6-wheel-owner="hertzbeat-ui-g6-wheel" data-hz-topology-g6-wheel-listener-passive="false-control" data-hz-topology-g6-wheel-origin="pointer-clamped" - data-hz-topology-g6-wheel-zoom-bounds="0.18-4.8" + data-hz-topology-g6-wheel-zoom-bounds={`${HZ_TOPOLOGY_G6_MIN_ZOOM}-${HZ_TOPOLOGY_G6_MAX_ZOOM}`} data-hz-topology-g6-node-motion="locked-layout" data-hz-topology-g6-node-motion-owner="hertzbeat-ui-g6-node-motion" data-hz-topology-g6-selection-engine="hertzbeat-controlled" --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
