diff --git a/examples/animation-events-hooks.html b/examples/animation-events-hooks.html index 60ef273..5d9844e 100644 --- a/examples/animation-events-hooks.html +++ b/examples/animation-events-hooks.html @@ -1,11 +1,11 @@ - - - Animation events hooks - - - + + - -
-
-
-
+ +
+
+
-
- -

After every animation end, function will log it below.

-

-
- - - + + - + + - + \ No newline at end of file diff --git a/examples/counter.html b/examples/counter.html index 4069593..9563009 100644 --- a/examples/counter.html +++ b/examples/counter.html @@ -6,24 +6,24 @@ Counter @@ -35,24 +35,28 @@ - + \ No newline at end of file diff --git a/examples/custom-interval.htm b/examples/custom-interval.htm index 6c58bda..921239c 100644 --- a/examples/custom-interval.htm +++ b/examples/custom-interval.htm @@ -5,25 +5,25 @@ Custom interval @@ -32,7 +32,8 @@

- You need to measure, say, between 350 and 980? No problem, just tell it to justGage. Displayed value and color are calculated as a percentage in defined range, with optional min and max labels shown. + You need to measure, say, between 350 and 980? No problem, just tell it to justGage. Displayed value and color + are calculated as a percentage in defined range, with optional min and max labels shown.

Also, if displayed value is out of range, relax and kick your feet up - justGage will take care of it for you. @@ -40,43 +41,48 @@ - + \ No newline at end of file diff --git a/examples/custom-node.html b/examples/custom-node.html index 98964e1..2722e51 100644 --- a/examples/custom-node.html +++ b/examples/custom-node.html @@ -6,31 +6,31 @@ @@ -52,79 +52,84 @@ - + \ No newline at end of file diff --git a/examples/custom-sectors.html b/examples/custom-sectors.html index 2d7f6c4..950b6c9 100644 --- a/examples/custom-sectors.html +++ b/examples/custom-sectors.html @@ -2,54 +2,53 @@ - + Custom Sectors @@ -99,57 +98,63 @@

Value-based sectors

+ \ No newline at end of file diff --git a/examples/custom-value-renderer.html b/examples/custom-value-renderer.html index 70ad78f..9aad0e4 100644 --- a/examples/custom-value-renderer.html +++ b/examples/custom-value-renderer.html @@ -5,76 +5,76 @@ Custom Render Function @@ -84,35 +84,40 @@ - + \ No newline at end of file diff --git a/examples/customize-style.htm b/examples/customize-style.htm index 5669f4e..5d13306 100644 --- a/examples/customize-style.htm +++ b/examples/customize-style.htm @@ -1,48 +1,62 @@ - - Customize style - - - - - - -
-
-
-
-
-
-

- Not digging default style? Then mock your own, Picasso! JustGage features bunch of styling options including gauge width, gauge color and shadow, gauge level colors, colors for title, value, min & max etc. -

-

- Check non-minified version of justgage.js for list of all setup parameters. -

- - - - + + + - - + + + + \ No newline at end of file diff --git a/examples/display-remaining.html b/examples/display-remaining.html index 56e4820..b43fa7a 100644 --- a/examples/display-remaining.html +++ b/examples/display-remaining.html @@ -5,76 +5,76 @@ Guage @@ -84,23 +84,28 @@ - + \ No newline at end of file diff --git a/examples/font-options.html b/examples/font-options.html index a2e9691..1449c81 100644 --- a/examples/font-options.html +++ b/examples/font-options.html @@ -6,24 +6,24 @@ Counter @@ -35,30 +35,35 @@ - + \ No newline at end of file diff --git a/examples/format-number.html b/examples/format-number.html index 4bf2c36..12c08fb 100644 --- a/examples/format-number.html +++ b/examples/format-number.html @@ -6,24 +6,24 @@ Counter @@ -35,21 +35,25 @@ diff --git a/examples/html5-data-attribute-config.html b/examples/html5-data-attribute-config.html index 3c2ab0b..26d9ce2 100644 --- a/examples/html5-data-attribute-config.html +++ b/examples/html5-data-attribute-config.html @@ -2,7 +2,7 @@ - + html5 data-attribute setup @@ -37,18 +37,24 @@ + \ No newline at end of file diff --git a/examples/human-friendly-numbers.html b/examples/human-friendly-numbers.html index c28b677..f34ced2 100644 --- a/examples/human-friendly-numbers.html +++ b/examples/human-friendly-numbers.html @@ -5,76 +5,76 @@ Guage @@ -84,26 +84,31 @@ - + \ No newline at end of file diff --git a/examples/pointer.html b/examples/pointer.html index b20ae5f..ddb3c88 100644 --- a/examples/pointer.html +++ b/examples/pointer.html @@ -1,11 +1,11 @@ - - - Pointer - - - + + - -
-
-
-
-
-
-
-
-
-
-
-
-
+ +
+
+
-
- +
+
- - - + + - + + - + \ No newline at end of file diff --git a/examples/refresh-minimum-maximum.html b/examples/refresh-minimum-maximum.html index 61b5b4a..7e2be23 100644 --- a/examples/refresh-minimum-maximum.html +++ b/examples/refresh-minimum-maximum.html @@ -6,24 +6,24 @@ Refresh maximum @@ -39,40 +39,45 @@ - + \ No newline at end of file diff --git a/examples/reverse.html b/examples/reverse.html index c8f5899..ccdb4bc 100644 --- a/examples/reverse.html +++ b/examples/reverse.html @@ -69,6 +69,11 @@ - + \ No newline at end of file diff --git a/examples/update-object.html b/examples/update-object.html index dcec49a..aa49a33 100644 --- a/examples/update-object.html +++ b/examples/update-object.html @@ -6,24 +6,24 @@ Refresh object @@ -35,25 +35,29 @@ - + \ No newline at end of file diff --git a/justgage.js b/justgage.js index 7cb5f1a..5b40d46 100644 --- a/justgage.js +++ b/justgage.js @@ -1,611 +1,581 @@ /** - * JustGage - animated gauges using RaphaelJS + * JustGage - Animated gauges using RaphaelJS * Check http://www.justgage.com for official releases * Licensed under MIT. * @author Bojan Djuricic (@Toorshia) **/ +(function (root, factory) { + if (typeof define === "function" && define.amd) { + define(["raphael"], function (raphael) { + return (root.JustGage = factory(raphael)); + }); + } else if (typeof module === "object" && module.exports) { + module.exports = (root.JustGage = factory(require("raphael"))); + } + else { //node.js diverges from the CommonJS spec a bit by using module. So, to use it in other common js environments + root.JustGage = factory(Raphael); + } +}(this, function (Raphael) {//passing this as the root argument, and our module method from earlier as the factory argument. If we run this in the browser, this, will be the window. -JustGage = function(config) { + JustGage = function (config) { - var obj = this; + var obj = this; - // Helps in case developer wants to debug it. unobtrusive - if (config === null || config === undefined) { - console.log('* justgage: Make sure to pass options to the constructor!'); - return false; - } + // Helps in case developer wants to debug it. unobtrusive + if (config === null || config === undefined) { + console.log('* justgage: Make sure to pass options to the constructor!'); + return false; + } - if (config.id !== null && config.id !== undefined) { - obj.node = document.getElementById(config.id); - if (!obj.node) { - console.log('* justgage: No element with id : %s found', config.id); + if (config.id !== null && config.id !== undefined) { + obj.node = document.getElementById(config.id); + if (!obj.node) { + console.log('* justgage: No element with id : %s found', config.id); + return false; + } + } else if (config.parentNode !== null && config.parentNode !== undefined) { + obj.node = config.parentNode; + } else { + console.log('* justgage: Make sure to pass the existing element id or parentNode to the constructor.'); return false; } - } else if (config.parentNode !== null && config.parentNode !== undefined) { - obj.node = config.parentNode; - } else { - console.log('* justgage: Make sure to pass the existing element id or parentNode to the constructor.'); - return false; - } - var dataset = obj.node.dataset ? obj.node.dataset : {}; + var dataset = obj.node.dataset ? obj.node.dataset : {}; - // check for defaults - var defaults = (config.defaults !== null && config.defaults !== undefined) ? config.defaults : false; - if (defaults !== false) { - config = extend({}, config, defaults); - delete config.defaults; - } + // check for defaults + var defaults = (config.defaults !== null && config.defaults !== undefined) ? config.defaults : false; + if (defaults !== false) { + config = extend({}, config, defaults); + delete config.defaults; + } - // configurable parameters - obj.config = { - // id : string - // this is container element id - id: config.id, + // configurable parameters + obj.config = { + // id : string + // this is container element id + id: config.id, - // value : float - // value gauge is showing - value: kvLookup('value', config, dataset, 0, 'float'), + // value : float + // value gauge is showing + value: kvLookup('value', config, dataset, 0, 'float'), - // defaults : bool - // defaults parameter to use - defaults: kvLookup('defaults', config, dataset, 0, false), + // defaults : bool + // defaults parameter to use + defaults: kvLookup('defaults', config, dataset, 0, false), - // parentNode : node object - // this is container element - parentNode: kvLookup('parentNode', config, dataset, null), + // parentNode : node object + // this is container element + parentNode: kvLookup('parentNode', config, dataset, null), - // width : int - // gauge width - width: kvLookup('width', config, dataset, null), + // width : int + // gauge width + width: kvLookup('width', config, dataset, null), - // height : int - // gauge height - height: kvLookup('height', config, dataset, null), + // height : int + // gauge height + height: kvLookup('height', config, dataset, null), - // valueFontColor : string - // color of label showing current value - valueFontColor: kvLookup('valueFontColor', config, dataset, "#010101"), + // valueFontColor : string + // color of label showing current value + valueFontColor: kvLookup('valueFontColor', config, dataset, "#010101"), - // valueFontFamily : string - // color of label showing current value - valueFontFamily: kvLookup('valueFontFamily', config, dataset, "Arial"), + // valueFontFamily : string + // color of label showing current value + valueFontFamily: kvLookup('valueFontFamily', config, dataset, "Arial"), - // symbol : string - // special symbol to show next to value - symbol: kvLookup('symbol', config, dataset, ''), + // symbol : string + // special symbol to show next to value + symbol: kvLookup('symbol', config, dataset, ''), - // min : float - // min value - min: kvLookup('min', config, dataset, 0, 'float'), + // min : float + // min value + min: kvLookup('min', config, dataset, 0, 'float'), - // minTxt : string - // min value text - minTxt: kvLookup('minTxt', config, dataset, false), + // minTxt : string + // min value text + minTxt: kvLookup('minTxt', config, dataset, false), - // max : float - // max value - max: kvLookup('max', config, dataset, 100, 'float'), + // max : float + // max value + max: kvLookup('max', config, dataset, 100, 'float'), - // maxTxt : string - // max value text - maxTxt: kvLookup('maxTxt', config, dataset, false), + // maxTxt : string + // max value text + maxTxt: kvLookup('maxTxt', config, dataset, false), - // reverse : bool - // reverse min and max - reverse: kvLookup('reverse', config, dataset, false), + // reverse : bool + // reverse min and max + reverse: kvLookup('reverse', config, dataset, false), - // humanFriendlyDecimal : int - // number of decimal places for our human friendly number to contain - humanFriendlyDecimal: kvLookup('humanFriendlyDecimal', config, dataset, 0), + // humanFriendlyDecimal : int + // number of decimal places for our human friendly number to contain + humanFriendlyDecimal: kvLookup('humanFriendlyDecimal', config, dataset, 0), - // textRenderer: func - // function applied before rendering text - textRenderer: kvLookup('textRenderer', config, dataset, null), + // textRenderer: func + // function applied before rendering text + textRenderer: kvLookup('textRenderer', config, dataset, null), - // onAnimationEnd: func - // function applied after animation is done - onAnimationEnd: kvLookup('onAnimationEnd', config, dataset, null), + // onAnimationEnd: func + // function applied after animation is done + onAnimationEnd: kvLookup('onAnimationEnd', config, dataset, null), - // gaugeWidthScale : float - // width of the gauge element - gaugeWidthScale: kvLookup('gaugeWidthScale', config, dataset, 1.0), + // gaugeWidthScale : float + // width of the gauge element + gaugeWidthScale: kvLookup('gaugeWidthScale', config, dataset, 1.0), - // gaugeColor : string - // background color of gauge element - gaugeColor: kvLookup('gaugeColor', config, dataset, "#edebeb"), + // gaugeColor : string + // background color of gauge element + gaugeColor: kvLookup('gaugeColor', config, dataset, "#edebeb"), - // label : string - // text to show below value - label: kvLookup('label', config, dataset, ''), + // label : string + // text to show below value + label: kvLookup('label', config, dataset, ''), - // labelFontColor : string - // color of label showing label under value - labelFontColor: kvLookup('labelFontColor', config, dataset, "#b3b3b3"), + // labelFontColor : string + // color of label showing label under value + labelFontColor: kvLookup('labelFontColor', config, dataset, "#b3b3b3"), - // shadowOpacity : int - // 0 ~ 1 - shadowOpacity: kvLookup('shadowOpacity', config, dataset, 0.2), + // shadowOpacity : int + // 0 ~ 1 + shadowOpacity: kvLookup('shadowOpacity', config, dataset, 0.2), - // shadowSize: int - // inner shadow size - shadowSize: kvLookup('shadowSize', config, dataset, 5), + // shadowSize: int + // inner shadow size + shadowSize: kvLookup('shadowSize', config, dataset, 5), - // shadowVerticalOffset : int - // how much shadow is offset from top - shadowVerticalOffset: kvLookup('shadowVerticalOffset', config, dataset, 3), + // shadowVerticalOffset : int + // how much shadow is offset from top + shadowVerticalOffset: kvLookup('shadowVerticalOffset', config, dataset, 3), - // levelColors : string[] - // colors of indicator, from lower to upper, in RGB format - levelColors: kvLookup('levelColors', config, dataset, ["#a9d70b", "#f9c802", "#ff0000"], 'array', ','), + // levelColors : string[] + // colors of indicator, from lower to upper, in RGB format + levelColors: kvLookup('levelColors', config, dataset, ["#a9d70b", "#f9c802", "#ff0000"], 'array', ','), - // startAnimationTime : int - // length of initial animation - startAnimationTime: kvLookup('startAnimationTime', config, dataset, 700), + // startAnimationTime : int + // length of initial animation + startAnimationTime: kvLookup('startAnimationTime', config, dataset, 700), - // startAnimationType : string - // type of initial animation (linear, >, <, <>, bounce) - startAnimationType: kvLookup('startAnimationType', config, dataset, '>'), + // startAnimationType : string + // type of initial animation (linear, >, <, <>, bounce) + startAnimationType: kvLookup('startAnimationType', config, dataset, '>'), - // refreshAnimationTime : int - // length of refresh animation - refreshAnimationTime: kvLookup('refreshAnimationTime', config, dataset, 700), + // refreshAnimationTime : int + // length of refresh animation + refreshAnimationTime: kvLookup('refreshAnimationTime', config, dataset, 700), - // refreshAnimationType : string - // type of refresh animation (linear, >, <, <>, bounce) - refreshAnimationType: kvLookup('refreshAnimationType', config, dataset, '>'), + // refreshAnimationType : string + // type of refresh animation (linear, >, <, <>, bounce) + refreshAnimationType: kvLookup('refreshAnimationType', config, dataset, '>'), - // donutStartAngle : int - // angle to start from when in donut mode - donutStartAngle: kvLookup('donutStartAngle', config, dataset, 90), + // donutStartAngle : int + // angle to start from when in donut mode + donutStartAngle: kvLookup('donutStartAngle', config, dataset, 90), - // valueMinFontSize : int - // absolute minimum font size for the value - valueMinFontSize: kvLookup('valueMinFontSize', config, dataset, 16), + // valueMinFontSize : int + // absolute minimum font size for the value + valueMinFontSize: kvLookup('valueMinFontSize', config, dataset, 16), - // labelMinFontSize - // absolute minimum font size for the label - labelMinFontSize: kvLookup('labelMinFontSize', config, dataset, 10), + // labelMinFontSize + // absolute minimum font size for the label + labelMinFontSize: kvLookup('labelMinFontSize', config, dataset, 10), - // minLabelMinFontSize - // absolute minimum font size for the minimum label - minLabelMinFontSize: kvLookup('minLabelMinFontSize', config, dataset, 10), + // minLabelMinFontSize + // absolute minimum font size for the minimum label + minLabelMinFontSize: kvLookup('minLabelMinFontSize', config, dataset, 10), - // maxLabelMinFontSize - // absolute minimum font size for the maximum label - maxLabelMinFontSize: kvLookup('maxLabelMinFontSize', config, dataset, 10), + // maxLabelMinFontSize + // absolute minimum font size for the maximum label + maxLabelMinFontSize: kvLookup('maxLabelMinFontSize', config, dataset, 10), - // hideValue : bool - // hide value text - hideValue: kvLookup('hideValue', config, dataset, false), + // hideValue : bool + // hide value text + hideValue: kvLookup('hideValue', config, dataset, false), - // hideMinMax : bool - // hide min and max values - hideMinMax: kvLookup('hideMinMax', config, dataset, false), + // hideMinMax : bool + // hide min and max values + hideMinMax: kvLookup('hideMinMax', config, dataset, false), - // showInnerShadow : bool - // show inner shadow - showInnerShadow: kvLookup('showInnerShadow', config, dataset, false), + // showInnerShadow : bool + // show inner shadow + showInnerShadow: kvLookup('showInnerShadow', config, dataset, false), - // humanFriendly : bool - // convert large numbers for min, max, value to human friendly (e.g. 1234567 -> 1.23M) - humanFriendly: kvLookup('humanFriendly', config, dataset, false), + // humanFriendly : bool + // convert large numbers for min, max, value to human friendly (e.g. 1234567 -> 1.23M) + humanFriendly: kvLookup('humanFriendly', config, dataset, false), - // noGradient : bool - // whether to use gradual color change for value, or sector-based - noGradient: kvLookup('noGradient', config, dataset, false), + // noGradient : bool + // whether to use gradual color change for value, or sector-based + noGradient: kvLookup('noGradient', config, dataset, false), - // donut : bool - // show full donut gauge - donut: kvLookup('donut', config, dataset, false), + // donut : bool + // show full donut gauge + donut: kvLookup('donut', config, dataset, false), - // relativeGaugeSize : bool - // whether gauge size should follow changes in container element size - relativeGaugeSize: kvLookup('relativeGaugeSize', config, dataset, false), + // relativeGaugeSize : bool + // whether gauge size should follow changes in container element size + relativeGaugeSize: kvLookup('relativeGaugeSize', config, dataset, false), - // counter : bool - // animate level number change - counter: kvLookup('counter', config, dataset, false), + // counter : bool + // animate level number change + counter: kvLookup('counter', config, dataset, false), - // decimals : int - // number of digits after floating point - decimals: kvLookup('decimals', config, dataset, 0), + // decimals : int + // number of digits after floating point + decimals: kvLookup('decimals', config, dataset, 0), - // customSectors : object - // custom sectors colors. Expects an object with props - // percents : bool hi/lo are percents values - // ranges : array of objects : {hi, lo, color} - customSectors: kvLookup('customSectors', config, dataset, {}), - - // formatNumber: boolean - // formats numbers with commas where appropriate - formatNumber: kvLookup('formatNumber', config, dataset, false), - - // pointer : bool - // show value pointer - pointer: kvLookup('pointer', config, dataset, false), - - // pointerOptions : object - // define pointer look - pointerOptions: kvLookup('pointerOptions', config, dataset, {}), - - // displayRemaining: boolean - // replace display number with the number remaining to reach max - displayRemaining: kvLookup('displayRemaining', config, dataset, false) - }; + // customSectors : object + // custom sectors colors. Expects an object with props + // percents : bool hi/lo are percents values + // ranges : array of objects : {hi, lo, color} + customSectors: kvLookup('customSectors', config, dataset, {}), + + // formatNumber: boolean + // formats numbers with commas where appropriate + formatNumber: kvLookup('formatNumber', config, dataset, false), + + // pointer : bool + // show value pointer + pointer: kvLookup('pointer', config, dataset, false), + + // pointerOptions : object + // define pointer look + pointerOptions: kvLookup('pointerOptions', config, dataset, {}), + + // displayRemaining: boolean + // replace display number with the number remaining to reach max + displayRemaining: kvLookup('displayRemaining', config, dataset, false) + }; - // variables - var - canvasW, - canvasH, - widgetW, - widgetH, - aspect, - dx, - dy, - valueFontSize, - valueX, - valueY, - labelFontSize, - labelX, - labelY, - minFontSize, - minX, - minY, - maxFontSize, - maxX, - maxY; - - // overflow values - if (obj.config.value > obj.config.max) obj.config.value = obj.config.max; - if (obj.config.value < obj.config.min) obj.config.value = obj.config.min; - obj.originalValue = kvLookup('value', config, dataset, -1, 'float'); - - // create canvas - if (obj.config.id !== null && (document.getElementById(obj.config.id)) !== null) { - obj.canvas = Raphael(obj.config.id, "100%", "100%"); - } else if (obj.config.parentNode !== null) { - obj.canvas = Raphael(obj.config.parentNode, "100%", "100%"); - } + // variables + var + canvasW, + canvasH, + widgetW, + widgetH, + aspect, + dx, + dy, + valueFontSize, + valueX, + valueY, + labelFontSize, + labelX, + labelY, + minFontSize, + minX, + minY, + maxFontSize, + maxX, + maxY; + + // overflow values + if (obj.config.value > obj.config.max) obj.config.value = obj.config.max; + if (obj.config.value < obj.config.min) obj.config.value = obj.config.min; + obj.originalValue = kvLookup('value', config, dataset, -1, 'float'); + + // create canvas + if (obj.config.id !== null && (document.getElementById(obj.config.id)) !== null) { + obj.canvas = Raphael(obj.config.id, "100%", "100%"); + } else if (obj.config.parentNode !== null) { + obj.canvas = Raphael(obj.config.parentNode, "100%", "100%"); + } - // canvas dimensions - if (obj.config.relativeGaugeSize === true) { - if (obj.config.donut === true) { - obj.canvas.setViewBox(0, 0, 200, 200, true); - canvasW = 200; - canvasH = 200; - } else { + // canvas dimensions + if (obj.config.relativeGaugeSize === true) { + if (obj.config.donut === true) { + obj.canvas.setViewBox(0, 0, 200, 200, true); + canvasW = 200; + canvasH = 200; + } else { + obj.canvas.setViewBox(0, 0, 200, 100, true); + canvasW = 200; + canvasH = 100; + } + } else if (obj.config.width !== null && obj.config.height !== null) { + canvasW = obj.config.width; + canvasH = obj.config.height; + } else if (obj.config.parentNode !== null) { obj.canvas.setViewBox(0, 0, 200, 100, true); canvasW = 200; canvasH = 100; - } - } else if (obj.config.width !== null && obj.config.height !== null) { - canvasW = obj.config.width; - canvasH = obj.config.height; - } else if (obj.config.parentNode !== null) { - obj.canvas.setViewBox(0, 0, 200, 100, true); - canvasW = 200; - canvasH = 100; - } else { - canvasW = getStyle(document.getElementById(obj.config.id), "width").slice(0, -2) * 1; - canvasH = getStyle(document.getElementById(obj.config.id), "height").slice(0, -2) * 1; - } - - // widget dimensions - if (obj.config.donut === true) { - if (canvasW > canvasH) { // landscape - widgetH = canvasH; - widgetW = widgetH; - // width less than height - } else if (canvasW < canvasH) { // portrait - widgetW = canvasW; - widgetH = widgetW; - } else { // square - widgetW = canvasW; - widgetH = widgetW; - } - - // delta - dx = (canvasW - widgetW) / 2; - dy = (canvasH - widgetH) / 2; - - // value - valueFontSize = ((widgetH / 6.4) > 16) ? (widgetH / 5.4) : 18; - valueX = dx + widgetW / 2; - if (obj.config.label !== '') { - valueY = dy + widgetH / 1.85; } else { - valueY = dy + widgetH / 1.7; + canvasW = getStyle(document.getElementById(obj.config.id), "width").slice(0, -2) * 1; + canvasH = getStyle(document.getElementById(obj.config.id), "height").slice(0, -2) * 1; } - // label - labelFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; - labelX = dx + widgetW / 2; - labelY = valueY + labelFontSize; + // widget dimensions + if (obj.config.donut === true) { + if (canvasW > canvasH) { // landscape + widgetH = canvasH; + widgetW = widgetH; + // width less than height + } else if (canvasW < canvasH) { // portrait + widgetW = canvasW; + widgetH = widgetW; + } else { // square + widgetW = canvasW; + widgetH = widgetW; + } - // min - minFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; - minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; - minY = labelY; + // delta + dx = (canvasW - widgetW) / 2; + dy = (canvasH - widgetH) / 2; - // max - maxFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; - maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; - maxY = labelY; - } else { - if (canvasW > canvasH) { // landscape - widgetH = canvasH; - widgetW = widgetH * 2; - if (widgetW > canvasW) { //if width doesn't fit, rescale both - aspect = widgetW / canvasW; - widgetW = widgetW / aspect; - widgetH = widgetH / aspect; + // value + valueFontSize = ((widgetH / 6.4) > 16) ? (widgetH / 5.4) : 18; + valueX = dx + widgetW / 2; + if (obj.config.label !== '') { + valueY = dy + widgetH / 1.85; + } else { + valueY = dy + widgetH / 1.7; } - } else if (canvasW < canvasH) { // portrait - widgetW = canvasW; - widgetH = widgetW / 2; - } else { // square - widgetW = canvasW; - widgetH = widgetW * 0.5; - } - // delta - dx = (canvasW - widgetW) / 2; - dy = (canvasH - widgetH) / 2; + // label + labelFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; + labelX = dx + widgetW / 2; + labelY = valueY + labelFontSize; - // value - valueFontSize = ((widgetH / 6.5) > obj.config.valueMinFontSize) ? (widgetH / 6.5) : obj.config.valueMinFontSize; - valueX = dx + widgetW / 2; - valueY = dy + widgetH / 1.275; + // min + minFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; + minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; + minY = labelY; - // label - labelFontSize = ((widgetH / 16) > obj.config.labelMinFontSize) ? (widgetH / 16) : obj.config.labelMinFontSize; - labelX = dx + widgetW / 2; - labelY = valueY + valueFontSize / 2 + 5; + // max + maxFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; + maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; + maxY = labelY; + } else { + if (canvasW > canvasH) { // landscape + widgetH = canvasH; + widgetW = widgetH * 2; + if (widgetW > canvasW) { //if width doesn't fit, rescale both + aspect = widgetW / canvasW; + widgetW = widgetW / aspect; + widgetH = widgetH / aspect; + } + } else if (canvasW < canvasH) { // portrait + widgetW = canvasW; + widgetH = widgetW / 2; + } else { // square + widgetW = canvasW; + widgetH = widgetW * 0.5; + } - // min - minFontSize = ((widgetH / 16) > obj.config.minLabelMinFontSize) ? (widgetH / 16) : obj.config.minLabelMinFontSize; - minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; - minY = labelY; + // delta + dx = (canvasW - widgetW) / 2; + dy = (canvasH - widgetH) / 2; + + // value + valueFontSize = ((widgetH / 6.5) > obj.config.valueMinFontSize) ? (widgetH / 6.5) : obj.config.valueMinFontSize; + valueX = dx + widgetW / 2; + valueY = dy + widgetH / 1.275; + + // label + labelFontSize = ((widgetH / 16) > obj.config.labelMinFontSize) ? (widgetH / 16) : obj.config.labelMinFontSize; + labelX = dx + widgetW / 2; + labelY = valueY + valueFontSize / 2 + 5; + + // min + minFontSize = ((widgetH / 16) > obj.config.minLabelMinFontSize) ? (widgetH / 16) : obj.config.minLabelMinFontSize; + minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; + minY = labelY; + + // max + maxFontSize = ((widgetH / 16) > obj.config.maxLabelMinFontSize) ? (widgetH / 16) : obj.config.maxLabelMinFontSize; + maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; + maxY = labelY; + } - // max - maxFontSize = ((widgetH / 16) > obj.config.maxLabelMinFontSize) ? (widgetH / 16) : obj.config.maxLabelMinFontSize; - maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; - maxY = labelY; - } + // parameters + obj.params = { + canvasW: canvasW, + canvasH: canvasH, + widgetW: widgetW, + widgetH: widgetH, + dx: dx, + dy: dy, + valueFontSize: valueFontSize, + valueX: valueX, + valueY: valueY, + labelFontSize: labelFontSize, + labelX: labelX, + labelY: labelY, + minFontSize: minFontSize, + minX: minX, + minY: minY, + maxFontSize: maxFontSize, + maxX: maxX, + maxY: maxY + }; - // parameters - obj.params = { - canvasW: canvasW, - canvasH: canvasH, - widgetW: widgetW, - widgetH: widgetH, - dx: dx, - dy: dy, - valueFontSize: valueFontSize, - valueX: valueX, - valueY: valueY, - labelFontSize: labelFontSize, - labelX: labelX, - labelY: labelY, - minFontSize: minFontSize, - minX: minX, - minY: minY, - maxFontSize: maxFontSize, - maxX: maxX, - maxY: maxY - }; + // var clear + canvasW, canvasH, widgetW, widgetH, aspect, dx, dy, valueFontSize, valueX, valueY, labelFontSize, labelX, labelY, minFontSize, minX, minY, maxFontSize, maxX, maxY = null; - // var clear - canvasW, canvasH, widgetW, widgetH, aspect, dx, dy, valueFontSize, valueX, valueY, labelFontSize, labelX, labelY, minFontSize, minX, minY, maxFontSize, maxX, maxY = null; + // pki - custom attribute for generating gauge paths + obj.canvas.customAttributes.pki = function (value, min, max, w, h, dx, dy, gws, donut, reverse) { - // pki - custom attribute for generating gauge paths - obj.canvas.customAttributes.pki = function(value, min, max, w, h, dx, dy, gws, donut, reverse) { + var alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, path; - var alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, path; + if (min < 0) { + max -= min; + value -= min; + min = 0; + } - if (min < 0) { - max -= min; - value -= min; - min = 0; - } + if (donut) { + alpha = (1 - 2 * (value - min) / (max - min)) * Math.PI; + Ro = w / 2 - w / 30; + Ri = Ro - w / 6.666666666666667 * gws; - if (donut) { - alpha = (1 - 2 * (value - min) / (max - min)) * Math.PI; - Ro = w / 2 - w / 30; - Ri = Ro - w / 6.666666666666667 * gws; + Cx = w / 2 + dx; + Cy = h / 2 + dy; - Cx = w / 2 + dx; - Cy = h / 2 + dy; + Xo = Cx + Ro * Math.cos(alpha); + Yo = Cy - Ro * Math.sin(alpha); + Xi = Cx + Ri * Math.cos(alpha); + Yi = Cy - Ri * Math.sin(alpha); - Xo = Cx + Ro * Math.cos(alpha); - Yo = Cy - Ro * Math.sin(alpha); - Xi = Cx + Ri * Math.cos(alpha); - Yi = Cy - Ri * Math.sin(alpha); + path = "M" + (Cx - Ri) + "," + Cy + " "; + path += "L" + (Cx - Ro) + "," + Cy + " "; + if (value > ((max - min) / 2)) { + path += "A" + Ro + "," + Ro + " 0 0 1 " + (Cx + Ro) + "," + Cy + " "; + } + path += "A" + Ro + "," + Ro + " 0 0 1 " + Xo + "," + Yo + " "; + path += "L" + Xi + "," + Yi + " "; + if (value > ((max - min) / 2)) { + path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx + Ri) + "," + Cy + " "; + } + path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx - Ri) + "," + Cy + " "; + path += "Z "; - path = "M" + (Cx - Ri) + "," + Cy + " "; - path += "L" + (Cx - Ro) + "," + Cy + " "; - if (value > ((max - min) / 2)) { - path += "A" + Ro + "," + Ro + " 0 0 1 " + (Cx + Ro) + "," + Cy + " "; - } - path += "A" + Ro + "," + Ro + " 0 0 1 " + Xo + "," + Yo + " "; - path += "L" + Xi + "," + Yi + " "; - if (value > ((max - min) / 2)) { - path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx + Ri) + "," + Cy + " "; + return { + path: path + }; + } else { + alpha = (1 - (value - min) / (max - min)) * Math.PI; + Ro = w / 2 - w / 10; + Ri = Ro - w / 6.666666666666667 * gws; + + Cx = w / 2 + dx; + Cy = h / 1.25 + dy; + + // Xo = w / 2 + dx + Ro * Math.cos(alpha); + // Yo = h - (h - Cy) - Ro * Math.sin(alpha); + // Xi = w / 2 + dx + Ri * Math.cos(alpha); + // Yi = h - (h - Cy) - Ri * Math.sin(alpha); + + Xo = Cx + Ro * Math.cos(alpha); + Yo = Cy - Ro * Math.sin(alpha); + Xi = Cx + Ri * Math.cos(alpha); + Yi = Cy - Ri * Math.sin(alpha); + + path = "M" + (Cx - Ri) + "," + Cy + " "; + path += "L" + (Cx - Ro) + "," + Cy + " "; + path += "A" + Ro + "," + Ro + " 0 0 1 " + Xo + "," + Yo + " "; + path += "L" + Xi + "," + Yi + " "; + path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx - Ri) + "," + Cy + " "; + path += "Z "; + + return { + path: path + }; } - path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx - Ri) + "," + Cy + " "; - path += "Z "; - - return { - path: path - }; - } else { - alpha = (1 - (value - min) / (max - min)) * Math.PI; - Ro = w / 2 - w / 10; - Ri = Ro - w / 6.666666666666667 * gws; - - Cx = w / 2 + dx; - Cy = h / 1.25 + dy; - - // Xo = w / 2 + dx + Ro * Math.cos(alpha); - // Yo = h - (h - Cy) - Ro * Math.sin(alpha); - // Xi = w / 2 + dx + Ri * Math.cos(alpha); - // Yi = h - (h - Cy) - Ri * Math.sin(alpha); - - Xo = Cx + Ro * Math.cos(alpha); - Yo = Cy - Ro * Math.sin(alpha); - Xi = Cx + Ri * Math.cos(alpha); - Yi = Cy - Ri * Math.sin(alpha); - - path = "M" + (Cx - Ri) + "," + Cy + " "; - path += "L" + (Cx - Ro) + "," + Cy + " "; - path += "A" + Ro + "," + Ro + " 0 0 1 " + Xo + "," + Yo + " "; - path += "L" + Xi + "," + Yi + " "; - path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx - Ri) + "," + Cy + " "; - path += "Z "; - - return { - path: path - }; - } - // var clear - alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, path = null; - }; - - // ndl - custom attribute for generating needle path - obj.canvas.customAttributes.ndl = function(value, min, max, w, h, dx, dy, gws, donut) { + // var clear + alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, path = null; + }; - var dlt = w * 3.5 / 100; - var dlb = w / 15; - var dw = w / 100; + // ndl - custom attribute for generating needle path + obj.canvas.customAttributes.ndl = function (value, min, max, w, h, dx, dy, gws, donut) { - if (obj.config.pointerOptions.toplength != null && obj.config.pointerOptions.toplength != undefined) dlt = obj.config.pointerOptions.toplength; - if (obj.config.pointerOptions.bottomlength != null && obj.config.pointerOptions.bottomlength != undefined) dlb = obj.config.pointerOptions.bottomlength; - if (obj.config.pointerOptions.bottomwidth != null && obj.config.pointerOptions.bottomwidth != undefined) dw = obj.config.pointerOptions.bottomwidth; + var dlt = w * 3.5 / 100; + var dlb = w / 15; + var dw = w / 100; - var alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, Xc, Yc, Xz, Yz, Xa, Ya, Xb, Yb, path; + if (obj.config.pointerOptions.toplength != null && obj.config.pointerOptions.toplength != undefined) dlt = obj.config.pointerOptions.toplength; + if (obj.config.pointerOptions.bottomlength != null && obj.config.pointerOptions.bottomlength != undefined) dlb = obj.config.pointerOptions.bottomlength; + if (obj.config.pointerOptions.bottomwidth != null && obj.config.pointerOptions.bottomwidth != undefined) dw = obj.config.pointerOptions.bottomwidth; - if (donut) { + var alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, Xc, Yc, Xz, Yz, Xa, Ya, Xb, Yb, path; - alpha = (1 - 2 * (value - min) / (max - min)) * Math.PI; - Ro = w / 2 - w / 30; - Ri = Ro - w / 6.666666666666667 * gws; + if (donut) { - Cx = w / 2 + dx; - Cy = h / 2 + dy; + alpha = (1 - 2 * (value - min) / (max - min)) * Math.PI; + Ro = w / 2 - w / 30; + Ri = Ro - w / 6.666666666666667 * gws; - Xo = w / 2 + dx + Ro * Math.cos(alpha); - Yo = h - (h - Cy) - Ro * Math.sin(alpha); - Xi = w / 2 + dx + Ri * Math.cos(alpha); - Yi = h - (h - Cy) - Ri * Math.sin(alpha); + Cx = w / 2 + dx; + Cy = h / 2 + dy; - Xc = Xo + dlt * Math.cos(alpha); - Yc = Yo - dlt * Math.sin(alpha); - Xz = Xi - dlb * Math.cos(alpha); - Yz = Yi + dlb * Math.sin(alpha); + Xo = w / 2 + dx + Ro * Math.cos(alpha); + Yo = h - (h - Cy) - Ro * Math.sin(alpha); + Xi = w / 2 + dx + Ri * Math.cos(alpha); + Yi = h - (h - Cy) - Ri * Math.sin(alpha); - Xa = Xz + dw * Math.sin(alpha); - Ya = Yz + dw * Math.cos(alpha); - Xb = Xz - dw * Math.sin(alpha); - Yb = Yz - dw * Math.cos(alpha); + Xc = Xo + dlt * Math.cos(alpha); + Yc = Yo - dlt * Math.sin(alpha); + Xz = Xi - dlb * Math.cos(alpha); + Yz = Yi + dlb * Math.sin(alpha); - path = 'M' + Xa + ',' + Ya + ' '; - path += 'L' + Xb + ',' + Yb + ' '; - path += 'L' + Xc + ',' + Yc + ' '; - path += 'Z '; + Xa = Xz + dw * Math.sin(alpha); + Ya = Yz + dw * Math.cos(alpha); + Xb = Xz - dw * Math.sin(alpha); + Yb = Yz - dw * Math.cos(alpha); - return { - path: path - }; + path = 'M' + Xa + ',' + Ya + ' '; + path += 'L' + Xb + ',' + Yb + ' '; + path += 'L' + Xc + ',' + Yc + ' '; + path += 'Z '; - } else { - alpha = (1 - (value - min) / (max - min)) * Math.PI; - Ro = w / 2 - w / 10; - Ri = Ro - w / 6.666666666666667 * gws; - - Cx = w / 2 + dx; - Cy = h / 1.25 + dy; - - Xo = w / 2 + dx + Ro * Math.cos(alpha); - Yo = h - (h - Cy) - Ro * Math.sin(alpha); - Xi = w / 2 + dx + Ri * Math.cos(alpha); - Yi = h - (h - Cy) - Ri * Math.sin(alpha); - - Xc = Xo + dlt * Math.cos(alpha); - Yc = Yo - dlt * Math.sin(alpha); - Xz = Xi - dlb * Math.cos(alpha); - Yz = Yi + dlb * Math.sin(alpha); - - Xa = Xz + dw * Math.sin(alpha); - Ya = Yz + dw * Math.cos(alpha); - Xb = Xz - dw * Math.sin(alpha); - Yb = Yz - dw * Math.cos(alpha); - - path = 'M' + Xa + ',' + Ya + ' '; - path += 'L' + Xb + ',' + Yb + ' '; - path += 'L' + Xc + ',' + Yc + ' '; - path += 'Z '; - - return { - path: path - }; - } + return { + path: path + }; - // var clear - alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, Xc, Yc, Xz, Yz, Xa, Ya, Xb, Yb, path = null; - }; + } else { + alpha = (1 - (value - min) / (max - min)) * Math.PI; + Ro = w / 2 - w / 10; + Ri = Ro - w / 6.666666666666667 * gws; + + Cx = w / 2 + dx; + Cy = h / 1.25 + dy; + + Xo = w / 2 + dx + Ro * Math.cos(alpha); + Yo = h - (h - Cy) - Ro * Math.sin(alpha); + Xi = w / 2 + dx + Ri * Math.cos(alpha); + Yi = h - (h - Cy) - Ri * Math.sin(alpha); + + Xc = Xo + dlt * Math.cos(alpha); + Yc = Yo - dlt * Math.sin(alpha); + Xz = Xi - dlb * Math.cos(alpha); + Yz = Yi + dlb * Math.sin(alpha); + + Xa = Xz + dw * Math.sin(alpha); + Ya = Yz + dw * Math.cos(alpha); + Xb = Xz - dw * Math.sin(alpha); + Yb = Yz - dw * Math.cos(alpha); + + path = 'M' + Xa + ',' + Ya + ' '; + path += 'L' + Xb + ',' + Yb + ' '; + path += 'L' + Xc + ',' + Yc + ' '; + path += 'Z '; + + return { + path: path + }; + } - // gauge - obj.gauge = obj.canvas.path().attr({ - "stroke": "none", - "fill": obj.config.gaugeColor, - pki: [ - obj.config.max, - obj.config.min, - obj.config.max, - obj.params.widgetW, - obj.params.widgetH, - obj.params.dx, - obj.params.dy, - obj.config.gaugeWidthScale, - obj.config.donut, - obj.config.reverse - ] - }); - - // level - obj.level = obj.canvas.path().attr({ - "stroke": "none", - "fill": getColor(obj.config.value, (obj.config.value - obj.config.min) / (obj.config.max - obj.config.min), obj.config.levelColors, obj.config.noGradient, obj.config.customSectors), - pki: [ - obj.config.min, - obj.config.min, - obj.config.max, - obj.params.widgetW, - obj.params.widgetH, - obj.params.dx, - obj.params.dy, - obj.config.gaugeWidthScale, - obj.config.donut, - obj.config.reverse - ] - }); - if (obj.config.donut) { - obj.level.transform("r" + obj.config.donutStartAngle + ", " + (obj.params.widgetW / 2 + obj.params.dx) + ", " + (obj.params.widgetH / 2 + obj.params.dy)); - } + // var clear + alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, Xc, Yc, Xz, Yz, Xa, Ya, Xb, Yb, path = null; + }; - if (obj.config.pointer) { - // needle - obj.needle = obj.canvas.path().attr({ - "stroke": (obj.config.pointerOptions.stroke !== null && obj.config.pointerOptions.stroke !== undefined) ? obj.config.pointerOptions.stroke : "none", - "stroke-width": (obj.config.pointerOptions.stroke_width !== null && obj.config.pointerOptions.stroke_width !== undefined) ? obj.config.pointerOptions.stroke_width : 0, - "stroke-linecap": (obj.config.pointerOptions.stroke_linecap !== null && obj.config.pointerOptions.stroke_linecap !== undefined) ? obj.config.pointerOptions.stroke_linecap : "square", - "fill": (obj.config.pointerOptions.color !== null && obj.config.pointerOptions.color !== undefined) ? obj.config.pointerOptions.color : "#000000", - ndl: [ - obj.config.min, + // gauge + obj.gauge = obj.canvas.path().attr({ + "stroke": "none", + "fill": obj.config.gaugeColor, + pki: [ + obj.config.max, obj.config.min, obj.config.max, obj.params.widgetW, @@ -613,175 +583,17 @@ JustGage = function(config) { obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, - obj.config.donut + obj.config.donut, + obj.config.reverse ] }); - if (obj.config.donut) { - obj.needle.transform("r" + obj.config.donutStartAngle + ", " + (obj.params.widgetW / 2 + obj.params.dx) + ", " + (obj.params.widgetH / 2 + obj.params.dy)); - } - } - - // value - obj.txtValue = obj.canvas.text(obj.params.valueX, obj.params.valueY, 0); - obj.txtValue.attr({ - "font-size": obj.params.valueFontSize, - "font-weight": "bold", - "font-family": obj.config.valueFontFamily, - "fill": obj.config.valueFontColor, - "fill-opacity": "0" - }); - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - - // label - obj.txtLabel = obj.canvas.text(obj.params.labelX, obj.params.labelY, obj.config.label); - obj.txtLabel.attr({ - "font-size": obj.params.labelFontSize, - "font-weight": "normal", - "font-family": "Arial", - "fill": obj.config.labelFontColor, - "fill-opacity": "0" - }); - setDy(obj.txtLabel, obj.params.labelFontSize, obj.params.labelY); - - // min - var min = obj.config.min; - if (obj.config.reverse) { - min = obj.config.max; - } - - obj.txtMinimum = min; - if (obj.config.minTxt) { - obj.txtMinimum = obj.config.minTxt; - } else if (obj.config.humanFriendly) { - obj.txtMinimum = humanFriendlyNumber(min, obj.config.humanFriendlyDecimal); - } else if (obj.config.formatNumber) { - obj.txtMinimum = formatNumber(min); - } - obj.txtMin = obj.canvas.text(obj.params.minX, obj.params.minY, obj.txtMinimum); - obj.txtMin.attr({ - "font-size": obj.params.minFontSize, - "font-weight": "normal", - "font-family": "Arial", - "fill": obj.config.labelFontColor, - "fill-opacity": (obj.config.hideMinMax || obj.config.donut) ? "0" : "1" - }); - setDy(obj.txtMin, obj.params.minFontSize, obj.params.minY); - - // max - var max = obj.config.max; - if (obj.config.reverse) { - max = obj.config.min; - } - obj.txtMaximum = max; - if (obj.config.maxTxt) { - obj.txtMaximum = obj.config.maxTxt; - } else if (obj.config.humanFriendly) { - obj.txtMaximum = humanFriendlyNumber(max, obj.config.humanFriendlyDecimal); - } else if (obj.config.formatNumber) { - obj.txtMaximum = formatNumber(max); - } - obj.txtMax = obj.canvas.text(obj.params.maxX, obj.params.maxY, obj.txtMaximum); - obj.txtMax.attr({ - "font-size": obj.params.maxFontSize, - "font-weight": "normal", - "font-family": "Arial", - "fill": obj.config.labelFontColor, - "fill-opacity": (obj.config.hideMinMax || obj.config.donut) ? "0" : "1" - }); - setDy(obj.txtMax, obj.params.maxFontSize, obj.params.maxY); - - var defs = obj.canvas.canvas.childNodes[1]; - var svg = "http://www.w3.org/2000/svg"; - - if (ie !== 'undefined' && ie < 9) { - // VML mode - no SVG & SVG filter support - } else if (ie !== 'undefined') { - onCreateElementNsReady(function() { - obj.generateShadow(svg, defs); - }); - } else { - obj.generateShadow(svg, defs); - } - - // var clear - defs, svg = null; - - // set value to display - if (obj.config.textRenderer) { - obj.originalValue = obj.config.textRenderer(obj.originalValue); - } else if (obj.config.humanFriendly) { - obj.originalValue = humanFriendlyNumber(obj.originalValue, obj.config.humanFriendlyDecimal) + obj.config.symbol; - } else if (obj.config.formatNumber) { - obj.originalValue = formatNumber(obj.originalValue) + obj.config.symbol; - } else if(obj.config.displayRemaining) { - obj.originalValue = ((obj.config.max - obj.originalValue) * 1).toFixed(obj.config.decimals) + obj.config.symbol; - } else { - obj.originalValue = (obj.originalValue * 1).toFixed(obj.config.decimals) + obj.config.symbol; - } - - if (obj.config.counter === true) { - //on each animation frame - eve.on("raphael.anim.frame." + (obj.level.id), function() { - var currentValue = obj.level.attr("pki")[0]; - if (obj.config.reverse) { - currentValue = (obj.config.max * 1) + (obj.config.min * 1) - (obj.level.attr("pki")[0] * 1); - } - if (obj.config.textRenderer) { - obj.txtValue.attr("text", obj.config.textRenderer(Math.floor(currentValue))); - } else if (obj.config.humanFriendly) { - obj.txtValue.attr("text", humanFriendlyNumber(Math.floor(currentValue), obj.config.humanFriendlyDecimal) + obj.config.symbol); - } else if (obj.config.formatNumber) { - obj.txtValue.attr("text", formatNumber(Math.floor(currentValue)) + obj.config.symbol); - } else if (obj.config.displayRemaining) { - obj.txtValue.attr("text", ((obj.config.max - currentValue) * 1).toFixed(obj.config.decimals) + obj.config.symbol); - }else { - obj.txtValue.attr("text", (currentValue * 1).toFixed(obj.config.decimals) + obj.config.symbol); - } - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - currentValue = null; - }); - //on animation end - eve.on("raphael.anim.finish." + (obj.level.id), function() { - obj.txtValue.attr({ - "text": obj.originalValue - }); - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - }); - } else { - //on animation start - eve.on("raphael.anim.start." + (obj.level.id), function() { - obj.txtValue.attr({ - "text": obj.originalValue - }); - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - }); - } - - // animate gauge level, value & label - var rvl = obj.config.value; - if (obj.config.reverse) { - rvl = (obj.config.max * 1) + (obj.config.min * 1) - (obj.config.value * 1); - } - obj.level.animate({ - pki: [ - rvl, - obj.config.min, - obj.config.max, - obj.params.widgetW, - obj.params.widgetH, - obj.params.dx, - obj.params.dy, - obj.config.gaugeWidthScale, - obj.config.donut, - obj.config.reverse - ] - }, obj.config.startAnimationTime, obj.config.startAnimationType, obj.config.onAnimationEnd); - - if (obj.config.pointer) { - obj.needle.animate({ - ndl: [ - rvl, + // level + obj.level = obj.canvas.path().attr({ + "stroke": "none", + "fill": getColor(obj.config.value, (obj.config.value - obj.config.min) / (obj.config.max - obj.config.min), obj.config.levelColors, obj.config.noGradient, obj.config.customSectors), + pki: [ + obj.config.min, obj.config.min, obj.config.max, obj.params.widgetW, @@ -789,146 +601,329 @@ JustGage = function(config) { obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, - obj.config.donut + obj.config.donut, + obj.config.reverse ] - }, obj.config.startAnimationTime, obj.config.startAnimationType); - } - - obj.txtValue.animate({ - "fill-opacity": (obj.config.hideValue) ? "0" : "1" - }, obj.config.startAnimationTime, obj.config.startAnimationType); - obj.txtLabel.animate({ - "fill-opacity": "1" - }, obj.config.startAnimationTime, obj.config.startAnimationType); -}; - -/** Refresh gauge level */ -JustGage.prototype.refresh = function(val, max, min, label) { + }); + if (obj.config.donut) { + obj.level.transform("r" + obj.config.donutStartAngle + ", " + (obj.params.widgetW / 2 + obj.params.dx) + ", " + (obj.params.widgetH / 2 + obj.params.dy)); + } - var obj = this; - var displayVal, color; + if (obj.config.pointer) { + // needle + obj.needle = obj.canvas.path().attr({ + "stroke": (obj.config.pointerOptions.stroke !== null && obj.config.pointerOptions.stroke !== undefined) ? obj.config.pointerOptions.stroke : "none", + "stroke-width": (obj.config.pointerOptions.stroke_width !== null && obj.config.pointerOptions.stroke_width !== undefined) ? obj.config.pointerOptions.stroke_width : 0, + "stroke-linecap": (obj.config.pointerOptions.stroke_linecap !== null && obj.config.pointerOptions.stroke_linecap !== undefined) ? obj.config.pointerOptions.stroke_linecap : "square", + "fill": (obj.config.pointerOptions.color !== null && obj.config.pointerOptions.color !== undefined) ? obj.config.pointerOptions.color : "#000000", + ndl: [ + obj.config.min, + obj.config.min, + obj.config.max, + obj.params.widgetW, + obj.params.widgetH, + obj.params.dx, + obj.params.dy, + obj.config.gaugeWidthScale, + obj.config.donut + ] + }); - max = max || null; - min = min || null; - label = label || null; + if (obj.config.donut) { + obj.needle.transform("r" + obj.config.donutStartAngle + ", " + (obj.params.widgetW / 2 + obj.params.dx) + ", " + (obj.params.widgetH / 2 + obj.params.dy)); + } + } - // set label min - if (label !== null) { - obj.config.label = label; + // value + obj.txtValue = obj.canvas.text(obj.params.valueX, obj.params.valueY, 0); + obj.txtValue.attr({ + "font-size": obj.params.valueFontSize, + "font-weight": "bold", + "font-family": obj.config.valueFontFamily, + "fill": obj.config.valueFontColor, + "fill-opacity": "0" + }); + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); + // label + obj.txtLabel = obj.canvas.text(obj.params.labelX, obj.params.labelY, obj.config.label); obj.txtLabel.attr({ - "text": obj.config.label + "font-size": obj.params.labelFontSize, + "font-weight": "normal", + "font-family": "Arial", + "fill": obj.config.labelFontColor, + "fill-opacity": "0" }); setDy(obj.txtLabel, obj.params.labelFontSize, obj.params.labelY); - } - // set new min - if (min !== null) { - obj.config.min = min; - // TODO: update customSectors + // min + var min = obj.config.min; + if (obj.config.reverse) { + min = obj.config.max; + } - obj.txtMinimum = obj.config.min; + obj.txtMinimum = min; if (obj.config.minTxt) { obj.txtMinimum = obj.config.minTxt; } else if (obj.config.humanFriendly) { - obj.txtMinimum = humanFriendlyNumber(obj.config.min, obj.config.humanFriendlyDecimal); + obj.txtMinimum = humanFriendlyNumber(min, obj.config.humanFriendlyDecimal); + } else if (obj.config.formatNumber) { + obj.txtMinimum = formatNumber(min); + } + obj.txtMin = obj.canvas.text(obj.params.minX, obj.params.minY, obj.txtMinimum); + obj.txtMin.attr({ + "font-size": obj.params.minFontSize, + "font-weight": "normal", + "font-family": "Arial", + "fill": obj.config.labelFontColor, + "fill-opacity": (obj.config.hideMinMax || obj.config.donut) ? "0" : "1" + }); + setDy(obj.txtMin, obj.params.minFontSize, obj.params.minY); + + // max + var max = obj.config.max; + if (obj.config.reverse) { + max = obj.config.min; + } + obj.txtMaximum = max; + if (obj.config.maxTxt) { + obj.txtMaximum = obj.config.maxTxt; + } else if (obj.config.humanFriendly) { + obj.txtMaximum = humanFriendlyNumber(max, obj.config.humanFriendlyDecimal); } else if (obj.config.formatNumber) { - obj.txtMinimum = formatNumber(obj.config.min); + obj.txtMaximum = formatNumber(max); } - if (!obj.config.reverse) { - obj.txtMin.attr({ - "text": obj.txtMinimum + obj.txtMax = obj.canvas.text(obj.params.maxX, obj.params.maxY, obj.txtMaximum); + obj.txtMax.attr({ + "font-size": obj.params.maxFontSize, + "font-weight": "normal", + "font-family": "Arial", + "fill": obj.config.labelFontColor, + "fill-opacity": (obj.config.hideMinMax || obj.config.donut) ? "0" : "1" + }); + setDy(obj.txtMax, obj.params.maxFontSize, obj.params.maxY); + + var defs = obj.canvas.canvas.childNodes[1]; + var svg = "http://www.w3.org/2000/svg"; + + if (ie !== 'undefined' && ie < 9) { + // VML mode - no SVG & SVG filter support + } else if (ie !== 'undefined') { + onCreateElementNsReady(function () { + obj.generateShadow(svg, defs); }); - setDy(obj.txtMin, obj.params.minFontSize, obj.params.minY); } else { - obj.txtMax.attr({ - "text": obj.txtMinimum - }); - setDy(obj.txtMax, obj.params.minFontSize, obj.params.minY); + obj.generateShadow(svg, defs); } - } - // set new max - if (max !== null) { - obj.config.max = max; + // var clear + defs, svg = null; - obj.txtMaximum = obj.config.max; - if (obj.config.maxTxt) { - obj.txtMaximum = obj.config.maxTxt; + // set value to display + if (obj.config.textRenderer) { + obj.originalValue = obj.config.textRenderer(obj.originalValue); } else if (obj.config.humanFriendly) { - obj.txtMaximum = humanFriendlyNumber(obj.config.max, obj.config.humanFriendlyDecimal); + obj.originalValue = humanFriendlyNumber(obj.originalValue, obj.config.humanFriendlyDecimal) + obj.config.symbol; } else if (obj.config.formatNumber) { - obj.txtMaximum = formatNumber(obj.config.max); + obj.originalValue = formatNumber(obj.originalValue) + obj.config.symbol; + } else if (obj.config.displayRemaining) { + obj.originalValue = ((obj.config.max - obj.originalValue) * 1).toFixed(obj.config.decimals) + obj.config.symbol; + } else { + obj.originalValue = (obj.originalValue * 1).toFixed(obj.config.decimals) + obj.config.symbol; } - if (!obj.config.reverse) { - obj.txtMax.attr({ - "text": obj.txtMaximum + + if (obj.config.counter === true) { + //on each animation frame + eve.on("raphael.anim.frame." + (obj.level.id), function () { + var currentValue = obj.level.attr("pki")[0]; + if (obj.config.reverse) { + currentValue = (obj.config.max * 1) + (obj.config.min * 1) - (obj.level.attr("pki")[0] * 1); + } + if (obj.config.textRenderer) { + obj.txtValue.attr("text", obj.config.textRenderer(Math.floor(currentValue))); + } else if (obj.config.humanFriendly) { + obj.txtValue.attr("text", humanFriendlyNumber(Math.floor(currentValue), obj.config.humanFriendlyDecimal) + obj.config.symbol); + } else if (obj.config.formatNumber) { + obj.txtValue.attr("text", formatNumber(Math.floor(currentValue)) + obj.config.symbol); + } else if (obj.config.displayRemaining) { + obj.txtValue.attr("text", ((obj.config.max - currentValue) * 1).toFixed(obj.config.decimals) + obj.config.symbol); + } else { + obj.txtValue.attr("text", (currentValue * 1).toFixed(obj.config.decimals) + obj.config.symbol); + } + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); + currentValue = null; + }); + //on animation end + eve.on("raphael.anim.finish." + (obj.level.id), function () { + obj.txtValue.attr({ + "text": obj.originalValue + }); + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); }); - setDy(obj.txtMax, obj.params.maxFontSize, obj.params.maxY); } else { - obj.txtMin.attr({ - "text": obj.txtMaximum + //on animation start + eve.on("raphael.anim.start." + (obj.level.id), function () { + obj.txtValue.attr({ + "text": obj.originalValue + }); + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); }); - setDy(obj.txtMin, obj.params.maxFontSize, obj.params.maxY); } - } - // overflow values - displayVal = val; - if ((val * 1) > (obj.config.max * 1)) { - val = (obj.config.max * 1); - } - if ((val * 1) < (obj.config.min * 1)) { - val = (obj.config.min * 1); - } + // animate gauge level, value & label + var rvl = obj.config.value; + if (obj.config.reverse) { + rvl = (obj.config.max * 1) + (obj.config.min * 1) - (obj.config.value * 1); + } + obj.level.animate({ + pki: [ + rvl, + obj.config.min, + obj.config.max, + obj.params.widgetW, + obj.params.widgetH, + obj.params.dx, + obj.params.dy, + obj.config.gaugeWidthScale, + obj.config.donut, + obj.config.reverse + ] + }, obj.config.startAnimationTime, obj.config.startAnimationType, obj.config.onAnimationEnd); + + if (obj.config.pointer) { + obj.needle.animate({ + ndl: [ + rvl, + obj.config.min, + obj.config.max, + obj.params.widgetW, + obj.params.widgetH, + obj.params.dx, + obj.params.dy, + obj.config.gaugeWidthScale, + obj.config.donut + ] + }, obj.config.startAnimationTime, obj.config.startAnimationType); + } + + obj.txtValue.animate({ + "fill-opacity": (obj.config.hideValue) ? "0" : "1" + }, obj.config.startAnimationTime, obj.config.startAnimationType); + obj.txtLabel.animate({ + "fill-opacity": "1" + }, obj.config.startAnimationTime, obj.config.startAnimationType); + }; - color = getColor(val, (val - obj.config.min) / (obj.config.max - obj.config.min), obj.config.levelColors, obj.config.noGradient, obj.config.customSectors); + /** Refresh gauge level */ + JustGage.prototype.refresh = function (val, max, min, label) { - if (obj.config.textRenderer) { - displayVal = obj.config.textRenderer(displayVal); - } else if (obj.config.humanFriendly) { - displayVal = humanFriendlyNumber(displayVal, obj.config.humanFriendlyDecimal) + obj.config.symbol; - } else if (obj.config.formatNumber) { - displayVal = formatNumber((displayVal * 1).toFixed(obj.config.decimals)) + obj.config.symbol; - } else if (obj.config.displayRemaining) { + var obj = this; + var displayVal, color; + + max = max || null; + min = min || null; + label = label || null; + + // set label min + if (label !== null) { + obj.config.label = label; + + obj.txtLabel.attr({ + "text": obj.config.label + }); + setDy(obj.txtLabel, obj.params.labelFontSize, obj.params.labelY); + } + + // set new min + if (min !== null) { + obj.config.min = min; + // TODO: update customSectors + + obj.txtMinimum = obj.config.min; + if (obj.config.minTxt) { + obj.txtMinimum = obj.config.minTxt; + } else if (obj.config.humanFriendly) { + obj.txtMinimum = humanFriendlyNumber(obj.config.min, obj.config.humanFriendlyDecimal); + } else if (obj.config.formatNumber) { + obj.txtMinimum = formatNumber(obj.config.min); + } + if (!obj.config.reverse) { + obj.txtMin.attr({ + "text": obj.txtMinimum + }); + setDy(obj.txtMin, obj.params.minFontSize, obj.params.minY); + } else { + obj.txtMax.attr({ + "text": obj.txtMinimum + }); + setDy(obj.txtMax, obj.params.minFontSize, obj.params.minY); + } + } + + // set new max + if (max !== null) { + obj.config.max = max; + + obj.txtMaximum = obj.config.max; + if (obj.config.maxTxt) { + obj.txtMaximum = obj.config.maxTxt; + } else if (obj.config.humanFriendly) { + obj.txtMaximum = humanFriendlyNumber(obj.config.max, obj.config.humanFriendlyDecimal); + } else if (obj.config.formatNumber) { + obj.txtMaximum = formatNumber(obj.config.max); + } + if (!obj.config.reverse) { + obj.txtMax.attr({ + "text": obj.txtMaximum + }); + setDy(obj.txtMax, obj.params.maxFontSize, obj.params.maxY); + } else { + obj.txtMin.attr({ + "text": obj.txtMaximum + }); + setDy(obj.txtMin, obj.params.maxFontSize, obj.params.maxY); + } + } + + // overflow values + displayVal = val; + if ((val * 1) > (obj.config.max * 1)) { + val = (obj.config.max * 1); + } + if ((val * 1) < (obj.config.min * 1)) { + val = (obj.config.min * 1); + } + + color = getColor(val, (val - obj.config.min) / (obj.config.max - obj.config.min), obj.config.levelColors, obj.config.noGradient, obj.config.customSectors); + + if (obj.config.textRenderer) { + displayVal = obj.config.textRenderer(displayVal); + } else if (obj.config.humanFriendly) { + displayVal = humanFriendlyNumber(displayVal, obj.config.humanFriendlyDecimal) + obj.config.symbol; + } else if (obj.config.formatNumber) { + displayVal = formatNumber((displayVal * 1).toFixed(obj.config.decimals)) + obj.config.symbol; + } else if (obj.config.displayRemaining) { displayVal = ((obj.config.max - displayVal) * 1).toFixed(obj.config.decimals) + obj.config.symbol; - } else { - displayVal = (displayVal * 1).toFixed(obj.config.decimals) + obj.config.symbol; - } + } else { + displayVal = (displayVal * 1).toFixed(obj.config.decimals) + obj.config.symbol; + } obj.originalValue = displayVal; - obj.config.value = val * 1; + obj.config.value = val * 1; - if (!obj.config.counter) { - obj.txtValue.attr({ - "text": displayVal - }); - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - } + if (!obj.config.counter) { + obj.txtValue.attr({ + "text": displayVal + }); + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); + } - var rvl = obj.config.value; - if (obj.config.reverse) { - rvl = (obj.config.max * 1) + (obj.config.min * 1) - (obj.config.value * 1); - } + var rvl = obj.config.value; + if (obj.config.reverse) { + rvl = (obj.config.max * 1) + (obj.config.min * 1) - (obj.config.value * 1); + } - obj.level.animate({ - pki: [ - rvl, - obj.config.min, - obj.config.max, - obj.params.widgetW, - obj.params.widgetH, - obj.params.dx, - obj.params.dy, - obj.config.gaugeWidthScale, - obj.config.donut, - obj.config.reverse - ], - "fill": color - }, obj.config.refreshAnimationTime, obj.config.refreshAnimationType, obj.config.onAnimationEnd); - - if (obj.config.pointer) { - obj.needle.animate({ - ndl: [ + obj.level.animate({ + pki: [ rvl, obj.config.min, obj.config.max, @@ -937,306 +932,318 @@ JustGage.prototype.refresh = function(val, max, min, label) { obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, - obj.config.donut - ] - }, obj.config.refreshAnimationTime, obj.config.refreshAnimationType); - } + obj.config.donut, + obj.config.reverse + ], + "fill": color + }, obj.config.refreshAnimationTime, obj.config.refreshAnimationType, obj.config.onAnimationEnd); + + if (obj.config.pointer) { + obj.needle.animate({ + ndl: [ + rvl, + obj.config.min, + obj.config.max, + obj.params.widgetW, + obj.params.widgetH, + obj.params.dx, + obj.params.dy, + obj.config.gaugeWidthScale, + obj.config.donut + ] + }, obj.config.refreshAnimationTime, obj.config.refreshAnimationType); + } - // var clear - obj, displayVal, color, max, min = null; -}; - -/** Destroy gauge object */ -JustGage.prototype.destroy = function() { - if(this.node && this.node.parentNode) this.node.innerHTML = '' -}; - -/** Generate shadow */ -JustGage.prototype.generateShadow = function(svg, defs) { - - var obj = this; - var sid = "inner-shadow-" + obj.config.id; - var gaussFilter, feOffset, feGaussianBlur, feComposite1, feFlood, feComposite2, feComposite3; - - // FILTER - gaussFilter = document.createElementNS(svg, "filter"); - gaussFilter.setAttribute("id", sid); - defs.appendChild(gaussFilter); - - // offset - feOffset = document.createElementNS(svg, "feOffset"); - feOffset.setAttribute("dx", 0); - feOffset.setAttribute("dy", obj.config.shadowVerticalOffset); - gaussFilter.appendChild(feOffset); - - // blur - feGaussianBlur = document.createElementNS(svg, "feGaussianBlur"); - feGaussianBlur.setAttribute("result", "offset-blur"); - feGaussianBlur.setAttribute("stdDeviation", obj.config.shadowSize); - gaussFilter.appendChild(feGaussianBlur); - - // composite 1 - feComposite1 = document.createElementNS(svg, "feComposite"); - feComposite1.setAttribute("operator", "out"); - feComposite1.setAttribute("in", "SourceGraphic"); - feComposite1.setAttribute("in2", "offset-blur"); - feComposite1.setAttribute("result", "inverse"); - gaussFilter.appendChild(feComposite1); - - // flood - feFlood = document.createElementNS(svg, "feFlood"); - feFlood.setAttribute("flood-color", "black"); - feFlood.setAttribute("flood-opacity", obj.config.shadowOpacity); - feFlood.setAttribute("result", "color"); - gaussFilter.appendChild(feFlood); - - // composite 2 - feComposite2 = document.createElementNS(svg, "feComposite"); - feComposite2.setAttribute("operator", "in"); - feComposite2.setAttribute("in", "color"); - feComposite2.setAttribute("in2", "inverse"); - feComposite2.setAttribute("result", "shadow"); - gaussFilter.appendChild(feComposite2); - - // composite 3 - feComposite3 = document.createElementNS(svg, "feComposite"); - feComposite3.setAttribute("operator", "over"); - feComposite3.setAttribute("in", "shadow"); - feComposite3.setAttribute("in2", "SourceGraphic"); - gaussFilter.appendChild(feComposite3); - - // set shadow - if (obj.config.showInnerShadow) { - obj.canvas.canvas.childNodes[2].setAttribute("filter", "url(" + window.location.pathname + "#" + sid + ")"); - obj.canvas.canvas.childNodes[3].setAttribute("filter", "url(" + window.location.pathname + "#" + sid + ")"); - } + // var clear + obj, displayVal, color, max, min = null; + }; - // var clear - gaussFilter, feOffset, feGaussianBlur, feComposite1, feFlood, feComposite2, feComposite3 = null; -}; - -// -// tiny helper function to lookup value of a key from two hash tables -// if none found, return defaultvalue -// -// key: string -// tablea: object -// tableb: DOMStringMap|object -// defval: string|integer|float|null -// datatype: return datatype -// delimiter: delimiter to be used in conjunction with datatype formatting -// -function kvLookup(key, tablea, tableb, defval, datatype, delimiter) { - var val = defval; - var canConvert = false; - if (!(key === null || key === undefined)) { - if (tableb !== null && tableb !== undefined && typeof tableb === "object" && key in tableb) { - val = tableb[key]; - canConvert = true; - } else if (tablea !== null && tablea !== undefined && typeof tablea === "object" && key in tablea) { - val = tablea[key]; - canConvert = true; - } else { - val = defval; + /** Destroy gauge object */ + JustGage.prototype.destroy = function () { + if (this.node && this.node.parentNode) this.node.innerHTML = '' + }; + + /** Generate shadow */ + JustGage.prototype.generateShadow = function (svg, defs) { + + var obj = this; + var sid = "inner-shadow-" + obj.config.id; + var gaussFilter, feOffset, feGaussianBlur, feComposite1, feFlood, feComposite2, feComposite3; + + // FILTER + gaussFilter = document.createElementNS(svg, "filter"); + gaussFilter.setAttribute("id", sid); + defs.appendChild(gaussFilter); + + // offset + feOffset = document.createElementNS(svg, "feOffset"); + feOffset.setAttribute("dx", 0); + feOffset.setAttribute("dy", obj.config.shadowVerticalOffset); + gaussFilter.appendChild(feOffset); + + // blur + feGaussianBlur = document.createElementNS(svg, "feGaussianBlur"); + feGaussianBlur.setAttribute("result", "offset-blur"); + feGaussianBlur.setAttribute("stdDeviation", obj.config.shadowSize); + gaussFilter.appendChild(feGaussianBlur); + + // composite 1 + feComposite1 = document.createElementNS(svg, "feComposite"); + feComposite1.setAttribute("operator", "out"); + feComposite1.setAttribute("in", "SourceGraphic"); + feComposite1.setAttribute("in2", "offset-blur"); + feComposite1.setAttribute("result", "inverse"); + gaussFilter.appendChild(feComposite1); + + // flood + feFlood = document.createElementNS(svg, "feFlood"); + feFlood.setAttribute("flood-color", "black"); + feFlood.setAttribute("flood-opacity", obj.config.shadowOpacity); + feFlood.setAttribute("result", "color"); + gaussFilter.appendChild(feFlood); + + // composite 2 + feComposite2 = document.createElementNS(svg, "feComposite"); + feComposite2.setAttribute("operator", "in"); + feComposite2.setAttribute("in", "color"); + feComposite2.setAttribute("in2", "inverse"); + feComposite2.setAttribute("result", "shadow"); + gaussFilter.appendChild(feComposite2); + + // composite 3 + feComposite3 = document.createElementNS(svg, "feComposite"); + feComposite3.setAttribute("operator", "over"); + feComposite3.setAttribute("in", "shadow"); + feComposite3.setAttribute("in2", "SourceGraphic"); + gaussFilter.appendChild(feComposite3); + + // set shadow + if (obj.config.showInnerShadow) { + obj.canvas.canvas.childNodes[2].setAttribute("filter", "url(" + window.location.pathname + "#" + sid + ")"); + obj.canvas.canvas.childNodes[3].setAttribute("filter", "url(" + window.location.pathname + "#" + sid + ")"); } - if (canConvert === true) { - if (datatype !== null && datatype !== undefined) { - switch (datatype) { - case 'int': - val = parseInt(val, 10); - break; - case 'float': - val = parseFloat(val); - break; - default: - break; + + // var clear + gaussFilter, feOffset, feGaussianBlur, feComposite1, feFlood, feComposite2, feComposite3 = null; + }; + + // + // tiny helper function to lookup value of a key from two hash tables + // if none found, return defaultvalue + // + // key: string + // tablea: object + // tableb: DOMStringMap|object + // defval: string|integer|float|null + // datatype: return datatype + // delimiter: delimiter to be used in conjunction with datatype formatting + // + function kvLookup(key, tablea, tableb, defval, datatype, delimiter) { + var val = defval; + var canConvert = false; + if (!(key === null || key === undefined)) { + if (tableb !== null && tableb !== undefined && typeof tableb === "object" && key in tableb) { + val = tableb[key]; + canConvert = true; + } else if (tablea !== null && tablea !== undefined && typeof tablea === "object" && key in tablea) { + val = tablea[key]; + canConvert = true; + } else { + val = defval; + } + if (canConvert === true) { + if (datatype !== null && datatype !== undefined) { + switch (datatype) { + case 'int': + val = parseInt(val, 10); + break; + case 'float': + val = parseFloat(val); + break; + default: + break; + } } } } - } - return val; -}; + return val; + }; -/** Get color for value */ -function getColor(val, pct, col, noGradient, custSec) { + /** Get color for value */ + function getColor(val, pct, col, noGradient, custSec) { - var no, inc, colors, percentage, rval, gval, bval, lower, upper, range, rangePct, pctLower, pctUpper, color; - var cust = custSec && custSec.ranges && custSec.ranges.length > 0; - var noGradient = noGradient || cust; + var no, inc, colors, percentage, rval, gval, bval, lower, upper, range, rangePct, pctLower, pctUpper, color; + var cust = custSec && custSec.ranges && custSec.ranges.length > 0; + var noGradient = noGradient || cust; - if (cust) { - if (custSec.percents === true) val = pct * 100; - for (var i = 0; i < custSec.ranges.length; i++) { - if (val >= custSec.ranges[i].lo && val <= custSec.ranges[i].hi) { - return custSec.ranges[i].color; + if (cust) { + if (custSec.percents === true) val = pct * 100; + for (var i = 0; i < custSec.ranges.length; i++) { + if (val >= custSec.ranges[i].lo && val <= custSec.ranges[i].hi) { + return custSec.ranges[i].color; + } } } - } - no = col.length; - if (no === 1) return col[0]; - inc = (noGradient) ? (1 / no) : (1 / (no - 1)); - colors = []; - for (i = 0; i < col.length; i++) { - percentage = (noGradient) ? (inc * (i + 1)) : (inc * i); - rval = parseInt((cutHex(col[i])).substring(0, 2), 16); - gval = parseInt((cutHex(col[i])).substring(2, 4), 16); - bval = parseInt((cutHex(col[i])).substring(4, 6), 16); - colors[i] = { - pct: percentage, - color: { - r: rval, - g: gval, - b: bval + no = col.length; + if (no === 1) return col[0]; + inc = (noGradient) ? (1 / no) : (1 / (no - 1)); + colors = []; + for (i = 0; i < col.length; i++) { + percentage = (noGradient) ? (inc * (i + 1)) : (inc * i); + rval = parseInt((cutHex(col[i])).substring(0, 2), 16); + gval = parseInt((cutHex(col[i])).substring(2, 4), 16); + bval = parseInt((cutHex(col[i])).substring(4, 6), 16); + colors[i] = { + pct: percentage, + color: { + r: rval, + g: gval, + b: bval + } + }; + } + + if (pct === 0) { + return 'rgb(' + [colors[0].color.r, colors[0].color.g, colors[0].color.b].join(',') + ')'; + } + + for (var j = 0; j < colors.length; j++) { + if (pct <= colors[j].pct) { + if (noGradient) { + return 'rgb(' + [colors[j].color.r, colors[j].color.g, colors[j].color.b].join(',') + ')'; + } else { + lower = colors[j - 1]; + upper = colors[j]; + range = upper.pct - lower.pct; + rangePct = (pct - lower.pct) / range; + pctLower = 1 - rangePct; + pctUpper = rangePct; + color = { + r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper), + g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper), + b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper) + }; + return 'rgb(' + [color.r, color.g, color.b].join(',') + ')'; + } } - }; - } + } - if (pct === 0) { - return 'rgb(' + [colors[0].color.r, colors[0].color.g, colors[0].color.b].join(',') + ')'; } - for (var j = 0; j < colors.length; j++) { - if (pct <= colors[j].pct) { - if (noGradient) { - return 'rgb(' + [colors[j].color.r, colors[j].color.g, colors[j].color.b].join(',') + ')'; - } else { - lower = colors[j - 1]; - upper = colors[j]; - range = upper.pct - lower.pct; - rangePct = (pct - lower.pct) / range; - pctLower = 1 - rangePct; - pctUpper = rangePct; - color = { - r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper), - g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper), - b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper) - }; - return 'rgb(' + [color.r, color.g, color.b].join(',') + ')'; - } + /** Fix Raphael display:none tspan dy attribute bug */ + function setDy(elem, fontSize, txtYpos) { + if ((!ie || ie > 9) && elem.node.firstChild.attributes.dy) { + elem.node.firstChild.attributes.dy.value = 0; } } -} + /** Cut hex */ + function cutHex(str) { + return (str.charAt(0) == "#") ? str.substring(1, 7) : str; + } + + /** Human friendly number suffix - @robertsLando */ + function humanFriendlyNumber(n, d) { + var d2, i, s, c; + + d2 = Math.pow(10, d); + s = " KMGTPE"; + i = 0; + c = 1000; + + while ((n >= c || n <= -c) && ++i < s.length) n = n / c; + + i = i >= s.length ? s.length - 1 : i; -/** Fix Raphael display:none tspan dy attribute bug */ -function setDy(elem, fontSize, txtYpos) { - if ((!ie || ie > 9) && elem.node.firstChild.attributes.dy) { - elem.node.firstChild.attributes.dy.value = 0; + return Math.round(n * d2) / d2 + s[i]; } -} - -/** Random integer */ -function getRandomInt(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; -} - -/** Cut hex */ -function cutHex(str) { - return (str.charAt(0) == "#") ? str.substring(1, 7) : str; -} - -/** Human friendly number suffix - @robertsLando */ -function humanFriendlyNumber(n, d) { - var d2, i, s, c; - - d2 = Math.pow(10, d); - s = " KMGTPE"; - i = 0; - c = 1000; - - while((n >= c || n <= -c) && ++i < s.length) n = n / c; - - i = i >= s.length ? s.length - 1 : i; - - return Math.round(n * d2) / d2 + s[i]; -} - -/** Format numbers with commas - From: http://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript */ -function formatNumber(x) { - var parts = x.toString().split("."); - parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); - return parts.join("."); -} - -/** Get style */ -function getStyle(oElm, strCssRule) { - var strValue = ""; - if (document.defaultView && document.defaultView.getComputedStyle) { - strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); - } else if (oElm.currentStyle) { - strCssRule = strCssRule.replace(/\-(\w)/g, function(strMatch, p1) { - return p1.toUpperCase(); - }); - strValue = oElm.currentStyle[strCssRule]; + + /** Format numbers with commas - From: http://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript */ + function formatNumber(x) { + var parts = x.toString().split("."); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); + return parts.join("."); } - return strValue; -} - -/** Create Element NS Ready */ -function onCreateElementNsReady(func) { - if (document.createElementNS !== undefined) { - func(); - } else { - setTimeout(function() { - onCreateElementNsReady(func); - }, 100); + + /** Get style */ + function getStyle(oElm, strCssRule) { + var strValue = ""; + if (document.defaultView && document.defaultView.getComputedStyle) { + strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); + } else if (oElm.currentStyle) { + strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1) { + return p1.toUpperCase(); + }); + strValue = oElm.currentStyle[strCssRule]; + } + return strValue; } -} - -/** Get IE version */ -// ---------------------------------------------------------- -// A short snippet for detecting versions of IE in JavaScript -// without resorting to user-agent sniffing -// ---------------------------------------------------------- -// If you're not in IE (or IE version is less than 5) then: -// ie === undefined -// If you're in IE (>=5) then you can determine which version: -// ie === 7; // IE7 -// Thus, to detect IE: -// if (ie) {} -// And to detect the version: -// ie === 6 // IE6 -// ie > 7 // IE8, IE9 ... -// ie < 9 // Anything less than IE9 -// ---------------------------------------------------------- -// UPDATE: Now using Live NodeList idea from @jdalton -var ie = (function() { - - var undef, - v = 3, - div = document.createElement('div'), - all = div.getElementsByTagName('i'); - - while ( - div.innerHTML = '', - all[0] - ); - return v > 4 ? v : undef; -}()); - -// extend target object with second object -function extend(out) { - out = out || {}; - - for (var i = 1; i < arguments.length; i++) { - if (!arguments[i]) - continue; - - for (var key in arguments[i]) { - if (arguments[i].hasOwnProperty(key)) - out[key] = arguments[i][key]; + + /** Create Element NS Ready */ + function onCreateElementNsReady(func) { + if (document.createElementNS !== undefined) { + func(); + } else { + setTimeout(function () { + onCreateElementNsReady(func); + }, 100); } } - return out; -}; + /** Get IE version */ + // ---------------------------------------------------------- + // A short snippet for detecting versions of IE in JavaScript + // without resorting to user-agent sniffing + // ---------------------------------------------------------- + // If you're not in IE (or IE version is less than 5) then: + // ie === undefined + // If you're in IE (>=5) then you can determine which version: + // ie === 7; // IE7 + // Thus, to detect IE: + // if (ie) {} + // And to detect the version: + // ie === 6 // IE6 + // ie > 7 // IE8, IE9 ... + // ie < 9 // Anything less than IE9 + // ---------------------------------------------------------- + // UPDATE: Now using Live NodeList idea from @jdalton + var ie = (function () { + + var undef, + v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + + while ( + div.innerHTML = '', + all[0] + ); + return v > 4 ? v : undef; + }()); + + // extend target object with second object + function extend(out) { + out = out || {}; + + for (var i = 1; i < arguments.length; i++) { + if (!arguments[i]) + continue; + + for (var key in arguments[i]) { + if (arguments[i].hasOwnProperty(key)) + out[key] = arguments[i][key]; + } + } + + return out; + }; + + return JustGage +})); + + + + -// am I in a commonJS environment? + -if(typeof exports === "object" && exports) { - // let's import raphael then - var Raphael = require('raphael'); - // and i will export myself as a module. - module.exports = JustGage; - }