Skip to content

Commit

Permalink
PDF export fixes (#139)
Browse files Browse the repository at this point in the history
* bind viewport to graph

* bind viewport to graph bounds && comments

* first LOD optimizations

* minimap optimizations

* quickfix simple_draw after invisible check

* added connector LOD

* first mousehandler optimizations (only highlight when close)

* mousehandler highlighting optimization (only redraw on change)

* arrowhead LOD

* fixed connectors rendered when invisible

* fixed edges rendered even if not visible

* added loading animation for relayout tasks

* added missing loading animation for settings change

* fixed mousehandler highlighting and solved state-outline performance issues

* changed state LOD formula

* removed adaptiveHideContent option from user settings menu

* reworked user settings menu, added curved edges setting, added adaptiveStateHiding setting again with a warning

* checked all lod occurrences

* added loading animation to settings menu

* fixed pdf export issues

* added loading animation for pdf export
  • Loading branch information
LeandroTreu authored Mar 28, 2024
1 parent 8df3afc commit 7ae672e
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 57 deletions.
120 changes: 72 additions & 48 deletions src/renderer/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1454,57 +1454,81 @@ export class SDFGRenderer extends EventEmitter {
}

public save_as_pdf(save_all = false): void {
const stream = blobStream();

this.add_loading_animation();

// Compute document size
const curx = this.canvas_manager?.mapPixelToCoordsX(0);
const cury = this.canvas_manager?.mapPixelToCoordsY(0);
let size;
if (save_all) {
// Get size of entire graph
const elements: SDFGElement[] = [];
this.graph?.nodes().forEach((n_id: string) => {
const node = this.graph?.node(n_id);
if (node)
elements.push(node);
// Use setTimeout to force browser to update the DOM with the above loading animation
setTimeout(() => {

const stream = blobStream();

// Compute document size
const curx = this.canvas_manager?.mapPixelToCoordsX(0);
const cury = this.canvas_manager?.mapPixelToCoordsY(0);
let size;
if (save_all) {
// Get size of entire graph
const elements: SDFGElement[] = [];
this.graph?.nodes().forEach((n_id: string) => {
const node = this.graph?.node(n_id);
if (node)
elements.push(node);
});
const bb = boundingBox(elements);
size = [bb.width, bb.height];
} else {
// Get size of current view
const canvasw = this.canvas?.width;
const canvash = this.canvas?.height;
let endx = null;
if (canvasw)
endx = this.canvas_manager?.mapPixelToCoordsX(canvasw);
let endy = null;
if (canvash)
endy = this.canvas_manager?.mapPixelToCoordsY(canvash);
const curw = (endx ? endx : 0) - (curx ? curx : 0);
const curh = (endy ? endy : 0) - (cury ? cury : 0);
size = [curw, curh];
}

const ctx = new canvas2pdf.PdfContext(stream, {
size: size
});
const bb = boundingBox(elements);
size = [bb.width, bb.height];
} else {
// Get size of current view
const canvasw = this.canvas?.width;
const canvash = this.canvas?.height;
let endx = null;
if (canvasw)
endx = this.canvas_manager?.mapPixelToCoordsX(canvasw);
let endy = null;
if (canvash)
endy = this.canvas_manager?.mapPixelToCoordsY(canvash);
const curw = (endx ? endx : 0) - (curx ? curx : 0);
const curh = (endy ? endy : 0) - (cury ? cury : 0);
size = [curw, curh];
}
//

const ctx = new canvas2pdf.PdfContext(stream, {
size: size
});
const oldctx = this.ctx;
this.ctx = ctx;
(this.ctx as any).lod = !save_all;
(this.ctx as any).pdf = true;
// Center on saved region
if (!save_all)
this.ctx?.translate(-(curx ? curx : 0), -(cury ? cury : 0));

this.draw_async();

ctx.stream.on('finish', () => {
const name = this.sdfg.attributes.name;
this.save(name + '.pdf', ctx.stream.toBlobURL('application/pdf'));
this.ctx = oldctx;
const oldctx = this.ctx;
this.ctx = ctx;

// Necessary for "what you see is what you get" in the exported pdf file
if (!save_all && (oldctx as any).lod) {
// User wants to save the view "as is" with details hidden
(this.ctx as any).lod = true;
}
else {
// User wants to save all details in the view
(this.ctx as any).lod = false;
}
(this.ctx as any).pdf = true;
// Center on saved region
if (!save_all)
this.ctx?.translate(-(curx ? curx : 0), -(cury ? cury : 0));

this.draw_async();
});

ctx.stream.on('finish', () => {
const name = this.sdfg.attributes.name;
this.save(name + '.pdf', ctx.stream.toBlobURL('application/pdf'));
this.ctx = oldctx;
this.draw_async();
// Remove loading animation
const info_field = document.getElementById('task-info-field');
if (info_field) {
info_field.innerHTML = "";
}
const info_field_settings = document.getElementById('task-info-field-settings');
if (info_field_settings) {
info_field_settings.innerHTML = "";
}
});
}, 10);
}

// Draw a debug grid on the canvas to indicate coordinates.
Expand Down
26 changes: 17 additions & 9 deletions src/renderer/renderer_elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1375,14 +1375,21 @@ export class InterstateEdge extends Edge {
const labelWs = [];
for (const l of labelLines) {
const labelMetrics = ctx.measureText(l);
labelWs.push(
Math.abs(labelMetrics.actualBoundingBoxLeft) +
Math.abs(labelMetrics.actualBoundingBoxRight)
);
labelHs.push(
Math.abs(labelMetrics.actualBoundingBoxDescent) +
Math.abs(labelMetrics.actualBoundingBoxAscent)
);

let label_width = Math.abs(labelMetrics.actualBoundingBoxLeft) +
Math.abs(labelMetrics.actualBoundingBoxRight);
let label_height = Math.abs(labelMetrics.actualBoundingBoxDescent) +
Math.abs(labelMetrics.actualBoundingBoxAscent);

// In case of canvas2pdf context, that only has width and height
// as TextMetrics properties
if (label_width != label_width)
label_width = (labelMetrics as any).width;
if (label_height != label_height)
label_height = (labelMetrics as any).height;

labelWs.push(label_width);
labelHs.push(label_height);
}
const labelW = Math.max(...labelWs);
const labelH = labelHs.reduce((pv, cv) => {
Expand Down Expand Up @@ -1448,12 +1455,13 @@ export class InterstateEdge extends Edge {
ctx.fillStyle = this.getCssProperty(
renderer, '--interstate-edge-color'
);
for (let i = 0; i < labelLines.length; i++)
for (let i = 0; i < labelLines.length; i++) {
ctx.fillText(
labelLines[i],
srcP.x + offsetX,
(srcP.y + offsetY) - (i * (labelHs[0] + SDFV.LINEHEIGHT))
);
}
ctx.font = oldFont;
}

Expand Down

0 comments on commit 7ae672e

Please sign in to comment.