diff --git a/.gitignore b/.gitignore index 37da99d..8e1f902 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.ps1 -node_modules \ No newline at end of file +node_modules +.idea \ No newline at end of file diff --git a/dist/gauge.coffee b/dist/gauge.coffee index e5a6e99..c1cd7f9 100644 --- a/dist/gauge.coffee +++ b/dist/gauge.coffee @@ -131,10 +131,10 @@ class BaseGauge extends ValueUpdater devicePixelRatio = window.devicePixelRatio or 1 backingStorePixelRatio = @ctx.webkitBackingStorePixelRatio or - @ctx.mozBackingStorePixelRatio or - @ctx.msBackingStorePixelRatio or - @ctx.oBackingStorePixelRatio or - @ctx.backingStorePixelRatio or 1 + @ctx.mozBackingStorePixelRatio or + @ctx.msBackingStorePixelRatio or + @ctx.oBackingStorePixelRatio or + @ctx.backingStorePixelRatio or 1 @displayScale = devicePixelRatio / backingStorePixelRatio if @displayScale != prevDisplayScale @@ -150,13 +150,13 @@ class BaseGauge extends ValueUpdater return @ parseValue: (value) -> - value = parseFloat(value) || Number(value) + value = parseFloat(value) || Number(value) return if isFinite(value) then value else 0 class TextRenderer constructor: (@el, @fractionDigits) -> - # Default behaviour, override to customize rendering +# Default behaviour, override to customize rendering render: (gauge) -> @el.innerHTML = formatNumber(gauge.displayedValue, @fractionDigits) @@ -201,7 +201,7 @@ class GaugePointer extends ValueUpdater img: null constructor: (@gauge) -> - #super() + super() if @gauge is undefined throw new Error 'The element isn\'t defined.' @ctx = @gauge.ctx @@ -215,7 +215,7 @@ class GaugePointer extends ValueUpdater @strokeWidth = @canvas.height * @options.strokeWidth @maxValue = @gauge.maxValue @minValue = @gauge.minValue - @animationSpeed = @gauge.animationSpeed + @animationSpeed = @gauge.animationSpeed @options.angle = @gauge.options.angle if @options.iconPath @img = new Image() @@ -272,8 +272,8 @@ class Bar valPercent = (@value / @maxValue) * 100 avgPercent = (@avgValue / @maxValue) * 100 - $(".bar-value", @elem).css( { "width": valPercent + "%" } ) - $(".typical-value", @elem).css( { "width": avgPercent + "%" } ) + $(".bar-value", @elem).css({"width": valPercent + "%"}) + $(".typical-value", @elem).css({"width": avgPercent + "%"}) class Gauge extends BaseGauge elem: null @@ -289,7 +289,7 @@ class Gauge extends BaseGauge options: colorStart: "#6fadcf" colorStop: undefined - gradientType: 0 # 0 : radial, 1 : linear + gradientType: 0 # 0 : radial, 1 : linear strokeColor: "#e0e0e0" pointer: length: 0.8 @@ -316,7 +316,7 @@ class Gauge extends BaseGauge @gp = [new GaugePointer(@)] @setOptions() - + setOptions: (options = null) -> super(options) @@ -329,7 +329,7 @@ class Gauge extends BaseGauge @lineWidth = @availableHeight * @options.lineWidth # .2 - .7 @radius = (@availableHeight - @lineWidth / 2) / (1.0 + @extraPadding) @ctx.clearRect(0, 0, @canvas.width, @canvas.height) - + for gauge in @gp gauge.setOptions(@options.pointer) gauge.render() @@ -344,7 +344,7 @@ class Gauge extends BaseGauge rval = parseInt((cutHex(@options.percentColors[i][1])).substring(0, 2), 16) gval = parseInt((cutHex(@options.percentColors[i][1])).substring(2, 4), 16) bval = parseInt((cutHex(@options.percentColors[i][1])).substring(4, 6), 16) - @percentColors[i] = { pct: @options.percentColors[i][0], color: { r: rval, g: gval, b: bval } } + @percentColors[i] = {pct: @options.percentColors[i][0], color: {r: rval, g: gval, b: bval}} set: (value) -> if not (value instanceof Array) @@ -361,14 +361,14 @@ class Gauge extends BaseGauge gp.setOptions(@options.pointer) @gp.push(gp) else if value.length < @gp.length - # Delete redundant GaugePointers +# Delete redundant GaugePointers @gp = @gp.slice(@gp.length - value.length) # get max value and update pointer(s) i = 0 for val in value - # Limit pointer within min and max? +# Limit pointer within min and max? if val > @maxValue if @options.limitMax val = @maxValue @@ -382,7 +382,7 @@ class Gauge extends BaseGauge @minValue = val - 1 @gp[i].value = val - @gp[i++].setOptions( { minValue: @minValue, maxValue: @maxValue, angle: @options.angle } ) + @gp[i++].setOptions({minValue: @minValue, maxValue: @maxValue, angle: @options.angle}) @value = Math.max(Math.min(value[value.length - 1], @maxValue), @minValue) # TODO: Span maybe?? # Force first .set() @@ -400,10 +400,10 @@ class Gauge extends BaseGauge for i in [0..(@percentColors.length - 1)] if (pct <= @percentColors[i].pct) if grad == true - # Gradually change between colors +# Gradually change between colors startColor = @percentColors[i - 1] || @percentColors[0] endColor = @percentColors[i] - rangePct = (pct - startColor.pct) / (endColor.pct - startColor.pct) # How far between both colors + rangePct = (pct - startColor.pct) / (endColor.pct - startColor.pct) # How far between both colors color = { r: Math.floor(startColor.color.r * (1 - rangePct) + endColor.color.r * rangePct), g: Math.floor(startColor.color.g * (1 - rangePct) + endColor.color.g * rangePct), @@ -435,27 +435,27 @@ class Gauge extends BaseGauge @ctx.textAlign = "center" for value in staticLabels.labels if (value.label != undefined) - # Draw labels depending on limitMin/Max +# Draw labels depending on limitMin/Max if (not @options.limitMin or value >= @minValue) and (not @options.limitMax or value <= @maxValue) font = value.font || staticLabels.font match = font.match(re)[0] rest = font.slice(match.length) fontsize = parseFloat(match) * this.displayScale @ctx.font = fontsize + rest - + rotationAngle = @getAngle(value.label) - 3 * Math.PI / 2 @ctx.rotate(rotationAngle) @ctx.fillText(formatNumber(value.label, staticLabels.fractionDigits), 0, -radius - @lineWidth / 2) @ctx.rotate(-rotationAngle) else - # Draw labels depending on limitMin/Max +# Draw labels depending on limitMin/Max if (not @options.limitMin or value >= @minValue) and (not @options.limitMax or value <= @maxValue) rotationAngle = @getAngle(value) - 3 * Math.PI / 2 @ctx.rotate(rotationAngle) @ctx.fillText(formatNumber(value, staticLabels.fractionDigits), 0, -radius - @lineWidth / 2) @ctx.rotate(-rotationAngle) - + @ctx.restore() renderTicks: (ticksOptions, w, h, radius) -> @@ -477,9 +477,9 @@ class Gauge extends BaseGauge for t in [0...divisionCount + 1] by 1 @ctx.lineWidth = @lineWidth * divLength - scaleMutate = (@lineWidth / 2) * ( 1 - divLength) + scaleMutate = (@lineWidth / 2) * (1 - divLength) tmpRadius = (@radius * @options.radiusScale) + scaleMutate - + @ctx.strokeStyle = divColor @ctx.beginPath() @ctx.arc(0, 0, tmpRadius, @getAngle(currentDivision - divWidth), @getAngle(currentDivision + divWidth), false) @@ -490,19 +490,19 @@ class Gauge extends BaseGauge if t != ticksOptions.divisions && subdivisionCount > 0 # if its not the last marker then draw subs for st in [0...subdivisionCount - 1] by 1 @ctx.lineWidth = @lineWidth * subLength - scaleMutate = (@lineWidth / 2) * ( 1 - subLength) + scaleMutate = (@lineWidth / 2) * (1 - subLength) tmpRadius = (@radius * @options.radiusScale) + scaleMutate - + @ctx.strokeStyle = subColor @ctx.beginPath() @ctx.arc(0, 0, tmpRadius, @getAngle(currentSubDivision - subWidth), @getAngle(currentSubDivision + subWidth), false) @ctx.stroke() currentSubDivision += subDivisions - #@ctx.restore() +#@ctx.restore() render: () -> - # Draw using canvas +# Draw using canvas w = @canvas.width / 2 h = (@canvas.height * @paddingTop + @availableHeight) - ((@radius + @lineWidth / 2) * @extraPadding) displayedAngle = @getAngle(@displayedValue) @@ -513,13 +513,13 @@ class Gauge extends BaseGauge radius = @radius * @options.radiusScale if (@options.staticLabels) @renderStaticLabels(@options.staticLabels, w, h, radius) - + if (@options.staticZones) @ctx.save() @ctx.translate(w, h) @ctx.lineWidth = @lineWidth for zone in @options.staticZones - # Draw zones depending on limitMin/Max +# Draw zones depending on limitMin/Max min = zone.min if @options.limitMin and min < @minValue min = @minValue @@ -531,7 +531,7 @@ class Gauge extends BaseGauge @ctx.lineWidth = @lineWidth * zone.height scaleMutate = (@lineWidth / 2) * (zone.offset || 1 - zone.height) tmpRadius = (@radius * @options.radiusScale) + scaleMutate - + @ctx.strokeStyle = zone.strokeStyle @ctx.beginPath() @ctx.arc(0, 0, tmpRadius, @getAngle(min), @getAngle(max), false) @@ -564,11 +564,11 @@ class Gauge extends BaseGauge @ctx.stroke() @ctx.save() @ctx.translate(w, h) - + if (@options.renderTicks) @renderTicks(@options.renderTicks, w, h, radius) - + @ctx.restore() # Draw pointers from (w, h) @@ -593,6 +593,7 @@ class BaseDonut extends BaseGauge shadowColor: "#d5d5d5" angle: 0.35 radiusScale: 1.0 + lineCap: "round" constructor: (@canvas) -> super() @@ -646,7 +647,7 @@ class BaseDonut extends BaseGauge @ctx.beginPath() @ctx.arc(w, h, @radius, (1 - @options.angle) * Math.PI, (2 + @options.angle) * Math.PI, false) @ctx.lineWidth = @lineWidth - @ctx.lineCap = "round" + @ctx.lineCap = @options.lineCap @ctx.stroke() @ctx.strokeStyle = grdFill @@ -686,10 +687,10 @@ window.AnimationUpdater = AnimationUpdater.elements.push(object) run: (force = false) -> - # 'force' can take three values, for which these paths should be taken - # true: Force repaint of the gauges (typically on first Gauge.set) - # false: Schedule repaint (2nd or later call to Gauge.set) - # a number: It's a callback. Repaint and schedule new callback if not done. +# 'force' can take three values, for which these paths should be taken +# true: Force repaint of the gauges (typically on first Gauge.set) +# false: Schedule repaint (2nd or later call to Gauge.set) +# a number: It's a callback. Repaint and schedule new callback if not done. isCallback = isFinite(parseFloat(force)) if isCallback or force is true finished = true @@ -699,7 +700,7 @@ window.AnimationUpdater = AnimationUpdater.animId = if finished then null else requestAnimationFrame(AnimationUpdater.run) else if force is false if AnimationUpdater.animId is not null - # Cancel pending callback if animId is already set to avoid overflow +# Cancel pending callback if animId is already set to avoid overflow cancelAnimationFrame(AnimationUpdater.animId) AnimationUpdater.animId = requestAnimationFrame(AnimationUpdater.run) diff --git a/dist/gauge.js b/dist/gauge.js index 7295e2d..2abf863 100644 --- a/dist/gauge.js +++ b/dist/gauge.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.10.0 +// Generated by CoffeeScript 1.12.7 (function() { var AnimatedText, AnimatedTextFactory, Bar, BaseDonut, BaseGauge, Donut, Gauge, GaugePointer, TextRenderer, ValueUpdater, addCommas, cutHex, formatNumber, mergeObjects, secondsToString, slice = [].slice, @@ -321,6 +321,7 @@ function GaugePointer(gauge1) { this.gauge = gauge1; + GaugePointer.__super__.constructor.call(this); if (this.gauge === void 0) { throw new Error('The element isn\'t defined.'); } @@ -799,7 +800,8 @@ strokeColor: "#eeeeee", shadowColor: "#d5d5d5", angle: 0.35, - radiusScale: 1.0 + radiusScale: 1.0, + lineCap: "round" }; function BaseDonut(canvas) { @@ -863,7 +865,7 @@ this.ctx.beginPath(); this.ctx.arc(w, h, this.radius, (1 - this.options.angle) * Math.PI, (2 + this.options.angle) * Math.PI, false); this.ctx.lineWidth = this.lineWidth; - this.ctx.lineCap = "round"; + this.ctx.lineCap = this.options.lineCap; this.ctx.stroke(); this.ctx.strokeStyle = grdFill; this.ctx.beginPath(); @@ -975,3 +977,5 @@ } }).call(this); + +//# sourceMappingURL=gauge.js.map diff --git a/dist/gauge.min.js b/dist/gauge.min.js index ad83c23..e34f35d 100644 --- a/dist/gauge.min.js +++ b/dist/gauge.min.js @@ -1 +1 @@ -(function(){var t,i,e,s,n,o,a,h,r,l,p,c,u,d=[].slice,g={}.hasOwnProperty,m=function(t,i){function e(){this.constructor=t}for(var s in i)g.call(i,s)&&(t[s]=i[s]);return e.prototype=i.prototype,t.prototype=new e,t.__super__=i.prototype,t};!function(){var t,i,e,s,n,o,a;for(a=["ms","moz","webkit","o"],e=0,n=a.length;e1&&(n="."+e[1]),i=/(\d+)(\d{3})/;i.test(s);)s=s.replace(i,"$1,$2");return s+n},l=function(t){return"#"===t.charAt(0)?t.substring(1,7):t},h=function(){function t(t,i){null==t&&(t=!0),this.clear=null==i||i,t&&AnimationUpdater.add(this)}return t.prototype.animationSpeed=32,t.prototype.update=function(t){var i;return null==t&&(t=!1),!(!t&&this.displayedValue===this.value)&&(this.ctx&&this.clear&&this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),i=this.value-this.displayedValue,Math.abs(i/this.animationSpeed)<=.001?this.displayedValue=this.value:this.displayedValue=this.displayedValue+i/this.animationSpeed,this.render(),!0)},t}(),e=function(t){function i(){return i.__super__.constructor.apply(this,arguments)}return m(i,t),i.prototype.displayScale=1,i.prototype.forceUpdate=!0,i.prototype.setTextField=function(t,i){return this.textField=t instanceof a?t:new a(t,i)},i.prototype.setMinValue=function(t,i){var e,s,n,o,a;if(this.minValue=t,null==i&&(i=!0),i){for(this.displayedValue=this.minValue,o=this.gp||[],a=[],s=0,n=o.length;s.5&&(this.options.angle=.5),this.configDisplayScale(),this},i.prototype.configDisplayScale=function(){var t,i,e,s,n;return s=this.displayScale,!1===this.options.highDpiSupport?delete this.displayScale:(i=window.devicePixelRatio||1,t=this.ctx.webkitBackingStorePixelRatio||this.ctx.mozBackingStorePixelRatio||this.ctx.msBackingStorePixelRatio||this.ctx.oBackingStorePixelRatio||this.ctx.backingStorePixelRatio||1,this.displayScale=i/t),this.displayScale!==s&&(n=this.canvas.G__width||this.canvas.width,e=this.canvas.G__height||this.canvas.height,this.canvas.width=n*this.displayScale,this.canvas.height=e*this.displayScale,this.canvas.style.width=n+"px",this.canvas.style.height=e+"px",this.canvas.G__width=n,this.canvas.G__height=e),this},i.prototype.parseValue=function(t){return t=parseFloat(t)||Number(t),isFinite(t)?t:0},i}(h),a=function(){function t(t,i){this.el=t,this.fractionDigits=i}return t.prototype.render=function(t){return this.el.innerHTML=p(t.displayedValue,this.fractionDigits)},t}(),t=function(t){function i(t,e){if(this.elem=t,this.text=null!=e&&e,i.__super__.constructor.call(this),void 0===this.elem)throw new Error("The element isn't defined.");this.value=1*this.elem.innerHTML,this.text&&(this.value=0)}return m(i,t),i.prototype.displayedValue=0,i.prototype.value=0,i.prototype.setVal=function(t){return this.value=1*t},i.prototype.render=function(){var t;return t=this.text?u(this.displayedValue.toFixed(0)):r(p(this.displayedValue)),this.elem.innerHTML=t},i}(h),o=function(t){function i(t){if(this.gauge=t,void 0===this.gauge)throw new Error("The element isn't defined.");this.ctx=this.gauge.ctx,this.canvas=this.gauge.canvas,i.__super__.constructor.call(this,!1,!1),this.setOptions()}return m(i,t),i.prototype.displayedValue=0,i.prototype.value=0,i.prototype.options={strokeWidth:.035,length:.1,color:"#000000",iconPath:null,iconScale:1,iconAngle:0},i.prototype.img=null,i.prototype.setOptions=function(t){if(null==t&&(t=null),this.options=c(this.options,t),this.length=2*this.gauge.radius*this.gauge.options.radiusScale*this.options.length,this.strokeWidth=this.canvas.height*this.options.strokeWidth,this.maxValue=this.gauge.maxValue,this.minValue=this.gauge.minValue,this.animationSpeed=this.gauge.animationSpeed,this.options.angle=this.gauge.options.angle,this.options.iconPath)return this.img=new Image,this.img.src=this.options.iconPath},i.prototype.render=function(){var t,i,e,s,n,o,a,h,r;if(t=this.gauge.getAngle.call(this,this.displayedValue),h=Math.round(this.length*Math.cos(t)),r=Math.round(this.length*Math.sin(t)),o=Math.round(this.strokeWidth*Math.cos(t-Math.PI/2)),a=Math.round(this.strokeWidth*Math.sin(t-Math.PI/2)),i=Math.round(this.strokeWidth*Math.cos(t+Math.PI/2)),e=Math.round(this.strokeWidth*Math.sin(t+Math.PI/2)),this.ctx.beginPath(),this.ctx.fillStyle=this.options.color,this.ctx.arc(0,0,this.strokeWidth,0,2*Math.PI,!1),this.ctx.fill(),this.ctx.beginPath(),this.ctx.moveTo(o,a),this.ctx.lineTo(h,r),this.ctx.lineTo(i,e),this.ctx.fill(),this.img)return s=Math.round(this.img.width*this.options.iconScale),n=Math.round(this.img.height*this.options.iconScale),this.ctx.save(),this.ctx.translate(h,r),this.ctx.rotate(t+Math.PI/180*(90+this.options.iconAngle)),this.ctx.drawImage(this.img,-s/2,-n/2,s,n),this.ctx.restore()},i}(h),function(){function t(t){this.elem=t}t.prototype.updateValues=function(t){return this.value=t[0],this.maxValue=t[1],this.avgValue=t[2],this.render()},t.prototype.render=function(){var t,i;return this.textField&&this.textField.text(p(this.value)),0===this.maxValue&&(this.maxValue=2*this.avgValue),i=this.value/this.maxValue*100,t=this.avgValue/this.maxValue*100,$(".bar-value",this.elem).css({width:i+"%"}),$(".typical-value",this.elem).css({width:t+"%"})}}(),n=function(t){function i(t){var e,s;this.canvas=t,i.__super__.constructor.call(this),this.percentColors=null,"undefined"!=typeof G_vmlCanvasManager&&(this.canvas=window.G_vmlCanvasManager.initElement(this.canvas)),this.ctx=this.canvas.getContext("2d"),e=this.canvas.clientHeight,s=this.canvas.clientWidth,this.canvas.height=e,this.canvas.width=s,this.gp=[new o(this)],this.setOptions()}return m(i,t),i.prototype.elem=null,i.prototype.value=[20],i.prototype.maxValue=80,i.prototype.minValue=0,i.prototype.displayedAngle=0,i.prototype.displayedValue=0,i.prototype.lineWidth=40,i.prototype.paddingTop=.1,i.prototype.paddingBottom=.1,i.prototype.percentColors=null,i.prototype.options={colorStart:"#6fadcf",colorStop:void 0,gradientType:0,strokeColor:"#e0e0e0",pointer:{length:.8,strokeWidth:.035,iconScale:1},angle:.15,lineWidth:.44,radiusScale:1,fontSize:40,limitMax:!1,limitMin:!1},i.prototype.setOptions=function(t){var e,s,n,o,a;for(null==t&&(t=null),i.__super__.setOptions.call(this,t),this.configPercentColors(),this.extraPadding=0,this.options.angle<0&&(o=Math.PI*(1+this.options.angle),this.extraPadding=Math.sin(o)),this.availableHeight=this.canvas.height*(1-this.paddingTop-this.paddingBottom),this.lineWidth=this.availableHeight*this.options.lineWidth,this.radius=(this.availableHeight-this.lineWidth/2)/(1+this.extraPadding),this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),a=this.gp,s=0,n=a.length;s=n;e=0<=n?++s:--s)a=parseInt(l(this.options.percentColors[e][1]).substring(0,2),16),i=parseInt(l(this.options.percentColors[e][1]).substring(2,4),16),t=parseInt(l(this.options.percentColors[e][1]).substring(4,6),16),o.push(this.percentColors[e]={pct:this.options.percentColors[e][0],color:{r:a,g:i,b:t}});return o}},i.prototype.set=function(t){var i,e,s,n,a,h,r,l,p;for(t instanceof Array||(t=[t]),e=s=0,r=t.length-1;0<=r?s<=r:s>=r;e=0<=r?++s:--s)t[e]=this.parseValue(t[e]);if(t.length>this.gp.length)for(e=n=0,l=t.length-this.gp.length;0<=l?nl;e=0<=l?++n:--n)i=new o(this),i.setOptions(this.options.pointer),this.gp.push(i);else t.lengththis.maxValue?this.options.limitMax?p=this.maxValue:this.maxValue=p+1:p=h;n=0<=h?++o:--o)if(t<=this.percentColors[n].pct){!0===i?(r=this.percentColors[n-1]||this.percentColors[0],s=this.percentColors[n],a=(t-r.pct)/(s.pct-r.pct),e={r:Math.floor(r.color.r*(1-a)+s.color.r*a),g:Math.floor(r.color.g*(1-a)+s.color.g*a),b:Math.floor(r.color.b*(1-a)+s.color.b*a)}):e=this.percentColors[n].color;break}return"rgb("+[e.r,e.g,e.b].join(",")+")"},i.prototype.getColorForValue=function(t,i){var e;return e=(t-this.minValue)/(this.maxValue-this.minValue),this.getColorForPercentage(e,i)},i.prototype.renderStaticLabels=function(t,i,e,s){var n,o,a,h,r,l,c,u,d,g;for(this.ctx.save(),this.ctx.translate(i,e),n=t.font||"10px Times",l=/\d+\.?\d?/,r=n.match(l)[0],u=n.slice(r.length),o=parseFloat(r)*this.displayScale,this.ctx.font=o+u,this.ctx.fillStyle=t.color||"#000000",this.ctx.textBaseline="bottom",this.ctx.textAlign="center",c=t.labels,a=0,h=c.length;a=this.minValue)&&(!this.options.limitMax||g<=this.maxValue)&&(n=g.font||t.font,r=n.match(l)[0],u=n.slice(r.length),o=parseFloat(r)*this.displayScale,this.ctx.font=o+u,d=this.getAngle(g.label)-3*Math.PI/2,this.ctx.rotate(d),this.ctx.fillText(p(g.label,t.fractionDigits),0,-s-this.lineWidth/2),this.ctx.rotate(-d)):(!this.options.limitMin||g>=this.minValue)&&(!this.options.limitMax||g<=this.maxValue)&&(d=this.getAngle(g)-3*Math.PI/2,this.ctx.rotate(d),this.ctx.fillText(p(g,t.fractionDigits),0,-s-this.lineWidth/2),this.ctx.rotate(-d));return this.ctx.restore()},i.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,C;if(t!=={}){for(l=t.divisions||0,S=t.subDivisions||0,a=t.divColor||"#fff",v=t.subColor||"#fff",h=t.divLength||.7,V=t.subLength||.2,u=parseFloat(this.maxValue)-parseFloat(this.minValue),d=parseFloat(u)/parseFloat(t.divisions),y=parseFloat(d)/parseFloat(t.subDivisions),n=parseFloat(this.minValue),o=0+y,c=u/400,r=c*(t.divWidth||1),w=c*(t.subWidth||1),m=[],M=p=0,g=l+1;p0?m.push(function(){var t,i,e;for(e=[],f=t=0,i=S-1;tthis.maxValue&&(r=this.maxValue),g=this.radius,x.height&&(this.ctx.lineWidth=this.lineWidth*x.height,d=this.lineWidth/2*(x.offset||1-x.height),g=this.radius*this.options.radiusScale+d),this.ctx.strokeStyle=x.strokeStyle,this.ctx.beginPath(),this.ctx.arc(0,0,g,this.getAngle(l),this.getAngle(r),!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(m,s,9,m,s,70):this.ctx.createLinearGradient(0,0,m,0),i.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(m,s,p,(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(m,s,p,t,(2-this.options.angle)*Math.PI,!1),this.ctx.stroke(),this.ctx.save(),this.ctx.translate(m,s);for(this.options.renderTicks&&this.renderTicks(this.options.renderTicks,m,s,p),this.ctx.restore(),this.ctx.translate(m,s),u=this.gp,o=0,h=u.length;othis.maxValue?this.options.limitMax?this.value=this.maxValue:this.maxValue=this.value:this.value1&&(n="."+e[1]),i=/(\d+)(\d{3})/;i.test(s);)s=s.replace(i,"$1,$2");return s+n},l=function(t){return"#"===t.charAt(0)?t.substring(1,7):t},h=function(){function t(t,i){null==t&&(t=!0),this.clear=null==i||i,t&&AnimationUpdater.add(this)}return t.prototype.animationSpeed=32,t.prototype.update=function(t){var i;return null==t&&(t=!1),!(!t&&this.displayedValue===this.value)&&(this.ctx&&this.clear&&this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),i=this.value-this.displayedValue,Math.abs(i/this.animationSpeed)<=.001?this.displayedValue=this.value:this.displayedValue=this.displayedValue+i/this.animationSpeed,this.render(),!0)},t}(),e=function(t){function i(){return i.__super__.constructor.apply(this,arguments)}return m(i,h),i.prototype.displayScale=1,i.prototype.forceUpdate=!0,i.prototype.setTextField=function(t,i){return this.textField=t instanceof a?t:new a(t,i)},i.prototype.setMinValue=function(t,i){var e,s,n,o,a;if(this.minValue=t,null==i&&(i=!0),i){for(this.displayedValue=this.minValue,a=[],s=0,n=(o=this.gp||[]).length;s.5&&(this.options.angle=.5),this.configDisplayScale(),this},i.prototype.configDisplayScale=function(){var t,i,e,s,n;return s=this.displayScale,!1===this.options.highDpiSupport?delete this.displayScale:(i=window.devicePixelRatio||1,t=this.ctx.webkitBackingStorePixelRatio||this.ctx.mozBackingStorePixelRatio||this.ctx.msBackingStorePixelRatio||this.ctx.oBackingStorePixelRatio||this.ctx.backingStorePixelRatio||1,this.displayScale=i/t),this.displayScale!==s&&(n=this.canvas.G__width||this.canvas.width,e=this.canvas.G__height||this.canvas.height,this.canvas.width=n*this.displayScale,this.canvas.height=e*this.displayScale,this.canvas.style.width=n+"px",this.canvas.style.height=e+"px",this.canvas.G__width=n,this.canvas.G__height=e),this},i.prototype.parseValue=function(t){return t=parseFloat(t)||Number(t),isFinite(t)?t:0},i}(),a=function(){function t(t,i){this.el=t,this.fractionDigits=i}return t.prototype.render=function(t){return this.el.innerHTML=p(t.displayedValue,this.fractionDigits)},t}(),t=function(t){function i(t,e){if(this.elem=t,this.text=null!=e&&e,i.__super__.constructor.call(this),void 0===this.elem)throw new Error("The element isn't defined.");this.value=1*this.elem.innerHTML,this.text&&(this.value=0)}return m(i,h),i.prototype.displayedValue=0,i.prototype.value=0,i.prototype.setVal=function(t){return this.value=1*t},i.prototype.render=function(){var t;return t=this.text?u(this.displayedValue.toFixed(0)):r(p(this.displayedValue)),this.elem.innerHTML=t},i}(),o=function(t){function i(t){if(this.gauge=t,i.__super__.constructor.call(this),void 0===this.gauge)throw new Error("The element isn't defined.");this.ctx=this.gauge.ctx,this.canvas=this.gauge.canvas,i.__super__.constructor.call(this,!1,!1),this.setOptions()}return m(i,h),i.prototype.displayedValue=0,i.prototype.value=0,i.prototype.options={strokeWidth:.035,length:.1,color:"#000000",iconPath:null,iconScale:1,iconAngle:0},i.prototype.img=null,i.prototype.setOptions=function(t){if(null==t&&(t=null),this.options=c(this.options,t),this.length=2*this.gauge.radius*this.gauge.options.radiusScale*this.options.length,this.strokeWidth=this.canvas.height*this.options.strokeWidth,this.maxValue=this.gauge.maxValue,this.minValue=this.gauge.minValue,this.animationSpeed=this.gauge.animationSpeed,this.options.angle=this.gauge.options.angle,this.options.iconPath)return this.img=new Image,this.img.src=this.options.iconPath},i.prototype.render=function(){var t,i,e,s,n,o,a,h,r;if(t=this.gauge.getAngle.call(this,this.displayedValue),h=Math.round(this.length*Math.cos(t)),r=Math.round(this.length*Math.sin(t)),o=Math.round(this.strokeWidth*Math.cos(t-Math.PI/2)),a=Math.round(this.strokeWidth*Math.sin(t-Math.PI/2)),i=Math.round(this.strokeWidth*Math.cos(t+Math.PI/2)),e=Math.round(this.strokeWidth*Math.sin(t+Math.PI/2)),this.ctx.beginPath(),this.ctx.fillStyle=this.options.color,this.ctx.arc(0,0,this.strokeWidth,0,2*Math.PI,!1),this.ctx.fill(),this.ctx.beginPath(),this.ctx.moveTo(o,a),this.ctx.lineTo(h,r),this.ctx.lineTo(i,e),this.ctx.fill(),this.img)return s=Math.round(this.img.width*this.options.iconScale),n=Math.round(this.img.height*this.options.iconScale),this.ctx.save(),this.ctx.translate(h,r),this.ctx.rotate(t+Math.PI/180*(90+this.options.iconAngle)),this.ctx.drawImage(this.img,-s/2,-n/2,s,n),this.ctx.restore()},i}(),function(){function t(t){this.elem=t}t.prototype.updateValues=function(t){return this.value=t[0],this.maxValue=t[1],this.avgValue=t[2],this.render()},t.prototype.render=function(){var t,i;return this.textField&&this.textField.text(p(this.value)),0===this.maxValue&&(this.maxValue=2*this.avgValue),i=this.value/this.maxValue*100,t=this.avgValue/this.maxValue*100,$(".bar-value",this.elem).css({width:i+"%"}),$(".typical-value",this.elem).css({width:t+"%"})}}(),n=function(t){function i(t){var e,s;this.canvas=t,i.__super__.constructor.call(this),this.percentColors=null,"undefined"!=typeof G_vmlCanvasManager&&(this.canvas=window.G_vmlCanvasManager.initElement(this.canvas)),this.ctx=this.canvas.getContext("2d"),e=this.canvas.clientHeight,s=this.canvas.clientWidth,this.canvas.height=e,this.canvas.width=s,this.gp=[new o(this)],this.setOptions()}return m(i,e),i.prototype.elem=null,i.prototype.value=[20],i.prototype.maxValue=80,i.prototype.minValue=0,i.prototype.displayedAngle=0,i.prototype.displayedValue=0,i.prototype.lineWidth=40,i.prototype.paddingTop=.1,i.prototype.paddingBottom=.1,i.prototype.percentColors=null,i.prototype.options={colorStart:"#6fadcf",colorStop:void 0,gradientType:0,strokeColor:"#e0e0e0",pointer:{length:.8,strokeWidth:.035,iconScale:1},angle:.15,lineWidth:.44,radiusScale:1,fontSize:40,limitMax:!1,limitMin:!1},i.prototype.setOptions=function(t){var e,s,n,o,a;for(null==t&&(t=null),i.__super__.setOptions.call(this,t),this.configPercentColors(),this.extraPadding=0,this.options.angle<0&&(o=Math.PI*(1+this.options.angle),this.extraPadding=Math.sin(o)),this.availableHeight=this.canvas.height*(1-this.paddingTop-this.paddingBottom),this.lineWidth=this.availableHeight*this.options.lineWidth,this.radius=(this.availableHeight-this.lineWidth/2)/(1+this.extraPadding),this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),s=0,n=(a=this.gp).length;s=n;e=0<=n?++s:--s)a=parseInt(l(this.options.percentColors[e][1]).substring(0,2),16),i=parseInt(l(this.options.percentColors[e][1]).substring(2,4),16),t=parseInt(l(this.options.percentColors[e][1]).substring(4,6),16),o.push(this.percentColors[e]={pct:this.options.percentColors[e][0],color:{r:a,g:i,b:t}});return o}},i.prototype.set=function(t){var i,e,s,n,a,h,r,l,p;for(t instanceof Array||(t=[t]),e=s=0,r=t.length-1;0<=r?s<=r:s>=r;e=0<=r?++s:--s)t[e]=this.parseValue(t[e]);if(t.length>this.gp.length)for(e=n=0,l=t.length-this.gp.length;0<=l?nl;e=0<=l?++n:--n)(i=new o(this)).setOptions(this.options.pointer),this.gp.push(i);else t.lengththis.maxValue?this.options.limitMax?p=this.maxValue:this.maxValue=p+1:p=h;n=0<=h?++o:--o)if(t<=this.percentColors[n].pct){!0===i?(r=this.percentColors[n-1]||this.percentColors[0],s=this.percentColors[n],a=(t-r.pct)/(s.pct-r.pct),e={r:Math.floor(r.color.r*(1-a)+s.color.r*a),g:Math.floor(r.color.g*(1-a)+s.color.g*a),b:Math.floor(r.color.b*(1-a)+s.color.b*a)}):e=this.percentColors[n].color;break}return"rgb("+[e.r,e.g,e.b].join(",")+")"},i.prototype.getColorForValue=function(t,i){var e;return e=(t-this.minValue)/(this.maxValue-this.minValue),this.getColorForPercentage(e,i)},i.prototype.renderStaticLabels=function(t,i,e,s){var n,o,a,h,r,l,c,u,d,g;for(this.ctx.save(),this.ctx.translate(i,e),l=/\d+\.?\d?/,r=(n=t.font||"10px Times").match(l)[0],u=n.slice(r.length),o=parseFloat(r)*this.displayScale,this.ctx.font=o+u,this.ctx.fillStyle=t.color||"#000000",this.ctx.textBaseline="bottom",this.ctx.textAlign="center",a=0,h=(c=t.labels).length;a=this.minValue)&&(!this.options.limitMax||g<=this.maxValue)&&(r=(n=g.font||t.font).match(l)[0],u=n.slice(r.length),o=parseFloat(r)*this.displayScale,this.ctx.font=o+u,d=this.getAngle(g.label)-3*Math.PI/2,this.ctx.rotate(d),this.ctx.fillText(p(g.label,t.fractionDigits),0,-s-this.lineWidth/2),this.ctx.rotate(-d)):(!this.options.limitMin||g>=this.minValue)&&(!this.options.limitMax||g<=this.maxValue)&&(d=this.getAngle(g)-3*Math.PI/2,this.ctx.rotate(d),this.ctx.fillText(p(g,t.fractionDigits),0,-s-this.lineWidth/2),this.ctx.rotate(-d));return this.ctx.restore()},i.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,C;if(t!=={}){for(l=t.divisions||0,S=t.subDivisions||0,a=t.divColor||"#fff",v=t.subColor||"#fff",h=t.divLength||.7,V=t.subLength||.2,u=parseFloat(this.maxValue)-parseFloat(this.minValue),d=parseFloat(u)/parseFloat(t.divisions),y=parseFloat(d)/parseFloat(t.subDivisions),n=parseFloat(this.minValue),o=0+y,r=(c=u/400)*(t.divWidth||1),w=c*(t.subWidth||1),m=[],M=p=0,g=l+1;p0?m.push(function(){var t,i,e;for(e=[],f=t=0,i=S-1;tthis.maxValue&&(h=this.maxValue),d=this.radius,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 +// TypeScript Version: 2.1 + +declare module 'gaugeJS' { + + interface BaseOptions { + + /** + * High resolution support + */ + highDpiSupport?: boolean + + /** + * Size of font + * + * @default 40 + */ + fontSize?: number; + + } + + export interface GaugeOptions extends BaseOptions { + + /** + * Colors. Just experiment with them to see which ones work best for you + * + * @default "#6fadcf" + */ + colorStart?: string + + /** + * Colors. Just experiment with them to see which ones work best for you + * + * @default undefined + */ + colorStop?: string + + /** + * 0 : radial, 1 : linear + * + * @default 0 + */ + gradientType?: 0 | 1; + + /** + * Colors. Just experiment with them to see which ones work best for you + * + * @default "#e0e0e0" + */ + strokeColor?: string + + /** + * General pointer settings + */ + pointer?: { + + /** + * Relative to gauge radius + * + * @default 0.8 + */ + length?: number + + /** + * The thickness + * + * @default 0.035 + */ + strokeWidth?: number + + /** + * Fill color + */ + color?: string + + /** + * Icon image source + */ + iconPath?: string + + /** + * Size scaling factor + * + * @default 1.0 + */ + iconScale?: number + + /** + * Rotation offset angle, degrees + */ + iconAngle?: number + } + + /** + * The span of the gauge arc + * + * @default 0.15 + */ + angle?: number + + + /** + * The line thickness + * + * @default 0.44 + */ + lineWidth?: number + + /** + * Relative radius + * + * @default 1.0 + */ + radiusScale?: number + + /** + * If false, max value increases automatically if value > maxValue + * + * @default false + */ + limitMax?: boolean + + /** + * If true, the min value of the gauge will be fixed + * + * @default false + */ + limitMin?: boolean + + + /** + * no documentation + */ + generateGradient?: boolean + + + /** + * Percentage color + * + * If you want to control how Gauge behavaes in relation to the displayed value you can use the Guage option called + * percentColors. To use it add following entry to the options + * + * @example + * + * percentColors = [[0.0, "#a9d70b" ], [0.50, "#f9c802"], [1.0, "#ff0000"]]; + * + * @see http://jsfiddle.net/berni/Yb4d7/ + */ + percentColors?: [ [ number, string ] ] + + /** + * Value labels + * + * For displaying value labels, enable the staticLabels option. A label will be printed at the given value just + * outside the display arc. + * + * @example + * + * staticLabels: { + * font: "10px sans-serif", + * labels: [100, 130, 150, 220.1, 260, 300], + * color: "#000000", + * fractionDigits: 0 + * }, + * + */ + staticLabels?: { + + /** + * Specifies font + */ + font: string + + /** + * Print labels at these values + */ + labels: [ number ] + + /** + * Label text color + */ + color?: string + + /** + * Numerical precision. 0=round off. + */ + fractionDigits?: number + + } + + /** + * Static zones + * + * When separating the background sectors or zones to have static colors, you must supply the staticZones property + * in the Gauge object's options. + * StaticZones, percentColors and gradient are mutually exclusive. If staticZones is defined, it will take + * precedence. + * Note: Zones should always be defined within the gauge objects .minValue and .maxValue limits. + * + * @example + * + * staticZones: [ + * {strokeStyle: "#F03E3E", min: 100, max: 130}, // Red from 100 to 130 + * {strokeStyle: "#FFDD00", min: 130, max: 150}, // Yellow + * {strokeStyle: "#30B32D", min: 150, max: 220}, // Green + * {strokeStyle: "#FFDD00", min: 220, max: 260}, // Yellow + * {strokeStyle: "#F03E3E", min: 260, max: 300} // Red + * ], + * + */ + staticZones?: [ { + + /** + * Color + */ + strokeStyle: string + + /** + * Beginn + */ + min: number + + /** + * End + */ + max: number + + } ] + + } + + export interface DonutOptions extends BaseOptions { + + /** + * The line thickness + * + * @default 0.10 + */ + lineWidth?: number + + /** + * Colors. Just experiment with them to see which ones work best for you + * + * @default "#6f6ea0" + */ + colorStart: string + + /** + * Colors. Just experiment with them to see which ones work best for you + * + * @default "#c0c0db" + */ + colorStop: string + + /** + * Colors. Just experiment with them to see which ones work best for you + * + * @default "#eeeeee" + */ + strokeColor?: string + + /** + * @default "#d5d5d5" + */ + shadowColor?: string + + /** + * The span of the gauge arc + * + * @default 0.35 + */ + angle?: number + + /** + * Relative radius + * + * @default 1.0 + */ + radiusScale?: number + + lineCap?: 'round' | 'butt' | 'square' + + } + + class BaseGauge { + + /** + * @default 1 + */ + displayScale: number; + + /** + * @default true + */ + forceUpdate: boolean; + + /** + * Set animation speed + * + * @default 32 + */ + animationSpeed: number; + + constructor(addToAnimationQueue?: true, clear?: true) + + update(force?: false): boolean + + setTextField(textField: TextRenderer | HTMLElement, fractionDigits?: number): void + + /** + * Set options + * + * @param {GaugeOptions} opts + */ + setOptions(opts?: GaugeOptions): void + + /** + * Prefer setter over gauge.minValue = 0 + * + * @param {number} val + * @param {true} updateStartValue + */ + setMinValue(val: number, updateStartValue?: true): void + + } + + export class Gauge extends BaseGauge { + + elem: HTMLCanvasElement; + + /** + * We support multiple pointers + */ + value: [ number ]; + + /** + * Set max gauge value + */ + maxValue: number; + + /** + * Set min gauge value + * + * @deprecated better use setMinValue() + */ + minValue: number; + + displayedAngle: number; + displayedValue: number; + lineWidth: number; + + /** + * @default 0.1 + */ + paddingTop: number; + + /** + * @default 0.1 + */ + paddingBottom: number; + + percentColors: any; + + options: GaugeOptions; + + /** + * @param {HTMLElement} target + */ + constructor(target: HTMLCanvasElement) + + /** + * Set actual value + * + * @param {number} val + */ + set(val: number): void + + render(): void + + } + + class BaseDonut extends BaseGauge { + + /** + * @default 15 + */ + lineWidth: number; + /** + * @default 0 + */ + displayedValue: number; + /** + * @default 33 + */ + value: number; + /** + * @default 80 + */ + maxValue: number; + /** + * @default 0 + */ + minValue: number; + + options: DonutOptions; + + /** + * @param {HTMLElement} target + */ + constructor(target: HTMLCanvasElement) + + /** + * Set options + * + * @param {DonutOptions} opts + */ + setOptions(opts?: DonutOptions): void + + /** + * Set actual value + * + * @param {number} val + */ + set(val: number): void + + render(): void + + } + + export class Donut extends BaseDonut { + } + + export class TextRenderer { + + constructor(el: HTMLElement, fractionDigits: number) + + /** + * Default behaviour, override to customize rendering + */ + render(): void + + } + +} diff --git a/package.json b/package.json index ca4788e..961e2e1 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,9 @@ "main": "dist/gauge.js", "repository": { "type": "git", - "url": "git@github.com:bernii/gauge.js.git" + "url": "https://github.com/razorness/gauge.js.git" }, + "types": "index.d.ts", "author": "bernii", "license": "MIT" }