How to load date[] from the Apex chart with msg.payload?

Hello, everyone! I'm starting in node-red and trying to load the msg.payload data inside the apex chart, but to no avail. Grateful

index.html

<!doctype html>
<html lang="en">
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
    
        <title>ApexChart/VueJS Example - Node-RED UI Builder</title>
        <meta name="description" content="Node-RED UI Builder - ApexChart/VueJS Example">
    
        <link rel="icon" href="./images/node-blue.ico">
    
        <link type="text/css" rel="stylesheet" href="../uibuilder/vendor/bootstrap/dist/css/bootstrap.min.css" />
        <link type="text/css" rel="stylesheet" href="../uibuilder/vendor/bootstrap-vue/dist/bootstrap-vue.css" />
    
        <link rel="stylesheet" href="./index.css" media="all">
    </head>

    <body>
        <div id="app">
            <b-container id="app_container">
                <h1>
                    Examples of using <a href="https://apexcharts.com/docs/vue-charts/" target="_blank">ApexChart</a>
                    with uibuilder, VueJS and bootstrap-vue
                </h1>
                <b-row>
                    <b-card col class="w-50" header="Line Chart" border-variant="primary" header-bg-variant="primary" header-text-variant="white" align="center">
                        <apexchart width="100%" type="line" :options="options" :series="series"></apexchart>
                    </b-card>
                </b-row>
            </b-container>
        </div>
    
        <script src="../uibuilder/vendor/socket.io/socket.io.js"></script>
        <script src="../uibuilder/vendor/vue/dist/vue.min.js"></script>
        <script src="../uibuilder/vendor/bootstrap-vue/dist/bootstrap-vue.js"></script>
    
        <!-- Loading from CDN, use uibuilder to install packages and change to vendor links -->
        <script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
        <script src="https://cdn.jsdelivr.net/npm/vue-apexcharts"></script>
    
        <script src="./uibuilderfe.min.js"></script> <!--    //prod version -->
        <script src="./index.js"></script>
    
    </body>
</html>

index.js

/* jshint browser: true, esversion: 5 */
/* globals document,Vue,window,uibuilder,VueApexCharts */
'use strict'

/** Reference the apexchart component (removes need for a build step) */
Vue.component('apexchart', VueApexCharts)

// eslint-disable-next-line no-unused-vars
var app1 = new Vue({
    el: '#app',
    data: {
        startMsg    : 'Vue has started, waiting for messages',

        options: {
            chart: {
                id: 'vuechart-example'
            },
            xaxis: {
                type: 'datetime',
                labels: {
                    format: 'yyyy-MM-dd HH:mm',
                }
            }       
        },
        
        series: [{
                name: "Temperatura",
                data: [],
        }], 
    }, // --- End of data --- //
    
    computed: {
    }, // --- End of computed --- //
    
    methods: {
    }, // --- End of methods --- //

    mounted: function(){
        uibuilder.start()
        var vueApp = this

        uibuilder.onChange('msg', function (msg) {
            Vue.set(vueApp.series, 0, {'data': msg.payload})
            //vueApp.series[0].data = msg.payload
            console.log('SERIES: ', vueApp.series)
        })

    } // --- End of mounted hook --- //

}) // --- End of app1 --- //

// EOF

Hello JĂ´natan,

Would it be possible to also share a sample message of the data that you are trying to plot with Apexchart ?

If you wire an Inject node to your uibuilder node with a msg.payload for example

[
    {
        "x": "02-10-2017 GMT",
        "y": 34
    },
    {
        "x": "02-11-2017 GMT",
        "y": 43
    },
    {
        "x": "02-12-2017 GMT",
        "y": 31
    },
    {
        "x": "02-13-2017 GMT",
        "y": 43
    },
    {
        "x": "02-14-2017 GMT",
        "y": 33
    },
    {
        "x": "02-15-2017 GMT",
        "y": 52
    }
]

You can receive it in the front-end and update series of the chart with

 uibuilder.onChange("msg", function(msg) {
      console.log("msg received from Node-red:", msg);
      vueApp.series = [{ name: "Temperatura", data: msg.payload }];
    });
1 Like

@UnborN. grateful for the willingness

I want to get only one given and then get the moisture
{"STAMP":"2021-12-02 15:08:17","TEMPERATURA":22.79,"UMIDADE":38.66}

Sem tĂ­tulo

The graph looks like this
image

You need to restructure your data to match what the Apexchart expects
Here is an example of how you could do it with Javascript in a Function node

[{"id":"8f698af8e2d11e60","type":"inject","z":"54efb553244c241f","name":"data","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"STAMP\":\"2021-12-02 15:08:17\",\"TEMPERATURA\":23.79,\"UMIDADE\":38.66},{\"STAMP\":\"2021-12-02 15:09:11\",\"TEMPERATURA\":25.79,\"UMIDADE\":36.66},{\"STAMP\":\"2021-12-02 15:10:13\",\"TEMPERATURA\":22.79,\"UMIDADE\":33.66},{\"STAMP\":\"2021-12-02 15:11:00\",\"TEMPERATURA\":28.79,\"UMIDADE\":35.66}]","payloadType":"json","x":290,"y":840,"wires":[["ce68b58e7943c968","c36af59b10129de8"]]},{"id":"a3b0746a3db510ed","type":"debug","z":"54efb553244c241f","name":"to uibuilder","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":710,"y":840,"wires":[]},{"id":"ce68b58e7943c968","type":"function","z":"54efb553244c241f","name":"prepare chart data","func":"\nlet temp = msg.payload.map(el => {\n    return { x: el.STAMP, y: el.TEMPERATURA }\n})\n\n\nlet hum = msg.payload.map(el => {\n    return { x: el.STAMP, y: el.UMIDADE }\n})\n\nmsg.payload = [{ name: \"Temperatura\", data: temp }, { name: \"Umidade\", data: hum },]\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":840,"wires":[["a3b0746a3db510ed"]]},{"id":"c36af59b10129de8","type":"debug","z":"54efb553244c241f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":410,"y":780,"wires":[]}]

And the following changes for the front end

uibuilder.onChange("msg", function(msg) {
      console.log("msg received from Node-red:", msg);
      vueApp.series = msg.payload ;
    });
2 Likes
 series: [{
                name: "Temperatura",
                data: [],
        }], 

Does that stretch still keep it?

Thank you very much for the reply, I will explore further the resources from now on

you could define series in the Vue data as an empty array initially series: [],
the actual values are assigned when you receive the msg from Node-red with
vueApp.series = msg.payload;

That's what I did and it worked :slight_smile:

If I put the index.html and the index.js within a ui_template, will it work the same way?

not that i know of ... uibuilder has its own node .. it creates its own url endpoints and its own logic to accept messages.

perfect. :wink:

I put ui_template a ui_frame, but I can't adjust the sizes to 100%

Brush chart – ApexCharts.js

Next step is to increment this type of selection

I dont know .. using a modern browser like Chrome or Firefox, inspect with its developer tools the html to see what is constraining it. Is it the iframe size ?
From the original code you shared try to remove the
<b-container id="app_container">
and set the card surrounding the chart to width 100 instead of 50
<b-card col class="w-100"

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