This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Google Chart API
#1
Hi everyone,

I've been looking for a way to introduce pie charts and bar graphs to our visualizations. I stumbled on the Google chart API and this example for other platform that uses lua script.

What I'd like to do is to get data from group addresses, send it to the API and present the chart in a frame.

I lack JS and HTML knowledge to understand all this, so any help is welcome.

BR,
A Neves
Reply
#2
You don't need any Lua scripting here, it can be done purely with Custom JavaScript.

Here's a Gauge example:
Code:
$(function(){
  // load chart JS
  $.getScript('https://www.gstatic.com/charts/loader.js', function() {
    google.charts.load('current', {'packages':['gauge']});
    
    google.charts.setOnLoadCallback(function() {
      // create empty element and add it to plan with ID=4
      var el = $('<div></div>').css({
        position: 'absolute',
        width: 200,
        height: 200,
        top: 200,
        left: 200
      }).appendTo('#plan-4');

      // (re)draw gauge on each object update
      grp.listen('32/1/1', function(object) {
        var data = google.visualization.arrayToDataTable([
          ['Label', 'Value'],
          ['Level', object.value]
        ]);

        // gauge options
        var options = {
          width: 200,
          height: 200,
          redFrom: 90,
          yellowFrom: 75,
          yellowTo: 90,
          redTo: 100,
          minorTicks: 5
        };

        var chart = new google.visualization.Gauge(el.get(0));
        chart.draw(data, options);
      });
    });
  });
});
Reply
#3
Thank you admin. This works just like I needed to.

How can I pass an array from a script to the custom JS? I'm thinking in combine Google charts with this example:

http://www.openrb.com/docs/trends-new.htm

Or simply creating a table like this and call it in JS:

Code:
kwh_lights = grp.getvalue('1/1/33')
kwh_sockets = grp.getvalue('1/1/53')
kwh_AC = grp.getvalue('1/1/73')
kwh_garden =  grp.getvalue('1/1/93')

energy_pie={{'Label', 'Value'},
           {'Lights', kwh_lights},
         {'Sockets', kwh_sockets},
           {'AC', kwh_AC },
            {'Garden', kwh_garden }
           }

log(energy_pie)

BR,
A Neves
Reply
#4
For smaller arrays you can use a virtual object with 250-byte string data type and put data converted via json.encode. For larger arrays you will need to create a sepearate .lp file that will output resulting data array.
Reply
#5
Unfortunately I don't know how to work with .lp files. Can you provide me an example, please?
Reply
#6
Docs on how to upload .lp files:
https://forum.logicmachine.net/showthread.php?tid=85

.lp file is a Lua script which is accessible from HTTP. Here's a minimal example that outputs data in JSON format:
Code:
<?
data = { 1, 2, 3 }
print(json.encode(data))

Then, in Custom JavaScript you can load data from .lp like this (in callback function passed to google.charts.setOnLoadCallback). Once data is loaded you can create new chart and draw it.
Code:
$.getJSON('/user/data.lp', function(data) {
  console.log(data);
  // draw chart here
});
Reply
#7
Found this cool:
https://quickchart.io/documentation

give image !
-----------
FRANCE SMARTHOME & SMARTBUILDING INTEGRATION
SE ECO EXPERT
Reply
#8
(17.05.2018, 12:28)admin Wrote: You don't need any Lua scripting here, it can be done purely with Custom JavaScript.

Here's a Gauge example:
Code:
$(function(){
  // load chart JS
  $.getScript('https://www.gstatic.com/charts/loader.js', function() {
    google.charts.load('current', {'packages':['gauge']});
    
    google.charts.setOnLoadCallback(function() {
      // create empty element and add it to plan with ID=4
      var el = $('<div></div>').css({
        position: 'absolute',
        width: 200,
        height: 200,
        top: 200,
        left: 200
      }).appendTo('#plan-4');

      // (re)draw gauge on each object update
      grp.listen('32/1/1', function(object) {
        var data = google.visualization.arrayToDataTable([
          ['Label', 'Value'],
          ['Level', object.value]
        ]);

        // gauge options
        var options = {
          width: 200,
          height: 200,
          redFrom: 90,
          yellowFrom: 75,
          yellowTo: 90,
          redTo: 100,
          minorTicks: 5
        };

        var chart = new google.visualization.Gauge(el.get(0));
        chart.draw(data, options);
      });
    });
  });
});

Hi,

I'm trying this function...but I have a doubt. What is the empty element that I must put in PLAN ? And where Can I found the plan ID ?

Regards,
Alberto
KNX Advanced Partner + Tutor
Reply
#9
Plan ID can be found by selecting your plan and then click quick view
   
Then in the new opened window you will see plan ID after the # in the url
   
You should see something like that in final visu
   
Your LM must have internet connection for this to work.
------------------------------
Ctrl+F5
Reply
#10
Great !! thanks Daniel !!

My doubt was for an "empty element". Now I understand that it was only to see the page (create a botton with empty image).

BR,
Alberto
KNX Advanced Partner + Tutor
Reply
#11
Hello, I am trying to implement the use of surplus photovoltaic energy taking into account the weather and radiation forecast. Now I am trying to tune the algorithm, plotting with google charts some info. I am able to plot different values, but I am not able to solve two issues

- With several plots, tooltip is only visible in the first #plan. Exchanging from one #plan to the other, the one that wasn't working now works, and vice versa.

- there is differenci if I access to the plan from home page or directly from specific url, i.e. http://192.168.0.10/scada-vis/#21. now the information lixe axes title and legend

I attach a snapshot of plan21, whose has the first chart, the tooltip works properly but not the info like legend. I draw the cursor by hand Smile 

[Image: kFCwn6T.jpg]
The #plan24 has not work the tooltip

[Image: wCNiCGP.jpg]
Changing the plot form #plan24 to #plan21 tooltips work well. And if I load 192.168.0.10/scada-vis/#21 the information like legend, it is showed

[Image: CzQLVaW.jpg]

The javascript used:
Code:
$(function(){
  // load chart JS
  $.getScript('https://www.gstatic.com/charts/loader.js', function() {
   
    google.charts.load('current', {'packages':['gauge', 'corechart'],language: 'es'});
 
    google.charts.setOnLoadCallback(drawSolcast);
    google.charts.setOnLoadCallback(drawGraphBC);

    //------------------------------------------------------------------------------------------------
    //-- plan21, graph consumo BC
    //--- 
    function drawGraphBC() { 

      // create empty element and add it to plan with ID=21
      var graphEl = $('<div></div>').css({
        position: 'absolute',
        width: 1000, height: 350,
        top: 20,  left: 20
      }).appendTo('#plan-21');

      $.getJSON('/user/energia.lp', function(jsonData) {
        console.log(jsonData);

        var data4 = new google.visualization.arrayToDataTable(jsonData);
    
        var opt4 = { title: 'Calefacción / ACS' ,
          width: 1000, height: 350,
          // Gives each series an axis that matches the vAxes number below.
          focusTarget: 'category', 
          seriesType: 'bars',
          series: {
            0: {targetAxisIndex: 0, areaOpacity: 1, lineWidth: 1},
            1: {targetAxisIndex: 0, areaOpacity: 1, lineWidth: 1},
            2: {targetAxisIndex: 1, areaOpacity: 0, visibleInLegend: false, type: 'line'}
          } ,
          vAxes: {
            // Adds titles to each axis.
            0: {title: 'Potencia [kW]', viewWindow: {min: 0, max:2500} },
            1: { title: 'COP', gridlines: { interval: [ 1, 2, 3, 4, 5, 6 ] },
                viewWindow: {min: 1, max: 6}, gridlines: { count: 0} }
          }
        };
        var chart4 = new google.visualization.ComboChart(graphEl.get(0));
        chart4.draw(data4, opt4);
      }); //getJSON
    }; //drawWCons   

    //------------------------------------------------------------------------------------------------
    //-- plan24, grafica weather
    //---
    function drawSolcast() { 
      // create empty element and add it to plan with ID=24
      var graphSol = $('<div></div>').css({
        position: 'absolute',
        width: 1000, height: 350,
        top: 400, left: 20,
        border: 'solid'
      }).appendTo('#plan-21');
     
      $.getJSON('/user/sol2graph.lp', function(jsonObj) {
        console.log(jsonObj);

        var data5 = new google.visualization.DataTable();
        data5.addColumn('date', 'fecha');
        data5.addColumn('number', "pv_estimate");
        data5.addColumn('number', "kWh/dia");
       
          // a formato tiempo
        for (var i = 0; i < jsonObj.length; i++) {
          jsonObj[i][0] = new Date( jsonObj[i][0] * 1000);
        }
     
        data5.addRows(jsonObj);
       
        var tickMarks = [];
        var hoy = new Date()
        for (var i = 0; i < 7; i++) {
          tickMarks.push(new Date(hoy.getTime() + i*24*60*60*1000));
        }              
       
        var opt5 = { title: 'Pv kWh' ,
          width: 1000, height: 350,
          chartArea: {width: '90%', height: '80%'},
          focusTarget: 'category', 
          seriesType: 'lines',
          hAxis: {
            format: 'EE, d MMM',
            gridlines: { count: 7},
            ticks: tickMarks
          }, 
          series: {
            0: {targetAxisIndex: 0, areaOpacity: 1, lineWidth: 1},
            1: {targetAxisIndex: 1, areaOpacity: 0.2, lineWidth: 1, type: 'area', color: '#f1ca3a' }
          },
          vAxes: {
            // Adds titles to each axis.
            0: {title: '[kW]', viewWindow: {min: 0, max:3.5}, gridlines: {interval: [ 0.5, 1, 1.5, 2, 2.5, 3 ] }},
            1: { viewWindow: {min: 0, max: 70}, gridlines: { count: 0}, ticks: [ ] }
          }
        };
       
        var date_formatter = new google.visualization.DateFormat({ pattern: 'dd MMM, HH:mm' });
        date_formatter.format(data5, 0);
       
        var chart5 = new google.visualization.ComboChart(graphSol.get(0));
          
         
        chart5.draw(data5, opt5);

      }); //getJSON
    }; //drawSolcast   
  
   
  }); // getscript
});


Any help is welcome, thanks

Jose
--
Reply
#12
The problem is that chart does not render properly when it's drawn in a hidden element (plan).
You can listen to the "showplan" event and draw charts only when the containing plan becomes visible like this:
Code:
google.charts.load('current', {'packages':['gauge', 'corechart'],language: 'es'});
  
    $('body').on('showplan', function(event, id) {
      if (id == 21) {
        google.charts.setOnLoadCallback(drawGraphBC);
      }
      else if (id == 24) {
        google.charts.setOnLoadCallback(drawSolcast);
      }
    }).trigger('showplan', [ currentPlanId ]);
    
    //------------------------------------------------------------------------------------------------
Reply
#13
Thanks Admin for the quick answer, I have added the listener, now the complete information is displayed, like legends. But the tooltip is only available for the first plan, it works in plan#21 but not in plan#24, Do you have any idea what is the origin for this issue? for me tooltips are important to keep the grahps human readable and clean. Thanks again for your support
Reply
#14
It's possible that chart instance can be created multiple times. Use this to create chart only once. I've removed some parts of the code to make it more readable.
Code:
$(function(){
  // load chart JS
  $.getScript('https://www.gstatic.com/charts/loader.js', function() {
    var chart4, chart5;
    
    google.charts.load('current', {'packages':['gauge', 'corechart'],language: 'es'});
  
    
    $('body').on('showplan', function(event, id) {
      if (id == 21) {
        google.charts.setOnLoadCallback(drawGraphBC);
      }
      else if (id == 24) {
        google.charts.setOnLoadCallback(drawSolcast);
      }
    }).trigger('showplan', [ currentPlanId ]);
    

    //------------------------------------------------------------------------------------------------
    //-- plan21, graph consumo BC
    //---  
    function drawGraphBC() {  
      if (!chart4) {
        // create empty element and add it to plan with ID=21
        var graphEl = $('<div></div>').css({
          position: 'absolute',
          width: 1000, height: 350,
          top: 20,  left: 20
        }).appendTo('#plan-21');
        chart4 = new google.visualization.ComboChart(graphEl.get(0));
      }
      
      $.getJSON('/user/data.lp', function(jsonData) {
        var data4 = new google.visualization.arrayToDataTable(jsonData);
        var opt4 = { ... };

        chart4.draw(data4, opt4);
      }); //getJSON
    }; //drawWCons    

    //------------------------------------------------------------------------------------------------
    //-- plan24, grafica weather
    //---
    function drawSolcast() {
      if (!chart5) {
        // create empty element and add it to plan with ID=24
        var graphSol = $('<div></div>').css({
          position: 'absolute',
          width: 1000, height: 350,
          top: 400, left: 20,
          border: 'solid'
        }).appendTo('#plan-24');
        chart5 = new google.visualization.ComboChart(graphSol.get(0));
      }
      
      $.getJSON('/user/data2.lp', function(jsonObj) {
        var data5 = new google.visualization.DataTable();
        var opt5 = { ... };
        var date_formatter = new google.visualization.DateFormat({ pattern: 'dd MMM, HH:mm' });
        date_formatter.format(data5, 0);

        chart5.draw(data5, opt5);
      }); //getJSON
    }; //drawSolcast    
  }); // getscript
});
Reply
#15
Thanks for the help, but it continues without showing the tooltip for the last #plan. It seems that for the other charts, it doesn't know where is the cursor .

I can use other chart library (highcharts ???). I'm a noob, any recommendation is welcome. Is it possible include de libraries in SL "harddisk"?, for not use it in CDN format and avoid script failures by abandoning backward compatibility.
Reply
#16
Hello again, I have found a solution, it is not ideal but it works, for both charts, Google and Highcharts.

Now it works because layout is removed from plan in Vis. structure > Levels/Plans. I said that tooltip works only with the first plan, but it seems that the problem was not the order, if not layout definition

[Image: NsjhqoE.jpg]

If any one want the code for use Highcharts I can upload
Reply
#17
Hi, I know this thread is quite old, but since it's related, I think it's the right place.

I have an script with a json format array saved in a group direction: [["Time","Price"],["0",207.56],["1",202.29],["2",193.04],["3",190.45],["4",193.28],["5",184.3],["6",186.88],["7",222.27],["8",217.72],["9",262.96],["10",265.24],["11",262.25],["12",256.23],["13",209.29],["14",212.33],["15",215.99],["16",219.46],["17",266.98],["18",284.13],["19",293.19],["20",274.91],["21",221.46],["22",214.04]]

I also have the javascript code to make the google's example line graph, but due to my lack of knowledge in JS, I don't know how to pass the array to the line graphic. Could you help me please?
Reply
#18
This thread has several examples that you can use: https://forum.logicmachine.net/showthread.php?tid=4202
You can put your data into storage and retrieve it by using a .lp server-side script.
Reply


Forum Jump: