From b859c3360de09ff6ca9355c62c7ab9bebc453902 Mon Sep 17 00:00:00 2001 From: Kia Lam Date: Mon, 7 Feb 2022 09:12:49 -0800 Subject: [PATCH] Add zoom to fit. --- awx/ui/src/screens/TopologyView/Header.js | 2 + awx/ui/src/screens/TopologyView/MeshGraph.js | 2 +- .../src/screens/TopologyView/TopologyView.js | 40 ++++++++++++++++--- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/awx/ui/src/screens/TopologyView/Header.js b/awx/ui/src/screens/TopologyView/Header.js index e1b8f6648d..4929c8ceb1 100644 --- a/awx/ui/src/screens/TopologyView/Header.js +++ b/awx/ui/src/screens/TopologyView/Header.js @@ -25,6 +25,7 @@ const Header = ({ zoomIn, zoomOut, resetZoom, + zoomFit, }) => { const { light } = PageSectionVariants; return ( @@ -74,6 +75,7 @@ const Header = ({ aria-label={t`Fit to screen`} variant="plain" icon={} + onClick={zoomFit} > diff --git a/awx/ui/src/screens/TopologyView/MeshGraph.js b/awx/ui/src/screens/TopologyView/MeshGraph.js index ab808f2a50..a94c805340 100644 --- a/awx/ui/src/screens/TopologyView/MeshGraph.js +++ b/awx/ui/src/screens/TopologyView/MeshGraph.js @@ -52,7 +52,7 @@ function MeshGraph({ showLegend, zoom }) { } return generateLinks(nodes, getRandomInt(1, n - 1)); }; - const data = generateNodes(getRandomInt(5, 30)); + const data = generateNodes(getRandomInt(250, 250)); const draw = () => { const margin = 15; const defaultRadius = 16; diff --git a/awx/ui/src/screens/TopologyView/TopologyView.js b/awx/ui/src/screens/TopologyView/TopologyView.js index bad237100b..21c52537ba 100644 --- a/awx/ui/src/screens/TopologyView/TopologyView.js +++ b/awx/ui/src/screens/TopologyView/TopologyView.js @@ -38,13 +38,40 @@ function TopologyView() { }; const resetZoom = () => { const margin = 15; + const height = 600; const width = parseInt(d3.select(`#chart`).style('width'), 10) - margin; - d3.select('.mesh-svg').transition().duration(750).call( - zoom.transform, - d3.zoomIdentity, - d3.zoomTransform(d3.select('.mesh-svg').node()).invert([width / 2, 600 / 2]) - ); - } + d3.select('.mesh-svg') + .transition() + .duration(750) + .call( + zoom.transform, + d3.zoomIdentity, + d3 + .zoomTransform(d3.select('.mesh-svg').node()) + .invert([width / 2, height / 2]) + ); + }; + + const zoomFit = () => { + const bounds = d3.select('.mesh').node().getBBox(); + const parent = d3.select('.mesh').node().parentElement; + const fullWidth = parent.clientWidth; + const fullHeight = parent.clientHeight; + const { width, height } = bounds; + const midX = bounds.x + width / 2; + const midY = bounds.y + height / 2; + if (width === 0 || height === 0) return; // nothing to fit + const scale = 0.8 / Math.max(width / fullWidth, height / fullHeight); + const translate = [ + fullWidth / 2 - scale * midX, + fullHeight / 2 - scale * midY, + ]; + const [x, y] = translate; + d3.select('.mesh-svg') + .transition() + .duration(750) + .call(zoom.transform, d3.zoomIdentity.translate(x, y).scale(scale)); + }; return ( <> @@ -54,6 +81,7 @@ function TopologyView() { toggleState={showLegend} zoomIn={zoomIn} zoomOut={zoomOut} + zoomFit={zoomFit} resetZoom={resetZoom} />