diff --git a/dist/react-chartjs-2.js b/dist/react-chartjs-2.js index 7b7b1f5cd..b4200183f 100644 --- a/dist/react-chartjs-2.js +++ b/dist/react-chartjs-2.js @@ -1,13825 +1,4 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Chart = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 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 < this.getDataset().data.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); - } - }); -}; - -},{}],10:[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); - } - }); -}; -},{}],11:[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; - } - } - }); -}; - -},{}],12:[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), - // 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); - } - }); -}; - -},{}],13:[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; - } - } - }); -}; - -},{}],14:[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); - } - }); -}; -},{}],15:[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(); - } - } - }; -}; -},{}],16:[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