Languages: English • 简体中文 • 繁體中文
SensorThings API - Multiple Datastreams on a Chart
In Part 1 of this series, we saw how to display Observations
of one Datastream
on a chart.
In this part, we'll be representing multiple Datastreams
on a chart. It can make comparison easier.
What we will do is retrieving a Thing
and its Datastreams
and then Observations
of each Datastream
.
We, then, add each of Datastreams
' Observations
as a new series to the chart.
Let's start with retriveing the Thing
. As we saw on previous tutorial retrieving an entity in SensorThings API is as easy as sending an HTTP GET
request.
We retrieve the Thing
and then follow the @iot.navigationLink
to retrieve its Datastreams
.
Then for each of those Datastreams
we follow, again, the @iot.navigationLink
to retrieve Observations
.
Here is the code for that:
var thingURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Things(1501)";
$.getJSON(thingURI , function(thing) {
$.getJSON(thing["Datastreams@iot.navigationLink"] , function(datastreams) {
$.each(datastreams.value, function(i, datastream) {
$.getJSON(datastream["Observations@iot.navigationLink"] , function(observations) {});
});
});
});
After we retrieve Observations
of one Datastream
, we prepare the data and add it to the chart.
We can do it in the latest callback function, exactly as we did in the previous tutorial, and because we call the "addSeries
" function each time in the "$.each
" loop, multiple series will be added to the chart.
The only difference is that, since we have different set of data on the chart, we want to add a Y axis for each of them so that the chart will be more readable. For that, we use "addAxis
" function of Highcharts library. Also to make the chart look more organized we can put Y axis to different side of chart every time.
Here is the code for that:
//Change position of YAxis every time we go to "$.each" loop
flag = !flag;
chart.addAxis({
id: datastream.unitOfMeasurement.name,
title: {
text: datastream.unitOfMeasurement.name + " (" + datastream.unitOfMeasurement.symbol + ")"
},
opposite: flag
});
var series = chart.addSeries({
name: datastream.name,
data: data,
tooltip: {
valueSuffix: " " + datastream.unitOfMeasurement.symbol
},
yAxis: datastream.unitOfMeasurement.name
});
The rest of the code is exactly like previous tutorial. Here is the result:
How to make it better?
Again instead of multiple HTTP GET
requests, we can get all the Thing
, Datastreams
, and Observations
in one request using $expand
query. One of the great capabilities of SensorThings API is that not only you can embed the
immediate related entities in the response, but also you can embed the entities from next level of
relation using multilevel $expand
. For example, in this tutorial what we need is /Thing(<id>)?$expand=Datastreams/Observations
We need to make a slight change in the retrieving data part and the rest of code is exactly the same.
Here is how we need to change the code for using $expand
:
var thingURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Things(1501)?$expand=Datastreams/Observations";
$.getJSON(thingURI , function(thing) {
$.each(thing.Datastreams, function(i, datastream) {
var data = $.map(datastream.Observations, function(observation) {
var timestamp = moment(observation.phenomenonTime).valueOf();
return [[timestamp, parseFloat(observation.result)]];
});
data.sort(function(a, b) {
return a[0] - b[0];
});
});
});
Here is the code uses $expand
that you can also try:
What's Next?
Our next tutorial will show you how to retrieve Observations
of a Datastream
for a specified day. This
tutorial will help you learn more about filtering capabilities of SensorThings API. Also,
in case that the SensorThings server supports pagination, it shows how to follow @iot.nextLink to
retrieve the next page of Observations
.
Proceed to Part 3 - Filter Observations and Display on Chart