Ubidots offers many off-the-shelf widgets that cover 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 wanted to better educate users to the capabilities of their data. Using your own HTML/JS/CSS code you can create your own custom widgets.

In this introductory HTML Canvas demo, we will demonstrate a simple development to monitor a non-static variable. For example, temperature on a 0-100 degree scale.

  • For values less than 30 the display will show a Blue LCD Screen
  • For values between 30 and 70 the display will show the normal (green) LCD Screen
  • For values greater than 70, the display will show a Red LCD Screen

To better understand this - check out the final product here. We have made the sliding scale manual for you to understand this application, but the scale can be powered by a sensor's variables or manual control based on your coding and desired application.

To start with, you should have created both a temperature variable and Slider widget. If you haven't created any or both yet, please refer to the following articles to learn how to do it.

Once done both, you can continue with this guide.

 Create a Custom HTML Canvas Widget

Now, let's see how we created this custom widget?

1- Start by logging into your Ubidots application.
Login to your Industrial account by clicking here.

2- Go to Dashboards and click on the upper-right blue icon to add a new widget.

3- Next, a panel will slide from the right; click on the widget called HTML Canvas.

4- After selecting the widget, a settings panel will slide from the right side. It is for  we are going to supply the widget with some parameters necessaries for this example  this new is for editing the Editor will appear. Firstly, we are going to add the code. To do so, click on "Open editor".

5-Right after, a coding box will appear containing 3 tabs: HTML, CSS and JS

The first tab we will insert HTML Code. This code will create the markup for our widget.

HTML CODE: 

<div id="image_background">
  <p>Last value:</p>
  <span id="image_background_text">No data</span>
</div>

6- The second tab is CSS. This code will give style to our HTML markup; HTML by itself is pretty ugly (or maybe we are the only ones who think so).

CSS CODE:

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

#image_background {
  background: url('http://i.imgur.com/uuYygjz.png') 0 / contain no-repeat;
  font-family: "VT323";
  font-size: 25px;
  letter-spacing: 10.5px;
  height: 220px;
  width: 450px;
}

#image_background p, #image_background_text {
  margin: 0;
  left: 75px;
  position: absolute;
}

#image_background p {
  top: 88px;
  font-size: 25px !important;
}

#image_background_text {
  top: 121px;
}

7- The third tab is for Javascript, the logic code for our widget. This is the only front-end programming language for web development so it is easily fittable for your needs.

Replace the variable ID and token fo
Javascript CODE:

var $bg = $('#image_background');
var $text = $('#image_background_text');
var lastValue = null;
function changeImage(value) {
  var choose = 'normal';
  var background = {
    blue: 'http://i.imgur.com/ZE0W7Yx.png',
    normal: 'http://i.imgur.com/uuYygjz.png',
    yellow: 'http://i.imgur.com/RHvDkUE.png'
  }
if (value <= 30) {
    choose = 'blue';
    $bg.css('color', 'white');
  } else if (value > 30 && value <= 70) {
    choose = 'yellow';
    $bg.css('color', 'white');
  }
$bg.css('background', 'url(' + background[choose] + ') 0 / contain no-repeat');
}
function getLastValue(variableId, token) {
  var url = 'https://industrial.api.ubidots.com/api/v1.6/variables/' + variableId + '/values';
  $.get(url, { token: token, page_size: 1 }, function (res) {
    if (lastValue === null ||res.results[0].value !== lastValue.value) {
      $text.text(res.results[0].value);
      lastValue = res.results[0].value;
      changeImage(lastValue);
    }
  });
}
setInterval(function () {
  getLastValue('PUT-YOUR-VARIABLE-ID', 'PUT-YOUR-UBIDOTS-TOKEN');
}, 2000);


NOTE: The code is not hard as it looks, in this Javascript we added the display adjustment functions for evaluating range, outlines in red.

8- Once you have entered HTML, CSS and Javascript codes, click on the green check mark to save the code. 

Back to the settings panel, there's is a section to import 3rd party libraries, in this example we will use the Google CDN for jQuery. A CDN is a service given by a third party which hosts this library and lets us use it in our application.
Please copy and paste the following URL into the text box:

https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js

jQuery is a library that will let us manipulate the DOM simply. The DOM is literally everything you see in your browser.

With this final step you have completed your custom color adjusting widget based pre-determined triggers of 30 and 70.
Check out the final product for our custom trigger widget adjusting based on:

  • values less than 30 the display will show a Blue LCD Screen
  • values between 30 and 70 the display will show the normal (green) LCD Screen
  • values greater than 70, the display will show a Red LCD Screen

The final Dashboard Display here.

Wait - You Want One More Layer?

To further display the capabilities of this HTML Canvas, let's keep going. Our widget demo was designed to adjust a display based on triggers (30 & 70). But, what if you wanted to go one more layer and overlay an image onto another image? This is possible too with Ubidots HTML Canvas.

Using an LCD display image, we coded HTML to adjust contrast according to a variables value. LCD screens user an analog input. This lets you change the contrast of the screen by varying the current, we will do something similar here with a new variable.


1- Create a new variable.
I'm going to create this new variable called contrast.


2- Use the new assets of the screen.
As we are just modifying the display of the LCD screen, we need to separate the display screen from the boarder. We will work with two images: The LCD screen body and the LCD display.

3- Let's take a look back to our example and edit it to incorporate this new layer

Our adjusted HTML code will be:

<div id="image_background">
 
  <img id="display_background" src="http://i.imgur.com/meoKhMG.png" />
 
  <p>Last value:</p>
  <span id="image_background_text">No data</span>
</div>

The new CSS code will be:

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

#image_background {
  background: url('http://i.imgur.com/ehNdUxY.png') 0 / contain no-repeat;
  font-family: "VT323";
  font-size: 25px;
  letter-spacing: 10.5px;
  height: 220px;
  width: 450px;
}

#image_background p, #image_background_text {
  margin: 0;
  left: 75px;
  position: absolute;
}

#image_background p {
  top: 88px;
  font-size: 25px !important;
}

#image_background_text {
  top: 121px;
}

#display_background {
  height: 94px;
  position: absolute;
  top: 70px;
  left: 52px;
  pointer-events: none;
}

Last but not least, the new JS code is:

var $bg = $('#display_background');
var $text = $('#image_background_text');
var lastValue = null;
var lastContrast = null;
var TOKEN = 'YOUR TOKEN';
var scale = d3.scaleLinear().range([0, 4]).domain([0, 1023])

function getLastValue(variableId, token, cb) {
  var url = 'https://industrial.api.ubidots.com/api/v1.6/variables/' + variableId + '/values';
  $.get(url, { token: token, page_size: 1 }, function (res) {
    if (typeof cb === 'function') cb(res);
  });
}

setInterval(function () {
  // Get LCD Screen last value
  getLastValue('YOUR LAST VALUE VARIABLE ID', TOKEN, function (res) {
    var value = null;
    try {
    value = res.results[0].value;
    } catch (e) {
      console.log('No data');
    }
  if ((lastContrast === null || value !== lastContrast.value) && value !== null) {
      $text.text(value);
      lastValue = value;
    }
  });
 
  // Get LCD Screen contrast
  getLastValue('YOUR CONTRAST VALUE VARIABLE ID', TOKEN, function (res) {
    var value = null;
    try {
    value = res.results[0].value;
    } catch (e) {
      console.log('No data');
    }
  if ((lastContrast === null || value !== lastContrast.value) && value !== null) {
 $bg.css('filter', 'contrast(' + scale(value) + ')');
      lastContrast = value;
    }
  });
 
}, 2000);


Finally, before saving the new code and try it out, a second third party library called 3d will be needed. As of the first example, please add the following library to your HTML canvas:

https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.0/d3.min.js

An example can be seen here: https://app.ubidots.com/ubi/public/getdashboard/page/wKyYTxt6bcaM3o-nFMOglR2NrAI/

Thank you for learning a little bit more about Ubidots and our HTML Canvas widget. Now it is your turn to build a custom widget tailored to your specific application needs. 

If you develop something amazing, please share it with us on Facebook, Twitter, or Youtube. 

Did this answer your question?