Yes we can :)
For gauge widgets, thingsboard uses a helper object called TbCanvasDigitalGauge
.
This thing draws a gauge for widgetContext.data[0]
onto an existing canvas element.
Based on one of the existing gauge widgets and the code of TbCanvasDigitalGauge
I figured out to setup a fake context for each of the gauges to reflect each resolved entity. Hence, the data for each resolved
entity is mapped to fakeCtx.data[0]
for every gauge.
This is the javascript part of my multi gauge widget:
self.createGauge = function(data, idx) {
let elementId, canvas, fakeCtx;
elementId = ['gauge', self.ctx.$scope.$id, idx].join('_');
// Canvas for the gauge.
canvas = document.createElement('CANVAS');
canvas.id = elementId;
self.ctx.$container.append(canvas);
// Fake context for the gauge helper object.
fakeCtx = {
$container: self.ctx.$container,
settings: self.ctx.settings,
data: [data],
decimals: self.ctx.decimals,
units: self.ctx.units,
isMobile: self.ctx.isMobile,
$scope: self.ctx.$scope,
width: self.ctx.width,
height: self.ctx.height
};
return new TbCanvasDigitalGauge(fakeCtx, elementId);
};
self.onInit = function() {
// Create a gauge for each resolved entity.
self.ctx.$scope.gauges = self.ctx.defaultSubscription.data.map(self.createGauge);
};
self.onDataUpdated = function() {
self.ctx.$scope.gauges.forEach(gauge => gauge.update());
};
self.onResize = function() {
self.ctx.$scope.gauges.forEach(gauge => gauge.resize());
};
self.getSettingsSchema = function() {
return TbCanvasDigitalGauge.settingsSchema;
};
self.typeParameters = function() {
return {
maxDatasources: 1,
maxDataKeys: 1
};
};
self.onMobileModeChanged = function() {
self.ctx.$scope.gauges.forEach(gauge => gauge.mobileModeChanged());
};
The html for the widget is empty, since the script creates the canvas elements dynamically.