Echarts options via msg.ui_update not persistant

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.


Fig.1 This is what I want (after a msg.ui_update inject)


Fig. 2 This is what happens after a browser refresh

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

[
    {
        "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

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

1 Like

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.

1 Like

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

1 Like

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