Languages: English简体中文繁體中文

SensorThings API - Gauges

In previous tutorial we focused on representation using chart. In this tutorial we will learn about gauges. We will learn how to retrieve the latest Observation of Datastream periodically and then we display that Observation on a Highcharts Gauge.

Prerequisite

In this tutorial we'll be using Highcharts library for Gauges, and jQuery library for retrieving data from SensorThings server.
Here is the code for adding jQuery and Highcharts libraries.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>

First Learning Step:
How to retrieve latest Observation of a Observation from a SensorThings Service

The way we naturally get the latest data is to sort the data by its time in descending order and then we get the very first data in the list as the latest data. We can do the same process using SensorThings API query options. In order to sort Observations we can use $orderby query option. $orderby=phenomenonTime desc is sorting Observations based on their phenomenonTime in descending order. Next, we need to get the first Observation in the sorted list which can be easily done using query option $top.

GET https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)/Observations?$orderby=phenomenonTime desc&$top=1

The code for retrieving latest Observations is no different from previous tutorial except in the URI to which we send HTTP GET request. Here is the code for that:

var datastreamURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)";
$.getJSON(datastreamURI, function(datastream) {
  $.getJSON(datastream["Observations@iot.navigationLink"]+"?$orderby=phenomenonTime desc&$top=1", function(observations) {
    var data = $.map(observations.value, function(observation) {
      return parseFloat(observation.result);
    });
  });
});

Now that we have the data, we are ready to prepare our Gauge.

Second Step:
Preparing the Gauge

We are using Highcharts library for Gauge. There are multiple parameters you can set for the Gauge, like Pane angle, yAxis minimum and maximum, etc. Also you the constructor for Gauge gets a function on how to fill the Gauge. The constructor of Gauge gets three parameters. First parameter is the id of the HTM container of Gauge. The second is Gauge options in JSON format. And the last one is the function to fill the Gauge.

Here you can see the code for preparing the Gauge.

Highcharts.chart('chart', {
    //guage options
    chart: {
      type: 'gauge'
    },
    title: {
      text: 'Loading Chart Data...'
    },
    pane: {
      startAngle: -150,
      endAngle: 150
    },
    //the value axis
    yAxis: {
      min: 0,
      max: 20,
      title: {
        text: ''
      }
    },
    //Temp series
    series: [{
      data: [0],
      tooltip: {
        valueSuffix: ''
      }
    }]
  },
  function (chart) {});
);

Final Step:
Load the latest Observation into the Gauge

We already retrieved the latest Observations and now we need to load it into the Gauge by using
updateSeries
function from Highcharts.

chart.series[0].update({
  name: datastream.name,
  tooltip: {
    valueSuffix: " " + datastream.unitOfMeasurement.symbol
  }
});
//Add data to guage
chart.series[0].points[0].update(data);
//Update guage to have the unitOfMeasurement in it
chart.series[0].yAxis.update({
  title: {
    text: datastream.unitOfMeasurement.name + " (" + datastream.unitOfMeasurement.symbol + ")"
  }
});

But it is not enough. We also want to periodically retrieve the latest Observation and update the Gauge. To this end, we just use JavaScript setInteval function.

Here is the code for the function we passed as the third parameter to the Gauge:

function (chart) {
  if (!chart.renderer.forExport) {
    setInterval(function () {
      var datastreamURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)";
      // We start with a *link* to a datastream entity
      $.getJSON(datastreamURI, function(datastream) {
        //Set the guage title with Datastream description
        chart.setTitle({ text: datastream.description });
        // Retrieve latest Observation
        $.getJSON(datastream["Observations@iot.navigationLink"]+"?$orderby=phenomenonTime desc&$top=1", function(observations) {
          // Retrieve observations embedded in response by $expand function
          var data = $.map(observations.value, function(observation) {
            return parseFloat(observation.result);
          });
          // Update the temp Series
          chart.series[0].update({
            name: datastream.name,
            tooltip: {
              valueSuffix: " " + datastream.unitOfMeasurement.symbol
            }
          });
          //Add data to guage
          chart.series[0].points[0].update(data);
          //Update guage to have the unitOfMeasurement in it
          chart.series[0].yAxis.update({
            title: {
              text: datastream.unitOfMeasurement.name + " (" + datastream.unitOfMeasurement.symbol + ")"
            }
          });
        });
      });
    }, 1000);
  }
}

And finally here is the final result of loading our latest Observation into the Gauge:

See the code on SensorThings Share

Summary

In these series of tutorials we cover fundamentals of SesnorThings Visualization on Charts and Gauges. If you are interested on other SensorThings Visualizations, we also have a series of tutorials for displaying SensoThings entities on Map.