# Visualising a Production line

**URL:** <https://discourse.nodered.org/t/visualising-a-production-line/100728>\
**Category:** Dashboard\
**Tags:** dashboard-2\
**Created:** [7 April 2026 10:15 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728 "2026-04-07T10:15:52Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![gerrybartley](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gerrybartley/32/67495_2.png) [@gerrybartley](https://discourse.nodered.org/u/gerrybartley)\
**Post date:** [7 April 2026 10:15 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/1 "2026-04-07T10:15:52Z")

</div>

Is there a nice way to visualise stations on a manufacturing line.

I've created a London tube status type idea for all the zones in the factory using the ui-gauge (tile), but I'd like to show a visual representation of the stations within each zone.  
I could use ui-gauge for each station but what ui element can I use to connect them. Also I'd like to be able to change the shape of the tile gauge to a circle for example  
Any ideas on how I might approach this?

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/9/e9e92d983b41fe147f4a0f37465c8af43a4735f9.png)

---

<div class="post-metadata">

**Author:** ![xx\_Nexus\_xx](https://avatars.discourse-cdn.com/v4/letter/x/54ee81/32.png) [@xx\_Nexus\_xx](https://discourse.nodered.org/u/xx_Nexus_xx)\
**Post date:** [7 April 2026 21:47 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/2 "2026-04-07T21:47:26Z")

</div>

I have something similar (see below),I have different rooms(zones) in my house and show in below UI

1. Which room/zones has an active Motion-Sensor. I can enable/disable the motion sensor when clicking on it)
2. the 2nd ui is showing whenever a motion is triggered in any of these rooms

As you can see, you can easily use REG/AMBER/GREEN status as well in the icons

Just for context, in my example the Title/Sub-title in the UI is displaying the room and time when a tile was changed last (to show last event)

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

---

<div class="post-metadata">

**Author:** ![gerrybartley](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gerrybartley/32/67495_2.png) [@gerrybartley](https://discourse.nodered.org/u/gerrybartley)\
**Post date:** [8 April 2026 06:57 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/3 "2026-04-08T06:57:03Z")

</div>

Very nice. Looking to do something like that with similar visual indicator of status colour/icon

Ideally I want do something like this, but I guess I can do it with just tile gauges without the connectors

Now if I can customise the shape,I'd be very happy 😀

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

---

<div class="post-metadata">

**Author:** ![xx\_Nexus\_xx](https://avatars.discourse-cdn.com/v4/letter/x/54ee81/32.png) [@xx\_Nexus\_xx](https://discourse.nodered.org/u/xx_Nexus_xx)\
**Post date:** [8 April 2026 07:14 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/4 "2026-04-08T07:14:01Z")

</div>

I'm not an expert, but a few guys here are using SVG for this kind of flow visualisation ... maybe search the forum for it

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [8 April 2026 07:17 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/5 "2026-04-08T07:17:12Z")

</div>

Ha, ha - I was just going to suggest that. You beat me to it.

> **[node-red-contrib-ui-svg](https://flows.nodered.org/node/node-red-contrib-ui-svg)**
>
> A Node-RED widget node to show interactive SVG (vector graphics) in the dashboard

I think Bart's node is just for Dashboard-1, but there maybe other versions for D-2.

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [8 April 2026 07:40 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/6 "2026-04-08T07:40:05Z")

</div>

Or you could just place the widgets on a background image that you create.

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [8 April 2026 07:53 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/7 "2026-04-08T07:53:03Z")

</div>

Here's an example of Colin's suggestion.

 ![wednesday_SVG_a](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/a/d/ad2a13e02693c3080083e4c46bd61289ff0696d7.jpeg)  
My CPU monitoring dashboard using Bart's SVG node. The LEDs change colour depending on the temperature reading. The grey one at the top indicates 192.168.1.158 is off-line. The Temp readings and IP addresses are superimposed on the photo of my old mini-server rack.

**I believe Bart's node had an SVG editor so you could create your own graphical shape.**

---

<div class="post-metadata">

**Author:** ![gerrybartley](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gerrybartley/32/67495_2.png) [@gerrybartley](https://discourse.nodered.org/u/gerrybartley)\
**Post date:** [8 April 2026 07:56 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/8 "2026-04-08T07:56:02Z")

</div>

Looks like there is a limited version for D2, but no longer being developed [https://github.com/bartbutenaers/node-red-dashboard-2-ui-svg](https://github.com/bartbutenaers/node-red-dashboard-2-ui-svg)

---

<div class="post-metadata">

**Author:** ![gerrybartley](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gerrybartley/32/67495_2.png) [@gerrybartley](https://discourse.nodered.org/u/gerrybartley)\
**Post date:** [8 April 2026 07:57 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/9 "2026-04-08T07:57:07Z")

</div>

Now that's a possibility. Didn't think of that

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [8 April 2026 07:57 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/10 "2026-04-08T07:57:53Z")

</div>

Probably worth exploring its capabilities as the _stuff_ Bart produced is/was brilliant.

---

<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:** [8 April 2026 08:24 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/11 "2026-04-08T08:24:02Z")

</div>

You can use the markdown node with mermaid formatting, quick example (AI converted your image into mermaid format)

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

In a markdown node you can put:

````auto

```mermaid
graph LR
    S1((S1)):::s1_color
    S2((S2)):::green
    
    subgraph Box[" "]
        S3((S3)):::red
        S4((S4)):::green
    end
    
    S5((S5)):::green
    S6((S6)):::green
    
    S1 -->|{{msg.payload.s1.value}}| Box
    S2 -->|1520| Box
    Box -->|200| S5
    Box -->|1320| S5
    S5 -->|1170| S6
    
    classDef s1_color fill:{{msg.payload.s1.color}},stroke:#666,color:#fff
    classDef green fill:#82b366,stroke:#6a9654,color:#fff
    classDef red fill:#e00,stroke:#a00,color:#fff

````

```auto

```

The color and value (for S1) are coming from a function node:

```auto
const o = {}

o.s1 = {}
o.s1.value = 120
o.s1.color = "#ff3300"

msg.payload = o
return msg;

```

The shapes, connections and colors/fonts can be all customized and even animated.

example flow

````flows
[
    {
        "id": "ecb066bc52ad3528",
        "type": "ui-markdown",
        "z": "122fc9cab06e5091",
        "group": "376057a66a602d2e",
        "name": "",
        "order": 1,
        "width": 0,
        "height": 0,
        "content": "```mermaid\ngraph LR\n S1((S1)):::s1_color\n S2((S2)):::green\n \n subgraph Box[\" \"]\n S3((S3)):::red\n S4((S4)):::green\n end\n \n S5((S5)):::green\n S6((S6)):::green\n \n S1 -->|{{msg.payload.s1.value}}| Box\n S2 -->|1520| Box\n Box -->|200| S5\n Box -->|1320| S5\n S5 -->|1170| S6\n \n classDef s1_color fill:{{msg.payload.s1.color}},stroke:#666,color:#fff\n classDef green fill:#82b366,stroke:#6a9654,color:#fff\n classDef red fill:#e00,stroke:#a00,color:#fff\n```",
        "className": "",
        "x": 490,
        "y": 320,
        "wires": [
            []
        ]
    },
    {
        "id": "06139bc01b526831",
        "type": "inject",
        "z": "122fc9cab06e5091",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 180,
        "y": 320,
        "wires": [
            [
                "978e9ef0dc625d62"
            ]
        ]
    },
    {
        "id": "978e9ef0dc625d62",
        "type": "function",
        "z": "122fc9cab06e5091",
        "name": "some values",
        "func": "const o = {}\n\no.s1 = {}\no.s1.value = 120\no.s1.color = \"#ff3300\"\n\nmsg.payload = o\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 330,
        "y": 320,
        "wires": [
            [
                "ecb066bc52ad3528",
                "3f8723e17b41f707"
            ]
        ]
    },
    {
        "id": "376057a66a602d2e",
        "type": "ui-group",
        "name": "Group 1",
        "page": "722d26d5f962a5bf",
        "width": 6,
        "height": 1,
        "order": 1,
        "showTitle": true,
        "className": "",
        "visible": true,
        "disabled": false,
        "groupType": "default"
    },
    {
        "id": "722d26d5f962a5bf",
        "type": "ui-page",
        "name": "Page 1",
        "ui": "79e3f392c899e28b",
        "path": "/page1",
        "icon": "home",
        "layout": "grid",
        "theme": "9fef7ae69829ce44",
        "breakpoints": [
            {
                "name": "Default",
                "px": 0,
                "cols": 3
            },
            {
                "name": "Tablet",
                "px": 576,
                "cols": 6
            },
            {
                "name": "Small Desktop",
                "px": 768,
                "cols": 9
            },
            {
                "name": "Desktop",
                "px": 1024,
                "cols": 12
            }
        ],
        "order": 1,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "79e3f392c899e28b",
        "type": "ui-base",
        "name": "My Dashboard",
        "path": "/dashboard",
        "appIcon": "",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-notification",
            "ui-control"
        ],
        "showPathInSidebar": false,
        "headerContent": "page",
        "navigationStyle": "default",
        "titleBarStyle": "default",
        "showReconnectNotification": true,
        "notificationDisplayTime": 1,
        "showDisconnectNotification": true,
        "allowInstall": false
    },
    {
        "id": "9fef7ae69829ce44",
        "type": "ui-theme",
        "name": "Default Theme",
        "colors": {
            "surface": "#ffffff",
            "primary": "#0094CE",
            "bgPage": "#eeeeee",
            "groupBg": "#ffffff",
            "groupOutline": "#cccccc"
        },
        "sizes": {
            "density": "default",
            "pagePadding": "12px",
            "groupGap": "12px",
            "groupBorderRadius": "4px",
            "widgetGap": "12px"
        }
    },
    {
        "id": "f08a209a16379eed",
        "type": "global-config",
        "env": [],
        "modules": {
            "@flowfuse/node-red-dashboard": "1.30.2"
        }
    }
]

````

---

<div class="post-metadata">

**Author:** ![gerrybartley](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gerrybartley/32/67495_2.png) [@gerrybartley](https://discourse.nodered.org/u/gerrybartley)\
**Post date:** [8 April 2026 08:56 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/12 "2026-04-08T08:56:09Z")

</div>

You're a star ⭐  
I think that will do exactly what I want  
I'll mark as solution when I get it all working  
Thanks

---

<div class="post-metadata">

**Author:** ![anka001](https://avatars.discourse-cdn.com/v4/letter/a/cdc98d/32.png) [@anka001](https://discourse.nodered.org/u/anka001)\
**Post date:** [8 April 2026 16:59 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/13 "2026-04-08T16:59:11Z")

</div>

If you still want to give a svg solution a try, the easiest way now is to use uibuilder to display the svg. uibuilder can take care of all the interactive stuff.  
[Here](https://flows.nodered.org/flow/02eb3716157db586f3f5b8a85c241009) you can find an example showing an interactive floorplan.

---

<div class="post-metadata">

**Author:** ![gerrybartley](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gerrybartley/32/67495_2.png) [@gerrybartley](https://discourse.nodered.org/u/gerrybartley)\
**Post date:** [8 April 2026 17:22 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/14 "2026-04-08T17:22:22Z")

</div>

Thanks, that looks interesting. Haven't used ui-builder yet

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [9 April 2026 09:19 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/15 "2026-04-09T09:19:50Z")

</div>

> [@gerrybartley](#):
>
> Haven't used ui-builder yet

I'm usually around if you have any questions. 😃

---

<div class="post-metadata">

**Author:** ![gemini86](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gemini86/32/70967_2.png) [@gemini86](https://discourse.nodered.org/u/gemini86)\
**Post date:** [14 April 2026 14:02 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/16 "2026-04-14T14:02:53Z")

</div>

If you like, you can still use tiles... CSS is your friend for shaping them. It may not be the best for your situation but I wanted to make sure others who find this know how CSS classes can (somewhat) easily customize built-in widgets.

```flows
[
    {
        "id": "de34d0275741fe5c",
        "type": "ui-gauge",
        "z": "14b49a9c9496432b",
        "name": "tile 2",
        "group": "efbce469212daff6",
        "order": 2,
        "value": "payload",
        "valueType": "msg",
        "width": "1",
        "height": "2",
        "gtype": "gauge-tile",
        "gstyle": "needle",
        "title": "Tile 2",
        "alwaysShowTitle": false,
        "floatingTitlePosition": "top-left",
        "units": "units",
        "icon": "",
        "prefix": "",
        "suffix": "",
        "segments": [
            {
                "from": "0",
                "color": "#5cd65c",
                "text": "",
                "textType": "label"
            },
            {
                "from": "4",
                "color": "#ffc800",
                "text": "",
                "textType": "label"
            },
            {
                "from": "7",
                "color": "#ea5353",
                "text": "",
                "textType": "label"
            }
        ],
        "min": 0,
        "max": 10,
        "sizeThickness": 16,
        "sizeGap": 4,
        "sizeKeyThickness": 8,
        "styleRounded": true,
        "styleGlow": false,
        "className": "rounded-tile",
        "x": 490,
        "y": 480,
        "wires": [
            []
        ]
    },
    {
        "id": "c39f8cf7c63c5374",
        "type": "ui-gauge",
        "z": "14b49a9c9496432b",
        "name": "tile 1",
        "group": "efbce469212daff6",
        "order": 1,
        "value": "payload",
        "valueType": "msg",
        "width": "1",
        "height": "2",
        "gtype": "gauge-tile",
        "gstyle": "needle",
        "title": "Tile 1",
        "alwaysShowTitle": false,
        "floatingTitlePosition": "top-left",
        "units": "units",
        "icon": "",
        "prefix": "",
        "suffix": "",
        "segments": [
            {
                "from": "0",
                "color": "#5cd65c",
                "text": "",
                "textType": "label"
            },
            {
                "from": "4",
                "color": "#ffc800",
                "text": "",
                "textType": "label"
            },
            {
                "from": "7",
                "color": "#ea5353",
                "text": "",
                "textType": "label"
            }
        ],
        "min": 0,
        "max": 10,
        "sizeThickness": 16,
        "sizeGap": 4,
        "sizeKeyThickness": 8,
        "styleRounded": true,
        "styleGlow": false,
        "className": "rounded-tile",
        "x": 490,
        "y": 440,
        "wires": [
            []
        ]
    },
    {
        "id": "99044c78c25adcf7",
        "type": "inject",
        "z": "14b49a9c9496432b",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "1",
        "payloadType": "num",
        "x": 290,
        "y": 420,
        "wires": [
            [
                "c39f8cf7c63c5374"
            ]
        ]
    },
    {
        "id": "fc6a1dfda7765f2b",
        "type": "inject",
        "z": "14b49a9c9496432b",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "4",
        "payloadType": "num",
        "x": 290,
        "y": 480,
        "wires": [
            [
                "de34d0275741fe5c"
            ]
        ]
    },
    {
        "id": "d8d36b2c0c022c20",
        "type": "ui-template",
        "z": "14b49a9c9496432b",
        "group": "",
        "page": "",
        "ui": "01cb2bb666191bef",
        "name": "css",
        "order": 0,
        "width": 0,
        "height": 0,
        "head": "",
        "format": ".rounded-tile div {\n border-radius: 50%;\n height: 80px;\n width: 80px;\n}",
        "storeOutMessages": true,
        "passthru": true,
        "resendOnRefresh": true,
        "templateScope": "site:style",
        "className": "",
        "x": 410,
        "y": 280,
        "wires": [
            []
        ]
    },
    {
        "id": "9c86cc294dae11c3",
        "type": "ui-gauge",
        "z": "14b49a9c9496432b",
        "name": "tile 3",
        "group": "efbce469212daff6",
        "order": 3,
        "value": "payload",
        "valueType": "msg",
        "width": "1",
        "height": "2",
        "gtype": "gauge-tile",
        "gstyle": "needle",
        "title": "Tile 3",
        "alwaysShowTitle": false,
        "floatingTitlePosition": "top-left",
        "units": "units",
        "icon": "",
        "prefix": "",
        "suffix": "",
        "segments": [
            {
                "from": "0",
                "color": "#5cd65c",
                "text": "",
                "textType": "label"
            },
            {
                "from": "4",
                "color": "#ffc800",
                "text": "",
                "textType": "label"
            },
            {
                "from": "7",
                "color": "#ea5353",
                "text": "",
                "textType": "label"
            }
        ],
        "min": 0,
        "max": 10,
        "sizeThickness": 16,
        "sizeGap": 4,
        "sizeKeyThickness": 8,
        "styleRounded": true,
        "styleGlow": false,
        "className": "rounded-tile",
        "x": 490,
        "y": 520,
        "wires": [
            []
        ]
    },
    {
        "id": "2a6f646ff2951070",
        "type": "inject",
        "z": "14b49a9c9496432b",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "7",
        "payloadType": "num",
        "x": 290,
        "y": 540,
        "wires": [
            [
                "9c86cc294dae11c3"
            ]
        ]
    },
    {
        "id": "efbce469212daff6",
        "type": "ui-group",
        "name": "Group 1",
        "page": "9b525f55b1e35863",
        "width": 6,
        "height": 1,
        "order": 1,
        "showTitle": true,
        "className": "",
        "visible": true,
        "disabled": false,
        "groupType": "default"
    },
    {
        "id": "01cb2bb666191bef",
        "type": "ui-base",
        "name": "My Dashboard",
        "path": "/dashboard",
        "appIcon": "",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-notification",
            "ui-control"
        ],
        "showPathInSidebar": false,
        "headerContent": "page",
        "navigationStyle": "default",
        "titleBarStyle": "default",
        "showReconnectNotification": true,
        "notificationDisplayTime": 1,
        "showDisconnectNotification": true,
        "allowInstall": false
    },
    {
        "id": "9b525f55b1e35863",
        "type": "ui-page",
        "name": "Page 1",
        "ui": "01cb2bb666191bef",
        "path": "/page1",
        "icon": "home",
        "layout": "grid",
        "theme": "370f48f6497327e6",
        "breakpoints": [
            {
                "name": "Default",
                "px": 0,
                "cols": 3
            },
            {
                "name": "Tablet",
                "px": 576,
                "cols": 6
            },
            {
                "name": "Small Desktop",
                "px": 768,
                "cols": 9
            },
            {
                "name": "Desktop",
                "px": 1024,
                "cols": 12
            }
        ],
        "order": 1,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "370f48f6497327e6",
        "type": "ui-theme",
        "name": "Default Theme",
        "colors": {
            "surface": "#ffffff",
            "primary": "#0094CE",
            "bgPage": "#eeeeee",
            "groupBg": "#ffffff",
            "groupOutline": "#cccccc"
        },
        "sizes": {
            "density": "default",
            "pagePadding": "12px",
            "groupGap": "12px",
            "groupBorderRadius": "4px",
            "widgetGap": "12px"
        }
    },
    {
        "id": "39466a3280681199",
        "type": "global-config",
        "env": [],
        "modules": {
            "@flowfuse/node-red-dashboard": "1.30.2"
        }
    }
]

```

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

---

<div class="post-metadata">

**Author:** ![gerrybartley](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gerrybartley/32/67495_2.png) [@gerrybartley](https://discourse.nodered.org/u/gerrybartley)\
**Post date:** [14 April 2026 14:30 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/17 "2026-04-14T14:30:30Z")

</div>

Very nice. I definitely have a use for that

---

<div class="post-metadata">

**Author:** ![gerrybartley](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gerrybartley/32/67495_2.png) [@gerrybartley](https://discourse.nodered.org/u/gerrybartley)\
**Post date:** [20 April 2026 06:58 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/18 "2026-04-20T06:58:29Z")

</div>

So I got my visualisation working using Mermaid

I'm passing in the the stations outs, state and current running state in msg.payload

I'm using colours to indicate how well the station is running  
Animated links to show if the station is actually in a run state

Overall I'm pretty pleased with the outcome  
Thanks to everyone who took the time to help  
I'll mark bakman2's reply as the solution

![mermaid](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/d/9d90da5ead7b25f32342ca25cff956d3988119dd.gif)

And here's a working flow

````auto
[{"id":"ecb066bc52ad3528","type":"ui-markdown","z":"aeb8a73b96be29c0","group":"efbce469212daff6","name":"Z1","order":2,"width":"0","height":"0","content":"```mermaid\n\n\n%%{\n init: {\n \"theme\": \"dark\",\n \"themeVariables\": {\n \"fontSize\": \"1.5rem\",\n \"edgeLabelBackground\": \"#424242\",\n \"edgeLabelColor\": \"white\"\n },\n\n \n \"logLevel\": \"info\",\n \"htmlLabels\": true,\n \"flowchart\": {\n \"curve\": \"linear\"\n },\n \"sequence\": {\n \"mirrorActors\": true\n }\n }\n}%%\n\n\ngraph LR\n S1(({{msg.payload[2].MODULE}})):::{{msg.payload[2].STATUS}}\n S2(({{msg.payload[3].MODULE}})):::{{msg.payload[3].STATUS}}\n S3(({{msg.payload[4].MODULE}})):::{{msg.payload[4].STATUS}}\n S4(({{msg.payload[5].MODULE}})):::{{msg.payload[5].STATUS}}\n CS(({{msg.payload[6].MODULE}})):::{{msg.payload[6].STATUS}}\n F1(({{msg.payload[7].MODULE}})):::{{msg.payload[7].STATUS}}\n F2(({{msg.payload[8].MODULE}})):::{{msg.payload[8].STATUS}}\n C1(({{msg.payload[9].MODULE}})):::{{msg.payload[9].STATUS}}\n C2(({{msg.payload[10].MODULE}})):::{{msg.payload[10].STATUS}}\n GL(({{msg.payload[11].MODULE}})):::{{msg.payload[11].STATUS}}\n \n Z2((Zone 2))\n\n \n S1 an2@-->|{{msg.payload[2].OUTS}}| J0\n S2 an3@-->|{{msg.payload[3].OUTS}}| J0\n S3 an4@-->|{{msg.payload[4].OUTS}}| J0\n J0 an17@--> J1\n S4 an5@-->|{{msg.payload[5].OUTS}}| J0 an12@---> CS\n\n CS an6@--->|{{msg.payload[6].OUTS}}| J1\n \n J1 an13@---> F1 an7@--->|{{msg.payload[7].OUTS}}| J2\n J1 an14@---> F2 an8@--->|{{msg.payload[8].OUTS}}| J2\n J2 an15@---> C1 an9@--->|{{msg.payload[9].OUTS}}| GL\n J2 an16@---> C2 an10@--->|{{msg.payload[10].OUTS}}| GL\n GL an11@--->|{{msg.payload[11].OUTS}} | Z2\n \n J0@{ shape: f-circ}\n J1@{ shape: f-circ}\n J2@{ shape: f-circ}\n\n \n an2@{ animate: {{msg.payload[2].STATE}} }\n an3@{ animate: {{msg.payload[3].STATE}} }\n an4@{ animate: {{msg.payload[4].STATE}} }\n an5@{ animate: {{msg.payload[5].STATE}} }\n an6@{ animate: {{msg.payload[6].STATE}} }\n an7@{ animate: {{msg.payload[7].STATE}} }\n an8@{ animate: {{msg.payload[8].STATE}} }\n an9@{ animate: {{msg.payload[9].STATE}} }\n an10@{ animate: {{msg.payload[10].STATE}} }\n an11@{ animate: {{msg.payload[11].STATE}} }\n an12@{ animate: {{msg.payload[2].STATE || msg.payload[3].STATE || msg.payload[4].STATE || msg.payload[5].STATE}} }\n an13@{ animate: {{msg.payload[2].STATE || msg.payload[3].STATE || msg.payload[4].STATE || msg.payload[5].STATE}} }\n an14@{ animate: {{msg.payload[2].STATE || msg.payload[3].STATE || msg.payload[4].STATE || msg.payload[5].STATE}} }\n an15@{ animate: {{msg.payload[7].STATE || msg.payload[8].STATE }} }\n an16@{ animate: {{msg.payload[7].STATE || msg.payload[8].STATE }} }\n an17@{ animate: {{(msg.payload[2].STATE || msg.payload[3].STATE || msg.payload[4].STATE || msg.payload[5].STATE) && msg.payload[6].OUTS == 0 }} }\n\n \n\n \n classDef grey fill:#808080,stroke:#6a9654,color:#fff\n classDef green fill:#5cd65c,stroke:#6a9654,color:#fff\n classDef orange fill:#ffc800,stroke:#6a9654,color:black\n classDef red fill:#e00,stroke:#a00,color:#fff\n\n \n \n linkStyle default stroke:grey,stroke-width:4px\n \n style Z2 fill:#424242,stroke:white,stroke-width:1px,color:white\n \n```\n","className":"","x":890,"y":280,"wires":[[]]},{"id":"c54dada3a8f273e1","type":"inject","z":"aeb8a73b96be29c0","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"MODULE\":\"X1\",\"STATUS\":\"grey\",\"STATE\":0,\"OUTS\":0},{\"MODULE\":\"X2\",\"STATUS\":\"green\",\"STATE\":10,\"OUTS\":11974},{\"MODULE\":\"SP1\",\"STATUS\":\"green\",\"STATE\":10,\"OUTS\":5605},{\"MODULE\":\"SP2\",\"STATUS\":\"green\",\"STATE\":10,\"OUTS\":6111},{\"ORDINAL\":5,\"MODULE\":\"SP3\",\"STATUS\":\"grey\",\"STATE\":0,\"OUTS\":0},{\"ORDINAL\":6,\"MODULE\":\"SP4\",\"STATUS\":\"grey\",\"STATE\":0,\"OUTS\":0},{\"MODULE\":\"CS1\",\"STATUS\":\"grey\",\"STATE\":0,\"OUTS\":0},{\"MODULE\":\"FT1\",\"STATUS\":\"orange\",\"STATE\":10,\"OUTS\":11687},{\"MODULE\":\"FT2\",\"STATUS\":\"grey\",\"STATE\":0,\"OUTS\":0},{\"MODULE\":\"CO1\",\"STATUS\":\"green\",\"STATE\":10,\"OUTS\":8278},{\"MODULE\":\"CO2\",\"STATUS\":\"orange\",\"STATE\":10,\"OUTS\":4779},{\"MODULE\":\"GL1\",\"STATUS\":\"green\",\"STATE\":10,\"OUTS\":13416}]","payloadType":"json","x":730,"y":280,"wires":[["ecb066bc52ad3528"]]},{"id":"efbce469212daff6","type":"ui-group","name":"Group 1","page":"9b525f55b1e35863","width":"12","height":1,"order":1,"showTitle":false,"className":"","visible":"true","disabled":"false","groupType":"default"},{"id":"9b525f55b1e35863","type":"ui-page","name":"Page 1","ui":"4740393b964cb7af","path":"/page1","icon":"home","layout":"grid","theme":"11edfaf96d0baec1","breakpoints":[{"name":"Default","px":"0","cols":"3"},{"name":"Tablet","px":"576","cols":"6"},{"name":"Small Desktop","px":"768","cols":"9"},{"name":"Desktop","px":"1024","cols":"12"}],"order":2,"className":"","visible":"true","disabled":"false"},{"id":"4740393b964cb7af","type":"ui-base","name":"Playground","path":"/dashboard","appIcon":"","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control","ui-dropdown","ui-chart","ui-gauge","ui-button","ui-template","ui-text","ui-table","ui-form","ui-switch","ui-text-input"],"showPathInSidebar":false,"headerContent":"page","navigationStyle":"fixed","titleBarStyle":"hidden","showReconnectNotification":true,"notificationDisplayTime":"1","showDisconnectNotification":true,"allowInstall":true},{"id":"11edfaf96d0baec1","type":"ui-theme","name":"Dark1","colors":{"surface":"#424242","primary":"#0094ce","bgPage":"#424242","groupBg":"#424242","groupOutline":"#424242"},"sizes":{"density":"default","pagePadding":"2px","groupGap":"6px","groupBorderRadius":"4px","widgetGap":"10px"}},{"id":"654c97f62568a8bd","type":"global-config","env":[],"modules":{"@flowfuse/node-red-dashboard":"1.29.0"}}]

````

---

<div class="post-metadata">

**Author:** ![iiLaw](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/iilaw/32/14782_2.png) [@iiLaw](https://discourse.nodered.org/u/iiLaw)\
**Post date:** [20 April 2026 18:45 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/19 "2026-04-20T18:45:22Z")

</div>

That is very neat ...

---

<div class="post-metadata">

**Author:** ![gerrybartley](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gerrybartley/32/67495_2.png) [@gerrybartley](https://discourse.nodered.org/u/gerrybartley)\
**Post date:** [27 April 2026 07:02 UTC](https://discourse.nodered.org/t/visualising-a-production-line/100728/20 "2026-04-27T07:02:02Z")

</div>

Added an updated flow in Share my Projects [https://discourse.nodered.org/t/visual-production-line/100856](https://discourse.nodered.org/t/visual-production-line/100856)

[Next page](https://discourse.nodered.org/t/visualising-a-production-line/100728.md?page=2)
