Blog der Heimetli Software AG

Temperaturverlauf mit Google Charts

Google Charts sind frei verwendbar, sehen ganz gut aus und sind vernünftig konfigurierbar. Der grosse Nachteil: Google registriert jeden Seitenaufruf...

Temperatur

Die Daten vom Server

Der Server liefert die Daten als JSON aus, weil das einfach zu verarbeiten ist.

Das Format für die Zeit ist allerdings bedeppert. Wenn ich frisch anfangen könnte, würde ich die Zeit als Unix-Timestamp darstellen, oder wenigstens in einem String der einfacher zu parsen ist.

[
 {"dt":"25.04.2019 22:19:24","t":9.5},
 {"dt":"25.04.2019 22:26:59","t":9.5},
 {"dt":"25.04.2019 22:32:14","t":9.5}
 .
 .
 .
]

Die beiden Buttons laden die Daten übrigens nicht wieder vom Server. Sie passen nur den View auf die DataTable an.

Das Script auf dieser Seite

var chart = null ;
var data  = null ;
var view  = null ;

var options = {
       explorer: {
         axis: "horizontal"
       },
       chartArea: { left: "10%", top: "10%", width: "85%", height: "80%" },
       legend: "none",
       hAxis: {
         format: "kk:mm"
       },
       vAxis: {
         title: "Temperatur"
       },
       backgroundColor: "#f1f8e9"
} ;

// Updates the graph when a button is clicked
function update( diff )
{
   if( (chart !== null) && (data !== null) && (view !== null) )
   {
      var last = data.getValue( data.getNumberOfRows() - 1, 0 ) ;
      view.setRows( data.getFilteredRows( [{column: 0, minValue: new Date(last.getTime()-diff*24*60*60*1000)}] ) ) ;
      chart.draw( view, options ) ;
   }
}

// Draws the chart when the library is ready
function drawChart()
{
  fetch( "https://www.heimetli.ch/cgi-bin/temperature" )
     .then( response => response.json() )
     .then( json => {
        data = new google.visualization.DataTable() ;
        data.addColumn('datetime', 'time') ;
        data.addColumn('number', 'Temperatur') ;
        data.addColumn({type: 'string', role: 'tooltip'}) ;

        // This regex is used to extract the components of date and time
        var regex = new RegExp( "(\\d\\d)\\.(\\d\\d)\\.(\\d\\d\\d\\d) (\\d\\d)\\:(\\d\\d)" ) ;
        var fmt   = new google.visualization.DateFormat({pattern: "d.M.yy - kk:mm"});
        var last  = null ;

        json.forEach( row => {
           // Transform the timestamp to a Date object and add a row to the data table
           var d    = regex.exec( row.dt ) ;
           var date = new Date( d[3], d[2]-1, d[1], d[4], d[5] ) ;
           data.addRow( [date, row.t, `${fmt.formatValue(date)}\nTemperatur ${row.t}\u00B0C`] ) ;
           last     = row.t ;
        } ) ;

        // Not needed for the chart
        if( last !== null )
        {
           document.querySelector( "h2" ).textContent = `Temperatur aktuell: ${last}\u00B0C` ;
        }

        view  = new google.visualization.DataView( data ) ;

        chart = new google.visualization.LineChart( document.getElementById('temperature') ) ;
        chart.draw( view, options ) ;
     } )
     .catch( error => alert(error) ) ;
}

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

Die globalen Variablen gefallen mir eigentlich nicht, aber ich habe keinen Weg gefunden um die Optionen und die DataTable wieder aus dem Graph auszulesen.

Die explorer-Option ist recht cool. Sie erlaubt das Zoomen und Scrollen auf dem Diagramm.

Ebenfalls sehr nützlich: für jeden Punkt kann man den Text für den Tooltip festlegen. Und das Format für die Zeitachse lässt sich ebenfalls frei festlegen.