# Standalone Flow Viewer Plugin

**URL:** <https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388>\
**Category:** General\
**Created:** [24 June 2023 10:58 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388 "2023-06-24T10:58:50Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [30 June 2023 10:45 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/41 "2023-06-30T10:45:46Z")

</div>

Another [update](https://blog.openmindmap.org/blog/backticks-in-markdown-and-node-red) this now has grid lines, rectangles as output, triangles as input and better naming of nodes (added some logic for better label texts). Also centred the text for nodes that become higher with multiple outputs.

 ![Screen Shot 2023-06-30 at 12.41.27](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/0/f/0f563832017661516e1cbe442257f3d436264a93.png)

Of course what would now be nice would be a formatted json view and a _download json for image_ button, so that one could actually retrieve the json.

---

<div class="post-metadata">

**Author:** ![rko](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rko/32/45807_2.png) [@rko](https://discourse.nodered.org/u/rko)\
**Post date:** [30 June 2023 12:47 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/42 "2023-06-30T12:47:18Z")

</div>

> [@gregorius](#):
>
> Misleading is perhaps too much since the triangles only show the flow of data. It's a clarification of a feature. It might be confusing but so is having just rectangles.

Maybe just let the user decide and make this optional. You could then have a "standard flow viewer", which aims to be an exact copy of the Node-RED editor view and an "advanced flow viewer", with new fancy stuff.

You did an amazing job and I really want to play with this. Our goal is to integrate the viewer in our cloud system. No more importing into Node-RED to see what this bloody flow does 😃

---

<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:** [30 June 2023 12:56 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/43 "2023-06-30T12:56:49Z")

</div>

Hi @gregorius

This is certainly something we've long wanted to do - a lot of my personal inertia on it has been due the issues around getting the colours/labels/icons right.

Are you at all interested in contributing this back into the node-red org on github where we can develop it into a properly reusable component? I know you'd expressed some reservations on doing that yourself earlier in the thread.

We'd want to make sure the appearance is consistent with Node-RED by default - so things like the arrow heads (a topic often discussed and even prototyped but never quite got over the line), could be an option that you can enable, but would be off by default.

Let me know what you think.

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [30 June 2023 13:10 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/44 "2023-06-30T13:10:05Z")

</div>

> [@rko](#):
>
> Maybe just let the user decide and make this optional. You could then have a "standard flow viewer", which aims to be an exact copy of the Node-RED editor view and an "advanced flow viewer", with new fancy stuff.

I've been playing around with the language specification in the code fencing block (i.e. the backticks) and unfortunately there isn't a standard way of passing options to plugins, e.g.

````auto
```nodredjson?option1=true,option2=false
<long json here>
```

````

doesn't work. Basically what happens is that the code block is assigned the class `language-nodredjson?option1=true,option2=false`, e.g.:

```auto
<pre><code class='nodredjson?option1=true,option2=false'>....

```

The jQuery selector I use is `$('.language-noderedjson')` so that would break. Using spaces causes everything after the language to be ignored... markdown was never designed for this 😉

So making that happen would be globally, i.e., when including the javascript into the page.

> [@rko](#):
>
> You did an amazing job and I really want to play with this.

Thank you, much appreciate 🙂 Please do play around with it and tell me how it goes!

---

<div class="post-metadata">

**Author:** ![rko](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rko/32/45807_2.png) [@rko](https://discourse.nodered.org/u/rko)\
**Post date:** [30 June 2023 13:30 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/45 "2023-06-30T13:30:45Z")

</div>

You can define languages right? So, default is `noderedjson` and then you have others like `advancednoderedjsonthingy`. Would that work?

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [30 June 2023 13:31 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/46 "2023-06-30T13:31:17Z")

</div>

> [@knolleary](#):
>
> Are you at all interested in contributing this back into the node-red org on github where we can develop it into a properly reusable component? I know you'd expressed some reservations on doing that yourself earlier in the thread.

I'd be most happy with having it included within Node-RED, after all that's where it should be!

I have reservations on making it into a mini-editor window, i.e., making it _too_ interactive. But that's just my thinking that I'd prefer to keep it simple so that people who have no experience with Node-RED can get an appreciation for Node-RED. My target audience is exactly those that are interested but have no experience with Node-RED, hence I would like it to be as clear and understandable as possible.

The arrow heads was an idea to facilitate understanding and clarity - as I said, a static image isn't an editor so that makes it difficult to transport knowledge. (json = one long word, image = one thousand words, an editor = ten thousand words!).

But I know that the Node-RED team definitely has an eye for UI, so I am sure that there will a great solution to make everyone happy 👍

> [@knolleary](#):
>
> We'd want to make sure the appearance is consistent with Node-RED by default - so things like the arrow heads (a topic often discussed and even prototyped but never quite got over the line), could be an option that you can enable, but would be off by default.

I've definitely cut corners (e.g. no slightly-thicker-white line under the grey line!) and explicitly didn't make an _exact_ copy since I wanted to have a prototype before spending that 80% of my time doing the final 20% of the job!

My goal is to bring Node-RED to broader audience and not to build the ultimate flow viewer 🙂

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [30 June 2023 13:34 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/47 "2023-06-30T13:34:12Z")

</div>

> [@rko](#):
>
> You can define languages right? So, default is `noderedjson` and then you have others like `advancednoderedjsonthingy`. Would that work?

doh - of course ... sometimes one doesn't see the trees because the forest is in the way.

Sounds like a plan! 👍

---

<div class="post-metadata">

**Author:** ![rko](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rko/32/45807_2.png) [@rko](https://discourse.nodered.org/u/rko)\
**Post date:** [30 June 2023 13:35 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/48 "2023-06-30T13:35:52Z")

</div>

~~Well, it's not "options" but maybe it's a start.~~ Or is it?

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [30 June 2023 13:39 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/49 "2023-06-30T13:39:22Z")

</div>

> [@rko](#):
>
> Well, it's not "options" but maybe it's a start.

Heck nothing wrong with that, sounds cool to me:

- `noderedjson-with-zoom`
- `noderedjson-interactive`
- `noderedjson-image-only`
- `noderedjson-with-sliced-bread`

I would use a prefix with options attached, prevents confusion!

---

<div class="post-metadata">

**Author:** ![rko](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rko/32/45807_2.png) [@rko](https://discourse.nodered.org/u/rko)\
**Post date:** [30 June 2023 14:35 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/50 "2023-06-30T14:35:08Z")

</div>

Sorry, haven't used `markdown` that way before. What else do I need to include to make it work?

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/7/872b2e31f80222830229d7be18cb1a1d6e9d2ddb.png)

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [30 June 2023 14:46 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/51 "2023-06-30T14:46:48Z")

</div>

> [@rko](#):
>
> Sorry, haven't used `markdown` that way before. What else do I need to include to make it work?

Hm, nothing - just the js & css includes and at the bottom of the page the script snippet ...

If you're not using markdown, then you need a `code` block with class `language-noderedjson`.

it basically goes looking for `$('code.language-noderedjson');` and replaces those elems.

What I do is generate markdown in Node-RED, then use the markdown node to get html and then I push that html [into a html template](https://demo.openmindmap.org/omm/#flow/1f980ab215b3d38b/n/2b36b7ed187aaf0a/edit).

So I have a specific setup whereby I generate markdown that goes into a html template and I control the entire pipeline ...

UPDATE: Mea Culpa!

the jquery src is wrong, it should be [https://blog.openmindmap.org/content/jquer](https://blog.openmindmap.org/content/jquer)...... it's a relative url in your screenshot - I've updated the page with the details to have the correct url

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [30 June 2023 14:52 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/52 "2023-06-30T14:52:21Z")

</div>

This is a pure html usage - [Flow Embeddation](https://blog.openmindmap.org/blog/embedded-flow-v10.html) it basically does this:

```auto
    <script src="https://blog.openmindmap.org/content/jquery-3.7.0.min.js" integrity="sha512-3gJwYpMe3QewGELv8k/BX9vcqhryRdzRMxVfq6ngyWXwo03GFEzjsUm8Q7RZcHPHksttq7/GFoxjCVUjkjvPdw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://blog.openmindmap.org/embed/flowviewer.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <link rel="stylesheet" href="https://blog.openmindmap.org/embed/flowviewer.css">

```

```auto
<body>
    <div id='svgcontainer' 
        style="transform: scale(0.5,0.5) translate(-2500px,-2500px) ; top: 50px; left: 10px; position: absolute; overflow: scroll; display: block;">
      <svg id="svgelem" width="5000" height="5000" viewBox="0 0 5000 5000" pointer-events="all" style="cursor: crosshair;" version="1.1" xmlns="http://www.w3.org/2000/svg">
        <!-- Use group elems to ensure that layering of shapes is correct, i.e. nodes always over links -->
        <g class='flowGridlines'></g>
        <g class='flowGroups'></g>
        <g class='flowWires'></g>
        <g class='flowNodes'></g>
      </svg>
    </div>
  </body>

```

and then js code:

```auto
    var flowId = "3b1289d7ccf9cb0f";

    $(function(){
      $.ajax({
        dataType: "json",
        url: "https://demo.openmindmap.org/omm/flows",
        method: 'get',
        success: function(flowdata) { 
          renderFlow(flowId, flowdata, $($('#svgelem')[0]));
        }
      });
    });
  </script>

```

`flowdata` is just the json that you get out of Node-RED export.

---

<div class="post-metadata">

**Author:** ![rko](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rko/32/45807_2.png) [@rko](https://discourse.nodered.org/u/rko)\
**Post date:** [30 June 2023 16:16 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/53 "2023-06-30T16:16:53Z")

</div>

Thanks!

Here's a `hello world` for those who want to try:

```auto
<html>

	<head>
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js" integrity="sha512-3gJwYpMe3QewGELv8k/BX9vcqhryRdzRMxVfq6ngyWXwo03GFEzjsUm8Q7RZcHPHksttq7/GFoxjCVUjkjvPdw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
		<script src="https://blog.openmindmap.org/embed/flowviewer.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
		<link rel="stylesheet" href="https://blog.openmindmap.org/embed/flowviewer.css">
	</head>

	<body>
	    <div id='svgcontainer' 
	        style="transform: scale(0.5,0.5) translate(-2500px,-2500px) ; top: 50px; left: 10px; position: absolute; overflow: scroll; display: block;">
	      <svg id="svgelem" width="5000" height="5000" viewBox="0 0 2000 2000" pointer-events="all" style="cursor: crosshair;" version="1.1" xmlns="http://www.w3.org/2000/svg">
	        <!-- Use group elems to ensure that layering of shapes is correct, i.e. nodes always over links -->
	        <g class='flowGridlines'></g>
	        <g class='flowGroups'></g>
	        <g class='flowWires'></g>
	        <g class='flowNodes'></g>
	      </svg>
	    </div>

		<script>

			let flowdata = [{"id":"185c2139f08e26a0","type":"tab","label":"Flow 3","disabled":false,"info":"","env":[]},{"id":"be54112eddcd9446","type":"inject","z":"185c2139f08e26a0","name":"hello","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"hello","payloadType":"str","x":90,"y":80,"wires":[["30ae335f5be8183b"]]},{"id":"30ae335f5be8183b","type":"debug","z":"185c2139f08e26a0","name":"world","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":270,"y":80,"wires":[]}];
			let flowId = flowdata[0].id;

			renderFlow(flowId, flowdata, $($('#svgelem')[0]));
		</script>

	</body>

</html>

```

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [30 June 2023 16:50 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/54 "2023-06-30T16:50:16Z")

</div>

> [@rko](#):
>
> `<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js" integ`

thanks for taking google for the jquery stuff 🙂

> [@rko](#):
>
> ```auto
> <script src="https://blog.openmindmap.org/embed/helpers-v7.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
> <link rel="stylesheet" href="https://blog.openmindmap.org/embed/helpers.css">
> 
> ```

better to use [https://blog.openmindmap.org/embed/flowviewer.js](https://blog.openmindmap.org/embed/flowviewer.js) and [https://blog.openmindmap.org/embed/flowviewer.css](https://blog.openmindmap.org/embed/flowviewer.css) there, the helpers thing is liable to disappear....

I've updated the example page with new languages, so now the `noderedjson` does as near as possible the default editor view, ie., rectangles + gridlines. `noderedjson-with-arrows` does input triangles but rectangles for outputs, `noderedjson-no-gridlines` removes the gridlines and `noderedjson-no-gridlines-with-arrows` needs not explanation.

But on that page I use `noderedjson-with-arrows` - after all, I like triangles! 🙂

> **[Replacing Node-RED flow codeblocks with flow images. | Open Mind Map Blog](https://blog.openmindmap.org/blog/backticks-in-markdown-and-node-red)**
>
> Codeblocks are one thing but images are further a thousand Json files. Show me your flow!

---

<div class="post-metadata">

**Author:** ![rko](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rko/32/45807_2.png) [@rko](https://discourse.nodered.org/u/rko)\
**Post date:** [30 June 2023 22:31 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/55 "2023-06-30T22:31:14Z")

</div>

Thanks, I changed the example. Maybe you'll publish a `hello world` here or on your page? Then I can delete the sloppy one up there 😜

How can I get the default Node-RED view btw?

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [1 July 2023 07:37 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/56 "2023-07-01T07:37:28Z")

</div>

> [@rko](#):
>
> How can I get the default Node-RED view btw?

if you're using the `-v7.` js and css files then you can't, need to be using the `flowviewer.`js and css. Then its the default `noderedjson` language that is as close as possible to the editor.

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [1 July 2023 07:55 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/57 "2023-07-01T07:55:21Z")

</div>

> [@rko](#):
>
> Thanks, I changed the example. Maybe you'll publish a `hello world` here or on your page?

Done - [https://blog.openmindmap.org/embed/example.html](https://blog.openmindmap.org/embed/example.html) that's the hello world page in action, source code is over [here](https://blog.openmindmap.org/blog/backticks-in-markdown-and-node-red#source-html).

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [2 July 2023 13:07 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/58 "2023-07-02T13:07:24Z")

</div>

Another [update](https://blog.openmindmap.org/blog/backticks-in-markdown-and-node-red#rendering-options) with better handling of rendering options: order is no longer a requirement, i.e. `noderedjson-with-arrows-no-gridlines` is the same as `noderedjson-no-gridlines-with-arrows`.

There is new option `with-zoom` which makes the image zoomable and pannable. Your mileage might vary on mobile but a double-click resets the image back to the original settings. Options are mix and matchable.

---

<div class="post-metadata">

**Author:** ![rko](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rko/32/45807_2.png) [@rko](https://discourse.nodered.org/u/rko)\
**Post date:** [3 July 2023 09:01 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/59 "2023-07-03T09:01:14Z")

</div>

Btw, this forum would be a candidate for the viewer too 🤓

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [5 July 2023 07:02 UTC](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388/60 "2023-07-05T07:02:19Z")

</div>

> [@rko](#):
>
> would be a candidate for the viewer too

That thought never, ever, not-even-once, really-never crossed my mind 😉

Btw2: Here is another thought I might (or might not) have had: a [diff viewer](https://blog.openmindmap.org/blog/diffviewer-v1.html) - obviously a very contrived example. Use the slider to blend between two versions of the same flow. Obviously this won't help with function nodes or anything that had content changes but visual changes can easily be identified.

[Previous page](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388.md?page=2)

[Next page](https://discourse.nodered.org/t/standalone-flow-viewer-plugin/79388.md?page=4)
