From bd71a4f1b1a4731ef0866f9513fa3c4b95378efe Mon Sep 17 00:00:00 2001 From: Mischa Braam Date: Fri, 14 Sep 2018 12:13:14 +0200 Subject: [PATCH 1/2] Added optional colors for negative values --- Chart.HeatMap.js | 13 +- ColorManager.js | 107 +++- dst/Chart.HeatMap.S.js | 486 +++++++++++++---- dst/Chart.HeatMap.S.min.js | 4 +- dst/Chart.HeatMap.js | 116 +++- dst/Chart.HeatMap.min.js | 2 +- package-lock.json | 1062 ++++++++++++++++++++++++++++++++++++ 7 files changed, 1636 insertions(+), 154 deletions(-) create mode 100644 package-lock.json diff --git a/Chart.HeatMap.js b/Chart.HeatMap.js index 0e062d5..0843c12 100644 --- a/Chart.HeatMap.js +++ b/Chart.HeatMap.js @@ -411,8 +411,8 @@ removeDataset: function(){ this.datasets.pop(); this.scale.yLabels.pop(); - this.scale.steps -= 1; - this.scale.max -= 1; + this.scale.steps -= 1; + this.scale.max -= 1; this.scale.fit(); this.findMaxAndMin(true); this.applyColors(); @@ -422,10 +422,11 @@ applyColors : function(){ this.colorManager.setup( - this.min, - this.max, - this.options.colors, - this.options.colorInterpolation, + this.min, + this.max, + this.options.colors, + this.options.negativeColors, + this.options.colorInterpolation, this.options.colorHighlightMultiplier ); diff --git a/ColorManager.js b/ColorManager.js index ece9ac4..6a614ea 100644 --- a/ColorManager.js +++ b/ColorManager.js @@ -17,23 +17,58 @@ var ColorManager = function(){ return v2*x+v1*(1-x); } - function getGradientColor(colors, i, base, scaleFactor){ - var fIndex = (i-base)*scaleFactor; + function getGradientColor(colors, negativeColors, i, base, scaleFactor, scaleFactorNegative){ + var useColors = colors; + var useScaleFactor = scaleFactor; + + if (negativeColors) { + if (i < 0) { + i = Math.abs(i); + useColors = negativeColors; + + if (scaleFactorNegative === false) { + base = Math.abs(base); + useScaleFactor = Math.abs(scaleFactor); + } else { + useScaleFactor = Math.abs(scaleFactorNegative); + } + } + } + + var fIndex = (i-base)*useScaleFactor; var iIndex = Math.floor(fIndex); + if (iIndex > useColors.length - 1){ iIndex = useColors.length - 1; } + if (iIndex < 0) { iIndex = 0 }; + var iv = fIndex - iIndex; var iIndex1 = iIndex+1; - if (iIndex1 > colors.length - 1){ iIndex1 = iIndex; } + if (iIndex1 > useColors.length - 1){ iIndex1 = iIndex; } return { - r: interp(colors[iIndex][0], colors[iIndex1][0], iv), - g: interp(colors[iIndex][1], colors[iIndex1][1], iv), - b: interp(colors[iIndex][2], colors[iIndex1][2], iv), - a: interp(colors[iIndex][3], colors[iIndex1][3], iv) + r: interp(useColors[iIndex][0], useColors[iIndex1][0], iv), + g: interp(useColors[iIndex][1], useColors[iIndex1][1], iv), + b: interp(useColors[iIndex][2], useColors[iIndex1][2], iv), + a: interp(useColors[iIndex][3], useColors[iIndex1][3], iv) }; } - function getIndexedColor(colors, i, base, scaleFactor){ + function getIndexedColor(colors, negativeColors, i, base, scaleFactor, scaleFactorNegative){ var index = Math.floor((i-base)*scaleFactor); + + if (negativeColors && index < 0) { + index = (index * -1) - 1; + if (index >= negativeColors.length) { + index = negativeColors.length - 1; + } + + return { + r: negativeColors[index][0], + g: negativeColors[index][1], + b: negativeColors[index][2], + a: negativeColors[index][3], + }; + } + return { r: colors[index][0], g: colors[index][1], @@ -59,35 +94,63 @@ var ColorManager = function(){ function cssColorToArray(color){ return cssColorParser(color); } - + this.getColor = function(){ console.error('ColorManager: colors have not been setup'); }; this.colors = []; + this.negativeColors = []; - this.setup = function(min, max, colors, colorInterpolation, colorHighlightMultiplier){ + this.setup = function (min, max, colors, negativeColors, colorInterpolation, colorHighlightMultiplier) { var colorFunction, scaleFactor; - var dataLength = max-min; var base = min; - - if (colorInterpolation === 'gradient'){ + var dataLength = max - min; + + var scaleFactorNegative = false; + var dataLengthNegative = false; + + if (negativeColors) { + if (max < 0) { + max = max + 0.000001; + base = max; + } else if (max > 0 && min < 0) { + dataLength = max; + dataLengthNegative = min; + base = 0; + } + } + + if (colorInterpolation === 'gradient') { colorFunction = getGradientColor; - scaleFactor = (colors.length-1)/(dataLength -1); + scaleFactor = (colors.length ) / (dataLength !== 0 ? dataLength : 1); } else { colorFunction = getIndexedColor; - scaleFactor = (colors.length)/(dataLength+1); - } - - this.colors = colors.map(function(clr){ + scaleFactor = (colors.length) / (dataLength + 1); + } + + if (negativeColors) { + if (max > 0 && min < 0) { + if (colorInterpolation === 'gradient') { + scaleFactorNegative = (negativeColors.length - 1) / (dataLengthNegative - 1); + } else { + scaleFactorNegative = (negativeColors.length) / (dataLengthNegative + 1); + } + } + } + + this.colors = colors.map(function (clr) { return cssColorToArray(clr); }); - - this.getColor = function(dataValue){ - var clr = colorFunction(this.colors, dataValue, base, scaleFactor); + this.negativeColors = negativeColors.map(function (clr) { + return cssColorToArray(clr); + }); + + this.getColor = function (dataValue) { + var clr = colorFunction(this.colors, this.negativeColors, dataValue, base, scaleFactor, scaleFactorNegative); var hclr = getHighlightColor(clr, colorHighlightMultiplier); - return { + return { color: rgbString(clr.r, clr.g, clr.b, clr.a), highlight: rgbString(hclr.r, hclr.g, hclr.b, hclr.a) }; diff --git a/dst/Chart.HeatMap.S.js b/dst/Chart.HeatMap.S.js index afdefac..4151c25 100644 --- a/dst/Chart.HeatMap.S.js +++ b/dst/Chart.HeatMap.S.js @@ -35,17 +35,11 @@ { return document.defaultView.getComputedStyle(element).getPropertyValue(dimension); } - } - - var width = this.width = computeDimension(context.canvas,'Width'); - var height = this.height = computeDimension(context.canvas,'Height'); + }; - // Firefox requires this to work correctly - context.canvas.width = width; - context.canvas.height = height; + var width = this.width = computeDimension(context.canvas,'Width') || context.canvas.width; + var height = this.height = computeDimension(context.canvas,'Height') || context.canvas.height; - var width = this.width = context.canvas.width; - var height = this.height = context.canvas.height; this.aspectRatio = this.width / this.height; //High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale. helpers.retinaScale(this); @@ -150,6 +144,9 @@ // String - Tooltip title font colour tooltipTitleFontColor: "#fff", + // String - Tooltip title template + tooltipTitleTemplate: "<%= label%>", + // Number - pixel width of padding around tooltip text tooltipYPadding: 6, @@ -169,11 +166,17 @@ tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= value %>", // String - Template string for single tooltips - multiTooltipTemplate: "<%= value %>", + multiTooltipTemplate: "<%= datasetLabel %>: <%= value %>", // String - Colour behind the legend colour block multiTooltipKeyBackground: '#fff', + // Array - A list of colors to use as the defaults + segmentColorDefault: ["#A6CEE3", "#1F78B4", "#B2DF8A", "#33A02C", "#FB9A99", "#E31A1C", "#FDBF6F", "#FF7F00", "#CAB2D6", "#6A3D9A", "#B4B482", "#B15928" ], + + // Array - A list of highlight colors to use as the defaults + segmentHighlightColorDefaults: [ "#CEF6FF", "#47A0DC", "#DAFFB2", "#5BC854", "#FFC2C1", "#FF4244", "#FFE797", "#FFA728", "#F2DAFE", "#9265C2", "#DCDCAA", "#D98150" ], + // Function - Will fire on animation progression. onAnimationProgress: function(){}, @@ -210,14 +213,18 @@ clone = helpers.clone = function(obj){ var objClone = {}; each(obj,function(value,key){ - if (obj.hasOwnProperty(key)) objClone[key] = value; + if (obj.hasOwnProperty(key)){ + objClone[key] = value; + } }); return objClone; }, extend = helpers.extend = function(base){ each(Array.prototype.slice.call(arguments,1), function(extensionObject) { each(extensionObject,function(value,key){ - if (extensionObject.hasOwnProperty(key)) base[key] = value; + if (extensionObject.hasOwnProperty(key)){ + base[key] = value; + } }); }); return base; @@ -300,9 +307,9 @@ })(), warn = helpers.warn = function(str){ //Method for warning of errors - if (window.console && typeof window.console.warn == "function") console.warn(str); + if (window.console && typeof window.console.warn === "function") console.warn(str); }, - amd = helpers.amd = (typeof define == 'function' && define.amd), + amd = helpers.amd = (typeof define === 'function' && define.amd), //-- Math methods isNumber = helpers.isNumber = function(n){ return !isNaN(parseFloat(n)) && isFinite(n); @@ -328,7 +335,20 @@ }, getDecimalPlaces = helpers.getDecimalPlaces = function(num){ if (num%1!==0 && isNumber(num)){ - return num.toString().split(".")[1].length; + var s = num.toString(); + if(s.indexOf("e-") < 0){ + // no exponent, e.g. 0.01 + return s.split(".")[1].length; + } + else if(s.indexOf(".") < 0) { + // no decimal point, e.g. 1e-9 + return parseInt(s.split("e-")[1]); + } + else { + // exponent and decimal point, e.g. 1.23e-9 + var parts = s.split(".")[1].split("e-"); + return parts[0].length + parseInt(parts[1]); + } } else { return 0; @@ -387,10 +407,15 @@ maxSteps = Math.floor(drawingSize/(textSize * 1.5)), skipFitting = (minSteps >= maxSteps); - var maxValue = max(valuesArray), - minValue = min(valuesArray); + // Filter out null values since these would min() to zero + var values = []; + each(valuesArray, function( v ){ + v == null || values.push( v ); + }); + var minValue = min(values), + maxValue = max(values); - // We need some degree of seperation here to calculate the scales if all the values are the same + // We need some degree of separation here to calculate the scales if all the values are the same // Adding/minusing 0.5 will give us a range of 1. if (maxValue === minValue){ maxValue += 0.5; @@ -505,7 +530,7 @@ /* jshint ignore:end */ generateLabels = helpers.generateLabels = function(templateString,numberOfSteps,graphMin,stepValue){ var labelsArray = new Array(numberOfSteps); - if (labelTemplateString){ + if (templateString){ each(labelsArray,function(val,index){ labelsArray[index] = template(templateString,{value: (graphMin + (stepValue*(index+1)))}); }); @@ -526,7 +551,9 @@ return -1 * t * (t - 2); }, easeInOutQuad: function (t) { - if ((t /= 1 / 2) < 1) return 1 / 2 * t * t; + if ((t /= 1 / 2) < 1){ + return 1 / 2 * t * t; + } return -1 / 2 * ((--t) * (t - 2) - 1); }, easeInCubic: function (t) { @@ -536,7 +563,9 @@ return 1 * ((t = t / 1 - 1) * t * t + 1); }, easeInOutCubic: function (t) { - if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t; + if ((t /= 1 / 2) < 1){ + return 1 / 2 * t * t * t; + } return 1 / 2 * ((t -= 2) * t * t + 2); }, easeInQuart: function (t) { @@ -546,7 +575,9 @@ return -1 * ((t = t / 1 - 1) * t * t * t - 1); }, easeInOutQuart: function (t) { - if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t; + if ((t /= 1 / 2) < 1){ + return 1 / 2 * t * t * t * t; + } return -1 / 2 * ((t -= 2) * t * t * t - 2); }, easeInQuint: function (t) { @@ -556,7 +587,9 @@ return 1 * ((t = t / 1 - 1) * t * t * t * t + 1); }, easeInOutQuint: function (t) { - if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t * t; + if ((t /= 1 / 2) < 1){ + return 1 / 2 * t * t * t * t * t; + } return 1 / 2 * ((t -= 2) * t * t * t * t + 2); }, easeInSine: function (t) { @@ -575,60 +608,95 @@ return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1); }, easeInOutExpo: function (t) { - if (t === 0) return 0; - if (t === 1) return 1; - if ((t /= 1 / 2) < 1) return 1 / 2 * Math.pow(2, 10 * (t - 1)); + if (t === 0){ + return 0; + } + if (t === 1){ + return 1; + } + if ((t /= 1 / 2) < 1){ + return 1 / 2 * Math.pow(2, 10 * (t - 1)); + } return 1 / 2 * (-Math.pow(2, -10 * --t) + 2); }, easeInCirc: function (t) { - if (t >= 1) return t; + if (t >= 1){ + return t; + } return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1); }, easeOutCirc: function (t) { return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t); }, easeInOutCirc: function (t) { - if ((t /= 1 / 2) < 1) return -1 / 2 * (Math.sqrt(1 - t * t) - 1); + if ((t /= 1 / 2) < 1){ + return -1 / 2 * (Math.sqrt(1 - t * t) - 1); + } return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1); }, easeInElastic: function (t) { var s = 1.70158; var p = 0; var a = 1; - if (t === 0) return 0; - if ((t /= 1) == 1) return 1; - if (!p) p = 1 * 0.3; + if (t === 0){ + return 0; + } + if ((t /= 1) == 1){ + return 1; + } + if (!p){ + p = 1 * 0.3; + } if (a < Math.abs(1)) { a = 1; s = p / 4; - } else s = p / (2 * Math.PI) * Math.asin(1 / a); + } else{ + s = p / (2 * Math.PI) * Math.asin(1 / a); + } return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p)); }, easeOutElastic: function (t) { var s = 1.70158; var p = 0; var a = 1; - if (t === 0) return 0; - if ((t /= 1) == 1) return 1; - if (!p) p = 1 * 0.3; + if (t === 0){ + return 0; + } + if ((t /= 1) == 1){ + return 1; + } + if (!p){ + p = 1 * 0.3; + } if (a < Math.abs(1)) { a = 1; s = p / 4; - } else s = p / (2 * Math.PI) * Math.asin(1 / a); + } else{ + s = p / (2 * Math.PI) * Math.asin(1 / a); + } return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1; }, easeInOutElastic: function (t) { var s = 1.70158; var p = 0; var a = 1; - if (t === 0) return 0; - if ((t /= 1 / 2) == 2) return 1; - if (!p) p = 1 * (0.3 * 1.5); + if (t === 0){ + return 0; + } + if ((t /= 1 / 2) == 2){ + return 1; + } + if (!p){ + p = 1 * (0.3 * 1.5); + } if (a < Math.abs(1)) { a = 1; s = p / 4; - } else s = p / (2 * Math.PI) * Math.asin(1 / a); - if (t < 1) return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p)); + } else { + s = p / (2 * Math.PI) * Math.asin(1 / a); + } + if (t < 1){ + return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));} return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1; }, easeInBack: function (t) { @@ -641,7 +709,9 @@ }, easeInOutBack: function (t) { var s = 1.70158; - if ((t /= 1 / 2) < 1) return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)); + if ((t /= 1 / 2) < 1){ + return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)); + } return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); }, easeInBounce: function (t) { @@ -659,7 +729,9 @@ } }, easeInOutBounce: function (t) { - if (t < 1 / 2) return easingEffects.easeInBounce(t * 2) * 0.5; + if (t < 1 / 2){ + return easingEffects.easeInBounce(t * 2) * 0.5; + } return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5; } }, @@ -762,14 +834,21 @@ }); }, getMaximumWidth = helpers.getMaximumWidth = function(domNode){ - var container = domNode.parentNode; + var container = domNode.parentNode, + padding = parseInt(getStyle(container, 'padding-left')) + parseInt(getStyle(container, 'padding-right')); // TODO = check cross browser stuff with this. - return container.clientWidth; + return container ? container.clientWidth - padding : 0; }, getMaximumHeight = helpers.getMaximumHeight = function(domNode){ - var container = domNode.parentNode; + var container = domNode.parentNode, + padding = parseInt(getStyle(container, 'padding-bottom')) + parseInt(getStyle(container, 'padding-top')); // TODO = check cross browser stuff with this. - return container.clientHeight; + return container ? container.clientHeight - padding : 0; + }, + getStyle = helpers.getStyle = function (el, property) { + return el.currentStyle ? + el.currentStyle[property] : + document.defaultView.getComputedStyle(el, null).getPropertyValue(property); }, getMaximumSize = helpers.getMaximumSize = helpers.getMaximumWidth, // legacy support retinaScale = helpers.retinaScale = function(chart){ @@ -844,7 +923,7 @@ }, stop : function(){ // Stops any current animation loop occuring - cancelAnimFrame(this.animationFrame); + Chart.animationService.cancelAnimation(this); return this; }, resize : function(callback){ @@ -868,15 +947,26 @@ if (reflow){ this.reflow(); } + if (this.options.animation && !reflow){ - helpers.animationLoop( - this.draw, - this.options.animationSteps, - this.options.animationEasing, - this.options.onAnimationProgress, - this.options.onAnimationComplete, - this - ); + var animation = new Chart.Animation(); + animation.numSteps = this.options.animationSteps; + animation.easing = this.options.animationEasing; + + // render function + animation.render = function(chartInstance, animationObject) { + var easingFunction = helpers.easingEffects[animationObject.easing]; + var stepDecimal = animationObject.currentStep / animationObject.numSteps; + var easeDecimal = easingFunction(stepDecimal); + + chartInstance.draw(easeDecimal, stepDecimal, animationObject.currentStep); + }; + + // user events + animation.onAnimationProgress = this.options.onAnimationProgress; + animation.onAnimationComplete = this.options.onAnimationComplete; + + Chart.animationService.addAnimation(this, animation); } else{ this.draw(); @@ -885,9 +975,10 @@ return this; }, generateLegend : function(){ - return template(this.options.legendTemplate,this); + return helpers.template(this.options.legendTemplate, this); }, destroy : function(){ + this.stop(); this.clear(); unbindEvents(this, this.events); var canvas = this.chart.canvas; @@ -1015,7 +1106,7 @@ labels: tooltipLabels, legendColors: tooltipColors, legendColorBackground : this.options.multiTooltipKeyBackground, - title: ChartElements[0].label, + title: template(this.options.tooltipTitleTemplate,ChartElements[0]), chart: this.chart, ctx: this.chart.ctx, custom: this.options.customTooltips @@ -1199,9 +1290,18 @@ y: chartY }); + // Normalize all angles to 0 - 2*PI (0 - 360°) + var pointRelativeAngle = pointRelativePosition.angle % (Math.PI * 2), + startAngle = (Math.PI * 2 + this.startAngle) % (Math.PI * 2), + endAngle = (Math.PI * 2 + this.endAngle) % (Math.PI * 2) || 360; + + // Calculate wether the pointRelativeAngle is between the start and the end angle + var betweenAngles = (endAngle < startAngle) ? + pointRelativeAngle <= endAngle || pointRelativeAngle >= startAngle: + pointRelativeAngle >= startAngle && pointRelativeAngle <= endAngle; + //Check if within the range of the open/close angle - var betweenAngles = (pointRelativePosition.angle >= this.startAngle && pointRelativePosition.angle <= this.endAngle), - withinRadius = (pointRelativePosition.distance >= this.innerRadius && pointRelativePosition.distance <= this.outerRadius); + var withinRadius = (pointRelativePosition.distance >= this.innerRadius && pointRelativePosition.distance <= this.outerRadius); return (betweenAngles && withinRadius); //Ensure within the outside of the arc centre, but inside arc outer @@ -1222,9 +1322,9 @@ ctx.beginPath(); - ctx.arc(this.x, this.y, this.outerRadius, this.startAngle, this.endAngle); + ctx.arc(this.x, this.y, this.outerRadius < 0 ? 0 : this.outerRadius, this.startAngle, this.endAngle); - ctx.arc(this.x, this.y, this.innerRadius, this.endAngle, this.startAngle, true); + ctx.arc(this.x, this.y, this.innerRadius < 0 ? 0 : this.innerRadius, this.endAngle, this.startAngle, true); ctx.closePath(); ctx.strokeStyle = this.strokeColor; @@ -1283,6 +1383,16 @@ } }); + Chart.Animation = Chart.Element.extend({ + currentStep: null, // the current animation step + numSteps: 60, // default number of steps + easing: "", // the easing to use for this animation + render: null, // render function used by the animation service + + onAnimationProgress: null, // user specified callback to fire on each step of the animation + onAnimationComplete: null, // user specified callback to fire when the animation finishes + }); + Chart.Tooltip = Chart.Element.extend({ draw : function(){ @@ -1372,7 +1482,8 @@ this.titleFont = fontString(this.titleFontSize,this.titleFontStyle,this.titleFontFamily); - this.height = (this.labels.length * this.fontSize) + ((this.labels.length-1) * (this.fontSize/2)) + (this.yPadding*2) + this.titleFontSize *1.5; + this.titleHeight = this.title ? this.titleFontSize * 1.5 : 0; + this.height = (this.labels.length * this.fontSize) + ((this.labels.length-1) * (this.fontSize/2)) + (this.yPadding*2) + this.titleHeight; this.ctx.font = this.titleFont; @@ -1408,9 +1519,9 @@ //If the index is zero, we're getting the title if (index === 0){ - return baseLineHeight + this.titleFontSize/2; + return baseLineHeight + this.titleHeight / 3; } else{ - return baseLineHeight + ((this.fontSize*1.5*afterTitleIndex) + this.fontSize/2) + this.titleFontSize * 1.5; + return baseLineHeight + ((this.fontSize * 1.5 * afterTitleIndex) + this.fontSize / 2) + this.titleHeight; } }, @@ -1466,7 +1577,7 @@ for (var i=0; i<=this.steps; i++){ this.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)})); } - this.yLabelWidth = (this.display && this.showLabels) ? longestText(this.ctx,this.font,this.yLabels) : 0; + this.yLabelWidth = (this.display && this.showLabels) ? longestText(this.ctx,this.font,this.yLabels) + 10 : 0; }, addXLabel : function(label){ this.xLabels.push(label); @@ -1490,6 +1601,9 @@ this.startPoint += this.padding; this.endPoint -= this.padding; + // Cache the starting endpoint, excluding the space for x labels + var cachedEndPoint = this.endPoint; + // Cache the starting height, so can determine if we need to recalculate the scale yAxis var cachedHeight = this.endPoint - this.startPoint, cachedYLabelWidth; @@ -1521,6 +1635,7 @@ // Only go through the xLabel loop again if the yLabel width has changed if (cachedYLabelWidth < this.yLabelWidth){ + this.endPoint = cachedEndPoint; this.calculateXLabelRotation(); } } @@ -1539,7 +1654,7 @@ this.xScalePaddingRight = lastWidth/2 + 3; - this.xScalePaddingLeft = (firstWidth/2 > this.yLabelWidth + 10) ? firstWidth/2 : this.yLabelWidth + 10; + this.xScalePaddingLeft = (firstWidth/2 > this.yLabelWidth) ? firstWidth/2 : this.yLabelWidth; this.xLabelRotation = 0; if (this.display){ @@ -1558,7 +1673,7 @@ lastRotated = cosRotation * lastWidth; // We're right aligning the text now. - if (firstRotated + this.fontSize / 2 > this.yLabelWidth + 8){ + if (firstRotated + this.fontSize / 2 > this.yLabelWidth){ this.xScalePaddingLeft = firstRotated + this.fontSize / 2; } this.xScalePaddingRight = this.fontSize/2; @@ -1940,14 +2055,40 @@ ctx.lineWidth = this.angleLineWidth; ctx.strokeStyle = this.angleLineColor; for (var i = this.valuesCount - 1; i >= 0; i--) { - if (this.angleLineWidth > 0){ - var outerPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max)); + var centerOffset = null, outerPosition = null; + + if (this.angleLineWidth > 0 && (i % this.angleLineInterval === 0)){ + centerOffset = this.calculateCenterOffset(this.max); + outerPosition = this.getPointPosition(i, centerOffset); ctx.beginPath(); ctx.moveTo(this.xCenter, this.yCenter); ctx.lineTo(outerPosition.x, outerPosition.y); ctx.stroke(); ctx.closePath(); } + + if (this.backgroundColors && this.backgroundColors.length == this.valuesCount) { + if (centerOffset == null) + centerOffset = this.calculateCenterOffset(this.max); + + if (outerPosition == null) + outerPosition = this.getPointPosition(i, centerOffset); + + var previousOuterPosition = this.getPointPosition(i === 0 ? this.valuesCount - 1 : i - 1, centerOffset); + var nextOuterPosition = this.getPointPosition(i === this.valuesCount - 1 ? 0 : i + 1, centerOffset); + + var previousOuterHalfway = { x: (previousOuterPosition.x + outerPosition.x) / 2, y: (previousOuterPosition.y + outerPosition.y) / 2 }; + var nextOuterHalfway = { x: (outerPosition.x + nextOuterPosition.x) / 2, y: (outerPosition.y + nextOuterPosition.y) / 2 }; + + ctx.beginPath(); + ctx.moveTo(this.xCenter, this.yCenter); + ctx.lineTo(previousOuterHalfway.x, previousOuterHalfway.y); + ctx.lineTo(outerPosition.x, outerPosition.y); + ctx.lineTo(nextOuterHalfway.x, nextOuterHalfway.y); + ctx.fillStyle = this.backgroundColors[i]; + ctx.fill(); + ctx.closePath(); + } // Extra 3px out for some label spacing var pointLabelPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max) + 5); ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily); @@ -1984,6 +2125,93 @@ } }); + Chart.animationService = { + frameDuration: 17, + animations: [], + dropFrames: 0, + addAnimation: function(chartInstance, animationObject) { + for (var index = 0; index < this.animations.length; ++ index){ + if (this.animations[index].chartInstance === chartInstance){ + // replacing an in progress animation + this.animations[index].animationObject = animationObject; + return; + } + } + + this.animations.push({ + chartInstance: chartInstance, + animationObject: animationObject + }); + + // If there are no animations queued, manually kickstart a digest, for lack of a better word + if (this.animations.length == 1) { + helpers.requestAnimFrame.call(window, this.digestWrapper); + } + }, + // Cancel the animation for a given chart instance + cancelAnimation: function(chartInstance) { + var index = helpers.findNextWhere(this.animations, function(animationWrapper) { + return animationWrapper.chartInstance === chartInstance; + }); + + if (index) + { + this.animations.splice(index, 1); + } + }, + // calls startDigest with the proper context + digestWrapper: function() { + Chart.animationService.startDigest.call(Chart.animationService); + }, + startDigest: function() { + + var startTime = Date.now(); + var framesToDrop = 0; + + if(this.dropFrames > 1){ + framesToDrop = Math.floor(this.dropFrames); + this.dropFrames -= framesToDrop; + } + + for (var i = 0; i < this.animations.length; i++) { + + if (this.animations[i].animationObject.currentStep === null){ + this.animations[i].animationObject.currentStep = 0; + } + + this.animations[i].animationObject.currentStep += 1 + framesToDrop; + if(this.animations[i].animationObject.currentStep > this.animations[i].animationObject.numSteps){ + this.animations[i].animationObject.currentStep = this.animations[i].animationObject.numSteps; + } + + this.animations[i].animationObject.render(this.animations[i].chartInstance, this.animations[i].animationObject); + + // Check if executed the last frame. + if (this.animations[i].animationObject.currentStep == this.animations[i].animationObject.numSteps){ + // Call onAnimationComplete + this.animations[i].animationObject.onAnimationComplete.call(this.animations[i].chartInstance); + // Remove the animation. + this.animations.splice(i, 1); + // Keep the index in place to offset the splice + i--; + } + } + + var endTime = Date.now(); + var delay = endTime - startTime - this.frameDuration; + var frameDelay = delay / this.frameDuration; + + if(frameDelay > 1){ + this.dropFrames += frameDelay; + } + + // Do we have more stuff to animate? + if (this.animations.length > 0){ + helpers.requestAnimFrame.call(window, this.digestWrapper); + } + } + }; + // Attach global event to resize each chart instance when the browser resizes helpers.addEvent(window, "resize", (function(){ // Basic debounce of resize function so it doesn't hurt performance when resizing browser. @@ -2004,7 +2232,7 @@ if (amd) { - define(function(){ + define('Chart', [], function(){ return Chart; }); } else if (typeof module === 'object' && module.exports) { @@ -2245,23 +2473,58 @@ var ColorManager = function(){ return v2*x+v1*(1-x); } - function getGradientColor(colors, i, base, scaleFactor){ - var fIndex = (i-base)*scaleFactor; + function getGradientColor(colors, negativeColors, i, base, scaleFactor, scaleFactorNegative){ + var useColors = colors; + var useScaleFactor = scaleFactor; + + if (negativeColors) { + if (i < 0) { + i = Math.abs(i); + useColors = negativeColors; + + if (scaleFactorNegative === false) { + base = Math.abs(base); + useScaleFactor = Math.abs(scaleFactor); + } else { + useScaleFactor = Math.abs(scaleFactorNegative); + } + } + } + + var fIndex = (i-base)*useScaleFactor; var iIndex = Math.floor(fIndex); + if (iIndex > useColors.length - 1){ iIndex = useColors.length - 1; } + if (iIndex < 0) { iIndex = 0 }; + var iv = fIndex - iIndex; var iIndex1 = iIndex+1; - if (iIndex1 > colors.length - 1){ iIndex1 = iIndex; } + if (iIndex1 > useColors.length - 1){ iIndex1 = iIndex; } return { - r: interp(colors[iIndex][0], colors[iIndex1][0], iv), - g: interp(colors[iIndex][1], colors[iIndex1][1], iv), - b: interp(colors[iIndex][2], colors[iIndex1][2], iv), - a: interp(colors[iIndex][3], colors[iIndex1][3], iv) + r: interp(useColors[iIndex][0], useColors[iIndex1][0], iv), + g: interp(useColors[iIndex][1], useColors[iIndex1][1], iv), + b: interp(useColors[iIndex][2], useColors[iIndex1][2], iv), + a: interp(useColors[iIndex][3], useColors[iIndex1][3], iv) }; } - function getIndexedColor(colors, i, base, scaleFactor){ + function getIndexedColor(colors, negativeColors, i, base, scaleFactor, scaleFactorNegative){ var index = Math.floor((i-base)*scaleFactor); + + if (negativeColors && index < 0) { + index = (index * -1) - 1; + if (index >= negativeColors.length) { + index = negativeColors.length - 1; + } + + return { + r: negativeColors[index][0], + g: negativeColors[index][1], + b: negativeColors[index][2], + a: negativeColors[index][3], + }; + } + return { r: colors[index][0], g: colors[index][1], @@ -2287,35 +2550,63 @@ var ColorManager = function(){ function cssColorToArray(color){ return cssColorParser(color); } - + this.getColor = function(){ console.error('ColorManager: colors have not been setup'); }; this.colors = []; + this.negativeColors = []; - this.setup = function(min, max, colors, colorInterpolation, colorHighlightMultiplier){ + this.setup = function (min, max, colors, negativeColors, colorInterpolation, colorHighlightMultiplier) { var colorFunction, scaleFactor; - var dataLength = max-min; var base = min; + var dataLength = max - min; + + var scaleFactorNegative = false; + var dataLengthNegative = false; + + if (negativeColors) { + if (max < 0) { + max = max + 0.000001; + base = max; + } else if (max > 0 && min < 0) { + dataLength = max; + dataLengthNegative = min; + base = 0; + } + } - if (colorInterpolation === 'gradient'){ + if (colorInterpolation === 'gradient') { colorFunction = getGradientColor; - scaleFactor = (colors.length-1)/(dataLength -1); + scaleFactor = (colors.length ) / (dataLength !== 0 ? dataLength : 1); } else { colorFunction = getIndexedColor; - scaleFactor = (colors.length)/(dataLength+1); - } + scaleFactor = (colors.length) / (dataLength + 1); + } - this.colors = colors.map(function(clr){ + if (negativeColors) { + if (max > 0 && min < 0) { + if (colorInterpolation === 'gradient') { + scaleFactorNegative = (negativeColors.length - 1) / (dataLengthNegative - 1); + } else { + scaleFactorNegative = (negativeColors.length) / (dataLengthNegative + 1); + } + } + } + + this.colors = colors.map(function (clr) { return cssColorToArray(clr); }); - - this.getColor = function(dataValue){ - var clr = colorFunction(this.colors, dataValue, base, scaleFactor); + this.negativeColors = negativeColors.map(function (clr) { + return cssColorToArray(clr); + }); + + this.getColor = function (dataValue) { + var clr = colorFunction(this.colors, this.negativeColors, dataValue, base, scaleFactor, scaleFactorNegative); var hclr = getHighlightColor(clr, colorHighlightMultiplier); - return { + return { color: rgbString(clr.r, clr.g, clr.b, clr.a), highlight: rgbString(hclr.r, hclr.g, hclr.b, hclr.a) }; @@ -2736,8 +3027,8 @@ var ColorManager = function(){ removeDataset: function(){ this.datasets.pop(); this.scale.yLabels.pop(); - this.scale.steps -= 1; - this.scale.max -= 1; + this.scale.steps -= 1; + this.scale.max -= 1; this.scale.fit(); this.findMaxAndMin(true); this.applyColors(); @@ -2747,10 +3038,11 @@ var ColorManager = function(){ applyColors : function(){ this.colorManager.setup( - this.min, - this.max, - this.options.colors, - this.options.colorInterpolation, + this.min, + this.max, + this.options.colors, + this.options.negativeColors, + this.options.colorInterpolation, this.options.colorHighlightMultiplier ); diff --git a/dst/Chart.HeatMap.S.min.js b/dst/Chart.HeatMap.S.min.js index 609358f..83c22af 100644 --- a/dst/Chart.HeatMap.S.min.js +++ b/dst/Chart.HeatMap.S.min.js @@ -6,5 +6,5 @@ * Copyright 2015 Nick Downie * Released under the MIT license * https://github.com/nnnick/Chart.js/blob/master/LICENSE.md - */(function(){"use strict";var e=this,t=e.Chart,n=function(e){var t=this;this.canvas=e.canvas,this.ctx=e;var n=function(e,t){return e["offset"+t]?e["offset"+t]:document.defaultView.getComputedStyle(e).getPropertyValue(t)},i=this.width=n(e.canvas,"Width"),s=this.height=n(e.canvas,"Height");e.canvas.width=i,e.canvas.height=s;var i=this.width=e.canvas.width,s=this.height=e.canvas.height;return this.aspectRatio=this.width/this.height,r.retinaScale(this),this};n.defaults={global:{animation:!0,animationSteps:60,animationEasing:"easeOutQuart",showScale:!0,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleIntegersOnly:!0,scaleBeginAtZero:!1,scaleFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",responsive:!1,maintainAspectRatio:!0,showTooltips:!0,customTooltips:!1,tooltipEvents:["mousemove","touchstart","touchmove","mouseout"],tooltipFillColor:"rgba(0,0,0,0.8)",tooltipFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",tooltipFontSize:14,tooltipFontStyle:"normal",tooltipFontColor:"#fff",tooltipTitleFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",tooltipTitleFontSize:14,tooltipTitleFontStyle:"bold",tooltipTitleFontColor:"#fff",tooltipYPadding:6,tooltipXPadding:6,tooltipCaretSize:8,tooltipCornerRadius:6,tooltipXOffset:10,tooltipTemplate:"<%if (label){%><%=label%>: <%}%><%= value %>",multiTooltipTemplate:"<%= value %>",multiTooltipKeyBackground:"#fff",onAnimationProgress:function(){},onAnimationComplete:function(){}}},n.types={};var r=n.helpers={},i=r.each=function(e,t,n){var r=Array.prototype.slice.call(arguments,3);if(e)if(e.length===+e.length){var i;for(i=0;i=0;r--){var i=e[r];if(t(i))return i}},h=r.inherits=function(e){var t=this,n=e&&e.hasOwnProperty("constructor")?e.constructor:function(){return t.apply(this,arguments)},r=function(){this.constructor=n};return r.prototype=t.prototype,n.prototype=new r,n.extend=h,e&&o(n.prototype,e),n.__super__=t.prototype,n},p=r.noop=function(){},d=r.uid=function(){var e=0;return function(){return"chart-"+e++}}(),v=r.warn=function(e){window.console&&typeof window.console.warn=="function"&&console.warn(e)},m=r.amd=typeof define=="function"&&define.amd,g=r.isNumber=function(e){return!isNaN(parseFloat(e))&&isFinite(e)},y=r.max=function(e){return Math.max.apply(Math,e)},b=r.min=function(e){return Math.min.apply(Math,e)},w=r.cap=function(e,t,n){if(g(t)){if(e>t)return t}else if(g(n)&&e=o,a=y(e),f=b(e);a===f&&(a+=.5,f>=.5&&!r?f-=.5:a+=.5);var l=Math.abs(a-f),c=C(l),h=Math.ceil(a/(1*Math.pow(10,c)))*Math.pow(10,c),p=r?0:Math.floor(f/(1*Math.pow(10,c)))*Math.pow(10,c),d=h-p,v=Math.pow(10,c),m=Math.round(d/v);while((m>o||m*2o)v*=2,m=Math.round(d/v),m%1!==0&&(u=!0);else if(i&&c>=0){if(v/2%1!==0)break;v/=2,m=Math.round(d/v)}else v/=2,m=Math.round(d/v);return u&&(m=s,v=d/m),{steps:m,stepValue:v,min:p,max:p+m*v}},L=r.template=function(e,t){function r(e,t){var r=/\W/.test(e)?new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+e.replace(/[\r\t\n]/g," ").split("<%").join(" ").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split(" ").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');"):n[e]=n[e];return t?r(t):r}if(e instanceof Function)return e(t);var n={};return r(e,t)},A=r.generateLabels=function(e,t,n,r){var s=new Array(t);return labelTemplateString&&i(s,function(t,i){s[i]=L(e,{value:n+r*(i+1)})}),s},O=r.easingEffects={linear:function(e){return e},easeInQuad:function(e){return e*e},easeOutQuad:function(e){return-1*e*(e-2)},easeInOutQuad:function(e){return(e/=.5)<1?.5*e*e:-0.5*(--e*(e-2)-1)},easeInCubic:function(e){return e*e*e},easeOutCubic:function(e){return 1*((e=e/1-1)*e*e+1)},easeInOutCubic:function(e){return(e/=.5)<1?.5*e*e*e:.5*((e-=2)*e*e+2)},easeInQuart:function(e){return e*e*e*e},easeOutQuart:function(e){return-1*((e=e/1-1)*e*e*e-1)},easeInOutQuart:function(e){return(e/=.5)<1?.5*e*e*e*e:-0.5*((e-=2)*e*e*e-2)},easeInQuint:function(e){return 1*(e/=1)*e*e*e*e},easeOutQuint:function(e){return 1*((e=e/1-1)*e*e*e*e+1)},easeInOutQuint:function(e){return(e/=.5)<1?.5*e*e*e*e*e:.5*((e-=2)*e*e*e*e+2)},easeInSine:function(e){return-1*Math.cos(e/1*(Math.PI/2))+1},easeOutSine:function(e){return 1*Math.sin(e/1*(Math.PI/2))},easeInOutSine:function(e){return-0.5*(Math.cos(Math.PI*e/1)-1)},easeInExpo:function(e){return e===0?1:1*Math.pow(2,10*(e/1-1))},easeOutExpo:function(e){return e===1?1:1*(-Math.pow(2,-10*e/1)+1)},easeInOutExpo:function(e){return e===0?0:e===1?1:(e/=.5)<1?.5*Math.pow(2,10*(e-1)):.5*(-Math.pow(2,-10*--e)+2)},easeInCirc:function(e){return e>=1?e:-1*(Math.sqrt(1-(e/=1)*e)-1)},easeOutCirc:function(e){return 1*Math.sqrt(1-(e=e/1-1)*e)},easeInOutCirc:function(e){return(e/=.5)<1?-0.5*(Math.sqrt(1-e*e)-1):.5*(Math.sqrt(1-(e-=2)*e)+1)},easeInElastic:function(e){var t=1.70158,n=0,r=1;return e===0?0:(e/=1)==1?1:(n||(n=.3),rr?n:r}),r},V=r.drawRoundedRectangle=function(e,t,n,r,i,s){e.beginPath(),e.moveTo(t+s,n),e.lineTo(t+r-s,n),e.quadraticCurveTo(t+r,n,t+r,n+s),e.lineTo(t+r,n+i-s),e.quadraticCurveTo(t+r,n+i,t+r-s,n+i),e.lineTo(t+s,n+i),e.quadraticCurveTo(t,n+i,t,n+i-s),e.lineTo(t,n+s),e.quadraticCurveTo(t,n,t+s,n),e.closePath()};n.instances={},n.Type=function(e,t,r){this.options=t,this.chart=r,this.id=d(),n.instances[this.id]=this,t.responsive&&this.resize(),this.initialize.call(this,e)},o(n.Type.prototype,{initialize:function(){return this},clear:function(){return z(this.chart),this},stop:function(){return _(this.animationFrame),this},resize:function(e){this.stop();var t=this.chart.canvas,n=I(this.chart.canvas),r=this.options.maintainAspectRatio?n/this.chart.aspectRatio:q(this.chart.canvas);return t.width=this.chart.width=n,t.height=this.chart.height=r,U(this.chart),typeof e=="function"&&e.apply(this,Array.prototype.slice.call(arguments,1)),this},reflow:p,render:function(e){return e&&this.reflow(),this.options.animation&&!e?r.animationLoop(this.draw,this.options.animationSteps,this.options.animationEasing,this.options.onAnimationProgress,this.options.onAnimationComplete,this):(this.draw(),this.options.onAnimationComplete.call(this)),this},generateLegend:function(){return L(this.options.legendTemplate,this)},destroy:function(){this.clear(),F(this,this.events);var e=this.chart.canvas;e.width=this.chart.width,e.height=this.chart.height,e.style.removeProperty?(e.style.removeProperty("width"),e.style.removeProperty("height")):(e.style.removeAttribute("width"),e.style.removeAttribute("height")),delete n.instances[this.id]},showTooltip:function(e,t){typeof this.activeElements=="undefined"&&(this.activeElements=[]);var s=function(e){var t=!1;return e.length!==this.activeElements.length?(t=!0,t):(i(e,function(e,n){e!==this.activeElements[n]&&(t=!0)},this),t)}.call(this,e);if(!s&&!t)return;this.activeElements=e,this.draw(),this.options.customTooltips&&this.options.customTooltips(!1);if(e.length>0)if(this.datasets&&this.datasets.length>1){var o,u;for(var f=this.datasets.length-1;f>=0;f--){o=this.datasets[f].points||this.datasets[f].bars||this.datasets[f].segments,u=a(o,e[0]);if(u!==-1)break}var l=[],c=[],h=function(e){var t=[],n,i=[],s=[],o,a,f,h;return r.each(this.datasets,function(e){n=e.points||e.bars||e.segments,n[u]&&n[u].hasValue()&&t.push(n[u])}),r.each(t,function(e){i.push(e.x),s.push(e.y),l.push(r.template(this.options.multiTooltipTemplate,e)),c.push({fill:e._saved.fillColor||e.fillColor,stroke:e._saved.strokeColor||e.strokeColor})},this),h=b(s),a=y(s),f=b(i),o=y(i),{x:f>this.chart.width/2?f:o,y:(h+a)/2}}.call(this,u);(new n.MultiTooltip({x:h.x,y:h.y,xPadding:this.options.tooltipXPadding,yPadding:this.options.tooltipYPadding,xOffset:this.options.tooltipXOffset,fillColor:this.options.tooltipFillColor,textColor:this.options.tooltipFontColor,fontFamily:this.options.tooltipFontFamily,fontStyle:this.options.tooltipFontStyle,fontSize:this.options.tooltipFontSize,titleTextColor:this.options.tooltipTitleFontColor,titleFontFamily:this.options.tooltipTitleFontFamily,titleFontStyle:this.options.tooltipTitleFontStyle,titleFontSize:this.options.tooltipTitleFontSize,cornerRadius:this.options.tooltipCornerRadius,labels:l,legendColors:c,legendColorBackground:this.options.multiTooltipKeyBackground,title:e[0].label,chart:this.chart,ctx:this.chart.ctx,custom:this.options.customTooltips})).draw()}else i(e,function(e){var t=e.tooltipPosition();(new n.Tooltip({x:Math.round(t.x),y:Math.round(t.y),xPadding:this.options.tooltipXPadding,yPadding:this.options.tooltipYPadding,fillColor:this.options.tooltipFillColor,textColor:this.options.tooltipFontColor,fontFamily:this.options.tooltipFontFamily,fontStyle:this.options.tooltipFontStyle,fontSize:this.options.tooltipFontSize,caretHeight:this.options.tooltipCaretSize,cornerRadius:this.options.tooltipCornerRadius,text:L(this.options.tooltipTemplate,e),chart:this.chart,custom:this.options.customTooltips})).draw()},this);return this},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)}}),n.Type.extend=function(e){var t=this,r=function(){return t.apply(this,arguments)};r.prototype=s(t.prototype),o(r.prototype,e),r.extend=n.Type.extend;if(e.name||t.prototype.name){var i=e.name||t.prototype.name,a=n.defaults[t.prototype.name]?s(n.defaults[t.prototype.name]):{};n.defaults[i]=o(a,e.defaults),n.types[i]=r,n.prototype[i]=function(e,t){var s=u(n.defaults.global,n.defaults[i],t||{});return new r(e,s,this)}}else v("Name not provided for this chart, so it hasn't been registered");return t},n.Element=function(e){o(this,e),this.initialize.apply(this,arguments),this.save()},o(n.Element.prototype,{initialize:function(){},restore:function(e){return e?i(e,function(e){this[e]=this._saved[e]},this):o(this,this._saved),this},save:function(){return this._saved=s(this),delete this._saved._saved,this},update:function(e){return i(e,function(e,t){this._saved[t]=this[t],this[t]=e},this),this},transition:function(e,t){return i(e,function(e,n){this[n]=(e-this._saved[n])*t+this._saved[n]},this),this},tooltipPosition:function(){return{x:this.x,y:this.y}},hasValue:function(){return g(this.value)}}),n.Element.extend=h,n.Point=n.Element.extend({display:!0,inRange:function(e,t){var n=this.hitDetectionRadius+this.radius;return Math.pow(e-this.x,2)+Math.pow(t-this.y,2)=this.startAngle&&n.angle<=this.endAngle,s=n.distance>=this.innerRadius&&n.distance<=this.outerRadius;return i&&s},tooltipPosition:function(){var e=this.startAngle+(this.endAngle-this.startAngle)/2,t=(this.outerRadius-this.innerRadius)/2+this.innerRadius;return{x:this.x+Math.cos(e)*t,y:this.y+Math.sin(e)*t}},draw:function(e){var t=e||1,n=this.ctx;n.beginPath(),n.arc(this.x,this.y,this.outerRadius,this.startAngle,this.endAngle),n.arc(this.x,this.y,this.innerRadius,this.endAngle,this.startAngle,!0),n.closePath(),n.strokeStyle=this.strokeColor,n.lineWidth=this.strokeWidth,n.fillStyle=this.fillColor,n.fill(),n.lineJoin="bevel",this.showStroke&&n.stroke()}}),n.Rectangle=n.Element.extend({draw:function(){var e=this.ctx,t=this.width/2,n=this.x-t,r=this.x+t,i=this.base-(this.base-this.y),s=this.strokeWidth/2;this.showStroke&&(n+=s,r-=s,i+=s),e.beginPath(),e.fillStyle=this.fillColor,e.strokeStyle=this.strokeColor,e.lineWidth=this.strokeWidth,e.moveTo(n,this.base),e.lineTo(n,i),e.lineTo(r,i),e.lineTo(r,this.base),e.fill(),this.showStroke&&e.stroke()},height:function(){return this.base-this.y},inRange:function(e,t){return e>=this.x-this.width/2&&e<=this.x+this.width/2&&t>=this.y&&t<=this.base}}),n.Tooltip=n.Element.extend({draw:function(){var e=this.chart.ctx;e.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.xAlign="center",this.yAlign="above";var t=this.caretPadding=2,n=e.measureText(this.text).width+2*this.xPadding,r=this.fontSize+2*this.yPadding,i=r+this.caretHeight+t;this.x+n/2>this.chart.width?this.xAlign="left":this.x-n/2<0&&(this.xAlign="right"),this.y-i<0&&(this.yAlign="below");var s=this.x-n/2,o=this.y-i;e.fillStyle=this.fillColor;if(this.custom)this.custom(this);else{switch(this.yAlign){case"above":e.beginPath(),e.moveTo(this.x,this.y-t),e.lineTo(this.x+this.caretHeight,this.y-(t+this.caretHeight)),e.lineTo(this.x-this.caretHeight,this.y-(t+this.caretHeight)),e.closePath(),e.fill();break;case"below":o=this.y+t+this.caretHeight,e.beginPath(),e.moveTo(this.x,this.y+t),e.lineTo(this.x+this.caretHeight,this.y+t+this.caretHeight),e.lineTo(this.x-this.caretHeight,this.y+t+this.caretHeight),e.closePath(),e.fill()}switch(this.xAlign){case"left":s=this.x-n+(this.cornerRadius+this.caretHeight);break;case"right":s=this.x-(this.cornerRadius+this.caretHeight)}V(e,s,o,n,r,this.cornerRadius),e.fill(),e.fillStyle=this.textColor,e.textAlign="center",e.textBaseline="middle",e.fillText(this.text,s+n/2,o+r/2)}}}),n.MultiTooltip=n.Element.extend({initialize:function(){this.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.titleFont=W(this.titleFontSize,this.titleFontStyle,this.titleFontFamily),this.height=this.labels.length*this.fontSize+(this.labels.length-1)*(this.fontSize/2)+this.yPadding*2+this.titleFontSize*1.5,this.ctx.font=this.titleFont;var e=this.ctx.measureText(this.title).width,t=X(this.ctx,this.font,this.labels)+this.fontSize+3,n=y([t,e]);this.width=n+this.xPadding*2;var r=this.height/2;this.y-r<0?this.y=r:this.y+r>this.chart.height&&(this.y=this.chart.height-r),this.x>this.chart.width/2?this.x-=this.xOffset+this.width:this.x+=this.xOffset},getLineHeight:function(e){var t=this.y-this.height/2+this.yPadding,n=e-1;return e===0?t+this.titleFontSize/2:t+(this.fontSize*1.5*n+this.fontSize/2)+this.titleFontSize*1.5},draw:function(){if(this.custom)this.custom(this);else{V(this.ctx,this.x,this.y-this.height/2,this.width,this.height,this.cornerRadius);var e=this.ctx;e.fillStyle=this.fillColor,e.fill(),e.closePath(),e.textAlign="left",e.textBaseline="middle",e.fillStyle=this.titleTextColor,e.font=this.titleFont,e.fillText(this.title,this.x+this.xPadding,this.getLineHeight(0)),e.font=this.font,r.each(this.labels,function(t,n){e.fillStyle=this.textColor,e.fillText(t,this.x+this.xPadding+this.fontSize+3,this.getLineHeight(n+1)),e.fillStyle=this.legendColorBackground,e.fillRect(this.x+this.xPadding,this.getLineHeight(n+1)-this.fontSize/2,this.fontSize,this.fontSize),e.fillStyle=this.legendColors[n].fill,e.fillRect(this.x+this.xPadding,this.getLineHeight(n+1)-this.fontSize/2,this.fontSize,this.fontSize)},this)}}}),n.Scale=n.Element.extend({initialize:function(){this.fit()},buildYLabels:function(){this.yLabels=[];var e=E(this.stepValue);for(var t=0;t<=this.steps;t++)this.yLabels.push(L(this.templateString,{value:(this.min+t*this.stepValue).toFixed(e)}));this.yLabelWidth=this.display&&this.showLabels?X(this.ctx,this.font,this.yLabels):0},addXLabel:function(e){this.xLabels.push(e),this.valuesCount++,this.fit()},removeXLabel:function(){this.xLabels.shift(),this.valuesCount--,this.fit()},fit:function(){this.startPoint=this.display?this.fontSize:0,this.endPoint=this.display?this.height-this.fontSize*1.5-5:this.height,this.startPoint+=this.padding,this.endPoint-=this.padding;var e=this.endPoint-this.startPoint,t;this.calculateYRange(e),this.buildYLabels(),this.calculateXLabelRotation();while(e>this.endPoint-this.startPoint)e=this.endPoint-this.startPoint,t=this.yLabelWidth,this.calculateYRange(e),this.buildYLabels(),tthis.yLabelWidth+10?e/2:this.yLabelWidth+10,this.xLabelRotation=0;if(this.display){var i=X(this.ctx,this.font,this.xLabels),s,o;this.xLabelWidth=i;var u=Math.floor(this.calculateX(1)-this.calculateX(0))-6;while(this.xLabelWidth>u&&this.xLabelRotation===0||this.xLabelWidth>u&&this.xLabelRotation<=90&&this.xLabelRotation>0)s=Math.cos(S(this.xLabelRotation)),n=s*e,r=s*t,n+this.fontSize/2>this.yLabelWidth+8&&(this.xScalePaddingLeft=n+this.fontSize/2),this.xScalePaddingRight=this.fontSize/2,this.xLabelRotation++,this.xLabelWidth=s*i;this.xLabelRotation>0&&(this.endPoint-=Math.sin(S(this.xLabelRotation))*i+3)}else this.xLabelWidth=0,this.xScalePaddingRight=this.padding,this.xScalePaddingLeft=this.padding},calculateYRange:p,drawingArea:function(){return this.startPoint-this.endPoint},calculateY:function(e){var t=this.drawingArea()/(this.min-this.max);return this.endPoint-t*(e-this.min)},calculateX:function(e){var t=this.xLabelRotation>0,n=this.width-(this.xScalePaddingLeft+this.xScalePaddingRight),r=n/Math.max(this.valuesCount-(this.offsetGridLines?0:1),1),i=r*e+this.xScalePaddingLeft;return this.offsetGridLines&&(i+=r/2),Math.round(i)},update:function(e){r.extend(this,e),this.fit()},draw:function(){var e=this.ctx,t=(this.endPoint-this.startPoint)/this.steps,n=Math.round(this.xScalePaddingLeft);this.display&&(e.fillStyle=this.textColor,e.font=this.font,i(this.yLabels,function(i,s){var o=this.endPoint-t*s,u=Math.round(o),a=this.showHorizontalLines;e.textAlign="right",e.textBaseline="middle",this.showLabels&&e.fillText(i,n-10,o),s===0&&!a&&(a=!0),a&&e.beginPath(),s>0?(e.lineWidth=this.gridLineWidth,e.strokeStyle=this.gridLineColor):(e.lineWidth=this.lineWidth,e.strokeStyle=this.lineColor),u+=r.aliasPixel(e.lineWidth),a&&(e.moveTo(n,u),e.lineTo(this.width,u),e.stroke(),e.closePath()),e.lineWidth=this.lineWidth,e.strokeStyle=this.lineColor,e.beginPath(),e.moveTo(n-5,u),e.lineTo(n,u),e.stroke(),e.closePath()},this),i(this.xLabels,function(t,n){var r=this.calculateX(n)+T(this.lineWidth),i=this.calculateX(n-(this.offsetGridLines?.5:0))+T(this.lineWidth),s=this.xLabelRotation>0,o=this.showVerticalLines;n===0&&!o&&(o=!0),o&&e.beginPath(),n>0?(e.lineWidth=this.gridLineWidth,e.strokeStyle=this.gridLineColor):(e.lineWidth=this.lineWidth,e.strokeStyle=this.lineColor),o&&(e.moveTo(i,this.endPoint),e.lineTo(i,this.startPoint-3),e.stroke(),e.closePath()),e.lineWidth=this.lineWidth,e.strokeStyle=this.lineColor,e.beginPath(),e.moveTo(i,this.endPoint),e.lineTo(i,this.endPoint+5),e.stroke(),e.closePath(),e.save(),e.translate(r,s?this.endPoint+12:this.endPoint+8),e.rotate(S(this.xLabelRotation)*-1),e.font=this.font,e.textAlign=s?"right":"center",e.textBaseline=s?"middle":"top",e.fillText(t,0,0),e.restore()},this))}}),n.RadialScale=n.Element.extend({initialize:function(){this.size=b([this.height,this.width]),this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2},calculateCenterOffset:function(e){var t=this.drawingArea/(this.max-this.min);return(e-this.min)*t},update:function(){this.lineArc?this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2:this.setScaleSize(),this.buildYLabels()},buildYLabels:function(){this.yLabels=[];var e=E(this.stepValue);for(var t=0;t<=this.steps;t++)this.yLabels.push(L(this.templateString,{value:(this.min+t*this.stepValue).toFixed(e)}))},getCircumference:function(){return Math.PI*2/this.valuesCount},setScaleSize:function(){var e=b([this.height/2-this.pointLabelFontSize-5,this.width/2]),t,n,r,i,s=this.width,o,u,a=0,f,l,c,h,p,d,v;this.ctx.font=W(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);for(n=0;ns&&(s=t.x+i,o=n),t.x-is&&(s=t.x+r,o=n):n>this.valuesCount/2&&t.x-r0){var r=n*(this.drawingArea/this.steps),i=this.yCenter-r,s;if(this.lineWidth>0){e.strokeStyle=this.lineColor,e.lineWidth=this.lineWidth;if(this.lineArc)e.beginPath(),e.arc(this.xCenter,this.yCenter,r,0,Math.PI*2),e.closePath(),e.stroke();else{e.beginPath();for(var o=0;o=0;t--){if(this.angleLineWidth>0){var n=this.getPointPosition(t,this.calculateCenterOffset(this.max));e.beginPath(),e.moveTo(this.xCenter,this.yCenter),e.lineTo(n.x,n.y),e.stroke(),e.closePath()}var r=this.getPointPosition(t,this.calculateCenterOffset(this.max)+5);e.font=W(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily),e.fillStyle=this.pointLabelFontColor;var s=this.labels.length,o=this.labels.length/2,u=o/2,a=ts-u,f=t===u||t===s-u;t===0?e.textAlign="center":t===o?e.textAlign="center":t255?255:e}function n(e){return e<0?0:e>1?1:e}function r(e){return e[e.length-1]==="%"?t(parseFloat(e)/100*255):t(parseInt(e))}function i(e){return e[e.length-1]==="%"?n(parseFloat(e)/100):n(parseFloat(e))}function s(e,t,n){return n<0?n+=1:n>1&&(n-=1),n*6<1?e+(t-e)*n*6:n*2<1?t:n*3<2?e+(t-e)*(2/3-n)*6:e}function o(n){var o=n.replace(/ /g,"").toLowerCase();if(o in e)return e[o].slice();if(o[0]==="#"){if(o.length===4){var u=parseInt(o.substr(1),16);return u>=0&&u<=4095?[(u&3840)>>4|(u&3840)>>8,u&240|(u&240)>>4,u&15|(u&15)<<4,1]:null}if(o.length===7){var u=parseInt(o.substr(1),16);return u>=0&&u<=16777215?[(u&16711680)>>16,(u&65280)>>8,u&255,1]:null}return null}var a=o.indexOf("("),f=o.indexOf(")");if(a!==-1&&f+1===o.length){var l=o.substr(0,a),c=o.substr(a+1,f-(a+1)).split(","),h=1;switch(l){case"rgba":if(c.length!==4)return null;h=i(c.pop());case"rgb":if(c.length!==3)return null;return[r(c[0]),r(c[1]),r(c[2]),h];case"hsla":if(c.length!==4)return null;h=i(c.pop());case"hsl":if(c.length!==3)return null;var p=(parseFloat(c[0])%360+360)%360/360,d=i(c[1]),v=i(c[2]),m=v<=.5?v*(d+1):v+d-v*d,g=v*2-m;return[t(s(g,m,p+1/3)*255),t(s(g,m,p)*255),t(s(g,m,p-1/3)*255),h];default:return null}}return null}var e={rebeccapurple:[102,51,153],transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen -:[154,205,50,1]};return o}(),ColorManager=function(){function e(e,n,r,i){return e=t(e,0,255),n=t(n,0,255),r=t(r,0,255),i=t(i,0,255),"rgba("+Math.floor(e)+","+Math.floor(n)+","+Math.floor(r)+","+i+")"}function t(e,t,n){return Math.max(t,Math.min(e,n))}function n(e,t,n){return t*n+e*(1-n)}function r(e,t,r,i){var s=(t-r)*i,o=Math.floor(s),u=s-o,a=o+1;return a>e.length-1&&(a=o),{r:n(e[o][0],e[a][0],u),g:n(e[o][1],e[a][1],u),b:n(e[o][2],e[a][2],u),a:n(e[o][3],e[a][3],u)}}function i(e,t,n,r){var i=Math.floor((t-n)*r);return{r:e[i][0],g:e[i][1],b:e[i][2],a:e[i][3]}}function s(e,t){return e*=t,e>255?255:e}function o(e,t){return{r:s(e.r,t),g:s(e.g,t),b:s(e.b,t),a:e.a}}function u(e){return cssColorParser(e)}this.getColor=function(){console.error("ColorManager: colors have not been setup")},this.colors=[],this.setup=function(t,n,s,a,f){var l,c,h=n-t,p=t;a==="gradient"?(l=r,c=(s.length-1)/(h-1)):(l=i,c=s.length/(h+1)),this.colors=s.map(function(e){return u(e)}),this.getColor=function(t){var n=l(this.colors,t,p,c),r=o(n,f);return{color:e(n.r,n.g,n.b,n.a),highlight:e(r.r,r.g,r.b,r.a)}}}};(function(){"use strict";var e=this,t=e.Chart,n=t.helpers,r={backgroundColor:"#fff",stroke:!1,strokePerc:.05,strokeColor:"rgb(128,128,128)",highlightStrokeColor:"rgb(192,192,192)",rounded:!0,roundedRadius:.1,paddingScale:.05,colorInterpolation:"gradient",colors:["rgba(220,220,220,0.9)","rgba(151,187,205,0.9)"],colorHighlight:!0,colorHighlightMultiplier:.92,showLabels:!0,labelScale:.2,labelFontFamily:'"HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif',labelFontStyle:"normal",labelFontColor:"rgba(0,0,0,0.5)",tooltipTemplate:"<%= xLabel %> | <%= yLabel %> : <%= value %>",legendTemplate:'
<%= min %><% for (var i = min; i <= max; i += (max-min)/6){ %>  <% } %><%= max %>
'};t.Type.extend({name:"HeatMap",defaults:r,initialize:function(e){var r=this.options;this.max=-Infinity,this.min=Infinity,this.colorManager=new ColorManager,this.ScaleClass=t.Scale.extend({offsetGridLines:!0,calculateBaseWidth:function(){return this.calculateX(1)-this.calculateX(0)},calculateBoxWidth:function(e,t){var n=this.calculateBaseWidth()-e-1,r=Math.max(e,t);return this.calculateBaseWidth()},calculateBoxHeight:function(){return this.calculateY(0)-this.calculateY(1)},buildYLabels:function(){this.yLabelWidth=this.display&&this.showLabels?n.longestText(this.ctx,this.font,this.yLabels):0},draw:function(){var e=this.ctx,t=(this.endPoint-this.startPoint)/this.steps,r=Math.round(this.xScalePaddingLeft);this.display&&(e.fillStyle=this.textColor,e.font=this.font,n.each(this.yLabels,function(n,i){var s=this.endPoint-t*i-t*.5,o=Math.round(s),u=this.showHorizontalLines;e.textAlign="right",e.textBaseline="middle",this.showLabels&&e.fillText(n,r-10,s)},this),n.each(this.xLabels,function(t,r){var i=this.calculateX(r)+n.aliasPixel(this.lineWidth),s=this.calculateX(r-(this.offsetGridLines?.5:0))+n.aliasPixel(this.lineWidth),o=this.xLabelRotation>0,u=this.showVerticalLines;e.lineWidth=this.lineWidth,e.strokeStyle=this.lineColor,e.save(),e.translate(i,o?this.endPoint+12:this.endPoint+8),e.rotate(n.radians(this.xLabelRotation)*-1),e.font=this.font,e.textAlign=o?"right":"center",e.textBaseline=o?"middle":"top",e.fillText(t,0,0),e.restore()},this))}}),this.datasets=[],this.yLabels=[],this.xLabels=e.labels,this.options.showTooltips&&n.bindEvents(this,this.options.tooltipEvents,function(e){var t=e.type!=="mouseout"?this.getBoxAtEvent(e):undefined;this.activeElement=t,this.eachBoxes(function(e){e.restore(["fillColor","strokeColor"])}),t&&(t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke),this.showTooltip(t)}),this.BoxClass=t.Rectangle.extend({strokePerc:this.options.strokePerc,strokeColor:this.options.strokeColor,showStroke:this.options.stroke,fontColor:this.options.labelFontColor,fontFamily:this.options.labelFontFamily,fontScale:this.options.labelScale,showLabels:this.options.showLabels,radiusScale:this.options.rounded?this.options.roundedRadius:0,paddingScale:this.options.paddingScale,ctx:this.chart.ctx,draw:function(){var e=this.ctx,t=this.width/2,r=this.width,i=this.height,s=this.x-t,o=this.y,u=this.strokePerc*this.width,a=u/2,f=this.paddingScale*r,l=this.paddingScale*i;s+=f*.5,o+=l*.5,r-=f,i-=l,this.showStroke&&(s+=a,r-=a,i-=a,o+=a),e.fillStyle=this.fillColor,e.strokeStyle=this.strokeColor,e.lineWidth=u,n.drawRoundedRectangle(e,s,o,r,i,this.radiusScale*this.width),e.fill(),this.showStroke&&e.stroke(),this.showLabels&&this.label!==null&&this.label!==undefined&&(e.textAlign="center",e.textBaseline="middle",e.fillStyle=this.fontColor,e.font=this.height*this.fontScale+"px "+this.fontFamily,e.fillText(this.value,s+r*.5,o+i*.5))}}),n.each(e.datasets,function(e,t){var r={label:e.label||null,boxes:[]};this.datasets.push(r),this.yLabels.push(e.label),n.each(e.data,function(t,n){r.boxes.push(new this.BoxClass({value:t,label:this.xLabels[n],datasetLabel:e.label,strokeColor:this.options.strokeColor,fillColor:"white",highlightFill:"black",highlightStroke:this.options.highlightStrokeColor}))},this)},this),this.datasets.reverse(),this.yLabels.reverse(),this.buildScale(e.labels,this.yLabels),this.BoxClass.prototype.base=this.scale.endPoint,this.eachBoxes(function(e,t,r){n.extend(e,{x:this.scale.calculateX(t),y:this.scale.calculateY(r+1),width:this.scale.calculateBoxWidth(),height:this.scale.calculateBoxHeight()}),e.save()},this),this.findMaxAndMin(!0),this.applyColors(),this.render()},update:function(){this.scale.update(),this.activeElement&&this.activeElement.restore(["fillColor","strokeColor"]),this.eachBoxes(function(e){e.save()}),this.render()},eachBoxes:function(e){n.each(this.datasets,function(t,r){n.each(t.boxes,e,this,r)},this)},getBoxAtEvent:function(e){var t=n.getRelativePosition(e),r;for(var i=0;ithis.max&&(this.max=e.value),e.value",scaleIntegersOnly:!0,scaleBeginAtZero:!1,scaleFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",responsive:!1,maintainAspectRatio:!0,showTooltips:!0,customTooltips:!1,tooltipEvents:["mousemove","touchstart","touchmove","mouseout"],tooltipFillColor:"rgba(0,0,0,0.8)",tooltipFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",tooltipFontSize:14,tooltipFontStyle:"normal",tooltipFontColor:"#fff",tooltipTitleFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",tooltipTitleFontSize:14,tooltipTitleFontStyle:"bold",tooltipTitleFontColor:"#fff",tooltipTitleTemplate:"<%= label%>",tooltipYPadding:6,tooltipXPadding:6,tooltipCaretSize:8,tooltipCornerRadius:6,tooltipXOffset:10,tooltipTemplate:"<%if (label){%><%=label%>: <%}%><%= value %>",multiTooltipTemplate:"<%= datasetLabel %>: <%= value %>",multiTooltipKeyBackground:"#fff",segmentColorDefault:["#A6CEE3","#1F78B4","#B2DF8A","#33A02C","#FB9A99","#E31A1C","#FDBF6F","#FF7F00","#CAB2D6","#6A3D9A","#B4B482","#B15928"],segmentHighlightColorDefaults:["#CEF6FF","#47A0DC","#DAFFB2","#5BC854","#FFC2C1","#FF4244","#FFE797","#FFA728","#F2DAFE","#9265C2","#DCDCAA","#D98150"],onAnimationProgress:function(){},onAnimationComplete:function(){}}},n.types={};var r=n.helpers={},i=r.each=function(e,t,n){var r=Array.prototype.slice.call(arguments,3);if(e)if(e.length===+e.length){var i;for(i=0;i=0;r--){var i=e[r];if(t(i))return i}},h=r.inherits=function(e){var t=this,n=e&&e.hasOwnProperty("constructor")?e.constructor:function(){return t.apply(this,arguments)},r=function(){this.constructor=n};return r.prototype=t.prototype,n.prototype=new r,n.extend=h,e&&o(n.prototype,e),n.__super__=t.prototype,n},p=r.noop=function(){},d=r.uid=function(){var e=0;return function(){return"chart-"+e++}}(),v=r.warn=function(e){window.console&&typeof window.console.warn=="function"&&console.warn(e)},m=r.amd=typeof define=="function"&&define.amd,g=r.isNumber=function(e){return!isNaN(parseFloat(e))&&isFinite(e)},y=r.max=function(e){return Math.max.apply(Math,e)},b=r.min=function(e){return Math.min.apply(Math,e)},w=r.cap=function(e,t,n){if(g(t)){if(e>t)return t}else if(g(n)&&e=u,f=[];i(e,function(e){e==null||f.push(e)});var l=b(f),c=y(f);c===l&&(c+=.5,l>=.5&&!r?l-=.5:c+=.5);var h=Math.abs(c-l),p=C(h),d=Math.ceil(c/(1*Math.pow(10,p)))*Math.pow(10,p),v=r?0:Math.floor(l/(1*Math.pow(10,p)))*Math.pow(10,p),m=d-v,g=Math.pow(10,p),w=Math.round(m/g);while((w>u||w*2u)g*=2,w=Math.round(m/g),w%1!==0&&(a=!0);else if(s&&p>=0){if(g/2%1!==0)break;g/=2,w=Math.round(m/g)}else g/=2,w=Math.round(m/g);return a&&(w=o,g=m/w),{steps:w,stepValue:g,min:v,max:v+w*g}},L=r.template=function(e,t){function r(e,t){var r=/\W/.test(e)?new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+e.replace(/[\r\t\n]/g," ").split("<%").join(" ").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split(" ").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');"):n[e]=n[e];return t?r(t):r}if(e instanceof Function)return e(t);var n={};return r(e,t)},A=r.generateLabels=function(e,t,n,r){var s=new Array(t);return e&&i(s,function(t,i){s[i]=L(e,{value:n+r*(i+1)})}),s},O=r.easingEffects={linear:function(e){return e},easeInQuad:function(e){return e*e},easeOutQuad:function(e){return-1*e*(e-2)},easeInOutQuad:function(e){return(e/=.5)<1?.5*e*e:-0.5*(--e*(e-2)-1)},easeInCubic:function(e){return e*e*e},easeOutCubic:function(e){return 1*((e=e/1-1)*e*e+1)},easeInOutCubic:function(e){return(e/=.5)<1?.5*e*e*e:.5*((e-=2)*e*e+2)},easeInQuart:function(e){return e*e*e*e},easeOutQuart:function(e){return-1*((e=e/1-1)*e*e*e-1)},easeInOutQuart:function(e){return(e/=.5)<1?.5*e*e*e*e:-0.5*((e-=2)*e*e*e-2)},easeInQuint:function(e){return 1*(e/=1)*e*e*e*e},easeOutQuint:function(e){return 1*((e=e/1-1)*e*e*e*e+1)},easeInOutQuint:function(e){return(e/=.5)<1?.5*e*e*e*e*e:.5*((e-=2)*e*e*e*e+2)},easeInSine:function(e){return-1*Math.cos(e/1*(Math.PI/2))+1},easeOutSine:function(e){return 1*Math.sin(e/1*(Math.PI/2))},easeInOutSine:function(e){return-0.5*(Math.cos(Math.PI*e/1)-1)},easeInExpo:function(e){return e===0?1:1*Math.pow(2,10*(e/1-1))},easeOutExpo:function(e){return e===1?1:1*(-Math.pow(2,-10*e/1)+1)},easeInOutExpo:function(e){return e===0?0:e===1?1:(e/=.5)<1?.5*Math.pow(2,10*(e-1)):.5*(-Math.pow(2,-10*--e)+2)},easeInCirc:function(e){return e>=1?e:-1*(Math.sqrt(1-(e/=1)*e)-1)},easeOutCirc:function(e){return 1*Math.sqrt(1-(e=e/1-1)*e)},easeInOutCirc:function(e){return(e/=.5)<1?-0.5*(Math.sqrt(1-e*e)-1):.5*(Math.sqrt(1-(e-=2)*e)+1)},easeInElastic:function(e){var t=1.70158,n=0,r=1;return e===0?0:(e/=1)==1?1:(n||(n=.3),rr?n:r}),r},$=r.drawRoundedRectangle=function(e,t,n,r,i,s){e.beginPath(),e.moveTo(t+s,n),e.lineTo(t+r-s,n),e.quadraticCurveTo(t+r,n,t+r,n+s),e.lineTo(t+r,n+i-s),e.quadraticCurveTo(t+r,n+i,t+r-s,n+i),e.lineTo(t+s,n+i),e.quadraticCurveTo(t,n+i,t,n+i-s),e.lineTo(t,n+s),e.quadraticCurveTo(t,n,t+s,n),e.closePath()};n.instances={},n.Type=function(e,t,r){this.options=t,this.chart=r,this.id=d(),n.instances[this.id]=this,t.responsive&&this.resize(),this.initialize.call(this,e)},o(n.Type.prototype,{initialize:function(){return this},clear:function(){return W(this.chart),this},stop:function(){return n.animationService.cancelAnimation(this),this},resize:function(e){this.stop();var t=this.chart.canvas,n=I(this.chart.canvas),r=this.options.maintainAspectRatio?n/this.chart.aspectRatio:q(this.chart.canvas);return t.width=this.chart.width=n,t.height=this.chart.height=r,z(this.chart),typeof e=="function"&&e.apply(this,Array.prototype.slice.call(arguments,1)),this},reflow:p,render:function(e){e&&this.reflow();if(this.options.animation&&!e){var t=new n.Animation;t.numSteps=this.options.animationSteps,t.easing=this.options.animationEasing,t.render=function(e,t){var n=r.easingEffects[t.easing],i=t.currentStep/t.numSteps,s=n(i);e.draw(s,i,t.currentStep)},t.onAnimationProgress=this.options.onAnimationProgress,t.onAnimationComplete=this.options.onAnimationComplete,n.animationService.addAnimation(this,t)}else this.draw(),this.options.onAnimationComplete.call(this);return this},generateLegend:function(){return r.template(this.options.legendTemplate,this)},destroy:function(){this.stop(),this.clear(),F(this,this.events);var e=this.chart.canvas;e.width=this.chart.width,e.height=this.chart.height,e.style.removeProperty?(e.style.removeProperty("width"),e.style.removeProperty("height")):(e.style.removeAttribute("width"),e.style.removeAttribute("height")),delete n.instances[this.id]},showTooltip:function(e,t){typeof this.activeElements=="undefined"&&(this.activeElements=[]);var s=function(e){var t=!1;return e.length!==this.activeElements.length?(t=!0,t):(i(e,function(e,n){e!==this.activeElements[n]&&(t=!0)},this),t)}.call(this,e);if(!s&&!t)return;this.activeElements=e,this.draw(),this.options.customTooltips&&this.options.customTooltips(!1);if(e.length>0)if(this.datasets&&this.datasets.length>1){var o,u;for(var f=this.datasets.length-1;f>=0;f--){o=this.datasets[f].points||this.datasets[f].bars||this.datasets[f].segments,u=a(o,e[0]);if(u!==-1)break}var l=[],c=[],h=function(e){var t=[],n,i=[],s=[],o,a,f,h;return r.each(this.datasets,function(e){n=e.points||e.bars||e.segments,n[u]&&n[u].hasValue()&&t.push(n[u])}),r.each(t,function(e){i.push(e.x),s.push(e.y),l.push(r.template(this.options.multiTooltipTemplate,e)),c.push({fill:e._saved.fillColor||e.fillColor,stroke:e._saved.strokeColor||e.strokeColor})},this),h=b(s),a=y(s),f=b(i),o=y(i),{x:f>this.chart.width/2?f:o,y:(h+a)/2}}.call(this,u);(new n.MultiTooltip({x:h.x,y:h.y,xPadding:this.options.tooltipXPadding,yPadding:this.options.tooltipYPadding,xOffset:this.options.tooltipXOffset,fillColor:this.options.tooltipFillColor,textColor:this.options.tooltipFontColor,fontFamily:this.options.tooltipFontFamily,fontStyle:this.options.tooltipFontStyle,fontSize:this.options.tooltipFontSize,titleTextColor:this.options.tooltipTitleFontColor,titleFontFamily:this.options.tooltipTitleFontFamily,titleFontStyle:this.options.tooltipTitleFontStyle,titleFontSize:this.options.tooltipTitleFontSize,cornerRadius:this.options.tooltipCornerRadius,labels:l,legendColors:c,legendColorBackground:this.options.multiTooltipKeyBackground,title:L(this.options.tooltipTitleTemplate,e[0]),chart:this.chart,ctx:this.chart.ctx,custom:this.options.customTooltips})).draw()}else i(e,function(e){var t=e.tooltipPosition();(new n.Tooltip({x:Math.round(t.x),y:Math.round(t.y),xPadding:this.options.tooltipXPadding,yPadding:this.options.tooltipYPadding,fillColor:this.options.tooltipFillColor,textColor:this.options.tooltipFontColor,fontFamily:this.options.tooltipFontFamily,fontStyle:this.options.tooltipFontStyle,fontSize:this.options.tooltipFontSize,caretHeight:this.options.tooltipCaretSize,cornerRadius:this.options.tooltipCornerRadius,text:L(this.options.tooltipTemplate,e),chart:this.chart,custom:this.options.customTooltips})).draw()},this);return this},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)}}),n.Type.extend=function(e){var t=this,r=function(){return t.apply(this,arguments)};r.prototype=s(t.prototype),o(r.prototype,e),r.extend=n.Type.extend;if(e.name||t.prototype.name){var i=e.name||t.prototype.name,a=n.defaults[t.prototype.name]?s(n.defaults[t.prototype.name]):{};n.defaults[i]=o(a,e.defaults),n.types[i]=r,n.prototype[i]=function(e,t){var s=u(n.defaults.global,n.defaults[i],t||{});return new r(e,s,this)}}else v("Name not provided for this chart, so it hasn't been registered");return t},n.Element=function(e){o(this,e),this.initialize.apply(this,arguments),this.save()},o(n.Element.prototype,{initialize:function(){},restore:function(e){return e?i(e,function(e){this[e]=this._saved[e]},this):o(this,this._saved),this},save:function(){return this._saved=s(this),delete this._saved._saved,this},update:function(e){return i(e,function(e,t){this._saved[t]=this[t],this[t]=e},this),this},transition:function(e,t){return i(e,function(e,n){this[n]=(e-this._saved[n])*t+this._saved[n]},this),this},tooltipPosition:function(){return{x:this.x,y:this.y}},hasValue:function(){return g(this.value)}}),n.Element.extend=h,n.Point=n.Element.extend({display:!0,inRange:function(e,t){var n=this.hitDetectionRadius+this.radius;return Math.pow(e-this.x,2)+Math.pow(t-this.y,2)=s:i>=s&&i<=o,a=n.distance>=this.innerRadius&&n.distance<=this.outerRadius;return u&&a},tooltipPosition:function(){var e=this.startAngle+(this.endAngle-this.startAngle)/2,t=(this.outerRadius-this.innerRadius)/2+this.innerRadius;return{x:this.x+Math.cos(e)*t,y:this.y+Math.sin(e)*t}},draw:function(e){var t=e||1,n=this.ctx;n.beginPath(),n.arc(this.x,this.y,this.outerRadius<0?0:this.outerRadius,this.startAngle,this.endAngle),n.arc(this.x,this.y,this.innerRadius<0?0:this.innerRadius,this.endAngle,this.startAngle,!0),n.closePath(),n.strokeStyle=this.strokeColor,n.lineWidth=this.strokeWidth,n.fillStyle=this.fillColor,n.fill(),n.lineJoin="bevel",this.showStroke&&n.stroke()}}),n.Rectangle=n.Element.extend({draw:function(){var e=this.ctx,t=this.width/2,n=this.x-t,r=this.x+t,i=this.base-(this.base-this.y),s=this.strokeWidth/2;this.showStroke&&(n+=s,r-=s,i+=s),e.beginPath(),e.fillStyle=this.fillColor,e.strokeStyle=this.strokeColor,e.lineWidth=this.strokeWidth,e.moveTo(n,this.base),e.lineTo(n,i),e.lineTo(r,i),e.lineTo(r,this.base),e.fill(),this.showStroke&&e.stroke()},height:function(){return this.base-this.y},inRange:function(e,t){return e>=this.x-this.width/2&&e<=this.x+this.width/2&&t>=this.y&&t<=this.base}}),n.Animation=n.Element.extend({currentStep:null,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),n.Tooltip=n.Element.extend({draw:function(){var e=this.chart.ctx;e.font=X(this.fontSize,this.fontStyle,this.fontFamily),this.xAlign="center",this.yAlign="above";var t=this.caretPadding=2,n=e.measureText(this.text).width+2*this.xPadding,r=this.fontSize+2*this.yPadding,i=r+this.caretHeight+t;this.x+n/2>this.chart.width?this.xAlign="left":this.x-n/2<0&&(this.xAlign="right"),this.y-i<0&&(this.yAlign="below");var s=this.x-n/2,o=this.y-i;e.fillStyle=this.fillColor;if(this.custom)this.custom(this);else{switch(this.yAlign){case"above":e.beginPath(),e.moveTo(this.x,this.y-t),e.lineTo(this.x+this.caretHeight,this.y-(t+this.caretHeight)),e.lineTo(this.x-this.caretHeight,this.y-(t+this.caretHeight)),e.closePath(),e.fill();break;case"below":o=this.y+t+this.caretHeight,e.beginPath(),e.moveTo(this.x,this.y+t),e.lineTo(this.x+this.caretHeight,this.y+t+this.caretHeight),e.lineTo(this.x-this.caretHeight,this.y+t+this.caretHeight),e.closePath(),e.fill()}switch(this.xAlign){case"left":s=this.x-n+(this.cornerRadius+this.caretHeight);break;case"right":s=this.x-(this.cornerRadius+this.caretHeight)}$(e,s,o,n,r,this.cornerRadius),e.fill(),e.fillStyle=this.textColor,e.textAlign="center",e.textBaseline="middle",e.fillText(this.text,s+n/2,o+r/2)}}}),n.MultiTooltip=n.Element.extend({initialize:function(){this.font=X(this.fontSize,this.fontStyle,this.fontFamily),this.titleFont=X(this.titleFontSize,this.titleFontStyle,this.titleFontFamily),this.titleHeight=this.title?this.titleFontSize*1.5:0,this.height=this.labels.length*this.fontSize+(this.labels.length-1)*(this.fontSize/2)+this.yPadding*2+this.titleHeight,this.ctx.font=this.titleFont;var e=this.ctx.measureText(this.title).width,t=V(this.ctx,this.font,this.labels)+this.fontSize+3,n=y([t,e]);this.width=n+this.xPadding*2;var r=this.height/2;this.y-r<0?this.y=r:this.y+r>this.chart.height&&(this.y=this.chart.height-r),this.x>this.chart.width/2?this.x-=this.xOffset+this.width:this.x+=this.xOffset},getLineHeight:function(e){var t=this.y-this.height/2+this.yPadding,n=e-1;return e===0?t+this.titleHeight/3:t+(this.fontSize*1.5*n+this.fontSize/2)+this.titleHeight},draw:function(){if(this.custom)this.custom(this);else{$(this.ctx,this.x,this.y-this.height/2,this.width,this.height,this.cornerRadius);var e=this.ctx;e.fillStyle=this.fillColor,e.fill(),e.closePath(),e.textAlign="left",e.textBaseline="middle",e.fillStyle=this.titleTextColor,e.font=this.titleFont,e.fillText(this.title,this.x+this.xPadding,this.getLineHeight(0)),e.font=this.font,r.each(this.labels,function(t,n){e.fillStyle=this.textColor,e.fillText(t,this.x+this.xPadding+this.fontSize+3,this.getLineHeight(n+1)),e.fillStyle=this.legendColorBackground,e.fillRect(this.x+this.xPadding,this.getLineHeight(n+1)-this.fontSize/2,this.fontSize,this.fontSize),e.fillStyle=this.legendColors[n].fill,e.fillRect(this.x+this.xPadding,this.getLineHeight(n+1)-this.fontSize/2,this.fontSize,this.fontSize)},this)}}}),n.Scale=n.Element.extend({initialize:function(){this.fit()},buildYLabels:function(){this.yLabels=[];var e=E(this.stepValue);for(var t=0;t<=this.steps;t++)this.yLabels.push(L(this.templateString,{value:(this.min+t*this.stepValue).toFixed(e)}));this.yLabelWidth=this.display&&this.showLabels?V(this.ctx,this.font,this.yLabels)+10:0},addXLabel:function(e){this.xLabels.push(e),this.valuesCount++,this.fit()},removeXLabel:function(){this.xLabels.shift(),this.valuesCount--,this.fit()},fit:function(){this.startPoint=this.display?this.fontSize:0,this.endPoint=this.display?this.height-this.fontSize*1.5-5:this.height,this.startPoint+=this.padding,this.endPoint-=this.padding;var e=this.endPoint,t=this.endPoint-this.startPoint,n;this.calculateYRange(t),this.buildYLabels(),this.calculateXLabelRotation();while(t>this.endPoint-this.startPoint)t=this.endPoint-this.startPoint,n=this.yLabelWidth,this.calculateYRange(t),this.buildYLabels(),nthis.yLabelWidth?e/2:this.yLabelWidth,this.xLabelRotation=0;if(this.display){var i=V(this.ctx,this.font,this.xLabels),s,o;this.xLabelWidth=i;var u=Math.floor(this.calculateX(1)-this.calculateX(0))-6;while(this.xLabelWidth>u&&this.xLabelRotation===0||this.xLabelWidth>u&&this.xLabelRotation<=90&&this.xLabelRotation>0)s=Math.cos(S(this.xLabelRotation)),n=s*e,r=s*t,n+this.fontSize/2>this.yLabelWidth&&(this.xScalePaddingLeft=n+this.fontSize/2),this.xScalePaddingRight=this.fontSize/2,this.xLabelRotation++,this.xLabelWidth=s*i;this.xLabelRotation>0&&(this.endPoint-=Math.sin(S(this.xLabelRotation))*i+3)}else this.xLabelWidth=0,this.xScalePaddingRight=this.padding,this.xScalePaddingLeft=this.padding},calculateYRange:p,drawingArea:function(){return this.startPoint-this.endPoint},calculateY:function(e){var t=this.drawingArea()/(this.min-this.max);return this.endPoint-t*(e-this.min)},calculateX:function(e){var t=this.xLabelRotation>0,n=this.width-(this.xScalePaddingLeft+this.xScalePaddingRight),r=n/Math.max(this.valuesCount-(this.offsetGridLines?0:1),1),i=r*e+this.xScalePaddingLeft;return this.offsetGridLines&&(i+=r/2),Math.round(i)},update:function(e){r.extend(this,e),this.fit()},draw:function(){var e=this.ctx,t=(this.endPoint-this.startPoint)/this.steps,n=Math.round(this.xScalePaddingLeft);this.display&&(e.fillStyle=this.textColor,e.font=this.font,i(this.yLabels,function(i,s){var o=this.endPoint-t*s,u=Math.round(o),a=this.showHorizontalLines;e.textAlign="right",e.textBaseline="middle",this.showLabels&&e.fillText(i,n-10,o),s===0&&!a&&(a=!0),a&&e.beginPath(),s>0?(e.lineWidth=this.gridLineWidth,e.strokeStyle=this.gridLineColor):(e.lineWidth=this.lineWidth,e.strokeStyle=this.lineColor),u+=r.aliasPixel(e.lineWidth),a&&(e.moveTo(n,u),e.lineTo(this.width,u),e.stroke(),e.closePath()),e.lineWidth=this.lineWidth,e.strokeStyle=this.lineColor,e.beginPath(),e.moveTo(n-5,u),e.lineTo(n,u),e.stroke(),e.closePath()},this),i(this.xLabels,function(t,n){var r=this.calculateX(n)+T(this.lineWidth),i=this.calculateX(n-(this.offsetGridLines?.5:0))+T(this.lineWidth),s=this.xLabelRotation>0,o=this.showVerticalLines;n===0&&!o&&(o=!0),o&&e.beginPath(),n>0?(e.lineWidth=this.gridLineWidth,e.strokeStyle=this.gridLineColor):(e.lineWidth=this.lineWidth,e.strokeStyle=this.lineColor),o&&(e.moveTo(i,this.endPoint),e.lineTo(i,this.startPoint-3),e.stroke(),e.closePath()),e.lineWidth=this.lineWidth,e.strokeStyle=this.lineColor,e.beginPath(),e.moveTo(i,this.endPoint),e.lineTo(i,this.endPoint+5),e.stroke(),e.closePath(),e.save(),e.translate(r,s?this.endPoint+12:this.endPoint+8),e.rotate(S(this.xLabelRotation)*-1),e.font=this.font,e.textAlign=s?"right":"center",e.textBaseline=s?"middle":"top",e.fillText(t,0,0),e.restore()},this))}}),n.RadialScale=n.Element.extend({initialize:function(){this.size=b([this.height,this.width]),this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2},calculateCenterOffset:function(e){var t=this.drawingArea/(this.max-this.min);return(e-this.min)*t},update:function(){this.lineArc?this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2:this.setScaleSize(),this.buildYLabels()},buildYLabels:function(){this.yLabels=[];var e=E(this.stepValue);for(var t=0;t<=this.steps;t++)this.yLabels.push(L(this.templateString,{value:(this.min+t*this.stepValue).toFixed(e)}))},getCircumference:function(){return Math.PI*2/this.valuesCount},setScaleSize:function(){var e=b([this.height/2-this.pointLabelFontSize-5,this.width/2]),t,n,r,i,s=this.width,o,u,a=0,f,l,c,h,p,d,v;this.ctx.font=X(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);for(n=0;ns&&(s=t.x+i,o=n),t.x-is&&(s=t.x+r,o=n):n>this.valuesCount/2&&t.x-r0){var r=n*(this.drawingArea/this.steps),i=this.yCenter-r,s;if(this.lineWidth>0){e.strokeStyle=this.lineColor,e.lineWidth=this.lineWidth;if(this.lineArc)e.beginPath(),e.arc(this.xCenter,this.yCenter,r,0,Math.PI*2),e.closePath(),e.stroke();else{e.beginPath();for(var o=0;o=0;t--){var n=null,r=null;this.angleLineWidth>0&&t%this.angleLineInterval===0&&(n=this.calculateCenterOffset(this.max),r=this.getPointPosition(t,n),e.beginPath(),e.moveTo(this.xCenter,this.yCenter),e.lineTo(r.x,r.y),e.stroke(),e.closePath());if(this.backgroundColors&&this.backgroundColors.length==this.valuesCount){n==null&&(n=this.calculateCenterOffset(this.max)),r==null&&(r=this.getPointPosition(t,n));var s=this.getPointPosition(t===0?this.valuesCount-1:t-1,n),o=this.getPointPosition(t===this.valuesCount-1?0:t+1,n),u={x:(s.x+r.x)/2,y:(s.y+r.y)/2},a={x:(r.x+o.x)/2,y:(r.y+o.y)/2};e.beginPath(),e.moveTo(this.xCenter,this.yCenter),e.lineTo(u.x,u.y),e.lineTo(r.x,r.y),e.lineTo(a.x,a.y),e.fillStyle=this.backgroundColors[t],e.fill(),e.closePath()}var f=this.getPointPosition(t,this.calculateCenterOffset(this.max)+5);e.font=X(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily),e.fillStyle=this.pointLabelFontColor;var l=this.labels.length,c=this.labels.length/2,h=c/2,p=tl-h,d=t===h||t===l-h;t===0?e.textAlign="center":t===c?e.textAlign="center":t1&&(t=Math.floor(this.dropFrames),this.dropFrames-=t);for(var n=0;nthis.animations[n].animationObject.numSteps&&(this.animations[n].animationObject.currentStep=this.animations[n].animationObject.numSteps),this.animations[n].animationObject.render(this.animations[n].chartInstance,this.animations[n].animationObject),this.animations[n].animationObject.currentStep==this.animations[n].animationObject.numSteps&&(this.animations[n].animationObject.onAnimationComplete.call(this.animations[n].chartInstance),this.animations.splice(n,1),n--);var i=Date.now(),s=i-e-this.frameDuration,o=s/this.frameDuration;o>1&&(this.dropFrames+=o),this.animations.length>0&&r.requestAnimFrame.call(window,this.digestWrapper)}},r.addEvent(window,"resize",function(){var e;return function(){clearTimeout(e),e=setTimeout(function(){i(n.instances,function(e){e.options.responsive&&e.resize(e.render,!0)})},50)}}()),m?define("Chart",[],function(){return n}):typeof module=="object"&&module.exports&&(module.exports=n),e.Chart=n,n.noConflict=function(){return e.Chart=t,n}}).call(this);var cssColorParser=function(){function t(e){return e=Math.round(e),e<0?0:e>255?255:e}function n(e){return e<0?0:e>1?1:e}function r(e){return e[e.length-1]==="%"?t(parseFloat(e)/100*255):t(parseInt(e))}function i(e){return e[e.length-1]==="%"?n(parseFloat(e)/100):n(parseFloat(e))}function s(e,t,n){return n<0?n+=1:n>1&&(n-=1),n*6<1?e+(t-e)*n*6:n*2<1?t:n*3<2?e+(t-e)*(2/3-n)*6:e}function o(n){var o=n.replace(/ /g,"").toLowerCase();if(o in e)return e[o].slice();if(o[0]==="#"){if(o.length===4){var u=parseInt(o.substr(1),16);return u>=0&&u<=4095?[(u&3840)>>4|(u&3840)>>8,u&240|(u&240)>>4,u&15|(u&15)<<4,1]:null}if(o.length===7){var u=parseInt(o.substr(1),16);return u>=0&&u<=16777215?[(u&16711680)>>16,(u&65280)>>8,u&255,1]:null}return null}var a=o.indexOf("("),f=o.indexOf(")");if(a!==-1&&f+1===o.length){var l=o.substr(0,a),c=o.substr(a+1,f-(a+1)).split(","),h=1;switch(l){case"rgba":if(c.length!==4)return null;h=i(c.pop());case"rgb":if(c.length!==3)return null;return[r(c[0]),r(c[1]),r(c[2]),h];case"hsla":if(c.length!==4)return null;h=i(c.pop());case"hsl":if(c.length!==3)return null;var p=(parseFloat(c[0])%360+360)%360/360,d=i(c[1]),v=i(c[2]),m=v<=.5?v*(d+1):v+d-v*d,g=v*2-m;return[t(s(g,m,p+1/3)*255),t(s(g,m,p)*255),t(s(g,m,p-1/3)*255),h];default:return null}}return null}var e={rebeccapurple:[102,51,153],transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245 +,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]};return o}(),ColorManager=function(){function e(e,n,r,i){return e=t(e,0,255),n=t(n,0,255),r=t(r,0,255),i=t(i,0,255),"rgba("+Math.floor(e)+","+Math.floor(n)+","+Math.floor(r)+","+i+")"}function t(e,t,n){return Math.max(t,Math.min(e,n))}function n(e,t,n){return t*n+e*(1-n)}function r(e,t,r,i,s,o){var u=e,a=s;t&&r<0&&(r=Math.abs(r),u=t,o===!1?(i=Math.abs(i),a=Math.abs(s)):a=Math.abs(o));var f=(r-i)*a,l=Math.floor(f);l>u.length-1&&(l=u.length-1),l<0&&(l=0);var c=f-l,h=l+1;return h>u.length-1&&(h=l),{r:n(u[l][0],u[h][0],c),g:n(u[l][1],u[h][1],c),b:n(u[l][2],u[h][2],c),a:n(u[l][3],u[h][3],c)}}function i(e,t,n,r,i,s){var o=Math.floor((n-r)*i);return t&&o<0?(o=o*-1-1,o>=t.length&&(o=t.length-1),{r:t[o][0],g:t[o][1],b:t[o][2],a:t[o][3]}):{r:e[o][0],g:e[o][1],b:e[o][2],a:e[o][3]}}function s(e,t){return e*=t,e>255?255:e}function o(e,t){return{r:s(e.r,t),g:s(e.g,t),b:s(e.b,t),a:e.a}}function u(e){return cssColorParser(e)}this.getColor=function(){console.error("ColorManager: colors have not been setup")},this.colors=[],this.negativeColors=[],this.setup=function(t,n,s,a,f,l){var c,h,p=t,d=n-t,v=!1,m=!1;a&&(n<0?(n+=1e-6,p=n):n>0&&t<0&&(d=n,m=t,p=0)),f==="gradient"?(c=r,h=s.length/(d!==0?d:1)):(c=i,h=s.length/(d+1)),a&&n>0&&t<0&&(f==="gradient"?v=(a.length-1)/(m-1):v=a.length/(m+1)),this.colors=s.map(function(e){return u(e)}),this.negativeColors=a.map(function(e){return u(e)}),this.getColor=function(t){var n=c(this.colors,this.negativeColors,t,p,h,v),r=o(n,l);return{color:e(n.r,n.g,n.b,n.a),highlight:e(r.r,r.g,r.b,r.a)}}}};(function(){"use strict";var e=this,t=e.Chart,n=t.helpers,r={backgroundColor:"#fff",stroke:!1,strokePerc:.05,strokeColor:"rgb(128,128,128)",highlightStrokeColor:"rgb(192,192,192)",rounded:!0,roundedRadius:.1,paddingScale:.05,colorInterpolation:"gradient",colors:["rgba(220,220,220,0.9)","rgba(151,187,205,0.9)"],colorHighlight:!0,colorHighlightMultiplier:.92,showLabels:!0,labelScale:.2,labelFontFamily:'"HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif',labelFontStyle:"normal",labelFontColor:"rgba(0,0,0,0.5)",tooltipTemplate:"<%= xLabel %> | <%= yLabel %> : <%= value %>",legendTemplate:'
<%= min %><% for (var i = min; i <= max; i += (max-min)/6){ %>  <% } %><%= max %>
'};t.Type.extend({name:"HeatMap",defaults:r,initialize:function(e){var r=this.options;this.max=-Infinity,this.min=Infinity,this.colorManager=new ColorManager,this.ScaleClass=t.Scale.extend({offsetGridLines:!0,calculateBaseWidth:function(){return this.calculateX(1)-this.calculateX(0)},calculateBoxWidth:function(e,t){var n=this.calculateBaseWidth()-e-1,r=Math.max(e,t);return this.calculateBaseWidth()},calculateBoxHeight:function(){return this.calculateY(0)-this.calculateY(1)},buildYLabels:function(){this.yLabelWidth=this.display&&this.showLabels?n.longestText(this.ctx,this.font,this.yLabels):0},draw:function(){var e=this.ctx,t=(this.endPoint-this.startPoint)/this.steps,r=Math.round(this.xScalePaddingLeft);this.display&&(e.fillStyle=this.textColor,e.font=this.font,n.each(this.yLabels,function(n,i){var s=this.endPoint-t*i-t*.5,o=Math.round(s),u=this.showHorizontalLines;e.textAlign="right",e.textBaseline="middle",this.showLabels&&e.fillText(n,r-10,s)},this),n.each(this.xLabels,function(t,r){var i=this.calculateX(r)+n.aliasPixel(this.lineWidth),s=this.calculateX(r-(this.offsetGridLines?.5:0))+n.aliasPixel(this.lineWidth),o=this.xLabelRotation>0,u=this.showVerticalLines;e.lineWidth=this.lineWidth,e.strokeStyle=this.lineColor,e.save(),e.translate(i,o?this.endPoint+12:this.endPoint+8),e.rotate(n.radians(this.xLabelRotation)*-1),e.font=this.font,e.textAlign=o?"right":"center",e.textBaseline=o?"middle":"top",e.fillText(t,0,0),e.restore()},this))}}),this.datasets=[],this.yLabels=[],this.xLabels=e.labels,this.options.showTooltips&&n.bindEvents(this,this.options.tooltipEvents,function(e){var t=e.type!=="mouseout"?this.getBoxAtEvent(e):undefined;this.activeElement=t,this.eachBoxes(function(e){e.restore(["fillColor","strokeColor"])}),t&&(t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke),this.showTooltip(t)}),this.BoxClass=t.Rectangle.extend({strokePerc:this.options.strokePerc,strokeColor:this.options.strokeColor,showStroke:this.options.stroke,fontColor:this.options.labelFontColor,fontFamily:this.options.labelFontFamily,fontScale:this.options.labelScale,showLabels:this.options.showLabels,radiusScale:this.options.rounded?this.options.roundedRadius:0,paddingScale:this.options.paddingScale,ctx:this.chart.ctx,draw:function(){var e=this.ctx,t=this.width/2,r=this.width,i=this.height,s=this.x-t,o=this.y,u=this.strokePerc*this.width,a=u/2,f=this.paddingScale*r,l=this.paddingScale*i;s+=f*.5,o+=l*.5,r-=f,i-=l,this.showStroke&&(s+=a,r-=a,i-=a,o+=a),e.fillStyle=this.fillColor,e.strokeStyle=this.strokeColor,e.lineWidth=u,n.drawRoundedRectangle(e,s,o,r,i,this.radiusScale*this.width),e.fill(),this.showStroke&&e.stroke(),this.showLabels&&this.label!==null&&this.label!==undefined&&(e.textAlign="center",e.textBaseline="middle",e.fillStyle=this.fontColor,e.font=this.height*this.fontScale+"px "+this.fontFamily,e.fillText(this.value,s+r*.5,o+i*.5))}}),n.each(e.datasets,function(e,t){var r={label:e.label||null,boxes:[]};this.datasets.push(r),this.yLabels.push(e.label),n.each(e.data,function(t,n){r.boxes.push(new this.BoxClass({value:t,label:this.xLabels[n],datasetLabel:e.label,strokeColor:this.options.strokeColor,fillColor:"white",highlightFill:"black",highlightStroke:this.options.highlightStrokeColor}))},this)},this),this.datasets.reverse(),this.yLabels.reverse(),this.buildScale(e.labels,this.yLabels),this.BoxClass.prototype.base=this.scale.endPoint,this.eachBoxes(function(e,t,r){n.extend(e,{x:this.scale.calculateX(t),y:this.scale.calculateY(r+1),width:this.scale.calculateBoxWidth(),height:this.scale.calculateBoxHeight()}),e.save()},this),this.findMaxAndMin(!0),this.applyColors(),this.render()},update:function(){this.scale.update(),this.activeElement&&this.activeElement.restore(["fillColor","strokeColor"]),this.eachBoxes(function(e){e.save()}),this.render()},eachBoxes:function(e){n.each(this.datasets,function(t,r){n.each(t.boxes,e,this,r)},this)},getBoxAtEvent:function(e){var t=n.getRelativePosition(e),r;for(var i=0;ithis.max&&(this.max=e.value),e.value useColors.length - 1){ iIndex = useColors.length - 1; } + if (iIndex < 0) { iIndex = 0 }; + var iv = fIndex - iIndex; var iIndex1 = iIndex+1; - if (iIndex1 > colors.length - 1){ iIndex1 = iIndex; } + if (iIndex1 > useColors.length - 1){ iIndex1 = iIndex; } return { - r: interp(colors[iIndex][0], colors[iIndex1][0], iv), - g: interp(colors[iIndex][1], colors[iIndex1][1], iv), - b: interp(colors[iIndex][2], colors[iIndex1][2], iv), - a: interp(colors[iIndex][3], colors[iIndex1][3], iv) + r: interp(useColors[iIndex][0], useColors[iIndex1][0], iv), + g: interp(useColors[iIndex][1], useColors[iIndex1][1], iv), + b: interp(useColors[iIndex][2], useColors[iIndex1][2], iv), + a: interp(useColors[iIndex][3], useColors[iIndex1][3], iv) }; } - function getIndexedColor(colors, i, base, scaleFactor){ + function getIndexedColor(colors, negativeColors, i, base, scaleFactor, scaleFactorNegative){ var index = Math.floor((i-base)*scaleFactor); + + if (negativeColors && index < 0) { + index = (index * -1) - 1; + if (index >= negativeColors.length) { + index = negativeColors.length - 1; + } + + return { + r: negativeColors[index][0], + g: negativeColors[index][1], + b: negativeColors[index][2], + a: negativeColors[index][3], + }; + } + return { r: colors[index][0], g: colors[index][1], @@ -266,35 +301,63 @@ var ColorManager = function(){ function cssColorToArray(color){ return cssColorParser(color); } - + this.getColor = function(){ console.error('ColorManager: colors have not been setup'); }; this.colors = []; + this.negativeColors = []; - this.setup = function(min, max, colors, colorInterpolation, colorHighlightMultiplier){ + this.setup = function (min, max, colors, negativeColors, colorInterpolation, colorHighlightMultiplier) { var colorFunction, scaleFactor; - var dataLength = max-min; var base = min; + var dataLength = max - min; + + var scaleFactorNegative = false; + var dataLengthNegative = false; + + if (negativeColors) { + if (max < 0) { + max = max + 0.000001; + base = max; + } else if (max > 0 && min < 0) { + dataLength = max; + dataLengthNegative = min; + base = 0; + } + } - if (colorInterpolation === 'gradient'){ + if (colorInterpolation === 'gradient') { colorFunction = getGradientColor; - scaleFactor = (colors.length-1)/(dataLength -1); + scaleFactor = (colors.length ) / (dataLength !== 0 ? dataLength : 1); } else { colorFunction = getIndexedColor; - scaleFactor = (colors.length)/(dataLength+1); - } + scaleFactor = (colors.length) / (dataLength + 1); + } - this.colors = colors.map(function(clr){ + if (negativeColors) { + if (max > 0 && min < 0) { + if (colorInterpolation === 'gradient') { + scaleFactorNegative = (negativeColors.length - 1) / (dataLengthNegative - 1); + } else { + scaleFactorNegative = (negativeColors.length) / (dataLengthNegative + 1); + } + } + } + + this.colors = colors.map(function (clr) { return cssColorToArray(clr); }); - - this.getColor = function(dataValue){ - var clr = colorFunction(this.colors, dataValue, base, scaleFactor); + this.negativeColors = negativeColors.map(function (clr) { + return cssColorToArray(clr); + }); + + this.getColor = function (dataValue) { + var clr = colorFunction(this.colors, this.negativeColors, dataValue, base, scaleFactor, scaleFactorNegative); var hclr = getHighlightColor(clr, colorHighlightMultiplier); - return { + return { color: rgbString(clr.r, clr.g, clr.b, clr.a), highlight: rgbString(hclr.r, hclr.g, hclr.b, hclr.a) }; @@ -715,8 +778,8 @@ var ColorManager = function(){ removeDataset: function(){ this.datasets.pop(); this.scale.yLabels.pop(); - this.scale.steps -= 1; - this.scale.max -= 1; + this.scale.steps -= 1; + this.scale.max -= 1; this.scale.fit(); this.findMaxAndMin(true); this.applyColors(); @@ -726,10 +789,11 @@ var ColorManager = function(){ applyColors : function(){ this.colorManager.setup( - this.min, - this.max, - this.options.colors, - this.options.colorInterpolation, + this.min, + this.max, + this.options.colors, + this.options.negativeColors, + this.options.colorInterpolation, this.options.colorHighlightMultiplier ); diff --git a/dst/Chart.HeatMap.min.js b/dst/Chart.HeatMap.min.js index 24be556..624edd5 100644 --- a/dst/Chart.HeatMap.min.js +++ b/dst/Chart.HeatMap.min.js @@ -22,4 +22,4 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. // http://www.w3.org/TR/css3-color/ -var cssColorParser=function(){function t(e){return e=Math.round(e),e<0?0:e>255?255:e}function n(e){return e<0?0:e>1?1:e}function r(e){return e[e.length-1]==="%"?t(parseFloat(e)/100*255):t(parseInt(e))}function i(e){return e[e.length-1]==="%"?n(parseFloat(e)/100):n(parseFloat(e))}function s(e,t,n){return n<0?n+=1:n>1&&(n-=1),n*6<1?e+(t-e)*n*6:n*2<1?t:n*3<2?e+(t-e)*(2/3-n)*6:e}function o(n){var o=n.replace(/ /g,"").toLowerCase();if(o in e)return e[o].slice();if(o[0]==="#"){if(o.length===4){var u=parseInt(o.substr(1),16);return u>=0&&u<=4095?[(u&3840)>>4|(u&3840)>>8,u&240|(u&240)>>4,u&15|(u&15)<<4,1]:null}if(o.length===7){var u=parseInt(o.substr(1),16);return u>=0&&u<=16777215?[(u&16711680)>>16,(u&65280)>>8,u&255,1]:null}return null}var a=o.indexOf("("),f=o.indexOf(")");if(a!==-1&&f+1===o.length){var l=o.substr(0,a),c=o.substr(a+1,f-(a+1)).split(","),h=1;switch(l){case"rgba":if(c.length!==4)return null;h=i(c.pop());case"rgb":if(c.length!==3)return null;return[r(c[0]),r(c[1]),r(c[2]),h];case"hsla":if(c.length!==4)return null;h=i(c.pop());case"hsl":if(c.length!==3)return null;var p=(parseFloat(c[0])%360+360)%360/360,d=i(c[1]),v=i(c[2]),m=v<=.5?v*(d+1):v+d-v*d,g=v*2-m;return[t(s(g,m,p+1/3)*255),t(s(g,m,p)*255),t(s(g,m,p-1/3)*255),h];default:return null}}return null}var e={rebeccapurple:[102,51,153],transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]};return o}(),ColorManager=function(){function e(e,n,r,i){return e=t(e,0,255),n=t(n,0,255),r=t(r,0,255),i=t(i,0,255),"rgba("+Math.floor(e)+","+Math.floor(n)+","+Math.floor(r)+","+i+")"}function t(e,t,n){return Math.max(t,Math.min(e,n))}function n(e,t,n){return t*n+e*(1-n)}function r(e,t,r,i){var s=(t-r)*i,o=Math.floor(s),u=s-o,a=o+1;return a>e.length-1&&(a=o),{r:n(e[o][0],e[a][0],u),g:n(e[o][1],e[a][1],u),b:n(e[o][2],e[a][2],u),a:n(e[o][3],e[a][3],u)}}function i(e,t,n,r){var i=Math.floor((t-n)*r);return{r:e[i][0],g:e[i][1],b:e[i][2],a:e[i][3]}}function s(e,t){return e*=t,e>255?255:e}function o(e,t){return{r:s(e.r,t),g:s(e.g,t),b:s(e.b,t),a:e.a}}function u(e){return cssColorParser(e)}this.getColor=function(){console.error("ColorManager: colors have not been setup")},this.colors=[],this.setup=function(t,n,s,a,f){var l,c,h=n-t,p=t;a==="gradient"?(l=r,c=(s.length-1)/(h-1)):(l=i,c=s.length/(h+1)),this.colors=s.map(function(e){return u(e)}),this.getColor=function(t){var n=l(this.colors,t,p,c),r=o(n,f);return{color:e(n.r,n.g,n.b,n.a),highlight:e(r.r,r.g,r.b,r.a)}}}};(function(){"use strict";var e=this,t=e.Chart,n=t.helpers,r={backgroundColor:"#fff",stroke:!1,strokePerc:.05,strokeColor:"rgb(128,128,128)",highlightStrokeColor:"rgb(192,192,192)",rounded:!0,roundedRadius:.1,paddingScale:.05,colorInterpolation:"gradient",colors:["rgba(220,220,220,0.9)","rgba(151,187,205,0.9)"],colorHighlight:!0,colorHighlightMultiplier:.92,showLabels:!0,labelScale:.2,labelFontFamily:'"HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif',labelFontStyle:"normal",labelFontColor:"rgba(0,0,0,0.5)",tooltipTemplate:"<%= xLabel %> | <%= yLabel %> : <%= value %>",legendTemplate:'
<%= min %><% for (var i = min; i <= max; i += (max-min)/6){ %>  <% } %><%= max %>
'};t.Type.extend({name:"HeatMap",defaults:r,initialize:function(e){var r=this.options;this.max=-Infinity,this.min=Infinity,this.colorManager=new ColorManager,this.ScaleClass=t.Scale.extend({offsetGridLines:!0,calculateBaseWidth:function(){return this.calculateX(1)-this.calculateX(0)},calculateBoxWidth:function(e,t){var n=this.calculateBaseWidth()-e-1,r=Math.max(e,t);return this.calculateBaseWidth()},calculateBoxHeight:function(){return this.calculateY(0)-this.calculateY(1)},buildYLabels:function(){this.yLabelWidth=this.display&&this.showLabels?n.longestText(this.ctx,this.font,this.yLabels):0},draw:function(){var e=this.ctx,t=(this.endPoint-this.startPoint)/this.steps,r=Math.round(this.xScalePaddingLeft);this.display&&(e.fillStyle=this.textColor,e.font=this.font,n.each(this.yLabels,function(n,i){var s=this.endPoint-t*i-t*.5,o=Math.round(s),u=this.showHorizontalLines;e.textAlign="right",e.textBaseline="middle",this.showLabels&&e.fillText(n,r-10,s)},this),n.each(this.xLabels,function(t,r){var i=this.calculateX(r)+n.aliasPixel(this.lineWidth),s=this.calculateX(r-(this.offsetGridLines?.5:0))+n.aliasPixel(this.lineWidth),o=this.xLabelRotation>0,u=this.showVerticalLines;e.lineWidth=this.lineWidth,e.strokeStyle=this.lineColor,e.save(),e.translate(i,o?this.endPoint+12:this.endPoint+8),e.rotate(n.radians(this.xLabelRotation)*-1),e.font=this.font,e.textAlign=o?"right":"center",e.textBaseline=o?"middle":"top",e.fillText(t,0,0),e.restore()},this))}}),this.datasets=[],this.yLabels=[],this.xLabels=e.labels,this.options.showTooltips&&n.bindEvents(this,this.options.tooltipEvents,function(e){var t=e.type!=="mouseout"?this.getBoxAtEvent(e):undefined;this.activeElement=t,this.eachBoxes(function(e){e.restore(["fillColor","strokeColor"])}),t&&(t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke),this.showTooltip(t)}),this.BoxClass=t.Rectangle.extend({strokePerc:this.options.strokePerc,strokeColor:this.options.strokeColor,showStroke:this.options.stroke,fontColor:this.options.labelFontColor,fontFamily:this.options.labelFontFamily,fontScale:this.options.labelScale,showLabels:this.options.showLabels,radiusScale:this.options.rounded?this.options.roundedRadius:0,paddingScale:this.options.paddingScale,ctx:this.chart.ctx,draw:function(){var e=this.ctx,t=this.width/2,r=this.width,i=this.height,s=this.x-t,o=this.y,u=this.strokePerc*this.width,a=u/2,f=this.paddingScale*r,l=this.paddingScale*i;s+=f*.5,o+=l*.5,r-=f,i-=l,this.showStroke&&(s+=a,r-=a,i-=a,o+=a),e.fillStyle=this.fillColor,e.strokeStyle=this.strokeColor,e.lineWidth=u,n.drawRoundedRectangle(e,s,o,r,i,this.radiusScale*this.width),e.fill(),this.showStroke&&e.stroke(),this.showLabels&&this.label!==null&&this.label!==undefined&&(e.textAlign="center",e.textBaseline="middle",e.fillStyle=this.fontColor,e.font=this.height*this.fontScale+"px "+this.fontFamily,e.fillText(this.value,s+r*.5,o+i*.5))}}),n.each(e.datasets,function(e,t){var r={label:e.label||null,boxes:[]};this.datasets.push(r),this.yLabels.push(e.label),n.each(e.data,function(t,n){r.boxes.push(new this.BoxClass({value:t,label:this.xLabels[n],datasetLabel:e.label,strokeColor:this.options.strokeColor,fillColor:"white",highlightFill:"black",highlightStroke:this.options.highlightStrokeColor}))},this)},this),this.datasets.reverse(),this.yLabels.reverse(),this.buildScale(e.labels,this.yLabels),this.BoxClass.prototype.base=this.scale.endPoint,this.eachBoxes(function(e,t,r){n.extend(e,{x:this.scale.calculateX(t),y:this.scale.calculateY(r+1),width:this.scale.calculateBoxWidth(),height:this.scale.calculateBoxHeight()}),e.save()},this),this.findMaxAndMin(!0),this.applyColors(),this.render()},update:function(){this.scale.update(),this.activeElement&&this.activeElement.restore(["fillColor","strokeColor"]),this.eachBoxes(function(e){e.save()}),this.render()},eachBoxes:function(e){n.each(this.datasets,function(t,r){n.each(t.boxes,e,this,r)},this)},getBoxAtEvent:function(e){var t=n.getRelativePosition(e),r;for(var i=0;ithis.max&&(this.max=e.value),e.value255?255:e}function n(e){return e<0?0:e>1?1:e}function r(e){return e[e.length-1]==="%"?t(parseFloat(e)/100*255):t(parseInt(e))}function i(e){return e[e.length-1]==="%"?n(parseFloat(e)/100):n(parseFloat(e))}function s(e,t,n){return n<0?n+=1:n>1&&(n-=1),n*6<1?e+(t-e)*n*6:n*2<1?t:n*3<2?e+(t-e)*(2/3-n)*6:e}function o(n){var o=n.replace(/ /g,"").toLowerCase();if(o in e)return e[o].slice();if(o[0]==="#"){if(o.length===4){var u=parseInt(o.substr(1),16);return u>=0&&u<=4095?[(u&3840)>>4|(u&3840)>>8,u&240|(u&240)>>4,u&15|(u&15)<<4,1]:null}if(o.length===7){var u=parseInt(o.substr(1),16);return u>=0&&u<=16777215?[(u&16711680)>>16,(u&65280)>>8,u&255,1]:null}return null}var a=o.indexOf("("),f=o.indexOf(")");if(a!==-1&&f+1===o.length){var l=o.substr(0,a),c=o.substr(a+1,f-(a+1)).split(","),h=1;switch(l){case"rgba":if(c.length!==4)return null;h=i(c.pop());case"rgb":if(c.length!==3)return null;return[r(c[0]),r(c[1]),r(c[2]),h];case"hsla":if(c.length!==4)return null;h=i(c.pop());case"hsl":if(c.length!==3)return null;var p=(parseFloat(c[0])%360+360)%360/360,d=i(c[1]),v=i(c[2]),m=v<=.5?v*(d+1):v+d-v*d,g=v*2-m;return[t(s(g,m,p+1/3)*255),t(s(g,m,p)*255),t(s(g,m,p-1/3)*255),h];default:return null}}return null}var e={rebeccapurple:[102,51,153],transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]};return o}(),ColorManager=function(){function e(e,n,r,i){return e=t(e,0,255),n=t(n,0,255),r=t(r,0,255),i=t(i,0,255),"rgba("+Math.floor(e)+","+Math.floor(n)+","+Math.floor(r)+","+i+")"}function t(e,t,n){return Math.max(t,Math.min(e,n))}function n(e,t,n){return t*n+e*(1-n)}function r(e,t,r,i,s,o){var u=e,a=s;t&&r<0&&(r=Math.abs(r),u=t,o===!1?(i=Math.abs(i),a=Math.abs(s)):a=Math.abs(o));var f=(r-i)*a,l=Math.floor(f);l>u.length-1&&(l=u.length-1),l<0&&(l=0);var c=f-l,h=l+1;return h>u.length-1&&(h=l),{r:n(u[l][0],u[h][0],c),g:n(u[l][1],u[h][1],c),b:n(u[l][2],u[h][2],c),a:n(u[l][3],u[h][3],c)}}function i(e,t,n,r,i,s){var o=Math.floor((n-r)*i);return t&&o<0?(o=o*-1-1,o>=t.length&&(o=t.length-1),{r:t[o][0],g:t[o][1],b:t[o][2],a:t[o][3]}):{r:e[o][0],g:e[o][1],b:e[o][2],a:e[o][3]}}function s(e,t){return e*=t,e>255?255:e}function o(e,t){return{r:s(e.r,t),g:s(e.g,t),b:s(e.b,t),a:e.a}}function u(e){return cssColorParser(e)}this.getColor=function(){console.error("ColorManager: colors have not been setup")},this.colors=[],this.negativeColors=[],this.setup=function(t,n,s,a,f,l){var c,h,p=t,d=n-t,v=!1,m=!1;a&&(n<0?(n+=1e-6,p=n):n>0&&t<0&&(d=n,m=t,p=0)),f==="gradient"?(c=r,h=s.length/(d!==0?d:1)):(c=i,h=s.length/(d+1)),a&&n>0&&t<0&&(f==="gradient"?v=(a.length-1)/(m-1):v=a.length/(m+1)),this.colors=s.map(function(e){return u(e)}),this.negativeColors=a.map(function(e){return u(e)}),this.getColor=function(t){var n=c(this.colors,this.negativeColors,t,p,h,v),r=o(n,l);return{color:e(n.r,n.g,n.b,n.a),highlight:e(r.r,r.g,r.b,r.a)}}}};(function(){"use strict";var e=this,t=e.Chart,n=t.helpers,r={backgroundColor:"#fff",stroke:!1,strokePerc:.05,strokeColor:"rgb(128,128,128)",highlightStrokeColor:"rgb(192,192,192)",rounded:!0,roundedRadius:.1,paddingScale:.05,colorInterpolation:"gradient",colors:["rgba(220,220,220,0.9)","rgba(151,187,205,0.9)"],colorHighlight:!0,colorHighlightMultiplier:.92,showLabels:!0,labelScale:.2,labelFontFamily:'"HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif',labelFontStyle:"normal",labelFontColor:"rgba(0,0,0,0.5)",tooltipTemplate:"<%= xLabel %> | <%= yLabel %> : <%= value %>",legendTemplate:'
<%= min %><% for (var i = min; i <= max; i += (max-min)/6){ %>  <% } %><%= max %>
'};t.Type.extend({name:"HeatMap",defaults:r,initialize:function(e){var r=this.options;this.max=-Infinity,this.min=Infinity,this.colorManager=new ColorManager,this.ScaleClass=t.Scale.extend({offsetGridLines:!0,calculateBaseWidth:function(){return this.calculateX(1)-this.calculateX(0)},calculateBoxWidth:function(e,t){var n=this.calculateBaseWidth()-e-1,r=Math.max(e,t);return this.calculateBaseWidth()},calculateBoxHeight:function(){return this.calculateY(0)-this.calculateY(1)},buildYLabels:function(){this.yLabelWidth=this.display&&this.showLabels?n.longestText(this.ctx,this.font,this.yLabels):0},draw:function(){var e=this.ctx,t=(this.endPoint-this.startPoint)/this.steps,r=Math.round(this.xScalePaddingLeft);this.display&&(e.fillStyle=this.textColor,e.font=this.font,n.each(this.yLabels,function(n,i){var s=this.endPoint-t*i-t*.5,o=Math.round(s),u=this.showHorizontalLines;e.textAlign="right",e.textBaseline="middle",this.showLabels&&e.fillText(n,r-10,s)},this),n.each(this.xLabels,function(t,r){var i=this.calculateX(r)+n.aliasPixel(this.lineWidth),s=this.calculateX(r-(this.offsetGridLines?.5:0))+n.aliasPixel(this.lineWidth),o=this.xLabelRotation>0,u=this.showVerticalLines;e.lineWidth=this.lineWidth,e.strokeStyle=this.lineColor,e.save(),e.translate(i,o?this.endPoint+12:this.endPoint+8),e.rotate(n.radians(this.xLabelRotation)*-1),e.font=this.font,e.textAlign=o?"right":"center",e.textBaseline=o?"middle":"top",e.fillText(t,0,0),e.restore()},this))}}),this.datasets=[],this.yLabels=[],this.xLabels=e.labels,this.options.showTooltips&&n.bindEvents(this,this.options.tooltipEvents,function(e){var t=e.type!=="mouseout"?this.getBoxAtEvent(e):undefined;this.activeElement=t,this.eachBoxes(function(e){e.restore(["fillColor","strokeColor"])}),t&&(t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke),this.showTooltip(t)}),this.BoxClass=t.Rectangle.extend({strokePerc:this.options.strokePerc,strokeColor:this.options.strokeColor,showStroke:this.options.stroke,fontColor:this.options.labelFontColor,fontFamily:this.options.labelFontFamily,fontScale:this.options.labelScale,showLabels:this.options.showLabels,radiusScale:this.options.rounded?this.options.roundedRadius:0,paddingScale:this.options.paddingScale,ctx:this.chart.ctx,draw:function(){var e=this.ctx,t=this.width/2,r=this.width,i=this.height,s=this.x-t,o=this.y,u=this.strokePerc*this.width,a=u/2,f=this.paddingScale*r,l=this.paddingScale*i;s+=f*.5,o+=l*.5,r-=f,i-=l,this.showStroke&&(s+=a,r-=a,i-=a,o+=a),e.fillStyle=this.fillColor,e.strokeStyle=this.strokeColor,e.lineWidth=u,n.drawRoundedRectangle(e,s,o,r,i,this.radiusScale*this.width),e.fill(),this.showStroke&&e.stroke(),this.showLabels&&this.label!==null&&this.label!==undefined&&(e.textAlign="center",e.textBaseline="middle",e.fillStyle=this.fontColor,e.font=this.height*this.fontScale+"px "+this.fontFamily,e.fillText(this.value,s+r*.5,o+i*.5))}}),n.each(e.datasets,function(e,t){var r={label:e.label||null,boxes:[]};this.datasets.push(r),this.yLabels.push(e.label),n.each(e.data,function(t,n){r.boxes.push(new this.BoxClass({value:t,label:this.xLabels[n],datasetLabel:e.label,strokeColor:this.options.strokeColor,fillColor:"white",highlightFill:"black",highlightStroke:this.options.highlightStrokeColor}))},this)},this),this.datasets.reverse(),this.yLabels.reverse(),this.buildScale(e.labels,this.yLabels),this.BoxClass.prototype.base=this.scale.endPoint,this.eachBoxes(function(e,t,r){n.extend(e,{x:this.scale.calculateX(t),y:this.scale.calculateY(r+1),width:this.scale.calculateBoxWidth(),height:this.scale.calculateBoxHeight()}),e.save()},this),this.findMaxAndMin(!0),this.applyColors(),this.render()},update:function(){this.scale.update(),this.activeElement&&this.activeElement.restore(["fillColor","strokeColor"]),this.eachBoxes(function(e){e.save()}),this.render()},eachBoxes:function(e){n.each(this.datasets,function(t,r){n.each(t.boxes,e,this,r)},this)},getBoxAtEvent:function(e){var t=n.getRelativePosition(e),r;for(var i=0;ithis.max&&(this.max=e.value),e.value Date: Mon, 6 May 2019 09:28:43 +0200 Subject: [PATCH 2/2] Update README to install fork --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 88bf9f2..226fa18 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,10 @@ Documentation is available [here](http://tmroyal.github.io/Chart.HeatMap/). `npm install chart.heatmap.js` +To install from Mischa Braam's fork use command below. If that doesn't work please advise [stack overflow](https://stackoverflow.com/questions/17509669/how-to-install-an-npm-package-from-github-directly) for a solution. + +`npm install mischabraam/Chart.Heatmap#master` + ### Github The built distributions are also available in the dst folder in