From: Tarqwyn Date: Tue, 10 May 2016 14:01:30 +0000 (+0100) Subject: Added new plugin Callback `afterScaleUpdate` X-Git-Tag: v2.1.3~8^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=194cfa7db6c2fa121c8a7d34fcbbf9dafaae75e9;p=thirdparty%2FChart.js.git Added new plugin Callback `afterScaleUpdate` Following a Slack conversation tadd new Callback to allow updates to datasets config (ie borderColor) based on results of the calculated scale, A typical use case would be apply a Gradient fill. On branch feature_New_plugin_interface_afterScaleUpdate Changes to be committed: modified: dist/Chart.bundle.js modified: dist/Chart.bundle.min.js --- diff --git a/dist/Chart.bundle.js b/dist/Chart.bundle.js index dce6252b0..aef362a25 100644 --- a/dist/Chart.bundle.js +++ b/dist/Chart.bundle.js @@ -230,426 +230,158 @@ for (var name in colorNames) { reverseNames[colorNames[name]] = name; } -},{"color-name":5}],2:[function(require,module,exports){ -/* MIT license */ - -var convert = require("color-convert"), - string = require("chartjs-color-string"); - -var Color = function(obj) { - if (obj instanceof Color) return obj; - if (!(this instanceof Color)) return new Color(obj); - - this.values = { - rgb: [0, 0, 0], - hsl: [0, 0, 0], - hsv: [0, 0, 0], - hwb: [0, 0, 0], - cmyk: [0, 0, 0, 0], - alpha: 1 - } - - // parse Color() argument - if (typeof obj == "string") { - var vals = string.getRgba(obj); - if (vals) { - this.setValues("rgb", vals); - } else if (vals = string.getHsla(obj)) { - this.setValues("hsl", vals); - } else if (vals = string.getHwb(obj)) { - this.setValues("hwb", vals); - } else { - throw new Error("Unable to parse color from string \"" + obj + "\""); - } - } else if (typeof obj == "object") { - var vals = obj; - if (vals["r"] !== undefined || vals["red"] !== undefined) { - this.setValues("rgb", vals) - } else if (vals["l"] !== undefined || vals["lightness"] !== undefined) { - this.setValues("hsl", vals) - } else if (vals["v"] !== undefined || vals["value"] !== undefined) { - this.setValues("hsv", vals) - } else if (vals["w"] !== undefined || vals["whiteness"] !== undefined) { - this.setValues("hwb", vals) - } else if (vals["c"] !== undefined || vals["cyan"] !== undefined) { - this.setValues("cmyk", vals) - } else { - throw new Error("Unable to parse color from object " + JSON.stringify(obj)); - } - } -} - -Color.prototype = { - rgb: function(vals) { - return this.setSpace("rgb", arguments); - }, - hsl: function(vals) { - return this.setSpace("hsl", arguments); - }, - hsv: function(vals) { - return this.setSpace("hsv", arguments); - }, - hwb: function(vals) { - return this.setSpace("hwb", arguments); - }, - cmyk: function(vals) { - return this.setSpace("cmyk", arguments); - }, - - rgbArray: function() { - return this.values.rgb; - }, - hslArray: function() { - return this.values.hsl; - }, - hsvArray: function() { - return this.values.hsv; - }, - hwbArray: function() { - if (this.values.alpha !== 1) { - return this.values.hwb.concat([this.values.alpha]) - } - return this.values.hwb; - }, - cmykArray: function() { - return this.values.cmyk; - }, - rgbaArray: function() { - var rgb = this.values.rgb; - return rgb.concat([this.values.alpha]); - }, - hslaArray: function() { - var hsl = this.values.hsl; - return hsl.concat([this.values.alpha]); - }, - alpha: function(val) { - if (val === undefined) { - return this.values.alpha; - } - this.setValues("alpha", val); - return this; - }, - - red: function(val) { - return this.setChannel("rgb", 0, val); - }, - green: function(val) { - return this.setChannel("rgb", 1, val); - }, - blue: function(val) { - return this.setChannel("rgb", 2, val); - }, - hue: function(val) { - return this.setChannel("hsl", 0, val); - }, - saturation: function(val) { - return this.setChannel("hsl", 1, val); - }, - lightness: function(val) { - return this.setChannel("hsl", 2, val); - }, - saturationv: function(val) { - return this.setChannel("hsv", 1, val); - }, - whiteness: function(val) { - return this.setChannel("hwb", 1, val); - }, - blackness: function(val) { - return this.setChannel("hwb", 2, val); - }, - value: function(val) { - return this.setChannel("hsv", 2, val); - }, - cyan: function(val) { - return this.setChannel("cmyk", 0, val); - }, - magenta: function(val) { - return this.setChannel("cmyk", 1, val); - }, - yellow: function(val) { - return this.setChannel("cmyk", 2, val); - }, - black: function(val) { - return this.setChannel("cmyk", 3, val); - }, - - hexString: function() { - return string.hexString(this.values.rgb); - }, - rgbString: function() { - return string.rgbString(this.values.rgb, this.values.alpha); - }, - rgbaString: function() { - return string.rgbaString(this.values.rgb, this.values.alpha); - }, - percentString: function() { - return string.percentString(this.values.rgb, this.values.alpha); - }, - hslString: function() { - return string.hslString(this.values.hsl, this.values.alpha); - }, - hslaString: function() { - return string.hslaString(this.values.hsl, this.values.alpha); - }, - hwbString: function() { - return string.hwbString(this.values.hwb, this.values.alpha); - }, - keyword: function() { - return string.keyword(this.values.rgb, this.values.alpha); - }, - - rgbNumber: function() { - return (this.values.rgb[0] << 16) | (this.values.rgb[1] << 8) | this.values.rgb[2]; - }, - - luminosity: function() { - // http://www.w3.org/TR/WCAG20/#relativeluminancedef - var rgb = this.values.rgb; - var lum = []; - for (var i = 0; i < rgb.length; i++) { - var chan = rgb[i] / 255; - lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4) - } - return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; - }, - - contrast: function(color2) { - // http://www.w3.org/TR/WCAG20/#contrast-ratiodef - var lum1 = this.luminosity(); - var lum2 = color2.luminosity(); - if (lum1 > lum2) { - return (lum1 + 0.05) / (lum2 + 0.05) - }; - return (lum2 + 0.05) / (lum1 + 0.05); - }, - - level: function(color2) { - var contrastRatio = this.contrast(color2); - return (contrastRatio >= 7.1) ? 'AAA' : (contrastRatio >= 4.5) ? 'AA' : ''; - }, - - dark: function() { - // YIQ equation from http://24ways.org/2010/calculating-color-contrast - var rgb = this.values.rgb, - yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; - return yiq < 128; - }, - - light: function() { - return !this.dark(); - }, - - negate: function() { - var rgb = [] - for (var i = 0; i < 3; i++) { - rgb[i] = 255 - this.values.rgb[i]; - } - this.setValues("rgb", rgb); - return this; - }, - - lighten: function(ratio) { - this.values.hsl[2] += this.values.hsl[2] * ratio; - this.setValues("hsl", this.values.hsl); - return this; - }, - - darken: function(ratio) { - this.values.hsl[2] -= this.values.hsl[2] * ratio; - this.setValues("hsl", this.values.hsl); - return this; - }, - - saturate: function(ratio) { - this.values.hsl[1] += this.values.hsl[1] * ratio; - this.setValues("hsl", this.values.hsl); - return this; - }, - - desaturate: function(ratio) { - this.values.hsl[1] -= this.values.hsl[1] * ratio; - this.setValues("hsl", this.values.hsl); - return this; - }, - - whiten: function(ratio) { - this.values.hwb[1] += this.values.hwb[1] * ratio; - this.setValues("hwb", this.values.hwb); - return this; - }, - - blacken: function(ratio) { - this.values.hwb[2] += this.values.hwb[2] * ratio; - this.setValues("hwb", this.values.hwb); - return this; - }, - - greyscale: function() { - var rgb = this.values.rgb; - // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale - var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; - this.setValues("rgb", [val, val, val]); - return this; - }, - - clearer: function(ratio) { - this.setValues("alpha", this.values.alpha - (this.values.alpha * ratio)); - return this; - }, - - opaquer: function(ratio) { - this.setValues("alpha", this.values.alpha + (this.values.alpha * ratio)); - return this; - }, - - rotate: function(degrees) { - var hue = this.values.hsl[0]; - hue = (hue + degrees) % 360; - hue = hue < 0 ? 360 + hue : hue; - this.values.hsl[0] = hue; - this.setValues("hsl", this.values.hsl); - return this; - }, - - mix: function(color2, weight) { - weight = 1 - (weight == null ? 0.5 : weight); - - // algorithm from Sass's mix(). Ratio of first color in mix is - // determined by the alphas of both colors and the weight - var t1 = weight * 2 - 1, - d = this.alpha() - color2.alpha(); - - var weight1 = (((t1 * d == -1) ? t1 : (t1 + d) / (1 + t1 * d)) + 1) / 2; - var weight2 = 1 - weight1; - - var rgb = this.rgbArray(); - var rgb2 = color2.rgbArray(); - - for (var i = 0; i < rgb.length; i++) { - rgb[i] = rgb[i] * weight1 + rgb2[i] * weight2; - } - this.setValues("rgb", rgb); - - var alpha = this.alpha() * weight + color2.alpha() * (1 - weight); - this.setValues("alpha", alpha); - - return this; - }, - - toJSON: function() { - return this.rgb(); - }, - - clone: function() { - return new Color(this.rgb()); - } -} - - -Color.prototype.getValues = function(space) { - var vals = {}; - for (var i = 0; i < space.length; i++) { - vals[space.charAt(i)] = this.values[space][i]; - } - if (this.values.alpha != 1) { - vals["a"] = this.values.alpha; - } - // {r: 255, g: 255, b: 255, a: 0.4} - return vals; -} - -Color.prototype.setValues = function(space, vals) { - var spaces = { - "rgb": ["red", "green", "blue"], - "hsl": ["hue", "saturation", "lightness"], - "hsv": ["hue", "saturation", "value"], - "hwb": ["hue", "whiteness", "blackness"], - "cmyk": ["cyan", "magenta", "yellow", "black"] - }; - - var maxes = { - "rgb": [255, 255, 255], - "hsl": [360, 100, 100], - "hsv": [360, 100, 100], - "hwb": [360, 100, 100], - "cmyk": [100, 100, 100, 100] - }; - - var alpha = 1; - if (space == "alpha") { - alpha = vals; - } else if (vals.length) { - // [10, 10, 10] - this.values[space] = vals.slice(0, space.length); - alpha = vals[space.length]; - } else if (vals[space.charAt(0)] !== undefined) { - // {r: 10, g: 10, b: 10} - for (var i = 0; i < space.length; i++) { - this.values[space][i] = vals[space.charAt(i)]; - } - alpha = vals.a; - } else if (vals[spaces[space][0]] !== undefined) { - // {red: 10, green: 10, blue: 10} - var chans = spaces[space]; - for (var i = 0; i < space.length; i++) { - this.values[space][i] = vals[chans[i]]; - } - alpha = vals.alpha; - } - this.values.alpha = Math.max(0, Math.min(1, (alpha !== undefined ? alpha : this.values.alpha))); - if (space == "alpha") { - return; - } - - // cap values of the space prior converting all values - for (var i = 0; i < space.length; i++) { - var capped = Math.max(0, Math.min(maxes[space][i], this.values[space][i])); - this.values[space][i] = Math.round(capped); - } - - // convert to all the other color spaces - for (var sname in spaces) { - if (sname != space) { - this.values[sname] = convert[space][sname](this.values[space]) - } - - // cap values - for (var i = 0; i < sname.length; i++) { - var capped = Math.max(0, Math.min(maxes[sname][i], this.values[sname][i])); - this.values[sname][i] = Math.round(capped); - } - } - return true; -} - -Color.prototype.setSpace = function(space, args) { - var vals = args[0]; - if (vals === undefined) { - // color.rgb() - return this.getValues(space); - } - // color.rgb(10, 10, 10) - if (typeof vals == "number") { - vals = Array.prototype.slice.call(args); - } - this.setValues(space, vals); - return this; -} - -Color.prototype.setChannel = function(space, index, val) { - if (val === undefined) { - // color.red() - return this.values[space][index]; - } - // color.red(100) - this.values[space][index] = val; - this.setValues(space, this.values[space]); - return this; -} - -window.Color = module.exports = Color - -},{"chartjs-color-string":1,"color-convert":4}],3:[function(require,module,exports){ +},{"color-name":2}],2:[function(require,module,exports){ +module.exports = { + "aliceblue": [240, 248, 255], + "antiquewhite": [250, 235, 215], + "aqua": [0, 255, 255], + "aquamarine": [127, 255, 212], + "azure": [240, 255, 255], + "beige": [245, 245, 220], + "bisque": [255, 228, 196], + "black": [0, 0, 0], + "blanchedalmond": [255, 235, 205], + "blue": [0, 0, 255], + "blueviolet": [138, 43, 226], + "brown": [165, 42, 42], + "burlywood": [222, 184, 135], + "cadetblue": [95, 158, 160], + "chartreuse": [127, 255, 0], + "chocolate": [210, 105, 30], + "coral": [255, 127, 80], + "cornflowerblue": [100, 149, 237], + "cornsilk": [255, 248, 220], + "crimson": [220, 20, 60], + "cyan": [0, 255, 255], + "darkblue": [0, 0, 139], + "darkcyan": [0, 139, 139], + "darkgoldenrod": [184, 134, 11], + "darkgray": [169, 169, 169], + "darkgreen": [0, 100, 0], + "darkgrey": [169, 169, 169], + "darkkhaki": [189, 183, 107], + "darkmagenta": [139, 0, 139], + "darkolivegreen": [85, 107, 47], + "darkorange": [255, 140, 0], + "darkorchid": [153, 50, 204], + "darkred": [139, 0, 0], + "darksalmon": [233, 150, 122], + "darkseagreen": [143, 188, 143], + "darkslateblue": [72, 61, 139], + "darkslategray": [47, 79, 79], + "darkslategrey": [47, 79, 79], + "darkturquoise": [0, 206, 209], + "darkviolet": [148, 0, 211], + "deeppink": [255, 20, 147], + "deepskyblue": [0, 191, 255], + "dimgray": [105, 105, 105], + "dimgrey": [105, 105, 105], + "dodgerblue": [30, 144, 255], + "firebrick": [178, 34, 34], + "floralwhite": [255, 250, 240], + "forestgreen": [34, 139, 34], + "fuchsia": [255, 0, 255], + "gainsboro": [220, 220, 220], + "ghostwhite": [248, 248, 255], + "gold": [255, 215, 0], + "goldenrod": [218, 165, 32], + "gray": [128, 128, 128], + "green": [0, 128, 0], + "greenyellow": [173, 255, 47], + "grey": [128, 128, 128], + "honeydew": [240, 255, 240], + "hotpink": [255, 105, 180], + "indianred": [205, 92, 92], + "indigo": [75, 0, 130], + "ivory": [255, 255, 240], + "khaki": [240, 230, 140], + "lavender": [230, 230, 250], + "lavenderblush": [255, 240, 245], + "lawngreen": [124, 252, 0], + "lemonchiffon": [255, 250, 205], + "lightblue": [173, 216, 230], + "lightcoral": [240, 128, 128], + "lightcyan": [224, 255, 255], + "lightgoldenrodyellow": [250, 250, 210], + "lightgray": [211, 211, 211], + "lightgreen": [144, 238, 144], + "lightgrey": [211, 211, 211], + "lightpink": [255, 182, 193], + "lightsalmon": [255, 160, 122], + "lightseagreen": [32, 178, 170], + "lightskyblue": [135, 206, 250], + "lightslategray": [119, 136, 153], + "lightslategrey": [119, 136, 153], + "lightsteelblue": [176, 196, 222], + "lightyellow": [255, 255, 224], + "lime": [0, 255, 0], + "limegreen": [50, 205, 50], + "linen": [250, 240, 230], + "magenta": [255, 0, 255], + "maroon": [128, 0, 0], + "mediumaquamarine": [102, 205, 170], + "mediumblue": [0, 0, 205], + "mediumorchid": [186, 85, 211], + "mediumpurple": [147, 112, 219], + "mediumseagreen": [60, 179, 113], + "mediumslateblue": [123, 104, 238], + "mediumspringgreen": [0, 250, 154], + "mediumturquoise": [72, 209, 204], + "mediumvioletred": [199, 21, 133], + "midnightblue": [25, 25, 112], + "mintcream": [245, 255, 250], + "mistyrose": [255, 228, 225], + "moccasin": [255, 228, 181], + "navajowhite": [255, 222, 173], + "navy": [0, 0, 128], + "oldlace": [253, 245, 230], + "olive": [128, 128, 0], + "olivedrab": [107, 142, 35], + "orange": [255, 165, 0], + "orangered": [255, 69, 0], + "orchid": [218, 112, 214], + "palegoldenrod": [238, 232, 170], + "palegreen": [152, 251, 152], + "paleturquoise": [175, 238, 238], + "palevioletred": [219, 112, 147], + "papayawhip": [255, 239, 213], + "peachpuff": [255, 218, 185], + "peru": [205, 133, 63], + "pink": [255, 192, 203], + "plum": [221, 160, 221], + "powderblue": [176, 224, 230], + "purple": [128, 0, 128], + "rebeccapurple": [102, 51, 153], + "red": [255, 0, 0], + "rosybrown": [188, 143, 143], + "royalblue": [65, 105, 225], + "saddlebrown": [139, 69, 19], + "salmon": [250, 128, 114], + "sandybrown": [244, 164, 96], + "seagreen": [46, 139, 87], + "seashell": [255, 245, 238], + "sienna": [160, 82, 45], + "silver": [192, 192, 192], + "skyblue": [135, 206, 235], + "slateblue": [106, 90, 205], + "slategray": [112, 128, 144], + "slategrey": [112, 128, 144], + "snow": [255, 250, 250], + "springgreen": [0, 255, 127], + "steelblue": [70, 130, 180], + "tan": [210, 180, 140], + "teal": [0, 128, 128], + "thistle": [216, 191, 216], + "tomato": [255, 99, 71], + "turquoise": [64, 224, 208], + "violet": [238, 130, 238], + "wheat": [245, 222, 179], + "white": [255, 255, 255], + "whitesmoke": [245, 245, 245], + "yellow": [255, 255, 0], + "yellowgreen": [154, 205, 50] +}; +},{}],3:[function(require,module,exports){ /* MIT license */ module.exports = { @@ -1443,157 +1175,425 @@ Converter.prototype.getValues = function(space) { module.exports = convert; },{"./conversions":3}],5:[function(require,module,exports){ -module.exports = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "darkkhaki": [189, 183, 107], - "darkmagenta": [139, 0, 139], - "darkolivegreen": [85, 107, 47], - "darkorange": [255, 140, 0], - "darkorchid": [153, 50, 204], - "darkred": [139, 0, 0], - "darksalmon": [233, 150, 122], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] -}; -},{}],6:[function(require,module,exports){ +/* MIT license */ + +var convert = require("color-convert"), + string = require("chartjs-color-string"); + +var Color = function(obj) { + if (obj instanceof Color) return obj; + if (!(this instanceof Color)) return new Color(obj); + + this.values = { + rgb: [0, 0, 0], + hsl: [0, 0, 0], + hsv: [0, 0, 0], + hwb: [0, 0, 0], + cmyk: [0, 0, 0, 0], + alpha: 1 + } + + // parse Color() argument + if (typeof obj == "string") { + var vals = string.getRgba(obj); + if (vals) { + this.setValues("rgb", vals); + } else if (vals = string.getHsla(obj)) { + this.setValues("hsl", vals); + } else if (vals = string.getHwb(obj)) { + this.setValues("hwb", vals); + } else { + throw new Error("Unable to parse color from string \"" + obj + "\""); + } + } else if (typeof obj == "object") { + var vals = obj; + if (vals["r"] !== undefined || vals["red"] !== undefined) { + this.setValues("rgb", vals) + } else if (vals["l"] !== undefined || vals["lightness"] !== undefined) { + this.setValues("hsl", vals) + } else if (vals["v"] !== undefined || vals["value"] !== undefined) { + this.setValues("hsv", vals) + } else if (vals["w"] !== undefined || vals["whiteness"] !== undefined) { + this.setValues("hwb", vals) + } else if (vals["c"] !== undefined || vals["cyan"] !== undefined) { + this.setValues("cmyk", vals) + } else { + throw new Error("Unable to parse color from object " + JSON.stringify(obj)); + } + } +} + +Color.prototype = { + rgb: function(vals) { + return this.setSpace("rgb", arguments); + }, + hsl: function(vals) { + return this.setSpace("hsl", arguments); + }, + hsv: function(vals) { + return this.setSpace("hsv", arguments); + }, + hwb: function(vals) { + return this.setSpace("hwb", arguments); + }, + cmyk: function(vals) { + return this.setSpace("cmyk", arguments); + }, + + rgbArray: function() { + return this.values.rgb; + }, + hslArray: function() { + return this.values.hsl; + }, + hsvArray: function() { + return this.values.hsv; + }, + hwbArray: function() { + if (this.values.alpha !== 1) { + return this.values.hwb.concat([this.values.alpha]) + } + return this.values.hwb; + }, + cmykArray: function() { + return this.values.cmyk; + }, + rgbaArray: function() { + var rgb = this.values.rgb; + return rgb.concat([this.values.alpha]); + }, + hslaArray: function() { + var hsl = this.values.hsl; + return hsl.concat([this.values.alpha]); + }, + alpha: function(val) { + if (val === undefined) { + return this.values.alpha; + } + this.setValues("alpha", val); + return this; + }, + + red: function(val) { + return this.setChannel("rgb", 0, val); + }, + green: function(val) { + return this.setChannel("rgb", 1, val); + }, + blue: function(val) { + return this.setChannel("rgb", 2, val); + }, + hue: function(val) { + return this.setChannel("hsl", 0, val); + }, + saturation: function(val) { + return this.setChannel("hsl", 1, val); + }, + lightness: function(val) { + return this.setChannel("hsl", 2, val); + }, + saturationv: function(val) { + return this.setChannel("hsv", 1, val); + }, + whiteness: function(val) { + return this.setChannel("hwb", 1, val); + }, + blackness: function(val) { + return this.setChannel("hwb", 2, val); + }, + value: function(val) { + return this.setChannel("hsv", 2, val); + }, + cyan: function(val) { + return this.setChannel("cmyk", 0, val); + }, + magenta: function(val) { + return this.setChannel("cmyk", 1, val); + }, + yellow: function(val) { + return this.setChannel("cmyk", 2, val); + }, + black: function(val) { + return this.setChannel("cmyk", 3, val); + }, + + hexString: function() { + return string.hexString(this.values.rgb); + }, + rgbString: function() { + return string.rgbString(this.values.rgb, this.values.alpha); + }, + rgbaString: function() { + return string.rgbaString(this.values.rgb, this.values.alpha); + }, + percentString: function() { + return string.percentString(this.values.rgb, this.values.alpha); + }, + hslString: function() { + return string.hslString(this.values.hsl, this.values.alpha); + }, + hslaString: function() { + return string.hslaString(this.values.hsl, this.values.alpha); + }, + hwbString: function() { + return string.hwbString(this.values.hwb, this.values.alpha); + }, + keyword: function() { + return string.keyword(this.values.rgb, this.values.alpha); + }, + + rgbNumber: function() { + return (this.values.rgb[0] << 16) | (this.values.rgb[1] << 8) | this.values.rgb[2]; + }, + + luminosity: function() { + // http://www.w3.org/TR/WCAG20/#relativeluminancedef + var rgb = this.values.rgb; + var lum = []; + for (var i = 0; i < rgb.length; i++) { + var chan = rgb[i] / 255; + lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4) + } + return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; + }, + + contrast: function(color2) { + // http://www.w3.org/TR/WCAG20/#contrast-ratiodef + var lum1 = this.luminosity(); + var lum2 = color2.luminosity(); + if (lum1 > lum2) { + return (lum1 + 0.05) / (lum2 + 0.05) + }; + return (lum2 + 0.05) / (lum1 + 0.05); + }, + + level: function(color2) { + var contrastRatio = this.contrast(color2); + return (contrastRatio >= 7.1) ? 'AAA' : (contrastRatio >= 4.5) ? 'AA' : ''; + }, + + dark: function() { + // YIQ equation from http://24ways.org/2010/calculating-color-contrast + var rgb = this.values.rgb, + yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; + return yiq < 128; + }, + + light: function() { + return !this.dark(); + }, + + negate: function() { + var rgb = [] + for (var i = 0; i < 3; i++) { + rgb[i] = 255 - this.values.rgb[i]; + } + this.setValues("rgb", rgb); + return this; + }, + + lighten: function(ratio) { + this.values.hsl[2] += this.values.hsl[2] * ratio; + this.setValues("hsl", this.values.hsl); + return this; + }, + + darken: function(ratio) { + this.values.hsl[2] -= this.values.hsl[2] * ratio; + this.setValues("hsl", this.values.hsl); + return this; + }, + + saturate: function(ratio) { + this.values.hsl[1] += this.values.hsl[1] * ratio; + this.setValues("hsl", this.values.hsl); + return this; + }, + + desaturate: function(ratio) { + this.values.hsl[1] -= this.values.hsl[1] * ratio; + this.setValues("hsl", this.values.hsl); + return this; + }, + + whiten: function(ratio) { + this.values.hwb[1] += this.values.hwb[1] * ratio; + this.setValues("hwb", this.values.hwb); + return this; + }, + + blacken: function(ratio) { + this.values.hwb[2] += this.values.hwb[2] * ratio; + this.setValues("hwb", this.values.hwb); + return this; + }, + + greyscale: function() { + var rgb = this.values.rgb; + // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale + var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; + this.setValues("rgb", [val, val, val]); + return this; + }, + + clearer: function(ratio) { + this.setValues("alpha", this.values.alpha - (this.values.alpha * ratio)); + return this; + }, + + opaquer: function(ratio) { + this.setValues("alpha", this.values.alpha + (this.values.alpha * ratio)); + return this; + }, + + rotate: function(degrees) { + var hue = this.values.hsl[0]; + hue = (hue + degrees) % 360; + hue = hue < 0 ? 360 + hue : hue; + this.values.hsl[0] = hue; + this.setValues("hsl", this.values.hsl); + return this; + }, + + mix: function(color2, weight) { + weight = 1 - (weight == null ? 0.5 : weight); + + // algorithm from Sass's mix(). Ratio of first color in mix is + // determined by the alphas of both colors and the weight + var t1 = weight * 2 - 1, + d = this.alpha() - color2.alpha(); + + var weight1 = (((t1 * d == -1) ? t1 : (t1 + d) / (1 + t1 * d)) + 1) / 2; + var weight2 = 1 - weight1; + + var rgb = this.rgbArray(); + var rgb2 = color2.rgbArray(); + + for (var i = 0; i < rgb.length; i++) { + rgb[i] = rgb[i] * weight1 + rgb2[i] * weight2; + } + this.setValues("rgb", rgb); + + var alpha = this.alpha() * weight + color2.alpha() * (1 - weight); + this.setValues("alpha", alpha); + + return this; + }, + + toJSON: function() { + return this.rgb(); + }, + + clone: function() { + return new Color(this.rgb()); + } +} + + +Color.prototype.getValues = function(space) { + var vals = {}; + for (var i = 0; i < space.length; i++) { + vals[space.charAt(i)] = this.values[space][i]; + } + if (this.values.alpha != 1) { + vals["a"] = this.values.alpha; + } + // {r: 255, g: 255, b: 255, a: 0.4} + return vals; +} + +Color.prototype.setValues = function(space, vals) { + var spaces = { + "rgb": ["red", "green", "blue"], + "hsl": ["hue", "saturation", "lightness"], + "hsv": ["hue", "saturation", "value"], + "hwb": ["hue", "whiteness", "blackness"], + "cmyk": ["cyan", "magenta", "yellow", "black"] + }; + + var maxes = { + "rgb": [255, 255, 255], + "hsl": [360, 100, 100], + "hsv": [360, 100, 100], + "hwb": [360, 100, 100], + "cmyk": [100, 100, 100, 100] + }; + + var alpha = 1; + if (space == "alpha") { + alpha = vals; + } else if (vals.length) { + // [10, 10, 10] + this.values[space] = vals.slice(0, space.length); + alpha = vals[space.length]; + } else if (vals[space.charAt(0)] !== undefined) { + // {r: 10, g: 10, b: 10} + for (var i = 0; i < space.length; i++) { + this.values[space][i] = vals[space.charAt(i)]; + } + alpha = vals.a; + } else if (vals[spaces[space][0]] !== undefined) { + // {red: 10, green: 10, blue: 10} + var chans = spaces[space]; + for (var i = 0; i < space.length; i++) { + this.values[space][i] = vals[chans[i]]; + } + alpha = vals.alpha; + } + this.values.alpha = Math.max(0, Math.min(1, (alpha !== undefined ? alpha : this.values.alpha))); + if (space == "alpha") { + return; + } + + // cap values of the space prior converting all values + for (var i = 0; i < space.length; i++) { + var capped = Math.max(0, Math.min(maxes[space][i], this.values[space][i])); + this.values[space][i] = Math.round(capped); + } + + // convert to all the other color spaces + for (var sname in spaces) { + if (sname != space) { + this.values[sname] = convert[space][sname](this.values[space]) + } + + // cap values + for (var i = 0; i < sname.length; i++) { + var capped = Math.max(0, Math.min(maxes[sname][i], this.values[sname][i])); + this.values[sname][i] = Math.round(capped); + } + } + return true; +} + +Color.prototype.setSpace = function(space, args) { + var vals = args[0]; + if (vals === undefined) { + // color.rgb() + return this.getValues(space); + } + // color.rgb(10, 10, 10) + if (typeof vals == "number") { + vals = Array.prototype.slice.call(args); + } + this.setValues(space, vals); + return this; +} + +Color.prototype.setChannel = function(space, index, val) { + if (val === undefined) { + // color.red() + return this.values[space][index]; + } + // color.red(100) + this.values[space][index] = val; + this.setValues(space, this.values[space]); + return this; +} + +window.Color = module.exports = Color + +},{"chartjs-color-string":1,"color-convert":4}],6:[function(require,module,exports){ //! moment.js //! version : 2.13.0 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors @@ -5617,8207 +5617,8214 @@ module.exports = { utils_hooks__hooks.isMoment = isMoment; utils_hooks__hooks.weekdays = lists__listWeekdays; utils_hooks__hooks.parseZone = moment__createInZone; - utils_hooks__hooks.localeData = locale_locales__getLocale; - utils_hooks__hooks.isDuration = isDuration; - utils_hooks__hooks.monthsShort = lists__listMonthsShort; - utils_hooks__hooks.weekdaysMin = lists__listWeekdaysMin; - utils_hooks__hooks.defineLocale = defineLocale; - utils_hooks__hooks.updateLocale = updateLocale; - utils_hooks__hooks.locales = locale_locales__listLocales; - utils_hooks__hooks.weekdaysShort = lists__listWeekdaysShort; - utils_hooks__hooks.normalizeUnits = normalizeUnits; - utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold; - utils_hooks__hooks.prototype = momentPrototype; - - var _moment = utils_hooks__hooks; - - return _moment; - -})); -},{}],7:[function(require,module,exports){ -var Chart = require('./core/core.js')(); - -require('./core/core.helpers')(Chart); -require('./core/core.element')(Chart); -require('./core/core.animation')(Chart); -require('./core/core.controller')(Chart); -require('./core/core.datasetController')(Chart); -require('./core/core.layoutService')(Chart); -require('./core/core.legend')(Chart); -require('./core/core.plugin.js')(Chart); -require('./core/core.scale')(Chart); -require('./core/core.scaleService')(Chart); -require('./core/core.title')(Chart); -require('./core/core.tooltip')(Chart); - -require('./controllers/controller.bar')(Chart); -require('./controllers/controller.bubble')(Chart); -require('./controllers/controller.doughnut')(Chart); -require('./controllers/controller.line')(Chart); -require('./controllers/controller.polarArea')(Chart); -require('./controllers/controller.radar')(Chart); - -require('./scales/scale.category')(Chart); -require('./scales/scale.linear')(Chart); -require('./scales/scale.logarithmic')(Chart); -require('./scales/scale.radialLinear')(Chart); -require('./scales/scale.time')(Chart); - -require('./elements/element.arc')(Chart); -require('./elements/element.line')(Chart); -require('./elements/element.point')(Chart); -require('./elements/element.rectangle')(Chart); - -require('./charts/Chart.Bar')(Chart); -require('./charts/Chart.Bubble')(Chart); -require('./charts/Chart.Doughnut')(Chart); -require('./charts/Chart.Line')(Chart); -require('./charts/Chart.PolarArea')(Chart); -require('./charts/Chart.Radar')(Chart); -require('./charts/Chart.Scatter')(Chart); - -window.Chart = module.exports = Chart; - -},{"./charts/Chart.Bar":8,"./charts/Chart.Bubble":9,"./charts/Chart.Doughnut":10,"./charts/Chart.Line":11,"./charts/Chart.PolarArea":12,"./charts/Chart.Radar":13,"./charts/Chart.Scatter":14,"./controllers/controller.bar":15,"./controllers/controller.bubble":16,"./controllers/controller.doughnut":17,"./controllers/controller.line":18,"./controllers/controller.polarArea":19,"./controllers/controller.radar":20,"./core/core.animation":21,"./core/core.controller":22,"./core/core.datasetController":23,"./core/core.element":24,"./core/core.helpers":25,"./core/core.js":26,"./core/core.layoutService":27,"./core/core.legend":28,"./core/core.plugin.js":29,"./core/core.scale":30,"./core/core.scaleService":31,"./core/core.title":32,"./core/core.tooltip":33,"./elements/element.arc":34,"./elements/element.line":35,"./elements/element.point":36,"./elements/element.rectangle":37,"./scales/scale.category":38,"./scales/scale.linear":39,"./scales/scale.logarithmic":40,"./scales/scale.radialLinear":41,"./scales/scale.time":42}],8:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.Bar = function(context, config) { - config.type = 'bar'; - - return new Chart(context, config); - }; - -}; -},{}],9:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.Bubble = function(context, config) { - config.type = 'bubble'; - return new Chart(context, config); - }; - -}; -},{}],10:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.Doughnut = function(context, config) { - config.type = 'doughnut'; - - return new Chart(context, config); - }; - -}; -},{}],11:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.Line = function(context, config) { - config.type = 'line'; - - return new Chart(context, config); - }; - -}; -},{}],12:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.PolarArea = function(context, config) { - config.type = 'polarArea'; - - return new Chart(context, config); - }; - -}; -},{}],13:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - var defaultConfig = { - aspectRatio: 1 - }; - - Chart.Radar = function(context, config) { - config.options = helpers.configMerge(defaultConfig, config.options); - config.type = 'radar'; - - return new Chart(context, config); - }; - -}; - -},{}],14:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var defaultConfig = { - hover: { - mode: 'single' - }, - - scales: { - xAxes: [{ - type: "linear", // scatter should not use a category axis - position: "bottom", - id: "x-axis-1" // need an ID so datasets can reference the scale - }], - yAxes: [{ - type: "linear", - position: "left", - id: "y-axis-1" - }] - }, - - tooltips: { - callbacks: { - title: function(tooltipItems, data) { - // Title doesn't make sense for scatter since we format the data as a point - return ''; - }, - label: function(tooltipItem, data) { - return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')'; - } - } - } - }; - - // Register the default config for this type - Chart.defaults.scatter = defaultConfig; - - // Scatter charts use line controllers - Chart.controllers.scatter = Chart.controllers.line; - - Chart.Scatter = function(context, config) { - config.type = 'scatter'; - return new Chart(context, config); - }; - -}; -},{}],15:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.bar = { - hover: { - mode: "label" - }, - - scales: { - xAxes: [{ - type: "category", - - // Specific to Bar Controller - categoryPercentage: 0.8, - barPercentage: 0.9, - - // grid line settings - gridLines: { - offsetGridLines: true - } - }], - yAxes: [{ - type: "linear" - }] - } - }; - - Chart.controllers.bar = Chart.DatasetController.extend({ - initialize: function(chart, datasetIndex) { - Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex); - - // Use this to indicate that this is a bar dataset. - this.getMeta().bar = true; - }, - // Get the number of datasets that display bars. We use this to correctly calculate the bar width - getBarCount: function getBarCount() { - var barCount = 0; - helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) { - var meta = this.chart.getDatasetMeta(datasetIndex); - if (meta.bar && this.chart.isDatasetVisible(datasetIndex)) { - ++barCount; - } - }, this); - return barCount; - }, - - addElements: function() { - var meta = this.getMeta(); - helpers.each(this.getDataset().data, function(value, index) { - meta.data[index] = meta.data[index] || new Chart.elements.Rectangle({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - - addElementAndReset: function(index) { - var rectangle = new Chart.elements.Rectangle({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - var numBars = this.getBarCount(); - - // Add to the points array and reset it - this.getMeta().data.splice(index, 0, rectangle); - this.updateElement(rectangle, index, true, numBars); - }, - - update: function update(reset) { - var numBars = this.getBarCount(); - - helpers.each(this.getMeta().data, function(rectangle, index) { - this.updateElement(rectangle, index, reset, numBars); - }, this); - }, - - updateElement: function updateElement(rectangle, index, reset, numBars) { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - - var yScalePoint; - - if (yScale.min < 0 && yScale.max < 0) { - // all less than 0. use the top - yScalePoint = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - yScalePoint = yScale.getPixelForValue(yScale.min); - } else { - yScalePoint = yScale.getPixelForValue(0); - } - - helpers.extend(rectangle, { - // Utility - _chart: this.chart.chart, - _xScale: xScale, - _yScale: yScale, - _datasetIndex: this.index, - _index: index, - - - // Desired view properties - _model: { - x: this.calculateBarX(index, this.index), - y: reset ? yScalePoint : this.calculateBarY(index, this.index), - - // Tooltip - label: this.chart.data.labels[index], - datasetLabel: this.getDataset().label, - - // Appearance - base: reset ? yScalePoint : this.calculateBarBase(this.index, index), - width: this.calculateBarWidth(numBars), - backgroundColor: rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor), - borderSkipped: rectangle.custom && rectangle.custom.borderSkipped ? rectangle.custom.borderSkipped : this.chart.options.elements.rectangle.borderSkipped, - borderColor: rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor), - borderWidth: rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth) - } - }); - rectangle.pivot(); - }, - - calculateBarBase: function(datasetIndex, index) { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - - var base = 0; - - if (yScale.options.stacked) { - - var value = this.chart.data.datasets[datasetIndex].data[index]; - - if (value < 0) { - for (var i = 0; i < datasetIndex; i++) { - var negDS = this.chart.data.datasets[i]; - var negDSMeta = this.chart.getDatasetMeta(i); - if (negDSMeta.bar && negDSMeta.yAxisID === yScale.id && this.chart.isDatasetVisible(i)) { - base += negDS.data[index] < 0 ? negDS.data[index] : 0; - } - } - } else { - for (var j = 0; j < datasetIndex; j++) { - var posDS = this.chart.data.datasets[j]; - var posDSMeta = this.chart.getDatasetMeta(j); - if (posDSMeta.bar && posDSMeta.yAxisID === yScale.id && this.chart.isDatasetVisible(j)) { - base += posDS.data[index] > 0 ? posDS.data[index] : 0; - } - } - } - - return yScale.getPixelForValue(base); - } - - base = yScale.getPixelForValue(yScale.min); - - if (yScale.beginAtZero || ((yScale.min <= 0 && yScale.max >= 0) || (yScale.min >= 0 && yScale.max <= 0))) { - base = yScale.getPixelForValue(0, 0); - //base += yScale.options.gridLines.lineWidth; - } else if (yScale.min < 0 && yScale.max < 0) { - // All values are negative. Use the top as the base - base = yScale.getPixelForValue(yScale.max); - } - - return base; - - }, - - getRuler: function() { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - var datasetCount = this.getBarCount(); - - var tickWidth = (function() { - var min = xScale.getPixelForTick(1) - xScale.getPixelForTick(0); - for (var i = 2; i < xScale.ticks.length; i++) { - min = Math.min(xScale.getPixelForTick(i) - xScale.getPixelForTick(i - 1), min); - } - return min; - }).call(this); - var categoryWidth = tickWidth * xScale.options.categoryPercentage; - var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2; - var fullBarWidth = categoryWidth / datasetCount; - - if (xScale.ticks.length !== this.chart.data.labels.length) { - var perc = xScale.ticks.length / this.chart.data.labels.length; - fullBarWidth = fullBarWidth * perc; - } - - var barWidth = fullBarWidth * xScale.options.barPercentage; - var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage); - - return { - datasetCount: datasetCount, - tickWidth: tickWidth, - categoryWidth: categoryWidth, - categorySpacing: categorySpacing, - fullBarWidth: fullBarWidth, - barWidth: barWidth, - barSpacing: barSpacing - }; - }, - - calculateBarWidth: function() { - var xScale = this.getScaleForId(this.getMeta().xAxisID); - var ruler = this.getRuler(); - return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth; - }, - - // Get bar index from the given dataset index accounting for the fact that not all bars are visible - getBarIndex: function(datasetIndex) { - var barIndex = 0; - var meta, j; - - for (j = 0; j < datasetIndex; ++j) { - meta = this.chart.getDatasetMeta(j); - if (meta.bar && this.chart.isDatasetVisible(j)) { - ++barIndex; - } - } - - return barIndex; - }, - - calculateBarX: function(index, datasetIndex) { - var meta = this.getMeta(); - var yScale = this.getScaleForId(meta.yAxisID); - var xScale = this.getScaleForId(meta.xAxisID); - var barIndex = this.getBarIndex(datasetIndex); - - var ruler = this.getRuler(); - var leftTick = xScale.getPixelForValue(null, index, datasetIndex, this.chart.isCombo); - leftTick -= this.chart.isCombo ? (ruler.tickWidth / 2) : 0; - - if (xScale.options.stacked) { - return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing; - } - - return leftTick + - (ruler.barWidth / 2) + - ruler.categorySpacing + - (ruler.barWidth * barIndex) + - (ruler.barSpacing / 2) + - (ruler.barSpacing * barIndex); - }, - - calculateBarY: function(index, datasetIndex) { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - - var value = this.getDataset().data[index]; - - if (yScale.options.stacked) { - - var sumPos = 0, - sumNeg = 0; - - for (var i = 0; i < datasetIndex; i++) { - var ds = this.chart.data.datasets[i]; - var dsMeta = this.chart.getDatasetMeta(i); - if (dsMeta.bar && dsMeta.yAxisID === yScale.id && this.chart.isDatasetVisible(i)) { - if (ds.data[index] < 0) { - sumNeg += ds.data[index] || 0; - } else { - sumPos += ds.data[index] || 0; - } - } - } - - if (value < 0) { - return yScale.getPixelForValue(sumNeg + value); - } else { - return yScale.getPixelForValue(sumPos + value); - } - } - - return yScale.getPixelForValue(value); - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - helpers.each(this.getMeta().data, function(rectangle, index) { - var d = this.getDataset().data[index]; - if (d !== null && d !== undefined && !isNaN(d)) { - rectangle.transition(easingDecimal).draw(); - } - }, this); - }, - - setHoverStyle: function(rectangle) { - var dataset = this.chart.data.datasets[rectangle._datasetIndex]; - var index = rectangle._index; - - rectangle._model.backgroundColor = rectangle.custom && rectangle.custom.hoverBackgroundColor ? rectangle.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(rectangle._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - rectangle._model.borderColor = rectangle.custom && rectangle.custom.hoverBorderColor ? rectangle.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(rectangle._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - rectangle._model.borderWidth = rectangle.custom && rectangle.custom.hoverBorderWidth ? rectangle.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, rectangle._model.borderWidth); - }, - - removeHoverStyle: function(rectangle) { - var dataset = this.chart.data.datasets[rectangle._datasetIndex]; - var index = rectangle._index; - - rectangle._model.backgroundColor = rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor); - rectangle._model.borderColor = rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor); - rectangle._model.borderWidth = rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth); - } - - }); - - - // including horizontalBar in the bar file, instead of a file of its own - // it extends bar (like pie extends doughnut) - Chart.defaults.horizontalBar = { - hover: { - mode: "label" - }, - - scales: { - xAxes: [{ - type: "linear", - position: "bottom" - }], - yAxes: [{ - position: "left", - type: "category", - - // Specific to Horizontal Bar Controller - categoryPercentage: 0.8, - barPercentage: 0.9, - - // grid line settings - gridLines: { - offsetGridLines: true - } - }] - }, - }; - - Chart.controllers.horizontalBar = Chart.controllers.bar.extend({ - updateElement: function updateElement(rectangle, index, reset, numBars) { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - - var xScalePoint; - - if (xScale.min < 0 && xScale.max < 0) { - // all less than 0. use the right - xScalePoint = xScale.getPixelForValue(xScale.max); - } else if (xScale.min > 0 && xScale.max > 0) { - xScalePoint = xScale.getPixelForValue(xScale.min); - } else { - xScalePoint = xScale.getPixelForValue(0); - } - - helpers.extend(rectangle, { - // Utility - _chart: this.chart.chart, - _xScale: xScale, - _yScale: yScale, - _datasetIndex: this.index, - _index: index, - - // Desired view properties - _model: { - x: reset ? xScalePoint : this.calculateBarX(index, this.index), - y: this.calculateBarY(index, this.index), - - // Tooltip - label: this.chart.data.labels[index], - datasetLabel: this.getDataset().label, - - // Appearance - base: reset ? xScalePoint : this.calculateBarBase(this.index, index), - height: this.calculateBarHeight(numBars), - backgroundColor: rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor), - borderSkipped: rectangle.custom && rectangle.custom.borderSkipped ? rectangle.custom.borderSkipped : this.chart.options.elements.rectangle.borderSkipped, - borderColor: rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor), - borderWidth: rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth) - }, - - draw: function () { - - var ctx = this._chart.ctx; - var vm = this._view; - - var halfHeight = vm.height / 2, - topY = vm.y - halfHeight, - bottomY = vm.y + halfHeight, - right = vm.base - (vm.base - vm.x), - halfStroke = vm.borderWidth / 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 (vm.borderWidth) { - topY += halfStroke; - bottomY -= halfStroke; - right += halfStroke; - } - - ctx.beginPath(); - - ctx.fillStyle = vm.backgroundColor; - ctx.strokeStyle = vm.borderColor; - ctx.lineWidth = vm.borderWidth; - - // Corner points, from bottom-left to bottom-right clockwise - // | 1 2 | - // | 0 3 | - var corners = [ - [vm.base, bottomY], - [vm.base, topY], - [right, topY], - [right, bottomY] - ]; - - // Find first (starting) corner with fallback to 'bottom' - var borders = ['bottom', 'left', 'top', 'right']; - var startCorner = borders.indexOf(vm.borderSkipped, 0); - if (startCorner === -1) - startCorner = 0; - - function cornerAt(index) { - return corners[(startCorner + index) % 4]; - } - - // Draw rectangle from 'startCorner' - ctx.moveTo.apply(ctx, cornerAt(0)); - for (var i = 1; i < 4; i++) - ctx.lineTo.apply(ctx, cornerAt(i)); - - ctx.fill(); - if (vm.borderWidth) { - ctx.stroke(); - } - }, - - inRange: function (mouseX, mouseY) { - var vm = this._view; - var inRange = false; - - if (vm) { - if (vm.x < vm.base) { - inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.x && mouseX <= vm.base); - } else { - inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.base && mouseX <= vm.x); - } - } - - return inRange; - } - }); - - rectangle.pivot(); - }, - - calculateBarBase: function (datasetIndex, index) { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - - var base = 0; - - if (xScale.options.stacked) { - - var value = this.chart.data.datasets[datasetIndex].data[index]; - - if (value < 0) { - for (var i = 0; i < datasetIndex; i++) { - var negDS = this.chart.data.datasets[i]; - var negDSMeta = this.chart.getDatasetMeta(i); - if (negDSMeta.bar && negDSMeta.xAxisID === xScale.id && this.chart.isDatasetVisible(i)) { - base += negDS.data[index] < 0 ? negDS.data[index] : 0; - } - } - } else { - for (var j = 0; j < datasetIndex; j++) { - var posDS = this.chart.data.datasets[j]; - var posDSMeta = this.chart.getDatasetMeta(j); - if (posDSMeta.bar && posDSMeta.xAxisID === xScale.id && this.chart.isDatasetVisible(j)) { - base += posDS.data[index] > 0 ? posDS.data[index] : 0; - } - } - } - - return xScale.getPixelForValue(base); - } - - base = xScale.getPixelForValue(xScale.min); - - if (xScale.beginAtZero || ((xScale.min <= 0 && xScale.max >= 0) || (xScale.min >= 0 && xScale.max <= 0))) { - base = xScale.getPixelForValue(0, 0); - } else if (xScale.min < 0 && xScale.max < 0) { - // All values are negative. Use the right as the base - base = xScale.getPixelForValue(xScale.max); - } - - return base; - }, - - getRuler: function () { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - var datasetCount = this.getBarCount(); - - var tickHeight = (function () { - var min = yScale.getPixelForTick(1) - yScale.getPixelForTick(0); - for (var i = 2; i < this.getDataset().data.length; i++) { - min = Math.min(yScale.getPixelForTick(i) - yScale.getPixelForTick(i - 1), min); - } - return min; - }).call(this); - var categoryHeight = tickHeight * yScale.options.categoryPercentage; - var categorySpacing = (tickHeight - (tickHeight * yScale.options.categoryPercentage)) / 2; - var fullBarHeight = categoryHeight / datasetCount; - - if (yScale.ticks.length !== this.chart.data.labels.length) { - var perc = yScale.ticks.length / this.chart.data.labels.length; - fullBarHeight = fullBarHeight * perc; - } - - var barHeight = fullBarHeight * yScale.options.barPercentage; - var barSpacing = fullBarHeight - (fullBarHeight * yScale.options.barPercentage); - - return { - datasetCount: datasetCount, - tickHeight: tickHeight, - categoryHeight: categoryHeight, - categorySpacing: categorySpacing, - fullBarHeight: fullBarHeight, - barHeight: barHeight, - barSpacing: barSpacing, - }; - }, - - calculateBarHeight: function () { - var yScale = this.getScaleForId(this.getMeta().yAxisID); - var ruler = this.getRuler(); - return yScale.options.stacked ? ruler.categoryHeight : ruler.barHeight; - }, - - calculateBarX: function (index, datasetIndex) { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - - var value = this.getDataset().data[index]; - - if (xScale.options.stacked) { - - var sumPos = 0, - sumNeg = 0; - - for (var i = 0; i < datasetIndex; i++) { - var ds = this.chart.data.datasets[i]; - var dsMeta = this.chart.getDatasetMeta(i); - if (dsMeta.bar && dsMeta.xAxisID === xScale.id && this.chart.isDatasetVisible(i)) { - if (ds.data[index] < 0) { - sumNeg += ds.data[index] || 0; - } else { - sumPos += ds.data[index] || 0; - } - } - } - - if (value < 0) { - return xScale.getPixelForValue(sumNeg + value); - } else { - return xScale.getPixelForValue(sumPos + value); - } - } - - return xScale.getPixelForValue(value); - }, - - calculateBarY: function (index, datasetIndex) { - var meta = this.getMeta(); - var yScale = this.getScaleForId(meta.yAxisID); - var xScale = this.getScaleForId(meta.xAxisID); - var barIndex = this.getBarIndex(datasetIndex); - - var ruler = this.getRuler(); - var topTick = yScale.getPixelForValue(null, index, datasetIndex, this.chart.isCombo); - topTick -= this.chart.isCombo ? (ruler.tickHeight / 2) : 0; - - if (yScale.options.stacked) { - return topTick + (ruler.categoryHeight / 2) + ruler.categorySpacing; - } - - return topTick + - (ruler.barHeight / 2) + - ruler.categorySpacing + - (ruler.barHeight * barIndex) + - (ruler.barSpacing / 2) + - (ruler.barSpacing * barIndex); - } - }); -}; + utils_hooks__hooks.localeData = locale_locales__getLocale; + utils_hooks__hooks.isDuration = isDuration; + utils_hooks__hooks.monthsShort = lists__listMonthsShort; + utils_hooks__hooks.weekdaysMin = lists__listWeekdaysMin; + utils_hooks__hooks.defineLocale = defineLocale; + utils_hooks__hooks.updateLocale = updateLocale; + utils_hooks__hooks.locales = locale_locales__listLocales; + utils_hooks__hooks.weekdaysShort = lists__listWeekdaysShort; + utils_hooks__hooks.normalizeUnits = normalizeUnits; + utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold; + utils_hooks__hooks.prototype = momentPrototype; -},{}],16:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.bubble = { - hover: { - mode: "single" - }, - - scales: { - xAxes: [{ - type: "linear", // bubble should probably use a linear scale by default - position: "bottom", - id: "x-axis-0" // need an ID so datasets can reference the scale - }], - yAxes: [{ - type: "linear", - position: "left", - id: "y-axis-0" - }] - }, - - tooltips: { - callbacks: { - title: function(tooltipItems, data) { - // Title doesn't make sense for scatter since we format the data as a point - return ''; - }, - label: function(tooltipItem, data) { - var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || ''; - var dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; - return datasetLabel + ': (' + dataPoint.x + ', ' + dataPoint.y + ', ' + dataPoint.r + ')'; - } - } - } - }; - - - Chart.controllers.bubble = Chart.DatasetController.extend({ - addElements: function() { - var meta = this.getMeta(); - helpers.each(this.getDataset().data, function(value, index) { - meta.data[index] = meta.data[index] || new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - addElementAndReset: function(index) { - var point = new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - // Add to the points array and reset it - this.getMeta().data.splice(index, 0, point); - this.updateElement(point, index, true); - }, - - update: function update(reset) { - var meta = this.getMeta(); - var points = meta.data; - var yScale = this.getScaleForId(meta.yAxisID); - var xScale = this.getScaleForId(meta.xAxisID); - var scaleBase; - - if (yScale.min < 0 && yScale.max < 0) { - scaleBase = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - scaleBase = yScale.getPixelForValue(yScale.min); - } else { - scaleBase = yScale.getPixelForValue(0); - } - - // Update Points - helpers.each(points, function(point, index) { - this.updateElement(point, index, reset); - }, this); - - }, - - updateElement: function(point, index, reset) { - var meta = this.getMeta(); - var yScale = this.getScaleForId(meta.yAxisID); - var xScale = this.getScaleForId(meta.xAxisID); - var scaleBase; - - if (yScale.min < 0 && yScale.max < 0) { - scaleBase = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - scaleBase = yScale.getPixelForValue(yScale.min); - } else { - scaleBase = yScale.getPixelForValue(0); - } - - helpers.extend(point, { - // Utility - _chart: this.chart.chart, - _xScale: xScale, - _yScale: yScale, - _datasetIndex: this.index, - _index: index, - - // Desired view properties - _model: { - x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(this.getDataset().data[index], index, this.index, this.chart.isCombo), - y: reset ? scaleBase : yScale.getPixelForValue(this.getDataset().data[index], index, this.index), - // Appearance - radius: reset ? 0 : point.custom && point.custom.radius ? point.custom.radius : this.getRadius(this.getDataset().data[index]), - backgroundColor: point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.point.backgroundColor), - borderColor: point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.point.borderColor), - borderWidth: point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.point.borderWidth), - - // Tooltip - hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius) - } - }); - - point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); - - point.pivot(); - }, - - getRadius: function(value) { - return value.r || this.chart.options.elements.point.radius; - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - - // Transition and Draw the Points - helpers.each(this.getMeta().data, function(point, index) { - point.transition(easingDecimal); - point.draw(); - }); - - }, - - setHoverStyle: function(point) { - // Point - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, this.chart.options.elements.point.hoverRadius)) + this.getRadius(this.getDataset().data[point._index]); - point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(point._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(point._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, point._model.borderWidth); - }, - - removeHoverStyle: function(point) { - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.radius ? point.custom.radius : this.getRadius(this.getDataset().data[point._index]); - point._model.backgroundColor = point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.point.backgroundColor); - point._model.borderColor = point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.point.borderColor); - point._model.borderWidth = point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.point.borderWidth); - } - }); -}; -},{}],17:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.doughnut = { - animation: { - //Boolean - Whether we animate the rotation of the Doughnut - animateRotate: true, - //Boolean - Whether we animate scaling the Doughnut from the centre - animateScale: false - }, - aspectRatio: 1, - hover: { - mode: 'single' - }, - legendCallback: function(chart) { - var text = []; - text.push(''); - return text.join(""); - }, - legend: { - labels: { - generateLabels: function(chart) { - var data = chart.data; - if (data.labels.length && data.datasets.length) { - return data.labels.map(function(label, i) { - var meta = chart.getDatasetMeta(0); - var ds = data.datasets[0]; - var arc = meta.data[i]; - var fill = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(ds.backgroundColor, i, this.chart.options.elements.arc.backgroundColor); - var stroke = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(ds.borderColor, i, this.chart.options.elements.arc.borderColor); - var bw = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(ds.borderWidth, i, this.chart.options.elements.arc.borderWidth); - - return { - text: label, - fillStyle: fill, - strokeStyle: stroke, - lineWidth: bw, - hidden: isNaN(ds.data[i]) || meta.data[i].hidden, - - // Extra data used for toggling the correct item - index: i - }; - }, this); - } else { - return []; - } - } - }, - - onClick: function(e, legendItem) { - var index = legendItem.index; - var chart = this.chart; - var i, ilen, meta; - - for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { - meta = chart.getDatasetMeta(i); - meta.data[index].hidden = !meta.data[index].hidden; - } - - chart.update(); - } - }, - - //The percentage of the chart that we cut out of the middle. - cutoutPercentage: 50, - - //The rotation of the chart, where the first data arc begins. - rotation: Math.PI * -0.5, - - //The total circumference of the chart. - circumference: Math.PI * 2.0, - - // Need to override these to give a nice default - tooltips: { - callbacks: { - title: function() { - return ''; - }, - label: function(tooltipItem, data) { - return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; - } - } - } - }; - - Chart.defaults.pie = helpers.clone(Chart.defaults.doughnut); - helpers.extend(Chart.defaults.pie, { - cutoutPercentage: 0 - }); - - - Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({ - linkScales: function() { - // no scales for doughnut - }, - - addElements: function() { - var meta = this.getMeta(); - helpers.each(this.getDataset().data, function(value, index) { - meta.data[index] = meta.data[index] || new Chart.elements.Arc({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - - addElementAndReset: function(index, colorForNewElement) { - var arc = new Chart.elements.Arc({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - if (colorForNewElement && helpers.isArray(this.getDataset().backgroundColor)) { - this.getDataset().backgroundColor.splice(index, 0, colorForNewElement); - } - - // Add to the points array and reset it - this.getMeta().data.splice(index, 0, arc); - this.updateElement(arc, index, true); - }, - - // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly - getRingIndex: function getRingIndex(datasetIndex) { - var ringIndex = 0; - - for (var j = 0; j < datasetIndex; ++j) { - if (this.chart.isDatasetVisible(j)) { - ++ringIndex; - } - } - - return ringIndex; - }, - - update: function update(reset) { - var availableWidth = this.chart.chartArea.right - this.chart.chartArea.left - this.chart.options.elements.arc.borderWidth; - var availableHeight = this.chart.chartArea.bottom - this.chart.chartArea.top - this.chart.options.elements.arc.borderWidth; - var minSize = Math.min(availableWidth, availableHeight); - var offset = {x: 0, y: 0}; - - // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc - if (this.chart.options.circumference < Math.PI * 2.0) { - var startAngle = this.chart.options.rotation % (Math.PI * 2.0); - startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0); - var endAngle = startAngle + this.chart.options.circumference; - var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)}; - var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)}; - var contains0 = (startAngle <= 0 && 0 <= endAngle) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle); - var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle); - var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle); - var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle); - var cutout = this.chart.options.cutoutPercentage / 100.0; - var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))}; - var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))}; - var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5}; - minSize = Math.min(availableWidth / size.width, availableHeight / size.height); - offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5}; - } - - this.chart.outerRadius = Math.max(minSize / 2, 0); - this.chart.innerRadius = Math.max(this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1, 0); - this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.chart.getVisibleDatasetCount(); - this.chart.offsetX = offset.x * this.chart.outerRadius; - this.chart.offsetY = offset.y * this.chart.outerRadius; - - this.getMeta().total = this.calculateTotal(); - - this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.getRingIndex(this.index)); - this.innerRadius = this.outerRadius - this.chart.radiusLength; - - helpers.each(this.getMeta().data, function(arc, index) { - this.updateElement(arc, index, reset); - }, this); - }, - - updateElement: function(arc, index, reset) { - var centerX = (this.chart.chartArea.left + this.chart.chartArea.right) / 2; - var centerY = (this.chart.chartArea.top + this.chart.chartArea.bottom) / 2; - var startAngle = this.chart.options.rotation; // non reset case handled later - var endAngle = this.chart.options.rotation; // non reset case handled later - var circumference = reset && this.chart.options.animation.animateRotate ? 0 : arc.hidden? 0 : this.calculateCircumference(this.getDataset().data[index]) * (this.chart.options.circumference / (2.0 * Math.PI)); - var innerRadius = reset && this.chart.options.animation.animateScale ? 0 : this.innerRadius; - var outerRadius = reset && this.chart.options.animation.animateScale ? 0 : this.outerRadius; - - helpers.extend(arc, { - // Utility - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index, - - // Desired view properties - _model: { - x: centerX + this.chart.offsetX, - y: centerY + this.chart.offsetY, - startAngle: startAngle, - endAngle: endAngle, - circumference: circumference, - outerRadius: outerRadius, - innerRadius: innerRadius, - - backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor), - hoverBackgroundColor: arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().hoverBackgroundColor, index, this.chart.options.elements.arc.hoverBackgroundColor), - borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth), - borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor), - - label: helpers.getValueAtIndexOrDefault(this.getDataset().label, index, this.chart.data.labels[index]) - } - }); - - // Set correct angles if not resetting - if (!reset || !this.chart.options.animation.animateRotate) { - - if (index === 0) { - arc._model.startAngle = this.chart.options.rotation; - } else { - arc._model.startAngle = this.getMeta().data[index - 1]._model.endAngle; - } - - arc._model.endAngle = arc._model.startAngle + arc._model.circumference; - } - - arc.pivot(); - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - helpers.each(this.getMeta().data, function(arc, index) { - arc.transition(easingDecimal).draw(); - }); - }, - - setHoverStyle: function(arc) { - var dataset = this.chart.data.datasets[arc._datasetIndex]; - var index = arc._index; - - arc._model.backgroundColor = arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(arc._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - arc._model.borderColor = arc.custom && arc.custom.hoverBorderColor ? arc.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(arc._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - arc._model.borderWidth = arc.custom && arc.custom.hoverBorderWidth ? arc.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, arc._model.borderWidth); - }, - - removeHoverStyle: function(arc) { - var dataset = this.chart.data.datasets[arc._datasetIndex]; - var index = arc._index; - - arc._model.backgroundColor = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor); - arc._model.borderColor = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor); - arc._model.borderWidth = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth); - }, - - calculateTotal: function() { - var dataset = this.getDataset(); - var meta = this.getMeta(); - var total = 0; - var value; - - helpers.each(meta.data, function(element, index) { - value = dataset.data[index]; - if (!isNaN(value) && !element.hidden) { - total += Math.abs(value); - } - }); - - return total; - }, - - calculateCircumference: function(value) { - var total = this.getMeta().total; - if (total > 0 && !isNaN(value)) { - return (Math.PI * 2.0) * (value / total); - } else { - return 0; - } - } - }); -}; + var _moment = utils_hooks__hooks; -},{}],18:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.line = { - showLines: true, - - hover: { - mode: "label" - }, - - scales: { - xAxes: [{ - type: "category", - id: 'x-axis-0' - }], - yAxes: [{ - type: "linear", - id: 'y-axis-0' - }] - } - }; - - - Chart.controllers.line = Chart.DatasetController.extend({ - addElements: function() { - var meta = this.getMeta(); - meta.dataset = meta.dataset || new Chart.elements.Line({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _points: meta.data - }); - - helpers.each(this.getDataset().data, function(value, index) { - meta.data[index] = meta.data[index] || new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - - addElementAndReset: function(index) { - var point = new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - // Add to the points array and reset it - this.getMeta().data.splice(index, 0, point); - this.updateElement(point, index, true); - - // Make sure bezier control points are updated - if (this.chart.options.showLines && this.chart.options.elements.line.tension !== 0) - this.updateBezierControlPoints(); - }, - - update: function update(reset) { - var meta = this.getMeta(); - var line = meta.dataset; - var points = meta.data; - - var yScale = this.getScaleForId(meta.yAxisID); - var xScale = this.getScaleForId(meta.xAxisID); - var scaleBase; - - if (yScale.min < 0 && yScale.max < 0) { - scaleBase = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - scaleBase = yScale.getPixelForValue(yScale.min); - } else { - scaleBase = yScale.getPixelForValue(0); - } - - // Update Line - if (this.chart.options.showLines) { - // Utility - line._scale = yScale; - line._datasetIndex = this.index; - // Data - line._children = points; - // Model - - // Compatibility: If the properties are defined with only the old name, use those values - if ((this.getDataset().tension !== undefined) && (this.getDataset().lineTension === undefined)) - { - this.getDataset().lineTension = this.getDataset().tension; - } - - line._model = { - // Appearance - tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().lineTension, this.chart.options.elements.line.tension), - backgroundColor: line.custom && line.custom.backgroundColor ? line.custom.backgroundColor : (this.getDataset().backgroundColor || this.chart.options.elements.line.backgroundColor), - borderWidth: line.custom && line.custom.borderWidth ? line.custom.borderWidth : (this.getDataset().borderWidth || this.chart.options.elements.line.borderWidth), - borderColor: line.custom && line.custom.borderColor ? line.custom.borderColor : (this.getDataset().borderColor || this.chart.options.elements.line.borderColor), - borderCapStyle: line.custom && line.custom.borderCapStyle ? line.custom.borderCapStyle : (this.getDataset().borderCapStyle || this.chart.options.elements.line.borderCapStyle), - borderDash: line.custom && line.custom.borderDash ? line.custom.borderDash : (this.getDataset().borderDash || this.chart.options.elements.line.borderDash), - borderDashOffset: line.custom && line.custom.borderDashOffset ? line.custom.borderDashOffset : (this.getDataset().borderDashOffset || this.chart.options.elements.line.borderDashOffset), - borderJoinStyle: line.custom && line.custom.borderJoinStyle ? line.custom.borderJoinStyle : (this.getDataset().borderJoinStyle || this.chart.options.elements.line.borderJoinStyle), - fill: line.custom && line.custom.fill ? line.custom.fill : (this.getDataset().fill !== undefined ? this.getDataset().fill : this.chart.options.elements.line.fill), - // Scale - scaleTop: yScale.top, - scaleBottom: yScale.bottom, - scaleZero: scaleBase - }; - line.pivot(); - } - - // Update Points - helpers.each(points, function(point, index) { - this.updateElement(point, index, reset); - }, this); - - if (this.chart.options.showLines && this.chart.options.elements.line.tension !== 0) - this.updateBezierControlPoints(); - }, - - getPointBackgroundColor: function(point, index) { - var backgroundColor = this.chart.options.elements.point.backgroundColor; - var dataset = this.getDataset(); - - if (point.custom && point.custom.backgroundColor) { - backgroundColor = point.custom.backgroundColor; - } else if (dataset.pointBackgroundColor) { - backgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor); - } else if (dataset.backgroundColor) { - backgroundColor = dataset.backgroundColor; - } - - return backgroundColor; - }, - getPointBorderColor: function(point, index) { - var borderColor = this.chart.options.elements.point.borderColor; - var dataset = this.getDataset(); - - if (point.custom && point.custom.borderColor) { - borderColor = point.custom.borderColor; - } else if (dataset.pointBorderColor) { - borderColor = helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, borderColor); - } else if (dataset.borderColor) { - borderColor = dataset.borderColor; - } - - return borderColor; - }, - getPointBorderWidth: function(point, index) { - var borderWidth = this.chart.options.elements.point.borderWidth; - var dataset = this.getDataset(); - - if (point.custom && point.custom.borderWidth !== undefined) { - borderWidth = point.custom.borderWidth; - } else if (dataset.pointBorderWidth !== undefined) { - borderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth); - } else if (dataset.borderWidth !== undefined) { - borderWidth = dataset.borderWidth; - } - - return borderWidth; - }, - - updateElement: function(point, index, reset) { - var meta = this.getMeta(); - var yScale = this.getScaleForId(meta.yAxisID); - var xScale = this.getScaleForId(meta.xAxisID); - var scaleBase; - - if (yScale.min < 0 && yScale.max < 0) { - scaleBase = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - scaleBase = yScale.getPixelForValue(yScale.min); - } else { - scaleBase = yScale.getPixelForValue(0); - } - - // Utility - point._chart = this.chart.chart; - point._xScale = xScale; - point._yScale = yScale; - point._datasetIndex = this.index; - point._index = index; - - // Desired view properties - - // Compatibility: If the properties are defined with only the old name, use those values - if ((this.getDataset().radius !== undefined) && (this.getDataset().pointRadius === undefined)) - { - this.getDataset().pointRadius = this.getDataset().radius; - } - if ((this.getDataset().hitRadius !== undefined) && (this.getDataset().pointHitRadius === undefined)) - { - this.getDataset().pointHitRadius = this.getDataset().hitRadius; - } - - point._model = { - x: xScale.getPixelForValue(this.getDataset().data[index], index, this.index, this.chart.isCombo), - y: reset ? scaleBase : this.calculatePointY(this.getDataset().data[index], index, this.index, this.chart.isCombo), - // Appearance - radius: point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().pointRadius, index, this.chart.options.elements.point.radius), - pointStyle: point.custom && point.custom.pointStyle ? point.custom.pointStyle : helpers.getValueAtIndexOrDefault(this.getDataset().pointStyle, index, this.chart.options.elements.point.pointStyle), - backgroundColor: this.getPointBackgroundColor(point, index), - borderColor: this.getPointBorderColor(point, index), - borderWidth: this.getPointBorderWidth(point, index), - tension: meta.dataset._model ? meta.dataset._model.tension : 0, - // Tooltip - hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().pointHitRadius, index, this.chart.options.elements.point.hitRadius) - }; - - point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); - }, - - calculatePointY: function(value, index, datasetIndex, isCombo) { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - - if (yScale.options.stacked) { - - var sumPos = 0, - sumNeg = 0; - - for (var i = 0; i < datasetIndex; i++) { - var ds = this.chart.data.datasets[i]; - var dsMeta = this.chart.getDatasetMeta(i); - if (dsMeta.type === 'line' && this.chart.isDatasetVisible(i)) { - if (ds.data[index] < 0) { - sumNeg += ds.data[index] || 0; - } else { - sumPos += ds.data[index] || 0; - } - } - } - - if (value < 0) { - return yScale.getPixelForValue(sumNeg + value); - } else { - return yScale.getPixelForValue(sumPos + value); - } - } - - return yScale.getPixelForValue(value); - }, - - updateBezierControlPoints: function() { - // Update bezier control points - var meta = this.getMeta(); - helpers.each(meta.data, function(point, index) { - var controlPoints = helpers.splineCurve( - helpers.previousItem(meta.data, index)._model, - point._model, - helpers.nextItem(meta.data, index)._model, - meta.dataset._model.tension - ); - - // Prevent the bezier going outside of the bounds of the graph - point._model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, this.chart.chartArea.right), this.chart.chartArea.left); - point._model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, this.chart.chartArea.bottom), this.chart.chartArea.top); - - point._model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, this.chart.chartArea.right), this.chart.chartArea.left); - point._model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, this.chart.chartArea.bottom), this.chart.chartArea.top); - - // Now pivot the point for animation - point.pivot(); - }, this); - }, - - draw: function(ease) { - var meta = this.getMeta(); - var easingDecimal = ease || 1; - - // Transition Point Locations - helpers.each(meta.data, function(point) { - point.transition(easingDecimal); - }); - - // Transition and Draw the line - if (this.chart.options.showLines) - meta.dataset.transition(easingDecimal).draw(); - - // Draw the points - helpers.each(meta.data, function(point) { - point.draw(); - }); - }, - - setHoverStyle: function(point) { - // Point - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); - point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(point._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(point._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, point._model.borderWidth); - }, - - removeHoverStyle: function(point) { - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - // Compatibility: If the properties are defined with only the old name, use those values - if ((this.getDataset().radius !== undefined) && (this.getDataset().pointRadius === undefined)) - { - this.getDataset().pointRadius = this.getDataset().radius; - } - - point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().pointRadius, index, this.chart.options.elements.point.radius); - point._model.backgroundColor = this.getPointBackgroundColor(point, index); - point._model.borderColor = this.getPointBorderColor(point, index); - point._model.borderWidth = this.getPointBorderWidth(point, index); - } - }); -}; + return _moment; -},{}],19:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.polarArea = { - - scale: { - type: "radialLinear", - lineArc: true // so that lines are circular - }, - - //Boolean - Whether to animate the rotation of the chart - animation: { - animateRotate: true, - animateScale: true - }, - - aspectRatio: 1, - legendCallback: function(chart) { - var text = []; - text.push(''); - return text.join(""); - }, - legend: { - labels: { - generateLabels: function(chart) { - var data = chart.data; - if (data.labels.length && data.datasets.length) { - return data.labels.map(function(label, i) { - var meta = chart.getDatasetMeta(0); - var ds = data.datasets[0]; - var arc = meta.data[i]; - var fill = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(ds.backgroundColor, i, this.chart.options.elements.arc.backgroundColor); - var stroke = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(ds.borderColor, i, this.chart.options.elements.arc.borderColor); - var bw = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(ds.borderWidth, i, this.chart.options.elements.arc.borderWidth); - - return { - text: label, - fillStyle: fill, - strokeStyle: stroke, - lineWidth: bw, - hidden: isNaN(ds.data[i]) || meta.data[i].hidden, - - // Extra data used for toggling the correct item - index: i - }; - }, this); - } else { - return []; - } - } - }, - - onClick: function(e, legendItem) { - var index = legendItem.index; - var chart = this.chart; - var i, ilen, meta; - - for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { - meta = chart.getDatasetMeta(i); - meta.data[index].hidden = !meta.data[index].hidden; - } - - chart.update(); - } - }, - - // Need to override these to give a nice default - tooltips: { - callbacks: { - title: function() { - return ''; - }, - label: function(tooltipItem, data) { - return data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel; - } - } - } - }; - - Chart.controllers.polarArea = Chart.DatasetController.extend({ - linkScales: function() { - // no scales for doughnut - }, - - addElements: function() { - var meta = this.getMeta(); - helpers.each(this.getDataset().data, function(value, index) { - meta.data[index] = meta.data[index] || new Chart.elements.Arc({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - - addElementAndReset: function(index) { - var arc = new Chart.elements.Arc({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - // Add to the points array and reset it - this.getMeta().data.splice(index, 0, arc); - this.updateElement(arc, index, true); - }, - - update: function update(reset) { - var meta = this.getMeta(); - var minSize = Math.min(this.chart.chartArea.right - this.chart.chartArea.left, this.chart.chartArea.bottom - this.chart.chartArea.top); - this.chart.outerRadius = Math.max((minSize - this.chart.options.elements.arc.borderWidth / 2) / 2, 0); - this.chart.innerRadius = Math.max(this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1, 0); - this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.chart.getVisibleDatasetCount(); - - this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.index); - this.innerRadius = this.outerRadius - this.chart.radiusLength; - - meta.count = this.countVisibleElements(); - - helpers.each(meta.data, function(arc, index) { - this.updateElement(arc, index, reset); - }, this); - }, - - updateElement: function(arc, index, reset) { - var circumference = this.calculateCircumference(this.getDataset().data[index]); - var centerX = (this.chart.chartArea.left + this.chart.chartArea.right) / 2; - var centerY = (this.chart.chartArea.top + this.chart.chartArea.bottom) / 2; - - // If there is NaN data before us, we need to calculate the starting angle correctly. - // We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data - var visibleCount = 0; - var meta = this.getMeta(); - for (var i = 0; i < index; ++i) { - if (!isNaN(this.getDataset().data[i]) && !meta.data[i].hidden) { - ++visibleCount; - } - } - - var distance = arc.hidden? 0 : this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]); - var startAngle = (-0.5 * Math.PI) + (circumference * visibleCount); - var endAngle = startAngle + (arc.hidden? 0 : circumference); - - var resetModel = { - x: centerX, - y: centerY, - innerRadius: 0, - outerRadius: this.chart.options.animation.animateScale ? 0 : this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]), - startAngle: this.chart.options.animation.animateRotate ? Math.PI * -0.5 : startAngle, - endAngle: this.chart.options.animation.animateRotate ? Math.PI * -0.5 : endAngle, - - backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor), - borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth), - borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor), - - label: helpers.getValueAtIndexOrDefault(this.chart.data.labels, index, this.chart.data.labels[index]) - }; - - helpers.extend(arc, { - // Utility - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index, - _scale: this.chart.scale, - - // Desired view properties - _model: reset ? resetModel : { - x: centerX, - y: centerY, - innerRadius: 0, - outerRadius: distance, - startAngle: startAngle, - endAngle: endAngle, - - backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor), - borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth), - borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor), - - label: helpers.getValueAtIndexOrDefault(this.chart.data.labels, index, this.chart.data.labels[index]) - } - }); - - arc.pivot(); - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - helpers.each(this.getMeta().data, function(arc, index) { - arc.transition(easingDecimal).draw(); - }); - }, - - setHoverStyle: function(arc) { - var dataset = this.chart.data.datasets[arc._datasetIndex]; - var index = arc._index; - - arc._model.backgroundColor = arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(arc._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - arc._model.borderColor = arc.custom && arc.custom.hoverBorderColor ? arc.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(arc._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - arc._model.borderWidth = arc.custom && arc.custom.hoverBorderWidth ? arc.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, arc._model.borderWidth); - }, - - removeHoverStyle: function(arc) { - var dataset = this.chart.data.datasets[arc._datasetIndex]; - var index = arc._index; - - arc._model.backgroundColor = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor); - arc._model.borderColor = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor); - arc._model.borderWidth = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth); - }, - - countVisibleElements: function() { - var dataset = this.getDataset(); - var meta = this.getMeta(); - var count = 0; - - helpers.each(meta.data, function(element, index) { - if (!isNaN(dataset.data[index]) && !element.hidden) { - count++; - } - }); - - return count; - }, - - calculateCircumference: function(value) { - var count = this.getMeta().count; - if (count > 0 && !isNaN(value)) { - return (2 * Math.PI) / count; - } else { - return 0; - } - } - }); -}; +})); +},{}],7:[function(require,module,exports){ +var Chart = require('./core/core.js')(); + +require('./core/core.helpers')(Chart); +require('./core/core.element')(Chart); +require('./core/core.animation')(Chart); +require('./core/core.controller')(Chart); +require('./core/core.datasetController')(Chart); +require('./core/core.layoutService')(Chart); +require('./core/core.legend')(Chart); +require('./core/core.plugin.js')(Chart); +require('./core/core.scale')(Chart); +require('./core/core.scaleService')(Chart); +require('./core/core.title')(Chart); +require('./core/core.tooltip')(Chart); + +require('./controllers/controller.bar')(Chart); +require('./controllers/controller.bubble')(Chart); +require('./controllers/controller.doughnut')(Chart); +require('./controllers/controller.line')(Chart); +require('./controllers/controller.polarArea')(Chart); +require('./controllers/controller.radar')(Chart); + +require('./scales/scale.category')(Chart); +require('./scales/scale.linear')(Chart); +require('./scales/scale.logarithmic')(Chart); +require('./scales/scale.radialLinear')(Chart); +require('./scales/scale.time')(Chart); + +require('./elements/element.arc')(Chart); +require('./elements/element.line')(Chart); +require('./elements/element.point')(Chart); +require('./elements/element.rectangle')(Chart); + +require('./charts/Chart.Bar')(Chart); +require('./charts/Chart.Bubble')(Chart); +require('./charts/Chart.Doughnut')(Chart); +require('./charts/Chart.Line')(Chart); +require('./charts/Chart.PolarArea')(Chart); +require('./charts/Chart.Radar')(Chart); +require('./charts/Chart.Scatter')(Chart); + +window.Chart = module.exports = Chart; + +},{"./charts/Chart.Bar":8,"./charts/Chart.Bubble":9,"./charts/Chart.Doughnut":10,"./charts/Chart.Line":11,"./charts/Chart.PolarArea":12,"./charts/Chart.Radar":13,"./charts/Chart.Scatter":14,"./controllers/controller.bar":15,"./controllers/controller.bubble":16,"./controllers/controller.doughnut":17,"./controllers/controller.line":18,"./controllers/controller.polarArea":19,"./controllers/controller.radar":20,"./core/core.animation":21,"./core/core.controller":22,"./core/core.datasetController":23,"./core/core.element":24,"./core/core.helpers":25,"./core/core.js":26,"./core/core.layoutService":27,"./core/core.legend":28,"./core/core.plugin.js":29,"./core/core.scale":30,"./core/core.scaleService":31,"./core/core.title":32,"./core/core.tooltip":33,"./elements/element.arc":34,"./elements/element.line":35,"./elements/element.point":36,"./elements/element.rectangle":37,"./scales/scale.category":38,"./scales/scale.linear":39,"./scales/scale.logarithmic":40,"./scales/scale.radialLinear":41,"./scales/scale.time":42}],8:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + Chart.Bar = function(context, config) { + config.type = 'bar'; + + return new Chart(context, config); + }; -},{}],20:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - - Chart.defaults.radar = { - scale: { - type: "radialLinear" - }, - elements: { - line: { - tension: 0 // no bezier in radar - } - } - }; - - Chart.controllers.radar = Chart.DatasetController.extend({ - linkScales: function() { - // No need. Single scale only - }, - - addElements: function() { - var meta = this.getMeta(); - - meta.dataset = meta.dataset || new Chart.elements.Line({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _points: meta.data, - _loop: true - }); - - helpers.each(this.getDataset().data, function(value, index) { - meta.data[index] = meta.data[index] || new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index, - _model: { - x: 0, //xScale.getPixelForValue(null, index, true), - y: 0 //this.chartArea.bottom, - } - }); - }, this); - }, - addElementAndReset: function(index) { - var point = new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - // Add to the points array and reset it - this.getMeta().data.splice(index, 0, point); - this.updateElement(point, index, true); - - // Make sure bezier control points are updated - this.updateBezierControlPoints(); - }, - - update: function update(reset) { - var meta = this.getMeta(); - var line = meta.dataset; - var points = meta.data; - - var scale = this.chart.scale; - var scaleBase; - - if (scale.min < 0 && scale.max < 0) { - scaleBase = scale.getPointPositionForValue(0, scale.max); - } else if (scale.min > 0 && scale.max > 0) { - scaleBase = scale.getPointPositionForValue(0, scale.min); - } else { - scaleBase = scale.getPointPositionForValue(0, 0); - } - - // Compatibility: If the properties are defined with only the old name, use those values - if ((this.getDataset().tension !== undefined) && (this.getDataset().lineTension === undefined)) - { - this.getDataset().lineTension = this.getDataset().tension; - } - - helpers.extend(meta.dataset, { - // Utility - _datasetIndex: this.index, - // Data - _children: points, - // Model - _model: { - // Appearance - tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().lineTension, this.chart.options.elements.line.tension), - backgroundColor: line.custom && line.custom.backgroundColor ? line.custom.backgroundColor : (this.getDataset().backgroundColor || this.chart.options.elements.line.backgroundColor), - borderWidth: line.custom && line.custom.borderWidth ? line.custom.borderWidth : (this.getDataset().borderWidth || this.chart.options.elements.line.borderWidth), - borderColor: line.custom && line.custom.borderColor ? line.custom.borderColor : (this.getDataset().borderColor || this.chart.options.elements.line.borderColor), - fill: line.custom && line.custom.fill ? line.custom.fill : (this.getDataset().fill !== undefined ? this.getDataset().fill : this.chart.options.elements.line.fill), - borderCapStyle: line.custom && line.custom.borderCapStyle ? line.custom.borderCapStyle : (this.getDataset().borderCapStyle || this.chart.options.elements.line.borderCapStyle), - borderDash: line.custom && line.custom.borderDash ? line.custom.borderDash : (this.getDataset().borderDash || this.chart.options.elements.line.borderDash), - borderDashOffset: line.custom && line.custom.borderDashOffset ? line.custom.borderDashOffset : (this.getDataset().borderDashOffset || this.chart.options.elements.line.borderDashOffset), - borderJoinStyle: line.custom && line.custom.borderJoinStyle ? line.custom.borderJoinStyle : (this.getDataset().borderJoinStyle || this.chart.options.elements.line.borderJoinStyle), - - // Scale - scaleTop: scale.top, - scaleBottom: scale.bottom, - scaleZero: scaleBase - } - }); - - meta.dataset.pivot(); - - // Update Points - helpers.each(points, function(point, index) { - this.updateElement(point, index, reset); - }, this); - - - // Update bezier control points - this.updateBezierControlPoints(); - }, - updateElement: function(point, index, reset) { - var pointPosition = this.chart.scale.getPointPositionForValue(index, this.getDataset().data[index]); - - helpers.extend(point, { - // Utility - _datasetIndex: this.index, - _index: index, - _scale: this.chart.scale, - - // Desired view properties - _model: { - x: reset ? this.chart.scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales - y: reset ? this.chart.scale.yCenter : pointPosition.y, - - // Appearance - tension: point.custom && point.custom.tension ? point.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension), - radius: point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().pointRadius, index, this.chart.options.elements.point.radius), - backgroundColor: point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBackgroundColor, index, this.chart.options.elements.point.backgroundColor), - borderColor: point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, this.chart.options.elements.point.borderColor), - borderWidth: point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderWidth, index, this.chart.options.elements.point.borderWidth), - pointStyle: point.custom && point.custom.pointStyle ? point.custom.pointStyle : helpers.getValueAtIndexOrDefault(this.getDataset().pointStyle, index, this.chart.options.elements.point.pointStyle), - - // Tooltip - hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius) - } - }); - - point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); - }, - updateBezierControlPoints: function() { - var meta = this.getMeta(); - helpers.each(meta.data, function(point, index) { - var controlPoints = helpers.splineCurve( - helpers.previousItem(meta.data, index, true)._model, - point._model, - helpers.nextItem(meta.data, index, true)._model, - point._model.tension - ); - - // Prevent the bezier going outside of the bounds of the graph - point._model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, this.chart.chartArea.right), this.chart.chartArea.left); - point._model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, this.chart.chartArea.bottom), this.chart.chartArea.top); - - point._model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, this.chart.chartArea.right), this.chart.chartArea.left); - point._model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, this.chart.chartArea.bottom), this.chart.chartArea.top); - - // Now pivot the point for animation - point.pivot(); - }, this); - }, - - draw: function(ease) { - var meta = this.getMeta(); - var easingDecimal = ease || 1; - - // Transition Point Locations - helpers.each(meta.data, function(point, index) { - point.transition(easingDecimal); - }); - - // Transition and Draw the line - meta.dataset.transition(easingDecimal).draw(); - - // Draw the points - helpers.each(meta.data, function(point) { - point.draw(); - }); - }, - - setHoverStyle: function(point) { - // Point - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); - point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(point._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(point._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, point._model.borderWidth); - }, - - removeHoverStyle: function(point) { - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius); - point._model.backgroundColor = point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBackgroundColor, index, this.chart.options.elements.point.backgroundColor); - point._model.borderColor = point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, this.chart.options.elements.point.borderColor); - point._model.borderWidth = point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderWidth, index, this.chart.options.elements.point.borderWidth); - } - }); -}; -},{}],21:[function(require,module,exports){ -/*global window: false */ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.global.animation = { - duration: 1000, - easing: "easeOutQuart", - onProgress: helpers.noop, - onComplete: helpers.noop - }; - - 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.animationService = { - frameDuration: 17, - animations: [], - dropFrames: 0, - request: null, - addAnimation: function(chartInstance, animationObject, duration, lazy) { - - if (!lazy) { - chartInstance.animating = true; - } - - 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) { - this.requestAnimationFrame(); - } - }, - // Cancel the animation for a given chart instance - cancelAnimation: function(chartInstance) { - var index = helpers.findIndex(this.animations, function(animationWrapper) { - return animationWrapper.chartInstance === chartInstance; - }); - - if (index !== -1) { - this.animations.splice(index, 1); - chartInstance.animating = false; - } - }, - requestAnimationFrame: function() { - var me = this; - if (me.request === null) { - // Skip animation frame requests until the active one is executed. - // This can happen when processing mouse events, e.g. 'mousemove' - // and 'mouseout' events will trigger multiple renders. - me.request = helpers.requestAnimFrame.call(window, function() { - me.request = null; - me.startDigest(); - }); - } - }, - startDigest: function() { - - var startTime = Date.now(); - var framesToDrop = 0; - - if (this.dropFrames > 1) { - framesToDrop = Math.floor(this.dropFrames); - this.dropFrames = this.dropFrames % 1; - } - - var i = 0; - while (i < this.animations.length) { - 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); - if (this.animations[i].animationObject.onAnimationProgress && this.animations[i].animationObject.onAnimationProgress.call) { - this.animations[i].animationObject.onAnimationProgress.call(this.animations[i].chartInstance, this.animations[i]); - } - - if (this.animations[i].animationObject.currentStep === this.animations[i].animationObject.numSteps) { - if (this.animations[i].animationObject.onAnimationComplete && this.animations[i].animationObject.onAnimationComplete.call) { - this.animations[i].animationObject.onAnimationComplete.call(this.animations[i].chartInstance, this.animations[i]); - } - - // executed the last frame. Remove the animation. - this.animations[i].chartInstance.animating = false; - - this.animations.splice(i, 1); - } else { - ++i; - } - } - - var endTime = Date.now(); - var dropFrames = (endTime - startTime) / this.frameDuration; - - this.dropFrames += dropFrames; - - // Do we have more stuff to animate? - if (this.animations.length > 0) { - this.requestAnimationFrame(); - } - } - }; }; -},{}],22:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - //Create a dictionary of chart types, to allow for extension of existing types - Chart.types = {}; - - //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 = {}; - - // Controllers available for dataset visualization eg. bar, line, slice, etc. - Chart.controllers = {}; - - // The main controller of a chart - Chart.Controller = function(instance) { - - this.chart = instance; - this.config = instance.config; - this.options = this.config.options = helpers.configMerge(Chart.defaults.global, Chart.defaults[this.config.type], this.config.options || {}); - this.id = helpers.uid(); - - Object.defineProperty(this, 'data', { - get: function() { - return this.config.data; - } - }); - - //Add the chart instance to the global namespace - Chart.instances[this.id] = this; - - if (this.options.responsive) { - // Silent resize before chart draws - this.resize(true); - } - - this.initialize(); - - return this; - }; - - helpers.extend(Chart.Controller.prototype, { - - initialize: function initialize() { - // Before init plugin notification - Chart.pluginService.notifyPlugins('beforeInit', [this]); - - this.bindEvents(); - - // Make sure controllers are built first so that each dataset is bound to an axis before the scales - // are built - this.ensureScalesHaveIDs(); - this.buildOrUpdateControllers(); - this.buildScales(); - this.buildSurroundingItems(); - this.updateLayout(); - this.resetElements(); - this.initToolTip(); - this.update(); - - // After init plugin notification - Chart.pluginService.notifyPlugins('afterInit', [this]); - - return this; - }, - - clear: function clear() { - helpers.clear(this.chart); - return this; - }, - - stop: function stop() { - // Stops any current animation loop occuring - Chart.animationService.cancelAnimation(this); - return this; - }, - - resize: function resize(silent) { - var canvas = this.chart.canvas; - var newWidth = helpers.getMaximumWidth(this.chart.canvas); - var newHeight = (this.options.maintainAspectRatio && isNaN(this.chart.aspectRatio) === false && isFinite(this.chart.aspectRatio) && this.chart.aspectRatio !== 0) ? newWidth / this.chart.aspectRatio : helpers.getMaximumHeight(this.chart.canvas); - - var sizeChanged = this.chart.width !== newWidth || this.chart.height !== newHeight; - - if (!sizeChanged) - return this; - - canvas.width = this.chart.width = newWidth; - canvas.height = this.chart.height = newHeight; - - helpers.retinaScale(this.chart); - - if (!silent) { - this.stop(); - this.update(this.options.responsiveAnimationDuration); - } - - return this; - }, - ensureScalesHaveIDs: function ensureScalesHaveIDs() { - var defaultXAxisID = 'x-axis-'; - var defaultYAxisID = 'y-axis-'; - - if (this.options.scales) { - if (this.options.scales.xAxes && this.options.scales.xAxes.length) { - helpers.each(this.options.scales.xAxes, function(xAxisOptions, index) { - xAxisOptions.id = xAxisOptions.id || (defaultXAxisID + index); - }); - } - - if (this.options.scales.yAxes && this.options.scales.yAxes.length) { - // Build the y axes - helpers.each(this.options.scales.yAxes, function(yAxisOptions, index) { - yAxisOptions.id = yAxisOptions.id || (defaultYAxisID + index); - }); - } - } - }, - buildScales: function buildScales() { - // Map of scale ID to scale object so we can lookup later - this.scales = {}; - - // Build the x axes - if (this.options.scales) { - if (this.options.scales.xAxes && this.options.scales.xAxes.length) { - helpers.each(this.options.scales.xAxes, function(xAxisOptions, index) { - var xType = helpers.getValueOrDefault(xAxisOptions.type, 'category'); - var ScaleClass = Chart.scaleService.getScaleConstructor(xType); - if (ScaleClass) { - var scale = new ScaleClass({ - ctx: this.chart.ctx, - options: xAxisOptions, - chart: this, - id: xAxisOptions.id - }); - - this.scales[scale.id] = scale; - } - }, this); - } - - if (this.options.scales.yAxes && this.options.scales.yAxes.length) { - // Build the y axes - helpers.each(this.options.scales.yAxes, function(yAxisOptions, index) { - var yType = helpers.getValueOrDefault(yAxisOptions.type, 'linear'); - var ScaleClass = Chart.scaleService.getScaleConstructor(yType); - if (ScaleClass) { - var scale = new ScaleClass({ - ctx: this.chart.ctx, - options: yAxisOptions, - chart: this, - id: yAxisOptions.id - }); - - this.scales[scale.id] = scale; - } - }, this); - } - } - if (this.options.scale) { - // Build radial axes - var ScaleClass = Chart.scaleService.getScaleConstructor(this.options.scale.type); - if (ScaleClass) { - var scale = new ScaleClass({ - ctx: this.chart.ctx, - options: this.options.scale, - chart: this - }); - - this.scale = scale; - - this.scales.radialScale = scale; - } - } - - Chart.scaleService.addScalesToLayout(this); - }, - - buildSurroundingItems: function() { - if (this.options.title) { - this.titleBlock = new Chart.Title({ - ctx: this.chart.ctx, - options: this.options.title, - chart: this - }); - - Chart.layoutService.addBox(this, this.titleBlock); - } - - if (this.options.legend) { - this.legend = new Chart.Legend({ - ctx: this.chart.ctx, - options: this.options.legend, - chart: this - }); - - Chart.layoutService.addBox(this, this.legend); - } - }, - - updateLayout: function() { - Chart.layoutService.update(this, this.chart.width, this.chart.height); - }, - - buildOrUpdateControllers: function buildOrUpdateControllers() { - var types = []; - var newControllers = []; - - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - var meta = this.getDatasetMeta(datasetIndex); - if (!meta.type) { - meta.type = dataset.type || this.config.type; - } - - types.push(meta.type); - - if (meta.controller) { - meta.controller.updateIndex(datasetIndex); - } else { - meta.controller = new Chart.controllers[meta.type](this, datasetIndex); - newControllers.push(meta.controller); - } - }, this); - - if (types.length > 1) { - for (var i = 1; i < types.length; i++) { - if (types[i] !== types[i - 1]) { - this.isCombo = true; - break; - } - } - } - - return newControllers; - }, - - resetElements: function resetElements() { - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - this.getDatasetMeta(datasetIndex).controller.reset(); - }, this); - }, - - update: function update(animationDuration, lazy) { - Chart.pluginService.notifyPlugins('beforeUpdate', [this]); - - // In case the entire data object changed - this.tooltip._data = this.data; - - // Make sure dataset controllers are updated and new controllers are reset - var newControllers = this.buildOrUpdateControllers(); - - // Make sure all dataset controllers have correct meta data counts - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - this.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements(); - }, this); - - Chart.layoutService.update(this, this.chart.width, this.chart.height); - - // Can only reset the new controllers after the scales have been updated - helpers.each(newControllers, function(controller) { - controller.reset(); - }); - - // This will loop through any data and do the appropriate element update for the type - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - this.getDatasetMeta(datasetIndex).controller.update(); - }, this); - - this.render(animationDuration, lazy); - - Chart.pluginService.notifyPlugins('afterUpdate', [this]); - }, - - render: function render(duration, lazy) { - Chart.pluginService.notifyPlugins('beforeRender', [this]); - - if (this.options.animation && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && this.options.animation.duration !== 0))) { - var animation = new Chart.Animation(); - animation.numSteps = (duration || this.options.animation.duration) / 16.66; //60 fps - animation.easing = this.options.animation.easing; - - // 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.animation.onProgress; - animation.onAnimationComplete = this.options.animation.onComplete; - - Chart.animationService.addAnimation(this, animation, duration, lazy); - } else { - this.draw(); - if (this.options.animation && this.options.animation.onComplete && this.options.animation.onComplete.call) { - this.options.animation.onComplete.call(this); - } - } - return this; - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - this.clear(); - - Chart.pluginService.notifyPlugins('beforeDraw', [this, easingDecimal]); - - // Draw all the scales - helpers.each(this.boxes, function(box) { - box.draw(this.chartArea); - }, this); - if (this.scale) { - this.scale.draw(); - } - - // Clip out the chart area so that anything outside does not draw. This is necessary for zoom and pan to function - this.chart.ctx.save(); - this.chart.ctx.beginPath(); - this.chart.ctx.rect(this.chartArea.left, this.chartArea.top, this.chartArea.right - this.chartArea.left, this.chartArea.bottom - this.chartArea.top); - this.chart.ctx.clip(); - - // Draw each dataset via its respective controller (reversed to support proper line stacking) - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - if (this.isDatasetVisible(datasetIndex)) { - this.getDatasetMeta(datasetIndex).controller.draw(ease); - } - }, this, true); - - // Restore from the clipping operation - this.chart.ctx.restore(); - - // Finally draw the tooltip - this.tooltip.transition(easingDecimal).draw(); - - Chart.pluginService.notifyPlugins('afterDraw', [this, easingDecimal]); - }, - - // Get the single element that was clicked on - // @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw - getElementAtEvent: function(e) { - var eventPosition = helpers.getRelativePosition(e, this.chart); - var elementsArray = []; - - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - if (this.isDatasetVisible(datasetIndex)) { - var meta = this.getDatasetMeta(datasetIndex); - helpers.each(meta.data, function(element, index) { - if (element.inRange(eventPosition.x, eventPosition.y)) { - elementsArray.push(element); - return elementsArray; - } - }); - } - }, this); - - return elementsArray; - }, - - getElementsAtEvent: function(e) { - var eventPosition = helpers.getRelativePosition(e, this.chart); - var elementsArray = []; - - var found = (function() { - if (this.data.datasets) { - for (var i = 0; i < this.data.datasets.length; i++) { - var meta = this.getDatasetMeta(i); - if (this.isDatasetVisible(i)) { - for (var j = 0; j < meta.data.length; j++) { - if (meta.data[j].inRange(eventPosition.x, eventPosition.y)) { - return meta.data[j]; - } - } - } - } - } - }).call(this); - - if (!found) { - return elementsArray; - } - - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - if (this.isDatasetVisible(datasetIndex)) { - var meta = this.getDatasetMeta(datasetIndex); - elementsArray.push(meta.data[found._index]); - } - }, this); - - return elementsArray; - }, - - getDatasetAtEvent: function(e) { - var elementsArray = this.getElementAtEvent(e); - - if (elementsArray.length > 0) { - elementsArray = this.getDatasetMeta(elementsArray[0]._datasetIndex).data; - } - - return elementsArray; - }, - - getDatasetMeta: function(datasetIndex) { - var dataset = this.data.datasets[datasetIndex]; - if (!dataset._meta) { - dataset._meta = {}; - } - - var meta = dataset._meta[this.id]; - if (!meta) { - meta = dataset._meta[this.id] = { - type: null, - data: [], - dataset: null, - controller: null, - hidden: null, // See isDatasetVisible() comment - xAxisID: null, - yAxisID: null - }; - } - - return meta; - }, - - getVisibleDatasetCount: function() { - var count = 0; - for (var i = 0, ilen = this.data.datasets.length; i