# Export Flows to image

**URL:** https://discourse.nodered.org/t/export-flows-to-image/40195
**Category:** General
**Created:** [1 February 2021 20:27 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195 "2021-02-01T20:27:49Z")
**Posts on this page:** 16
**Page:** 1

<div class="post-metadata">

### Author: ![crackytsi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/crackytsi/32/28369_2.png) [@crackytsi](https://discourse.nodered.org/u/crackytsi)
#### Post date: [1 February 2021 20:27 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/1 "2021-02-01T20:27:49Z")

</div>

Hi!  
Is there a way to export a flow to a graphic? E.g. to PNG file or Graphviz dot file?  
I want to create some automated documentation, where i'm trying to find an export solution. Sharing the exportable json is not really easy to understand, so i try to find something better...

Thanks 🙂

---

<div class="post-metadata">

### Author: ![ncherry](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ncherry/32/27_2.png) [@ncherry](https://discourse.nodered.org/u/ncherry)
#### Post date: [2 February 2021 01:15 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/2 "2021-02-02T01:15:07Z")

</div>

Not trying to be flippant but wouldn't that be a screen shot?

I do realize that this doesn't work well for a very crowded flow.

---

<div class="post-metadata">

### Author: ![crackytsi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/crackytsi/32/28369_2.png) [@crackytsi](https://discourse.nodered.org/u/crackytsi)
#### Post date: [2 February 2021 08:21 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/3 "2021-02-02T08:21:20Z")

</div>

Thanks ncherry.  
Actually thats my current way of working, but thats not so nice, as I have too small screenshots or I have to combine multiple screenshots to a complete picture...  
I hoped that there is someone having a better solution 😉

---

<div class="post-metadata">

### Author: ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)
#### Post date: [2 February 2021 08:33 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/4 "2021-02-02T08:33:46Z")

</div>

What do you have in mind for "automated documentation ?"

---

<div class="post-metadata">

### Author: ![crackytsi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/crackytsi/32/28369_2.png) [@crackytsi](https://discourse.nodered.org/u/crackytsi)
#### Post date: [2 February 2021 09:02 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/5 "2021-02-02T09:02:01Z")

</div>

To include the drawing of the latest flow as image into the documentation.

---

<div class="post-metadata">

### Author: ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)
#### Post date: [2 February 2021 09:54 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/6 "2021-02-02T09:54:23Z")

</div>

Perhaps you could try a [screenshot node](https://flows.nodered.org/node/node-red-contrib-web-page-screenshot), not sure how it deals with logins.

---

<div class="post-metadata">

### Author: ![ncherry](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ncherry/32/27_2.png) [@ncherry](https://discourse.nodered.org/u/ncherry)
#### Post date: [3 February 2021 03:08 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/7 "2021-02-03T03:08:17Z")

</div>

I missed the obvious reference to automated. I'm hoping for a good idea also. 🙂

---

<div class="post-metadata">

### Author: ![crackytsi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/crackytsi/32/28369_2.png) [@crackytsi](https://discourse.nodered.org/u/crackytsi)
#### Post date: [3 February 2021 06:16 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/8 "2021-02-03T06:16:34Z")

</div>

> [@ncherry](#):
>
> sed the obvious reference to automated. I'm hoping for a good

Unfortunately I'm not a javascript developer, but it seems that there could be an option to use the toDataURL function on canvas:

```auto
document.getElementById("canvas").toDataURL("image/png")

```

Unfortunately I have no idear how to embed that into Node-Red or call that using developer console.

---

<div class="post-metadata">

### Author: ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)
#### Post date: [3 February 2021 16:06 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/9 "2021-02-03T16:06:25Z")

</div>

Don’t know if this will help, but a quick google search found this

> <https://stackoverflow.com/questions/10673122/how-to-save-canvas-as-an-image-with-canvas-todataurl>

And I notice you don’t have `image/octet-stream` in your code

---

<div class="post-metadata">

### Author: ![shrickus](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/shrickus/32/517_2.png) [@shrickus](https://discourse.nodered.org/u/shrickus)
#### Post date: [3 February 2021 18:10 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/10 "2021-02-03T18:10:59Z")

</div>

I spent several days working on this exact feature last year... with some success. I managed to add a button to the editor that exported the canvas to a PNG image, suitable for hi-res printing or pasting into a slide show. I'd be happy to send you my code, although it's not finished.

The main issue is dealing with Fonts -- the Javascript library I was using (pdfjs, iirc) did not handle the CSS styling that is used to render the text inside the nodes. So although the image and fonts _looked_ good, it did not match what was on the screen exactly:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/5/f5f1dd8a1791b711f78fb7a28a361fc42ff68665.png)

Better yet, I'd be happy to contrib this feature back into the core development, if Nick and Dave are interested... but with my current workload, it will take me a while to get it ready to submit.

-- Steve

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [3 February 2021 18:20 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/11 "2021-02-03T18:20:56Z")

</div>

@shrickus I got to a similar point when I tried this a while ago. Although I seem to have mislaid the code for that - probably sat in a branch on my old laptop.

The main issue was, as you've seen, the font handling - particularly with Font-Awesome icons for some nodes.

If you wanted to share a link to whatever code you have that would be helpful. It certainly doesn't need to be a ready-to-merge PR as I'm not sure how we'd want to integrate it at the moment.

---

<div class="post-metadata">

### Author: ![shrickus](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/shrickus/32/517_2.png) [@shrickus](https://discourse.nodered.org/u/shrickus)
#### Post date: [3 February 2021 18:43 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/12 "2021-02-03T18:43:56Z")

</div>

Ah, i was wrong about the library I was using -- it was this one: [save-svg-as-png](https://www.npmjs.com/package/save-svg-as-png)

I see now they have support for a list of fonts, so quite possibly that would be enough to fix my old code. Unfortunately, the work was done against an old v1.9.x version of node-red -- but here is the function I added to editor/js/view.js in order to invoke the library:

```auto
    function savePng() {
        var editor = document.querySelector("#workspace #chart");
        // get the bounds of the visible area, inside the scroll bars
        var bounds = { height: editor.clientHeight, width: editor.clientWidth };
        //var bounds = editor.getBoundingClientRect();
        var topsvg = editor.querySelector("svg");
        // temporarily hide the grid, if shown
        var gridon = grid.style("visibility") === "visible";
        if (gridon) {
            toggleShowGrid(false);
        }

        var active = RED.workspaces.active();
        var acttab = RED.nodes.workspace(active);
        var pngwin = window.open('', 'svgpng', "height=" + bounds.height + ",width=" + bounds.width + ",titlebar=no,location=no,resizable,menubar,tabbar,dialog");

        svgAsPngUri(topsvg, {
            height: bounds.height,
            width: bounds.width,
            scale: 1 / scaleFactor
        },
        function(pnguri) {
            pngwin.document.head.innerHTML = "<title>" + acttab.label + "</title>";
            pngwin.document.body.style = "margin: 0;";
            pngwin.document.body.innerHTML = "<img src='" + pnguri + "'/>";
            // redisplay the grid, if shown
            if (gridon) {
                toggleShowGrid(true);
            }
        });
    }

```

The window that is opened (see the image in my previous post) shows only the "visible" part of the editor canvas (i.e. you have to zoom into the section to be converted), not the entire 5000px wide editor canvas. But the image can them be copied to the clipboard, saved as a file, or sent directly to the printer from the popup browser window.

---

<div class="post-metadata">

### Author: ![shrickus](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/shrickus/32/517_2.png) [@shrickus](https://discourse.nodered.org/u/shrickus)
#### Post date: [3 February 2021 18:51 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/13 "2021-02-03T18:51:41Z")

</div>

Incidentally, I chose to implement this feature as a new button next to the canvas zoom buttons shown at the bottom right of the editor window:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/1/c/1c18f704bee4b0ac746c6c11e959ccc1c815185e.png)

So the `savePng` event was triggered by clicking on the `fa-image` button shown in the lower left of this screenshot... fwiw. Cheers!

---

<div class="post-metadata">

### Author: ![crackytsi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/crackytsi/32/28369_2.png) [@crackytsi](https://discourse.nodered.org/u/crackytsi)
#### Post date: [4 February 2021 15:28 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/14 "2021-02-04T15:28:36Z")

</div>

@shrickus thank you very much! Wow, you really did a lot! 🙂 😉 🙂

Do you also have the code, you wrote to add button?  
How did you make nodered loading thr library save-svg-as-png?  
Sorry for my basic questions, but i'm not very experienced writing nodejs or javascript code...

---

<div class="post-metadata">

### Author: ![shrickus](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/shrickus/32/517_2.png) [@shrickus](https://discourse.nodered.org/u/shrickus)
#### Post date: [9 February 2021 12:53 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/15 "2021-02-09T12:53:50Z")

</div>

These changes were made directly to an old (v0.19.x) copy of the editor's ui/view.js file -- enhancements like this require a good bit of Javascript and git experience... but the process for pulling down the node-red codebase from the repo, making local changes, compiling and running the new version are described [here](https://nodered.org/about/contribute/).

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [10 April 2021 12:54 UTC](https://discourse.nodered.org/t/export-flows-to-image/40195/16 "2021-04-10T12:54:29Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
