From 4732dd80ae16e303b08dc06c0982c4aa7c475cf0 Mon Sep 17 00:00:00 2001 From: toorshia Date: Wed, 19 Aug 2015 11:46:39 +0200 Subject: [PATCH] testing issue with prototype reference --- issues/customize-style.htm | 135 +++++++++++ justgage-1.0.1.js | 477 +++++++++++++++++++++++++++++++++++++ justgage.js | 2 +- 3 files changed, 613 insertions(+), 1 deletion(-) create mode 100644 issues/customize-style.htm create mode 100644 justgage-1.0.1.js diff --git a/issues/customize-style.htm b/issues/customize-style.htm new file mode 100644 index 0000000..24553e1 --- /dev/null +++ b/issues/customize-style.htm @@ -0,0 +1,135 @@ + + + + + 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. +

+ + + + + + diff --git a/justgage-1.0.1.js b/justgage-1.0.1.js new file mode 100644 index 0000000..909d47a --- /dev/null +++ b/justgage-1.0.1.js @@ -0,0 +1,477 @@ +/** + * JustGage - a handy JavaScript plugin for generating and animating nice & clean dashboard gauges. + * Copyright (c) 2012 Bojan Djuricic - pindjur(at)gmail(dot)com | http://www.madcog.com + * Licensed under MIT. + * Date: 31/07/2012 + * @author Bojan Djuricic (@Toorshia) + * @version 1.0 + * + * http://www.justgage.com + */ + +JustGage = function(config) { + + if (!config.id) {alert("Missing id parameter for gauge!"); return false;} + if (!document.getElementById(config.id)) {alert("No element with id: \""+config.id+"\" found!"); return false;} + + // configurable parameters + this.config = + { + // id : string + // this is container element id + id : config.id, + + // title : string + // gauge title + title : (config.title) ? config.title : "Title", + + // titleFontColor : string + // color of gauge title + titleFontColor : (config.titleFontColor) ? config.titleFontColor : "#999999", + + // value : int + // value gauge is showing + value : (config.value) ? config.value : 0, + + // valueFontColor : string + // color of label showing current value + valueFontColor : (config.valueFontColor) ? config.valueFontColor : "#010101", + + // min : int + // min value + min : (config.min) ? config.min : 0, + + // max : int + // max value + max : (config.max) ? config.max : 100, + + // showMinMax : bool + // hide or display min and max values + showMinMax : (config.showMinMax != null) ? config.showMinMax : true, + + // gaugeWidthScale : float + // width of the gauge element + gaugeWidthScale : (config.gaugeWidthScale) ? config.gaugeWidthScale : 1.0, + + // gaugeColor : string + // background color of gauge element + gaugeColor : (config.gaugeColor) ? config.gaugeColor : "#edebeb", + + // label : string + // text to show below value + label : (config.label) ? config.label : "", + + // showInnerShadow : bool + // give gauge element small amount of inner shadow + showInnerShadow : (config.showInnerShadow != null) ? config.showInnerShadow : true, + + // shadowOpacity : int + // 0 ~ 1 + shadowOpacity : (config.shadowOpacity) ? config.shadowOpacity : 0.2, + + // shadowSize: int + // inner shadow size + shadowSize : (config.shadowSize) ? config.shadowSize : 5, + + // shadowVerticalOffset : int + // how much shadow is offset from top + shadowVerticalOffset : (config.shadowVerticalOffset) ? config.shadowVerticalOffset : 3, + + // levelColors : string[] + // colors of indicator, from lower to upper, in RGB format + levelColors : (config.levelColors) ? config.levelColors : [ + "#a9d70b", + "#f9c802", + "#ff0000" + ], + + // levelColorsGradient : bool + // whether to use gradual color change for value, or sector-based + levelColorsGradient : (config.levelColorsGradient != null) ? config.levelColorsGradient : true, + + // labelFontColor : string + // color of label showing label under value + labelFontColor : (config.labelFontColor) ? config.labelFontColor : "#b3b3b3", + + // startAnimationTime : int + // length of initial animation + startAnimationTime : (config.startAnimationTime) ? config.startAnimationTime : 700, + + // startAnimationType : string + // type of initial animation (linear, >, <, <>, bounce) + startAnimationType : (config.startAnimationType) ? config.startAnimationType : ">", + + // refreshAnimationTime : int + // length of refresh animation + refreshAnimationTime : (config.refreshAnimationTime) ? config.refreshAnimationTime : 700, + + // refreshAnimationType : string + // type of refresh animation (linear, >, <, <>, bounce) + refreshAnimationType : (config.refreshAnimationType) ? config.refreshAnimationType : ">" + }; + + // overflow values + if (config.value > this.config.max) this.config.value = this.config.max; + if (config.value < this.config.min) this.config.value = this.config.min; + this.originalValue = config.value; + + // canvas + this.canvas = Raphael(this.config.id, "100%", "100%"); + + // canvas dimensions + //var canvasW = document.getElementById(this.config.id).clientWidth; + //var canvasH = document.getElementById(this.config.id).clientHeight; + var canvasW = getStyle(document.getElementById(this.config.id), "width").slice(0, -2) * 1; + var canvasH = getStyle(document.getElementById(this.config.id), "height").slice(0, -2) * 1; + + // widget dimensions + var widgetW, widgetH; + if ((canvasW / canvasH) > 1.25) { + widgetW = 1.25 * canvasH; + widgetH = canvasH; + } else { + widgetW = canvasW; + widgetH = canvasW / 1.25; + } + + // delta + var dx = (canvasW - widgetW)/2; + var dy = (canvasH - widgetH)/2; + + // title + var titleFontSize = ((widgetH / 8) > 10) ? (widgetH / 10) : 10; + var titleX = dx + widgetW / 2; + var titleY = dy + widgetH / 6.5; + + // value + var valueFontSize = ((widgetH / 6.4) > 16) ? (widgetH / 6.4) : 16; + var valueX = dx + widgetW / 2; + var valueY = dy + widgetH / 1.4; + + // label + var labelFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; + var labelX = dx + widgetW / 2; + //var labelY = dy + widgetH / 1.126760563380282; + var labelY = valueY + valueFontSize / 2 + 6; + + // min + var minFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; + var minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * this.config.gaugeWidthScale) / 2 ; + var minY = dy + widgetH / 1.126760563380282; + + // max + var maxFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; + var maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * this.config.gaugeWidthScale) / 2 ; + var maxY = dy + widgetH / 1.126760563380282; + + // parameters + this.params = { + canvasW : canvasW, + canvasH : canvasH, + widgetW : widgetW, + widgetH : widgetH, + dx : dx, + dy : dy, + titleFontSize : titleFontSize, + titleX : titleX, + titleY : titleY, + valueFontSize : valueFontSize, + valueX : valueX, + valueY : valueY, + labelFontSize : labelFontSize, + labelX : labelX, + labelY : labelY, + minFontSize : minFontSize, + minX : minX, + minY : minY, + maxFontSize : maxFontSize, + maxX : maxX, + maxY : maxY + }; + + // pki - custom attribute for generating gauge paths + this.canvas.customAttributes.pki = function (value, min, max, w, h, dx, dy, gws) { + + var 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) + dy - Ro * Math.sin(alpha), + Xi = w / 2 + dx + Ri * Math.cos(alpha), + Yi = h - (h - Cy) + dy - Ri * Math.sin(alpha), + path; + + 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 }; + } + + // gauge + this.gauge = this.canvas.path().attr({ + "stroke": "none", + "fill": this.config.gaugeColor, + pki: [this.config.max, this.config.min, this.config.max, this.params.widgetW, this.params.widgetH, this.params.dx, this.params.dy, this.config.gaugeWidthScale] + }); + this.gauge.id = this.config.id+"-gauge"; + + // level + this.level = this.canvas.path().attr({ + "stroke": "none", + "fill": getColorForPercentage((this.config.value - this.config.min) / (this.config.max - this.config.min), this.config.levelColors, this.config.levelColorsGradient), + pki: [this.config.min, this.config.min, this.config.max, this.params.widgetW, this.params.widgetH, this.params.dx, this.params.dy, this.config.gaugeWidthScale] + }); + this.level.id = this.config.id+"-level"; + + // title + this.txtTitle = this.canvas.text(this.params.titleX, this.params.titleY, this.config.title); + this.txtTitle. attr({ + "font-size":this.params.titleFontSize, + "font-weight":"bold", + "font-family":"Arial", + "fill":this.config.titleFontColor, + "fill-opacity":"1" + }); + this.txtTitle.id = this.config.id+"-txttitle"; + + // value + this.txtValue = this.canvas.text(this.params.valueX, this.params.valueY, this.originalValue + "%"); + this.txtValue. attr({ + "font-size":this.params.valueFontSize, + "font-weight":"bold", + "font-family":"Arial", + "fill":this.config.valueFontColor, + "fill-opacity":"0" + }); + this.txtValue.id = this.config.id+"-txtvalue"; + + // label + this.txtLabel = this.canvas.text(this.params.labelX, this.params.labelY, this.config.label); + this.txtLabel. attr({ + "font-size":this.params.labelFontSize, + "font-weight":"normal", + "font-family":"Arial", + "fill":this.config.labelFontColor, + "fill-opacity":"0" + }); + this.txtLabel.id = this.config.id+"-txtlabel"; + + // min + this.txtMin = this.canvas.text(this.params.minX, this.params.minY, this.config.min); + this.txtMin. attr({ + "font-size":this.params.minFontSize, + "font-weight":"normal", + "font-family":"Arial", + "fill":this.config.labelFontColor, + "fill-opacity": (this.config.showMinMax == true)? "1" : "0" + }); + this.txtMin.id = this.config.id+"-txtmin"; + + // max + this.txtMax = this.canvas.text(this.params.maxX, this.params.maxY, this.config.max); + this.txtMax. attr({ + "font-size":this.params.maxFontSize, + "font-weight":"normal", + "font-family":"Arial", + "fill":this.config.labelFontColor, + "fill-opacity": (this.config.showMinMax == true)? "1" : "0" + }); + this.txtMax.id = this.config.id+"-txtmax"; + + var defs = this.canvas.canvas.childNodes[1]; + var svg = "http://www.w3.org/2000/svg"; + + + + if (ie < 9) { + onCreateElementNsReady(function() { + this.generateShadow(); + }); + } else { + this.generateShadow(svg, defs); + } + + // animate + this.level.animate({pki: [this.config.value, this.config.min, this.config.max, this.params.widgetW, this.params.widgetH, this.params.dx, this.params.dy, this.config.gaugeWidthScale]}, this.config.startAnimationTime, this.config.startAnimationType); + + this.txtValue.animate({"fill-opacity":"1"}, this.config.startAnimationTime, this.config.startAnimationType); + this.txtLabel.animate({"fill-opacity":"1"}, this.config.startAnimationTime, this.config.startAnimationType); +}; + +/** Refresh gauge level */ +JustGage.prototype.refresh = function(val) { + // overflow values + originalVal = val; + if (val > this.config.max) {val = this.config.max;} + if (val < this.config.min) {val = this.config.min;} + + var color = getColorForPercentage((val - this.config.min) / (this.config.max - this.config.min), this.config.levelColors, this.config.levelColorsGradient); + this.canvas.getById(this.config.id+"-txtvalue").attr({"text":originalVal + "%"}); + this.canvas.getById(this.config.id+"-level").animate({pki: [val, this.config.min, this.config.max, this.params.widgetW, this.params.widgetH, this.params.dx, this.params.dy, this.config.gaugeWidthScale], "fill":color}, this.config.refreshAnimationTime, this.config.refreshAnimationType); +}; + +/** Generate shadow */ +JustGage.prototype.generateShadow = function(svg, defs) { + // FILTER + var gaussFilter=document.createElementNS(svg,"filter"); + gaussFilter.setAttribute("id", this.config.id + "-inner-shadow"); + defs.appendChild(gaussFilter); + + // offset + var feOffset = document.createElementNS(svg,"feOffset"); + feOffset.setAttribute("dx", 0); + feOffset.setAttribute("dy", this.config.shadowVerticalOffset); + gaussFilter.appendChild(feOffset); + + // blur + var feGaussianBlur = document.createElementNS(svg,"feGaussianBlur"); + feGaussianBlur.setAttribute("result","offset-blur"); + feGaussianBlur.setAttribute("stdDeviation", this.config.shadowSize); + gaussFilter.appendChild(feGaussianBlur); + + // composite 1 + var 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 + var feFlood = document.createElementNS(svg,"feFlood"); + feFlood.setAttribute("flood-color","black"); + feFlood.setAttribute("flood-opacity", this.config.shadowOpacity); + feFlood.setAttribute("result","color"); + gaussFilter.appendChild(feFlood); + + // composite 2 + var 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 + var feComposite3 = document.createElementNS(svg,"feComposite"); + feComposite3.setAttribute("operator","over"); + feComposite3.setAttribute("in", "shadow"); + feComposite3.setAttribute("in2","SourceGraphic"); + gaussFilter.appendChild(feComposite3); + + // set shadow + if (this.config.showInnerShadow == true) { + this.canvas.canvas.childNodes[2].setAttribute("filter", "url(#" + this.config.id + "-inner-shadow)"); + this.canvas.canvas.childNodes[3].setAttribute("filter", "url(#" + this.config.id + "-inner-shadow)"); + } +} + +/** Get color for value percentage */ +var getColorForPercentage = function(pct, col, grad) { + + var no = col.length; + if (no === 1) return col[0]; + var inc = (grad) ? (1 / (no - 1)) : (1 / no); + var colors = new Array(); + for (var i = 0; i < col.length; i++) { + var percentage = (grad) ? (inc * i) : (inc * (i + 1)); + var rval = parseInt((cutHex(col[i])).substring(0,2),16); + var gval = parseInt((cutHex(col[i])).substring(2,4),16); + var 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 i = 0; i < colors.length; i++) { + if (pct <= colors[i].pct) { + if (grad == true) { + var lower = colors[i - 1]; + var upper = colors[i]; + var range = upper.pct - lower.pct; + var rangePct = (pct - lower.pct) / range; + var pctLower = 1 - rangePct; + var pctUpper = rangePct; + var 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(',') + ')'; + } else { + return 'rgb(' + [colors[i].color.r, colors[i].color.g, colors[i].color.b].join(',') + ')'; + } + } + } +} + +/** 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} + +/** 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; +} + +/** Create Element NS Ready */ + function onCreateElementNsReady(func) { + if (document.createElementNS != undefined) { + func(); + } else { + setTimeout(function() { onCreateElementNsReady(func); }, 100); + } +} + +/** 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; + +}()); \ No newline at end of file diff --git a/justgage.js b/justgage.js index 939333d..7bb86f9 100644 --- a/justgage.js +++ b/justgage.js @@ -10,7 +10,7 @@ * March 16, 2014. * ----------------------------- * fix - https://github.com/toorshia/justgage/issues/112 - * + * * ----------------------------- * February 16, 2014. * -----------------------------