mirror of
https://github.com/ail-project/ail-framework.git
synced 2024-11-26 15:57:16 +00:00
Added script flexgauge
This commit is contained in:
parent
c12e67a35a
commit
f0b527167a
1 changed files with 438 additions and 0 deletions
438
var/www/static/js/FlexGauge.js
Normal file
438
var/www/static/js/FlexGauge.js
Normal file
|
@ -0,0 +1,438 @@
|
|||
/**
|
||||
* FlexGauge
|
||||
* Version: 1.0
|
||||
* Author: Jeff Millies
|
||||
* Author URI:
|
||||
*/
|
||||
(function ($) {
|
||||
var FlexGauge = function (o) {
|
||||
if (typeof o === 'object') {
|
||||
this._extendOptions(o, false);
|
||||
this._build();
|
||||
}
|
||||
};
|
||||
FlexGauge.prototype = {
|
||||
/**
|
||||
* {String} Element that you would like to append to. ie '#idname', '.classname', 'div#idname', etc..
|
||||
*/
|
||||
appendTo: 'body',
|
||||
/**
|
||||
* {String} Id of Canvas already created or Id of canvas that will be created automatically
|
||||
*/
|
||||
elementId: 'canvas',
|
||||
/**
|
||||
* {String} Class of canvas created
|
||||
*/
|
||||
elementClass: 'canvas',
|
||||
/**
|
||||
* {Int} Canvas Width & Height
|
||||
*/
|
||||
elementWidth: 200,
|
||||
elementHeight: 200,
|
||||
/**
|
||||
* {Boolean|String} Generate Dial Value for the Gauge, true will use arcFillPercent or arcFillInt
|
||||
* depending on provided values and specified dialUnits, string will use specified value
|
||||
*/
|
||||
dialValue: false,
|
||||
/**
|
||||
* {String} Class applied to div when dial is generated.
|
||||
*/
|
||||
dialClass: 'fg-dial',
|
||||
/**
|
||||
* {string: %|$| } Type of unit to use for the dial
|
||||
*/
|
||||
dialUnit: '%',
|
||||
/**
|
||||
* {string: before|after} Where the dial unit will be displayed
|
||||
*/
|
||||
dialUnitPosition: 'after',
|
||||
/**
|
||||
* {Boolean|String} Generate Label for the Gauge, true will use default "FlexGauge", string will use specified
|
||||
*/
|
||||
dialLabel: false,
|
||||
/**
|
||||
* {String} Class applied to div when label is generated.
|
||||
*/
|
||||
dialLabelClass: 'fg-dial-label',
|
||||
/**
|
||||
* {Int} Radius of the arc
|
||||
*/
|
||||
inc: 0.0,
|
||||
incTot: 1.0,
|
||||
/**
|
||||
* {Doule} Increment value
|
||||
*/
|
||||
arcSize: 85,
|
||||
/**
|
||||
* {double} Starting and Ending location of the arc, End always needs to be larger
|
||||
* arc(x, y, radius, startAngle, endAngle, anticlockwise)
|
||||
*/
|
||||
arcAngleStart: 0.85,
|
||||
arcAngleEnd: 2.15,
|
||||
/**
|
||||
* {double} Percentage the arc fills
|
||||
*/
|
||||
arcFillPercent: .5,
|
||||
/**
|
||||
* {Int} Starting and Ending values that are used to
|
||||
* find a difference for amount of units
|
||||
* ie: 60 (arcFillEnd) - 10 (arcFillStart) = 50
|
||||
*/
|
||||
arcFillStart: null,
|
||||
arcFillEnd: null,
|
||||
/**
|
||||
* {Int} Data used to find out what percentage of the
|
||||
* arc to fill. arcFillInt can be populated by
|
||||
* the difference of arcFillStart and arcFillEnd
|
||||
*/
|
||||
arcFillInt: null,
|
||||
arcFillTotal: null,
|
||||
/**
|
||||
* {Int} Color lightness: 0 - 255, 0 having no white added, 255 having all white and no color
|
||||
*/
|
||||
arcBgColorLight: 80,
|
||||
/**
|
||||
* {Int} Color saturation: 0 - 100, 0 having no color, 100 is full color
|
||||
*/
|
||||
arcBgColorSat: 60,
|
||||
/**
|
||||
* {Int} Size of the line marking the percentage
|
||||
*/
|
||||
arcStrokeFg: 30,
|
||||
/**
|
||||
* {Int} Size of the container holding the line
|
||||
*/
|
||||
arcStrokeBg: 30,
|
||||
|
||||
/**
|
||||
* {string: hex} Color of the line marking the percentage
|
||||
*/
|
||||
colorArcFg: '#5bc0de',
|
||||
/**
|
||||
* {string: hex} Color of the container holding the line, default is using the Fg color and lightening it
|
||||
*/
|
||||
colorArcBg: null,
|
||||
|
||||
/**
|
||||
* {String} Instead of providing a color or hex for the color, you can provide a class from the style
|
||||
* sheet and specify what you would like to grab for the color in styleSrc
|
||||
*/
|
||||
styleArcFg: null,
|
||||
styleArcBg: null,
|
||||
styleSrc: 'color',
|
||||
|
||||
/**
|
||||
* {Boolean} If set to false, then the graph will not be animated
|
||||
*/
|
||||
animateEasing: true,
|
||||
/**
|
||||
* {Int} Speed for the animation, 1 is fastest, higher the number, slower the animation
|
||||
*/
|
||||
animateSpeed: 5,
|
||||
/**
|
||||
* {Int} Math used in animation speed
|
||||
*/
|
||||
animateNumerator: 12,
|
||||
animateDivisor: 15,
|
||||
|
||||
/**
|
||||
* {double} Placeholder for current percentage while animating
|
||||
*/
|
||||
_animatePerc: 0.00,
|
||||
|
||||
/**
|
||||
* {Object} Placeholder for setInterval
|
||||
*/
|
||||
_animateLoop: null,
|
||||
|
||||
/**
|
||||
* {Object} Placeholder for canvas
|
||||
*/
|
||||
_canvas: null,
|
||||
|
||||
/**
|
||||
* {Object} Placeholder for canvas context
|
||||
*/
|
||||
_ctx: null,
|
||||
|
||||
update: function (o) {
|
||||
if (typeof o === 'object') {
|
||||
var difference;
|
||||
|
||||
// if using int, convert to percent to check difference
|
||||
if (typeof o.arcFillInt !== 'undefined' && o.arcFillInt == this.arcFillInt &&
|
||||
typeof o.arcFillTotal !== 'undefined' && o.arcFillTotal == this.arcFillTotal) {
|
||||
o.arcFillPercent = this.arcFillPercent;
|
||||
} else if (typeof o.arcFillInt !== 'undefined' && typeof o.arcFillTotal !== 'undefined' &&
|
||||
(o.arcFillInt != this.arcFillInt || o.arcFillTotal == this.arcFillTotal)) {
|
||||
o.arcFillPercent = (o.arcFillInt / o.arcFillTotal);
|
||||
} else if (typeof o.arcFillInt !== 'undefined' && typeof o.arcFillTotal === 'undefined' &&
|
||||
(o.arcFillInt != this.arcFillInt)) {
|
||||
o.arcFillPercent = (o.arcFillInt / this.arcFillTotal);
|
||||
}
|
||||
|
||||
if (typeof o.arcFillPercent !== 'undefined') {
|
||||
difference = Math.abs((this.arcFillPercent - o.arcFillPercent));
|
||||
} else {
|
||||
difference = this.arcFillPercent;
|
||||
}
|
||||
|
||||
this._extendOptions(o, true);
|
||||
|
||||
clearInterval(this._animateLoop);
|
||||
|
||||
if (difference > 0) {
|
||||
var that = this;
|
||||
this._animateLoop = setInterval(function () {
|
||||
return that._animate();
|
||||
}, (this.animateSpeed * this.animateNumerator) / (difference * this.animateDivisor));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_extendOptions: function (o, update) {
|
||||
var color = false;
|
||||
if (update)
|
||||
color = this.colorArcFg;
|
||||
|
||||
$.extend(this, o, true);
|
||||
|
||||
if (typeof o.arcFillStart !== 'undefined' && typeof o.arcFillEnd !== 'undefined' && typeof o.arcFillTotal !== 'undefined') {
|
||||
this.arcFillInt = (o.arcFillEnd - o.arcFillStart);
|
||||
}
|
||||
|
||||
if (typeof o.arcFillPercent === 'undefined' && this.arcFillInt !== null && this.arcFillInt >= 0 && this.arcFillTotal !== null && this.arcFillTotal > 0) {
|
||||
this.arcFillPercent = this.arcFillInt / this.arcFillTotal;
|
||||
}
|
||||
|
||||
if (typeof o.elementId === 'undefined') {
|
||||
this.elementId = 'fg-' + this.appendTo + '-canvas';
|
||||
}
|
||||
// supporting color if pass, changing to hex
|
||||
if (typeof o.colorArcFg !== 'undefined') {
|
||||
this.colorArcFg = colorToHex(o.colorArcFg);
|
||||
}
|
||||
|
||||
if (typeof o.colorArcBg !== 'undefined') {
|
||||
this.colorArcBg = colorToHex(o.colorArcBg);
|
||||
}
|
||||
|
||||
// only use the styleArcFg if colorArcFg wasn't specified in the options
|
||||
if (typeof o.styleArcFg !== 'undefined' && typeof o.colorArcFg === 'undefined') {
|
||||
this.colorArcFg = getStyleRuleValue(this.styleSrc, this.styleArcFg);
|
||||
}
|
||||
|
||||
if (typeof o.colorArcBg === 'undefined' && this.colorArcBg === null && this.colorArcFg !== null) {
|
||||
this.colorArcBg = this.colorArcFg;
|
||||
}
|
||||
|
||||
if (typeof this.colorArcBg !== null && (!update || colorToHex(this.colorArcFg) != colorToHex(color))) {
|
||||
if (colorToHex(this.colorArcFg) != colorToHex(color))
|
||||
this.colorArcBg = this.colorArcFg;
|
||||
|
||||
this.colorArcBg = shadeColor(this.colorArcBg, this.arcBgColorLight, this.arcBgColorSat);
|
||||
}
|
||||
|
||||
if (typeof o.dialLabel === 'boolean' && o.dialLabel) {
|
||||
this.dialLabel = 'FlexGauge';
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
_build: function () {
|
||||
if (document.getElementById(this.elementId) === null) {
|
||||
$(this.appendTo).append('<canvas id="' + this.elementId + '" width="' + this.elementWidth + '" height="' + this.elementHeight + '"></canvas>');
|
||||
}
|
||||
|
||||
this._canvas = document.getElementById(this.elementId);
|
||||
this._ctx = this._canvas.getContext("2d");
|
||||
|
||||
this.arcAngleStart = this.arcAngleStart * Math.PI;
|
||||
this.arcAngleEnd = this.arcAngleEnd * Math.PI;
|
||||
if (this.animateEasing === false) {
|
||||
this._animatePerc = this.arcFillPercent;
|
||||
}
|
||||
|
||||
var that = this;
|
||||
this._animateLoop = setInterval(function () {
|
||||
return that._animate();
|
||||
}, (this.animateSpeed * this.animateNumerator) / (this.arcFillPercent * this.animateDivisor));
|
||||
},
|
||||
|
||||
_animate: function () {
|
||||
var animateInt = Math.round(this._animatePerc * 100);
|
||||
var arcInt = Math.round(this.arcFillPercent * 100);
|
||||
|
||||
if (animateInt < arcInt)
|
||||
animateInt++;
|
||||
else
|
||||
animateInt--;
|
||||
|
||||
this._animatePerc = (animateInt / 100);
|
||||
if (animateInt === arcInt) {
|
||||
this.arcFillPercent = this._animatePerc;
|
||||
clearInterval(this._animateLoop);
|
||||
this._draw();
|
||||
}
|
||||
this._draw();
|
||||
},
|
||||
|
||||
_draw: function () {
|
||||
//Clear the canvas everytime a chart is drawn
|
||||
this._ctx.clearRect(0, 0, this.elementWidth, this.elementHeight);
|
||||
|
||||
//Background 360 degree arc
|
||||
this._ctx.beginPath();
|
||||
this._ctx.strokeStyle = this.colorArcBg;
|
||||
this._ctx.lineWidth = this.arcStrokeBg;
|
||||
this._ctx.arc(
|
||||
this.elementWidth / 2,
|
||||
this.elementHeight / 2 + 50,
|
||||
this.arcSize,
|
||||
0,
|
||||
Math.PI,
|
||||
true
|
||||
);
|
||||
|
||||
this._ctx.stroke();
|
||||
|
||||
//var newEnd = ((this.arcAngleEnd - this.arcAngleStart) * this._animatePerc) + this.arcAngleStart;
|
||||
var newStart;
|
||||
var newEnd;
|
||||
|
||||
var incArc = this.inc*Math.PI/2;
|
||||
if (this.inc >= 0.0){
|
||||
newStart = -Math.PI/2;
|
||||
newEnd = newStart + incArc;
|
||||
} else {
|
||||
newStart = -Math.PI/2 + incArc;
|
||||
newEnd = -Math.PI/2;
|
||||
}
|
||||
|
||||
var colorShadesTabRed = ['#ff0000','#ff4000','#ff8000','#ff9900','#ffbf00','#ffff00'];
|
||||
var colorShadesTabGreen = ['#ffff00','#E0FF00','#D0FF00','#a0ff00','#00ff00','#00ff40',];
|
||||
var colorValue = parseInt(Math.abs((this.inc / this.incTot) * 5));
|
||||
var theColor;
|
||||
if (this.inc >= 0.0)
|
||||
theColor = colorShadesTabGreen[colorValue];
|
||||
else
|
||||
theColor = colorShadesTabRed[5-colorValue];
|
||||
this.colorArcFg = theColor;
|
||||
|
||||
this._ctx.beginPath();
|
||||
this._ctx.strokeStyle = this.colorArcFg;
|
||||
this._ctx.lineWidth = this.arcStrokeFg;
|
||||
this._ctx.arc(
|
||||
this.elementWidth / 2,
|
||||
this.elementHeight / 2 + 50,
|
||||
this.arcSize,
|
||||
newStart,
|
||||
newEnd,
|
||||
false
|
||||
);
|
||||
this._ctx.stroke();
|
||||
this._renderLabel();
|
||||
},
|
||||
|
||||
_renderLabel: function () {
|
||||
if (this.dialValue) {
|
||||
var dialVal;
|
||||
var dial = $(this.appendTo).find('div.' + this.dialClass);
|
||||
if (dial.length === 0) {
|
||||
$(this.appendTo).append('<div class="' + this.dialClass + '"></div>');
|
||||
}
|
||||
dial = $(this.appendTo).find('div.' + this.dialClass);
|
||||
if (typeof this.dialValue === 'boolean') {
|
||||
switch (this.dialUnit) {
|
||||
case '%':
|
||||
dialVal = Math.round(this._animatePerc * 100);
|
||||
break;
|
||||
default:
|
||||
dialVal = Math.round(this.arcFillInt * (this._animatePerc / this.arcFillPercent));
|
||||
break;
|
||||
}
|
||||
dialVal = (isNaN(dialVal) ? 0 : dialVal);
|
||||
switch (this.dialUnitPosition) {
|
||||
case 'before':
|
||||
dialVal = this.dialUnit + dialVal;
|
||||
break;
|
||||
case 'after':
|
||||
dialVal = dialVal + this.dialUnit;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
dialVal = this.dialValue;
|
||||
}
|
||||
dial.html(dialVal)
|
||||
}
|
||||
if (this.dialLabel) {
|
||||
var label = $(this.appendTo).find('div.' + this.dialLabelClass);
|
||||
if (label.length === 0) {
|
||||
$(this.appendTo).append('<div class="' + this.dialLabelClass + '"></div>');
|
||||
}
|
||||
label = $(this.appendTo).find('div.' + this.dialLabelClass);
|
||||
label.html(this.dialLabel);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function shadeColor(col, amt, sat) {
|
||||
if (col[0] == "#") {
|
||||
col = col.slice(1);
|
||||
}
|
||||
|
||||
var num = parseInt(col, 16);
|
||||
|
||||
var r = (num >> 16) + amt;
|
||||
|
||||
if (r > 255) r = 255;
|
||||
else if (r < 0) r = 0;
|
||||
|
||||
var b = ((num >> 8) & 0x00FF) + amt;
|
||||
|
||||
if (b > 255) b = 255;
|
||||
else if (b < 0) b = 0;
|
||||
|
||||
var g = (num & 0x0000FF) + amt;
|
||||
|
||||
if (g > 255) g = 255;
|
||||
else if (g < 0) g = 0;
|
||||
|
||||
var gray = r * 0.3086 + g * 0.6094 + b * 0.0820;
|
||||
sat = (sat / 100);
|
||||
|
||||
r = Math.round(r * sat + gray * (1 - sat));
|
||||
g = Math.round(g * sat + gray * (1 - sat));
|
||||
b = Math.round(b * sat + gray * (1 - sat));
|
||||
return "#" + (g | (b << 8) | (r << 16)).toString(16);
|
||||
}
|
||||
|
||||
function getStyleRuleValue(style, selector) {
|
||||
$('body').append('<div id="getStyleRuleValue-' + selector + '"></div>');
|
||||
var element = $('#getStyleRuleValue-' + selector);
|
||||
element.addClass(selector);
|
||||
var color = element.css(style);
|
||||
var hex = colorToHex(color);
|
||||
element.remove();
|
||||
return hex;
|
||||
}
|
||||
|
||||
function colorToHex(color) {
|
||||
if (color[0] != 'r')
|
||||
return color;
|
||||
|
||||
var rgb = color.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
|
||||
return "#" +
|
||||
("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) +
|
||||
("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) +
|
||||
("0" + parseInt(rgb[3], 10).toString(16)).slice(-2);
|
||||
}
|
||||
|
||||
if (typeof define === 'function') {
|
||||
define('flex-gauge', ['jquery'], function ($) {
|
||||
return FlexGauge;
|
||||
});
|
||||
} else {
|
||||
window.FlexGauge = FlexGauge;
|
||||
}
|
||||
})(jQuery);
|
Loading…
Reference in a new issue