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

kaxilnaik pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 5cfba2bbaba0975cac680e0f485109f0a412a776
Author: shreyaskj-0710 <[email protected]>
AuthorDate: Tue Sep 9 23:14:56 2025 +0530

    Fix graph export cropping when view is partial (#55012)
    
    * Fix graph export cropping when view is partial
    
    * Refine graph export fix by applying fitView with delay only
    
    * Fix static check issues
---
 .../airflow/ui/src/components/Graph/DownloadButton.tsx    | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git 
a/airflow-core/src/airflow/ui/src/components/Graph/DownloadButton.tsx 
b/airflow-core/src/airflow/ui/src/components/Graph/DownloadButton.tsx
index e1ff71d0add..5455cecd305 100644
--- a/airflow-core/src/airflow/ui/src/components/Graph/DownloadButton.tsx
+++ b/airflow-core/src/airflow/ui/src/components/Graph/DownloadButton.tsx
@@ -17,7 +17,7 @@
  * under the License.
  */
 import { IconButton } from "@chakra-ui/react";
-import { Panel, useReactFlow, getNodesBounds, getViewportForBounds } from 
"@xyflow/react";
+import { Panel, useReactFlow } from "@xyflow/react";
 import { toPng } from "html-to-image";
 import { useTranslation } from "react-i18next";
 import { FiDownload } from "react-icons/fi";
@@ -26,24 +26,23 @@ import { toaster } from "src/components/ui";
 
 export const DownloadButton = ({ name }: { readonly name: string }) => {
   const { t: translate } = useTranslation("components");
-  const { getNodes, getZoom } = useReactFlow();
 
-  const onClick = () => {
-    const nodesBounds = getNodesBounds(getNodes());
+  const { fitView } = useReactFlow();
+
+  const onClick = async () => {
+    // Ensure the graph fits before taking screenshot
+    await fitView({ duration: 0, padding: 0.1 });
 
     // Method obtained from https://reactflow.dev/examples/misc/download-image
     const container = document.querySelector(".react-flow__viewport");
 
     if (container instanceof HTMLElement) {
       const dimensions = { height: container.clientHeight, width: 
container.clientWidth };
-      const zoom = getZoom();
-      const viewport = getViewportForBounds(nodesBounds, dimensions.width, 
dimensions.height, zoom, zoom, 2);
 
       toPng(container, {
         height: dimensions.height,
         style: {
           height: `${dimensions.height}px`,
-          transform: `translate(${viewport.x}px, ${viewport.y}px) 
scale(${viewport.zoom})`,
           width: `${dimensions.width}px`,
         },
         width: dimensions.width,
@@ -69,7 +68,7 @@ export const DownloadButton = ({ name }: { readonly name: 
string }) => {
     <Panel position="bottom-right" style={{ transform: "translateY(-150px)" }}>
       <IconButton
         aria-label={translate("graph.downloadImage")}
-        onClick={onClick}
+        onClick={() => void onClick()}
         size="xs"
         title={translate("graph.downloadImage")}
         variant="ghost"

Reply via email to