diff --git a/gauge-group.html b/gauge-group.html new file mode 100644 index 0000000..c62ccda --- /dev/null +++ b/gauge-group.html @@ -0,0 +1,93 @@ + + + + + \ No newline at end of file diff --git a/gauge-group.js b/gauge-group.js new file mode 100644 index 0000000..99b303a --- /dev/null +++ b/gauge-group.js @@ -0,0 +1,132 @@ +var path = require('path'); + +module.exports = function (RED) { + var counter = 0; + function ButtonGroupNode(config) { + const iid = ++counter; + var ui = undefined; + try { + var node = this; + if (ui === undefined) { + ui = RED.require("node-red-dashboard")(RED); + } + RED.nodes.createNode(this, config); + + var sizes = ui.getSizes(); + + var widthPx = (config.gaugewidth * sizes.sx) - (sizes.gx * 2); + + var heightPx = (config.gaugeheight * sizes.sy) - (sizes.gy * 2); + + var html = ` + +
+ `; + + var done = ui.addWidget({ + node: node, + order: config.order, + group: config.group, + width: config.width, + height: config.height, + format: html, + templateScope: 'local', + emitOnlyNewValues: false, + forwardInputMessages: false, + storeFrontEndInputAsState: false, + convertBack: function (value) { + return value; + }, + beforeEmit: function (msg, value) { + return { msg: { iid: iid, width: widthPx, height: heightPx, marginX: sizes.gx, marginY: sizes.gy, gauges: value, socketid: msg.socketid } }; + }, + initController: function ($scope, events) { + let gauges = []; + const opts = { + angle: 0, // The span of the gauge arc + lineWidth: 0.4, // The line thickness + radiusScale: 1, // Relative radius + pointer: { + length: 0.6, // // Relative to gauge radius + strokeWidth: 0.07, // The thickness + color: '#000000' // Fill color + }, + limitMax: true, // If false, max value increases automatically if value > maxValue + limitMin: true, // If true, the min value of the gauge will be fixed + colorStart: '#6FADCF', // Colors + colorStop: '#8FC0DA', // just experiment with them + strokeColor: '#E0E0E0', // to see which ones work best for you + generateGradient: true, + highDpiSupport: true, // High resolution support + percentColors: undefined, + }; + + $scope.$watch('msg', function (msg) { + if (!msg) { + return; + } + var target = $(`#gauge-${msg.iid}`); + + if (gauges.length < msg.gauges.length) { + const difference = msg.gauges.length - gauges.length; + for (let i = 0; i < difference; i++) { + const obj = { + canvas: undefined, + gauge: undefined, + label: undefined + } + const canvasId = `gauge-${msg.iid}-${i}-canvas`; + const labelId = `gauge-${msg.iid}-${i}-label`; + target.append(` +
+
+ +
+ `); + + obj.canvas = $(`#${canvasId}`)[0]; + obj.label = $(`#${labelId}`)[0]; + + let modifiedOpts = Object.assign({}, opts); + + modifiedOpts.percentColors = msg.gauges[i].smoothColors; + + obj.gauge = new Gauge(obj.canvas).setOptions(modifiedOpts); + obj.gauge.setMinValue(0); + + gauges.push(obj); + } + } else if (gauges.length > msg.gauges.length) { + const difference = gauges.length - msg.gauges.length; + for (let i = 0; i < difference; i++) { + const obj = gauges.pop(); + obj.canvas.remove(); + } + } + + for (let i = 0; i < gauges.length; i++) { + gauges[i].gauge.maxValue = msg.gauges[i].max; + gauges[i].gauge.set(msg.gauges[i].value); + gauges[i].label.innerHTML = msg.gauges[i].label; + } + }); + } + }); + } catch (e) { + console.log(e) + } + node.on('close', done); + } + RED.nodes.registerType("ui_gauge_group", ButtonGroupNode); + + var uipath = 'ui'; + if (RED.settings.ui) { uipath = RED.settings.ui.path; } + var fullPath = path.join('/', uipath, '/ui-gauge-group/*').replace(/\\/g, '/'); + RED.httpNode.get(fullPath, function (req, res) { + var options = { + root: __dirname + '/lib/', + dotfiles: 'deny' + }; + res.sendFile(req.params[0], options) + }); +} \ No newline at end of file diff --git a/lib/gauge.min.js b/lib/gauge.min.js new file mode 100644 index 0000000..1b77c1c --- /dev/null +++ b/lib/gauge.min.js @@ -0,0 +1 @@ +(function(){function t(t,i){for(var e in i)m.call(i,e)&&(t[e]=i[e]);function s(){this.constructor=t}return s.prototype=i.prototype,t.prototype=new s,t.__super__=i.prototype,t}var i,e,s,n,o,p,a,h,r,l,g,c,u,d=[].slice,m={}.hasOwnProperty,x=[].indexOf||function(t){for(var i=0,e=this.length;ithis.gp.length)for(e=n=0,r=t.length-this.gp.length;0<=r?nthis.maxValue?this.options.limitMax?l=this.maxValue:this.maxValue=l+1:l=this.minValue)&&(!this.options.limitMax||d<=this.maxValue)&&(r=(n=d.font||t.font).match(l)[0],c=n.slice(r.length),o=parseFloat(r)*this.displayScale,this.ctx.font=o+c,u=this.getAngle(d.label)-3*Math.PI/2,this.ctx.rotate(u),this.ctx.fillText(g(d.label,t.fractionDigits),0,-s-this.lineWidth/2),this.ctx.rotate(-u)):(!this.options.limitMin||d>=this.minValue)&&(!this.options.limitMax||d<=this.maxValue)&&(u=this.getAngle(d)-3*Math.PI/2,this.ctx.rotate(u),this.ctx.fillText(g(d,t.fractionDigits),0,-s-this.lineWidth/2),this.ctx.rotate(-u));return this.ctx.restore()},M.prototype.renderTicks=function(t,i,e,s){var n,o,a,h,r,l,p,c,u,d,g,m,x,f,v,y,V,w,S,M;if(t!=={}){for(l=t.divisions||0,w=t.subDivisions||0,a=t.divColor||"#fff",f=t.subColor||"#fff",h=t.divLength||.7,y=t.subLength||.2,u=parseFloat(this.maxValue)-parseFloat(this.minValue),d=parseFloat(u)/parseFloat(t.divisions),v=parseFloat(d)/parseFloat(t.subDivisions),n=parseFloat(this.minValue),o=0+v,r=(c=u/400)*(t.divWidth||1),V=c*(t.subWidth||1),m=[],S=p=0,g=l+1;pthis.maxValue&&(h=this.maxValue),d=this.radius*this.options.radiusScale,m.height&&(this.ctx.lineWidth=this.lineWidth*m.height,u=this.lineWidth/2*(m.offset||1-m.height),d=this.radius*this.options.radiusScale+u),this.ctx.strokeStyle=m.strokeStyle,this.ctx.beginPath(),this.ctx.arc(0,0,d,this.getAngle(r),this.getAngle(h),!1),this.ctx.stroke();else void 0!==this.options.customFillStyle?i=this.options.customFillStyle(this):null!==this.percentColors?i=this.getColorForValue(this.displayedValue,this.options.generateGradient):void 0!==this.options.colorStop?((i=0===this.options.gradientType?this.ctx.createRadialGradient(g,e,9,g,e,70):this.ctx.createLinearGradient(0,0,g,0)).addColorStop(0,this.options.colorStart),i.addColorStop(1,this.options.colorStop)):i=this.options.colorStart,this.ctx.strokeStyle=i,this.ctx.beginPath(),this.ctx.arc(g,e,l,(1+this.options.angle)*Math.PI,t,!1),this.ctx.lineWidth=this.lineWidth,this.ctx.stroke(),this.ctx.strokeStyle=this.options.strokeColor,this.ctx.beginPath(),this.ctx.arc(g,e,l,t,(2-this.options.angle)*Math.PI,!1),this.ctx.stroke(),this.ctx.save(),this.ctx.translate(g,e);for(this.options.renderTicks&&this.renderTicks(this.options.renderTicks,g,e,l),this.ctx.restore(),this.ctx.translate(g,e),n=0,a=(c=this.gp).length;nthis.maxValue?this.options.limitMax?this.value=this.maxValue:this.maxValue=this.value:this.value