dongjoon-hyun commented on code in PR #55769:
URL: https://github.com/apache/spark/pull/55769#discussion_r3209372389


##########
sql/core/src/main/resources/org/apache/spark/sql/execution/ui/static/spark-sql-viz.js:
##########
@@ -694,12 +713,118 @@ function rerenderWithDetailedLabels() {
   setupTooltipForSparkPlanNode(g);
   resizeSvg(svg);
   postprocessForAdditionalMetrics();
+  setupZoomAndPan(svg, zoomLayer);
+}
+
+/* ---------------------- *
+ * | Zoom and pan        | *
+ * ---------------------- */
+
+/*
+ * Wire d3-zoom to the SVG: apply transforms to the inner zoom-layer group,
+ * fit the graph to the viewport on load, and bind toolbar/keyboard controls.
+ */
+function setupZoomAndPan(svg, zoomLayer) {
+  var svgNode = svg.node();
+  if (!svgNode || !zoomLayer || zoomLayer.empty()) return;
+
+  planVizZoom = d3.zoom()
+    .scaleExtent([PlanVizConstants.zoomMin, PlanVizConstants.zoomMax])
+    .filter(function (event) {
+      // Suppress pan/zoom when the user interacts with HTML labels
+      // (foreignObject) so text inside metrics tables remains selectable.
+      // Also ignore right-click to leave the browser context menu intact.
+      if (event.button === 2) return false;
+      var target = event.target;
+      while (target && target !== svgNode) {
+        if (target.nodeName === "foreignObject") return false;
+        target = target.parentNode;
+      }
+      return true;
+    })
+    .on("start", function () { svg.classed("grabbing", true); })
+    .on("zoom", function (event) {
+      zoomLayer.attr("transform", event.transform);
+      updateZoomLevelLabel(event.transform.k);
+    })
+    .on("end", function () { svg.classed("grabbing", false); });
+
+  svg.call(planVizZoom);
+
+  // Fit the graph to the viewport on initial render.
+  fitToViewport(svg);
+}
+
+/* Compute the transform that fits the current viewBox content into the SVG's
+ * displayed size, then apply it via d3-zoom. The SVG's viewBox already maps
+ * content to fit the displayed area (preserveAspectRatio="xMidYMid meet" by
+ * default), so the identity transform is the natural fit. */
+function fitToViewport(svgArg) {
+  var svg = svgArg || planVizContainer().select("svg");
+  if (!svg || svg.empty() || !planVizZoom) return;
+  svg.call(planVizZoom.transform, d3.zoomIdentity);
+}

Review Comment:
   Given that `d3.zoomIdentity`, what is the difference from invoking 
`updateZoomLevelLabel(1)` directly instead of `fitToViewport`?
   
   Is it for simply invoking event to update label somehow?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to