Select your language

The article shows you how to built a simple and cusotomizable viszalization wigh Google Charts that runs in every web browser.

Pre-Requisites

To get started with, you need a running server. I am using my Raspberry Pi and Apache. The details are described here Install Apache and PHP

A CGI script will provide the data for the chharts. Enable your server to work with them here Run CGI Scripts on Apache 2

To keep things simplee is our dataset a simple JSON file with a very limited content that you can find below. Just create a file on the hard drive and give yourself read access.

The first file holds the data for the gauges

{"temperature": 23.0, "humidity": 64.6, "time_code": "Sat May 23 14:50:56 2020"}

A second file will hold the data for the chart

[{"temperature": 23.0, "humidity": 63.0, "time_code": "2020-05-22 00:00:54"}, {"temperature": 23.0, "humidity": 60.0, "time_code": "2020-05-22 00:10:57"}, {"temperature": 23.0, "humidity": 50.0, "time_code": "2020-05-22 00:20:51"}, {"temperature": 23.0, "humidity": 50.0, "time_code": "2020-05-22 00:30:52"}, {"temperature": 20.0, "humidity": 63.0, "time_code": "2020-05-22 00:40:54"}, {"temperature": 20.0, "humidity": 63.0, "time_code": "2020-05-22 00:50:54"}, {"temperature": 20.0, "humidity": 63.0, "time_code": "2020-05-22 01:00:51"}, {"temperature": 23.0, "humidity": 63.0, "time_code": "2020-05-22 01:10:52"}, {"temperature": 23.0, "humidity": 63.0, "time_code": "2020-05-22 01:20:51"}, {"temperature": 23.0, "humidity": 63.0, "time_code": "2020-05-22 01:30:52"}, {"temperature": 23.0, "humidity": 63.0, "time_code": "2020-05-22 01:40:54"}, {"temperature": 23.0, "humidity": 63.0, "time_code": "2020-05-22 01:50:54"}]

HTML Code

I start by creating the website. For starters we keep it simple and minimalistic by only adding a few captions and the three main elements. Two gauges and a chart.

The gauges and charts require some Javascript which follow after the HTML part. The documentation for the Google Chatrs ir pretty extensive, so take your time to make yourself familiar with it.

<!DOCTYPE html>
<html>
<head>
    <title>Page Title</title>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
    <h1 style="text-align:center">HomeDataViewer</h1>
    <table style="width:100%; text-align:center">
        <tr>
            <th colspan="2">Wohnzimmer</th>
        </tr>
        <tr>
            <td id="chart1_div" style="align: center; display: inline-block; margin: 0 auto"></td>
            <td id="chart2_div" style="align: center; display: inline-block; margin: 0 auto"></td>
        </tr>
        <tr>
            <td id="curve_chart" style="align: center; display: inline-block; margin: 0 auto" colspan="2"></td>
        </tr>
    </table>
</body>
</html>

<script type="text/javascript">

//<![CDATA[
    google.charts.load('current', { 'packages': ['gauge'] });
    google.charts.setOnLoadCallback(drawGaugeChart);

    function drawGaugeChart() {        

        var myData1 = $.ajax({
            url: "/cgi-bin/getCurTemp.py",
            dataType: "json",
            async: false
        }).responseText;      

        var myData2 = $.ajax({
            url: "/cgi-bin/getCurHumidity.py",
            dataType: "json",
            async: false
        }).responseText;

        var currentTemp = new google.visualization.DataTable(myData1);
        var currentHum = new google.visualization.DataTable(myData2);

        var optionsTemp = {
            width: 600, height: 180,
            redFrom: 30, redTo: 40,
            yellowFrom: 26, yellowTo: 30,
            greenFrom: 18, greenTo: 26,
            minorTicks: 5,
            min: 15,
            max: 40
        };

        var optionsHum = {
            width: 600, height: 180,
            redFrom: 70, redTo: 90,
            yellowFrom: 60, yellowTo: 70,
            greenFrom: 30, greenTo: 60,
            minorTicks: 5,
            min: 20, 
            max: 90
        };

        var chart1 = new google.visualization.Gauge(document.getElementById('chart1_div'));
        var chart2 = new google.visualization.Gauge(document.getElementById('chart2_div'));

        chart1.draw(currentTemp, optionsTemp);
        chart2.draw(currentHum, optionsHum);
    }

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

    function drawLineChart() {

        var myData = $.ajax({
            url: "/cgi-bin/graph_cgi.py",
            dataType: "json",
            async: false
        }).responseText;

        var data = new google.visualization.DataTable(myData);
        var options = {
            chart:{
                title: 'Humidity & Temperature'
            },
            width: 900,
            height: 400,
            series:{
                0: {axis: 'Temperature', color: 'red'},
                1: {axis: 'Humidity', color: 'blue'}
            },
            axes: {
                y:{
                Temperature: {label: 'Temperature'},
                Humidity: {label: 'Humidity'}
            }
            },
            hAxes: {
                format: 'E, HH:mm',
                gridlines: {count: 4}
                },
            legend: {position: 'none'}
        };

        var chart = new google.charts.Line(document.getElementById('curve_chart'));

        chart.draw(data, google.charts.Line.convertOptions(options));
    }

  //]]></script>

The CGI Scripts

The Java scripts will call three Python scripts which are programmed now.

getCurTemp.py

The script reads the JSON file and converts the data into the DataTable format which is requested by tha Google Charts.

#!/usr/bin/env python

import json
from datetime import datetime
from time import strftime, strptime

timestamp = []
temperature = []
cold = []
rows = []

#construct cols for DataTable
col1={'label':'Description', 'type':'string'}
col2={'label':'Temperature', 'type':'number'}
cols = [col1, col2]

with open('PfadZurDateiMitDenAktuellenDaten', 'r') as read_file:
    data = json.load(read_file)
    
    r1 = {'v': 'Temperature'}
    r2 = {'v': float(data['temperature'])}
    c = {'c': [r1, r2]}
    rows.append(c)

data = {'cols': cols, 'rows': rows}
json_data = json.dumps(data)

print('Content-type: application/json; charset=utf-8\n')
print(json_data)

 

getCurHumidity.py

The same script is taken to deal with getting the humidity.

#!/usr/bin/env python

import json

timestamp = []
humidity = []
cold = []
rows = []

#construct cols for DataTable
col1={'label':'Description', 'type':'string'}
col2={'label':'humidity', 'type':'number'}
cols = [col1, col2]

with open('PfadZurDateiMitDenAktuellenWerten', 'r') as read_file:
    data = json.load(read_file)
    
    r1 = {'v': 'Humidity'}
    r2 = {'v': float(data['humidity'])}
    c = {'c': [r1, r2]}
    rows.append(c)

data = {'cols': cols, 'rows': rows}
json_data = json.dumps(data)

print('Content-type: application/json; charset=utf-8\n')
print(json_data)

 

graph.py

The data for the graph is fed with basically the same DataTable format. The extra code in the script is necesary to convert the data from the JSON file into the order which is requestd by the Google Charts.

#!/usr/bin/env python

import json
from datetime import datetime
from time import strftime, strptime

timestamp = []
temperature = []
humidity = []
cold = []
rows = []

#construct cols for DataTable
col1={'label':'Timestamp', 'type':'date'}
col2={'label':'Temperature', 'type':'number'}
col3={'label':'Humidity', 'type':'number'}
cols = [col1, col2, col3]

with open('PfadZurDateiMitDenVerläufen', 'r') as read_file:
    data = json.load(read_file)
    for index in data:
        
        #construct date string representation. Note January is 0 in date string but 1 in datetime object returned by strptime
        time = strptime(index['time_code'],'%Y-%m-%d %H:%M:%S')
        timeToStr = '{}, {}, {}, {}, {}, {}'.format(time.tm_year, time.tm_mon - 1, time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec)

        r1 = {'v': 'Date({})'.format(timeToStr)}
        r2 = {'v': float(index['temperature'])}
        r3 = {'v': float(index['humidity'])}
        c = {'c': [r1, r2, r3]}
        rows.append(c)

data = {'cols': cols, 'rows': rows}
json_data = json.dumps(data)

print('Content-type: application/json; charset=utf-8\n')
print(json_data)

Thats it. From now on can you read your data with your smartphone from anywhere.

Sonstiges

All details about the Google Charts are here: https://developers.google.com/chart