Load data to chart in uibuilder

I am testing contrib-uibuilder with Apexcharts but, so far can't load data into a line chart which modified from example uibuilder/wiki/Integrating-ApexCharts I am trying to load the data from inject node set to json output at intervals of 10 seconds. This then loads into uibuilder - I want it to update my chart but it does not.

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



                <b-card col class="w-80" 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-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 */
// @ts-nocheck
/*
  Copyright (c) 2019 Julian Knight (Totally Information)

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/
'use strict'

/** @see https://github.com/TotallyInformation/node-red-contrib-uibuilder/wiki/Front-End-Library---available-properties-and-methods */

/** 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',

        // Data for bar chart
        options: {
            chart: {
                id: 'vuechart-example'
            },

            xaxis: {
            type: 'datetime'
            }

        },
        series: [{
            name: 'series-1',
            data: [[1582672682720,1.3],[1582672743197,1.4],[1582672802656,1.4],[1582672863262,1.5],[1582672922642,1.6],[1582672983224,1.6],[1582673042637,1.6],[1582673103127,1.6],[1582674603470,1.4],[1582674662717,1.3],[1582674723201,1.2],[1582674782700,1.1]]
            }],


    }, // --- End of data --- //
    computed: {
    }, // --- End of computed --- //
    methods: {
    }, // --- End of methods --- //

    // Available hooks: init,mounted,updated,destroyed
    mounted: function(){
        /** **REQUIRED** Start uibuilder comms with Node-RED @since v2.0.0-dev3
         * Pass the namespace and ioPath variables if hosting page is not in the instance root folder
         * e.g. If you get continual `uibuilderfe:ioSetup: SOCKET CONNECT ERROR` error messages.
         * e.g. uibuilder.start('/nr/uib', '/nr/uibuilder/vendor/socket.io') // change to use your paths/names
         */
        uibuilder.start();

        var vueApp = this;

        // Process new messages from Node-RED
        uibuilder.onChange('msg', function (newVal) {
            if ( typeof newVal.payload === 'number' ){
                // Add new element
                vueApp.series.push(newVal.payload);
                // Lose the first element
                vueApp.series.shift();
                //console.log(vueApp.series);
            }
        });

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

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

// EOF

inject node

[{"name":"series-1","data":[[1582672682720,3.3],[1582672743197,3.5],[1582672802656,3.6],[1582672863262,3.8],[1582672922642,4.1],[1582672983224,3.9],[1582673042637,3.8],[1582673103127,3.7],[1582674603470,3.5],[1582674662717,3.3],[1582674723201,3.2],[1582674782700,3.1]]}]

flow

[{"id":"5dbec1b5.a78888","type":"debug","z":"abadcf95.e7cf1","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1590,"y":120,"wires":[]},{"id":"81f1a18a.98316","type":"debug","z":"abadcf95.e7cf1","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1610,"y":180,"wires":[]},{"id":"3a0106a7.8b4cb2","type":"uibuilder","z":"abadcf95.e7cf1","name":"","topic":"","url":"apexchart1","fwdInMessages":false,"allowScripts":false,"allowStyles":false,"copyIndex":true,"showfolder":false,"x":1390,"y":120,"wires":[["5dbec1b5.a78888"],["81f1a18a.98316"]]},{"id":"9c71ad.f9f1365","type":"inject","z":"abadcf95.e7cf1","name":"Inject Data","topic":"","payload":"[{\"name\":\"series-1\",\"data\":[[1582672682720,3.3],[1582672743197,3.5],[1582672802656,3.6],[1582672863262,3.8],[1582672922642,4.1],[1582672983224,3.9],[1582673042637,3.8],[1582673103127,3.7],[1582674603470,3.5],[1582674662717,3.3],[1582674723201,3.2],[1582674782700,3.1]]}]","payloadType":"json","repeat":"10","crontab":"","once":false,"onceDelay":0.1,"x":1170,"y":120,"wires":[["3a0106a7.8b4cb2","1caa4bef.14f384"]]},{"id":"1caa4bef.14f384","type":"debug","z":"abadcf95.e7cf1","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1370,"y":180,"wires":[]}]

Appreciate any thoughts.

Right, so the first problem is that the vueApp.series.push(newVal.payload) is pushing into the wrong place.

I'm assuming that if payload is a number, you want to add that number to the existing series?

If so, you need vueApp.series[0].data.push(newVal.payload). You can see that you are walking down to the first array element of the series data and then selecting the data property and pushing a new array entry to that.

Then, of course, you don't want to delete the series which is what vueApp.series.shift() does because you haven't added a new series, only a new data entry to your existing series. What you might want to do is restrict the series to a maximum number of entries as, if you go too mad, your browser will start to slow down. You might even crash the browser in extreme cases. You will need to experiment with what is a reasonable number. Just remember that there is no point in having more entries that you have pixels to display them.

OK, I think suggested changes are made but still no reaction in chart after inject node fires?

/* jshint browser: true, esversion: 5 */
/* globals document,Vue,window,uibuilder,VueApexCharts */
// @ts-nocheck
/*
  Copyright (c) 2019 Julian Knight (Totally Information)

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/
'use strict';

/** @see https://github.com/TotallyInformation/node-red-contrib-uibuilder/wiki/Front-End-Library---available-properties-and-methods */

/** 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',

        // Data for bar chart
        options: {
            chart: {
                id: 'vuechart-example'
            },

            xaxis: {
            type: 'datetime'
            }

        },
 

        series: [{
            name: 'series',
            data: [[1582672682720,1.3],[1582672743197,1.4],[1582672802656,1.4],[1582672863262,1.5],[1582672922642,1.6],[1582672983224,1.6],[1582673042637,1.6],[1582673103127,1.6],[1582674603470,1.4],[1582674662717,1.3],[1582674723201,1.2],[1582674782700,1.1]]
            }],


    }, // --- End of data --- //
    computed: {
    }, // --- End of computed --- //
    methods: {
    }, // --- End of methods --- //

    // Available hooks: init,mounted,updated,destroyed
    mounted: function(){
        /** **REQUIRED** Start uibuilder comms with Node-RED @since v2.0.0-dev3
         * Pass the namespace and ioPath variables if hosting page is not in the instance root folder
         * e.g. If you get continual `uibuilderfe:ioSetup: SOCKET CONNECT ERROR` error messages.
         * e.g. uibuilder.start('/nr/uib', '/nr/uibuilder/vendor/socket.io') // change to use your paths/names
         */
        uibuilder.start();

        var vueApp = this;

        // Process new messages from Node-RED
        uibuilder.onChange('msg', function (newVal) {
            if ( typeof newVal.payload === 'number' ){
                // Add new element
                vueApp.series[0].data.push(newVal.payload); //<<< new bit
                // vueApp.series.push(newVal.payload);      //<<< old bit
                // Lose the first element
                // vueApp.series.shift();               
                // console.log(vueApp.series);
            }
        });

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

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

// EOF

just wondering if typeof newVal.payload === 'number' should be something like typeof newVal.payload === 'array' ?

Sorry, I didn't actually read the data you were sending, I just went by the code.

The code you have would let you send a new data point to the chart on the existing series.

But actually, you are sending a complete series. So you should add another if statement using a test of Array.isArray(newVal.payload). Inside that if statement, use the original code to replace the existing series with the new one that you've just sent. Unless you want your chart to add new series, in that case you can comment out the shift line.

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