Export Flows to image

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 :slight_smile:

1 Like

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.

1 Like

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 :wink:

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

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

Perhaps you could try a screenshot node, not sure how it deals with logins.

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

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

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

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

1 Like

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

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

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:

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

@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.

Ah, i was wrong about the library I was using -- it was this one: 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:

    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.

2 Likes

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:

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

2 Likes

@shrickus thank you very much! Wow, you really did a lot! :slight_smile: :wink: :slight_smile:

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...

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.