Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit 6425b26baf14c5d3fe0396928d34257801744a17 @tblobaum committed Dec 23, 2011
Showing with 445 additions and 0 deletions.
  1. 0 LICENSE
  2. 0 README.md
  3. +28 −0 example.html
  4. +417 −0 gauge.js
0 LICENSE
No changes.
0 README.md
No changes.
28 example.html
@@ -0,0 +1,28 @@
+<script src='gauge.js'></script>
+<canvas id='ui-gauge-total'></canvas>
+<script>
+var gaugeTotal;
+var totalOptions = {
+ label: "Active",
+ bands: [{
+ color: '#339BB9',
+ from: 0,
+ to: 5,
+ }],
+ value: 0,
+ min: 0,
+ max: 5,
+ majorTicks: 1,
+ minorTicks: 0,
+ // small ticks inside each major tick
+ greenFrom: 0,
+ greenTo: 0,
+ yellowFrom: 0,
+ yellowTo: 0,
+ redFrom: 0,
+ redTo: 0
+};
+
+// Draw gauge and use custom bands
+gaugeTotal = new Gauge(document.getElementById('ui-gauge-total'), totalOptions);
+</script>
417 gauge.js
@@ -0,0 +1,417 @@
+
+/*!
+ * Analyticker - Gauge
+ * Copyright(c) Thomas Blobaum
+ * MIT Licensed
+ *
+ * ORIGINAL
+ * Jsgauge 0.4.1
+ * http://code.google.com/p/jsgauge/
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/mit-license.php
+ */
+
+
+/*jslint browser: true */
+function Gauge( canvas, options ) {
+ var that = this;
+ this.canvas = canvas;
+ options = options || {};
+
+ // Gauge settings
+ this.settings = {
+ value: options.value || 0,
+ pointerValue: options.value || 0,
+ label: options.label || '',
+ unitsLabel: options.unitsLabel || '',
+ min: options.min || 0,
+ max: options.max || 50,
+ majorTicks: options.majorTicks || 5,
+ minorTicks: options.minorTicks || 0, // small ticks inside each major tick
+ bands: [].concat(options.bands || []),
+
+ // START - Deprecated
+ greenFrom: [].concat(options.greenFrom || 0),
+ greenTo: [].concat(options.greenTo || 0),
+ yellowFrom: [].concat(options.yellowFrom || 0),
+ yellowTo: [].concat(options.yellowTo || 0),
+ redFrom: [].concat(options.redFrom || 0),
+ redTo: [].concat(options.redTo || 0)
+ // END - Deprecated
+ };
+
+ // settings normalized to a [0, 100] interval
+ function normalize( settings ) {
+ var i,
+ span = settings.max - settings.min,
+ spanPct = span/50,
+ normalized;
+
+ // Restrict pointer to range of values
+ if (settings.pointerValue > settings.max){
+ settings.pointerValue = settings.max;
+ } else if(settings.pointerValue < settings.min){
+ settings.pointerValue = settings.min;
+ }
+
+ normalized = {
+ min: 0,
+ max: 50,
+ value: ( settings.value - settings.min ) / spanPct,
+ pointerValue: ( settings.pointerValue - settings.min ) / spanPct,
+ label: settings.label || '',
+ greenFrom: [],
+ greenTo: [],
+ yellowFrom: [],
+ yellowTo: [],
+ redFrom: [],
+ redTo: [],
+ bands: [],
+ // also fix some possible invalid settings
+ majorTicks: Math.max( 2, settings.majorTicks ),
+ minorTicks: Math.max( 0, settings.minorTicks ),
+ decimals: Math.max( 0, 3 - ( settings.max - settings.min ).toFixed( 0 ).length )
+ };
+
+ for(i=settings.bands.length;i--;) {
+ var band = settings.bands[i];
+ normalized.bands[i] = {
+ color: band.color,
+ from: (band.from - settings.min)/spanPct,
+ to: (band.to - settings.min)/spanPct
+ };
+ }
+
+ return normalized;
+ }
+
+
+ // Colors used to render the gauge
+ this.colors = {
+ text: options.colorOfText || 'rgb(25, 25, 25)',
+ warningText: options.colorOfWarningText || 'rgb(255, 0, 0)',
+ fill: options.colorOfFill || ['rgba(150, 150, 150, 0)'],
+ pointerFill: options.colorOfPointerFill || 'rgba(25, 25, 25, 1)',
+ pointerStroke: options.colorOfPointerStroke || 'rgba(25, 25, 25, 1)',
+ centerCircleFill: options.colorOfCenterCircleFill || 'rgba(25, 25, 25, 1)',
+ centerCircleStroke: options.colorOfCenterCircleStroke || 'rgba(50, 50, 55, .8)',
+
+ // START - Deprecated
+ redBand: options.colorOfRedBand || options.redColor || 'rgba(255, 0, 0, 0.2)',
+ yelBand: options.colorOfYellowBand || options.yellowColor || 'rgba(255, 215, 0, 0.2)',
+ grnBand: options.colorOfGreenBand || options.greenColor || 'rgba(0, 255, 0, 0.2)'
+ // END - Deprecated
+ };
+
+ // Add colors to the bands object
+ for(var i=this.settings.redFrom.length; i--;){
+ this.settings.bands.push({ // Red
+ color: this.colors.redBand,
+ from: this.settings.redFrom[i],
+ to: this.settings.redTo[i]
+ });
+ }
+ for(i=this.settings.yellowFrom.length; i--;){
+ this.settings.bands.push({ // Yellow
+ color: this.colors.yelBand,
+ from: this.settings.yellowFrom[i],
+ to: this.settings.yellowTo[i]
+ });
+ }
+ for(i=this.settings.greenFrom.length; i--;){
+ this.settings.bands.push({ // Green
+ color: this.colors.grnBand,
+ from: this.settings.greenFrom[i],
+ to: this.settings.greenTo[i]
+ });
+ }
+
+ // draw context contains a set of values useful for
+ // most drawing operations.
+ this.relSettings = normalize( this.settings );
+
+ // Private helper functions
+ function styleText( context, style ) {
+ context.font = style;
+ context.mozTextStyle = style; // FF3
+ }
+
+ function measureText(context, text) {
+ if (context.measureText) {
+ return context.measureText(text).width; //-->
+ } else if (context.mozMeasureText) { //FF < 3.5
+ return context.mozMeasureText(text); //-->
+ }
+ throw "measureText() not supported!";
+ }
+
+ function fillText(context, text, px, py) {
+ var width;
+ if (context.fillText) {
+ return context.fillText(text, px, py);
+ } else if (context.mozDrawText) { //FF < 3.5
+ context.save();
+ context.translate(px, py);
+ width = context.mozDrawText(text);
+ context.restore();
+ return width;
+ }
+ throw "fillText() not supported!";
+ }
+
+ this.drawBackground = function( ) {
+ var fill = that.colors.fill,
+ rad = [ this.radius, this.radius - 1, this.radius * 0.98, this.radius * 0.95 ],
+ i;
+
+ this.c2d.rotate( this.startDeg );
+ for ( i = 0; i < fill.length; i++ ) {
+ this.c2d.fillStyle = fill[ i ];
+ this.c2d.beginPath();
+ this.c2d.arc( 0, 0, rad[ i ], 0, this.spanDeg, false );
+ this.c2d.fill();
+ }
+ };
+
+ this.drawRange = function( from, to, style ) {
+ if ( to > from ) {
+ var span = this.spanDeg * ( to - from ) / 50;
+
+ this.c2d.rotate( this.startDeg );
+ this.c2d.fillStyle = style;
+ this.c2d.rotate( this.spanDeg * from / 50 );
+ this.c2d.beginPath();
+ this.c2d.moveTo( this.innerRadius, 0 );
+ this.c2d.lineTo( this.outerRadius, 0 );
+ this.c2d.arc( 0, 0, this.outerRadius, 0, span, false );
+ this.c2d.rotate( span );
+ this.c2d.lineTo( this.innerRadius, 0 );
+ this.c2d.arc( 0, 0, this.innerRadius, 0, - span, true );
+ this.c2d.fill();
+ }
+ };
+
+ this.drawTicks = function( majorTicks, minorTicks ) {
+ var majorSpan,
+ i, j;
+ // major ticks
+ this.c2d.rotate( this.startDeg );
+ this.c2d.lineWidth = this.radius * 0;
+ majorSpan = this.spanDeg / ( majorTicks - 1 );
+ for ( i = 0; i < majorTicks; i++ ) {
+ this.c2d.beginPath();
+ this.c2d.moveTo( this.innerRadius,0 );
+ this.c2d.lineTo( this.outerRadius,0 );
+ //this.c2d.stroke();
+
+ // minor ticks
+ if ( i + 1 < majorTicks ) {
+ this.c2d.save();
+ this.c2d.lineWidth = this.radius * 0;
+ var minorSpan = majorSpan / ( minorTicks + 1 );
+ for ( j = 0; j < minorTicks; j++ ) {
+ this.c2d.rotate( minorSpan );
+ this.c2d.beginPath();
+ this.c2d.moveTo( this.innerRadius + ( this.outerRadius - this.innerRadius ) / 1, 0 );
+ this.c2d.lineTo( this.outerRadius, 0 );
+ //this.c2d.stroke();
+ }
+ this.c2d.restore();
+ }
+ this.c2d.rotate( majorSpan );
+ }
+ };
+
+ this.drawPointer = function( value ) {
+
+ function pointer( ctx ) {
+ ctx.c2d.beginPath();
+ ctx.c2d.moveTo( - ctx.radius * 0.05, 0 );
+ ctx.c2d.lineTo( 0, ctx.radius * 0.05 );
+ ctx.c2d.lineTo( ctx.radius * 1.1, 0 );
+ ctx.c2d.lineTo( 0, - ctx.radius * 0.05 );
+ ctx.c2d.lineTo( - ctx.radius * 0.05, 0 );
+ }
+ this.c2d.rotate( this.startDeg );
+ this.c2d.rotate( this.spanDeg * value / 100 );
+ this.c2d.lineWidth = this.radius * 0.0075;
+ this.c2d.fillStyle = that.colors.pointerFill;
+ pointer( this );
+ this.c2d.fill();
+ this.c2d.strokeStyle = that.colors.pointerStroke;
+ pointer( this );
+ this.c2d.stroke();
+ // center circle
+ this.c2d.fillStyle = that.colors.centerCircleFill;
+ this.c2d.beginPath();
+ this.c2d.arc( 0, 0, this.radius * 0.005, 0, Math.PI * 2, true );
+ this.c2d.fill();
+ this.c2d.strokeStyle = that.colors.centerCircleStroke;
+ this.c2d.beginPath();
+ this.c2d.arc( 0, 0, this.radius * 0.005, 0, Math.PI * 2, true );
+ this.c2d.stroke();
+
+ };
+
+ this.drawCaption = function( label ) {
+ if ( label ) {
+ var fontSize = this.radius / 4;
+ styleText( this.c2d, fontSize.toFixed(0) + 'px sans-serif');
+ var metrics = measureText( this.c2d, label );
+ this.c2d.fillStyle = that.colors.text;
+ var px = - metrics/ 2;
+ var py = - this.radius * 0.1 + fontSize * 5;
+ //fillText( this.c2d, label, px, py );
+ }
+ };
+
+ this.drawValues = function( min, max, value, decimals ) {
+ var deg, fontSize, metrics, valueText;
+ function formatNum( value, decimals ) {
+ var ret = value.toFixed( decimals );
+ while ( ( decimals > 0 ) && ret.match( /^\d+\.(\d+)?0$/ ) ) {
+ decimals -= 1;
+ ret = value.toFixed( decimals );
+ }
+ return ret;
+ }
+
+ // value text
+ valueText = formatNum( value, decimals ) + that.settings.unitsLabel;
+ fontSize = this.radius / 2;
+ styleText( this.c2d, fontSize.toFixed(0) + 'px sans-serif');
+ metrics = measureText( this.c2d, valueText );
+ if (value < min || value > max) { // Outside min/max ranges?
+ this.c2d.fillStyle = that.colors.warningText;
+ } else {
+ this.c2d.fillStyle = that.colors.text;
+ }
+ //fillText( this.c2d, valueText, - metrics/ 2, this.radius * 0.72 );
+
+ // min label
+ this.save();
+ deg = Math.PI * 12/8;
+ this.c2d.translate( this.radius * 0.65 * Math.sin( deg ),
+ this.radius * 0.65 * Math.cos( deg ) );
+ fontSize = this.radius / 4;
+ styleText( this.c2d, fontSize.toFixed(0) + 'px sans-serif');
+ this.c2d.fillStyle = that.colors.text;
+ //fillText( this.c2d, formatNum( min, decimals ), 0, 0 );
+ //fillText( this.c2d, 'min', -12, 12 );
+ this.restore();
+
+ // max label
+ this.save();
+ deg = Math.PI * 20/8;
+ this.c2d.translate( this.radius * 0.65 * Math.sin( deg ),
+ this.radius * 0.65 * Math.cos( deg ) );
+ fontSize = this.radius / 4;
+ styleText( this.c2d, fontSize.toFixed(0) + 'px sans-serif');
+ metrics = measureText( this.c2d, formatNum( max, decimals ) );
+ this.c2d.fillStyle = that.colors.text;
+ //fillText( this.c2d, formatNum( max, decimals ), -12, 0 );
+ //fillText( this.c2d, 'max', -12, 12 );
+ this.restore();
+ };
+
+ this.draw();
+
+ return this;
+}
+
+ Gauge.prototype.setValue = function( value ) {
+ var that = this,
+ pointerValue = (value > that.settings.max) ?
+ that.settings.max : // Nomalize to max value
+ (value < that.settings.min) ?
+ that.settings.min : // Nomalize to min value
+ value,
+ increment = Math.abs( that.settings.pointerValue - pointerValue ) / 20;
+
+ function adjustValue() {
+ var span;
+ if ( that.settings.pointerValue < pointerValue ) {
+ that.settings.pointerValue += increment;
+ if ( that.settings.pointerValue + increment >= pointerValue ) {
+ that.settings.pointerValue = pointerValue;
+ }
+ } else {
+ that.settings.pointerValue -= increment;
+ if ( that.settings.pointerValue - increment <= pointerValue ) {
+ that.settings.pointerValue = pointerValue;
+ }
+ }
+ span = that.settings.max - that.settings.min;
+ that.relSettings.pointerValue = (that.settings.pointerValue -
+ that.settings.min) / (span / 100);
+ that.draw();
+ if (that.settings.pointerValue != pointerValue) {
+ setTimeout(adjustValue, 50); // Draw another frame
+ }
+ }
+
+ if ( !isNaN(value) && this.settings.value !== value ) {
+ this.settings.value = value;
+ adjustValue();
+ }
+ };
+
+ Gauge.prototype.draw = function() {
+ var r, g, y;
+
+ if ( ! this.canvas.getContext ) {
+ return; //-->
+ }
+
+ var drawCtx = {
+ c2d: this.canvas.getContext( '2d' ),
+ startDeg: Math.PI * 9.5 / 8,
+ spanDeg: Math.PI * 5 / 8,
+ save: function() {
+ this.c2d.save();
+ },
+ restore: function() {
+ this.c2d.restore();
+ },
+ call: function( fn ) {
+ var args = Array.prototype.slice.call( arguments );
+ this.save();
+ this.translateCenter();
+ fn.apply( this, args.slice( 1 ) );
+ this.restore();
+ },
+ clear: function() {
+ this.c2d.clearRect( 0, 0, this.width, this.height );
+ },
+ translateCenter: function() {
+ this.c2d.translate( this.centerX, this.centerY );
+ }
+ };
+
+ drawCtx.width = drawCtx.c2d.canvas.width;
+ drawCtx.height = drawCtx.c2d.canvas.height;
+ drawCtx.radius = Math.min( drawCtx.width / 2 - 4, drawCtx.height / 2 - 4 );
+ drawCtx.innerRadius = drawCtx.radius * 0.5;
+ drawCtx.outerRadius = drawCtx.radius * 1.0;
+ drawCtx.centerX = drawCtx.radius + 5;
+ drawCtx.centerY = drawCtx.radius - 40 + ( drawCtx.radius -
+ drawCtx.radius * Math.sin( drawCtx.startDeg ) ) / 2;
+
+ // draw everything
+ drawCtx.clear();
+ drawCtx.call( this.drawBackground );
+ for(var i = this.relSettings.bands.length; i--;) {
+ var band = this.relSettings.bands[i];
+ drawCtx.call(this.drawRange, band.from, band.to, band.color);
+ }
+ drawCtx.call( this.drawTicks, this.relSettings.majorTicks, this.relSettings.minorTicks );
+ drawCtx.call( this.drawPointer, this.relSettings.pointerValue );
+ drawCtx.call( this.drawCaption, this.relSettings.label );
+ drawCtx.call( this.drawValues,
+ this.settings.min,
+ this.settings.max,
+ this.settings.value,
+ this.relSettings.decimals );
+ };
+

0 comments on commit 6425b26

Please sign in to comment.