Ubidots offers off-the-shelf widgets to cover most visualization and control needs for your IoT projects. However, in some projects you may want to code your own customized widget. Knowing some of our users have customization needs beyond our white-glove customer service we decided to open the possibility of users designing their your own HTML/CSS/JS code and creating their own custom widgets and visualizations.

Table of Contents

1. How the HTML canvas widget works?
2. Example 1: Simple text with an image.
3. Example 2: Simple text box to set a variable.
4. Example 3: Highcharts – Line Chart.
5. Example 4: Mapbox Map.
6. Example 5: Plotly Graph.

How does the HTML Canvas widget work?

When you select the widget, you will find a code editor as depicted in the gif below. The widget works with the same HTML/CSS/JS you would code when creating a simple website. There's no need to learn a special API.
It also consider the case when you may need to use a 3rd library (e.g. jQuery), so you can add these by inserting an URL containing the library.

IMPORTANT NOTE: You should consider when writing code in this widget that all the execution will be made by your browser, we do not do any kind of polyfilling here, so it's up to your browser to support all the features that you make use of.

Following the below steps you will be able to create an HTML canvas widget with your own code.

Step 1: Click on the top-right "+" button. Drawer menu with widgets options opens.
Step 2: Click on HTML canvas. Drawer menu displays setup options.
Step 3: Name your widget.
Step 4: Click on "Open editor" button.
Step 5: Enter your HTML, CSS and JS code in the respective tab.
Step 6: Add libraries by entering its URL in the "3rd party libraries section".
Step 7: Save the changes.

Below you will find example to create custom widgets and visualizations. For simplicity in explanations, these examples will use jQuery to manipulate the DOM.

2. Example 1: Simple text with an Image

In this section we're going to create an HTML Canvas that contains an image accompanied by a text. The result is presented below:

We're going to use the Ubidots logo and our motto which is "Accelerate IoT Innovation" to create this simple but gorgeous example.
This example doesn't contain any JS code.

The HTML code will be:

<img src="https://iot.cdnedge.bluemix.net/ind/static/images/logo-ubidots@2x.png" />
<p class="motto">Accelerate IoT Innovation</p>

The CSS code will be:

@import url('https://fonts.googleapis.com/css?family=Open+Sans');

body {
background: #28AECD;
  color: #FFFFFF;
font-family: 'Open Sans', sans-serif;
}

img {
    display: block;
    margin: 0 auto;
    position: absolute;
    width: 350px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.motto {
    position: absolute;
    top: 60%;
    transform: translate(-50%, -50%);
    left: calc(50% + 80px);
    white-space: nowrap;
}

You can see the result of this example in this widget here.

3. Example 2: Simple text box to set a variable

Here you will need to add the jQuery library by copy/paste the following link in the "add 3rd party library" section.

https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js

This is the first example showing how to interact with the Ubidots API. The final result of this example will be an HTML Widget capable of sending a value to a Variable.

The HTML code will be:

<div class="notification--container" id="notification">
  <p>Value sent successfully</p>
</div>

<div class="send-value--container">
  <input type="number" step="0.0001" placeholder="Enter number" class="send-value--input" id="value" />
  <button type="button" class="send-value--button" id="send-value">Send value</button>
</div>

The CSS code will be:

.send-value--container {
  left: 50%;
position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
}

.send-value--input {
border: none;
  border-bottom: 2px solid #28AECD;
  display: block;
  margin: 0 auto;
  font-size: 14px;
  outline: none;
}

.send-value--button {
  background: #FFFFFF;
  border: 2px solid #28AECD;
  border-radius: 20px;
  color: #28AECD;
  font-size: 14px;
margin-top: 10px;
width: 100%;
}

.send-value--button:hover {
  background: #28AECD;
  cursor: pointer;
  color: #FFFFFF;
}

.notification--container {
  display: none;
}

The JS code will be:

var $sendValue = $('#send-value');
var $value = $('#value');
var $notification = $('#notification');
var TOKEN = 'YOUR TOKEN';
var VARIABLE_ID = 'YOUR VARIABLE ID';

function postValue(variable, token, callback) {
  var url = 'https://industrial.api.ubidots.com/api/v1.6/variables/' + variable + '/values';
  var headers = {
    'Content-Type': 'application/json',
    'X-Auth-Token': TOKEN
  };
 
  $notification.hide();

  $.ajax({
    data: JSON.stringify({
      value: parseFloat($value.val(), 10)
    }),
    method: 'POST',
    url: url,
    headers: headers,
    success: function (res) {
   callback(res.value);
  }
  });
}

$sendValue.on('click', function () {
  postValue(VARIABLE_ID, TOKEN, function (value) {
    $notification.show();
  });
});

4. Example 3: Highcharts – Line Chart

Here you will need to add the jQuery and Highcharts libraries by copy/paste the following links in the "add 3rd party library" section

https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js
https://cdnjs.cloudflare.com/ajax/libs/highcharts/6.1.1/highcharts.js


In the next example we're going to bring the data from Ubidots and show the data in a HighCharts chart. The result will look like this:

This shows the great level of customization that the HTML Canvas widget could have.
This example doesn't contain any CSS code.

The HTML code will be:

<div id="container" style="min-width: 310px; height: 310px; margin: 0 auto"></div>

The JS code will be:

var TOKEN = 'YOUR TOKEN';
var VARIABLE = 'YOUR VARIABLE ID';

function getDataFromVariable(variable, token, callback) {
  var url = 'https://industrial.api.ubidots.com/api/v1.6/variables/' + variable + '/values';
  var headers = {
    'X-Auth-Token': token,
    'Content-Type': 'application/json'
  };
 
  $.ajax({
    url: url,
    method: 'GET',
    headers: headers,
    success: function (res) {
      callback(res.results);
    }
  });
}

var chart = Highcharts.chart('container', {
    chart: {
        type: 'line'
    },
    title: {
        text: 'Bring data from Ubidots'
    },
    xAxis: {
        type: 'datetime',
    },
    credits: {
        enabled: false
    },
    series: [{
    data: []
    }]
});

getDataFromVariable(VARIABLE, TOKEN, function (values) {
  var data = values.map(function (value) {
    return [value.timestamp, value.value];
  });
 
  chart.series[0].setData(data);
});

You can see the result of this example in this widget here.

5. Example 4: Mapbox Map

Here you will need to create an account in Mapbox to get the appropriate authentication KEY and paste accordingly in the JS code.

In this example we'll use Mapbox instead of Google Maps, which is the service we use to our default Map widget.

This is a bit more complicated example, as we're using OpenLayers and Mapbox APIs. Here you will need to include the jQuery and OpenLayer libraries by copy/paste the following 3 links in the "add 3rd party library" section:

https://openlayers.org/en/v3.20.1/build/ol.js
https://openlayers.org/en/v3.20.1/examples/resources/mapbox-streets-v6-style.js
https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js

The HTML code is:

<div id='map'>
  <div id="info"></div>
</div>

The CSS code is:

body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }

The JS code is:

var TOKEN = 'YOUR TOKEN';
var VARIABLE = 'YOUR VARIABLE ID';

var key = 'YOUR MAPBOX.COM KEY';

function getDataFromVariable(variable, token, callback) {
  var url = 'https://industrial.api.ubidots.com/api/v1.6/variables/' + variable + '/values';
  var headers = {
    'X-Auth-Token': token,
    'Content-Type': 'application/json'
  };
  var params = {
page_size: 1
  };
 
  $.ajax({
    url: url,
    method: 'GET',
    params: params,
    headers: headers,
    success: function (res) {
      callback(res.results);
    }
  })
}

var styles = {
  'geoMarker': new ol.style.Style({
    image: new ol.style.Circle({
      radius: 7,
      snapToPixel: false,
      fill: new ol.style.Fill({color: 'black'}),
      stroke: new ol.style.Stroke({
        color: 'white', width: 2
      })
    })
  })
};

var vectorSource = new ol.source.Vector({});

var map = new ol.Map({
  layers: [
    new ol.layer.VectorTile({
      source: new ol.source.VectorTile({
        format: new ol.format.MVT(),
        tileGrid: ol.tilegrid.createXYZ({maxZoom: 22}),
        tilePixelRatio: 16,
        url: 'https://{a-d}.tiles.mapbox.com/v4/mapbox.mapbox-streets-v6/' +
        '{z}/{x}/{y}.vector.pbf?access_token=' + key
      }),
      style: createMapboxStreetsV6Style()
    }),
   
    new ol.layer.Vector({
      source: vectorSource
    })
  ],
  target: 'map',
  view: new ol.View({
    center: [0, 0],
    zoom: 2
  })
});

getDataFromVariable(VARIABLE, TOKEN, function (values) {
  var geoMarker = new ol.Feature({
    type: 'geoMarker',
    geometry: new ol.geom.Point([0,0])
  });
 
  vectorSource.addFeature(geoMarker);
}); 

The result widget can be seen here.

6. Example 5: Plotly Graph

Here you will need to add the jQuery and Plot.ly libraries by copy/paste the following links in the "add 3rd party library" section

https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js
https://cdnjs.cloudflare.com/ajax/libs/plotly.js/1.39.4/plotly.min.js

We used a Highcharts implementation before, but what if we want to use another graphing library? It is also possible with this HTML Widget, in this example we'll use Plotly to graph the data of our chart.

The HTML code will be:

<div id="plotlyDiv" style="width:100%;height:400px;"></div>

The JS code will be:

var TOKEN = 'YOUR TOKEN';
var VARIABLE = 'YOUR VARIABLE ID';

function getDataFromVariable(variable, token, callback) {
  var url = 'https://industrial.api.ubidots.com/api/v1.6/variables/' + variable + '/values';
  var headers = {
    'X-Auth-Token': token,
    'Content-Type': 'application/json'
  };
 
  $.ajax({
    url: url,
    method: 'GET',
    headers: headers,
    success: function (res) {
      callback(res.results);
    }
  })
}

var layout = {
  xaxis: {
    type: 'date',
    title: 'Date'
  },
  yaxis: {
    title: 'Value'
  },
  title:'My Variable'
};

Plotly.plot('plotlyDiv', [], layout);

getDataFromVariable(VARIABLE, TOKEN, function (values) {
  var trace = {
    x: [],
    y: [],
    mode: 'lines',
  type: 'scatter',
    name: '2000'
  };
  var data = values.forEach(function (value) {
    trace.x.push(value.timestamp);
    trace.y.push(value.value);
  });
 
  Plotly.addTraces('plotlyDiv', trace)
});

The result widget can be seen here.

Did this answer your question?