This is an automated email from the ASF dual-hosted git repository.

pierrejeambrun pushed a commit to branch v2-5-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit ea8227b385d39f936aff8cd96b5f0bc7d50347ab
Author: yuqian90 <[email protected]>
AuthorDate: Fri Mar 10 00:59:15 2023 +0800

    Fix some long known Graph View UI problems (#29971)
    
    * Center clicked node around mouse
    
    graph zoom changes
    
    Fix find zoom
    
    Remove unused args
    
    Refactor
    
    * rebase
    
    * revert redundant change
    
    * Fix unused variable
    
    * pre-commit
    
    ---------
    
    Co-authored-by: Qian Yu <[email protected]>
    (cherry picked from commit ff9cae99bf6f622066f14c33568ed929a523bdad)
---
 airflow/www/static/js/graph.js           | 59 ++++++++++++--------------------
 airflow/www/templates/airflow/graph.html |  2 +-
 airflow/www/views.py                     |  2 --
 3 files changed, 22 insertions(+), 41 deletions(-)

diff --git a/airflow/www/static/js/graph.js b/airflow/www/static/js/graph.js
index c6755a6cce..8ca4a99fc7 100644
--- a/airflow/www/static/js/graph.js
+++ b/airflow/www/static/js/graph.js
@@ -43,10 +43,8 @@ const mapTaskToNode = new Map();
 
 // Below variables are being used in dag.js
 
-const getTaskInstanceURL = 
`${taskInstancesUrl}?dag_id=${encodeURIComponent(dagId)}&execution_date=${
-  encodeURIComponent(executionDate)}`;
+const getTaskInstanceURL = 
`${taskInstancesUrl}?dag_id=${encodeURIComponent(dagId)}&execution_date=${encodeURIComponent(executionDate)}`;
 
-const duration = 500;
 const stateFocusMap = {
   success: false,
   running: false,
@@ -255,17 +253,11 @@ function setUpZoomSupport() {
   // Get Dagre Graph dimensions
   const graphWidth = g.graph().width;
   const graphHeight = g.graph().height;
-  // Get SVG dimensions
-  const padding = 80;
-  const svgBb = svg.node().getBoundingClientRect();
-  const width = svgBb.width - padding * 2;
-  const height = svgBb.height - padding; // we are not centering the dag 
vertically
+  const { width, height } = svg.node().viewBox.animVal;
+  const padding = width * 0.05;
 
   // Calculate applicable scale for zoom
-  const zoomScale = Math.min(
-    Math.min(width / graphWidth, height / graphHeight),
-    1.5, // cap zoom level to 1.5 so nodes are not too large
-  );
+  const zoomScale = Math.min(Math.min(width / graphWidth, height / 
graphHeight)) * 0.8;
 
   zoom.translate([(width / 2) - ((graphWidth * zoomScale) / 2) + padding, 
padding]);
   zoom.scale(zoomScale);
@@ -362,20 +354,7 @@ d3.select('#searchbox').on('keyup', () => {
 
   // This moves the matched node to the center of the graph area
   if (match) {
-    const transform = d3.transform(d3.select(match).attr('transform'));
-
-    const svgBb = svg.node().getBoundingClientRect();
-    transform.translate = [
-      svgBb.width / 2 - transform.translate[0],
-      svgBb.height / 2 - transform.translate[1],
-    ];
-    transform.scale = [1, 1];
-
-    if (zoom != null) {
-      zoom.translate(transform.translate);
-      zoom.scale(1);
-      zoom.event(innerSvg);
-    }
+    focusGroup(match.id, false);
   }
 });
 
@@ -441,7 +420,7 @@ function handleRefresh() {
       (tis) => {
         // only refresh if the data has changed
         if (prevTis !== tis) {
-        // eslint-disable-next-line no-global-assign
+          // eslint-disable-next-line no-global-assign
           updateNodesStates(tis);
 
           // Only redraw the graph if labels have changed
@@ -631,32 +610,36 @@ function focusedGroupKey() {
 }
 
 // Focus the graph on the expanded/collapsed node
-function focusGroup(nodeId) {
+function focusGroup(nodeId, followMouse = true) {
   if (nodeId != null && zoom != null) {
-    const { x } = g.node(nodeId);
+    const { x, y } = g.node(nodeId);
     // This is the total canvas size.
-    const { width, height } = svg.node().getBoundingClientRect();
+    const { width, height } = svg.node().viewBox.animVal;
 
     // This is the size of the node or the cluster (i.e. group)
     let rect = d3.selectAll('g.node').filter((n) => n === 
nodeId).select('rect');
     if (rect.empty()) rect = d3.selectAll('g.cluster').filter((n) => n === 
nodeId).select('rect');
 
+    const [mouseX, mouseY] = d3.mouse(svg.node());
+
     // Is there a better way to get nodeWidth and nodeHeight ?
     const [nodeWidth, nodeHeight] = [
       rect[0][0].attributes.width.value, rect[0][0].attributes.height.value,
     ];
 
     // Calculate zoom scale to fill most of the canvas with the node/cluster 
in focus.
-    const scale = Math.min(
-      Math.min(width / nodeWidth, height / nodeHeight),
-      1.5, // cap zoom level to 1.5 so nodes are not too large
-    ) * 0.9;
-
-    // deltaY of 5 keeps the zoom at the top of the view but with a slight 
margin
-    const [deltaX, deltaY] = [width / 2 - x * scale, 5];
+    const scale = Math.min(Math.min(width / nodeWidth, height / nodeHeight), 
1) * 0.2;
+
+    // Move the graph so that the node that was expanded/collapsed is centered 
around
+    // the mouse click.
+    const [toX, toY] = followMouse ? [mouseX, mouseY] : [width / 2, height / 
5];
+    const [deltaX, deltaY] = [
+      toX - x * scale,
+      toY + (nodeHeight / 2 - y) * scale,
+    ];
     zoom.translate([deltaX, deltaY]);
     zoom.scale(scale);
-    zoom.event(innerSvg.transition().duration(duration));
+    zoom.event(innerSvg);
 
     const children = new Set(g.children(nodeId));
     // Set data attr to highlight the focused group (via CSS).
diff --git a/airflow/www/templates/airflow/graph.html 
b/airflow/www/templates/airflow/graph.html
index c4e28c32fb..9d4ee6e817 100644
--- a/airflow/www/templates/airflow/graph.html
+++ b/airflow/www/templates/airflow/graph.html
@@ -121,7 +121,7 @@
   </div>
   <div class="svg-wrapper">
     <div class="graph-svg-wrap">
-      <svg id="graph-svg" width="{{ width }}" height="{{ height }}">
+      <svg id="graph-svg" viewBox="0 0 100 100">
         <g id="dig" transform="translate(20,20)"></g>
       </svg>
     </div>
diff --git a/airflow/www/views.py b/airflow/www/views.py
index 56e3a28a26..bf55a8ffba 100644
--- a/airflow/www/views.py
+++ b/airflow/www/views.py
@@ -2874,8 +2874,6 @@ class Airflow(AirflowBaseView):
             "airflow/graph.html",
             dag=dag,
             form=form,
-            width=request.args.get("width", "100%"),
-            height=request.args.get("height", "800"),
             dag_run_id=dag_run_id,
             execution_date=dttm.isoformat(),
             state_token=wwwutils.state_token(dt_nr_dr_data["dr_state"]),

Reply via email to