Friday, May 13, 2022

Gauges and Linecharts in Javascript

For an index to all my stories click this text

As we have seen with cloud based IOT services like Thingspeak and IoTtweet it is easy to have a graphical representation of the data of your sensors. With Thingspeak you can create bar-charts and gauges for visualisation of your data. And you can do the same with IoTtweet. We have been using these in previous stories and adressing them in ESP-Basic. You can find the weblog entry about Thingspeak here:
http://lucstechblog.blogspot.com/2017/11/thingspeak.html
And about IoTtweet I wrote two stories which you can find in the next links:
http://lucstechblog.blogspot.com/2019/10/iottweet-part-1.html
http://lucstechblog.blogspot.com/2019/11/iottweet-part-2.html

Maybe you do not want to send your data to the cloud for privacy reasons, or you do not need to access the data from all over the world and just want a nice visualisation of the data from within your own network. Well that is possible. I am going to show you how to build a webpage with the ESP32 that has gauges and/or line charts made with data from your sensors. And then you can access that webpage from within your network. To achieve this you need to combine C++ (arduino language) with Javascript.

Javascript.

Every web-browser has a standard built-in programming language which is Javascript. And almost any modern web-page has Javascript programs running to perform tasks like acting on button-presses etc. The fun part is that anyone with a plain text-editor like Notepad or Wordpad which are standard supplied with Windows can start programming. If you have never paid any attention to Javascript before I urge you to do so, as it is easy to learn and fun to play with.

Javascript is the motor that is going to put the gauges and line-charts on our web-page. Don't worry if you have no Javascript experience. I am going to do this the easy way.

Gauges

Searching the web you will find many Javascript libraries that can put gauges on a web-page. I will show you two different ones that are very easy to use and can easily be adapted for use with the ESP8266 and ESP32 for IOT purposes.



The gauge you see here is made with Google Charts. This is a free to use service from Google which brings you a great many different charts which you can incorporate on your website. To use Google Charts your Javascript program needs to download a library from the web to display the charts. You can find details on Google Charts on their website:
https://developers.google.com/chart

Linecharts

A Gauge just displays a value at a certain moment, like what is the temperature at this moment. When the data changes the Gauges pointer moves and the old value is forgotten. With a line chart you can get a historical view of the data.



The linechart is also made with Google Charts. This is the same library with which the Gauge was made.

Javascript code

Before we are going to bring the Gauges and Linecharts to the ESP8266 and ESP32 I am going to show you how the Javascript code works. Study this code and then porting it to the ESP32 will be easy.

You can learn Javascript by following all kinds of tutorials on the web. Lots of them are free and I give you here two possibilities. If you want to learn it by self-study on your own pace with lots of examples and excercises you can do that at the W3schools website in the Javascript section:
https://www.w3schools.com/js/default.asp
Another option is to study Javascript at EDX. Here you find multiple courses on Javascript. This is a more -school-like approach with a teacher that gives lectures and then you need to do some excercises. You can follow the classes for free. After I had already devellopped some Android Apps myself I decided to follow EDX courses on Mits App-Inventor to build Android Apps and I can recommend it. I learned some neat tricks there. You can find EDX's Javascript courses here: https://www.edx.org/course?search_query=javascript

Javascript Gauge

I am going to show you how to build a HTML page that displays a Gauge and a button. Everytime you press the button the Gauge displays a new random figure which represents the temperature. The Gauge is build with the Google Charts library. The Javascript program generates a new random figure and produces the Gauge.



If you want to try this code copy it and paste it in the notebook editor. Then save it as Gauge.HTML in a folder on your computer.
Opening the folder will show you a webpage with the HTML file Gauge. Click on it and your browser will open displaying the Gauge. Press the button and see the value change.


<html>
 <head>
 </head>
 <body>

  <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  <script type="text/javascript">
    google.charts.load('current', {'packages':['gauge']});
    google.charts.setOnLoadCallback(drawGauge);

    var gaugeOptions = {min: -5, max: 50, yellowFrom: 18, yellowTo: 24,
        redFrom: 24, redTo: 50, minorTicks: 10};

    function drawGauge() 
    {
      gaugeData = new google.visualization.DataTable();
      gaugeData.addColumn('number', 'Deg. C');
      gaugeData.addRows(1);
      gaugeData.setCell(0, 0, 19);
      gauge = new google.visualization.Gauge(document.getElementById('gauge_div'));
      gauge.draw(gaugeData, gaugeOptions);
    }

    function changeTemp() 
    {
      gaugeData.setValue(0, 0, Math.round(Math.random()*50));
      gauge.draw(gaugeData, gaugeOptions);
    }
  </script>


  <div id="gauge_div" style="width:560px; height: 240px;"></div>
  <input type="button" value="New Value" onclick="changeTemp()" />
 </body>
</html>

Lets have a look at the program so you'll understand how it works.

<html>
 <head>
 </head>
 <body>

Like all webpages this HTML code starts with a header whic is empty in this case and then opens the <body> part. In this the Javascript program will be placed and the objects we need to put the Gauge on the screen.

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

This line tells your browser where to find andload the Javascript charts library.

<script type="text/javascript">

This line tells the browser that the following lines will be another script (Javascript program).

    google.charts.load('current', {'packages':['gauge']});
    google.charts.setOnLoadCallback(drawGauge);

Here we start the library and tell it that we want to use the Gauge function. The second line starts the drawGauge function in which the Gauge is drawn initially on the webpage.

       var gaugeOptions = {min: -5, max: 50, yellowFrom: 18, yellowTo: 24,
        redFrom: 24, redTo: 50, minorTicks: 10}; var gaugeOptions = {min: -5, max: 50, yellowFrom: 18, yellowTo: 24,

This line tells the library that the gauge's scale starts at -5 and ands at 50. This will be the range of degrees Celsius we want to use. Next there will be a yellow marking from 18 to 24 degrees which I consider as a safe zone in which I am comfortable to work in. The red zone goed from 25 to 50 degrees and that is what I definitely consider as to warm. The scale is divided in small steps of 5 after which a larger indicator follows. Alter these to your own liking.

Then the drawGauge() function starts in which the gauge is actually put on the screen.

The Gauge library gets its data out of a table. The table can have many rows and colums and these could be used for pre-defined values. In reality this is part of the overall library and the colums can be filled with multiple data for displaying a line or bar-chart.
in this case only 1 row is used.

      gaugeData.addColumn('number', 'Deg. C');
The first row is filled with initial data. The first column is for numbers (the actual temperature) and the second column is used for the legend which I defined as 'Deg. C'

      gaugeData.addRows(1);
      gaugeData.setCell(0, 0, 19);

A row is added and that row is actually row 0. Row 0 column 9 (first column) is filled with the value 19. The setCell command is the important command that allows us to put or own data in the table. We can achieve that also with setValue which we will use further on in the program.

      gauge = new google.visualization.Gauge(document.getElementById('gauge_div'));
      gauge.draw(gaugeData, gaugeOptions);

These lines make sure that the Gauge is intialised with the Data list we choose (in this case there is only one) and put on the webpage in the pre-defined div (gauge div) using the options for the scale defined in gaugeOptions.

The next function is the changeTemp() function. This will be activated when we press the button which is defined further on.

gaugeData.setValue(0, 0, Math.round(Math.random()*50));

In the changeTemp function the first cell in the table which contains the value of the temperature is changed.

Math.round(Math.random()*50))

This part of that line calculates a new random temperature. Math.random() gives a figure between 0 and 1. So we multiply it by 50 and then round it to an integer.

And that ends the Javascript code.

  <div id="gauge_div" style="width:560px; height: 240px;"></div>
  <input type="button" value="New Value" onclick="changeTemp()" />

The last two things we have to do is to create a place on the webpage where the Gauge will be displayed and this is inside the <div> In this <div> we also define the width and height of the Gauge.
And we need to define a button which calls the function to re-draw the Gauge with a new random value.

That's it.
Just copy the code into your notebook editor. Save it as a non-txt file with the extention html like for example gauge.html and it will turn into a webpage. Click on that and the Gauge will appear in a new browser tab or window.

To port this to an ESP you will need to put this in a webserver and make sure that the formula Math.round(Math.random()*50) is altered in a real sensor reading. This is what we are going to cover in an upcoming story.

Javascript Linechart

As stated above a Gauge only displays the current or last supplied value. Sometimes we want to see some history. That is when a linechart comes in handy.



The linecharts are build by using the same Google Charts library as the Gauge does. So the basics are the same. I'll give you the complete code first.

<html>
<head>
</head>
<body style='background-color:powderblue;'>

    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
      google.charts.load('current', {'packages':['corechart']});
      google.charts.setOnLoadCallback(drawChart);

      function drawChart() 
      {
        var data = google.visualization.arrayToDataTable([
          ['Time' , 'Temp'],
          ['19.00', 15],
          ['19.30', 17],
          ['20.00', 19],
          ['20.30', 19.5],
          ['21.00', 19.5],
          ['21.30', 19.5],
          ['22.00', 19.5],
          ['22.30', 19.5],
          ['23.00', 18],
          ['23.30', 10],
        ]);

        var options = 
        {
          title: 'Mancave temperature',
          legend: { position: 'bottom' },
          width: 600,
          height: 400,
          chartArea: {width: '90%', height: '75%'}
        };
        var chart = new google.visualization.LineChart(document.getElementById('temp_chart'));
        chart.draw(data, options);
      }
    </script>
<br>
<br>
    <div id="temp_chart"></div>
  </body>
</html>

For those that are not familiar with Javascript I'll do an analyses for the most important lines.

<html>
<head>
</head>
<body style='background-color:powderblue;'>

These are the starting lines of almost any webpage. We define that it is build on HTML code. The heading of the page stays empty although you may fill in the ususla credentials. Next the body of the webpage's background color is defined. As ususla I use my favorite which is powderblue.

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

This line tells your browser where to find andload the Javascript charts library.

<script type="text/javascript">

This line tells the browser that the following lines will be another script (Javascript program).

      google.charts.load('current', {'packages':['corechart']});
      google.charts.setOnLoadCallback(drawChart);

Here we start the library and tell it that we want to use the Gauge function. The second line starts the drawGauge function in which the Gauge is drawn on the webpage.

      function drawChart() 
      {
        var data = google.visualization.arrayToDataTable([
          ['Time' , 'Temp'],
          ['19.00', 15],
          ['19.30', 17],
          ['20.00', 19],
          ['20.30', 19.5],
          ['21.00', 19.5],
          ['21.30', 19.5],
          ['22.00', 19.5],
          ['22.30', 19.5],
          ['23.00', 18],
          ['23.30', 10],
        ]);

Then follows the function drawChart() which puts all data we want to display in a table. The first entries called Time and Temp are to be displayed as the legend of the chart. The next entries all define a timestamp and the measured temperature at that time.

As you can see I defined 10 entries (0 to 9). You may add or delete entries as you like. By adding more entries the time indication at the bottom of the chart may get cramped. Widening the screen eand the width of the chart may bring relief but remember that will have an impact on displayi8ng the chart on a mobile phone or tablet.

        var options = 
        {
          title: 'Mancave temperature',
          legend: { position: 'bottom' },
          width: 600,
          height: 400,
          chartArea: {width: '90%', height: '75%'}
        };

I splitted the options out in multiple lines for clarity.
The title of the chart will be "Mancave Temperature" and the name of what we measured (temp) will be placed at the bottom of the chart.
Next the width and height of the chart are defined.
The last line defines how much space the chart will use within the defined area. I used 90% for width and 75% for height. If you do not specify these percentages there will be a lot of whitespace next to the chart.

        var chart = new google.visualization.LineChart(document.getElementById('temp_chart'));
        chart.draw(data, options);

These 2 lines actually put the chart on the webpage and in the <div> with the name "temp_chart"

That concludes the Javascript program.

    <div id="temp_chart"></div>

This last line defines some space on the webpage with the name "temp_chart" in which the chart will be drawn.

That's it.

Again like with the Gauge code, copy this code paste it into a texteditor like Notepad and save it as a non-text file with a name like charts.html
locate the file on your computer and click on it. Your preferred web-browser wil open and a webpage with the line chart will appear.

Altering the charts.

Both the Gauges and the Linechart code have a variable with options in the name (or as the name). Altering this variable can modify the charts in all kinds of ways. You can alter the background, line colors, texts, width and height etc etc etc.
There ate tons of options to play with.

Next to that there are many more types of charts available. Their basic Javascript code for these is the same as the charts I presented you here so altering the code for making barcharts, column charts, donuts, piecharts, histograms etc etc etc should not prove to be all that difficult.

You can find all details here:
https://developers.google.com/chart/interactive/docs/gallery/histogram

Nerxt steps

First I urge you to play around with Javascript. Look for examples on the web and you will be amazed at how much information, tutorials and programs are available. Javascript is easy to learn and you only need a simple text editor and a browser to start building amazing projects. Next to that Javascript web-programs work on your computer, phone and tablet without alterations.

I have done a complete tutorial on building webpages on the ESP line of micro-controllers. Now lets bring the Gauges and charts to the ESP !!! so keep on coming back to see how it's done.

Till tnext time.
Have fun

Luc