# Echarts options via msg.ui\_update not persistant

**URL:** https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968
**Category:** Dashboard
**Tags:** dashboard-2
**Created:** [18 December 2025 00:06 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968 "2025-12-18T00:06:16Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![ceysa75](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ceysa75/32/31340_2.png) [@ceysa75](https://discourse.nodered.org/u/ceysa75)
#### Post date: [18 December 2025 00:06 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968/1 "2025-12-18T00:06:16Z")

</div>

Hi All, Hi Colin,

now after doing my first experiements I am quite satisfied with what can be achieved triggering the echarts options via msg.ui\_update. However, what I experience is that the options once set do not survive a browser refresh (or closing and opening the browser). Which means, each time I open the browser it is required to re-inject the msg.ui\_update.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/b/fb219b75a11270d4d500e359131dd18232a76b59.png)  
Fig.1 This is what I want (after a msg.ui\_update inject)

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/c/fcec5881ceb86e37c81f5ba93059cd19845184c5.png)  
Fig. 2 This is what happens after a browser refresh

I have attached a nice example flow which demonstrates my issues:

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

```auto
[
    {
        "id": "23448822b52f0ac1",
        "type": "ui-chart",
        "z": "d219a270aa9d8c20",
        "group": "b6dcd3e8ee87dac6",
        "name": "Room XX",
        "label": "Room XX",
        "order": 1,
        "chartType": "line",
        "category": "topic",
        "categoryType": "msg",
        "xAxisLabel": "Uhrzeit",
        "xAxisProperty": "payload.x",
        "xAxisPropertyType": "msg",
        "xAxisType": "time",
        "xAxisFormat": "",
        "xAxisFormatType": "{HH}:{mm}",
        "xmin": "",
        "xmax": "",
        "yAxisLabel": "Temperatur °C",
        "yAxisProperty": "payload.y",
        "yAxisPropertyType": "msg",
        "ymin": "14",
        "ymax": "28",
        "bins": 10,
        "action": "append",
        "stackSeries": false,
        "pointShape": "circle",
        "pointRadius": "5",
        "showLegend": true,
        "removeOlder": "12",
        "removeOlderUnit": "3600",
        "removeOlderPoints": "",
        "colors": [
            "#0095ff",
            "#f50000",
            "#ffdd00",
            "#f2f2f2",
            "#4dff00",
            "#fb00ff",
            "#2ca02c",
            "#00ffd5",
            "#c5b0d5"
        ],
        "textColor": [
            "#ffffff"
        ],
        "textColorDefault": false,
        "gridColor": [
            "#5c5c5c"
        ],
        "gridColorDefault": false,
        "width": 6,
        "height": "6",
        "className": "",
        "interpolation": "linear",
        "x": 2660,
        "y": 3750,
        "wires": [
            []
        ]
    },
    {
        "id": "72dc649413ed09b2",
        "type": "function",
        "z": "d219a270aa9d8c20",
        "name": "msg.ui_update",
        "func": "msg.payload = {} // create an empty object\n\nmsg.ui_update = {\n \"chartOptions\": {\n \"series\": [\n {\n \"name\": \"ext Sensor\",\n \"type\": \"line\",\n \"areaStyle\": null,\n \"smooth\": false,\n \"lineStyle\": {\n \"color\": \"rgb(64, 156, 255)\",\n \"width\": 3\n },\n \"itemStyle\": {\n \"color\": \"rgb(64, 156, 255)\"\n }\n },\n {\n \"name\": \"heat\",\n \"type\": \"line\",\n \"symbol\": \"none\",\n \"areaStyle\": {\n \"color\": \"rgba(255, 99, 110, 0.5)\"\n },\n \"smooth\": false,\n \"lineStyle\": {\n \"color\": \"rgb(255, 99, 110)\",\n \"width\": 0\n },\n \"itemStyle\": {\n \"color\": \"rgb(255, 99, 110)\"\n },\n \"tooltip\": {\n \"show\": false\n }\n },\n {\n \"name\": \"target\",\n \"type\": \"line\",\n \"areaStyle\": null,\n \"smooth\": false,\n \"lineStyle\": {\n \"color\": \"rgb(210, 204, 190)\",\n \"width\": 3\n },\n \"itemStyle\": {\n \"color\": \"rgb(210, 204, 190)\"\n }\n }\n]\n }\n};\n\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 2450,
        "y": 3850,
        "wires": [
            [
                "23448822b52f0ac1"
            ]
        ]
    },
    {
        "id": "960cbc5dce84c9f9",
        "type": "inject",
        "z": "d219a270aa9d8c20",
        "name": "Clear Data",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "[]",
        "payloadType": "json",
        "x": 2480,
        "y": 3700,
        "wires": [
            [
                "23448822b52f0ac1"
            ]
        ]
    },
    {
        "id": "033f02d33b10315e",
        "type": "function",
        "z": "d219a270aa9d8c20",
        "name": "payloads & topics",
        "func": "\nconst state = Math.random() < 0.4 ? \"idle\" : \"heat\";\nconst target_temp = 21;\nconst ext_temp = Math.floor(Math.random() * (24 - 18 + 1)) + 18; // random between 18 and 24\n\nlet ext_temp_4_idle;\nlet ext_temp_4_heat;\n\nif (state == \"idle\") {\n ext_temp_4_idle = ext_temp\n ext_temp_4_heat = \"null\"\n} else if (state == \"heat\") {\n ext_temp_4_idle = ext_temp\n ext_temp_4_heat = ext_temp \n}\n\nlet msg1 = {}\nmsg1.payload = ext_temp_4_idle\nmsg1.topic = \"ext Sensor\"\n\n\nlet msg2 = {}\nmsg2.payload = ext_temp_4_heat\nmsg2.topic = \"heat\"\n\nlet msg3 = {}\nmsg3.payload = target_temp\nmsg3.topic = \"target\"\n\n\nreturn [msg1,msg2,msg3];",
        "outputs": 3,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1920,
        "y": 3750,
        "wires": [
            [
                "1454e8d7c2a6eccd"
            ],
            [
                "c380f1eb2d7f5725"
            ],
            [
                "c10fb20c658e352d"
            ]
        ]
    },
    {
        "id": "1454e8d7c2a6eccd",
        "type": "delay",
        "z": "d219a270aa9d8c20",
        "name": "",
        "pauseType": "delay",
        "timeout": "0",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 2130,
        "y": 3700,
        "wires": [
            [
                "2db0f5ab0ddeb12c"
            ]
        ]
    },
    {
        "id": "c380f1eb2d7f5725",
        "type": "delay",
        "z": "d219a270aa9d8c20",
        "name": "",
        "pauseType": "delay",
        "timeout": "200",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 2130,
        "y": 3750,
        "wires": [
            [
                "2db0f5ab0ddeb12c"
            ]
        ]
    },
    {
        "id": "c10fb20c658e352d",
        "type": "delay",
        "z": "d219a270aa9d8c20",
        "name": "",
        "pauseType": "delay",
        "timeout": "400",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 2130,
        "y": 3800,
        "wires": [
            [
                "2db0f5ab0ddeb12c"
            ]
        ]
    },
    {
        "id": "2db0f5ab0ddeb12c",
        "type": "function",
        "z": "d219a270aa9d8c20",
        "name": "quantitize time to nearest 5 s",
        "func": "const now = Date.now();\nconst aligned = Math.round(now / 5000) * 5000; // 5.000 ms = 5 s\nmsg.payload = { x: aligned, y: msg.payload };\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 2420,
        "y": 3750,
        "wires": [
            [
                "23448822b52f0ac1"
            ]
        ]
    },
    {
        "id": "c5fdc2d42ca15846",
        "type": "inject",
        "z": "d219a270aa9d8c20",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "5",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 1710,
        "y": 3750,
        "wires": [
            [
                "033f02d33b10315e"
            ]
        ]
    },
    {
        "id": "9d899f13a56ffbe1",
        "type": "inject",
        "z": "d219a270aa9d8c20",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 2260,
        "y": 3850,
        "wires": [
            [
                "72dc649413ed09b2"
            ]
        ]
    },
    {
        "id": "b6dcd3e8ee87dac6",
        "type": "ui-group",
        "name": "msg.ui_update_NEU",
        "page": "a9b32250ebfa989b",
        "width": 6,
        "height": 1,
        "order": 4,
        "showTitle": true,
        "className": "",
        "visible": "true",
        "disabled": "false",
        "groupType": "default"
    },
    {
        "id": "a9b32250ebfa989b",
        "type": "ui-page",
        "name": "Dashboard 2.0 Examples",
        "ui": "14a551a96b61dade",
        "path": "/templates",
        "icon": "view-dashboard",
        "layout": "grid",
        "theme": "cbe751f3fb4f230f",
        "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": 12,
        "className": "",
        "visible": true,
        "disabled": false
    },
    {
        "id": "14a551a96b61dade",
        "type": "ui-base",
        "name": "My Dashboard 2",
        "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": true
    },
    {
        "id": "cbe751f3fb4f230f",
        "type": "ui-theme",
        "name": "JJ_Dark",
        "colors": {
            "surface": "#2c5168",
            "primary": "#585858",
            "bgPage": "#121212",
            "groupBg": "#2c2b2b",
            "groupOutline": "#c7c2c2"
        },
        "sizes": {
            "density": "compact",
            "pagePadding": "1px",
            "groupGap": "4px",
            "groupBorderRadius": "2px",
            "widgetGap": "6px"
        }
    },
    {
        "id": "348efdce5e5bb4a8",
        "type": "global-config",
        "env": [],
        "modules": {
            "@flowfuse/node-red-dashboard": "1.30.0"
        }
    }
]

```

Thank you

---

<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: [18 December 2025 08:12 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968/2 "2025-12-18T08:12:05Z")

</div>

That is certainly not a general problem, I will try your flow.

---

<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: [18 December 2025 13:48 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968/3 "2025-12-18T13:48:12Z")

</div>

I can replicate the problem.  
Until it is sorted you can use a ui-event node to tell you when the page is opened or refreshed and trigger the ui\_update then.

---

<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: [19 December 2025 16:18 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968/4 "2025-12-19T16:18:52Z")

</div>

I have raised an bug report for this. I am working on the fix.

> <https://github.com/FlowFuse/node-red-dashboard/issues/1978>
>
> \### Current Behavior
> 
> There are a number of issues using msg.ui\_update.chartOpti…ons where the options specified act on Series. 
> 1. The settings are not persistent across page refresh.
> 2. If the options message is sent before there is data on the chart for the series being referenced then the option may not be applied when data are added.
> 3. The docs do not specify that any settings on series must include the series name in order to identify it.
> 
> Related forum post https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968
> 
> \### Expected Behavior
> 
> \_No response\_
> 
> \### Steps To Reproduce
> 
> \_No response\_
> 
> \### Environment
> 
> \- Dashboard version: 1.30.0
> \- Node-RED version:
> \- Node.js version:
> \- npm version:
> \- Platform/OS:
> \- Browser:
> 
> 
> \### Have you provided an initial effort estimate for this issue?
> 
> I have provided an initial effort estimate

---

<div class="post-metadata">

### Author: ![ceysa75](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ceysa75/32/31340_2.png) [@ceysa75](https://discourse.nodered.org/u/ceysa75)
#### Post date: [20 December 2025 12:14 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968/5 "2025-12-20T12:14:39Z")

</div>

Hi Colin,  
Thanks. Hope it is nothing too complicated standing behind that behavior. I also found that smaller changes in terms of e.g. chart tiltle etc. remain persistant. However, as soon as data series come in it doesn't work.  
Thanks again and best wishes...

---

<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: [30 December 2025 17:42 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968/6 "2025-12-30T17:42:57Z")

</div>

This should all be working now in v1.30.1

---

<div class="post-metadata">

### Author: ![ceysa75](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ceysa75/32/31340_2.png) [@ceysa75](https://discourse.nodered.org/u/ceysa75)
#### Post date: [31 December 2025 10:02 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968/7 "2025-12-31T10:02:34Z")

</div>

Thank you!! It works perfectly now! And thank you that this has been published on very short notice.  
Will start doing sophisticated Charts designs. One question: Is there any command that would reset all settings that have been injected via msg.ui\_update ? I can clear the data by injecting a `msg.payload = []`. However, I also want to reset everything for test purposes. The only working way I found is a NR restart.  
Thank you.

---

<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: [31 December 2025 10:36 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968/8 "2025-12-31T10:36:21Z")

</div>

Unfortunately no, I don't think that there is a way that can be done. Node red has no way of knowing the default values for all the thousands of eCharts options. If you override one of those then, as far as I know, there is no way to tell eCharts to reset it to the default value.

---

<div class="post-metadata">

### Author: ![Buckskin](https://avatars.discourse-cdn.com/v4/letter/b/b9e5f3/32.png) [@Buckskin](https://discourse.nodered.org/u/Buckskin)
#### Post date: [1 January 2026 18:07 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968/9 "2026-01-01T18:07:40Z")

</div>

The way I do this is to keep a copy of what I have set as a default and then inject that as a `msg.ui_update` (so I keep track of all update changes)

The only way to get a true charts default is as Colin says to go through the eChart configuration document and save them.

One thought as I have not tried it, would changing the chart type reset the 'options' Object?

---

<div class="post-metadata">

### Author: ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)
#### Post date: [1 January 2026 18:25 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968/10 "2026-01-01T18:25:31Z")

</div>

> [@Colin](#):
>
> If you override one of those then, as far as I know, there is no way to tell eCharts to reset it to the default value.

In order to get a "reset" button I'm having to set multiple parameters, many of which are not the default values listed in echarts documentation.  
Of course ui-chart passes some overrides. I just wish they were listed somewhere!

---

<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: [1 January 2026 21:09 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968/11 "2026-01-01T21:09:15Z")

</div>

> [@jbudd](#):
>
> Of course ui-chart passes some overrides. I just wish they were listed somewhere!

I think the best I can do is to point you to [node-red-dashboard/ui/src/widgets/ui-chart/UIChart.vue at main · FlowFuse/node-red-dashboard · GitHub](https://github.com/FlowFuse/node-red-dashboard/blob/main/ui/src/widgets/ui-chart/UIChart.vue). Any overrides should be in there, but it is fairly complex as the values depend on settings in the chart configuration.

---

<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: [2 January 2026 10:19 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968/12 "2026-01-02T10:19:49Z")

</div>

I am wondering whether a Reset Options feature would be a good idea, that says discard all previous chartOptions fed in, and recreate the chart object itself with the existing chart data, so that all options will be reset.

---

<div class="post-metadata">

### Author: ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)
#### Post date: [2 January 2026 10:31 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968/13 "2026-01-02T10:31:59Z")

</div>

It would be very handy while experimenting with options, when there is no available "current set" to view (dev tools just shows "canvas") and if you break it it says broke.

Not much use once you have a working set of options?

---

<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: [1 February 2026 10:32 UTC](https://discourse.nodered.org/t/echarts-options-via-msg-ui-update-not-persistant/99968/14 "2026-02-01T10:32:16Z")

</div>

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