Skip to content

Commit

Permalink
Fix Downloading Large Graphs (#733)
Browse files Browse the repository at this point in the history
  • Loading branch information
rob-gordon authored Sep 10, 2024
1 parent cc015e4 commit e22b40a
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 18 deletions.
28 changes: 16 additions & 12 deletions app/src/components/DownloadDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,22 @@ export function DownloadDropdown({ children }: { children: React.ReactNode }) {
const svg = await getSvg({ cy: window.__cy });
downloadSvg({ svg, filename });
} else {
const { canvas } = await getCanvas({
cy: window.__cy,
type: format as "png" | "jpg",
watermark,
scale,
});
downloadCanvas({
canvas,
filename,
type: format as "png" | "jpg",
cleanup: () => {},
});
try {
const { canvas } = await getCanvas({
cy: window.__cy,
type: format as "png" | "jpg",
watermark,
scale,
});
downloadCanvas({
canvas,
filename,
type: format as "png" | "jpg",
cleanup: () => {},
});
} catch (err) {
console.error(`Failed to download ${format}:`, err);
}
}
};

Expand Down
41 changes: 35 additions & 6 deletions app/src/components/downloads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import { getBackground } from "../lib/toTheme";
// padding, gets divided in half
const PADDING = 60;

const MAX_ATTEMPTS = 8;
const SCALE_REDUCTION_FACTOR = 0.75;
const CANVAS_SIZE_ERROR = "`canvas.toBlob()` sent a null value in its callback";

/**
* Returns the SVG code for the current graph
*/
Expand Down Expand Up @@ -136,12 +140,36 @@ export async function getCanvas({
cleanup: () => void;
}> {
const bg = getBackground();
const blob = await cy[type]({
full: true,
scale,
output: "blob-promise",
bg,
});
let blob: Blob | null = null;
let currentScale = scale;
let attempts = 0;

// Try to create the blob, reducing scale if necessary
while (attempts < MAX_ATTEMPTS) {
try {
blob = await cy[type]({
full: true,
scale: currentScale,
output: "blob-promise",
bg,
});
break; // Success, exit the loop
} catch (error) {
if (error instanceof Error && error.message.includes(CANVAS_SIZE_ERROR)) {
attempts++;
currentScale *= SCALE_REDUCTION_FACTOR;
console.warn(
`Canvas size too large. Reducing scale to ${currentScale}`
);
} else {
throw error; // Rethrow if it's not the expected error
}
}
}

if (!blob) {
throw new Error("Failed to create canvas after maximum attempts");
}

// Get width and height of flowchart
const { w, h } = await new Promise<{ w: number; h: number }>((resolve) => {
Expand Down Expand Up @@ -227,6 +255,7 @@ export function downloadCanvas({
}: {
filename: string;
} & Awaited<ReturnType<typeof getCanvas>>) {
console.log("downloadCanvas", canvas, type, filename);
const mime = type === "png" ? "image/png" : "image/jpeg";
saveAs(canvas.toDataURL(mime), `${filename}.${type}`);
cleanup();
Expand Down

0 comments on commit e22b40a

Please sign in to comment.