# Node-RED auto layouting using elkjs & dagre

**URL:** <https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052>\
**Category:** General\
**Created:** [5 September 2023 11:24 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052 "2023-09-05T11:24:52Z")\
**Posts on this page:** 19\
**Page:** 1

<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 September 2023 11:24 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/1 "2023-09-05T11:24:53Z")

</div>

Hi There!

Following up on a [long discussion](https://discourse.nodered.org/t/noisecraft-anyone-heard-of-it/79813/41) and a [previous discussion](https://discourse.nodered.org/t/read-flows-json-and-position-the-nodes-in-most-efficient-readable-way/78158) and also the [pull request](https://github.com/node-red/node-red/pull/2267), I've come up with a flow that demonstrates various approaches to auto layout. To use the flow, you must install the [introspection](https://flows.nodered.org/node/@gregoriusrippenstein/node-red-contrib-introspection) package which includes the ClientCode node.

I would have included the flow here directly but it's too large for discourse (see screenshot)

The flow is hosted at [flowhub](https://flowhub.org/f/291e3f0b7f652839) and if you install the [flowhub nodes](https://flows.nodered.org/node/@gregoriusrippenstein/node-red-contrib-flowhub), you can pull the flow directly into Node-RED, flowid being: 291e3f0b7f652839

These layout engines (elkjs and dagre) can be used with any flow you happen to wish to layout, you can play with the layout algorithms and even use other engines. The whole thing works within Node-RED client, i.e. browser.

Cheers!

Thanks to @BartButenaers, the visuals:  
 ![example](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/1/e/1eec174b0f5678cd71fe636e206f01dc515bfd4a.gif)

 ![Screen Shot 2023-09-05 at 13.16.29](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/f/3f9f6578b89575a492b528c102dcfed4bea33a5a.png)

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [5 September 2023 20:50 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/2 "2023-09-05T20:50:23Z")

</div>

Hi @gregorius,

Unfortunately I don't get it running. I think I have replaced all the escaped html characters by their original symbols, but there are quite a lot (in conditions, lambda expressions, ...). So most probably I fixed one of these incorrectly...

A couple of questions about your demo with the 2 layout engines (elkjs and dagre). Not sure if I ask them too soon, because you had not much time yet to experiment with this...

1. Are these the 2 best layout engines for Node-RED (for some reason), or is there perhaps another reason why you choose those two (e.g. because they are the most easy to embed)?

2. Are you going to explore other engines, or are these good enough?

3. Is there already one of the two that you like most for some reason?

4. Do you think one of those engines is good enough to be used in real life?

5. So these engines offer lots and lots of options. I assume most of these can have default values that will do for all/most users, and that only some of them are useful to be customizable by users. Do you already have a subset in your mind, that might be useful?

6. Are you already aware of some severe limitations, that makes it hard to build a general usable solution?

7. Do you have plans to integrate this (e.g. using a plugin) into the editor in the near future, or are you just having an immense amount of fun with your lovely experiments? 😋

Thanks for sharing your knowledge and endless creativity with us!!

Bart

---

<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 September 2023 22:14 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/3 "2023-09-05T22:14:58Z")

</div>

Ay, that there be many questions! As proviso I have to say that is this is very much an experiment, it's a side track of other things I'm doing, so no, I'm not going to push this to become part of Node-RED - that's for others to decide. I'm happy to help where I can, if others want to run with these ideas, all the better!

> [@BartButenaers](#):
>
> - Are these the 2 best layout engines for Node-RED (for some reason), or is there perhaps another reason why you choose those two (e.g. because they are the most easy to embed)?

The only reason was that a) dagre there was example code from @lizzardguki and b) elkjs was the simplest to implement from the list from @TotallyInformation (it wasn't react related and seems to be stable and in usage). My main intention is for others to say "hey, I've got experience with engine XYZ and here's a flow that shows me how to integrate it and test it in Node-RED - let me try!". I built the flow to be extendable: extracting the including of a javascript lib, extracting the moving of the nodes (provided the right array of nodes is passed over) and I extracted the selection of the nodes which should be laid out.

All that was together in one client code node in the [original flow](https://flowhub.org/f/291e3f0b7f652839?v2=42a4457ea75aa71a63c52d9e9aa313cf360d2639&v1=a957026c4cf7271bfcb1b91335a85f1ca97fd54c) 😉

> [@BartButenaers](#):
>
> - Are you going to explore other engines, or are these good enough?

Probably not since dagre does a pretty good job - for my tastes but I'm not doing this for laying out regular flows, rather flows that I generate on the fly from other sources. Also elkjs has some 198 options for 12 different layout algorithms! There is plenty of room to experiment - IMHO 🙂

I'm simply not a layout engine expert (depth and rank where new to me!) so objectively, learning the meaning of 198 options for something that is very much personal test (everyone has their own opinion on what is a good layout) is a little off the radar for me. Hence if someone has the knowledge, then that would be great.

What I'm trying to do is make experimenting with auto layout simpler since there is no checking out of branches nor hacking around in the browser console, it's just hacking around in a flow in Node-RED and pressing deploy.

> [@BartButenaers](#):
>
> - Is there already one of the two that you like most for some reason?

dagre since it simply did a good layout from the start - admittedly from taken from the [example code](https://pastebin.com/TJRFD3mg). Although if elkjs `mrtree` layout algorithm would go right, then it might will also be a good candidate.

> [@BartButenaers](#):
>
> - Do you think one of those engines is good enough to be used in real life?

How long is a piece of string? What is real life and what is good enough? I do think that elkjs must be able to do the job, after all it's from Eclipse layout engine ... if they're using it ... but it's a matter of experimenting with the various options. There are a bunch of [examples](https://rtsys.informatik.uni-kiel.de/elklive/examples.html) and configuration possibilities ... it's a rabbit hole!

> [@BartButenaers](#):
>
> - So these engines offer lots and lots of options. I assume most of these can have default values that will do for all/most users, and that only some of them are useful to be customizable by users. Do you already have a subset in your mind, that might be useful?

Not gotten that far but you're right, a subset or options for configuration would be great. On the other hand, why not have flows that have different lay-outing possibilities? Have a competition using the flow I've built and everyone can configure their own examples. One could define a set of ten different flows and the person who comes up with the best configuration options for a layout engine (any layout engine), gets a free subscription to the Node-RED monthly magazine! Of course, before that, one would have to have a Node-RED monthly magazine 🙂

> [@BartButenaers](#):
>
> - Are you already aware of some severe limitations, that makes it hard to build a general usable solution?

I've been playing around with very simple flows and nothing bad has yet happened 🙂 Whether this is a general usable solution depends on whether another JS library should be bundled into Node-RED or whether an inbuilt solution would be better - after all these libraries aren't tiny - dagre 100k v. elkjs 1.5MB - space v. time!

> [@BartButenaers](#):
>
> - Do you have plans to integrate this (e.g. using a plugin) into the editor in the near future, or are you just having an immense amount of fun with your lovely experiments? 😋

I'm pursuing other things but will help if others are interested in moving this along. I have my solution and am happy to work with an extra node - i.e. I don't need to have it integrated into Node-RED. IMHO it's definitely a feature that should be in Node-RED but whether that happens ... there are others here that have more to say about that.

> [@BartButenaers](#):
>
> Thanks for sharing your knowledge and endless creativity with us!!

I'm just a dude that has too many ideas 🤪

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [11 September 2023 05:28 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/4 "2023-09-11T05:28:36Z")

</div>

@gregorius has created a flow to experiment with the different layout algorithms. Hopefully some folks here can find some time to play with it on different kinds of flows (straight lines, loops, ...) and share here their experiences. If one of the algorithms can solve most common flow layouts, it might be a good idea to integrate that one in our flow editor (via a plugin or whatever...).

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [11 September 2023 20:16 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/5 "2023-09-11T20:16:37Z")

</div>

Also see this branch - [WIP: Add an auto-layout action by knolleary · Pull Request #2267 · node-red/node-red · GitHub](https://github.com/node-red/node-red/pull/2267)

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [11 September 2023 20:51 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/6 "2023-09-11T20:51:39Z")

</div>

Hi Dave,  
One of the algorithms that @gregorius demonstrates already in his example flow, is the algorithm from that pull request. That way people can compare all the algorithms currently available, and discuss here which they like most and why...

---

<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:** [12 September 2023 11:17 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/7 "2023-09-12T11:17:33Z")

</div>

In fact the animated gif above is the the algorithm from #2267 - since the entire code is frontend, I put it in a ClientCode node to be executed when triggered (btw the gif is from an earlier version of the flow).

I created this because I wanted to do some auto layout'ing for something else I was working on and the PR was not on my radar - else I might not have tried out dagre and elkjs, who knows.

As I said, this is an FYI not a request to have auto layout in Node-RED itself. At the moment, I prefer the mediative work of aligning nodes by hand and won't want the computer to have that pleasure! 🙂

---

<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 October 2023 10:26 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/8 "2023-10-01T10:26:10Z")

</div>

There is now a [node for doing auto layout](https://flows.nodered.org/node/@gregoriusrippenstein/node-red-contrib-auto-alignment), once again the readme isn't showing there, so more [details at NPMjs](https://www.npmjs.com/package/@gregoriusrippenstein/node-red-contrib-auto-alignment).

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [1 October 2023 19:34 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/9 "2023-10-01T19:34:41Z")

</div>

Thanks!  
I installed it, and I really love this node 😍

I have one feature request. Currently the nodes are rather close to each other:

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

For some users that will be fine, but I like to have them a bit more apart from each other.

Is it possible (in your limited free time) to implement something like this:

1. Your node's config screen shows a json typedinput field.
2. When another algorithm is selected, the most common used properties (and their corresponding default values) are automatically being displayed in the json.
3. You can edit property values (e.g. distance between the nodes), and those changes can be deployed.
4. From then on these updated values are being used by the the algorithm in this node.
5. When another algorithm is selected from the dropdown, then the typedinput is again filled with the default values of that algorithm.

And perhaps a hyperlink on your readme page to all available settings.

---

<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 October 2023 20:24 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/10 "2023-10-01T20:24:53Z")

</div>

> [@BartButenaers](#):
>
> Currently the nodes are rather close to each other:

try the "Dagre LR" algorithm, it becomes this:

 ![Screen Shot 2023-10-01 at 22.15.36](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/6/a/6a519b20316cee1f42952f32ce6ff2dcad5d0de6.png)

Feature requests are best done as pull requests with code modifications and additions - the code is all there and just as your time, mine is also limited. I only created the node because I'm testing [nodedev](https://www.npmjs.com/package/@gregoriusrippenstein/node-red-contrib-nodedev) setup - in this case adding [template nodes to split code up](https://flowhub.org/f/3de89bdf647951dc).

---

<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 October 2023 04:03 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/11 "2023-10-02T04:03:10Z")

</div>

Another curious node :') nice, personally i like them a little bit closer, but besides this point - would it be possible to add a checkbox that also performs a "hide node labels" at the time of re-layout ? I am terrible at node development (although I get the "idea", the workflow is quite cumbersome and confusing to me).

---

<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 October 2023 07:57 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/12 "2023-10-02T07:57:37Z")

</div>

> [@bakman2](#):
>
> "hide node labels"

No that is not trivial, but why would this be important? You can export the flow as an SVG and then edit it that to remove the labels.

> [@bakman2](#):
>
> the workflow is quite cumbersome and confusing to me

Yes unfortunately that is the case. The workflow is still very technical however every node developer has to master those steps eventually, be it outside or within Node-RED. There is no way around it.

Using Node-RED at least provides the node developer with a familiar environment to do that development.

---

<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 October 2023 08:10 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/13 "2023-10-02T08:10:12Z")

</div>

Thanks i dont mean removing the labels but hiding the node labels, it reduces/minimises the nodes to a little square 🙂 not sure if there is an api call for it (i use the keyboard shortcuts to do this currently)

---

<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:** [2 October 2023 08:13 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/14 "2023-10-02T08:13:46Z")

</div>

I'm curious why you are publishing all of these utilities as nodes - given they are purely editor enhancements. You could be publishing them as a plugin that adds everything to the editor without expecting a user to drag a node into their workspace to make them functional.

You could then register an action so a keyboard short-cut can be assigned, have them show up in the Action menu and so on.

---

<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 October 2023 08:44 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/15 "2023-10-02T08:44:56Z")

</div>

How do I install a plugin within Node-RED? How does a user install a plugin? How do I define a menu entry for a plugin? I had a look at [Documentation : Node-RED](https://nodered.org/docs/) but there was nothing on plugins that I found.

Is there a manage palette equivalent for plugins? Is there a plugin download or plugin collection @ [flows.nodered.org](http://flows.nodered.org)? Plugins don't seem to have a first-class representation as nodes or flows do.

I think the best thing would be that auto layout be integrated into Node-RED but that has been [tried and failed](https://github.com/node-red/node-red/pull/2267), so instead people go their own way. What does it then matter whether it be a plugin, node or flow - it gets the job done. The nice thing, this being a node, is that I can also trigger a layout event in a [flow](https://flowhub.org/f/119a019d22344192).

Also, I created this for me much as flowfuse creates features for themselves, but I shared it in the form that I need it. I'm not here to create feature per-request from non-paying users, much as flowfuse is not in the business of giving away money.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [2 October 2023 20:31 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/16 "2023-10-02T20:31:01Z")

</div>

@gregorius,  
I am by far a specialist in this area, so others are welcome to append or correct my information!!

First of all I am already a fan of your layouting node. I am just wondering - like Nick said - if a node is the best way to store this kind of functionality. _ **NOT** _ saying at all that I expect you to re-implement your stuff. Because nobody has to tell us open-source developers what to do in our free time 🙂 . But I like to discuss and compare in this community the different ways to implement something. Because that way I can learn a LOT from feedback of other users. And at the end of these discussions, I have no free time left to implement their feedback 😉

I "think" these are the available ways to implement something like this:

1. Using a _ **node** _. When I want to layout the selected nodes on tab X, I first need to add (or find) your layouting node. So although I love nodes, it somehow feels not the best option in this case.

2. Using a _ **plugin** _. I must admit that I am not familiar with plugins in Node-RED. This is the only thing I know about them:

3. Using a _ **sidebar** _. This seems (IMHO) the best solution:

As I said: full of assumptions.  
Shoot 🥶

---

<div class="post-metadata">

**Author:** ![ralphwetzel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ralphwetzel/32/53713_2.png) [@ralphwetzel](https://discourse.nodered.org/u/ralphwetzel)\
**Post date:** [2 October 2023 20:48 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/17 "2023-10-02T20:48:52Z")

</div>

Adding a bit of first-hand experience:

> [@BartButenaers](#):
>
> Using a _ **sidebar** _.

A _sidebar_ is a mean to create a UI for a _plugin_ (if the plugin needs a UI).  
A plugin may store its (config) data wherever it likes, e.g. in a subdirectory of `userDir`.  
Plugins may be registered at the flow library like any other node, and installed via the palette manager. Further / full support via the palette manager is [in the making](https://github.com/node-red/node-red/issues/4271) - short final.  
For an example, you may reference to [node-red-mcu-plugin](https://flows.nodered.org/node/@ralphwetzel/node-red-mcu-plugin).

Finally @gregorius : Great job!

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [2 October 2023 21:40 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/18 "2023-10-02T21:40:01Z")

</div>

> [@ralphwetzel](#):
>
> A _sidebar_ is a mean to create a UI for a _plugin_ (if the plugin needs a UI).

@ralphwetzel,  
Thanks for the addition! Indeed I should have mentioned that. It is indeed correct that your node-red-mcu-sidebar is a plugin (as we can see in your [package.json](https://github.com/ralphwetzel/node-red-mcu-plugin/blob/main/package.json#L7) file). However my [/node-red-contrib-xterm](https://github.com/bartbutenaers/node-red-contrib-xterm) sidebar was developed in 2019, long before the plugin mechanism was introduced in Node-RED (version Version 1.3 was released in 2021). So the original sidebars were no plugins, which made me forget to add it in my overview above...

From that point of view, it indeed makes sense to implement an auto complete feature as a plugin that visualizes the algorithm settings in a sidebar. And that these settings are persisted e.g. in a node via deploy (or somewhere else). Back on track 😉

---

<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:** [3 October 2023 09:12 UTC](https://discourse.nodered.org/t/node-red-auto-layouting-using-elkjs-dagre/81052/19 "2023-10-03T09:12:55Z")

</div>

> [@ralphwetzel](#):
>
> Plugins may be registered at the flow library like any other node, and installed via the palette manager.

Ok that's great to know, then there is a certain amount of visibility that a plugin can gain.

A feature I'd prefer to implement as a plugin would be a [visual unit testing](https://discourse.nodered.org/t/visual-unit-tests/80478) - far more interesting and would make Node-RED that much more approachable for non-developers.

It seems a shame that no one has made an effort in that direction since it would allow people who do testing to also have a use case for using Node-RED.
