I have a bit issue in uibuilder or might be my code is wrong

Hi there,
I am trying to save chart settings to Json file
and calling that chart setting also payload data to show in chart
below is flow

[
    {
        "id": "026d68caf9ab771a",
        "type": "group",
        "z": "9f7b1754540bc18d",
        "name": "Example",
        "style": {
            "label": true
        },
        "nodes": [
            "302c0dc43009022d",
            "5d705ad581f69853",
            "028b2478f42b1e48",
            "cc53d48af51b0bbd",
            "b95cb7a5cad37d3d",
            "332f43786d0c6d61",
            "f4847914f639d384",
            "66ad913ee70fac20",
            "1697c436e0f389d1",
            "1bb337592fa7ba62",
            "8ade43c9e768f5dc",
            "19b4b1d6fb485513",
            "94e67937ea9fe050",
            "54f124111665f03c",
            "b4dc095894adb6d4"
        ],
        "x": 74,
        "y": 599,
        "w": 572,
        "h": 382
    },
    {
        "id": "302c0dc43009022d",
        "type": "uibuilder",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "",
        "topic": "",
        "url": "chart",
        "okToGo": true,
        "fwdInMessages": true,
        "allowScripts": false,
        "allowStyles": false,
        "copyIndex": true,
        "templateFolder": "blank",
        "extTemplate": "",
        "showfolder": false,
        "reload": true,
        "sourceFolder": "src",
        "deployedVersion": "7.0.4",
        "showMsgUib": false,
        "title": "",
        "descr": "",
        "editurl": "vscode://vscode-remote/ssh-remote+192.170.26.29/home/pi/.node-red/uibuilder/vue/?windowId=_blank",
        "x": 220,
        "y": 760,
        "wires": [
            [
                "5d705ad581f69853",
                "66ad913ee70fac20"
            ],
            []
        ]
    },
    {
        "id": "5d705ad581f69853",
        "type": "switch",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "Switch on topic",
        "property": "topic",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "loadSettings",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "data",
                "vt": "str"
            }
        ],
        "checkall": "false",
        "repair": false,
        "outputs": 2,
        "x": 200,
        "y": 820,
        "wires": [
            [
                "028b2478f42b1e48"
            ],
            [
                "332f43786d0c6d61"
            ]
        ]
    },
    {
        "id": "028b2478f42b1e48",
        "type": "file in",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "Read Config File",
        "filename": "/home/pi/data/chart_configurations.json",
        "filenameType": "str",
        "format": "utf8",
        "encoding": "none",
        "x": 450,
        "y": 780,
        "wires": [
            [
                "cc53d48af51b0bbd"
            ]
        ]
    },
    {
        "id": "cc53d48af51b0bbd",
        "type": "json",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "Parse JSON",
        "property": "payload",
        "action": "",
        "pretty": false,
        "x": 450,
        "y": 840,
        "wires": [
            [
                "b95cb7a5cad37d3d"
            ]
        ]
    },
    {
        "id": "b95cb7a5cad37d3d",
        "type": "change",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "Set topic to loadSettings",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "loadSettings",
                "tot": "str"
            }
        ],
        "x": 450,
        "y": 900,
        "wires": [
            [
                "1bb337592fa7ba62"
            ]
        ]
    },
    {
        "id": "332f43786d0c6d61",
        "type": "function",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "Generate Data",
        "func": "msg.payload = {\n    \"Front Temp\": Math.floor(Math.random() * 500),\n    \"Middle Temp\": Math.floor(Math.random() * 500),\n    \"Trial Temp\": Math.floor(Math.random() * 500),\n    \"Die Temp\": Math.floor(Math.random() * 500),\n    \"Back Temp\": Math.floor(Math.random() * 500)\n};\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 180,
        "y": 880,
        "wires": [
            [
                "f4847914f639d384"
            ]
        ]
    },
    {
        "id": "f4847914f639d384",
        "type": "change",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "Set topic to data",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "data",
                "tot": "str"
            }
        ],
        "x": 200,
        "y": 940,
        "wires": [
            [
                "1bb337592fa7ba62"
            ]
        ]
    },
    {
        "id": "66ad913ee70fac20",
        "type": "debug",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "debug 10",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 480,
        "y": 720,
        "wires": []
    },
    {
        "id": "1697c436e0f389d1",
        "type": "link in",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "link in 1",
        "links": [
            "1bb337592fa7ba62"
        ],
        "x": 115,
        "y": 760,
        "wires": [
            [
                "302c0dc43009022d"
            ]
        ]
    },
    {
        "id": "1bb337592fa7ba62",
        "type": "link out",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "link out 1",
        "mode": "link",
        "links": [
            "1697c436e0f389d1"
        ],
        "x": 605,
        "y": 940,
        "wires": []
    },
    {
        "id": "8ade43c9e768f5dc",
        "type": "comment",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "index.html",
        "info": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Temperature Charts</title>\n    <link href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css\" rel=\"stylesheet\">\n    <link href=\"./index.css\" rel=\"stylesheet\">\n    <script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script> <!-- Include Chart.js -->\n    <script defer src=\"../uibuilder/uibuilder.iife.min.js\"></script>\n    <script defer src=\"./index.js\"></script>\n</head>\n\n<body>\n    <nav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">\n        <a class=\"navbar-brand\" href=\"#\">Temperature Charts Dashboard</a>\n    </nav>\n\n    <div class=\"container mt-4\">\n        <div id=\"gauges-container\"></div>\n        <div id=\"charts-container\" class=\"row\">\n            <!-- Dynamic charts will be rendered here -->\n        </div>\n    </div>\n</body>\n\n</html>",
        "x": 180,
        "y": 640,
        "wires": []
    },
    {
        "id": "19b4b1d6fb485513",
        "type": "comment",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "index.css",
        "info": "h1 {\n    text-align: center;\n}\n\n#charts-container {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 20px;\n    justify-content: center;\n}\n\n.chart-card {\n    border: 1px solid #ddd;\n    border-radius: 8px;\n    padding: 15px;\n    box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1);\n    background-color: #fff;\n    flex: 1 1 calc(50% - 20px);\n    margin: 10px;\n    max-width: 600px;\n}\n\n@media (max-width: 768px) {\n    .chart-card {\n        flex: 1 1 100%;\n    }\n}\n\ncanvas {\n    width: 100% !important;\n    height: auto !important;\n    display: block;\n}\n\n.chart-card h2 {\n    font-size: 18px;\n    text-align: center;\n    margin-bottom: 10px;\n}\n\n.chart-wrapper {\n    padding: 20px;\n    margin: 10px;\n    border: 1px solid #ddd;\n    border-radius: 10px;\n    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);\n    background-color: #ffffff;\n    height: 300px;\n    width: 46%;\n}\n\n#charts-container {\n    display: flex;\n    flex-wrap: wrap;\n    justify-content: center;\n    gap: 20px;\n}\n\n/* Ensure canvas takes full height of the wrapper */\ncanvas {\n    width: 100%;\n    height: 100% !important;\n    /* Override any other height properties */\n}",
        "x": 180,
        "y": 680,
        "wires": []
    },
    {
        "id": "94e67937ea9fe050",
        "type": "comment",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "index.js",
        "info": "// Initialize uibuilder\nuibuilder.start();\n\n// Hold chart configurations and data\nlet chartConfigurations = [];\nlet chartData = {};\nconst chartInstances = {}; // Store Chart.js instances keyed by chart ID\n\n\ndocument.addEventListener('DOMContentLoaded', () => {\n    // Send the 'loadSettings' message to Node-RED when the page loads\n    uibuilder.send({ topic: 'loadSettings' });\n});\n\nuibuilder.onChange('ioConnected', (connected) => {\n    if (connected) {\n        // Send a message to request loadSettings\n        uibuilder.send({\n            topic: 'loadSettings',\n            payload: 'Requesting settings load on client connect'\n        });\n    }\n});\n\n// Handle messages from uibuilder\nuibuilder.onChange('msg', (msg) => {\n\n    console.log('Message received:', msg);\n\n    // Handle settings load message\n    if (msg.topic === 'loadSettings') {\n        // Check if settings payload is valid and initialize charts\n        if (msg.payload && Array.isArray(msg.payload)) {\n            chartConfigurations = msg.payload;\n            initializeCharts();\n        } else {\n            console.error(\"Settings not found or not in expected format\");\n        }\n    }\n\n    // Handle real-time data message\n    if (msg.topic === 'data') {\n        // Update charts with real-time data\n        updateCharts(msg.payload);\n    }\n});\n\n// Initialize charts based on settings loaded\nfunction initializeCharts() {\n    const chartsContainer = document.getElementById('charts-container');\n    if (!chartsContainer) {\n        console.error('Charts container not found!');\n        return;\n    }\n\n    chartsContainer.innerHTML = ''; // Clear any existing charts\n\n    // Loop through the chart configurations to create charts dynamically\n    if (Array.isArray(chartConfigurations) && chartConfigurations.length > 0) {\n        chartConfigurations.forEach((config, configIndex) => {\n            if (config.payloadNames && Array.isArray(config.payloadNames)) {\n                config.payloadNames.forEach((payloadName, keyIndex) => {\n                    const chartId = `chart-${configIndex}-${keyIndex}`;\n                    const chartWrapper = document.createElement('div');\n                    chartWrapper.className = 'chart-wrapper';\n                    chartWrapper.style.width = '400px';\n                    chartWrapper.style.height = '300px';\n\n                    const chartCanvas = document.createElement('canvas');\n                    chartCanvas.id = chartId;\n                    chartWrapper.appendChild(chartCanvas);\n                    chartsContainer.appendChild(chartWrapper);\n\n                    const ctx = chartCanvas.getContext('2d');\n\n                    const dataset = {\n                        label: payloadName,\n                        data: chartData[payloadName] || [],\n                        borderColor: `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255}, 1)`,\n                        backgroundColor: `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255}, 0.2)`,\n                        borderWidth: 2,\n                    };\n\n                    chartInstances[chartId] = new Chart(ctx, {\n                        type: config.chartType || 'line',\n                        data: {\n                            labels: chartData[payloadName] ? chartData[payloadName].map((_, idx) => `Label ${idx + 1}`) : [],\n                            datasets: [dataset],\n                        },\n                        options: {\n                            responsive: true,\n                            maintainAspectRatio: false,\n                            plugins: {\n                                legend: {\n                                    labels: { color: 'black' },\n                                },\n                                tooltip: {\n                                    callbacks: {\n                                        label: (tooltipItem) => {\n                                            const point = tooltipItem.raw;\n                                            return `${tooltipItem.dataset.label}: ${point}`;\n                                        },\n                                    },\n                                },\n                            },\n                        },\n                    });\n                });\n            }\n        });\n    } else {\n        console.warn('No valid chart configurations found.');\n    }\n}\n\n// Function to update chart (example, replace with your implementation)\nfunction updateChart(settings) {\n    console.log('Updating chart with settings:', settings);\n    // Chart.js or other chart library code to update the chart\n}\n\n// Update the charts dynamically with new data\nfunction updateCharts(payload) {\n    console.log('Updating charts with payload:', payload);\n\n    // Loop through the payload data and update the corresponding charts\n    Object.keys(payload).forEach((key) => {\n        chartConfigurations.forEach((config, configIndex) => {\n            if (config.payloadNames && config.payloadNames.includes(key)) {\n                const chartId = `chart-${configIndex}-${config.payloadNames.indexOf(key)}`;\n                const chart = chartInstances[chartId];\n\n                if (!chart) {\n                    console.warn(`Chart ${chartId} not found.`);\n                    return;\n                }\n\n                // Add a new data point with the timestamp\n                const currentTime = new Date().toLocaleTimeString();\n                chart.data.labels.push(currentTime);\n                chart.data.datasets[0].data.push(payload[key]);\n\n                // Limit to the last 10 data points\n                if (chart.data.labels.length > 10) {\n                    chart.data.labels = chart.data.labels.slice(-10);\n                    chart.data.datasets[0].data = chart.data.datasets[0].data.slice(-10);\n                }\n\n                chart.update();\n            }\n        });\n    });\n}\n",
        "x": 310,
        "y": 640,
        "wires": []
    },
    {
        "id": "54f124111665f03c",
        "type": "comment",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "setting.html",
        "info": "",
        "x": 327,
        "y": 679,
        "wires": []
    },
    {
        "id": "b4dc095894adb6d4",
        "type": "comment",
        "z": "9f7b1754540bc18d",
        "g": "026d68caf9ab771a",
        "name": "setting.js",
        "info": "let chartConfigurations = []; // Store chart configurations globally\nlet lastPayloadKeys = []; // Cache the last payload keys\n\n// Listen for messages from Node-RED via uibuilder\nuibuilder.start();\n\n// Listen for messages from Node-RED to update dropdowns\nuibuilder.onChange('msg', (msg) => {\n    if (msg.payload) {\n        console.log('Payload received:', msg.payload);\n\n        // Parse string payload to JSON if needed\n        if (typeof msg.payload === 'string') {\n            try {\n                msg.payload = JSON.parse(msg.payload);\n            } catch (e) {\n                console.error('Failed to parse payload:', e);\n                return;\n            }\n        }\n\n        if (typeof msg.payload !== 'object') {\n            console.error('Payload is not an object:', msg.payload);\n            return;\n        }\n\n        const payloadKeys = Object.keys(msg.payload);\n\n        // Only update the dropdown if the payload keys have changed\n        if (!arraysEqual(lastPayloadKeys, payloadKeys)) {\n            console.log('Updated payload keys:', payloadKeys);\n            updateAllDropdowns(payloadKeys); // Update dropdowns with new keys\n            lastPayloadKeys = payloadKeys; // Update cached keys\n        }\n    }\n});\n\n// Utility function to compare arrays\nfunction arraysEqual(arr1, arr2) {\n    if (arr1.length !== arr2.length) return false;\n    return arr1.every((value, index) => value === arr2[index]);\n}\n\n// Update all payload dropdowns dynamically\nfunction updateAllDropdowns(payloadKeys) {\n    const dropdowns = document.querySelectorAll('.first-payload-dropdown');\n\n    dropdowns.forEach(dropdown => {\n        dropdown.innerHTML = '<option value=\"\">Select Payload Name</option>'; // Clear existing options\n\n        payloadKeys.forEach((key) => {\n            const option = document.createElement('option');\n            option.value = key;\n            option.textContent = key;\n            dropdown.appendChild(option);\n        });\n    });\n}\n\n// Adds a new chart configuration card\nfunction addChartConfigCard(config = null) {\n    const chartConfigContainer = document.getElementById('chart-config-container');\n    const card = document.createElement('div');\n    card.className = 'card p-3 col-md-4';\n\n    const uniqueId = `config-${Date.now()}`;\n\n    card.innerHTML = `\n        <div class=\"form-group\">\n            <label for=\"chartType-${uniqueId}\">Select Chart Type</label>\n            <select id=\"chartType-${uniqueId}\" class=\"form-control chart-type\">\n                <option value=\"line\">Line</option>\n                <option value=\"bar\">Bar</option>\n                <option value=\"radar\">Radar</option>\n                <option value=\"doughnut\">Doughnut</option>\n                <option value=\"pie\">Pie</option>\n                <option value=\"polarArea\">Polar Area</option>\n                <option value=\"bubble\">Bubble</option>\n                <option value=\"scatter\">Scatter</option>\n            </select>\n        </div>\n        <div class=\"form-group\">\n            <label>Payload Names</label>\n            <div class=\"payload-container\">\n                <select class=\"form-control first-payload-dropdown\">\n                    <option value=\"\">Select Payload Name</option>\n                </select>\n                <button class=\"btn btn-primary btn-sm mt-2\" onclick=\"addPayloadName(this)\">Add Payload</button>\n            </div>\n            <div class=\"added-payloads mt-2\"></div>\n        </div>\n        <button class=\"btn btn-danger mt-2\" onclick=\"removeCard(this)\">Remove Chart</button>\n    `;\n\n    chartConfigContainer.appendChild(card);\n    updateAllDropdowns(lastPayloadKeys); // Populate dropdown with the latest payload keys\n\n    if (config) {\n        const addedPayloads = card.querySelector('.added-payloads');\n        config.payloadNames.forEach(name => addPayloadToList(addedPayloads, name));\n        card.querySelector(`#chartType-${uniqueId}`).value = config.chartType;\n    }\n}\n\n// Add selected payload name\nfunction addPayloadName(button) {\n    const payloadContainer = button.closest('.payload-container');\n    const firstDropdown = payloadContainer.querySelector('.first-payload-dropdown');\n    const selectedPayloadName = firstDropdown.value;\n\n    if (!selectedPayloadName) {\n        alert('Please select a payload name first!');\n        return;\n    }\n\n    const addedPayloads = payloadContainer.nextElementSibling;\n    addPayloadToList(addedPayloads, selectedPayloadName);\n}\n\nfunction addPayloadToList(container, payloadName) {\n    const existingNames = Array.from(container.querySelectorAll('span')).map(span => span.textContent.trim());\n\n    if (existingNames.includes(payloadName)) {\n        alert('Payload name already added.');\n        return;\n    }\n\n    const payloadNameDiv = document.createElement('div');\n    payloadNameDiv.className = 'd-flex align-items-center mb-2';\n\n    payloadNameDiv.innerHTML = `\n        <span class=\"mr-2\">${payloadName}</span>\n        <button class=\"btn btn-danger btn-sm\" onclick=\"removePayloadName(this)\">Delete</button>\n    `;\n\n    container.appendChild(payloadNameDiv);\n}\n\nfunction removeCard(button) {\n    button.parentElement.remove();\n}\n\nfunction removePayloadName(button) {\n    button.parentElement.remove();\n}\n\n\n// Modify the collectConfigurations function to send the chart configurations to Node-RED\nfunction collectConfigurations() {\n    chartConfigurations = [];\n    const cards = document.querySelectorAll('#chart-config-container .card');\n\n    cards.forEach(card => {\n        const chartType = card.querySelector('.chart-type').value;\n        const payloadNames = Array.from(card.querySelectorAll('.added-payloads div span')).map(span => span.textContent.trim());\n\n        if (chartType && payloadNames.length > 0) {\n            chartConfigurations.push({ chartType, payloadNames });\n        }\n    });\n\n    // Send the chart configurations to Node-RED\n    uibuilder.send({\n        topic: 'saveChartConfigurations', // Distinct topic for chart settings\n        payload: chartConfigurations,    // Send only the configurations\n    });\n\n    saveConfigurationsToLocalStorage();\n    alert('Settings saved successfully!');\n}\n\n\n\nfunction saveConfigurationsToLocalStorage() {\n    localStorage.setItem('chartConfigurations', JSON.stringify(chartConfigurations));\n    console.log('Configurations saved:', chartConfigurations);\n}\n\nfunction loadConfigurationsFromLocalStorage() {\n    const savedConfigurations = localStorage.getItem('chartConfigurations');\n    if (savedConfigurations) {\n        chartConfigurations = JSON.parse(savedConfigurations);\n        chartConfigurations.forEach(config => addChartConfigCard(config));\n    }\n}\n\ndocument.addEventListener('DOMContentLoaded', () => {\n    loadConfigurationsFromLocalStorage();\n\n    const saveButton = document.getElementById('save-button');\n    if (saveButton) {\n        saveButton.addEventListener('click', collectConfigurations);\n    }\n\n    const addChartButton = document.getElementById('add-chart-button');\n    if (addChartButton) {\n        addChartButton.addEventListener('click', () => addChartConfigCard());\n    }\n});\n\n",
        "x": 460,
        "y": 640,
        "wires": []
    }
]

I need help in this that when I connect inject it running like hell 1 second and therefore, I have two issues that it loads the settings in 1 second and also data but due to loading setting the data does not show so I need to make it load at once
could anyone help in this issue.

@TotallyInformation
Can you help me

No need to separately ping me - I monitor the uibuilder tag. I will look when I can.

What versions of Node-RED, Node.js and UIBUILDER Are you using? Also what browser?

BTW, you don't need to uibuilder.start() and haven't needed to for quite a while now. Doesn't particularly hurt except to delay starting. Just not needed.

Can you also please share the content of /home/pi/data/chart_configurations.json

You have created a logic loop by making things a little too complex.

You shouldn't be loading your settings in DOMContentLoaded and in ioConnected. Better would be to listen for a client connect uibuilder control message in node-red and send the config then. You wouldn't need to request from the front-end code.

chartWrapper.style.width = '400px';
chartWrapper.style.height = '300px';

Not needed, simply include that in your class. If you want more flexibility, use:

:root {
  --width: 400px;
  --height: 300px;
}
.chart-wrapper {
  ...
  width: var(--width);
  height: var(--height);
}

Then you can easily change the size of the chart with a simple style attribute: style="--width: 50%;".

Also, I recommend training yourself to stop using px measurements for everything - far too many people are still doing that and in doing so, give their pages poor accessibility and usability. Prefer using em or rem for most measures, sometimes % for widths.

@TotallyInformation ,
I got a bit but still I need help regarding how to load setting once only
after seeing flow, you might get to know the issues so please help me with solution

Can you also please share the content of /home/pi/data/chart_configurations.json

This consist the data
[{"chartType":"line","payloadNames":["Front Temp","Middle Temp","Trial Temp","Die Temp"]}]

So here is my adjusted flow.

[{"id":"026d68caf9ab771a","type":"group","z":"3a20af9f0b232322","name":"Example","style":{"label":true},"nodes":["302c0dc43009022d","5d705ad581f69853","b95cb7a5cad37d3d","332f43786d0c6d61","f4847914f639d384","66ad913ee70fac20","1697c436e0f389d1","1bb337592fa7ba62","a4e1e51077a132da","df1a8f6b2377968f","b555cb139f8adb68","b406b5eca2f38ce8"],"x":54,"y":1419,"w":1042,"h":282},{"id":"302c0dc43009022d","type":"uibuilder","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"","topic":"","url":"Jayeshpitale1a","okToGo":true,"fwdInMessages":true,"allowScripts":false,"allowStyles":false,"copyIndex":true,"templateFolder":"blank","extTemplate":"","showfolder":false,"reload":true,"sourceFolder":"src","deployedVersion":"7.2.0","showMsgUib":false,"title":"","descr":"","editurl":"vscode://file/src/uibRoot/Jayeshpitale1a/?windowId=_blank","x":230,"y":1560,"wires":[["66ad913ee70fac20","5d705ad581f69853"],["df1a8f6b2377968f"]]},{"id":"5d705ad581f69853","type":"switch","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"Switch on topic","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"loadSettings","vt":"str"},{"t":"eq","v":"data","vt":"str"}],"checkall":"false","repair":false,"outputs":2,"x":560,"y":1520,"wires":[[],["332f43786d0c6d61"]]},{"id":"b95cb7a5cad37d3d","type":"change","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"Set topic to loadSettings","rules":[{"t":"set","p":"topic","pt":"msg","to":"loadSettings","tot":"str"},{"t":"set","p":"payload","pt":"msg","to":"[{\"chartType\":\"line\",\"payloadNames\":[\"Front Temp\",\"Middle Temp\",\"Trial Temp\",\"Die Temp\"]}]","tot":"json"},{"t":"delete","p":"uibuilderCtrl","pt":"msg"}],"x":770,"y":1600,"wires":[["b555cb139f8adb68","b406b5eca2f38ce8"]]},{"id":"332f43786d0c6d61","type":"function","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"Generate Data","func":"msg.payload = {\n    \"Front Temp\": Math.floor(Math.random() * 500),\n    \"Middle Temp\": Math.floor(Math.random() * 500),\n    \"Trial Temp\": Math.floor(Math.random() * 500),\n    \"Die Temp\": Math.floor(Math.random() * 500),\n    \"Back Temp\": Math.floor(Math.random() * 500)\n};\nreturn msg;","outputs":1,"noerr":0,"x":760,"y":1540,"wires":[["f4847914f639d384"]]},{"id":"f4847914f639d384","type":"change","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"Set topic to data","rules":[{"t":"set","p":"topic","pt":"msg","to":"data","tot":"str"}],"x":940,"y":1540,"wires":[["1bb337592fa7ba62"]]},{"id":"66ad913ee70fac20","type":"debug","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"debug 10","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"","statusType":"counter","x":595,"y":1460,"wires":[],"l":false},{"id":"1697c436e0f389d1","type":"link in","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"link in 1","links":["1bb337592fa7ba62","b406b5eca2f38ce8"],"x":95,"y":1560,"wires":[["302c0dc43009022d"]]},{"id":"1bb337592fa7ba62","type":"link out","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"link out 1","mode":"link","links":["1697c436e0f389d1"],"x":1055,"y":1540,"wires":[]},{"id":"a4e1e51077a132da","type":"debug","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"debug 6","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"","statusType":"counter","x":635,"y":1660,"wires":[],"l":false},{"id":"df1a8f6b2377968f","type":"switch","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"New connect?","property":"uibuilderCtrl","propertyType":"msg","rules":[{"t":"eq","v":"client connect","vt":"str"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":480,"y":1600,"wires":[["b95cb7a5cad37d3d"],["a4e1e51077a132da"]]},{"id":"b555cb139f8adb68","type":"debug","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"debug 7","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"","statusType":"counter","x":935,"y":1660,"wires":[],"l":false},{"id":"b406b5eca2f38ce8","type":"link out","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"link out 11","mode":"link","links":["1697c436e0f389d1"],"x":955,"y":1600,"wires":[]}]

I'm not loading the chart settings from a file just to simplify the example, they are set in the "Set topic to loadSettings" node. "Switch on topic" isn't really needed any more but you might want it if you ever wanted, for example, a button on the page that reloads the settings.

So when a client connects, it is sent the chart settings.

Only change I made to the code was in index.js to remove these:

document.addEventListener('DOMContentLoaded', () => {
    // Send the 'loadSettings' message to Node-RED when the page loads
    uibuilder.send({ topic: 'loadSettings' });
});

uibuilder.onChange('ioConnected', (connected) => {
    if (connected) {
        // Send a message to request loadSettings
        uibuilder.send({
            topic: 'loadSettings',
            payload: 'Requesting settings load on client connect'
        });
    }
});

@TotallyInformation ,
Sorry and leave this I will give you my working code which i used to just save the setting of chart in local storage of browser

[
    {
        "id": "c717f0c636be0829",
        "type": "comment",
        "z": "9f7b1754540bc18d",
        "name": "index.html",
        "info": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Temperature Charts</title>\n    <link href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css\" rel=\"stylesheet\">\n        <link href=\"./index.css\" rel=\"stylesheet\">\n    <script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script> <!-- Include Chart.js -->\n<script defer src=\"../uibuilder/uibuilder.iife.min.js\"></script>\n<script defer src=\"./index.js\"></script>\n</head>\n\n<body>\n    <nav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">\n        <a class=\"navbar-brand\" href=\"#\">Temperature Charts Dashboard</a>\n    </nav>\n\n    <div class=\"container mt-4\">\n        <div id=\"gauges-container\"></div>\n        <div id=\"charts-container\" class=\"row\">\n            <!-- Dynamic charts will be rendered here -->\n        </div>\n    </div>\n</body>\n\n</html>",
        "x": 120,
        "y": 1100,
        "wires": []
    },
    {
        "id": "e43e15dd46f4eb57",
        "type": "comment",
        "z": "9f7b1754540bc18d",
        "name": "index.css",
        "info": "\n\n  h1 {\n      text-align: center;\n  }\n\n  #charts-container {\n      display: flex;\n      flex-wrap: wrap;\n      gap: 20px;\n      justify-content: center;\n  }\n\n  .chart-card {\n      border: 1px solid #ddd;\n      border-radius: 8px;\n      padding: 15px;\n      box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1);\n      background-color: #fff;\n      flex: 1 1 calc(50% - 20px);\n      margin: 10px;\n      max-width: 600px;\n  }\n\n  @media (max-width: 768px) {\n      .chart-card {\n          flex: 1 1 100%;\n      }\n  }\n\n  canvas {\n      width: 100% !important;\n      height: auto !important;\n      display: block;\n  }\n\n  .chart-card h2 {\n      font-size: 18px;\n      text-align: center;\n      margin-bottom: 10px;\n  }\n\n  .chart-wrapper {\n      padding: 20px;\n      margin: 10px;\n      border: 1px solid #ddd;\n      border-radius: 10px;\n      box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);\n      background-color: #ffffff;\n      height: 300px;\n      width: 46%;\n  }\n\n  #charts-container {\n      display: flex;\n      flex-wrap: wrap;\n      justify-content: center;\n      gap: 20px;\n  }\n       \n         /* Ensure canvas takes full height of the wrapper */\n         canvas {\n             width: 100%;\n             height: 100% !important;\n             /* Override any other height properties */\n         }\n",
        "x": 120,
        "y": 1140,
        "wires": []
    },
    {
        "id": "c9a266833d4dfab8",
        "type": "comment",
        "z": "9f7b1754540bc18d",
        "name": "index.js",
        "info": "uibuilder.start();\nlet chartConfigurations = [];\n\n// On page load, load configurations and initialize charts\ndocument.addEventListener('DOMContentLoaded', () => {\n    loadConfigurationsFromLocalStorage(); // Load saved configurations\n    initializeCharts(); // Initialize charts based on loaded configurations\n});\n\n// Handle incoming messages from Node-RED\nuibuilder.onChange('msg', (msg) => {\n    if (msg.payload) {\n        console.log('Received payload:', msg.payload); // Log the received payload\n        updateCharts(msg.payload); // Update charts based on new payload data\n    } else {\n        console.error('No payload received in message.');\n    }\n});\n\n// Load chart configurations from localStorage\nfunction loadConfigurationsFromLocalStorage() {\n    const savedConfigurations = localStorage.getItem('chartConfigurations');\n    if (savedConfigurations) {\n        chartConfigurations = JSON.parse(savedConfigurations); // Parse saved configurations\n        console.log('Loaded chart configurations:', chartConfigurations); // Log to verify configurations\n    } else {\n        console.warn('No chart configurations found in localStorage.');\n    }\n}\n\n// Dynamically create charts based on configurations\nfunction initializeCharts() {\n    const chartsContainer = document.getElementById('charts-container');\n    if (!chartsContainer) {\n        console.error('Charts container not found!');\n        return;\n    }\n\n    chartsContainer.innerHTML = ''; // Clear any existing charts\n\n    if (Array.isArray(chartConfigurations) && chartConfigurations.length > 0) {\n        chartConfigurations.forEach((config, configIndex) => {\n            if (config.payloadNames && Array.isArray(config.payloadNames)) {\n                config.payloadNames.forEach((payloadName, keyIndex) => {\n                    const chartWrapper = document.createElement('div');\n                    chartWrapper.className = 'chart-wrapper';\n\n                    const chartCanvas = document.createElement('canvas');\n                    chartCanvas.id = `chart-${configIndex}-${keyIndex}`;\n                    chartWrapper.appendChild(chartCanvas);\n                    chartsContainer.appendChild(chartWrapper);\n\n                    const ctx = chartCanvas.getContext('2d');\n\n                    const dataset = {\n                        label: payloadName,\n                        data: [], // Empty dataset initially\n                        borderColor: `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255}, 1)`,\n                        backgroundColor: `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255}, 0.2)`,\n                        borderWidth: 2,\n                    };\n\n                    new Chart(ctx, {\n                        type: config.chartType || 'line', // Default to 'line' if no type is provided\n                        data: {\n                            labels: [], // Labels are dynamically updated\n                            datasets: [dataset],\n                        },\n                        options: {\n                            responsive: true,\n                            maintainAspectRatio: false,\n                            plugins: {\n                                legend: {\n                                    labels: {\n                                        color: 'black', // Set legend text color to black\n                                        generateLabels: (chart) => {\n                                            return chart.data.datasets.map((dataset, index) => {\n                                                let lastValue;\n\n                                                // Handle different data types\n                                                if (dataset.data.length > 0) {\n                                                    const lastDataPoint = dataset.data[dataset.data.length - 1];\n\n                                                    if (typeof lastDataPoint === 'object' && lastDataPoint !== null) {\n                                                        // For Scatter/Bubble charts, format the object {x, y, r} or {x, y}\n                                                        const x = lastDataPoint.x !== undefined ? `x: ${lastDataPoint.x}` : '';\n                                                        const y = lastDataPoint.y !== undefined ? `y: ${lastDataPoint.y}` : '';\n                                                        lastValue = `${x}, ${y}`.trim();\n                                                    } else {\n                                                        // For other chart types, use the raw value directly\n                                                        lastValue = lastDataPoint;\n                                                    }\n                                                } else {\n                                                    lastValue = 'N/A'; // Default to 'N/A' if no value exists\n                                                }\n\n                                                return {\n                                                    text: `${dataset.label}: ${lastValue}`,\n                                                    fillStyle: dataset.borderColor, // Use dataset color as fill style\n                                                    fontColor: 'black', // Set text color explicitly to black\n                                                    hidden: !chart.isDatasetVisible(index),\n                                                };\n                                            });\n                                        }\n                                        ,\n                                    },\n                                },\n                                tooltip: {\n                                    callbacks: {\n                                        label: (tooltipItem) => {\n                                            const point = tooltipItem.raw;\n                                            return `${tooltipItem.dataset.label}: ${point}`;\n                                        },\n                                    },\n                                },\n                            },\n                        },\n                    });\n                });\n            }\n        });\n    } else {\n        console.warn('No valid chart configurations found.');\n    }\n}\n\n\n// Update chart data dynamically when new payload is received\nfunction updateCharts(payload) {\n    console.log('Updating charts with new payload:', payload);\n    chartConfigurations.forEach((config, configIndex) => {\n        if (config.payloadNames && Array.isArray(config.payloadNames)) {\n            config.payloadNames.forEach((key, keyIndex) => {\n                const chartId = `chart-${configIndex}-${keyIndex}`;\n                const chart = Chart.getChart(chartId);\n\n                if (!chart) {\n                    console.warn(`Chart ${chartId} not found.`);\n                    return;\n                }\n\n                if (payload[key] !== undefined) {\n                    const currentTime = new Date().toLocaleTimeString();\n\n                    if (config.chartType === 'bubble') {\n                        // For Bubble chart: {x, y, r}\n                        chart.data.datasets[0].data.push({\n                            x: Math.random() * 100, // Example value, replace as needed\n                            y: payload[key],\n                            r: Math.random() * 10 + 5, // Example radius\n                        });\n                    } else if (config.chartType === 'scatter') {\n                        // For Scatter chart: {x, y}\n                        chart.data.datasets[0].data.push({\n                            x: Math.random() * 100, // Example value, replace as needed\n                            y: payload[key],\n                        });\n                    } else {\n                        // For other chart types\n                        chart.data.labels.push(currentTime);\n                        chart.data.datasets[0].data.push(payload[key]);\n                    }\n\n                    // Keep only the last 10 data points\n                    if (chart.data.labels.length > 10) {\n                        chart.data.labels = chart.data.labels.slice(-10);\n                        chart.data.datasets[0].data = chart.data.datasets[0].data.slice(-10);\n                    }\n\n                    chart.update();\n                }\n            });\n        }\n    });\n}\n\n",
        "x": 250,
        "y": 1100,
        "wires": []
    },
    {
        "id": "8c7a84cb60e2efef",
        "type": "comment",
        "z": "9f7b1754540bc18d",
        "name": "setting.html",
        "info": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Chart Settings</title>\n  <link href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css\" rel=\"stylesheet\">\n  <script defer src=\"../uibuilder/uibuilder.iife.min.js\"></script>\n  <script defer src=\"./setting.js\">\n    /* OPTIONAL: Put your custom code in that */\n  </script>  <style>\n    .card {\n      margin-bottom: 1rem;\n    }\n  </style>\n</head>\n\n<body>\n  <nav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">\n    <a class=\"navbar-brand\" href=\"#\">Chart Settings</a>\n  </nav>\n\n  <div class=\"container-fluid mt-3\">\n    <div class=\"row\" id=\"chart-config-container\">\n      <!-- Dynamic chart configuration cards will be added here -->\n    </div>\n    <button class=\"btn btn-success mt-3\" onclick=\"addChartConfigCard()\">Add New Chart Configuration</button>\n<!-- Save Button -->\n<button id=\"save-button\" class=\"btn btn-success\">Save Configurations</button>\n  </div>\n</body>\n\n</html>",
        "x": 267,
        "y": 1139,
        "wires": []
    },
    {
        "id": "3732d1dc3aebbdbb",
        "type": "comment",
        "z": "9f7b1754540bc18d",
        "name": "setting.js",
        "info": "let chartConfigurations = []; // Store chart configurations globally\nlet lastPayloadKeys = []; // Cache the last payload keys\n\n// Listen for messages from Node-RED via uibuilder\nuibuilder.start();\n\n// Listen for messages from Node-RED to update dropdowns\nuibuilder.onChange('msg', (msg) => {\n    if (msg.payload) {\n        console.log('Payload received:', msg.payload);\n\n        // Parse string payload to JSON if needed\n        if (typeof msg.payload === 'string') {\n            try {\n                msg.payload = JSON.parse(msg.payload);\n            } catch (e) {\n                console.error('Failed to parse payload:', e);\n                return;\n            }\n        }\n\n        if (typeof msg.payload !== 'object') {\n            console.error('Payload is not an object:', msg.payload);\n            return;\n        }\n\n        const payloadKeys = Object.keys(msg.payload);\n\n        // Only update the dropdown if the payload keys have changed\n        if (!arraysEqual(lastPayloadKeys, payloadKeys)) {\n            console.log('Updated payload keys:', payloadKeys);\n            updateAllDropdowns(payloadKeys);\n            lastPayloadKeys = payloadKeys; // Update cached keys\n        }\n    }\n});\n\n// Utility function to compare arrays\nfunction arraysEqual(arr1, arr2) {\n    if (arr1.length !== arr2.length) return false;\n    return arr1.every((value, index) => value === arr2[index]);\n}\n\n// Update all payload dropdowns dynamically\nfunction updateAllDropdowns(payloadKeys) {\n    const dropdowns = document.querySelectorAll('.first-payload-dropdown');\n\n    dropdowns.forEach(dropdown => {\n        dropdown.innerHTML = '<option value=\"\">Select Payload Name</option>'; // Clear existing options\n\n        payloadKeys.forEach((key) => {\n            const option = document.createElement('option');\n            option.value = key;\n            option.textContent = key;\n            dropdown.appendChild(option);\n        });\n    });\n}\n\n// Adds a new chart configuration card\nfunction addChartConfigCard(config = null) {\n    const chartConfigContainer = document.getElementById('chart-config-container');\n    const card = document.createElement('div');\n    card.className = 'card p-3 col-md-4';\n\n    const uniqueId = `config-${Date.now()}`;\n\n    card.innerHTML = `\n        <div class=\"form-group\">\n            <label for=\"chartType-${uniqueId}\">Select Chart Type</label>\n            <select id=\"chartType-${uniqueId}\" class=\"form-control chart-type\">\n                <option value=\"line\">Line</option>\n                <option value=\"bar\">Bar</option>\n                <option value=\"radar\">Radar</option>\n                <option value=\"doughnut\">Doughnut</option>\n                <option value=\"pie\">Pie</option>\n                <option value=\"polarArea\">Polar Area</option>\n                <option value=\"bubble\">Bubble</option>\n                <option value=\"scatter\">Scatter</option>\n            </select>\n        </div>\n        <div class=\"form-group\">\n            <label>Payload Names</label>\n            <div class=\"payload-container\">\n                <select class=\"form-control first-payload-dropdown\">\n                    <option value=\"\">Select Payload Name</option>\n                </select>\n                <button class=\"btn btn-primary btn-sm mt-2\" onclick=\"addPayloadName(this)\">Add Payload</button>\n            </div>\n            <div class=\"added-payloads mt-2\"></div>\n        </div>\n        <button class=\"btn btn-danger mt-2\" onclick=\"removeCard(this)\">Remove Chart</button>\n    `;\n\n    chartConfigContainer.appendChild(card);\n    updateAllDropdowns(lastPayloadKeys);\n\n    if (config) {\n        const addedPayloads = card.querySelector('.added-payloads');\n        config.payloadNames.forEach(name => addPayloadToList(addedPayloads, name));\n        card.querySelector(`#chartType-${uniqueId}`).value = config.chartType;\n    }\n}\n\n// Add selected payload name\nfunction addPayloadName(button) {\n    const payloadContainer = button.closest('.payload-container');\n    const firstDropdown = payloadContainer.querySelector('.first-payload-dropdown');\n    const selectedPayloadName = firstDropdown.value;\n\n    if (!selectedPayloadName) {\n        alert('Please select a payload name first!');\n        return;\n    }\n\n    const addedPayloads = payloadContainer.nextElementSibling;\n    addPayloadToList(addedPayloads, selectedPayloadName);\n}\n\nfunction addPayloadToList(container, payloadName) {\n    const existingNames = Array.from(container.querySelectorAll('span')).map(span => span.textContent.trim());\n\n    if (existingNames.includes(payloadName)) {\n        alert('Payload name already added.');\n        return;\n    }\n\n    const payloadNameDiv = document.createElement('div');\n    payloadNameDiv.className = 'd-flex align-items-center mb-2';\n\n    payloadNameDiv.innerHTML = `\n        <span class=\"mr-2\">${payloadName}</span>\n        <button class=\"btn btn-danger btn-sm\" onclick=\"removePayloadName(this)\">Delete</button>\n    `;\n\n    container.appendChild(payloadNameDiv);\n}\n\nfunction removeCard(button) {\n    button.parentElement.remove();\n}\n\nfunction removePayloadName(button) {\n    button.parentElement.remove();\n}\n\nfunction collectConfigurations() {\n    chartConfigurations = [];\n    const cards = document.querySelectorAll('#chart-config-container .card');\n\n    cards.forEach(card => {\n        const chartType = card.querySelector('.chart-type').value;\n        const payloadNames = Array.from(card.querySelectorAll('.added-payloads div span')).map(span => span.textContent.trim());\n\n        if (chartType && payloadNames.length > 0) {\n            chartConfigurations.push({ chartType, payloadNames });\n        }\n    });\n\n    saveConfigurationsToLocalStorage();\n    alert('Settings saved successfully!');\n}\n\nfunction saveConfigurationsToLocalStorage() {\n    localStorage.setItem('chartConfigurations', JSON.stringify(chartConfigurations));\n    console.log('Configurations saved:', chartConfigurations);\n}\n\nfunction loadConfigurationsFromLocalStorage() {\n    const savedConfigurations = localStorage.getItem('chartConfigurations');\n    if (savedConfigurations) {\n        chartConfigurations = JSON.parse(savedConfigurations);\n        chartConfigurations.forEach(config => addChartConfigCard(config));\n    }\n}\n\ndocument.addEventListener('DOMContentLoaded', () => {\n    loadConfigurationsFromLocalStorage();\n\n    const saveButton = document.getElementById('save-button');\n    if (saveButton) {\n        saveButton.addEventListener('click', collectConfigurations);\n    }\n\n    const addChartButton = document.getElementById('add-chart-button');\n    if (addChartButton) {\n        addChartButton.addEventListener('click', () => addChartConfigCard());\n    }\n});\n",
        "x": 400,
        "y": 1100,
        "wires": []
    },
    {
        "id": "57ddf755a6299750",
        "type": "inject",
        "z": "9f7b1754540bc18d",
        "name": "",
        "props": [],
        "repeat": "1",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 130,
        "y": 1200,
        "wires": [
            [
                "1402345c842e2bce"
            ]
        ]
    },
    {
        "id": "1402345c842e2bce",
        "type": "function",
        "z": "9f7b1754540bc18d",
        "name": "function 24",
        "func": "msg.payload = {\n  \"Front Temp\": Math.floor(Math.random() * 500),\n  \"Middle Temp\": Math.floor(Math.random() * 500),\n  \"Trial Temp\": Math.floor(Math.random() * 500),\n  \"Die Temp\": Math.floor(Math.random() * 500),\n  \"Back Temp\": Math.floor(Math.random() * 500)\n};\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 140,
        "y": 1280,
        "wires": [
            [
                "dd0c19aac671d56f"
            ]
        ]
    },
    {
        "id": "dd0c19aac671d56f",
        "type": "uibuilder",
        "z": "9f7b1754540bc18d",
        "name": "",
        "topic": "",
        "url": "egs",
        "okToGo": true,
        "fwdInMessages": true,
        "allowScripts": false,
        "allowStyles": false,
        "copyIndex": true,
        "templateFolder": "blank",
        "extTemplate": "",
        "showfolder": false,
        "reload": true,
        "sourceFolder": "src",
        "deployedVersion": "7.0.4",
        "showMsgUib": false,
        "title": "",
        "descr": "",
        "editurl": "vscode://vscode-remote/ssh-remote+192.170.26.29/home/pi/.node-red/uibuilder/vue/?windowId=_blank",
        "x": 320,
        "y": 1320,
        "wires": [
            [],
            []
        ]
    }
]

you might get the point what i am trying to tell
and I don't want to save it in local storage of browser instead i need to save it in Json if I update the setting it should update in Json File like that I wanted

@TotallyInformation
Could you help me

Remember that most of those here are volunteers helping others in their spare time. Also they may not be in the same time zone as you. To hope for an answer within a couple of hours is not reasonable.

I'm afraid that I don't now get your issue. If you want a way to change the settings, you can either store in a file as you have done or you could store in a context variable. Node-red is largely event driven. So if you want to change the settings, you can do so either from the front-end (and send back to node-red with, lets say a topic of "settings-change") AND/OR from a node-red flow. Either way, you simply need to re-send the data to the front-end , you already have some front-end code to change the settings.

What changes the chart settings?

As I said before and as Colin has also said, please stop pinging me, it won't make me magically appear, I have a day-job, family and other commitments. Rapid support comes with a cost.

Firstly, if you go through example and try to use setting as below is snapshot of it

in first card you can see there i added chart type line and payload names Front temp and Middle Temp this setting are saved in local storage of browser

And if you see the index then you will see this below snapshot

So the issue is that i dont need localstorage setting in this i need to save it in json and if setting gets updated it should override the setting so if you can provide a code that would be great

I appreciate that you and other are helping in this and providing me your precious time
what is the cost by the way

Right, now we are getting somewhere. You've now described the actual issue. That's the first time you've mentioned the settings page.

You want the separate setting.html page to update the chart settings.

You could, of course, do that with a pop-over window on the same page. But leaving that aside, here is the rough flow you need.

I've shown you already how to change the main page to avoid the settings loop and to load the settings on connection.

There were a few coding errors that I corrected. And I turned off the "Forward input msgs to output" advanced uibuilder setting as it just confuses things. I also tidied up the HTML and JS.

In settings.js:

  • Used an onTopic listener to filter out other noise. Renamed the dropdown update fn to make it clear what it actually does. Simplified the button event listeners. Simplified the startup. Corrected some errors.
  • You would also be better using an HTML template tag for the card. The uibuilder client library has an applyTemplate function to make life easy.

.... Sorry, I'm lost in the somewhat convoluted logic now and I've run out of time.

Here's where I got to.

[{"id":"026d68caf9ab771a","type":"group","z":"3a20af9f0b232322","name":"Example","style":{"label":true},"nodes":["302c0dc43009022d","5d705ad581f69853","b95cb7a5cad37d3d","332f43786d0c6d61","f4847914f639d384","66ad913ee70fac20","1697c436e0f389d1","1bb337592fa7ba62","df1a8f6b2377968f","b555cb139f8adb68","b406b5eca2f38ce8","403c6f631b56768d","38d73bcc21013ee8"],"x":14,"y":1419,"w":1042,"h":282},{"id":"302c0dc43009022d","type":"uibuilder","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"","topic":"","url":"Jayeshpitale1a","okToGo":true,"fwdInMessages":false,"allowScripts":false,"allowStyles":false,"copyIndex":true,"templateFolder":"blank","extTemplate":"","showfolder":false,"reload":true,"sourceFolder":"src","deployedVersion":"7.2.0","showMsgUib":false,"title":"","descr":"","editurl":"vscode://file/src/uibRoot/Jayeshpitale1a/?windowId=_blank","x":190,"y":1560,"wires":[["66ad913ee70fac20","5d705ad581f69853"],["df1a8f6b2377968f"]]},{"id":"5d705ad581f69853","type":"switch","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"Switch on topic","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"loadSettings","vt":"str"},{"t":"eq","v":"data","vt":"str"}],"checkall":"false","repair":false,"outputs":2,"x":520,"y":1520,"wires":[[],["332f43786d0c6d61"]]},{"id":"b95cb7a5cad37d3d","type":"change","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"Set topic to loadSettings","rules":[{"t":"set","p":"topic","pt":"msg","to":"loadSettings","tot":"str"},{"t":"set","p":"payload","pt":"msg","to":"[{\"chartType\":\"line\",\"payloadNames\":[\"Front Temp\",\"Middle Temp\",\"Trial Temp\",\"Die Temp\"]}]","tot":"json"},{"t":"delete","p":"uibuilderCtrl","pt":"msg"}],"x":710,"y":1660,"wires":[["b555cb139f8adb68","b406b5eca2f38ce8"]]},{"id":"332f43786d0c6d61","type":"function","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"Generate Data","func":"msg.payload = {\n    \"Front Temp\": Math.floor(Math.random() * 500),\n    \"Middle Temp\": Math.floor(Math.random() * 500),\n    \"Trial Temp\": Math.floor(Math.random() * 500),\n    \"Die Temp\": Math.floor(Math.random() * 500),\n    \"Back Temp\": Math.floor(Math.random() * 500)\n};\nreturn msg;","outputs":1,"noerr":0,"x":720,"y":1540,"wires":[["f4847914f639d384"]]},{"id":"f4847914f639d384","type":"change","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"Set topic to data","rules":[{"t":"set","p":"topic","pt":"msg","to":"data","tot":"str"}],"x":900,"y":1540,"wires":[["1bb337592fa7ba62"]]},{"id":"66ad913ee70fac20","type":"debug","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"debug 10","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"","statusType":"counter","x":555,"y":1460,"wires":[],"l":false},{"id":"1697c436e0f389d1","type":"link in","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"link in 1","links":["1bb337592fa7ba62","b406b5eca2f38ce8"],"x":55,"y":1560,"wires":[["302c0dc43009022d"]]},{"id":"1bb337592fa7ba62","type":"link out","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"link out 1","mode":"link","links":["1697c436e0f389d1"],"x":1015,"y":1540,"wires":[]},{"id":"df1a8f6b2377968f","type":"switch","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"Connect?","property":"uibuilderCtrl","propertyType":"msg","rules":[{"t":"eq","v":"client connect","vt":"str"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":360,"y":1600,"wires":[["403c6f631b56768d"],[]]},{"id":"b555cb139f8adb68","type":"debug","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"debug 7","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"","statusType":"counter","x":895,"y":1660,"wires":[],"l":false},{"id":"b406b5eca2f38ce8","type":"link out","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"link out 11","mode":"link","links":["1697c436e0f389d1"],"x":875,"y":1620,"wires":[]},{"id":"403c6f631b56768d","type":"switch","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"Page?","property":"pageName","propertyType":"msg","rules":[{"t":"eq","v":"setting.html","vt":"str"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":510,"y":1600,"wires":[["38d73bcc21013ee8"],["b95cb7a5cad37d3d"]]},{"id":"38d73bcc21013ee8","type":"function","z":"3a20af9f0b232322","g":"026d68caf9ab771a","name":"init settings","func":"const settingsTemplate = {\n  chartTypes: {\n    'line': 'Line',\n    'bar': 'Bar',\n    'pie': 'Pie',\n  },\n  payloadNames: {\n    front: \"Front Temp\",\n    middle: \"Middle Temp\",\n    trial: \"Trial Temp\",\n    die: \"Die Temp\",\n    back: \"Back Temp\",\n  }\n}\n\nconst newMsg = flow.get('chartSettings') ?? settingsTemplate\n\nnewMsg.topic = 'settings-from-nr'\n\nreturn newMsg\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":690,"y":1600,"wires":[["b406b5eca2f38ce8"]]}]

You don't need to save to a file but you can if you want. I started to add context variable to the init settings fn but it isn't complete. Best to keep the settings in-memory and only load from file when NR starts - you could use persistent context instead.

The body from settings.html - slightly simplified - best not to mix click attributes with event handlers in code. Also give everything important an ID:

<body>
  <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <a class="navbar-brand" href="#">Chart Settings</a>
  </nav>

  <div class="container-fluid mt-3">
    <div class="row" id="chart-config-container">
      <!-- Dynamic chart configuration cards will be added here -->
    </div>

    <button id="new-chart" class="btn btn-success mt-3">Add New Chart Configuration</button>
    <button id="save-button" class="btn btn-success">Save Configurations</button>
  </div>
</body>

Extract from the top of settings.js - I got rid of the on load, it isn't necessary. Also, as previously mentioned, you don't need uibuilder.start().

uib.logLevel = 3;

let chartConfigurations = []; // Store chart configurations globally
let lastPayloadKeys = []; // Cache the last payload keys

$('#save-button').addEventListener('click', collectConfigurations)
$('#new-chart').addEventListener('click', addChartConfigCard)

loadConfigurationsFromLocalStorage()

// Listen for messages from Node-RED to update dropdowns
uibuilder.onTopic('settings-from-nr', (msg) => {    
    const payloadKeys = Object.values(msg.payloadNames)

    console.log('Settings received:', payloadKeys, msg)

    updatePayloadDropdowns(payloadKeys)
})


// Update all payload dropdowns dynamically
function updatePayloadDropdowns(payloadKeys) {
    const dropdowns = document.querySelectorAll('.first-payload-dropdown');

    dropdowns.forEach(dropdown => {
        dropdown.innerHTML = '<option value="">Select Payload Name</option>'; // Clear existing options

        payloadKeys.forEach((key) => {
            const option = document.createElement('option');
            option.value = key;
            option.textContent = key;
            dropdown.appendChild(option);
        });
    });
}

// Adds a new chart configuration card
function addChartConfigCard(config = null) {
    const chartConfigContainer = document.getElementById('chart-config-container');
    const card = document.createElement('div');
    card.className = 'card p-3 col-md-4';

    const uniqueId = `config-${Date.now()}`;

    card.innerHTML = `
        <div class="form-group">
            <label for="chartType-${uniqueId}">Select Chart Type</label>
            <select id="chartType-${uniqueId}" class="form-control chart-type">
                <option value="line">Line</option>
                <option value="bar">Bar</option>
                <option value="radar">Radar</option>
                <option value="doughnut">Doughnut</option>
                <option value="pie">Pie</option>
                <option value="polarArea">Polar Area</option>
                <option value="bubble">Bubble</option>
                <option value="scatter">Scatter</option>
            </select>
        </div>
        <div class="form-group">
            <label>Payload Names</label>
            <div class="payload-container">
                <select class="form-control first-payload-dropdown">
                    <option value="">Select Payload Name</option>
                </select>
                <button class="btn btn-primary btn-sm mt-2" onclick="addPayloadName(this)">Add Payload</button>
            </div>
            <div class="added-payloads mt-2"></div>
        </div>
        <button class="btn btn-danger mt-2" onclick="removeCard(this)">Remove Chart</button>
    `;

    chartConfigContainer.appendChild(card);
    updatePayloadDropdowns(lastPayloadKeys);

    if (config) {
        const addedPayloads = card.querySelector('.added-payloads');
        config.payloadNames.forEach(name => addPayloadToList(addedPayloads, name));
        card.querySelector(`#chartType-${uniqueId}`).value = config.chartType;
    }
}

The code isn't completely working but should give you a steer. In settings.js, I only added processing to update the dropdown options. You need to add any existing cards to that process as well.

The point is to separate the the settings process from the show chart process. In the updated flow that is done with an extra switch node that works off the pageName property on the connect message.

Keep the chart settings in a flow context variable and send that to the main display on load.

You can add improvements:

  • When you get a new settings message from a settings.html page, update the flow variable AND trigger the same flow as a new connection for the main page.
  • in the settings.js, on receipt of a settings message, you should save the settings data immediately to a variable and to local storage. You don't really need an updateDropdown fn, you should simply rebuild all the cards - because on load, there might not be any cards.
  • As mentioned, personally, I probably wouldn't use 2 pages for this, instead I'd have a config icon that toggles an overlay display with the settings.