diff --git a/web/gui/src/main/webapp/index.html b/web/gui/src/main/webapp/index.html
index 5266d89..ce74665 100644
--- a/web/gui/src/main/webapp/index.html
+++ b/web/gui/src/main/webapp/index.html
@@ -35,6 +35,9 @@
     <script src="tp/d3.js"></script>
     <script src="tp/topojson.v1.min.js"></script>
 
+    <script src="tp/Chart.min.js"></script>
+    <script src="tp/angular-chart.min.js"></script>
+
     <!-- ONOS UI Framework included here -->
     <!-- TODO: use a single catenated-minified file here -->
     <script src="onos.js"></script>
@@ -81,6 +84,8 @@
     <script src="app/fw/layer/loading.js"></script>
 
     <!-- Framework and library stylesheets included here -->
+    <link rel="stylesheet" href="tp/angular-chart.min.css">
+
     <!-- TODO: use a single catenated-minified file here -->
     <link rel="stylesheet" href="app/onos.css">
     <link rel="stylesheet" href="app/common.css">
diff --git a/web/gui/src/main/webapp/tp/Chart.LICENSE b/web/gui/src/main/webapp/tp/Chart.LICENSE
new file mode 100755
index 0000000..36d5cf0
--- /dev/null
+++ b/web/gui/src/main/webapp/tp/Chart.LICENSE
@@ -0,0 +1,7 @@
+Copyright (c) 2013-2016 Nick Downie
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/web/gui/src/main/webapp/tp/Chart.js b/web/gui/src/main/webapp/tp/Chart.js
new file mode 100755
index 0000000..3e48608
--- /dev/null
+++ b/web/gui/src/main/webapp/tp/Chart.js
@@ -0,0 +1,3731 @@
+/*!
+ * Chart.js
+ * http://chartjs.org/
+ * Version: 1.0.2
+ *
+ * Copyright 2015 Nick Downie
+ * Released under the MIT license
+ * https://github.com/nnnick/Chart.js/blob/master/LICENSE.md
+ */
+
+
+(function(){
+
+    "use strict";
+
+    //Declare root variable - window in the browser, global on the server
+    var root = this,
+        previous = root.Chart;
+
+    //Occupy the global variable of Chart, and create a simple base class
+    var Chart = function(context){
+        var chart = this;
+        this.canvas = context.canvas;
+
+        this.ctx = context;
+
+        //Variables global to the chart
+        var computeDimension = function(element,dimension)
+        {
+            if (element['offset'+dimension])
+            {
+                return element['offset'+dimension];
+            }
+            else
+            {
+                return document.defaultView.getComputedStyle(element).getPropertyValue(dimension);
+            }
+        };
+
+        var width = this.width = computeDimension(context.canvas,'Width') || context.canvas.width;
+        var height = this.height = computeDimension(context.canvas,'Height') || context.canvas.height;
+
+        width = this.width = context.canvas.width;
+        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);
+
+        return this;
+    };
+    //Globally expose the defaults to allow for user updating/changing
+    Chart.defaults = {
+        global: {
+            // Boolean - Whether to animate the chart
+            animation: true,
+
+            // Number - Number of animation steps
+            animationSteps: 60,
+
+            // String - Animation easing effect
+            animationEasing: "easeOutQuart",
+
+            // Boolean - If we should show the scale at all
+            showScale: true,
+
+            // Boolean - If we want to override with a hard coded scale
+            scaleOverride: false,
+
+            // ** Required if scaleOverride is true **
+            // Number - The number of steps in a hard coded scale
+            scaleSteps: null,
+            // Number - The value jump in the hard coded scale
+            scaleStepWidth: null,
+            // Number - The scale starting value
+            scaleStartValue: null,
+
+            // String - Colour of the scale line
+            scaleLineColor: "rgba(0,0,0,.1)",
+
+            // Number - Pixel width of the scale line
+            scaleLineWidth: 1,
+
+            // Boolean - Whether to show labels on the scale
+            scaleShowLabels: true,
+
+            // Interpolated JS string - can access value
+            scaleLabel: "<%=value%>",
+
+            // Boolean - Whether the scale should stick to integers, and not show any floats even if drawing space is there
+            scaleIntegersOnly: true,
+
+            // Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
+            scaleBeginAtZero: false,
+
+            // String - Scale label font declaration for the scale label
+            scaleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
+
+            // Number - Scale label font size in pixels
+            scaleFontSize: 12,
+
+            // String - Scale label font weight style
+            scaleFontStyle: "normal",
+
+            // String - Scale label font colour
+            scaleFontColor: "#666",
+
+            // Boolean - whether or not the chart should be responsive and resize when the browser does.
+            responsive: false,
+
+            // Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
+            maintainAspectRatio: true,
+
+            // Boolean - Determines whether to draw tooltips on the canvas or not - attaches events to touchmove & mousemove
+            showTooltips: true,
+
+            // Boolean - Determines whether to draw built-in tooltip or call custom tooltip function
+            customTooltips: false,
+
+            // Array - Array of string names to attach tooltip events
+            tooltipEvents: ["mousemove", "touchstart", "touchmove", "mouseout"],
+
+            // String - Tooltip background colour
+            tooltipFillColor: "rgba(0,0,0,0.8)",
+
+            // String - Tooltip label font declaration for the scale label
+            tooltipFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
+
+            // Number - Tooltip label font size in pixels
+            tooltipFontSize: 14,
+
+            // String - Tooltip font weight style
+            tooltipFontStyle: "normal",
+
+            // String - Tooltip label font colour
+            tooltipFontColor: "#fff",
+
+            // String - Tooltip title font declaration for the scale label
+            tooltipTitleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
+
+            // Number - Tooltip title font size in pixels
+            tooltipTitleFontSize: 14,
+
+            // String - Tooltip title font weight style
+            tooltipTitleFontStyle: "bold",
+
+            // String - Tooltip title font colour
+            tooltipTitleFontColor: "#fff",
+
+            // String - Tooltip title template
+            tooltipTitleTemplate: "<%= label%>",
+
+            // Number - pixel width of padding around tooltip text
+            tooltipYPadding: 6,
+
+            // Number - pixel width of padding around tooltip text
+            tooltipXPadding: 6,
+
+            // Number - Size of the caret on the tooltip
+            tooltipCaretSize: 8,
+
+            // Number - Pixel radius of the tooltip border
+            tooltipCornerRadius: 6,
+
+            // Number - Pixel offset from point x to tooltip edge
+            tooltipXOffset: 10,
+
+            // String - Template string for single tooltips
+            tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= value %>",
+
+            // String - Template string for single tooltips
+            multiTooltipTemplate: "<%= 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(){},
+
+            // Function - Will fire on animation completion.
+            onAnimationComplete: function(){}
+
+        }
+    };
+
+    //Create a dictionary of chart types, to allow for extension of existing types
+    Chart.types = {};
+
+    //Global Chart helpers object for utility methods and classes
+    var helpers = Chart.helpers = {};
+
+        //-- Basic js utility methods
+    var each = helpers.each = function(loopable,callback,self){
+            var additionalArgs = Array.prototype.slice.call(arguments, 3);
+            // Check to see if null or undefined firstly.
+            if (loopable){
+                if (loopable.length === +loopable.length){
+                    var i;
+                    for (i=0; i<loopable.length; i++){
+                        callback.apply(self,[loopable[i], i].concat(additionalArgs));
+                    }
+                }
+                else{
+                    for (var item in loopable){
+                        callback.apply(self,[loopable[item],item].concat(additionalArgs));
+                    }
+                }
+            }
+        },
+        clone = helpers.clone = function(obj){
+            var objClone = {};
+            each(obj,function(value,key){
+                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;
+                    }
+                });
+            });
+            return base;
+        },
+        merge = helpers.merge = function(base,master){
+            //Merge properties in left object over to a shallow clone of object right.
+            var args = Array.prototype.slice.call(arguments,0);
+            args.unshift({});
+            return extend.apply(null, args);
+        },
+        indexOf = helpers.indexOf = function(arrayToSearch, item){
+            if (Array.prototype.indexOf) {
+                return arrayToSearch.indexOf(item);
+            }
+            else{
+                for (var i = 0; i < arrayToSearch.length; i++) {
+                    if (arrayToSearch[i] === item) return i;
+                }
+                return -1;
+            }
+        },
+        where = helpers.where = function(collection, filterCallback){
+            var filtered = [];
+
+            helpers.each(collection, function(item){
+                if (filterCallback(item)){
+                    filtered.push(item);
+                }
+            });
+
+            return filtered;
+        },
+        findNextWhere = helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex){
+            // Default to start of the array
+            if (!startIndex){
+                startIndex = -1;
+            }
+            for (var i = startIndex + 1; i < arrayToSearch.length; i++) {
+                var currentItem = arrayToSearch[i];
+                if (filterCallback(currentItem)){
+                    return currentItem;
+                }
+            }
+        },
+        findPreviousWhere = helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex){
+            // Default to end of the array
+            if (!startIndex){
+                startIndex = arrayToSearch.length;
+            }
+            for (var i = startIndex - 1; i >= 0; i--) {
+                var currentItem = arrayToSearch[i];
+                if (filterCallback(currentItem)){
+                    return currentItem;
+                }
+            }
+        },
+        inherits = helpers.inherits = function(extensions){
+            //Basic javascript inheritance based on the model created in Backbone.js
+            var parent = this;
+            var ChartElement = (extensions && extensions.hasOwnProperty("constructor")) ? extensions.constructor : function(){ return parent.apply(this, arguments); };
+
+            var Surrogate = function(){ this.constructor = ChartElement;};
+            Surrogate.prototype = parent.prototype;
+            ChartElement.prototype = new Surrogate();
+
+            ChartElement.extend = inherits;
+
+            if (extensions) extend(ChartElement.prototype, extensions);
+
+            ChartElement.__super__ = parent.prototype;
+
+            return ChartElement;
+        },
+        noop = helpers.noop = function(){},
+        uid = helpers.uid = (function(){
+            var id=0;
+            return function(){
+                return "chart-" + id++;
+            };
+        })(),
+        warn = helpers.warn = function(str){
+            //Method for warning of errors
+            if (window.console && typeof window.console.warn === "function") console.warn(str);
+        },
+        amd = helpers.amd = (typeof define === 'function' && define.amd),
+        //-- Math methods
+        isNumber = helpers.isNumber = function(n){
+            return !isNaN(parseFloat(n)) && isFinite(n);
+        },
+        max = helpers.max = function(array){
+            return Math.max.apply( Math, array );
+        },
+        min = helpers.min = function(array){
+            return Math.min.apply( Math, array );
+        },
+        cap = helpers.cap = function(valueToCap,maxValue,minValue){
+            if(isNumber(maxValue)) {
+                if( valueToCap > maxValue ) {
+                    return maxValue;
+                }
+            }
+            else if(isNumber(minValue)){
+                if ( valueToCap < minValue ){
+                    return minValue;
+                }
+            }
+            return valueToCap;
+        },
+        getDecimalPlaces = helpers.getDecimalPlaces = function(num){
+            if (num%1!==0 && isNumber(num)){
+                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;
+            }
+        },
+        toRadians = helpers.radians = function(degrees){
+            return degrees * (Math.PI/180);
+        },
+        // Gets the angle from vertical upright to the point about a centre.
+        getAngleFromPoint = helpers.getAngleFromPoint = function(centrePoint, anglePoint){
+            var distanceFromXCenter = anglePoint.x - centrePoint.x,
+                distanceFromYCenter = anglePoint.y - centrePoint.y,
+                radialDistanceFromCenter = Math.sqrt( distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
+
+
+            var angle = Math.PI * 2 + Math.atan2(distanceFromYCenter, distanceFromXCenter);
+
+            //If the segment is in the top left quadrant, we need to add another rotation to the angle
+            if (distanceFromXCenter < 0 && distanceFromYCenter < 0){
+                angle += Math.PI*2;
+            }
+
+            return {
+                angle: angle,
+                distance: radialDistanceFromCenter
+            };
+        },
+        aliasPixel = helpers.aliasPixel = function(pixelWidth){
+            return (pixelWidth % 2 === 0) ? 0 : 0.5;
+        },
+        splineCurve = helpers.splineCurve = function(FirstPoint,MiddlePoint,AfterPoint,t){
+            //Props to Rob Spencer at scaled innovation for his post on splining between points
+            //http://scaledinnovation.com/analytics/splines/aboutSplines.html
+            var d01=Math.sqrt(Math.pow(MiddlePoint.x-FirstPoint.x,2)+Math.pow(MiddlePoint.y-FirstPoint.y,2)),
+                d12=Math.sqrt(Math.pow(AfterPoint.x-MiddlePoint.x,2)+Math.pow(AfterPoint.y-MiddlePoint.y,2)),
+                fa=t*d01/(d01+d12),// scaling factor for triangle Ta
+                fb=t*d12/(d01+d12);
+            return {
+                inner : {
+                    x : MiddlePoint.x-fa*(AfterPoint.x-FirstPoint.x),
+                    y : MiddlePoint.y-fa*(AfterPoint.y-FirstPoint.y)
+                },
+                outer : {
+                    x: MiddlePoint.x+fb*(AfterPoint.x-FirstPoint.x),
+                    y : MiddlePoint.y+fb*(AfterPoint.y-FirstPoint.y)
+                }
+            };
+        },
+        calculateOrderOfMagnitude = helpers.calculateOrderOfMagnitude = function(val){
+            return Math.floor(Math.log(val) / Math.LN10);
+        },
+        calculateScaleRange = helpers.calculateScaleRange = function(valuesArray, drawingSize, textSize, startFromZero, integersOnly){
+
+            //Set a minimum step of two - a point at the top of the graph, and a point at the base
+            var minSteps = 2,
+                maxSteps = Math.floor(drawingSize/(textSize * 1.5)),
+                skipFitting = (minSteps >= maxSteps);
+
+            // 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 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;
+                // So we don't end up with a graph with a negative start value if we've said always start from zero
+                if (minValue >= 0.5 && !startFromZero){
+                    minValue -= 0.5;
+                }
+                else{
+                    // Make up a whole number above the values
+                    maxValue += 0.5;
+                }
+            }
+
+            var	valueRange = Math.abs(maxValue - minValue),
+                rangeOrderOfMagnitude = calculateOrderOfMagnitude(valueRange),
+                graphMax = Math.ceil(maxValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),
+                graphMin = (startFromZero) ? 0 : Math.floor(minValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),
+                graphRange = graphMax - graphMin,
+                stepValue = Math.pow(10, rangeOrderOfMagnitude),
+                numberOfSteps = Math.round(graphRange / stepValue);
+
+            //If we have more space on the graph we'll use it to give more definition to the data
+            while((numberOfSteps > maxSteps || (numberOfSteps * 2) < maxSteps) && !skipFitting) {
+                if(numberOfSteps > maxSteps){
+                    stepValue *=2;
+                    numberOfSteps = Math.round(graphRange/stepValue);
+                    // Don't ever deal with a decimal number of steps - cancel fitting and just use the minimum number of steps.
+                    if (numberOfSteps % 1 !== 0){
+                        skipFitting = true;
+                    }
+                }
+                //We can fit in double the amount of scale points on the scale
+                else{
+                    //If user has declared ints only, and the step value isn't a decimal
+                    if (integersOnly && rangeOrderOfMagnitude >= 0){
+                        //If the user has said integers only, we need to check that making the scale more granular wouldn't make it a float
+                        if(stepValue/2 % 1 === 0){
+                            stepValue /=2;
+                            numberOfSteps = Math.round(graphRange/stepValue);
+                        }
+                        //If it would make it a float break out of the loop
+                        else{
+                            break;
+                        }
+                    }
+                    //If the scale doesn't have to be an int, make the scale more granular anyway.
+                    else{
+                        stepValue /=2;
+                        numberOfSteps = Math.round(graphRange/stepValue);
+                    }
+
+                }
+            }
+
+            if (skipFitting){
+                numberOfSteps = minSteps;
+                stepValue = graphRange / numberOfSteps;
+            }
+
+            return {
+                steps : numberOfSteps,
+                stepValue : stepValue,
+                min : graphMin,
+                max	: graphMin + (numberOfSteps * stepValue)
+            };
+
+        },
+        /* jshint ignore:start */
+        // Blows up jshint errors based on the new Function constructor
+        //Templating methods
+        //Javascript micro templating by John Resig - source at http://ejohn.org/blog/javascript-micro-templating/
+        template = helpers.template = function(templateString, valuesObject){
+
+            // If templateString is function rather than string-template - call the function for valuesObject
+
+            if(templateString instanceof Function){
+                return templateString(valuesObject);
+            }
+
+            var cache = {};
+            function tmpl(str, data){
+                // Figure out if we're getting a template, or if we need to
+                // load the template - and be sure to cache the result.
+                var fn = !/\W/.test(str) ?
+                cache[str] = cache[str] :
+
+                // Generate a reusable function that will serve as a template
+                // generator (and which will be cached).
+                new Function("obj",
+                    "var p=[],print=function(){p.push.apply(p,arguments);};" +
+
+                    // Introduce the data as local variables using with(){}
+                    "with(obj){p.push('" +
+
+                    // Convert the template into pure JavaScript
+                    str
+                        .replace(/[\r\t\n]/g, " ")
+                        .split("<%").join("\t")
+                        .replace(/((^|%>)[^\t]*)'/g, "$1\r")
+                        .replace(/\t=(.*?)%>/g, "',$1,'")
+                        .split("\t").join("');")
+                        .split("%>").join("p.push('")
+                        .split("\r").join("\\'") +
+                    "');}return p.join('');"
+                );
+
+                // Provide some basic currying to the user
+                return data ? fn( data ) : fn;
+            }
+            return tmpl(templateString,valuesObject);
+        },
+        /* jshint ignore:end */
+        generateLabels = helpers.generateLabels = function(templateString,numberOfSteps,graphMin,stepValue){
+            var labelsArray = new Array(numberOfSteps);
+            if (templateString){
+                each(labelsArray,function(val,index){
+                    labelsArray[index] = template(templateString,{value: (graphMin + (stepValue*(index+1)))});
+                });
+            }
+            return labelsArray;
+        },
+        //--Animation methods
+        //Easing functions adapted from Robert Penner's easing equations
+        //http://www.robertpenner.com/easing/
+        easingEffects = helpers.easingEffects = {
+            linear: function (t) {
+                return t;
+            },
+            easeInQuad: function (t) {
+                return t * t;
+            },
+            easeOutQuad: function (t) {
+                return -1 * t * (t - 2);
+            },
+            easeInOutQuad: function (t) {
+                if ((t /= 1 / 2) < 1){
+                    return 1 / 2 * t * t;
+                }
+                return -1 / 2 * ((--t) * (t - 2) - 1);
+            },
+            easeInCubic: function (t) {
+                return t * t * t;
+            },
+            easeOutCubic: function (t) {
+                return 1 * ((t = t / 1 - 1) * t * t + 1);
+            },
+            easeInOutCubic: function (t) {
+                if ((t /= 1 / 2) < 1){
+                    return 1 / 2 * t * t * t;
+                }
+                return 1 / 2 * ((t -= 2) * t * t + 2);
+            },
+            easeInQuart: function (t) {
+                return t * t * t * t;
+            },
+            easeOutQuart: function (t) {
+                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;
+                }
+                return -1 / 2 * ((t -= 2) * t * t * t - 2);
+            },
+            easeInQuint: function (t) {
+                return 1 * (t /= 1) * t * t * t * t;
+            },
+            easeOutQuint: function (t) {
+                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;
+                }
+                return 1 / 2 * ((t -= 2) * t * t * t * t + 2);
+            },
+            easeInSine: function (t) {
+                return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;
+            },
+            easeOutSine: function (t) {
+                return 1 * Math.sin(t / 1 * (Math.PI / 2));
+            },
+            easeInOutSine: function (t) {
+                return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);
+            },
+            easeInExpo: function (t) {
+                return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));
+            },
+            easeOutExpo: function (t) {
+                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));
+                }
+                return 1 / 2 * (-Math.pow(2, -10 * --t) + 2);
+            },
+            easeInCirc: function (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);
+                }
+                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 (a < Math.abs(1)) {
+                    a = 1;
+                    s = p / 4;
+                } 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 (a < Math.abs(1)) {
+                    a = 1;
+                    s = p / 4;
+                } 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 (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));}
+                return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;
+            },
+            easeInBack: function (t) {
+                var s = 1.70158;
+                return 1 * (t /= 1) * t * ((s + 1) * t - s);
+            },
+            easeOutBack: function (t) {
+                var s = 1.70158;
+                return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);
+            },
+            easeInOutBack: function (t) {
+                var s = 1.70158;
+                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) {
+                return 1 - easingEffects.easeOutBounce(1 - t);
+            },
+            easeOutBounce: function (t) {
+                if ((t /= 1) < (1 / 2.75)) {
+                    return 1 * (7.5625 * t * t);
+                } else if (t < (2 / 2.75)) {
+                    return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);
+                } else if (t < (2.5 / 2.75)) {
+                    return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);
+                } else {
+                    return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);
+                }
+            },
+            easeInOutBounce: function (t) {
+                if (t < 1 / 2){
+                    return easingEffects.easeInBounce(t * 2) * 0.5;
+                }
+                return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;
+            }
+        },
+        //Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
+        requestAnimFrame = helpers.requestAnimFrame = (function(){
+            return window.requestAnimationFrame ||
+                window.webkitRequestAnimationFrame ||
+                window.mozRequestAnimationFrame ||
+                window.oRequestAnimationFrame ||
+                window.msRequestAnimationFrame ||
+                function(callback) {
+                    return window.setTimeout(callback, 1000 / 60);
+                };
+        })(),
+        cancelAnimFrame = helpers.cancelAnimFrame = (function(){
+            return window.cancelAnimationFrame ||
+                window.webkitCancelAnimationFrame ||
+                window.mozCancelAnimationFrame ||
+                window.oCancelAnimationFrame ||
+                window.msCancelAnimationFrame ||
+                function(callback) {
+                    return window.clearTimeout(callback, 1000 / 60);
+                };
+        })(),
+        animationLoop = helpers.animationLoop = function(callback,totalSteps,easingString,onProgress,onComplete,chartInstance){
+
+            var currentStep = 0,
+                easingFunction = easingEffects[easingString] || easingEffects.linear;
+
+            var animationFrame = function(){
+                currentStep++;
+                var stepDecimal = currentStep/totalSteps;
+                var easeDecimal = easingFunction(stepDecimal);
+
+                callback.call(chartInstance,easeDecimal,stepDecimal, currentStep);
+                onProgress.call(chartInstance,easeDecimal,stepDecimal);
+                if (currentStep < totalSteps){
+                    chartInstance.animationFrame = requestAnimFrame(animationFrame);
+                } else{
+                    onComplete.apply(chartInstance);
+                }
+            };
+            requestAnimFrame(animationFrame);
+        },
+        //-- DOM methods
+        getRelativePosition = helpers.getRelativePosition = function(evt){
+            var mouseX, mouseY;
+            var e = evt.originalEvent || evt,
+                canvas = evt.currentTarget || evt.srcElement,
+                boundingRect = canvas.getBoundingClientRect();
+
+            if (e.touches){
+                mouseX = e.touches[0].clientX - boundingRect.left;
+                mouseY = e.touches[0].clientY - boundingRect.top;
+
+            }
+            else{
+                mouseX = e.clientX - boundingRect.left;
+                mouseY = e.clientY - boundingRect.top;
+            }
+
+            return {
+                x : mouseX,
+                y : mouseY
+            };
+
+        },
+        addEvent = helpers.addEvent = function(node,eventType,method){
+            if (node.addEventListener){
+                node.addEventListener(eventType,method);
+            } else if (node.attachEvent){
+                node.attachEvent("on"+eventType, method);
+            } else {
+                node["on"+eventType] = method;
+            }
+        },
+        removeEvent = helpers.removeEvent = function(node, eventType, handler){
+            if (node.removeEventListener){
+                node.removeEventListener(eventType, handler, false);
+            } else if (node.detachEvent){
+                node.detachEvent("on"+eventType,handler);
+            } else{
+                node["on" + eventType] = noop;
+            }
+        },
+        bindEvents = helpers.bindEvents = function(chartInstance, arrayOfEvents, handler){
+            // Create the events object if it's not already present
+            if (!chartInstance.events) chartInstance.events = {};
+
+            each(arrayOfEvents,function(eventName){
+                chartInstance.events[eventName] = function(){
+                    handler.apply(chartInstance, arguments);
+                };
+                addEvent(chartInstance.chart.canvas,eventName,chartInstance.events[eventName]);
+            });
+        },
+        unbindEvents = helpers.unbindEvents = function (chartInstance, arrayOfEvents) {
+            each(arrayOfEvents, function(handler,eventName){
+                removeEvent(chartInstance.chart.canvas, eventName, handler);
+            });
+        },
+        getMaximumWidth = helpers.getMaximumWidth = function(domNode){
+            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 - padding;
+        },
+        getMaximumHeight = helpers.getMaximumHeight = function(domNode){
+            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 - padding;
+        },
+        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){
+            var ctx = chart.ctx,
+                width = chart.canvas.width,
+                height = chart.canvas.height;
+
+            if (window.devicePixelRatio) {
+                ctx.canvas.style.width = width + "px";
+                ctx.canvas.style.height = height + "px";
+                ctx.canvas.height = height * window.devicePixelRatio;
+                ctx.canvas.width = width * window.devicePixelRatio;
+                ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
+            }
+        },
+        //-- Canvas methods
+        clear = helpers.clear = function(chart){
+            chart.ctx.clearRect(0,0,chart.width,chart.height);
+        },
+        fontString = helpers.fontString = function(pixelSize,fontStyle,fontFamily){
+            return fontStyle + " " + pixelSize+"px " + fontFamily;
+        },
+        longestText = helpers.longestText = function(ctx,font,arrayOfStrings){
+            ctx.font = font;
+            var longest = 0;
+            each(arrayOfStrings,function(string){
+                var textWidth = ctx.measureText(string).width;
+                longest = (textWidth > longest) ? textWidth : longest;
+            });
+            return longest;
+        },
+        drawRoundedRectangle = helpers.drawRoundedRectangle = function(ctx,x,y,width,height,radius){
+            ctx.beginPath();
+            ctx.moveTo(x + radius, y);
+            ctx.lineTo(x + width - radius, y);
+            ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
+            ctx.lineTo(x + width, y + height - radius);
+            ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
+            ctx.lineTo(x + radius, y + height);
+            ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
+            ctx.lineTo(x, y + radius);
+            ctx.quadraticCurveTo(x, y, x + radius, y);
+            ctx.closePath();
+        };
+
+
+    //Store a reference to each instance - allowing us to globally resize chart instances on window resize.
+    //Destroy method on the chart will remove the instance of the chart from this reference.
+    Chart.instances = {};
+
+    Chart.Type = function(data,options,chart){
+        this.options = options;
+        this.chart = chart;
+        this.id = uid();
+        //Add the chart instance to the global namespace
+        Chart.instances[this.id] = this;
+
+        // Initialize is always called when a chart type is created
+        // By default it is a no op, but it should be extended
+        if (options.responsive){
+            this.resize();
+        }
+        this.initialize.call(this,data);
+    };
+
+    //Core methods that'll be a part of every chart type
+    extend(Chart.Type.prototype,{
+        initialize : function(){return this;},
+        clear : function(){
+            clear(this.chart);
+            return this;
+        },
+        stop : function(){
+            // Stops any current animation loop occuring
+            Chart.animationService.cancelAnimation(this);
+            return this;
+        },
+        resize : function(callback){
+            this.stop();
+            var canvas = this.chart.canvas,
+                newWidth = getMaximumWidth(this.chart.canvas),
+                newHeight = this.options.maintainAspectRatio ? newWidth / this.chart.aspectRatio : getMaximumHeight(this.chart.canvas);
+
+            canvas.width = this.chart.width = newWidth;
+            canvas.height = this.chart.height = newHeight;
+
+            retinaScale(this.chart);
+
+            if (typeof callback === "function"){
+                callback.apply(this, Array.prototype.slice.call(arguments, 1));
+            }
+            return this;
+        },
+        reflow : noop,
+        render : function(reflow){
+            if (reflow){
+                this.reflow();
+            }
+
+            if (this.options.animation && !reflow){
+                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();
+                this.options.onAnimationComplete.call(this);
+            }
+            return this;
+        },
+        generateLegend : function(){
+            return template(this.options.legendTemplate,this);
+        },
+        destroy : function(){
+            this.clear();
+            unbindEvents(this, this.events);
+            var canvas = this.chart.canvas;
+
+            // Reset canvas height/width attributes starts a fresh with the canvas context
+            canvas.width = this.chart.width;
+            canvas.height = this.chart.height;
+
+            // < IE9 doesn't support removeProperty
+            if (canvas.style.removeProperty) {
+                canvas.style.removeProperty('width');
+                canvas.style.removeProperty('height');
+            } else {
+                canvas.style.removeAttribute('width');
+                canvas.style.removeAttribute('height');
+            }
+
+            delete Chart.instances[this.id];
+        },
+        showTooltip : function(ChartElements, forceRedraw){
+            // Only redraw the chart if we've actually changed what we're hovering on.
+            if (typeof this.activeElements === 'undefined') this.activeElements = [];
+
+            var isChanged = (function(Elements){
+                var changed = false;
+
+                if (Elements.length !== this.activeElements.length){
+                    changed = true;
+                    return changed;
+                }
+
+                each(Elements, function(element, index){
+                    if (element !== this.activeElements[index]){
+                        changed = true;
+                    }
+                }, this);
+                return changed;
+            }).call(this, ChartElements);
+
+            if (!isChanged && !forceRedraw){
+                return;
+            }
+            else{
+                this.activeElements = ChartElements;
+            }
+            this.draw();
+            if(this.options.customTooltips){
+                this.options.customTooltips(false);
+            }
+            if (ChartElements.length > 0){
+                // If we have multiple datasets, show a MultiTooltip for all of the data points at that index
+                if (this.datasets && this.datasets.length > 1) {
+                    var dataArray,
+                        dataIndex;
+
+                    for (var i = this.datasets.length - 1; i >= 0; i--) {
+                        dataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments;
+                        dataIndex = indexOf(dataArray, ChartElements[0]);
+                        if (dataIndex !== -1){
+                            break;
+                        }
+                    }
+                    var tooltipLabels = [],
+                        tooltipColors = [],
+                        medianPosition = (function(index) {
+
+                            // Get all the points at that particular index
+                            var Elements = [],
+                                dataCollection,
+                                xPositions = [],
+                                yPositions = [],
+                                xMax,
+                                yMax,
+                                xMin,
+                                yMin;
+                            helpers.each(this.datasets, function(dataset){
+                                dataCollection = dataset.points || dataset.bars || dataset.segments;
+                                if (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()){
+                                    Elements.push(dataCollection[dataIndex]);
+                                }
+                            });
+
+                            helpers.each(Elements, function(element) {
+                                xPositions.push(element.x);
+                                yPositions.push(element.y);
+
+
+                                //Include any colour information about the element
+                                tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));
+                                tooltipColors.push({
+                                    fill: element._saved.fillColor || element.fillColor,
+                                    stroke: element._saved.strokeColor || element.strokeColor
+                                });
+
+                            }, this);
+
+                            yMin = min(yPositions);
+                            yMax = max(yPositions);
+
+                            xMin = min(xPositions);
+                            xMax = max(xPositions);
+
+                            return {
+                                x: (xMin > this.chart.width/2) ? xMin : xMax,
+                                y: (yMin + yMax)/2
+                            };
+                        }).call(this, dataIndex);
+
+                    new Chart.MultiTooltip({
+                        x: medianPosition.x,
+                        y: medianPosition.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: tooltipLabels,
+                        legendColors: tooltipColors,
+                        legendColorBackground : this.options.multiTooltipKeyBackground,
+                        title: template(this.options.tooltipTitleTemplate,ChartElements[0]),
+                        chart: this.chart,
+                        ctx: this.chart.ctx,
+                        custom: this.options.customTooltips
+                    }).draw();
+
+                } else {
+                    each(ChartElements, function(Element) {
+                        var tooltipPosition = Element.tooltipPosition();
+                        new Chart.Tooltip({
+                            x: Math.round(tooltipPosition.x),
+                            y: Math.round(tooltipPosition.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: template(this.options.tooltipTemplate, Element),
+                            chart: this.chart,
+                            custom: this.options.customTooltips
+                        }).draw();
+                    }, this);
+                }
+            }
+            return this;
+        },
+        toBase64Image : function(){
+            return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);
+        }
+    });
+
+    Chart.Type.extend = function(extensions){
+
+        var parent = this;
+
+        var ChartType = function(){
+            return parent.apply(this,arguments);
+        };
+
+        //Copy the prototype object of the this class
+        ChartType.prototype = clone(parent.prototype);
+        //Now overwrite some of the properties in the base class with the new extensions
+        extend(ChartType.prototype, extensions);
+
+        ChartType.extend = Chart.Type.extend;
+
+        if (extensions.name || parent.prototype.name){
+
+            var chartName = extensions.name || parent.prototype.name;
+            //Assign any potential default values of the new chart type
+
+            //If none are defined, we'll use a clone of the chart type this is being extended from.
+            //I.e. if we extend a line chart, we'll use the defaults from the line chart if our new chart
+            //doesn't define some defaults of their own.
+
+            var baseDefaults = (Chart.defaults[parent.prototype.name]) ? clone(Chart.defaults[parent.prototype.name]) : {};
+
+            Chart.defaults[chartName] = extend(baseDefaults,extensions.defaults);
+
+            Chart.types[chartName] = ChartType;
+
+            //Register this new chart type in the Chart prototype
+            Chart.prototype[chartName] = function(data,options){
+                var config = merge(Chart.defaults.global, Chart.defaults[chartName], options || {});
+                return new ChartType(data,config,this);
+            };
+        } else{
+            warn("Name not provided for this chart, so it hasn't been registered");
+        }
+        return parent;
+    };
+
+    Chart.Element = function(configuration){
+        extend(this,configuration);
+        this.initialize.apply(this,arguments);
+        this.save();
+    };
+    extend(Chart.Element.prototype,{
+        initialize : function(){},
+        restore : function(props){
+            if (!props){
+                extend(this,this._saved);
+            } else {
+                each(props,function(key){
+                    this[key] = this._saved[key];
+                },this);
+            }
+            return this;
+        },
+        save : function(){
+            this._saved = clone(this);
+            delete this._saved._saved;
+            return this;
+        },
+        update : function(newProps){
+            each(newProps,function(value,key){
+                this._saved[key] = this[key];
+                this[key] = value;
+            },this);
+            return this;
+        },
+        transition : function(props,ease){
+            each(props,function(value,key){
+                this[key] = ((value - this._saved[key]) * ease) + this._saved[key];
+            },this);
+            return this;
+        },
+        tooltipPosition : function(){
+            return {
+                x : this.x,
+                y : this.y
+            };
+        },
+        hasValue: function(){
+            return isNumber(this.value);
+        }
+    });
+
+    Chart.Element.extend = inherits;
+
+
+    Chart.Point = Chart.Element.extend({
+        display: true,
+        inRange: function(chartX,chartY){
+            var hitDetectionRange = this.hitDetectionRadius + this.radius;
+            return ((Math.pow(chartX-this.x, 2)+Math.pow(chartY-this.y, 2)) < Math.pow(hitDetectionRange,2));
+        },
+        draw : function(){
+            if (this.display){
+                var ctx = this.ctx;
+                ctx.beginPath();
+
+                ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2);
+                ctx.closePath();
+
+                ctx.strokeStyle = this.strokeColor;
+                ctx.lineWidth = this.strokeWidth;
+
+                ctx.fillStyle = this.fillColor;
+
+                ctx.fill();
+                ctx.stroke();
+            }
+
+
+            //Quick debug for bezier curve splining
+            //Highlights control points and the line between them.
+            //Handy for dev - stripped in the min version.
+
+            // ctx.save();
+            // ctx.fillStyle = "black";
+            // ctx.strokeStyle = "black"
+            // ctx.beginPath();
+            // ctx.arc(this.controlPoints.inner.x,this.controlPoints.inner.y, 2, 0, Math.PI*2);
+            // ctx.fill();
+
+            // ctx.beginPath();
+            // ctx.arc(this.controlPoints.outer.x,this.controlPoints.outer.y, 2, 0, Math.PI*2);
+            // ctx.fill();
+
+            // ctx.moveTo(this.controlPoints.inner.x,this.controlPoints.inner.y);
+            // ctx.lineTo(this.x, this.y);
+            // ctx.lineTo(this.controlPoints.outer.x,this.controlPoints.outer.y);
+            // ctx.stroke();
+
+            // ctx.restore();
+
+
+
+        }
+    });
+
+    Chart.Arc = Chart.Element.extend({
+        inRange : function(chartX,chartY){
+
+            var pointRelativePosition = helpers.getAngleFromPoint(this, {
+                x: chartX,
+                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 withinRadius = (pointRelativePosition.distance >= this.innerRadius && pointRelativePosition.distance <= this.outerRadius);
+
+            return (betweenAngles && withinRadius);
+            //Ensure within the outside of the arc centre, but inside arc outer
+        },
+        tooltipPosition : function(){
+            var centreAngle = this.startAngle + ((this.endAngle - this.startAngle) / 2),
+                rangeFromCentre = (this.outerRadius - this.innerRadius) / 2 + this.innerRadius;
+            return {
+                x : this.x + (Math.cos(centreAngle) * rangeFromCentre),
+                y : this.y + (Math.sin(centreAngle) * rangeFromCentre)
+            };
+        },
+        draw : function(animationPercent){
+
+            var easingDecimal = animationPercent || 1;
+
+            var ctx = this.ctx;
+
+            ctx.beginPath();
+
+            ctx.arc(this.x, this.y, this.outerRadius < 0 ? 0 : this.outerRadius, this.startAngle, this.endAngle);
+
+            ctx.arc(this.x, this.y, this.innerRadius < 0 ? 0 : this.innerRadius, this.endAngle, this.startAngle, true);
+
+            ctx.closePath();
+            ctx.strokeStyle = this.strokeColor;
+            ctx.lineWidth = this.strokeWidth;
+
+            ctx.fillStyle = this.fillColor;
+
+            ctx.fill();
+            ctx.lineJoin = 'bevel';
+
+            if (this.showStroke){
+                ctx.stroke();
+            }
+        }
+    });
+
+    Chart.Rectangle = Chart.Element.extend({
+        draw : function(){
+            var ctx = this.ctx,
+                halfWidth = this.width/2,
+                leftX = this.x - halfWidth,
+                rightX = this.x + halfWidth,
+                top = this.base - (this.base - this.y),
+                halfStroke = this.strokeWidth / 2;
+
+            // Canvas doesn't allow us to stroke inside the width so we can
+            // adjust the sizes to fit if we're setting a stroke on the line
+            if (this.showStroke){
+                leftX += halfStroke;
+                rightX -= halfStroke;
+                top += halfStroke;
+            }
+
+            ctx.beginPath();
+
+            ctx.fillStyle = this.fillColor;
+            ctx.strokeStyle = this.strokeColor;
+            ctx.lineWidth = this.strokeWidth;
+
+            // It'd be nice to keep this class totally generic to any rectangle
+            // and simply specify which border to miss out.
+            ctx.moveTo(leftX, this.base);
+            ctx.lineTo(leftX, top);
+            ctx.lineTo(rightX, top);
+            ctx.lineTo(rightX, this.base);
+            ctx.fill();
+            if (this.showStroke){
+                ctx.stroke();
+            }
+        },
+        height : function(){
+            return this.base - this.y;
+        },
+        inRange : function(chartX,chartY){
+            return (chartX >= this.x - this.width/2 && chartX <= this.x + this.width/2) && (chartY >= this.y && chartY <= this.base);
+        }
+    });
+
+    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(){
+
+            var ctx = this.chart.ctx;
+
+            ctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
+
+            this.xAlign = "center";
+            this.yAlign = "above";
+
+            //Distance between the actual element.y position and the start of the tooltip caret
+            var caretPadding = this.caretPadding = 2;
+
+            var tooltipWidth = ctx.measureText(this.text).width + 2*this.xPadding,
+                tooltipRectHeight = this.fontSize + 2*this.yPadding,
+                tooltipHeight = tooltipRectHeight + this.caretHeight + caretPadding;
+
+            if (this.x + tooltipWidth/2 >this.chart.width){
+                this.xAlign = "left";
+            } else if (this.x - tooltipWidth/2 < 0){
+                this.xAlign = "right";
+            }
+
+            if (this.y - tooltipHeight < 0){
+                this.yAlign = "below";
+            }
+
+
+            var tooltipX = this.x - tooltipWidth/2,
+                tooltipY = this.y - tooltipHeight;
+
+            ctx.fillStyle = this.fillColor;
+
+            // Custom Tooltips
+            if(this.custom){
+                this.custom(this);
+            }
+            else{
+                switch(this.yAlign)
+                {
+                case "above":
+                    //Draw a caret above the x/y
+                    ctx.beginPath();
+                    ctx.moveTo(this.x,this.y - caretPadding);
+                    ctx.lineTo(this.x + this.caretHeight, this.y - (caretPadding + this.caretHeight));
+                    ctx.lineTo(this.x - this.caretHeight, this.y - (caretPadding + this.caretHeight));
+                    ctx.closePath();
+                    ctx.fill();
+                    break;
+                case "below":
+                    tooltipY = this.y + caretPadding + this.caretHeight;
+                    //Draw a caret below the x/y
+                    ctx.beginPath();
+                    ctx.moveTo(this.x, this.y + caretPadding);
+                    ctx.lineTo(this.x + this.caretHeight, this.y + caretPadding + this.caretHeight);
+                    ctx.lineTo(this.x - this.caretHeight, this.y + caretPadding + this.caretHeight);
+                    ctx.closePath();
+                    ctx.fill();
+                    break;
+                }
+
+                switch(this.xAlign)
+                {
+                case "left":
+                    tooltipX = this.x - tooltipWidth + (this.cornerRadius + this.caretHeight);
+                    break;
+                case "right":
+                    tooltipX = this.x - (this.cornerRadius + this.caretHeight);
+                    break;
+                }
+
+                drawRoundedRectangle(ctx,tooltipX,tooltipY,tooltipWidth,tooltipRectHeight,this.cornerRadius);
+
+                ctx.fill();
+
+                ctx.fillStyle = this.textColor;
+                ctx.textAlign = "center";
+                ctx.textBaseline = "middle";
+                ctx.fillText(this.text, tooltipX + tooltipWidth/2, tooltipY + tooltipRectHeight/2);
+            }
+        }
+    });
+
+    Chart.MultiTooltip = Chart.Element.extend({
+        initialize : function(){
+            this.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
+
+            this.titleFont = fontString(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 titleWidth = this.ctx.measureText(this.title).width,
+                //Label has a legend square as well so account for this.
+                labelWidth = longestText(this.ctx,this.font,this.labels) + this.fontSize + 3,
+                longestTextWidth = max([labelWidth,titleWidth]);
+
+            this.width = longestTextWidth + (this.xPadding*2);
+
+
+            var halfHeight = this.height/2;
+
+            //Check to ensure the height will fit on the canvas
+            if (this.y - halfHeight < 0 ){
+                this.y = halfHeight;
+            } else if (this.y + halfHeight > this.chart.height){
+                this.y = this.chart.height - halfHeight;
+            }
+
+            //Decide whether to align left or right based on position on canvas
+            if (this.x > this.chart.width/2){
+                this.x -= this.xOffset + this.width;
+            } else {
+                this.x += this.xOffset;
+            }
+
+
+        },
+        getLineHeight : function(index){
+            var baseLineHeight = this.y - (this.height/2) + this.yPadding,
+                afterTitleIndex = index-1;
+
+            //If the index is zero, we're getting the title
+            if (index === 0){
+                return baseLineHeight + this.titleHeight / 3;
+            } else{
+                return baseLineHeight + ((this.fontSize * 1.5 * afterTitleIndex) + this.fontSize / 2) + this.titleHeight;
+            }
+
+        },
+        draw : function(){
+            // Custom Tooltips
+            if(this.custom){
+                this.custom(this);
+            }
+            else{
+                drawRoundedRectangle(this.ctx,this.x,this.y - this.height/2,this.width,this.height,this.cornerRadius);
+                var ctx = this.ctx;
+                ctx.fillStyle = this.fillColor;
+                ctx.fill();
+                ctx.closePath();
+
+                ctx.textAlign = "left";
+                ctx.textBaseline = "middle";
+                ctx.fillStyle = this.titleTextColor;
+                ctx.font = this.titleFont;
+
+                ctx.fillText(this.title,this.x + this.xPadding, this.getLineHeight(0));
+
+                ctx.font = this.font;
+                helpers.each(this.labels,function(label,index){
+                    ctx.fillStyle = this.textColor;
+                    ctx.fillText(label,this.x + this.xPadding + this.fontSize + 3, this.getLineHeight(index + 1));
+
+                    //A bit gnarly, but clearing this rectangle breaks when using explorercanvas (clears whole canvas)
+                    //ctx.clearRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
+                    //Instead we'll make a white filled block to put the legendColour palette over.
+
+                    ctx.fillStyle = this.legendColorBackground;
+                    ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
+
+                    ctx.fillStyle = this.legendColors[index].fill;
+                    ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
+
+
+                },this);
+            }
+        }
+    });
+
+    Chart.Scale = Chart.Element.extend({
+        initialize : function(){
+            this.fit();
+        },
+        buildYLabels : function(){
+            this.yLabels = [];
+
+            var stepDecimalPlaces = getDecimalPlaces(this.stepValue);
+
+            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) + 10 : 0;
+        },
+        addXLabel : function(label){
+            this.xLabels.push(label);
+            this.valuesCount++;
+            this.fit();
+        },
+        removeXLabel : function(){
+            this.xLabels.shift();
+            this.valuesCount--;
+            this.fit();
+        },
+        // Fitting loop to rotate x Labels and figure out what fits there, and also calculate how many Y steps to use
+        fit: function(){
+            // First we need the width of the yLabels, assuming the xLabels aren't rotated
+
+            // To do that we need the base line at the top and base of the chart, assuming there is no x label rotation
+            this.startPoint = (this.display) ? this.fontSize : 0;
+            this.endPoint = (this.display) ? this.height - (this.fontSize * 1.5) - 5 : this.height; // -5 to pad labels
+
+            // Apply padding settings to the start and end point.
+            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;
+
+            // Build the current yLabels so we have an idea of what size they'll be to start
+            /*
+             *	This sets what is returned from calculateScaleRange as static properties of this class:
+             *
+                this.steps;
+                this.stepValue;
+                this.min;
+                this.max;
+             *
+             */
+            this.calculateYRange(cachedHeight);
+
+            // With these properties set we can now build the array of yLabels
+            // and also the width of the largest yLabel
+            this.buildYLabels();
+
+            this.calculateXLabelRotation();
+
+            while((cachedHeight > this.endPoint - this.startPoint)){
+                cachedHeight = this.endPoint - this.startPoint;
+                cachedYLabelWidth = this.yLabelWidth;
+
+                this.calculateYRange(cachedHeight);
+                this.buildYLabels();
+
+                // Only go through the xLabel loop again if the yLabel width has changed
+                if (cachedYLabelWidth < this.yLabelWidth){
+                    this.endPoint = cachedEndPoint;
+                    this.calculateXLabelRotation();
+                }
+            }
+
+        },
+        calculateXLabelRotation : function(){
+            //Get the width of each grid by calculating the difference
+            //between x offsets between 0 and 1.
+
+            this.ctx.font = this.font;
+
+            var firstWidth = this.ctx.measureText(this.xLabels[0]).width,
+                lastWidth = this.ctx.measureText(this.xLabels[this.xLabels.length - 1]).width,
+                firstRotated,
+                lastRotated;
+
+
+            this.xScalePaddingRight = lastWidth/2 + 3;
+            this.xScalePaddingLeft = (firstWidth/2 > this.yLabelWidth) ? firstWidth/2 : this.yLabelWidth;
+
+            this.xLabelRotation = 0;
+            if (this.display){
+                var originalLabelWidth = longestText(this.ctx,this.font,this.xLabels),
+                    cosRotation,
+                    firstRotatedWidth;
+                this.xLabelWidth = originalLabelWidth;
+                //Allow 3 pixels x2 padding either side for label readability
+                var xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6;
+
+                //Max label rotate should be 90 - also act as a loop counter
+                while ((this.xLabelWidth > xGridWidth && this.xLabelRotation === 0) || (this.xLabelWidth > xGridWidth && this.xLabelRotation <= 90 && this.xLabelRotation > 0)){
+                    cosRotation = Math.cos(toRadians(this.xLabelRotation));
+
+                    firstRotated = cosRotation * firstWidth;
+                    lastRotated = cosRotation * lastWidth;
+
+                    // We're right aligning the text now.
+                    if (firstRotated + this.fontSize / 2 > this.yLabelWidth){
+                        this.xScalePaddingLeft = firstRotated + this.fontSize / 2;
+                    }
+                    this.xScalePaddingRight = this.fontSize/2;
+
+
+                    this.xLabelRotation++;
+                    this.xLabelWidth = cosRotation * originalLabelWidth;
+
+                }
+                if (this.xLabelRotation > 0){
+                    this.endPoint -= Math.sin(toRadians(this.xLabelRotation))*originalLabelWidth + 3;
+                }
+            }
+            else{
+                this.xLabelWidth = 0;
+                this.xScalePaddingRight = this.padding;
+                this.xScalePaddingLeft = this.padding;
+            }
+
+        },
+        // Needs to be overidden in each Chart type
+        // Otherwise we need to pass all the data into the scale class
+        calculateYRange: noop,
+        drawingArea: function(){
+            return this.startPoint - this.endPoint;
+        },
+        calculateY : function(value){
+            var scalingFactor = this.drawingArea() / (this.min - this.max);
+            return this.endPoint - (scalingFactor * (value - this.min));
+        },
+        calculateX : function(index){
+            var isRotated = (this.xLabelRotation > 0),
+                // innerWidth = (this.offsetGridLines) ? this.width - offsetLeft - this.padding : this.width - (offsetLeft + halfLabelWidth * 2) - this.padding,
+                innerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight),
+                valueWidth = innerWidth/Math.max((this.valuesCount - ((this.offsetGridLines) ? 0 : 1)), 1),
+                valueOffset = (valueWidth * index) + this.xScalePaddingLeft;
+
+            if (this.offsetGridLines){
+                valueOffset += (valueWidth/2);
+            }
+
+            return Math.round(valueOffset);
+        },
+        update : function(newProps){
+            helpers.extend(this, newProps);
+            this.fit();
+        },
+        draw : function(){
+            var ctx = this.ctx,
+                yLabelGap = (this.endPoint - this.startPoint) / this.steps,
+                xStart = Math.round(this.xScalePaddingLeft);
+            if (this.display){
+                ctx.fillStyle = this.textColor;
+                ctx.font = this.font;
+                each(this.yLabels,function(labelString,index){
+                    var yLabelCenter = this.endPoint - (yLabelGap * index),
+                        linePositionY = Math.round(yLabelCenter),
+                        drawHorizontalLine = this.showHorizontalLines;
+
+                    ctx.textAlign = "right";
+                    ctx.textBaseline = "middle";
+                    if (this.showLabels){
+                        ctx.fillText(labelString,xStart - 10,yLabelCenter);
+                    }
+
+                    // This is X axis, so draw it
+                    if (index === 0 && !drawHorizontalLine){
+                        drawHorizontalLine = true;
+                    }
+
+                    if (drawHorizontalLine){
+                        ctx.beginPath();
+                    }
+
+                    if (index > 0){
+                        // This is a grid line in the centre, so drop that
+                        ctx.lineWidth = this.gridLineWidth;
+                        ctx.strokeStyle = this.gridLineColor;
+                    } else {
+                        // This is the first line on the scale
+                        ctx.lineWidth = this.lineWidth;
+                        ctx.strokeStyle = this.lineColor;
+                    }
+
+                    linePositionY += helpers.aliasPixel(ctx.lineWidth);
+
+                    if(drawHorizontalLine){
+                        ctx.moveTo(xStart, linePositionY);
+                        ctx.lineTo(this.width, linePositionY);
+                        ctx.stroke();
+                        ctx.closePath();
+                    }
+
+                    ctx.lineWidth = this.lineWidth;
+                    ctx.strokeStyle = this.lineColor;
+                    ctx.beginPath();
+                    ctx.moveTo(xStart - 5, linePositionY);
+                    ctx.lineTo(xStart, linePositionY);
+                    ctx.stroke();
+                    ctx.closePath();
+
+                },this);
+
+                each(this.xLabels,function(label,index){
+                    var xPos = this.calculateX(index) + aliasPixel(this.lineWidth),
+                        // Check to see if line/bar here and decide where to place the line
+                        linePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth),
+                        isRotated = (this.xLabelRotation > 0),
+                        drawVerticalLine = this.showVerticalLines;
+
+                    // This is Y axis, so draw it
+                    if (index === 0 && !drawVerticalLine){
+                        drawVerticalLine = true;
+                    }
+
+                    if (drawVerticalLine){
+                        ctx.beginPath();
+                    }
+
+                    if (index > 0){
+                        // This is a grid line in the centre, so drop that
+                        ctx.lineWidth = this.gridLineWidth;
+                        ctx.strokeStyle = this.gridLineColor;
+                    } else {
+                        // This is the first line on the scale
+                        ctx.lineWidth = this.lineWidth;
+                        ctx.strokeStyle = this.lineColor;
+                    }
+
+                    if (drawVerticalLine){
+                        ctx.moveTo(linePos,this.endPoint);
+                        ctx.lineTo(linePos,this.startPoint - 3);
+                        ctx.stroke();
+                        ctx.closePath();
+                    }
+
+
+                    ctx.lineWidth = this.lineWidth;
+                    ctx.strokeStyle = this.lineColor;
+
+
+                    // Small lines at the bottom of the base grid line
+                    ctx.beginPath();
+                    ctx.moveTo(linePos,this.endPoint);
+                    ctx.lineTo(linePos,this.endPoint + 5);
+                    ctx.stroke();
+                    ctx.closePath();
+
+                    ctx.save();
+                    ctx.translate(xPos,(isRotated) ? this.endPoint + 12 : this.endPoint + 8);
+                    ctx.rotate(toRadians(this.xLabelRotation)*-1);
+                    ctx.font = this.font;
+                    ctx.textAlign = (isRotated) ? "right" : "center";
+                    ctx.textBaseline = (isRotated) ? "middle" : "top";
+                    ctx.fillText(label, 0, 0);
+                    ctx.restore();
+                },this);
+
+            }
+        }
+
+    });
+
+    Chart.RadialScale = Chart.Element.extend({
+        initialize: function(){
+            this.size = min([this.height, this.width]);
+            this.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);
+        },
+        calculateCenterOffset: function(value){
+            // Take into account half font size + the yPadding of the top value
+            var scalingFactor = this.drawingArea / (this.max - this.min);
+
+            return (value - this.min) * scalingFactor;
+        },
+        update : function(){
+            if (!this.lineArc){
+                this.setScaleSize();
+            } else {
+                this.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);
+            }
+            this.buildYLabels();
+        },
+        buildYLabels: function(){
+            this.yLabels = [];
+
+            var stepDecimalPlaces = getDecimalPlaces(this.stepValue);
+
+            for (var i=0; i<=this.steps; i++){
+                this.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));
+            }
+        },
+        getCircumference : function(){
+            return ((Math.PI*2) / this.valuesCount);
+        },
+        setScaleSize: function(){
+            /*
+             * Right, this is really confusing and there is a lot of maths going on here
+             * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9
+             *
+             * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif
+             *
+             * Solution:
+             *
+             * We assume the radius of the polygon is half the size of the canvas at first
+             * at each index we check if the text overlaps.
+             *
+             * Where it does, we store that angle and that index.
+             *
+             * After finding the largest index and angle we calculate how much we need to remove
+             * from the shape radius to move the point inwards by that x.
+             *
+             * We average the left and right distances to get the maximum shape radius that can fit in the box
+             * along with labels.
+             *
+             * Once we have that, we can find the centre point for the chart, by taking the x text protrusion
+             * on each side, removing that from the size, halving it and adding the left x protrusion width.
+             *
+             * This will mean we have a shape fitted to the canvas, as large as it can be with the labels
+             * and position it in the most space efficient manner
+             *
+             * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif
+             */
+
+
+            // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.
+            // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points
+            var largestPossibleRadius = min([(this.height/2 - this.pointLabelFontSize - 5), this.width/2]),
+                pointPosition,
+                i,
+                textWidth,
+                halfTextWidth,
+                furthestRight = this.width,
+                furthestRightIndex,
+                furthestRightAngle,
+                furthestLeft = 0,
+                furthestLeftIndex,
+                furthestLeftAngle,
+                xProtrusionLeft,
+                xProtrusionRight,
+                radiusReductionRight,
+                radiusReductionLeft,
+                maxWidthRadius;
+            this.ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);
+            for (i=0;i<this.valuesCount;i++){
+                // 5px to space the text slightly out - similar to what we do in the draw function.
+                pointPosition = this.getPointPosition(i, largestPossibleRadius);
+                textWidth = this.ctx.measureText(template(this.templateString, { value: this.labels[i] })).width + 5;
+                if (i === 0 || i === this.valuesCount/2){
+                    // If we're at index zero, or exactly the middle, we're at exactly the top/bottom
+                    // of the radar chart, so text will be aligned centrally, so we'll half it and compare
+                    // w/left and right text sizes
+                    halfTextWidth = textWidth/2;
+                    if (pointPosition.x + halfTextWidth > furthestRight) {
+                        furthestRight = pointPosition.x + halfTextWidth;
+                        furthestRightIndex = i;
+                    }
+                    if (pointPosition.x - halfTextWidth < furthestLeft) {
+                        furthestLeft = pointPosition.x - halfTextWidth;
+                        furthestLeftIndex = i;
+                    }
+                }
+                else if (i < this.valuesCount/2) {
+                    // Less than half the values means we'll left align the text
+                    if (pointPosition.x + textWidth > furthestRight) {
+                        furthestRight = pointPosition.x + textWidth;
+                        furthestRightIndex = i;
+                    }
+                }
+                else if (i > this.valuesCount/2){
+                    // More than half the values means we'll right align the text
+                    if (pointPosition.x - textWidth < furthestLeft) {
+                        furthestLeft = pointPosition.x - textWidth;
+                        furthestLeftIndex = i;
+                    }
+                }
+            }
+
+            xProtrusionLeft = furthestLeft;
+
+            xProtrusionRight = Math.ceil(furthestRight - this.width);
+
+            furthestRightAngle = this.getIndexAngle(furthestRightIndex);
+
+            furthestLeftAngle = this.getIndexAngle(furthestLeftIndex);
+
+            radiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI/2);
+
+            radiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI/2);
+
+            // Ensure we actually need to reduce the size of the chart
+            radiusReductionRight = (isNumber(radiusReductionRight)) ? radiusReductionRight : 0;
+            radiusReductionLeft = (isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0;
+
+            this.drawingArea = largestPossibleRadius - (radiusReductionLeft + radiusReductionRight)/2;
+
+            //this.drawingArea = min([maxWidthRadius, (this.height - (2 * (this.pointLabelFontSize + 5)))/2])
+            this.setCenterPoint(radiusReductionLeft, radiusReductionRight);
+
+        },
+        setCenterPoint: function(leftMovement, rightMovement){
+
+            var maxRight = this.width - rightMovement - this.drawingArea,
+                maxLeft = leftMovement + this.drawingArea;
+
+            this.xCenter = (maxLeft + maxRight)/2;
+            // Always vertically in the centre as the text height doesn't change
+            this.yCenter = (this.height/2);
+        },
+
+        getIndexAngle : function(index){
+            var angleMultiplier = (Math.PI * 2) / this.valuesCount;
+            // Start from the top instead of right, so remove a quarter of the circle
+
+            return index * angleMultiplier - (Math.PI/2);
+        },
+        getPointPosition : function(index, distanceFromCenter){
+            var thisAngle = this.getIndexAngle(index);
+            return {
+                x : (Math.cos(thisAngle) * distanceFromCenter) + this.xCenter,
+                y : (Math.sin(thisAngle) * distanceFromCenter) + this.yCenter
+            };
+        },
+        draw: function(){
+            if (this.display){
+                var ctx = this.ctx;
+                each(this.yLabels, function(label, index){
+                    // Don't draw a centre value
+                    if (index > 0){
+                        var yCenterOffset = index * (this.drawingArea/this.steps),
+                            yHeight = this.yCenter - yCenterOffset,
+                            pointPosition;
+
+                        // Draw circular lines around the scale
+                        if (this.lineWidth > 0){
+                            ctx.strokeStyle = this.lineColor;
+                            ctx.lineWidth = this.lineWidth;
+
+                            if(this.lineArc){
+                                ctx.beginPath();
+                                ctx.arc(this.xCenter, this.yCenter, yCenterOffset, 0, Math.PI*2);
+                                ctx.closePath();
+                                ctx.stroke();
+                            } else{
+                                ctx.beginPath();
+                                for (var i=0;i<this.valuesCount;i++)
+                                {
+                                    pointPosition = this.getPointPosition(i, this.calculateCenterOffset(this.min + (index * this.stepValue)));
+                                    if (i === 0){
+                                        ctx.moveTo(pointPosition.x, pointPosition.y);
+                                    } else {
+                                        ctx.lineTo(pointPosition.x, pointPosition.y);
+                                    }
+                                }
+                                ctx.closePath();
+                                ctx.stroke();
+                            }
+                        }
+                        if(this.showLabels){
+                            ctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
+                            if (this.showLabelBackdrop){
+                                var labelWidth = ctx.measureText(label).width;
+                                ctx.fillStyle = this.backdropColor;
+                                ctx.fillRect(
+                                    this.xCenter - labelWidth/2 - this.backdropPaddingX,
+                                    yHeight - this.fontSize/2 - this.backdropPaddingY,
+                                    labelWidth + this.backdropPaddingX*2,
+                                    this.fontSize + this.backdropPaddingY*2
+                                );
+                            }
+                            ctx.textAlign = 'center';
+                            ctx.textBaseline = "middle";
+                            ctx.fillStyle = this.fontColor;
+                            ctx.fillText(label, this.xCenter, yHeight);
+                        }
+                    }
+                }, this);
+
+                if (!this.lineArc){
+                    ctx.lineWidth = this.angleLineWidth;
+                    ctx.strokeStyle = this.angleLineColor;
+                    for (var i = this.valuesCount - 1; i >= 0; i--) {
+                        var centerOffset = null, outerPosition = null;
+
+                        if (this.angleLineWidth > 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);
+                        ctx.fillStyle = this.pointLabelFontColor;
+
+                        var labelsCount = this.labels.length,
+                            halfLabelsCount = this.labels.length/2,
+                            quarterLabelsCount = halfLabelsCount/2,
+                            upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),
+                            exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);
+                        if (i === 0){
+                            ctx.textAlign = 'center';
+                        } else if(i === halfLabelsCount){
+                            ctx.textAlign = 'center';
+                        } else if (i < halfLabelsCount){
+                            ctx.textAlign = 'left';
+                        } else {
+                            ctx.textAlign = 'right';
+                        }
+
+                        // Set the correct text baseline based on outer positioning
+                        if (exactQuarter){
+                            ctx.textBaseline = 'middle';
+                        } else if (upperHalf){
+                            ctx.textBaseline = 'bottom';
+                        } else {
+                            ctx.textBaseline = 'top';
+                        }
+
+                        ctx.fillText(this.labels[i], pointLabelPosition.x, pointLabelPosition.y);
+                    }
+                }
+            }
+        }
+    });
+
+    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.
+        var timeout;
+        return function(){
+            clearTimeout(timeout);
+            timeout = setTimeout(function(){
+                each(Chart.instances,function(instance){
+                    // If the responsive flag is set in the chart instance config
+                    // Cascade the resize event down to the chart.
+                    if (instance.options.responsive){
+                        instance.resize(instance.render, true);
+                    }
+                });
+            }, 50);
+        };
+    })());
+
+
+    if (amd) {
+        define(function(){
+            return Chart;
+        });
+    } else if (typeof module === 'object' && module.exports) {
+        module.exports = Chart;
+    }
+
+    root.Chart = Chart;
+
+    Chart.noConflict = function(){
+        root.Chart = previous;
+        return Chart;
+    };
+
+}).call(this);
+
+(function(){
+    "use strict";
+
+    var root = this,
+        Chart = root.Chart,
+        helpers = Chart.helpers;
+
+
+    var defaultConfig = {
+        //Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
+        scaleBeginAtZero : true,
+
+        //Boolean - Whether grid lines are shown across the chart
+        scaleShowGridLines : true,
+
+        //String - Colour of the grid lines
+        scaleGridLineColor : "rgba(0,0,0,.05)",
+
+        //Number - Width of the grid lines
+        scaleGridLineWidth : 1,
+
+        //Boolean - Whether to show horizontal lines (except X axis)
+        scaleShowHorizontalLines: true,
+
+        //Boolean - Whether to show vertical lines (except Y axis)
+        scaleShowVerticalLines: true,
+
+        //Boolean - If there is a stroke on each bar
+        barShowStroke : true,
+
+        //Number - Pixel width of the bar stroke
+        barStrokeWidth : 2,
+
+        //Number - Spacing between each of the X value sets
+        barValueSpacing : 5,
+
+        //Number - Spacing between data sets within X values
+        barDatasetSpacing : 1,
+
+        //String - A legend template
+        legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].fillColor%>\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>"
+
+    };
+
+
+    Chart.Type.extend({
+        name: "Bar",
+        defaults : defaultConfig,
+        initialize:  function(data){
+
+            //Expose options as a scope variable here so we can access it in the ScaleClass
+            var options = this.options;
+
+            this.ScaleClass = Chart.Scale.extend({
+                offsetGridLines : true,
+                calculateBarX : function(datasetCount, datasetIndex, barIndex){
+                    //Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar
+                    var xWidth = this.calculateBaseWidth(),
+                        xAbsolute = this.calculateX(barIndex) - (xWidth/2),
+                        barWidth = this.calculateBarWidth(datasetCount);
+
+                    return xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth/2;
+                },
+                calculateBaseWidth : function(){
+                    return (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing);
+                },
+                calculateBarWidth : function(datasetCount){
+                    //The padding between datasets is to the right of each bar, providing that there are more than 1 dataset
+                    var baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing);
+
+                    return (baseWidth / datasetCount);
+                }
+            });
+
+            this.datasets = [];
+
+            //Set up tooltip events on the chart
+            if (this.options.showTooltips){
+                helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
+                    var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];
+
+                    this.eachBars(function(bar){
+                        bar.restore(['fillColor', 'strokeColor']);
+                    });
+                    helpers.each(activeBars, function(activeBar){
+                        activeBar.fillColor = activeBar.highlightFill;
+                        activeBar.strokeColor = activeBar.highlightStroke;
+                    });
+                    this.showTooltip(activeBars);
+                });
+            }
+
+            //Declare the extension of the default point, to cater for the options passed in to the constructor
+            this.BarClass = Chart.Rectangle.extend({
+                strokeWidth : this.options.barStrokeWidth,
+                showStroke : this.options.barShowStroke,
+                ctx : this.chart.ctx
+            });
+
+            //Iterate through each of the datasets, and build this into a property of the chart
+            helpers.each(data.datasets,function(dataset,datasetIndex){
+
+                var datasetObject = {
+                    label : dataset.label || null,
+                    fillColor : dataset.fillColor,
+                    strokeColor : dataset.strokeColor,
+                    bars : []
+                };
+
+                this.datasets.push(datasetObject);
+
+                helpers.each(dataset.data,function(dataPoint,index){
+                    //Add a new point for each piece of data, passing any required data to draw.
+                    datasetObject.bars.push(new this.BarClass({
+                        value : dataPoint,
+                        label : data.labels[index],
+                        datasetLabel: dataset.label,
+                        strokeColor : dataset.strokeColor,
+                        fillColor : dataset.fillColor,
+                        highlightFill : dataset.highlightFill || dataset.fillColor,
+                        highlightStroke : dataset.highlightStroke || dataset.strokeColor
+                    }));
+                },this);
+
+            },this);
+
+            this.buildScale(data.labels);
+
+            this.BarClass.prototype.base = this.scale.endPoint;
+
+            this.eachBars(function(bar, index, datasetIndex){
+                helpers.extend(bar, {
+                    width : this.scale.calculateBarWidth(this.datasets.length),
+                    x: this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
+                    y: this.scale.endPoint
+                });
+                bar.save();
+            }, this);
+
+            this.render();
+        },
+        update : function(){
+            this.scale.update();
+            // Reset any highlight colours before updating.
+            helpers.each(this.activeElements, function(activeElement){
+                activeElement.restore(['fillColor', 'strokeColor']);
+            });
+
+            this.eachBars(function(bar){
+                bar.save();
+            });
+            this.render();
+        },
+        eachBars : function(callback){
+            helpers.each(this.datasets,function(dataset, datasetIndex){
+                helpers.each(dataset.bars, callback, this, datasetIndex);
+            },this);
+        },
+        getBarsAtEvent : function(e){
+            var barsArray = [],
+                eventPosition = helpers.getRelativePosition(e),
+                datasetIterator = function(dataset){
+                    barsArray.push(dataset.bars[barIndex]);
+                },
+                barIndex;
+
+            for (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {
+                for (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {
+                    if (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){
+                        helpers.each(this.datasets, datasetIterator);
+                        return barsArray;
+                    }
+                }
+            }
+
+            return barsArray;
+        },
+        buildScale : function(labels){
+            var self = this;
+
+            var dataTotal = function(){
+                var values = [];
+                self.eachBars(function(bar){
+                    values.push(bar.value);
+                });
+                return values;
+            };
+
+            var scaleOptions = {
+                templateString : this.options.scaleLabel,
+                height : this.chart.height,
+                width : this.chart.width,
+                ctx : this.chart.ctx,
+                textColor : this.options.scaleFontColor,
+                fontSize : this.options.scaleFontSize,
+                fontStyle : this.options.scaleFontStyle,
+                fontFamily : this.options.scaleFontFamily,
+                valuesCount : labels.length,
+                beginAtZero : this.options.scaleBeginAtZero,
+                integersOnly : this.options.scaleIntegersOnly,
+                calculateYRange: function(currentHeight){
+                    var updatedRanges = helpers.calculateScaleRange(
+                        dataTotal(),
+                        currentHeight,
+                        this.fontSize,
+                        this.beginAtZero,
+                        this.integersOnly
+                    );
+                    helpers.extend(this, updatedRanges);
+                },
+                xLabels : labels,
+                font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
+                lineWidth : this.options.scaleLineWidth,
+                lineColor : this.options.scaleLineColor,
+                showHorizontalLines : this.options.scaleShowHorizontalLines,
+                showVerticalLines : this.options.scaleShowVerticalLines,
+                gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
+                gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
+                padding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,
+                showLabels : this.options.scaleShowLabels,
+                display : this.options.showScale
+            };
+
+            if (this.options.scaleOverride){
+                helpers.extend(scaleOptions, {
+                    calculateYRange: helpers.noop,
+                    steps: this.options.scaleSteps,
+                    stepValue: this.options.scaleStepWidth,
+                    min: this.options.scaleStartValue,
+                    max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
+                });
+            }
+
+            this.scale = new this.ScaleClass(scaleOptions);
+        },
+        addData : function(valuesArray,label){
+            //Map the values array for each of the datasets
+            helpers.each(valuesArray,function(value,datasetIndex){
+                //Add a new point for each piece of data, passing any required data to draw.
+                this.datasets[datasetIndex].bars.push(new this.BarClass({
+                    value : value,
+                    label : label,
+                    datasetLabel: this.datasets[datasetIndex].label,
+                    x: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1),
+                    y: this.scale.endPoint,
+                    width : this.scale.calculateBarWidth(this.datasets.length),
+                    base : this.scale.endPoint,
+                    strokeColor : this.datasets[datasetIndex].strokeColor,
+                    fillColor : this.datasets[datasetIndex].fillColor
+                }));
+            },this);
+
+            this.scale.addXLabel(label);
+            //Then re-render the chart.
+            this.update();
+        },
+        removeData : function(){
+            this.scale.removeXLabel();
+            //Then re-render the chart.
+            helpers.each(this.datasets,function(dataset){
+                dataset.bars.shift();
+            },this);
+            this.update();
+        },
+        reflow : function(){
+            helpers.extend(this.BarClass.prototype,{
+                y: this.scale.endPoint,
+                base : this.scale.endPoint
+            });
+            var newScaleProps = helpers.extend({
+                height : this.chart.height,
+                width : this.chart.width
+            });
+            this.scale.update(newScaleProps);
+        },
+        draw : function(ease){
+            var easingDecimal = ease || 1;
+            this.clear();
+
+            var ctx = this.chart.ctx;
+
+            this.scale.draw(easingDecimal);
+
+            //Draw all the bars for each dataset
+            helpers.each(this.datasets,function(dataset,datasetIndex){
+                helpers.each(dataset.bars,function(bar,index){
+                    if (bar.hasValue()){
+                        bar.base = this.scale.endPoint;
+                        //Transition then draw
+                        bar.transition({
+                            x : this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
+                            y : this.scale.calculateY(bar.value),
+                            width : this.scale.calculateBarWidth(this.datasets.length)
+                        }, easingDecimal).draw();
+                    }
+                },this);
+
+            },this);
+        }
+    });
+
+
+}).call(this);
+
+(function(){
+    "use strict";
+
+    var root = this,
+        Chart = root.Chart,
+        //Cache a local reference to Chart.helpers
+        helpers = Chart.helpers;
+
+    var defaultConfig = {
+        //Boolean - Whether we should show a stroke on each segment
+        segmentShowStroke : true,
+
+        //String - The colour of each segment stroke
+        segmentStrokeColor : "#fff",
+
+        //Number - The width of each segment stroke
+        segmentStrokeWidth : 2,
+
+        //The percentage of the chart that we cut out of the middle.
+        percentageInnerCutout : 50,
+
+        //Number - Amount of animation steps
+        animationSteps : 100,
+
+        //String - Animation easing effect
+        animationEasing : "easeOutBounce",
+
+        //Boolean - Whether we animate the rotation of the Doughnut
+        animateRotate : true,
+
+        //Boolean - Whether we animate scaling the Doughnut from the centre
+        animateScale : false,
+
+        //String - A legend template
+        legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"><%if(segments[i].label){%><%=segments[i].label%><%}%></span></li><%}%></ul>"
+
+    };
+
+    Chart.Type.extend({
+        //Passing in a name registers this chart in the Chart namespace
+        name: "Doughnut",
+        //Providing a defaults will also register the deafults in the chart namespace
+        defaults : defaultConfig,
+        //Initialize is fired when the chart is initialized - Data is passed in as a parameter
+        //Config is automatically merged by the core of Chart.js, and is available at this.options
+        initialize:  function(data){
+
+            //Declare segments as a static property to prevent inheriting across the Chart type prototype
+            this.segments = [];
+            this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) -	this.options.segmentStrokeWidth/2)/2;
+
+            this.SegmentArc = Chart.Arc.extend({
+                ctx : this.chart.ctx,
+                x : this.chart.width/2,
+                y : this.chart.height/2
+            });
+
+            //Set up tooltip events on the chart
+            if (this.options.showTooltips){
+                helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
+                    var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
+
+                    helpers.each(this.segments,function(segment){
+                        segment.restore(["fillColor"]);
+                    });
+                    helpers.each(activeSegments,function(activeSegment){
+                        activeSegment.fillColor = activeSegment.highlightColor;
+                    });
+                    this.showTooltip(activeSegments);
+                });
+            }
+            this.calculateTotal(data);
+
+            helpers.each(data,function(datapoint, index){
+                if (!datapoint.color) {
+                    datapoint.color = 'hsl(' + (360 * index / data.length) + ', 100%, 50%)';
+                }
+                this.addData(datapoint, index, true);
+            },this);
+
+            this.render();
+        },
+        getSegmentsAtEvent : function(e){
+            var segmentsArray = [];
+
+            var location = helpers.getRelativePosition(e);
+
+            helpers.each(this.segments,function(segment){
+                if (segment.inRange(location.x,location.y)) segmentsArray.push(segment);
+            },this);
+            return segmentsArray;
+        },
+        addData : function(segment, atIndex, silent){
+            var index = atIndex !== undefined ? atIndex : this.segments.length;
+            if ( typeof(segment.color) === "undefined" ) {
+                segment.color = Chart.defaults.global.segmentColorDefault[index % Chart.defaults.global.segmentColorDefault.length];
+                segment.highlight = Chart.defaults.global.segmentHighlightColorDefaults[index % Chart.defaults.global.segmentHighlightColorDefaults.length];
+            }
+            this.segments.splice(index, 0, new this.SegmentArc({
+                value : segment.value,
+                outerRadius : (this.options.animateScale) ? 0 : this.outerRadius,
+                innerRadius : (this.options.animateScale) ? 0 : (this.outerRadius/100) * this.options.percentageInnerCutout,
+                fillColor : segment.color,
+                highlightColor : segment.highlight || segment.color,
+                showStroke : this.options.segmentShowStroke,
+                strokeWidth : this.options.segmentStrokeWidth,
+                strokeColor : this.options.segmentStrokeColor,
+                startAngle : Math.PI * 1.5,
+                circumference : (this.options.animateRotate) ? 0 : this.calculateCircumference(segment.value),
+                label : segment.label
+            }));
+            if (!silent){
+                this.reflow();
+                this.update();
+            }
+        },
+        calculateCircumference : function(value) {
+            if ( this.total > 0 ) {
+                return (Math.PI*2)*(value / this.total);
+            } else {
+                return 0;
+            }
+        },
+        calculateTotal : function(data){
+            this.total = 0;
+            helpers.each(data,function(segment){
+                this.total += Math.abs(segment.value);
+            },this);
+        },
+        update : function(){
+            this.calculateTotal(this.segments);
+
+            // Reset any highlight colours before updating.
+            helpers.each(this.activeElements, function(activeElement){
+                activeElement.restore(['fillColor']);
+            });
+
+            helpers.each(this.segments,function(segment){
+                segment.save();
+            });
+            this.render();
+        },
+
+        removeData: function(atIndex){
+            var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
+            this.segments.splice(indexToDelete, 1);
+            this.reflow();
+            this.update();
+        },
+
+        reflow : function(){
+            helpers.extend(this.SegmentArc.prototype,{
+                x : this.chart.width/2,
+                y : this.chart.height/2
+            });
+            this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) -	this.options.segmentStrokeWidth/2)/2;
+            helpers.each(this.segments, function(segment){
+                segment.update({
+                    outerRadius : this.outerRadius,
+                    innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
+                });
+            }, this);
+        },
+        draw : function(easeDecimal){
+            var animDecimal = (easeDecimal) ? easeDecimal : 1;
+            this.clear();
+            helpers.each(this.segments,function(segment,index){
+                segment.transition({
+                    circumference : this.calculateCircumference(segment.value),
+                    outerRadius : this.outerRadius,
+                    innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
+                },animDecimal);
+
+                segment.endAngle = segment.startAngle + segment.circumference;
+
+                segment.draw();
+                if (index === 0){
+                    segment.startAngle = Math.PI * 1.5;
+                }
+                //Check to see if it's the last segment, if not get the next and update the start angle
+                if (index < this.segments.length-1){
+                    this.segments[index+1].startAngle = segment.endAngle;
+                }
+            },this);
+
+        }
+    });
+
+    Chart.types.Doughnut.extend({
+        name : "Pie",
+        defaults : helpers.merge(defaultConfig,{percentageInnerCutout : 0})
+    });
+
+}).call(this);
+
+(function(){
+    "use strict";
+
+    var root = this,
+        Chart = root.Chart,
+        helpers = Chart.helpers;
+
+    var defaultConfig = {
+
+        ///Boolean - Whether grid lines are shown across the chart
+        scaleShowGridLines : true,
+
+        //String - Colour of the grid lines
+        scaleGridLineColor : "rgba(0,0,0,.05)",
+
+        //Number - Width of the grid lines
+        scaleGridLineWidth : 1,
+
+        //Boolean - Whether to show horizontal lines (except X axis)
+        scaleShowHorizontalLines: true,
+
+        //Boolean - Whether to show vertical lines (except Y axis)
+        scaleShowVerticalLines: true,
+
+        //Boolean - Whether the line is curved between points
+        bezierCurve : true,
+
+        //Number - Tension of the bezier curve between points
+        bezierCurveTension : 0.4,
+
+        //Boolean - Whether to show a dot for each point
+        pointDot : true,
+
+        //Number - Radius of each point dot in pixels
+        pointDotRadius : 4,
+
+        //Number - Pixel width of point dot stroke
+        pointDotStrokeWidth : 1,
+
+        //Number - amount extra to add to the radius to cater for hit detection outside the drawn point
+        pointHitDetectionRadius : 20,
+
+        //Boolean - Whether to show a stroke for datasets
+        datasetStroke : true,
+
+        //Number - Pixel width of dataset stroke
+        datasetStrokeWidth : 2,
+
+        //Boolean - Whether to fill the dataset with a colour
+        datasetFill : true,
+
+        //String - A legend template
+        legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>",
+
+        //Boolean - Whether to horizontally center the label and point dot inside the grid
+        offsetGridLines : false
+
+    };
+
+
+    Chart.Type.extend({
+        name: "Line",
+        defaults : defaultConfig,
+        initialize:  function(data){
+            //Declare the extension of the default point, to cater for the options passed in to the constructor
+            this.PointClass = Chart.Point.extend({
+                offsetGridLines : this.options.offsetGridLines,
+                strokeWidth : this.options.pointDotStrokeWidth,
+                radius : this.options.pointDotRadius,
+                display: this.options.pointDot,
+                hitDetectionRadius : this.options.pointHitDetectionRadius,
+                ctx : this.chart.ctx,
+                inRange : function(mouseX){
+                    return (Math.pow(mouseX-this.x, 2) < Math.pow(this.radius + this.hitDetectionRadius,2));
+                }
+            });
+
+            this.datasets = [];
+
+            //Set up tooltip events on the chart
+            if (this.options.showTooltips){
+                helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
+                    var activePoints = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
+                    this.eachPoints(function(point){
+                        point.restore(['fillColor', 'strokeColor']);
+                    });
+                    helpers.each(activePoints, function(activePoint){
+                        activePoint.fillColor = activePoint.highlightFill;
+                        activePoint.strokeColor = activePoint.highlightStroke;
+                    });
+                    this.showTooltip(activePoints);
+                });
+            }
+
+            //Iterate through each of the datasets, and build this into a property of the chart
+            helpers.each(data.datasets,function(dataset){
+
+                var datasetObject = {
+                    label : dataset.label || null,
+                    fillColor : dataset.fillColor,
+                    strokeColor : dataset.strokeColor,
+                    pointColor : dataset.pointColor,
+                    pointStrokeColor : dataset.pointStrokeColor,
+                    points : []
+                };
+
+                this.datasets.push(datasetObject);
+
+
+                helpers.each(dataset.data,function(dataPoint,index){
+                    //Add a new point for each piece of data, passing any required data to draw.
+                    datasetObject.points.push(new this.PointClass({
+                        value : dataPoint,
+                        label : data.labels[index],
+                        datasetLabel: dataset.label,
+                        strokeColor : dataset.pointStrokeColor,
+                        fillColor : dataset.pointColor,
+                        highlightFill : dataset.pointHighlightFill || dataset.pointColor,
+                        highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
+                    }));
+                },this);
+
+                this.buildScale(data.labels);
+
+
+                this.eachPoints(function(point, index){
+                    helpers.extend(point, {
+                        x: this.scale.calculateX(index),
+                        y: this.scale.endPoint
+                    });
+                    point.save();
+                }, this);
+
+            },this);
+
+
+            this.render();
+        },
+        update : function(){
+            this.scale.update();
+            // Reset any highlight colours before updating.
+            helpers.each(this.activeElements, function(activeElement){
+                activeElement.restore(['fillColor', 'strokeColor']);
+            });
+            this.eachPoints(function(point){
+                point.save();
+            });
+            this.render();
+        },
+        eachPoints : function(callback){
+            helpers.each(this.datasets,function(dataset){
+                helpers.each(dataset.points,callback,this);
+            },this);
+        },
+        getPointsAtEvent : function(e){
+            var pointsArray = [],
+                eventPosition = helpers.getRelativePosition(e);
+            helpers.each(this.datasets,function(dataset){
+                helpers.each(dataset.points,function(point){
+                    if (point.inRange(eventPosition.x,eventPosition.y)) pointsArray.push(point);
+                });
+            },this);
+            return pointsArray;
+        },
+        buildScale : function(labels){
+            var self = this;
+
+            var dataTotal = function(){
+                var values = [];
+                self.eachPoints(function(point){
+                    values.push(point.value);
+                });
+
+                return values;
+            };
+
+            var scaleOptions = {
+                templateString : this.options.scaleLabel,
+                height : this.chart.height,
+                width : this.chart.width,
+                ctx : this.chart.ctx,
+                textColor : this.options.scaleFontColor,
+                offsetGridLines : this.options.offsetGridLines,
+                fontSize : this.options.scaleFontSize,
+                fontStyle : this.options.scaleFontStyle,
+                fontFamily : this.options.scaleFontFamily,
+                valuesCount : labels.length,
+                beginAtZero : this.options.scaleBeginAtZero,
+                integersOnly : this.options.scaleIntegersOnly,
+                calculateYRange : function(currentHeight){
+                    var updatedRanges = helpers.calculateScaleRange(
+                        dataTotal(),
+                        currentHeight,
+                        this.fontSize,
+                        this.beginAtZero,
+                        this.integersOnly
+                    );
+                    helpers.extend(this, updatedRanges);
+                },
+                xLabels : labels,
+                font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
+                lineWidth : this.options.scaleLineWidth,
+                lineColor : this.options.scaleLineColor,
+                showHorizontalLines : this.options.scaleShowHorizontalLines,
+                showVerticalLines : this.options.scaleShowVerticalLines,
+                gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
+                gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
+                padding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,
+                showLabels : this.options.scaleShowLabels,
+                display : this.options.showScale
+            };
+
+            if (this.options.scaleOverride){
+                helpers.extend(scaleOptions, {
+                    calculateYRange: helpers.noop,
+                    steps: this.options.scaleSteps,
+                    stepValue: this.options.scaleStepWidth,
+                    min: this.options.scaleStartValue,
+                    max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
+                });
+            }
+
+
+            this.scale = new Chart.Scale(scaleOptions);
+        },
+        addData : function(valuesArray,label){
+            //Map the values array for each of the datasets
+
+            helpers.each(valuesArray,function(value,datasetIndex){
+                //Add a new point for each piece of data, passing any required data to draw.
+                this.datasets[datasetIndex].points.push(new this.PointClass({
+                    value : value,
+                    label : label,
+                    datasetLabel: this.datasets[datasetIndex].label,
+                    x: this.scale.calculateX(this.scale.valuesCount+1),
+                    y: this.scale.endPoint,
+                    strokeColor : this.datasets[datasetIndex].pointStrokeColor,
+                    fillColor : this.datasets[datasetIndex].pointColor
+                }));
+            },this);
+
+            this.scale.addXLabel(label);
+            //Then re-render the chart.
+            this.update();
+        },
+        removeData : function(){
+            this.scale.removeXLabel();
+            //Then re-render the chart.
+            helpers.each(this.datasets,function(dataset){
+                dataset.points.shift();
+            },this);
+            this.update();
+        },
+        reflow : function(){
+            var newScaleProps = helpers.extend({
+                height : this.chart.height,
+                width : this.chart.width
+            });
+            this.scale.update(newScaleProps);
+        },
+        draw : function(ease){
+            var easingDecimal = ease || 1;
+            this.clear();
+
+            var ctx = this.chart.ctx;
+
+            // Some helper methods for getting the next/prev points
+            var hasValue = function(item){
+                return item.value !== null;
+            },
+            nextPoint = function(point, collection, index){
+                return helpers.findNextWhere(collection, hasValue, index) || point;
+            },
+            previousPoint = function(point, collection, index){
+                return helpers.findPreviousWhere(collection, hasValue, index) || point;
+            };
+
+            if (!this.scale) return;
+            this.scale.draw(easingDecimal);
+
+
+            helpers.each(this.datasets,function(dataset){
+                var pointsWithValues = helpers.where(dataset.points, hasValue);
+
+                //Transition each point first so that the line and point drawing isn't out of sync
+                //We can use this extra loop to calculate the control points of this dataset also in this loop
+
+                helpers.each(dataset.points, function(point, index){
+                    if (point.hasValue()){
+                        point.transition({
+                            y : this.scale.calculateY(point.value),
+                            x : this.scale.calculateX(index)
+                        }, easingDecimal);
+                    }
+                },this);
+
+
+                // Control points need to be calculated in a separate loop, because we need to know the current x/y of the point
+                // This would cause issues when there is no animation, because the y of the next point would be 0, so beziers would be skewed
+                if (this.options.bezierCurve){
+                    helpers.each(pointsWithValues, function(point, index){
+                        var tension = (index > 0 && index < pointsWithValues.length - 1) ? this.options.bezierCurveTension : 0;
+                        point.controlPoints = helpers.splineCurve(
+                            previousPoint(point, pointsWithValues, index),
+                            point,
+                            nextPoint(point, pointsWithValues, index),
+                            tension
+                        );
+
+                        // Prevent the bezier going outside of the bounds of the graph
+
+                        // Cap puter bezier handles to the upper/lower scale bounds
+                        if (point.controlPoints.outer.y > this.scale.endPoint){
+                            point.controlPoints.outer.y = this.scale.endPoint;
+                        }
+                        else if (point.controlPoints.outer.y < this.scale.startPoint){
+                            point.controlPoints.outer.y = this.scale.startPoint;
+                        }
+
+                        // Cap inner bezier handles to the upper/lower scale bounds
+                        if (point.controlPoints.inner.y > this.scale.endPoint){
+                            point.controlPoints.inner.y = this.scale.endPoint;
+                        }
+                        else if (point.controlPoints.inner.y < this.scale.startPoint){
+                            point.controlPoints.inner.y = this.scale.startPoint;
+                        }
+                    },this);
+                }
+
+
+                //Draw the line between all the points
+                ctx.lineWidth = this.options.datasetStrokeWidth;
+                ctx.strokeStyle = dataset.strokeColor;
+                ctx.beginPath();
+
+                helpers.each(pointsWithValues, function(point, index){
+                    if (index === 0){
+                        ctx.moveTo(point.x, point.y);
+                    }
+                    else{
+                        if(this.options.bezierCurve){
+                            var previous = previousPoint(point, pointsWithValues, index);
+
+                            ctx.bezierCurveTo(
+                                previous.controlPoints.outer.x,
+                                previous.controlPoints.outer.y,
+                                point.controlPoints.inner.x,
+                                point.controlPoints.inner.y,
+                                point.x,
+                                point.y
+                            );
+                        }
+                        else{
+                            ctx.lineTo(point.x,point.y);
+                        }
+                    }
+                }, this);
+
+                if (this.options.datasetStroke) {
+                    ctx.stroke();
+                }
+
+                if (this.options.datasetFill && pointsWithValues.length > 0){
+                    //Round off the line by going to the base of the chart, back to the start, then fill.
+                    ctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, this.scale.endPoint);
+                    ctx.lineTo(pointsWithValues[0].x, this.scale.endPoint);
+                    ctx.fillStyle = dataset.fillColor;
+                    ctx.closePath();
+                    ctx.fill();
+                }
+
+                //Now draw the points over the line
+                //A little inefficient double looping, but better than the line
+                //lagging behind the point positions
+                helpers.each(pointsWithValues,function(point){
+                    point.draw();
+                });
+            },this);
+        }
+    });
+
+
+}).call(this);
+
+(function(){
+    "use strict";
+
+    var root = this,
+        Chart = root.Chart,
+        //Cache a local reference to Chart.helpers
+        helpers = Chart.helpers;
+
+    var defaultConfig = {
+        //Boolean - Show a backdrop to the scale label
+        scaleShowLabelBackdrop : true,
+
+        //String - The colour of the label backdrop
+        scaleBackdropColor : "rgba(255,255,255,0.75)",
+
+        // Boolean - Whether the scale should begin at zero
+        scaleBeginAtZero : true,
+
+        //Number - The backdrop padding above & below the label in pixels
+        scaleBackdropPaddingY : 2,
+
+        //Number - The backdrop padding to the side of the label in pixels
+        scaleBackdropPaddingX : 2,
+
+        //Boolean - Show line for each value in the scale
+        scaleShowLine : true,
+
+        //Boolean - Stroke a line around each segment in the chart
+        segmentShowStroke : true,
+
+        //String - The colour of the stroke on each segment.
+        segmentStrokeColor : "#fff",
+
+        //Number - The width of the stroke value in pixels
+        segmentStrokeWidth : 2,
+
+        //Number - Amount of animation steps
+        animationSteps : 100,
+
+        //String - Animation easing effect.
+        animationEasing : "easeOutBounce",
+
+        //Boolean - Whether to animate the rotation of the chart
+        animateRotate : true,
+
+        //Boolean - Whether to animate scaling the chart from the centre
+        animateScale : false,
+
+        //String - A legend template
+        legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"><%if(segments[i].label){%><%=segments[i].label%><%}%></span></li><%}%></ul>"
+    };
+
+
+    Chart.Type.extend({
+        //Passing in a name registers this chart in the Chart namespace
+        name: "PolarArea",
+        //Providing a defaults will also register the deafults in the chart namespace
+        defaults : defaultConfig,
+        //Initialize is fired when the chart is initialized - Data is passed in as a parameter
+        //Config is automatically merged by the core of Chart.js, and is available at this.options
+        initialize:  function(data){
+            this.segments = [];
+            //Declare segment class as a chart instance specific class, so it can share props for this instance
+            this.SegmentArc = Chart.Arc.extend({
+                showStroke : this.options.segmentShowStroke,
+                strokeWidth : this.options.segmentStrokeWidth,
+                strokeColor : this.options.segmentStrokeColor,
+                ctx : this.chart.ctx,
+                innerRadius : 0,
+                x : this.chart.width/2,
+                y : this.chart.height/2
+            });
+            this.scale = new Chart.RadialScale({
+                display: this.options.showScale,
+                fontStyle: this.options.scaleFontStyle,
+                fontSize: this.options.scaleFontSize,
+                fontFamily: this.options.scaleFontFamily,
+                fontColor: this.options.scaleFontColor,
+                showLabels: this.options.scaleShowLabels,
+                showLabelBackdrop: this.options.scaleShowLabelBackdrop,
+                backdropColor: this.options.scaleBackdropColor,
+                backdropPaddingY : this.options.scaleBackdropPaddingY,
+                backdropPaddingX: this.options.scaleBackdropPaddingX,
+                lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
+                lineColor: this.options.scaleLineColor,
+                lineArc: true,
+                width: this.chart.width,
+                height: this.chart.height,
+                xCenter: this.chart.width/2,
+                yCenter: this.chart.height/2,
+                ctx : this.chart.ctx,
+                templateString: this.options.scaleLabel,
+                valuesCount: data.length
+            });
+
+            this.updateScaleRange(data);
+
+            this.scale.update();
+
+            helpers.each(data,function(segment,index){
+                this.addData(segment,index,true);
+            },this);
+
+            //Set up tooltip events on the chart
+            if (this.options.showTooltips){
+                helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
+                    var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
+                    helpers.each(this.segments,function(segment){
+                        segment.restore(["fillColor"]);
+                    });
+                    helpers.each(activeSegments,function(activeSegment){
+                        activeSegment.fillColor = activeSegment.highlightColor;
+                    });
+                    this.showTooltip(activeSegments);
+                });
+            }
+
+            this.render();
+        },
+        getSegmentsAtEvent : function(e){
+            var segmentsArray = [];
+
+            var location = helpers.getRelativePosition(e);
+
+            helpers.each(this.segments,function(segment){
+                if (segment.inRange(location.x,location.y)) segmentsArray.push(segment);
+            },this);
+            return segmentsArray;
+        },
+        addData : function(segment, atIndex, silent){
+            var index = atIndex || this.segments.length;
+
+            this.segments.splice(index, 0, new this.SegmentArc({
+                fillColor: segment.color,
+                highlightColor: segment.highlight || segment.color,
+                label: segment.label,
+                value: segment.value,
+                outerRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),
+                circumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),
+                startAngle: Math.PI * 1.5
+            }));
+            if (!silent){
+                this.reflow();
+                this.update();
+            }
+        },
+        removeData: function(atIndex){
+            var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
+            this.segments.splice(indexToDelete, 1);
+            this.reflow();
+            this.update();
+        },
+        calculateTotal: function(data){
+            this.total = 0;
+            helpers.each(data,function(segment){
+                this.total += segment.value;
+            },this);
+            this.scale.valuesCount = this.segments.length;
+        },
+        updateScaleRange: function(datapoints){
+            var valuesArray = [];
+            helpers.each(datapoints,function(segment){
+                valuesArray.push(segment.value);
+            });
+
+            var scaleSizes = (this.options.scaleOverride) ?
+                {
+                    steps: this.options.scaleSteps,
+                    stepValue: this.options.scaleStepWidth,
+                    min: this.options.scaleStartValue,
+                    max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
+                } :
+                helpers.calculateScaleRange(
+                    valuesArray,
+                    helpers.min([this.chart.width, this.chart.height])/2,
+                    this.options.scaleFontSize,
+                    this.options.scaleBeginAtZero,
+                    this.options.scaleIntegersOnly
+                );
+
+            helpers.extend(
+                this.scale,
+                scaleSizes,
+                {
+                    size: helpers.min([this.chart.width, this.chart.height]),
+                    xCenter: this.chart.width/2,
+                    yCenter: this.chart.height/2
+                }
+            );
+
+        },
+        update : function(){
+            this.calculateTotal(this.segments);
+
+            helpers.each(this.segments,function(segment){
+                segment.save();
+            });
+
+            this.reflow();
+            this.render();
+        },
+        reflow : function(){
+            helpers.extend(this.SegmentArc.prototype,{
+                x : this.chart.width/2,
+                y : this.chart.height/2
+            });
+            this.updateScaleRange(this.segments);
+            this.scale.update();
+
+            helpers.extend(this.scale,{
+                xCenter: this.chart.width/2,
+                yCenter: this.chart.height/2
+            });
+
+            helpers.each(this.segments, function(segment){
+                segment.update({
+                    outerRadius : this.scale.calculateCenterOffset(segment.value)
+                });
+            }, this);
+
+        },
+        draw : function(ease){
+            var easingDecimal = ease || 1;
+            //Clear & draw the canvas
+            this.clear();
+            helpers.each(this.segments,function(segment, index){
+                segment.transition({
+                    circumference : this.scale.getCircumference(),
+                    outerRadius : this.scale.calculateCenterOffset(segment.value)
+                },easingDecimal);
+
+                segment.endAngle = segment.startAngle + segment.circumference;
+
+                // If we've removed the first segment we need to set the first one to
+                // start at the top.
+                if (index === 0){
+                    segment.startAngle = Math.PI * 1.5;
+                }
+
+                //Check to see if it's the last segment, if not get the next and update the start angle
+                if (index < this.segments.length - 1){
+                    this.segments[index+1].startAngle = segment.endAngle;
+                }
+                segment.draw();
+            }, this);
+            this.scale.draw();
+        }
+    });
+
+}).call(this);
+
+(function(){
+    "use strict";
+
+    var root = this,
+        Chart = root.Chart,
+        helpers = Chart.helpers;
+
+
+
+    Chart.Type.extend({
+        name: "Radar",
+        defaults:{
+            //Boolean - Whether to show lines for each scale point
+            scaleShowLine : true,
+
+            //Boolean - Whether we show the angle lines out of the radar
+            angleShowLineOut : true,
+
+            //Boolean - Whether to show labels on the scale
+            scaleShowLabels : false,
+
+            // Boolean - Whether the scale should begin at zero
+            scaleBeginAtZero : true,
+
+            //String - Colour of the angle line
+            angleLineColor : "rgba(0,0,0,.1)",
+
+            //Number - Pixel width of the angle line
+            angleLineWidth : 1,
+
+            //String - Point label font declaration
+            pointLabelFontFamily : "'Arial'",
+
+            //String - Point label font weight
+            pointLabelFontStyle : "normal",
+
+            //Number - Point label font size in pixels
+            pointLabelFontSize : 10,
+
+            //String - Point label font colour
+            pointLabelFontColor : "#666",
+
+            //Boolean - Whether to show a dot for each point
+            pointDot : true,
+
+            //Number - Radius of each point dot in pixels
+            pointDotRadius : 3,
+
+            //Number - Pixel width of point dot stroke
+            pointDotStrokeWidth : 1,
+
+            //Number - amount extra to add to the radius to cater for hit detection outside the drawn point
+            pointHitDetectionRadius : 20,
+
+            //Boolean - Whether to show a stroke for datasets
+            datasetStroke : true,
+
+            //Number - Pixel width of dataset stroke
+            datasetStrokeWidth : 2,
+
+            //Boolean - Whether to fill the dataset with a colour
+            datasetFill : true,
+
+            //String - A legend template
+            legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>"
+
+        },
+
+        initialize: function(data){
+            this.PointClass = Chart.Point.extend({
+                strokeWidth : this.options.pointDotStrokeWidth,
+                radius : this.options.pointDotRadius,
+                display: this.options.pointDot,
+                hitDetectionRadius : this.options.pointHitDetectionRadius,
+                ctx : this.chart.ctx
+            });
+
+            this.datasets = [];
+
+            this.buildScale(data);
+
+            //Set up tooltip events on the chart
+            if (this.options.showTooltips){
+                helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
+                    var activePointsCollection = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
+
+                    this.eachPoints(function(point){
+                        point.restore(['fillColor', 'strokeColor']);
+                    });
+                    helpers.each(activePointsCollection, function(activePoint){
+                        activePoint.fillColor = activePoint.highlightFill;
+                        activePoint.strokeColor = activePoint.highlightStroke;
+                    });
+
+                    this.showTooltip(activePointsCollection);
+                });
+            }
+
+            //Iterate through each of the datasets, and build this into a property of the chart
+            helpers.each(data.datasets,function(dataset){
+
+                var datasetObject = {
+                    label: dataset.label || null,
+                    fillColor : dataset.fillColor,
+                    strokeColor : dataset.strokeColor,
+                    pointColor : dataset.pointColor,
+                    pointStrokeColor : dataset.pointStrokeColor,
+                    points : []
+                };
+
+                this.datasets.push(datasetObject);
+
+                helpers.each(dataset.data,function(dataPoint,index){
+                    //Add a new point for each piece of data, passing any required data to draw.
+                    var pointPosition;
+                    if (!this.scale.animation){
+                        pointPosition = this.scale.getPointPosition(index, this.scale.calculateCenterOffset(dataPoint));
+                    }
+                    datasetObject.points.push(new this.PointClass({
+                        value : dataPoint,
+                        label : data.labels[index],
+                        datasetLabel: dataset.label,
+                        x: (this.options.animation) ? this.scale.xCenter : pointPosition.x,
+                        y: (this.options.animation) ? this.scale.yCenter : pointPosition.y,
+                        strokeColor : dataset.pointStrokeColor,
+                        fillColor : dataset.pointColor,
+                        highlightFill : dataset.pointHighlightFill || dataset.pointColor,
+                        highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
+                    }));
+                },this);
+
+            },this);
+
+            this.render();
+        },
+        eachPoints : function(callback){
+            helpers.each(this.datasets,function(dataset){
+                helpers.each(dataset.points,callback,this);
+            },this);
+        },
+
+        getPointsAtEvent : function(evt){
+            var mousePosition = helpers.getRelativePosition(evt),
+                fromCenter = helpers.getAngleFromPoint({
+                    x: this.scale.xCenter,
+                    y: this.scale.yCenter
+                }, mousePosition);
+
+            var anglePerIndex = (Math.PI * 2) /this.scale.valuesCount,
+                pointIndex = Math.round((fromCenter.angle - Math.PI * 1.5) / anglePerIndex),
+                activePointsCollection = [];
+
+            // If we're at the top, make the pointIndex 0 to get the first of the array.
+            if (pointIndex >= this.scale.valuesCount || pointIndex < 0){
+                pointIndex = 0;
+            }
+
+            if (fromCenter.distance <= this.scale.drawingArea){
+                helpers.each(this.datasets, function(dataset){
+                    activePointsCollection.push(dataset.points[pointIndex]);
+                });
+            }
+
+            return activePointsCollection;
+        },
+
+        buildScale : function(data){
+            this.scale = new Chart.RadialScale({
+                display: this.options.showScale,
+                fontStyle: this.options.scaleFontStyle,
+                fontSize: this.options.scaleFontSize,
+                fontFamily: this.options.scaleFontFamily,
+                fontColor: this.options.scaleFontColor,
+                showLabels: this.options.scaleShowLabels,
+                showLabelBackdrop: this.options.scaleShowLabelBackdrop,
+                backdropColor: this.options.scaleBackdropColor,
+                backgroundColors: this.options.scaleBackgroundColors,
+                backdropPaddingY : this.options.scaleBackdropPaddingY,
+                backdropPaddingX: this.options.scaleBackdropPaddingX,
+                lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
+                lineColor: this.options.scaleLineColor,
+                angleLineColor : this.options.angleLineColor,
+                angleLineWidth : (this.options.angleShowLineOut) ? this.options.angleLineWidth : 0,
+                // Point labels at the edge of each line
+                pointLabelFontColor : this.options.pointLabelFontColor,
+                pointLabelFontSize : this.options.pointLabelFontSize,
+                pointLabelFontFamily : this.options.pointLabelFontFamily,
+                pointLabelFontStyle : this.options.pointLabelFontStyle,
+                height : this.chart.height,
+                width: this.chart.width,
+                xCenter: this.chart.width/2,
+                yCenter: this.chart.height/2,
+                ctx : this.chart.ctx,
+                templateString: this.options.scaleLabel,
+                labels: data.labels,
+                valuesCount: data.datasets[0].data.length
+            });
+
+            this.scale.setScaleSize();
+            this.updateScaleRange(data.datasets);
+            this.scale.buildYLabels();
+        },
+        updateScaleRange: function(datasets){
+            var valuesArray = (function(){
+                var totalDataArray = [];
+                helpers.each(datasets,function(dataset){
+                    if (dataset.data){
+                        totalDataArray = totalDataArray.concat(dataset.data);
+                    }
+                    else {
+                        helpers.each(dataset.points, function(point){
+                            totalDataArray.push(point.value);
+                        });
+                    }
+                });
+                return totalDataArray;
+            })();
+
+
+            var scaleSizes = (this.options.scaleOverride) ?
+                {
+                    steps: this.options.scaleSteps,
+                    stepValue: this.options.scaleStepWidth,
+                    min: this.options.scaleStartValue,
+                    max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
+                } :
+                helpers.calculateScaleRange(
+                    valuesArray,
+                    helpers.min([this.chart.width, this.chart.height])/2,
+                    this.options.scaleFontSize,
+                    this.options.scaleBeginAtZero,
+                    this.options.scaleIntegersOnly
+                );
+
+            helpers.extend(
+                this.scale,
+                scaleSizes
+            );
+
+        },
+        addData : function(valuesArray,label){
+            //Map the values array for each of the datasets
+            this.scale.valuesCount++;
+            helpers.each(valuesArray,function(value,datasetIndex){
+                var pointPosition = this.scale.getPointPosition(this.scale.valuesCount, this.scale.calculateCenterOffset(value));
+                this.datasets[datasetIndex].points.push(new this.PointClass({
+                    value : value,
+                    label : label,
+                    datasetLabel: this.datasets[datasetIndex].label,
+                    x: pointPosition.x,
+                    y: pointPosition.y,
+                    strokeColor : this.datasets[datasetIndex].pointStrokeColor,
+                    fillColor : this.datasets[datasetIndex].pointColor
+                }));
+            },this);
+
+            this.scale.labels.push(label);
+
+            this.reflow();
+
+            this.update();
+        },
+        removeData : function(){
+            this.scale.valuesCount--;
+            this.scale.labels.shift();
+            helpers.each(this.datasets,function(dataset){
+                dataset.points.shift();
+            },this);
+            this.reflow();
+            this.update();
+        },
+        update : function(){
+            this.eachPoints(function(point){
+                point.save();
+            });
+            this.reflow();
+            this.render();
+        },
+        reflow: function(){
+            helpers.extend(this.scale, {
+                width : this.chart.width,
+                height: this.chart.height,
+                size : helpers.min([this.chart.width, this.chart.height]),
+                xCenter: this.chart.width/2,
+                yCenter: this.chart.height/2
+            });
+            this.updateScaleRange(this.datasets);
+            this.scale.setScaleSize();
+            this.scale.buildYLabels();
+        },
+        draw : function(ease){
+            var easeDecimal = ease || 1,
+                ctx = this.chart.ctx;
+            this.clear();
+            this.scale.draw();
+
+            helpers.each(this.datasets,function(dataset){
+
+                //Transition each point first so that the line and point drawing isn't out of sync
+                helpers.each(dataset.points,function(point,index){
+                    if (point.hasValue()){
+                        point.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal);
+                    }
+                },this);
+
+
+
+                //Draw the line between all the points
+                ctx.lineWidth = this.options.datasetStrokeWidth;
+                ctx.strokeStyle = dataset.strokeColor;
+                ctx.beginPath();
+                helpers.each(dataset.points,function(point,index){
+                    if (index === 0){
+                        ctx.moveTo(point.x,point.y);
+                    }
+                    else{
+                        ctx.lineTo(point.x,point.y);
+                    }
+                },this);
+                ctx.closePath();
+                ctx.stroke();
+
+                ctx.fillStyle = dataset.fillColor;
+                if(this.options.datasetFill){
+                    ctx.fill();
+                }
+                //Now draw the points over the line
+                //A little inefficient double looping, but better than the line
+                //lagging behind the point positions
+                helpers.each(dataset.points,function(point){
+                    if (point.hasValue()){
+                        point.draw();
+                    }
+                });
+
+            },this);
+
+        }
+
+    });
+
+
+
+
+
+}).call(this);
diff --git a/web/gui/src/main/webapp/tp/Chart.min.js b/web/gui/src/main/webapp/tp/Chart.min.js
new file mode 100755
index 0000000..1ff0cd4
--- /dev/null
+++ b/web/gui/src/main/webapp/tp/Chart.min.js
@@ -0,0 +1,11 @@
+/*!
+ * Chart.js
+ * http://chartjs.org/
+ * Version: 1.0.2
+ *
+ * Copyright 2015 Nick Downie
+ * Released under the MIT license
+ * https://github.com/nnnick/Chart.js/blob/master/LICENSE.md
+ */
+(function(){"use strict";var t=this,i=t.Chart,e=function(t){this.canvas=t.canvas,this.ctx=t;var i=function(t,i){return t["offset"+i]?t["offset"+i]:document.defaultView.getComputedStyle(t).getPropertyValue(i)},e=this.width=i(t.canvas,"Width")||t.canvas.width,n=this.height=i(t.canvas,"Height")||t.canvas.height;return e=this.width=t.canvas.width,n=this.height=t.canvas.height,this.aspectRatio=this.width/this.height,s.retinaScale(this),this};e.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",tooltipTitleTemplate:"<%= label%>",tooltipYPadding:6,tooltipXPadding:6,tooltipCaretSize:8,tooltipCornerRadius:6,tooltipXOffset:10,tooltipTemplate:"<%if (label){%><%=label%>: <%}%><%= value %>",multiTooltipTemplate:"<%= 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(){}}},e.types={};var s=e.helpers={},n=s.each=function(t,i,e){var s=Array.prototype.slice.call(arguments,3);if(t)if(t.length===+t.length){var n;for(n=0;n<t.length;n++)i.apply(e,[t[n],n].concat(s))}else for(var o in t)i.apply(e,[t[o],o].concat(s))},o=s.clone=function(t){var i={};return n(t,function(e,s){t.hasOwnProperty(s)&&(i[s]=e)}),i},a=s.extend=function(t){return n(Array.prototype.slice.call(arguments,1),function(i){n(i,function(e,s){i.hasOwnProperty(s)&&(t[s]=e)})}),t},h=s.merge=function(t,i){var e=Array.prototype.slice.call(arguments,0);return e.unshift({}),a.apply(null,e)},l=s.indexOf=function(t,i){if(Array.prototype.indexOf)return t.indexOf(i);for(var e=0;e<t.length;e++)if(t[e]===i)return e;return-1},r=(s.where=function(t,i){var e=[];return s.each(t,function(t){i(t)&&e.push(t)}),e},s.findNextWhere=function(t,i,e){e||(e=-1);for(var s=e+1;s<t.length;s++){var n=t[s];if(i(n))return n}},s.findPreviousWhere=function(t,i,e){e||(e=t.length);for(var s=e-1;s>=0;s--){var n=t[s];if(i(n))return n}},s.inherits=function(t){var i=this,e=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return i.apply(this,arguments)},s=function(){this.constructor=e};return s.prototype=i.prototype,e.prototype=new s,e.extend=r,t&&a(e.prototype,t),e.__super__=i.prototype,e}),c=s.noop=function(){},u=s.uid=function(){var t=0;return function(){return"chart-"+t++}}(),d=s.warn=function(t){window.console&&"function"==typeof window.console.warn&&console.warn(t)},p=s.amd="function"==typeof define&&define.amd,f=s.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},g=s.max=function(t){return Math.max.apply(Math,t)},m=s.min=function(t){return Math.min.apply(Math,t)},v=(s.cap=function(t,i,e){if(f(i)){if(t>i)return i}else if(f(e)&&e>t)return e;return t},s.getDecimalPlaces=function(t){if(t%1!==0&&f(t)){var i=t.toString();if(i.indexOf("e-")<0)return i.split(".")[1].length;if(i.indexOf(".")<0)return parseInt(i.split("e-")[1]);var e=i.split(".")[1].split("e-");return e[0].length+parseInt(e[1])}return 0}),S=s.radians=function(t){return t*(Math.PI/180)},x=(s.getAngleFromPoint=function(t,i){var e=i.x-t.x,s=i.y-t.y,n=Math.sqrt(e*e+s*s),o=2*Math.PI+Math.atan2(s,e);return 0>e&&0>s&&(o+=2*Math.PI),{angle:o,distance:n}},s.aliasPixel=function(t){return t%2===0?0:.5}),y=(s.splineCurve=function(t,i,e,s){var n=Math.sqrt(Math.pow(i.x-t.x,2)+Math.pow(i.y-t.y,2)),o=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),a=s*n/(n+o),h=s*o/(n+o);return{inner:{x:i.x-a*(e.x-t.x),y:i.y-a*(e.y-t.y)},outer:{x:i.x+h*(e.x-t.x),y:i.y+h*(e.y-t.y)}}},s.calculateOrderOfMagnitude=function(t){return Math.floor(Math.log(t)/Math.LN10)}),C=(s.calculateScaleRange=function(t,i,e,s,o){var a=2,h=Math.floor(i/(1.5*e)),l=a>=h,r=[];n(t,function(t){null==t||r.push(t)});var c=m(r),u=g(r);u===c&&(u+=.5,c>=.5&&!s?c-=.5:u+=.5);for(var d=Math.abs(u-c),p=y(d),f=Math.ceil(u/(1*Math.pow(10,p)))*Math.pow(10,p),v=s?0:Math.floor(c/(1*Math.pow(10,p)))*Math.pow(10,p),S=f-v,x=Math.pow(10,p),C=Math.round(S/x);(C>h||h>2*C)&&!l;)if(C>h)x*=2,C=Math.round(S/x),C%1!==0&&(l=!0);else if(o&&p>=0){if(x/2%1!==0)break;x/=2,C=Math.round(S/x)}else x/=2,C=Math.round(S/x);return l&&(C=a,x=S/C),{steps:C,stepValue:x,min:v,max:v+C*x}},s.template=function(t,i){function e(t,i){var e=/\W/.test(t)?new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+t.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('');"):s[t]=s[t];return i?e(i):e}if(t instanceof Function)return t(i);var s={};return e(t,i)}),b=(s.generateLabels=function(t,i,e,s){var o=new Array(i);return t&&n(o,function(i,n){o[n]=C(t,{value:e+s*(n+1)})}),o},s.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-0.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-0.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-0.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-0.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var i=1.70158,e=0,s=1;return 0===t?0:1==(t/=1)?1:(e||(e=.3),s<Math.abs(1)?(s=1,i=e/4):i=e/(2*Math.PI)*Math.asin(1/s),-(s*Math.pow(2,10*(t-=1))*Math.sin((1*t-i)*(2*Math.PI)/e)))},easeOutElastic:function(t){var i=1.70158,e=0,s=1;return 0===t?0:1==(t/=1)?1:(e||(e=.3),s<Math.abs(1)?(s=1,i=e/4):i=e/(2*Math.PI)*Math.asin(1/s),s*Math.pow(2,-10*t)*Math.sin((1*t-i)*(2*Math.PI)/e)+1)},easeInOutElastic:function(t){var i=1.70158,e=0,s=1;return 0===t?0:2==(t/=.5)?1:(e||(e=1*(.3*1.5)),s<Math.abs(1)?(s=1,i=e/4):i=e/(2*Math.PI)*Math.asin(1/s),1>t?-.5*(s*Math.pow(2,10*(t-=1))*Math.sin((1*t-i)*(2*Math.PI)/e)):s*Math.pow(2,-10*(t-=1))*Math.sin((1*t-i)*(2*Math.PI)/e)*.5+1)},easeInBack:function(t){var i=1.70158;return 1*(t/=1)*t*((i+1)*t-i)},easeOutBack:function(t){var i=1.70158;return 1*((t=t/1-1)*t*((i+1)*t+i)+1)},easeInOutBack:function(t){var i=1.70158;return(t/=.5)<1?.5*(t*t*(((i*=1.525)+1)*t-i)):.5*((t-=2)*t*(((i*=1.525)+1)*t+i)+2)},easeInBounce:function(t){return 1-b.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?1*(7.5625*t*t):2/2.75>t?1*(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return.5>t?.5*b.easeInBounce(2*t):.5*b.easeOutBounce(2*t-1)+.5}}),w=s.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),P=(s.cancelAnimFrame=function(){return window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t,1e3/60)}}(),s.animationLoop=function(t,i,e,s,n,o){var a=0,h=b[e]||b.linear,l=function(){a++;var e=a/i,r=h(e);t.call(o,r,e,a),s.call(o,r,e),i>a?o.animationFrame=w(l):n.apply(o)};w(l)},s.getRelativePosition=function(t){var i,e,s=t.originalEvent||t,n=t.currentTarget||t.srcElement,o=n.getBoundingClientRect();return s.touches?(i=s.touches[0].clientX-o.left,e=s.touches[0].clientY-o.top):(i=s.clientX-o.left,e=s.clientY-o.top),{x:i,y:e}},s.addEvent=function(t,i,e){t.addEventListener?t.addEventListener(i,e):t.attachEvent?t.attachEvent("on"+i,e):t["on"+i]=e}),L=s.removeEvent=function(t,i,e){t.removeEventListener?t.removeEventListener(i,e,!1):t.detachEvent?t.detachEvent("on"+i,e):t["on"+i]=c},k=(s.bindEvents=function(t,i,e){t.events||(t.events={}),n(i,function(i){t.events[i]=function(){e.apply(t,arguments)},P(t.chart.canvas,i,t.events[i])})},s.unbindEvents=function(t,i){n(i,function(i,e){L(t.chart.canvas,e,i)})}),F=s.getMaximumWidth=function(t){var i=t.parentNode,e=parseInt(R(i,"padding-left"))+parseInt(R(i,"padding-right"));return i.clientWidth-e},A=s.getMaximumHeight=function(t){var i=t.parentNode,e=parseInt(R(i,"padding-bottom"))+parseInt(R(i,"padding-top"));return i.clientHeight-e},R=s.getStyle=function(t,i){return t.currentStyle?t.currentStyle[i]:document.defaultView.getComputedStyle(t,null).getPropertyValue(i)},T=(s.getMaximumSize=s.getMaximumWidth,s.retinaScale=function(t){var i=t.ctx,e=t.canvas.width,s=t.canvas.height;window.devicePixelRatio&&(i.canvas.style.width=e+"px",i.canvas.style.height=s+"px",i.canvas.height=s*window.devicePixelRatio,i.canvas.width=e*window.devicePixelRatio,i.scale(window.devicePixelRatio,window.devicePixelRatio))}),M=s.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},W=s.fontString=function(t,i,e){return i+" "+t+"px "+e},z=s.longestText=function(t,i,e){t.font=i;var s=0;return n(e,function(i){var e=t.measureText(i).width;s=e>s?e:s}),s},B=s.drawRoundedRectangle=function(t,i,e,s,n,o){t.beginPath(),t.moveTo(i+o,e),t.lineTo(i+s-o,e),t.quadraticCurveTo(i+s,e,i+s,e+o),t.lineTo(i+s,e+n-o),t.quadraticCurveTo(i+s,e+n,i+s-o,e+n),t.lineTo(i+o,e+n),t.quadraticCurveTo(i,e+n,i,e+n-o),t.lineTo(i,e+o),t.quadraticCurveTo(i,e,i+o,e),t.closePath()};e.instances={},e.Type=function(t,i,s){this.options=i,this.chart=s,this.id=u(),e.instances[this.id]=this,i.responsive&&this.resize(),this.initialize.call(this,t)},a(e.Type.prototype,{initialize:function(){return this},clear:function(){return M(this.chart),this},stop:function(){return e.animationService.cancelAnimation(this),this},resize:function(t){this.stop();var i=this.chart.canvas,e=F(this.chart.canvas),s=this.options.maintainAspectRatio?e/this.chart.aspectRatio:A(this.chart.canvas);return i.width=this.chart.width=e,i.height=this.chart.height=s,T(this.chart),"function"==typeof t&&t.apply(this,Array.prototype.slice.call(arguments,1)),this},reflow:c,render:function(t){if(t&&this.reflow(),this.options.animation&&!t){var i=new e.Animation;i.numSteps=this.options.animationSteps,i.easing=this.options.animationEasing,i.render=function(t,i){var e=s.easingEffects[i.easing],n=i.currentStep/i.numSteps,o=e(n);t.draw(o,n,i.currentStep)},i.onAnimationProgress=this.options.onAnimationProgress,i.onAnimationComplete=this.options.onAnimationComplete,e.animationService.addAnimation(this,i)}else this.draw(),this.options.onAnimationComplete.call(this);return this},generateLegend:function(){return C(this.options.legendTemplate,this)},destroy:function(){this.clear(),k(this,this.events);var t=this.chart.canvas;t.width=this.chart.width,t.height=this.chart.height,t.style.removeProperty?(t.style.removeProperty("width"),t.style.removeProperty("height")):(t.style.removeAttribute("width"),t.style.removeAttribute("height")),delete e.instances[this.id]},showTooltip:function(t,i){"undefined"==typeof this.activeElements&&(this.activeElements=[]);var o=function(t){var i=!1;return t.length!==this.activeElements.length?i=!0:(n(t,function(t,e){t!==this.activeElements[e]&&(i=!0)},this),i)}.call(this,t);if(o||i){if(this.activeElements=t,this.draw(),this.options.customTooltips&&this.options.customTooltips(!1),t.length>0)if(this.datasets&&this.datasets.length>1){for(var a,h,r=this.datasets.length-1;r>=0&&(a=this.datasets[r].points||this.datasets[r].bars||this.datasets[r].segments,h=l(a,t[0]),-1===h);r--);var c=[],u=[],d=function(t){var i,e,n,o,a,l=[],r=[],d=[];return s.each(this.datasets,function(t){i=t.points||t.bars||t.segments,i[h]&&i[h].hasValue()&&l.push(i[h])}),s.each(l,function(t){r.push(t.x),d.push(t.y),c.push(s.template(this.options.multiTooltipTemplate,t)),u.push({fill:t._saved.fillColor||t.fillColor,stroke:t._saved.strokeColor||t.strokeColor})},this),a=m(d),n=g(d),o=m(r),e=g(r),{x:o>this.chart.width/2?o:e,y:(a+n)/2}}.call(this,h);new e.MultiTooltip({x:d.x,y:d.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:c,legendColors:u,legendColorBackground:this.options.multiTooltipKeyBackground,title:C(this.options.tooltipTitleTemplate,t[0]),chart:this.chart,ctx:this.chart.ctx,custom:this.options.customTooltips}).draw()}else n(t,function(t){var i=t.tooltipPosition();new e.Tooltip({x:Math.round(i.x),y:Math.round(i.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:C(this.options.tooltipTemplate,t),chart:this.chart,custom:this.options.customTooltips}).draw()},this);return this}},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)}}),e.Type.extend=function(t){var i=this,s=function(){return i.apply(this,arguments)};if(s.prototype=o(i.prototype),a(s.prototype,t),s.extend=e.Type.extend,t.name||i.prototype.name){var n=t.name||i.prototype.name,l=e.defaults[i.prototype.name]?o(e.defaults[i.prototype.name]):{};e.defaults[n]=a(l,t.defaults),e.types[n]=s,e.prototype[n]=function(t,i){var o=h(e.defaults.global,e.defaults[n],i||{});return new s(t,o,this)}}else d("Name not provided for this chart, so it hasn't been registered");return i},e.Element=function(t){a(this,t),this.initialize.apply(this,arguments),this.save()},a(e.Element.prototype,{initialize:function(){},restore:function(t){return t?n(t,function(t){this[t]=this._saved[t]},this):a(this,this._saved),this},save:function(){return this._saved=o(this),delete this._saved._saved,this},update:function(t){return n(t,function(t,i){this._saved[i]=this[i],this[i]=t},this),this},transition:function(t,i){return n(t,function(t,e){this[e]=(t-this._saved[e])*i+this._saved[e]},this),this},tooltipPosition:function(){return{x:this.x,y:this.y}},hasValue:function(){return f(this.value)}}),e.Element.extend=r,e.Point=e.Element.extend({display:!0,inRange:function(t,i){var e=this.hitDetectionRadius+this.radius;return Math.pow(t-this.x,2)+Math.pow(i-this.y,2)<Math.pow(e,2)},draw:function(){if(this.display){var t=this.ctx;t.beginPath(),t.arc(this.x,this.y,this.radius,0,2*Math.PI),t.closePath(),t.strokeStyle=this.strokeColor,t.lineWidth=this.strokeWidth,t.fillStyle=this.fillColor,t.fill(),t.stroke()}}}),e.Arc=e.Element.extend({inRange:function(t,i){var e=s.getAngleFromPoint(this,{x:t,y:i}),n=e.angle%(2*Math.PI),o=(2*Math.PI+this.startAngle)%(2*Math.PI),a=(2*Math.PI+this.endAngle)%(2*Math.PI)||360,h=o>a?a>=n||n>=o:n>=o&&a>=n,l=e.distance>=this.innerRadius&&e.distance<=this.outerRadius;return h&&l},tooltipPosition:function(){var t=this.startAngle+(this.endAngle-this.startAngle)/2,i=(this.outerRadius-this.innerRadius)/2+this.innerRadius;return{x:this.x+Math.cos(t)*i,y:this.y+Math.sin(t)*i}},draw:function(t){var i=this.ctx;i.beginPath(),i.arc(this.x,this.y,this.outerRadius<0?0:this.outerRadius,this.startAngle,this.endAngle),i.arc(this.x,this.y,this.innerRadius<0?0:this.innerRadius,this.endAngle,this.startAngle,!0),i.closePath(),i.strokeStyle=this.strokeColor,i.lineWidth=this.strokeWidth,i.fillStyle=this.fillColor,i.fill(),i.lineJoin="bevel",this.showStroke&&i.stroke()}}),e.Rectangle=e.Element.extend({draw:function(){var t=this.ctx,i=this.width/2,e=this.x-i,s=this.x+i,n=this.base-(this.base-this.y),o=this.strokeWidth/2;this.showStroke&&(e+=o,s-=o,n+=o),t.beginPath(),t.fillStyle=this.fillColor,t.strokeStyle=this.strokeColor,t.lineWidth=this.strokeWidth,t.moveTo(e,this.base),t.lineTo(e,n),t.lineTo(s,n),t.lineTo(s,this.base),t.fill(),this.showStroke&&t.stroke()},height:function(){return this.base-this.y},inRange:function(t,i){return t>=this.x-this.width/2&&t<=this.x+this.width/2&&i>=this.y&&i<=this.base}}),e.Animation=e.Element.extend({currentStep:null,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),e.Tooltip=e.Element.extend({draw:function(){var t=this.chart.ctx;t.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.xAlign="center",this.yAlign="above";var i=this.caretPadding=2,e=t.measureText(this.text).width+2*this.xPadding,s=this.fontSize+2*this.yPadding,n=s+this.caretHeight+i;this.x+e/2>this.chart.width?this.xAlign="left":this.x-e/2<0&&(this.xAlign="right"),this.y-n<0&&(this.yAlign="below");var o=this.x-e/2,a=this.y-n;if(t.fillStyle=this.fillColor,this.custom)this.custom(this);else{switch(this.yAlign){case"above":t.beginPath(),t.moveTo(this.x,this.y-i),t.lineTo(this.x+this.caretHeight,this.y-(i+this.caretHeight)),t.lineTo(this.x-this.caretHeight,this.y-(i+this.caretHeight)),t.closePath(),t.fill();break;case"below":a=this.y+i+this.caretHeight,t.beginPath(),t.moveTo(this.x,this.y+i),t.lineTo(this.x+this.caretHeight,this.y+i+this.caretHeight),t.lineTo(this.x-this.caretHeight,this.y+i+this.caretHeight),t.closePath(),t.fill()}switch(this.xAlign){case"left":o=this.x-e+(this.cornerRadius+this.caretHeight);break;case"right":o=this.x-(this.cornerRadius+this.caretHeight)}B(t,o,a,e,s,this.cornerRadius),t.fill(),t.fillStyle=this.textColor,t.textAlign="center",t.textBaseline="middle",t.fillText(this.text,o+e/2,a+s/2)}}}),e.MultiTooltip=e.Element.extend({initialize:function(){this.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.titleFont=W(this.titleFontSize,this.titleFontStyle,this.titleFontFamily),this.titleHeight=this.title?1.5*this.titleFontSize:0,this.height=this.labels.length*this.fontSize+(this.labels.length-1)*(this.fontSize/2)+2*this.yPadding+this.titleHeight,this.ctx.font=this.titleFont;var t=this.ctx.measureText(this.title).width,i=z(this.ctx,this.font,this.labels)+this.fontSize+3,e=g([i,t]);this.width=e+2*this.xPadding;var s=this.height/2;this.y-s<0?this.y=s:this.y+s>this.chart.height&&(this.y=this.chart.height-s),this.x>this.chart.width/2?this.x-=this.xOffset+this.width:this.x+=this.xOffset},getLineHeight:function(t){var i=this.y-this.height/2+this.yPadding,e=t-1;return 0===t?i+this.titleHeight/3:i+(1.5*this.fontSize*e+this.fontSize/2)+this.titleHeight},draw:function(){if(this.custom)this.custom(this);else{B(this.ctx,this.x,this.y-this.height/2,this.width,this.height,this.cornerRadius);var t=this.ctx;t.fillStyle=this.fillColor,t.fill(),t.closePath(),t.textAlign="left",t.textBaseline="middle",t.fillStyle=this.titleTextColor,t.font=this.titleFont,t.fillText(this.title,this.x+this.xPadding,this.getLineHeight(0)),t.font=this.font,s.each(this.labels,function(i,e){t.fillStyle=this.textColor,t.fillText(i,this.x+this.xPadding+this.fontSize+3,this.getLineHeight(e+1)),t.fillStyle=this.legendColorBackground,t.fillRect(this.x+this.xPadding,this.getLineHeight(e+1)-this.fontSize/2,this.fontSize,this.fontSize),t.fillStyle=this.legendColors[e].fill,t.fillRect(this.x+this.xPadding,this.getLineHeight(e+1)-this.fontSize/2,this.fontSize,this.fontSize)},this)}}}),e.Scale=e.Element.extend({initialize:function(){this.fit()},buildYLabels:function(){this.yLabels=[];for(var t=v(this.stepValue),i=0;i<=this.steps;i++)this.yLabels.push(C(this.templateString,{value:(this.min+i*this.stepValue).toFixed(t)}));this.yLabelWidth=this.display&&this.showLabels?z(this.ctx,this.font,this.yLabels)+10:0},addXLabel:function(t){this.xLabels.push(t),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-1.5*this.fontSize-5:this.height,this.startPoint+=this.padding,this.endPoint-=this.padding;var t,i=this.endPoint,e=this.endPoint-this.startPoint;for(this.calculateYRange(e),this.buildYLabels(),this.calculateXLabelRotation();e>this.endPoint-this.startPoint;)e=this.endPoint-this.startPoint,t=this.yLabelWidth,this.calculateYRange(e),this.buildYLabels(),t<this.yLabelWidth&&(this.endPoint=i,this.calculateXLabelRotation())},calculateXLabelRotation:function(){this.ctx.font=this.font;var t,i,e=this.ctx.measureText(this.xLabels[0]).width,s=this.ctx.measureText(this.xLabels[this.xLabels.length-1]).width;if(this.xScalePaddingRight=s/2+3,this.xScalePaddingLeft=e/2>this.yLabelWidth?e/2:this.yLabelWidth,this.xLabelRotation=0,this.display){var n,o=z(this.ctx,this.font,this.xLabels);this.xLabelWidth=o;for(var a=Math.floor(this.calculateX(1)-this.calculateX(0))-6;this.xLabelWidth>a&&0===this.xLabelRotation||this.xLabelWidth>a&&this.xLabelRotation<=90&&this.xLabelRotation>0;)n=Math.cos(S(this.xLabelRotation)),t=n*e,i=n*s,t+this.fontSize/2>this.yLabelWidth&&(this.xScalePaddingLeft=t+this.fontSize/2),this.xScalePaddingRight=this.fontSize/2,this.xLabelRotation++,this.xLabelWidth=n*o;this.xLabelRotation>0&&(this.endPoint-=Math.sin(S(this.xLabelRotation))*o+3)}else this.xLabelWidth=0,this.xScalePaddingRight=this.padding,this.xScalePaddingLeft=this.padding},calculateYRange:c,drawingArea:function(){return this.startPoint-this.endPoint},calculateY:function(t){var i=this.drawingArea()/(this.min-this.max);return this.endPoint-i*(t-this.min)},calculateX:function(t){var i=(this.xLabelRotation>0,this.width-(this.xScalePaddingLeft+this.xScalePaddingRight)),e=i/Math.max(this.valuesCount-(this.offsetGridLines?0:1),1),s=e*t+this.xScalePaddingLeft;return this.offsetGridLines&&(s+=e/2),Math.round(s)},update:function(t){s.extend(this,t),this.fit()},draw:function(){var t=this.ctx,i=(this.endPoint-this.startPoint)/this.steps,e=Math.round(this.xScalePaddingLeft);this.display&&(t.fillStyle=this.textColor,t.font=this.font,n(this.yLabels,function(n,o){var a=this.endPoint-i*o,h=Math.round(a),l=this.showHorizontalLines;t.textAlign="right",t.textBaseline="middle",this.showLabels&&t.fillText(n,e-10,a),0!==o||l||(l=!0),l&&t.beginPath(),o>0?(t.lineWidth=this.gridLineWidth,t.strokeStyle=this.gridLineColor):(t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor),h+=s.aliasPixel(t.lineWidth),l&&(t.moveTo(e,h),t.lineTo(this.width,h),t.stroke(),t.closePath()),t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor,t.beginPath(),t.moveTo(e-5,h),t.lineTo(e,h),t.stroke(),t.closePath()},this),n(this.xLabels,function(i,e){var s=this.calculateX(e)+x(this.lineWidth),n=this.calculateX(e-(this.offsetGridLines?.5:0))+x(this.lineWidth),o=this.xLabelRotation>0,a=this.showVerticalLines;0!==e||a||(a=!0),a&&t.beginPath(),e>0?(t.lineWidth=this.gridLineWidth,t.strokeStyle=this.gridLineColor):(t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor),a&&(t.moveTo(n,this.endPoint),t.lineTo(n,this.startPoint-3),t.stroke(),t.closePath()),t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor,t.beginPath(),t.moveTo(n,this.endPoint),t.lineTo(n,this.endPoint+5),t.stroke(),t.closePath(),t.save(),t.translate(s,o?this.endPoint+12:this.endPoint+8),t.rotate(-1*S(this.xLabelRotation)),t.font=this.font,t.textAlign=o?"right":"center",t.textBaseline=o?"middle":"top",t.fillText(i,0,0),t.restore()},this))}}),e.RadialScale=e.Element.extend({initialize:function(){this.size=m([this.height,this.width]),this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2},calculateCenterOffset:function(t){var i=this.drawingArea/(this.max-this.min);return(t-this.min)*i},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=[];for(var t=v(this.stepValue),i=0;i<=this.steps;i++)this.yLabels.push(C(this.templateString,{value:(this.min+i*this.stepValue).toFixed(t)}))},getCircumference:function(){return 2*Math.PI/this.valuesCount},setScaleSize:function(){var t,i,e,s,n,o,a,h,l,r,c,u,d=m([this.height/2-this.pointLabelFontSize-5,this.width/2]),p=this.width,g=0;for(this.ctx.font=W(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily),i=0;i<this.valuesCount;i++)t=this.getPointPosition(i,d),e=this.ctx.measureText(C(this.templateString,{value:this.labels[i]})).width+5,0===i||i===this.valuesCount/2?(s=e/2,t.x+s>p&&(p=t.x+s,n=i),t.x-s<g&&(g=t.x-s,a=i)):i<this.valuesCount/2?t.x+e>p&&(p=t.x+e,n=i):i>this.valuesCount/2&&t.x-e<g&&(g=t.x-e,a=i);l=g,r=Math.ceil(p-this.width),o=this.getIndexAngle(n),h=this.getIndexAngle(a),c=r/Math.sin(o+Math.PI/2),u=l/Math.sin(h+Math.PI/2),c=f(c)?c:0,u=f(u)?u:0,this.drawingArea=d-(u+c)/2,this.setCenterPoint(u,c)},setCenterPoint:function(t,i){var e=this.width-i-this.drawingArea,s=t+this.drawingArea;this.xCenter=(s+e)/2,this.yCenter=this.height/2},getIndexAngle:function(t){var i=2*Math.PI/this.valuesCount;return t*i-Math.PI/2},getPointPosition:function(t,i){var e=this.getIndexAngle(t);return{x:Math.cos(e)*i+this.xCenter,y:Math.sin(e)*i+this.yCenter}},draw:function(){if(this.display){var t=this.ctx;if(n(this.yLabels,function(i,e){if(e>0){var s,n=e*(this.drawingArea/this.steps),o=this.yCenter-n;if(this.lineWidth>0)if(t.strokeStyle=this.lineColor,t.lineWidth=this.lineWidth,this.lineArc)t.beginPath(),t.arc(this.xCenter,this.yCenter,n,0,2*Math.PI),t.closePath(),t.stroke();else{t.beginPath();for(var a=0;a<this.valuesCount;a++)s=this.getPointPosition(a,this.calculateCenterOffset(this.min+e*this.stepValue)),0===a?t.moveTo(s.x,s.y):t.lineTo(s.x,s.y);t.closePath(),t.stroke()}if(this.showLabels){if(t.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.showLabelBackdrop){var h=t.measureText(i).width;t.fillStyle=this.backdropColor,t.fillRect(this.xCenter-h/2-this.backdropPaddingX,o-this.fontSize/2-this.backdropPaddingY,h+2*this.backdropPaddingX,this.fontSize+2*this.backdropPaddingY)}t.textAlign="center",t.textBaseline="middle",t.fillStyle=this.fontColor,t.fillText(i,this.xCenter,o)}}},this),!this.lineArc){t.lineWidth=this.angleLineWidth,t.strokeStyle=this.angleLineColor;for(var i=this.valuesCount-1;i>=0;i--){var e=null,s=null;if(this.angleLineWidth>0&&(e=this.calculateCenterOffset(this.max),s=this.getPointPosition(i,e),t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(s.x,s.y),t.stroke(),t.closePath()),this.backgroundColors&&this.backgroundColors.length==this.valuesCount){null==e&&(e=this.calculateCenterOffset(this.max)),null==s&&(s=this.getPointPosition(i,e));var o=this.getPointPosition(0===i?this.valuesCount-1:i-1,e),a=this.getPointPosition(i===this.valuesCount-1?0:i+1,e),h={x:(o.x+s.x)/2,y:(o.y+s.y)/2},l={x:(s.x+a.x)/2,y:(s.y+a.y)/2};t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(h.x,h.y),t.lineTo(s.x,s.y),t.lineTo(l.x,l.y),t.fillStyle=this.backgroundColors[i],t.fill(),t.closePath()}var r=this.getPointPosition(i,this.calculateCenterOffset(this.max)+5);t.font=W(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily),t.fillStyle=this.pointLabelFontColor;var c=this.labels.length,u=this.labels.length/2,d=u/2,p=d>i||i>c-d,f=i===d||i===c-d;0===i?t.textAlign="center":i===u?t.textAlign="center":u>i?t.textAlign="left":t.textAlign="right",f?t.textBaseline="middle":p?t.textBaseline="bottom":t.textBaseline="top",t.fillText(this.labels[i],r.x,r.y)}}}}}),e.animationService={frameDuration:17,animations:[],dropFrames:0,addAnimation:function(t,i){for(var e=0;e<this.animations.length;++e)if(this.animations[e].chartInstance===t)return void(this.animations[e].animationObject=i);this.animations.push({chartInstance:t,animationObject:i}),1==this.animations.length&&s.requestAnimFrame.call(window,this.digestWrapper)},cancelAnimation:function(t){var i=s.findNextWhere(this.animations,function(i){return i.chartInstance===t});i&&this.animations.splice(i,1)},digestWrapper:function(){e.animationService.startDigest.call(e.animationService)},startDigest:function(){var t=Date.now(),i=0;this.dropFrames>1&&(i=Math.floor(this.dropFrames),this.dropFrames-=i);for(var e=0;e<this.animations.length;e++)null===this.animations[e].animationObject.currentStep&&(this.animations[e].animationObject.currentStep=0),this.animations[e].animationObject.currentStep+=1+i,this.animations[e].animationObject.currentStep>this.animations[e].animationObject.numSteps&&(this.animations[e].animationObject.currentStep=this.animations[e].animationObject.numSteps),this.animations[e].animationObject.render(this.animations[e].chartInstance,this.animations[e].animationObject),this.animations[e].animationObject.currentStep==this.animations[e].animationObject.numSteps&&(this.animations[e].animationObject.onAnimationComplete.call(this.animations[e].chartInstance),this.animations.splice(e,1),e--);var n=Date.now(),o=n-t-this.frameDuration,a=o/this.frameDuration;a>1&&(this.dropFrames+=a),this.animations.length>0&&s.requestAnimFrame.call(window,this.digestWrapper)}},s.addEvent(window,"resize",function(){var t;return function(){clearTimeout(t),t=setTimeout(function(){n(e.instances,function(t){t.options.responsive&&t.resize(t.render,!0)})},50)}}()),p?define(function(){return e}):"object"==typeof module&&module.exports&&(module.exports=e),t.Chart=e,e.noConflict=function(){return t.Chart=i,e}}).call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleBeginAtZero:!0,scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,scaleShowHorizontalLines:!0,scaleShowVerticalLines:!0,barShowStroke:!0,barStrokeWidth:2,barValueSpacing:5,barDatasetSpacing:1,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<datasets.length; i++){%><li><span style="background-color:<%=datasets[i].fillColor%>"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>'};i.Type.extend({name:"Bar",defaults:s,initialize:function(t){var s=this.options;this.ScaleClass=i.Scale.extend({offsetGridLines:!0,calculateBarX:function(t,i,e){var n=this.calculateBaseWidth(),o=this.calculateX(e)-n/2,a=this.calculateBarWidth(t);return o+a*i+i*s.barDatasetSpacing+a/2},calculateBaseWidth:function(){return this.calculateX(1)-this.calculateX(0)-2*s.barValueSpacing},calculateBarWidth:function(t){var i=this.calculateBaseWidth()-(t-1)*s.barDatasetSpacing;
+return i/t}}),this.datasets=[],this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getBarsAtEvent(t):[];this.eachBars(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),this.BarClass=i.Rectangle.extend({strokeWidth:this.options.barStrokeWidth,showStroke:this.options.barShowStroke,ctx:this.chart.ctx}),e.each(t.datasets,function(i,s){var n={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,bars:[]};this.datasets.push(n),e.each(i.data,function(e,s){n.bars.push(new this.BarClass({value:e,label:t.labels[s],datasetLabel:i.label,strokeColor:i.strokeColor,fillColor:i.fillColor,highlightFill:i.highlightFill||i.fillColor,highlightStroke:i.highlightStroke||i.strokeColor}))},this)},this),this.buildScale(t.labels),this.BarClass.prototype.base=this.scale.endPoint,this.eachBars(function(t,i,s){e.extend(t,{width:this.scale.calculateBarWidth(this.datasets.length),x:this.scale.calculateBarX(this.datasets.length,s,i),y:this.scale.endPoint}),t.save()},this),this.render()},update:function(){this.scale.update(),e.each(this.activeElements,function(t){t.restore(["fillColor","strokeColor"])}),this.eachBars(function(t){t.save()}),this.render()},eachBars:function(t){e.each(this.datasets,function(i,s){e.each(i.bars,t,this,s)},this)},getBarsAtEvent:function(t){for(var i,s=[],n=e.getRelativePosition(t),o=function(t){s.push(t.bars[i])},a=0;a<this.datasets.length;a++)for(i=0;i<this.datasets[a].bars.length;i++)if(this.datasets[a].bars[i].inRange(n.x,n.y))return e.each(this.datasets,o),s;return s},buildScale:function(t){var i=this,s=function(){var t=[];return i.eachBars(function(i){t.push(i.value)}),t},n={templateString:this.options.scaleLabel,height:this.chart.height,width:this.chart.width,ctx:this.chart.ctx,textColor:this.options.scaleFontColor,fontSize:this.options.scaleFontSize,fontStyle:this.options.scaleFontStyle,fontFamily:this.options.scaleFontFamily,valuesCount:t.length,beginAtZero:this.options.scaleBeginAtZero,integersOnly:this.options.scaleIntegersOnly,calculateYRange:function(t){var i=e.calculateScaleRange(s(),t,this.fontSize,this.beginAtZero,this.integersOnly);e.extend(this,i)},xLabels:t,font:e.fontString(this.options.scaleFontSize,this.options.scaleFontStyle,this.options.scaleFontFamily),lineWidth:this.options.scaleLineWidth,lineColor:this.options.scaleLineColor,showHorizontalLines:this.options.scaleShowHorizontalLines,showVerticalLines:this.options.scaleShowVerticalLines,gridLineWidth:this.options.scaleShowGridLines?this.options.scaleGridLineWidth:0,gridLineColor:this.options.scaleShowGridLines?this.options.scaleGridLineColor:"rgba(0,0,0,0)",padding:this.options.showScale?0:this.options.barShowStroke?this.options.barStrokeWidth:0,showLabels:this.options.scaleShowLabels,display:this.options.showScale};this.options.scaleOverride&&e.extend(n,{calculateYRange:e.noop,steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}),this.scale=new this.ScaleClass(n)},addData:function(t,i){e.each(t,function(t,e){this.datasets[e].bars.push(new this.BarClass({value:t,label:i,datasetLabel:this.datasets[e].label,x:this.scale.calculateBarX(this.datasets.length,e,this.scale.valuesCount+1),y:this.scale.endPoint,width:this.scale.calculateBarWidth(this.datasets.length),base:this.scale.endPoint,strokeColor:this.datasets[e].strokeColor,fillColor:this.datasets[e].fillColor}))},this),this.scale.addXLabel(i),this.update()},removeData:function(){this.scale.removeXLabel(),e.each(this.datasets,function(t){t.bars.shift()},this),this.update()},reflow:function(){e.extend(this.BarClass.prototype,{y:this.scale.endPoint,base:this.scale.endPoint});var t=e.extend({height:this.chart.height,width:this.chart.width});this.scale.update(t)},draw:function(t){var i=t||1;this.clear();this.chart.ctx;this.scale.draw(i),e.each(this.datasets,function(t,s){e.each(t.bars,function(t,e){t.hasValue()&&(t.base=this.scale.endPoint,t.transition({x:this.scale.calculateBarX(this.datasets.length,s,e),y:this.scale.calculateY(t.value),width:this.scale.calculateBarWidth(this.datasets.length)},i).draw())},this)},this)}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,percentageInnerCutout:50,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"><%if(segments[i].label){%><%=segments[i].label%><%}%></span></li><%}%></ul>'};i.Type.extend({name:"Doughnut",defaults:s,initialize:function(t){this.segments=[],this.outerRadius=(e.min([this.chart.width,this.chart.height])-this.options.segmentStrokeWidth/2)/2,this.SegmentArc=i.Arc.extend({ctx:this.chart.ctx,x:this.chart.width/2,y:this.chart.height/2}),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getSegmentsAtEvent(t):[];e.each(this.segments,function(t){t.restore(["fillColor"])}),e.each(i,function(t){t.fillColor=t.highlightColor}),this.showTooltip(i)}),this.calculateTotal(t),e.each(t,function(i,e){i.color||(i.color="hsl("+360*e/t.length+", 100%, 50%)"),this.addData(i,e,!0)},this),this.render()},getSegmentsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.segments,function(t){t.inRange(s.x,s.y)&&i.push(t)},this),i},addData:function(t,e,s){var n=void 0!==e?e:this.segments.length;"undefined"==typeof t.color&&(t.color=i.defaults.global.segmentColorDefault[n%i.defaults.global.segmentColorDefault.length],t.highlight=i.defaults.global.segmentHighlightColorDefaults[n%i.defaults.global.segmentHighlightColorDefaults.length]),this.segments.splice(n,0,new this.SegmentArc({value:t.value,outerRadius:this.options.animateScale?0:this.outerRadius,innerRadius:this.options.animateScale?0:this.outerRadius/100*this.options.percentageInnerCutout,fillColor:t.color,highlightColor:t.highlight||t.color,showStroke:this.options.segmentShowStroke,strokeWidth:this.options.segmentStrokeWidth,strokeColor:this.options.segmentStrokeColor,startAngle:1.5*Math.PI,circumference:this.options.animateRotate?0:this.calculateCircumference(t.value),label:t.label})),s||(this.reflow(),this.update())},calculateCircumference:function(t){return this.total>0?2*Math.PI*(t/this.total):0},calculateTotal:function(t){this.total=0,e.each(t,function(t){this.total+=Math.abs(t.value)},this)},update:function(){this.calculateTotal(this.segments),e.each(this.activeElements,function(t){t.restore(["fillColor"])}),e.each(this.segments,function(t){t.save()}),this.render()},removeData:function(t){var i=e.isNumber(t)?t:this.segments.length-1;this.segments.splice(i,1),this.reflow(),this.update()},reflow:function(){e.extend(this.SegmentArc.prototype,{x:this.chart.width/2,y:this.chart.height/2}),this.outerRadius=(e.min([this.chart.width,this.chart.height])-this.options.segmentStrokeWidth/2)/2,e.each(this.segments,function(t){t.update({outerRadius:this.outerRadius,innerRadius:this.outerRadius/100*this.options.percentageInnerCutout})},this)},draw:function(t){var i=t?t:1;this.clear(),e.each(this.segments,function(t,e){t.transition({circumference:this.calculateCircumference(t.value),outerRadius:this.outerRadius,innerRadius:this.outerRadius/100*this.options.percentageInnerCutout},i),t.endAngle=t.startAngle+t.circumference,t.draw(),0===e&&(t.startAngle=1.5*Math.PI),e<this.segments.length-1&&(this.segments[e+1].startAngle=t.endAngle)},this)}}),i.types.Doughnut.extend({name:"Pie",defaults:e.merge(s,{percentageInnerCutout:0})})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,scaleShowHorizontalLines:!0,scaleShowVerticalLines:!0,bezierCurve:!0,bezierCurveTension:.4,pointDot:!0,pointDotRadius:4,pointDotStrokeWidth:1,pointHitDetectionRadius:20,datasetStroke:!0,datasetStrokeWidth:2,datasetFill:!0,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<datasets.length; i++){%><li><span style="background-color:<%=datasets[i].strokeColor%>"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>',offsetGridLines:!1};i.Type.extend({name:"Line",defaults:s,initialize:function(t){this.PointClass=i.Point.extend({offsetGridLines:this.options.offsetGridLines,strokeWidth:this.options.pointDotStrokeWidth,radius:this.options.pointDotRadius,display:this.options.pointDot,hitDetectionRadius:this.options.pointHitDetectionRadius,ctx:this.chart.ctx,inRange:function(t){return Math.pow(t-this.x,2)<Math.pow(this.radius+this.hitDetectionRadius,2)}}),this.datasets=[],this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getPointsAtEvent(t):[];this.eachPoints(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,pointColor:i.pointColor,pointStrokeColor:i.pointStrokeColor,points:[]};this.datasets.push(s),e.each(i.data,function(e,n){s.points.push(new this.PointClass({value:e,label:t.labels[n],datasetLabel:i.label,strokeColor:i.pointStrokeColor,fillColor:i.pointColor,highlightFill:i.pointHighlightFill||i.pointColor,highlightStroke:i.pointHighlightStroke||i.pointStrokeColor}))},this),this.buildScale(t.labels),this.eachPoints(function(t,i){e.extend(t,{x:this.scale.calculateX(i),y:this.scale.endPoint}),t.save()},this)},this),this.render()},update:function(){this.scale.update(),e.each(this.activeElements,function(t){t.restore(["fillColor","strokeColor"])}),this.eachPoints(function(t){t.save()}),this.render()},eachPoints:function(t){e.each(this.datasets,function(i){e.each(i.points,t,this)},this)},getPointsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.datasets,function(t){e.each(t.points,function(t){t.inRange(s.x,s.y)&&i.push(t)})},this),i},buildScale:function(t){var s=this,n=function(){var t=[];return s.eachPoints(function(i){t.push(i.value)}),t},o={templateString:this.options.scaleLabel,height:this.chart.height,width:this.chart.width,ctx:this.chart.ctx,textColor:this.options.scaleFontColor,offsetGridLines:this.options.offsetGridLines,fontSize:this.options.scaleFontSize,fontStyle:this.options.scaleFontStyle,fontFamily:this.options.scaleFontFamily,valuesCount:t.length,beginAtZero:this.options.scaleBeginAtZero,integersOnly:this.options.scaleIntegersOnly,calculateYRange:function(t){var i=e.calculateScaleRange(n(),t,this.fontSize,this.beginAtZero,this.integersOnly);e.extend(this,i)},xLabels:t,font:e.fontString(this.options.scaleFontSize,this.options.scaleFontStyle,this.options.scaleFontFamily),lineWidth:this.options.scaleLineWidth,lineColor:this.options.scaleLineColor,showHorizontalLines:this.options.scaleShowHorizontalLines,showVerticalLines:this.options.scaleShowVerticalLines,gridLineWidth:this.options.scaleShowGridLines?this.options.scaleGridLineWidth:0,gridLineColor:this.options.scaleShowGridLines?this.options.scaleGridLineColor:"rgba(0,0,0,0)",padding:this.options.showScale?0:this.options.pointDotRadius+this.options.pointDotStrokeWidth,showLabels:this.options.scaleShowLabels,display:this.options.showScale};this.options.scaleOverride&&e.extend(o,{calculateYRange:e.noop,steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}),this.scale=new i.Scale(o)},addData:function(t,i){e.each(t,function(t,e){this.datasets[e].points.push(new this.PointClass({value:t,label:i,datasetLabel:this.datasets[e].label,x:this.scale.calculateX(this.scale.valuesCount+1),y:this.scale.endPoint,strokeColor:this.datasets[e].pointStrokeColor,fillColor:this.datasets[e].pointColor}))},this),this.scale.addXLabel(i),this.update()},removeData:function(){this.scale.removeXLabel(),e.each(this.datasets,function(t){t.points.shift()},this),this.update()},reflow:function(){var t=e.extend({height:this.chart.height,width:this.chart.width});this.scale.update(t)},draw:function(t){var i=t||1;this.clear();var s=this.chart.ctx,n=function(t){return null!==t.value},o=function(t,i,s){return e.findNextWhere(i,n,s)||t},a=function(t,i,s){return e.findPreviousWhere(i,n,s)||t};this.scale&&(this.scale.draw(i),e.each(this.datasets,function(t){var h=e.where(t.points,n);e.each(t.points,function(t,e){t.hasValue()&&t.transition({y:this.scale.calculateY(t.value),x:this.scale.calculateX(e)},i)},this),this.options.bezierCurve&&e.each(h,function(t,i){var s=i>0&&i<h.length-1?this.options.bezierCurveTension:0;t.controlPoints=e.splineCurve(a(t,h,i),t,o(t,h,i),s),t.controlPoints.outer.y>this.scale.endPoint?t.controlPoints.outer.y=this.scale.endPoint:t.controlPoints.outer.y<this.scale.startPoint&&(t.controlPoints.outer.y=this.scale.startPoint),t.controlPoints.inner.y>this.scale.endPoint?t.controlPoints.inner.y=this.scale.endPoint:t.controlPoints.inner.y<this.scale.startPoint&&(t.controlPoints.inner.y=this.scale.startPoint)},this),s.lineWidth=this.options.datasetStrokeWidth,s.strokeStyle=t.strokeColor,s.beginPath(),e.each(h,function(t,i){if(0===i)s.moveTo(t.x,t.y);else if(this.options.bezierCurve){var e=a(t,h,i);s.bezierCurveTo(e.controlPoints.outer.x,e.controlPoints.outer.y,t.controlPoints.inner.x,t.controlPoints.inner.y,t.x,t.y)}else s.lineTo(t.x,t.y)},this),this.options.datasetStroke&&s.stroke(),this.options.datasetFill&&h.length>0&&(s.lineTo(h[h.length-1].x,this.scale.endPoint),s.lineTo(h[0].x,this.scale.endPoint),s.fillStyle=t.fillColor,s.closePath(),s.fill()),e.each(h,function(t){t.draw()})},this))}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleShowLabelBackdrop:!0,scaleBackdropColor:"rgba(255,255,255,0.75)",scaleBeginAtZero:!0,scaleBackdropPaddingY:2,scaleBackdropPaddingX:2,scaleShowLine:!0,segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"><%if(segments[i].label){%><%=segments[i].label%><%}%></span></li><%}%></ul>'};i.Type.extend({name:"PolarArea",defaults:s,initialize:function(t){this.segments=[],this.SegmentArc=i.Arc.extend({showStroke:this.options.segmentShowStroke,strokeWidth:this.options.segmentStrokeWidth,strokeColor:this.options.segmentStrokeColor,ctx:this.chart.ctx,innerRadius:0,x:this.chart.width/2,y:this.chart.height/2}),this.scale=new i.RadialScale({display:this.options.showScale,fontStyle:this.options.scaleFontStyle,fontSize:this.options.scaleFontSize,fontFamily:this.options.scaleFontFamily,fontColor:this.options.scaleFontColor,showLabels:this.options.scaleShowLabels,showLabelBackdrop:this.options.scaleShowLabelBackdrop,backdropColor:this.options.scaleBackdropColor,backdropPaddingY:this.options.scaleBackdropPaddingY,backdropPaddingX:this.options.scaleBackdropPaddingX,lineWidth:this.options.scaleShowLine?this.options.scaleLineWidth:0,lineColor:this.options.scaleLineColor,lineArc:!0,width:this.chart.width,height:this.chart.height,xCenter:this.chart.width/2,yCenter:this.chart.height/2,ctx:this.chart.ctx,templateString:this.options.scaleLabel,valuesCount:t.length}),this.updateScaleRange(t),this.scale.update(),e.each(t,function(t,i){this.addData(t,i,!0)},this),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getSegmentsAtEvent(t):[];e.each(this.segments,function(t){t.restore(["fillColor"])}),e.each(i,function(t){t.fillColor=t.highlightColor}),this.showTooltip(i)}),this.render()},getSegmentsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.segments,function(t){t.inRange(s.x,s.y)&&i.push(t)},this),i},addData:function(t,i,e){var s=i||this.segments.length;this.segments.splice(s,0,new this.SegmentArc({fillColor:t.color,highlightColor:t.highlight||t.color,label:t.label,value:t.value,outerRadius:this.options.animateScale?0:this.scale.calculateCenterOffset(t.value),circumference:this.options.animateRotate?0:this.scale.getCircumference(),startAngle:1.5*Math.PI})),e||(this.reflow(),this.update())},removeData:function(t){var i=e.isNumber(t)?t:this.segments.length-1;this.segments.splice(i,1),this.reflow(),this.update()},calculateTotal:function(t){this.total=0,e.each(t,function(t){this.total+=t.value},this),this.scale.valuesCount=this.segments.length},updateScaleRange:function(t){var i=[];e.each(t,function(t){i.push(t.value)});var s=this.options.scaleOverride?{steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}:e.calculateScaleRange(i,e.min([this.chart.width,this.chart.height])/2,this.options.scaleFontSize,this.options.scaleBeginAtZero,this.options.scaleIntegersOnly);e.extend(this.scale,s,{size:e.min([this.chart.width,this.chart.height]),xCenter:this.chart.width/2,yCenter:this.chart.height/2})},update:function(){this.calculateTotal(this.segments),e.each(this.segments,function(t){t.save()}),this.reflow(),this.render()},reflow:function(){e.extend(this.SegmentArc.prototype,{x:this.chart.width/2,y:this.chart.height/2}),this.updateScaleRange(this.segments),this.scale.update(),e.extend(this.scale,{xCenter:this.chart.width/2,yCenter:this.chart.height/2}),e.each(this.segments,function(t){t.update({outerRadius:this.scale.calculateCenterOffset(t.value)})},this)},draw:function(t){var i=t||1;this.clear(),e.each(this.segments,function(t,e){t.transition({circumference:this.scale.getCircumference(),outerRadius:this.scale.calculateCenterOffset(t.value)},i),t.endAngle=t.startAngle+t.circumference,0===e&&(t.startAngle=1.5*Math.PI),e<this.segments.length-1&&(this.segments[e+1].startAngle=t.endAngle),t.draw()},this),this.scale.draw()}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers;i.Type.extend({name:"Radar",defaults:{scaleShowLine:!0,angleShowLineOut:!0,scaleShowLabels:!1,scaleBeginAtZero:!0,angleLineColor:"rgba(0,0,0,.1)",angleLineWidth:1,pointLabelFontFamily:"'Arial'",pointLabelFontStyle:"normal",pointLabelFontSize:10,pointLabelFontColor:"#666",pointDot:!0,pointDotRadius:3,pointDotStrokeWidth:1,pointHitDetectionRadius:20,datasetStroke:!0,datasetStrokeWidth:2,datasetFill:!0,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<datasets.length; i++){%><li><span style="background-color:<%=datasets[i].strokeColor%>"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>'},initialize:function(t){this.PointClass=i.Point.extend({strokeWidth:this.options.pointDotStrokeWidth,radius:this.options.pointDotRadius,display:this.options.pointDot,hitDetectionRadius:this.options.pointHitDetectionRadius,ctx:this.chart.ctx}),this.datasets=[],this.buildScale(t),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getPointsAtEvent(t):[];this.eachPoints(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,pointColor:i.pointColor,pointStrokeColor:i.pointStrokeColor,points:[]};this.datasets.push(s),e.each(i.data,function(e,n){var o;this.scale.animation||(o=this.scale.getPointPosition(n,this.scale.calculateCenterOffset(e))),s.points.push(new this.PointClass({value:e,label:t.labels[n],datasetLabel:i.label,x:this.options.animation?this.scale.xCenter:o.x,y:this.options.animation?this.scale.yCenter:o.y,strokeColor:i.pointStrokeColor,fillColor:i.pointColor,highlightFill:i.pointHighlightFill||i.pointColor,highlightStroke:i.pointHighlightStroke||i.pointStrokeColor}))},this)},this),this.render()},eachPoints:function(t){e.each(this.datasets,function(i){e.each(i.points,t,this)},this)},getPointsAtEvent:function(t){var i=e.getRelativePosition(t),s=e.getAngleFromPoint({x:this.scale.xCenter,y:this.scale.yCenter},i),n=2*Math.PI/this.scale.valuesCount,o=Math.round((s.angle-1.5*Math.PI)/n),a=[];return(o>=this.scale.valuesCount||0>o)&&(o=0),s.distance<=this.scale.drawingArea&&e.each(this.datasets,function(t){a.push(t.points[o])}),a},buildScale:function(t){this.scale=new i.RadialScale({display:this.options.showScale,fontStyle:this.options.scaleFontStyle,fontSize:this.options.scaleFontSize,fontFamily:this.options.scaleFontFamily,fontColor:this.options.scaleFontColor,showLabels:this.options.scaleShowLabels,showLabelBackdrop:this.options.scaleShowLabelBackdrop,backdropColor:this.options.scaleBackdropColor,backgroundColors:this.options.scaleBackgroundColors,backdropPaddingY:this.options.scaleBackdropPaddingY,backdropPaddingX:this.options.scaleBackdropPaddingX,lineWidth:this.options.scaleShowLine?this.options.scaleLineWidth:0,lineColor:this.options.scaleLineColor,angleLineColor:this.options.angleLineColor,angleLineWidth:this.options.angleShowLineOut?this.options.angleLineWidth:0,pointLabelFontColor:this.options.pointLabelFontColor,pointLabelFontSize:this.options.pointLabelFontSize,pointLabelFontFamily:this.options.pointLabelFontFamily,pointLabelFontStyle:this.options.pointLabelFontStyle,height:this.chart.height,width:this.chart.width,xCenter:this.chart.width/2,yCenter:this.chart.height/2,ctx:this.chart.ctx,templateString:this.options.scaleLabel,labels:t.labels,valuesCount:t.datasets[0].data.length}),this.scale.setScaleSize(),this.updateScaleRange(t.datasets),this.scale.buildYLabels()},updateScaleRange:function(t){var i=function(){var i=[];return e.each(t,function(t){t.data?i=i.concat(t.data):e.each(t.points,function(t){i.push(t.value)})}),i}(),s=this.options.scaleOverride?{steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}:e.calculateScaleRange(i,e.min([this.chart.width,this.chart.height])/2,this.options.scaleFontSize,this.options.scaleBeginAtZero,this.options.scaleIntegersOnly);e.extend(this.scale,s)},addData:function(t,i){this.scale.valuesCount++,e.each(t,function(t,e){var s=this.scale.getPointPosition(this.scale.valuesCount,this.scale.calculateCenterOffset(t));this.datasets[e].points.push(new this.PointClass({value:t,label:i,datasetLabel:this.datasets[e].label,x:s.x,y:s.y,strokeColor:this.datasets[e].pointStrokeColor,fillColor:this.datasets[e].pointColor}))},this),this.scale.labels.push(i),this.reflow(),this.update()},removeData:function(){this.scale.valuesCount--,this.scale.labels.shift(),e.each(this.datasets,function(t){t.points.shift()},this),this.reflow(),this.update()},update:function(){this.eachPoints(function(t){t.save()}),this.reflow(),this.render()},reflow:function(){e.extend(this.scale,{width:this.chart.width,height:this.chart.height,size:e.min([this.chart.width,this.chart.height]),xCenter:this.chart.width/2,yCenter:this.chart.height/2}),this.updateScaleRange(this.datasets),this.scale.setScaleSize(),this.scale.buildYLabels()},draw:function(t){var i=t||1,s=this.chart.ctx;this.clear(),this.scale.draw(),e.each(this.datasets,function(t){e.each(t.points,function(t,e){t.hasValue()&&t.transition(this.scale.getPointPosition(e,this.scale.calculateCenterOffset(t.value)),i)},this),s.lineWidth=this.options.datasetStrokeWidth,s.strokeStyle=t.strokeColor,s.beginPath(),e.each(t.points,function(t,i){0===i?s.moveTo(t.x,t.y):s.lineTo(t.x,t.y)},this),s.closePath(),s.stroke(),s.fillStyle=t.fillColor,this.options.datasetFill&&s.fill(),e.each(t.points,function(t){t.hasValue()&&t.draw()})},this)}})}.call(this);
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/tp/angular-chart.LICENSE b/web/gui/src/main/webapp/tp/angular-chart.LICENSE
new file mode 100644
index 0000000..f3bd714
--- /dev/null
+++ b/web/gui/src/main/webapp/tp/angular-chart.LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) Jerome Touffe-Blin ("Author")
+All rights reserved.
+
+The BSD License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/tp/angular-chart.css b/web/gui/src/main/webapp/tp/angular-chart.css
new file mode 100644
index 0000000..e6598ee
--- /dev/null
+++ b/web/gui/src/main/webapp/tp/angular-chart.css
@@ -0,0 +1,49 @@
+.chart-legend,
+.bar-legend,
+.line-legend,
+.pie-legend,
+.radar-legend,
+.polararea-legend,
+.doughnut-legend {
+  list-style-type: none;
+  margin-top: 5px;
+  text-align: center;
+  /* NOTE: Browsers automatically add 40px of padding-left to all lists, so we should offset that, otherwise the legend is off-center */
+  -webkit-padding-start: 0;
+  /* Webkit */
+  -moz-padding-start: 0;
+  /* Mozilla */
+  padding-left: 0;
+  /* IE (handles all cases, really, but we should also include the vendor-specific properties just to be safe) */
+}
+.chart-legend li,
+.bar-legend li,
+.line-legend li,
+.pie-legend li,
+.radar-legend li,
+.polararea-legend li,
+.doughnut-legend li {
+  display: inline-block;
+  white-space: nowrap;
+  position: relative;
+  margin-bottom: 4px;
+  border-radius: 5px;
+  padding: 2px 8px 2px 28px;
+  font-size: smaller;
+  cursor: default;
+}
+.chart-legend li span,
+.bar-legend li span,
+.line-legend li span,
+.pie-legend li span,
+.radar-legend li span,
+.polararea-legend li span,
+.doughnut-legend li span {
+  display: block;
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 20px;
+  height: 20px;
+  border-radius: 5px;
+}
diff --git a/web/gui/src/main/webapp/tp/angular-chart.js b/web/gui/src/main/webapp/tp/angular-chart.js
new file mode 100644
index 0000000..ff71905
--- /dev/null
+++ b/web/gui/src/main/webapp/tp/angular-chart.js
@@ -0,0 +1,372 @@
+/*!
+ * angular-chart.js
+ * http://jtblin.github.io/angular-chart.js/
+ * Version: 0.8.8
+ *
+ * Copyright 2015 Jerome Touffe-Blin
+ * Released under the BSD license
+ * https://github.com/jtblin/angular-chart.js/blob/master/LICENSE
+ */
+
+(function (factory) {
+  'use strict';
+  if (typeof exports === 'object') {
+    // Node/CommonJS
+    module.exports = factory(
+      typeof angular !== 'undefined' ? angular : require('angular'),
+      typeof Chart !== 'undefined' ? Chart : require('chart.js'));
+  }  else if (typeof define === 'function' && define.amd) {
+    // AMD. Register as an anonymous module.
+    define(['angular', 'chart'], factory);
+  } else {
+    // Browser globals
+    factory(angular, Chart);
+  }
+}(function (angular, Chart) {
+  'use strict';
+
+  Chart.defaults.global.responsive = true;
+  Chart.defaults.global.multiTooltipTemplate = '<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>';
+
+  Chart.defaults.global.colours = [
+    '#97BBCD', // blue
+    '#DCDCDC', // light grey
+    '#F7464A', // red
+    '#46BFBD', // green
+    '#FDB45C', // yellow
+    '#949FB1', // grey
+    '#4D5360'  // dark grey
+  ];
+
+  var usingExcanvas = typeof window.G_vmlCanvasManager === 'object' &&
+    window.G_vmlCanvasManager !== null &&
+    typeof window.G_vmlCanvasManager.initElement === 'function';
+
+  if (usingExcanvas) Chart.defaults.global.animation = false;
+
+  return angular.module('chart.js', [])
+    .provider('ChartJs', ChartJsProvider)
+    .factory('ChartJsFactory', ['ChartJs', '$timeout', ChartJsFactory])
+    .directive('chartBase', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory(); }])
+    .directive('chartLine', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Line'); }])
+    .directive('chartBar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Bar'); }])
+    .directive('chartRadar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Radar'); }])
+    .directive('chartDoughnut', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Doughnut'); }])
+    .directive('chartPie', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Pie'); }])
+    .directive('chartPolarArea', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('PolarArea'); }]);
+
+  /**
+   * Wrapper for chart.js
+   * Allows configuring chart js using the provider
+   *
+   * angular.module('myModule', ['chart.js']).config(function(ChartJsProvider) {
+   *   ChartJsProvider.setOptions({ responsive: true });
+   *   ChartJsProvider.setOptions('Line', { responsive: false });
+   * })))
+   */
+  function ChartJsProvider () {
+    var options = {};
+    var ChartJs = {
+      Chart: Chart,
+      getOptions: function (type) {
+        var typeOptions = type && options[type] || {};
+        return angular.extend({}, options, typeOptions);
+      }
+    };
+
+    /**
+     * Allow to set global options during configuration
+     */
+    this.setOptions = function (type, customOptions) {
+      // If no type was specified set option for the global object
+      if (! customOptions) {
+        customOptions = type;
+        options = angular.extend(options, customOptions);
+        return;
+      }
+      // Set options for the specific chart
+      options[type] = angular.extend(options[type] || {}, customOptions);
+    };
+
+    this.$get = function () {
+      return ChartJs;
+    };
+  }
+
+  function ChartJsFactory (ChartJs, $timeout) {
+    return function chart (type) {
+      return {
+        restrict: 'CA',
+        scope: {
+          data: '=?',
+          labels: '=?',
+          options: '=?',
+          series: '=?',
+          colours: '=?',
+          getColour: '=?',
+          chartType: '=',
+          legend: '@',
+          click: '=?',
+          hover: '=?',
+
+          chartData: '=?',
+          chartLabels: '=?',
+          chartOptions: '=?',
+          chartSeries: '=?',
+          chartColours: '=?',
+          chartLegend: '@',
+          chartClick: '=?',
+          chartHover: '=?'
+        },
+        link: function (scope, elem/*, attrs */) {
+          var chart, container = document.createElement('div');
+          container.className = 'chart-container';
+          elem.replaceWith(container);
+          container.appendChild(elem[0]);
+
+          if (usingExcanvas) window.G_vmlCanvasManager.initElement(elem[0]);
+
+          ['data', 'labels', 'options', 'series', 'colours', 'legend', 'click', 'hover'].forEach(deprecated);
+          function aliasVar (fromName, toName) {
+            scope.$watch(fromName, function (newVal) {
+              if (typeof newVal === 'undefined') return;
+              scope[toName] = newVal;
+            });
+          }
+          /* provide backward compatibility to "old" directive names, by
+           * having an alias point from the new names to the old names. */
+          aliasVar('chartData', 'data');
+          aliasVar('chartLabels', 'labels');
+          aliasVar('chartOptions', 'options');
+          aliasVar('chartSeries', 'series');
+          aliasVar('chartColours', 'colours');
+          aliasVar('chartLegend', 'legend');
+          aliasVar('chartClick', 'click');
+          aliasVar('chartHover', 'hover');
+
+          // Order of setting "watch" matter
+
+          scope.$watch('data', function (newVal, oldVal) {
+            if (! newVal || ! newVal.length || (Array.isArray(newVal[0]) && ! newVal[0].length)) return;
+            var chartType = type || scope.chartType;
+            if (! chartType) return;
+
+            if (chart) {
+              if (canUpdateChart(newVal, oldVal)) return updateChart(chart, newVal, scope, elem);
+              chart.destroy();
+            }
+
+            createChart(chartType);
+          }, true);
+
+          scope.$watch('series', resetChart, true);
+          scope.$watch('labels', resetChart, true);
+          scope.$watch('options', resetChart, true);
+          scope.$watch('colours', resetChart, true);
+
+          scope.$watch('chartType', function (newVal, oldVal) {
+            if (isEmpty(newVal)) return;
+            if (angular.equals(newVal, oldVal)) return;
+            if (chart) chart.destroy();
+            createChart(newVal);
+          });
+
+          scope.$on('$destroy', function () {
+            if (chart) chart.destroy();
+          });
+
+          function resetChart (newVal, oldVal) {
+            if (isEmpty(newVal)) return;
+            if (angular.equals(newVal, oldVal)) return;
+            var chartType = type || scope.chartType;
+            if (! chartType) return;
+
+            // chart.update() doesn't work for series and labels
+            // so we have to re-create the chart entirely
+            if (chart) chart.destroy();
+
+            createChart(chartType);
+          }
+
+          function createChart (type) {
+            if (isResponsive(type, scope) && elem[0].clientHeight === 0 && container.clientHeight === 0) {
+              return $timeout(function () {
+                createChart(type);
+              }, 50, false);
+            }
+            if (! scope.data || ! scope.data.length) return;
+            scope.getColour = typeof scope.getColour === 'function' ? scope.getColour : getRandomColour;
+            scope.colours = getColours(type, scope);
+            var cvs = elem[0], ctx = cvs.getContext('2d');
+            var data = Array.isArray(scope.data[0]) ?
+              getDataSets(scope.labels, scope.data, scope.series || [], scope.colours) :
+              getData(scope.labels, scope.data, scope.colours);
+            var options = angular.extend({}, ChartJs.getOptions(type), scope.options);
+            chart = new ChartJs.Chart(ctx)[type](data, options);
+            scope.$emit('create', chart);
+
+            // Bind events
+            cvs.onclick = scope.click ? getEventHandler(scope, chart, 'click', false) : angular.noop;
+            cvs.onmousemove = scope.hover ? getEventHandler(scope, chart, 'hover', true) : angular.noop;
+
+            if (scope.legend && scope.legend !== 'false') setLegend(elem, chart);
+          }
+
+          function deprecated (attr) {
+            if (typeof console !== 'undefined' && ChartJs.getOptions().env !== 'test') {
+              var warn = typeof console.warn === 'function' ? console.warn : console.log;
+              if (!! scope[attr]) {
+                warn.call(console, '"%s" is deprecated and will be removed in a future version. ' +
+                  'Please use "chart-%s" instead.', attr, attr);
+              }
+            }
+          }
+        }
+      };
+    };
+
+    function canUpdateChart (newVal, oldVal) {
+      if (newVal && oldVal && newVal.length && oldVal.length) {
+        return Array.isArray(newVal[0]) ?
+        newVal.length === oldVal.length && newVal.every(function (element, index) {
+          return element.length === oldVal[index].length; }) :
+          oldVal.reduce(sum, 0) > 0 ? newVal.length === oldVal.length : false;
+      }
+      return false;
+    }
+
+    function sum (carry, val) {
+      return carry + val;
+    }
+
+    function getEventHandler (scope, chart, action, triggerOnlyOnChange) {
+      var lastState = null;
+      return function (evt) {
+        var atEvent = chart.getPointsAtEvent || chart.getBarsAtEvent || chart.getSegmentsAtEvent;
+        if (atEvent) {
+          var activePoints = atEvent.call(chart, evt);
+          if (triggerOnlyOnChange === false || angular.equals(lastState, activePoints) === false) {
+            lastState = activePoints;
+            scope[action](activePoints, evt);
+            scope.$apply();
+          }
+        }
+      };
+    }
+
+    function getColours (type, scope) {
+      var colours = angular.copy(scope.colours ||
+        ChartJs.getOptions(type).colours ||
+        Chart.defaults.global.colours
+      );
+      while (colours.length < scope.data.length) {
+        colours.push(scope.getColour());
+      }
+      return colours.map(convertColour);
+    }
+
+    function convertColour (colour) {
+      if (typeof colour === 'object' && colour !== null) return colour;
+      if (typeof colour === 'string' && colour[0] === '#') return getColour(hexToRgb(colour.substr(1)));
+      return getRandomColour();
+    }
+
+    function getRandomColour () {
+      var colour = [getRandomInt(0, 255), getRandomInt(0, 255), getRandomInt(0, 255)];
+      return getColour(colour);
+    }
+
+    function getColour (colour) {
+      return {
+        fillColor: rgba(colour, 0.2),
+        strokeColor: rgba(colour, 1),
+        pointColor: rgba(colour, 1),
+        pointStrokeColor: '#fff',
+        pointHighlightFill: '#fff',
+        pointHighlightStroke: rgba(colour, 0.8)
+      };
+    }
+
+    function getRandomInt (min, max) {
+      return Math.floor(Math.random() * (max - min + 1)) + min;
+    }
+
+    function rgba (colour, alpha) {
+      if (usingExcanvas) {
+        // rgba not supported by IE8
+        return 'rgb(' + colour.join(',') + ')';
+      } else {
+        return 'rgba(' + colour.concat(alpha).join(',') + ')';
+      }
+    }
+
+    // Credit: http://stackoverflow.com/a/11508164/1190235
+    function hexToRgb (hex) {
+      var bigint = parseInt(hex, 16),
+        r = (bigint >> 16) & 255,
+        g = (bigint >> 8) & 255,
+        b = bigint & 255;
+
+      return [r, g, b];
+    }
+
+    function getDataSets (labels, data, series, colours) {
+      return {
+        labels: labels,
+        datasets: data.map(function (item, i) {
+          return angular.extend({}, colours[i], {
+            label: series[i],
+            data: item
+          });
+        })
+      };
+    }
+
+    function getData (labels, data, colours) {
+      return labels.map(function (label, i) {
+        return angular.extend({}, colours[i], {
+          label: label,
+          value: data[i],
+          color: colours[i].strokeColor,
+          highlight: colours[i].pointHighlightStroke
+        });
+      });
+    }
+
+    function setLegend (elem, chart) {
+      var $parent = elem.parent(),
+          $oldLegend = $parent.find('chart-legend'),
+          legend = '<chart-legend>' + chart.generateLegend() + '</chart-legend>';
+      if ($oldLegend.length) $oldLegend.replaceWith(legend);
+      else $parent.append(legend);
+    }
+
+    function updateChart (chart, values, scope, elem) {
+      if (Array.isArray(scope.data[0])) {
+        chart.datasets.forEach(function (dataset, i) {
+          (dataset.points || dataset.bars).forEach(function (dataItem, j) {
+            dataItem.value = values[i][j];
+          });
+        });
+      } else {
+        chart.segments.forEach(function (segment, i) {
+          segment.value = values[i];
+        });
+      }
+      chart.update();
+      scope.$emit('update', chart);
+      if (scope.legend && scope.legend !== 'false') setLegend(elem, chart);
+    }
+
+    function isEmpty (value) {
+      return ! value ||
+        (Array.isArray(value) && ! value.length) ||
+        (typeof value === 'object' && ! Object.keys(value).length);
+    }
+
+    function isResponsive (type, scope) {
+      var options = angular.extend({}, Chart.defaults.global, ChartJs.getOptions(type), scope.options);
+      return options.responsive;
+    }
+  }
+}));
diff --git a/web/gui/src/main/webapp/tp/angular-chart.min.css b/web/gui/src/main/webapp/tp/angular-chart.min.css
new file mode 100644
index 0000000..86f5488
--- /dev/null
+++ b/web/gui/src/main/webapp/tp/angular-chart.min.css
@@ -0,0 +1,2 @@
+.chart-legend,.bar-legend,.line-legend,.pie-legend,.radar-legend,.polararea-legend,.doughnut-legend{list-style-type:none;margin-top:5px;text-align:center;-webkit-padding-start:0;-moz-padding-start:0;padding-left:0}.chart-legend li,.bar-legend li,.line-legend li,.pie-legend li,.radar-legend li,.polararea-legend li,.doughnut-legend li{display:inline-block;white-space:nowrap;position:relative;margin-bottom:4px;border-radius:5px;padding:2px 8px 2px 28px;font-size:smaller;cursor:default}.chart-legend li span,.bar-legend li span,.line-legend li span,.pie-legend li span,.radar-legend li span,.polararea-legend li span,.doughnut-legend li span{display:block;position:absolute;left:0;top:0;width:20px;height:20px;border-radius:5px}
+/*# sourceMappingURL=angular-chart.min.css.map */
diff --git a/web/gui/src/main/webapp/tp/angular-chart.min.js b/web/gui/src/main/webapp/tp/angular-chart.min.js
new file mode 100644
index 0000000..bc9598f
--- /dev/null
+++ b/web/gui/src/main/webapp/tp/angular-chart.min.js
@@ -0,0 +1,2 @@
+!function(t){"use strict";"object"==typeof exports?module.exports=t("undefined"!=typeof angular?angular:require("angular"),"undefined"!=typeof Chart?Chart:require("chart.js")):"function"==typeof define&&define.amd?define(["angular","chart"],t):t(angular,Chart)}(function(t,e){"use strict";function n(){var n={},r={Chart:e,getOptions:function(e){var r=e&&n[e]||{};return t.extend({},n,r)}};this.setOptions=function(e,r){return r?void(n[e]=t.extend(n[e]||{},r)):(r=e,void(n=t.extend(n,r)))},this.$get=function(){return r}}function r(n,r){function o(t,e){return t&&e&&t.length&&e.length?Array.isArray(t[0])?t.length===e.length&&t.every(function(t,n){return t.length===e[n].length}):e.reduce(i,0)>0?t.length===e.length:!1:!1}function i(t,e){return t+e}function c(e,n,r,a){var o=null;return function(i){var c=n.getPointsAtEvent||n.getBarsAtEvent||n.getSegmentsAtEvent;if(c){var l=c.call(n,i);(a===!1||t.equals(o,l)===!1)&&(o=l,e[r](l,i),e.$apply())}}}function l(r,a){for(var o=t.copy(a.colours||n.getOptions(r).colours||e.defaults.global.colours);o.length<a.data.length;)o.push(a.getColour());return o.map(u)}function u(t){return"object"==typeof t&&null!==t?t:"string"==typeof t&&"#"===t[0]?f(g(t.substr(1))):s()}function s(){var t=[h(0,255),h(0,255),h(0,255)];return f(t)}function f(t){return{fillColor:d(t,.2),strokeColor:d(t,1),pointColor:d(t,1),pointStrokeColor:"#fff",pointHighlightFill:"#fff",pointHighlightStroke:d(t,.8)}}function h(t,e){return Math.floor(Math.random()*(e-t+1))+t}function d(t,e){return a?"rgb("+t.join(",")+")":"rgba("+t.concat(e).join(",")+")"}function g(t){var e=parseInt(t,16),n=e>>16&255,r=e>>8&255,a=255&e;return[n,r,a]}function p(e,n,r,a){return{labels:e,datasets:n.map(function(e,n){return t.extend({},a[n],{label:r[n],data:e})})}}function v(e,n,r){return e.map(function(e,a){return t.extend({},r[a],{label:e,value:n[a],color:r[a].strokeColor,highlight:r[a].pointHighlightStroke})})}function y(t,e){var n=t.parent(),r=n.find("chart-legend"),a="<chart-legend>"+e.generateLegend()+"</chart-legend>";r.length?r.replaceWith(a):n.append(a)}function C(t,e,n,r){Array.isArray(n.data[0])?t.datasets.forEach(function(t,n){(t.points||t.bars).forEach(function(t,r){t.value=e[n][r]})}):t.segments.forEach(function(t,n){t.value=e[n]}),t.update(),n.$emit("update",t),n.legend&&"false"!==n.legend&&y(r,t)}function b(t){return!t||Array.isArray(t)&&!t.length||"object"==typeof t&&!Object.keys(t).length}function m(r,a){var o=t.extend({},e.defaults.global,n.getOptions(r),a.options);return o.responsive}return function(e){return{restrict:"CA",scope:{data:"=?",labels:"=?",options:"=?",series:"=?",colours:"=?",getColour:"=?",chartType:"=",legend:"@",click:"=?",hover:"=?",chartData:"=?",chartLabels:"=?",chartOptions:"=?",chartSeries:"=?",chartColours:"=?",chartLegend:"@",chartClick:"=?",chartHover:"=?"},link:function(i,u){function f(t,e){i.$watch(t,function(t){"undefined"!=typeof t&&(i[e]=t)})}function h(n,r){if(!b(n)&&!t.equals(n,r)){var a=e||i.chartType;a&&(w&&w.destroy(),d(a))}}function d(e){if(m(e,i)&&0===u[0].clientHeight&&0===A.clientHeight)return r(function(){d(e)},50,!1);if(i.data&&i.data.length){i.getColour="function"==typeof i.getColour?i.getColour:s,i.colours=l(e,i);var a=u[0],o=a.getContext("2d"),f=Array.isArray(i.data[0])?p(i.labels,i.data,i.series||[],i.colours):v(i.labels,i.data,i.colours),h=t.extend({},n.getOptions(e),i.options);w=new n.Chart(o)[e](f,h),i.$emit("create",w),a.onclick=i.click?c(i,w,"click",!1):t.noop,a.onmousemove=i.hover?c(i,w,"hover",!0):t.noop,i.legend&&"false"!==i.legend&&y(u,w)}}function g(t){if("undefined"!=typeof console&&"test"!==n.getOptions().env){var e="function"==typeof console.warn?console.warn:console.log;i[t]&&e.call(console,'"%s" is deprecated and will be removed in a future version. Please use "chart-%s" instead.',t,t)}}var w,A=document.createElement("div");A.className="chart-container",u.replaceWith(A),A.appendChild(u[0]),a&&window.G_vmlCanvasManager.initElement(u[0]),["data","labels","options","series","colours","legend","click","hover"].forEach(g),f("chartData","data"),f("chartLabels","labels"),f("chartOptions","options"),f("chartSeries","series"),f("chartColours","colours"),f("chartLegend","legend"),f("chartClick","click"),f("chartHover","hover"),i.$watch("data",function(t,n){if(t&&t.length&&(!Array.isArray(t[0])||t[0].length)){var r=e||i.chartType;if(r){if(w){if(o(t,n))return C(w,t,i,u);w.destroy()}d(r)}}},!0),i.$watch("series",h,!0),i.$watch("labels",h,!0),i.$watch("options",h,!0),i.$watch("colours",h,!0),i.$watch("chartType",function(e,n){b(e)||t.equals(e,n)||(w&&w.destroy(),d(e))}),i.$on("$destroy",function(){w&&w.destroy()})}}}}e.defaults.global.responsive=!0,e.defaults.global.multiTooltipTemplate="<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>",e.defaults.global.colours=["#97BBCD","#DCDCDC","#F7464A","#46BFBD","#FDB45C","#949FB1","#4D5360"];var a="object"==typeof window.G_vmlCanvasManager&&null!==window.G_vmlCanvasManager&&"function"==typeof window.G_vmlCanvasManager.initElement;return a&&(e.defaults.global.animation=!1),t.module("chart.js",[]).provider("ChartJs",n).factory("ChartJsFactory",["ChartJs","$timeout",r]).directive("chartBase",["ChartJsFactory",function(t){return new t}]).directive("chartLine",["ChartJsFactory",function(t){return new t("Line")}]).directive("chartBar",["ChartJsFactory",function(t){return new t("Bar")}]).directive("chartRadar",["ChartJsFactory",function(t){return new t("Radar")}]).directive("chartDoughnut",["ChartJsFactory",function(t){return new t("Doughnut")}]).directive("chartPie",["ChartJsFactory",function(t){return new t("Pie")}]).directive("chartPolarArea",["ChartJsFactory",function(t){return new t("PolarArea")}])});
+//# sourceMappingURL=angular-chart.min.js.map
