diff --git a/src/charts/chart.bar.js b/src/charts/chart.bar.js index 1cba8b9b5..4d9990b11 100644 --- a/src/charts/chart.bar.js +++ b/src/charts/chart.bar.js @@ -33,24 +33,16 @@ name: "Bar", defaults: defaultConfig, initialize: function() { - - var _this = this; - - // Events - helpers.bindEvents(this, this.options.events, this.events); + this.elementController = new Chart.RectangularElementController(this); + this.canvasController = new Chart.RectangularCanvasController(this, this.elementController); //Create a new bar for each piece of data helpers.each(this.data.datasets, function(dataset, datasetIndex) { - dataset.metaData = []; helpers.each(dataset.data, function(dataPoint, index) { - dataset.metaData.push(new Chart.Rectangle({ - _chart: this.chart, - _datasetIndex: datasetIndex, - _index: index, - })); + this.elementController.addRectangle(dataset, datasetIndex, index); }, this); - // The bar chart only supports a single x axis because the x axis is always a dataset axis + // The bar chart only supports a single x axis because the x axis is always a category axis dataset.xAxisID = this.options.scales.xAxes[0].id; if (!dataset.yAxisID) { @@ -58,138 +50,7 @@ } }, this); - // Build and fit the scale. Needs to happen after the axis IDs have been set - this.buildScale(); - - // Create tooltip instance exclusively for this chart with some defaults. - this.tooltip = new Chart.Tooltip({ - _chart: this.chart, - _data: this.data, - _options: this.options, - }, this); - - // Need to fit scales before we reset elements. - Chart.scaleService.fitScalesForChart(this, this.chart.width, this.chart.height); - - // So that we animate from the baseline - this.resetElements(); - - // Update the chart with the latest data. - this.update(); - }, - resetElements: function() { - // Update the points - this.eachElement(function(bar, index, dataset, datasetIndex) { - var xScale = this.scales[this.data.datasets[datasetIndex].xAxisID]; - var yScale = this.scales[this.data.datasets[datasetIndex].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(bar, { - // Utility - _chart: this.chart, - _xScale: xScale, - _yScale: yScale, - _datasetIndex: datasetIndex, - _index: index, - - // Desired view properties - _model: { - x: xScale.calculateBarX(this.data.datasets.length, datasetIndex, index), - y: yScalePoint, - - // Appearance - base: yScale.calculateBarBase(datasetIndex, index), - width: xScale.calculateBarWidth(this.data.datasets.length), - backgroundColor: bar.custom && bar.custom.backgroundColor ? bar.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.data.datasets[datasetIndex].backgroundColor, index, this.options.elements.rectangle.backgroundColor), - borderColor: bar.custom && bar.custom.borderColor ? bar.custom.borderColor : helpers.getValueAtIndexOrDefault(this.data.datasets[datasetIndex].borderColor, index, this.options.elements.rectangle.borderColor), - borderWidth: bar.custom && bar.custom.borderWidth ? bar.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.data.datasets[datasetIndex].borderWidth, index, this.options.elements.rectangle.borderWidth), - - // Tooltip - label: this.data.labels[index], - datasetLabel: this.data.datasets[datasetIndex].label, - }, - }); - bar.pivot(); - }, this); - }, - update: function(animationDuration) { - // Update the scale sizes - Chart.scaleService.fitScalesForChart(this, this.chart.width, this.chart.height); - - // Update the points - this.eachElement(function(bar, index, dataset, datasetIndex) { - var xScale = this.scales[this.data.datasets[datasetIndex].xAxisID]; - var yScale = this.scales[this.data.datasets[datasetIndex].yAxisID]; - - helpers.extend(bar, { - // Utility - _chart: this.chart, - _xScale: xScale, - _yScale: yScale, - _datasetIndex: datasetIndex, - _index: index, - - // Desired view properties - _model: { - x: xScale.calculateBarX(this.data.datasets.length, datasetIndex, index), - y: yScale.calculateBarY(datasetIndex, index), - - // Appearance - base: yScale.calculateBarBase(datasetIndex, index), - width: xScale.calculateBarWidth(this.data.datasets.length), - backgroundColor: bar.custom && bar.custom.backgroundColor ? bar.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.data.datasets[datasetIndex].backgroundColor, index, this.options.elements.rectangle.backgroundColor), - borderColor: bar.custom && bar.custom.borderColor ? bar.custom.borderColor : helpers.getValueAtIndexOrDefault(this.data.datasets[datasetIndex].borderColor, index, this.options.elements.rectangle.borderColor), - borderWidth: bar.custom && bar.custom.borderWidth ? bar.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.data.datasets[datasetIndex].borderWidth, index, this.options.elements.rectangle.borderWidth), - - // Tooltip - label: this.data.labels[index], - datasetLabel: this.data.datasets[datasetIndex].label, - }, - }); - bar.pivot(); - }, this); - - - this.render(animationDuration); - }, - buildScale: function(labels) { - var self = this; - - // Map of scale ID to scale object so we can lookup later - this.scales = {}; - - // Build the x axis. The line chart only supports a single x axis - var ScaleClass = Chart.scaleService.getScaleConstructor(this.options.scales.xAxes[0].type); - var xScale = new ScaleClass({ - ctx: this.chart.ctx, - options: this.options.scales.xAxes[0], - id: this.options.scales.xAxes[0].id, - data: this.data, - }); - this.scales[xScale.id] = xScale; - - // Build up all the y scales - helpers.each(this.options.scales.yAxes, function(yAxisOptions) { - var ScaleClass = Chart.scaleService.getScaleConstructor(yAxisOptions.type); - var scale = new ScaleClass({ - ctx: this.chart.ctx, - options: yAxisOptions, - data: this.data, - id: yAxisOptions.id, - }); - - this.scales[scale.id] = scale; - }, this); + this.canvasController.initialize(); }, draw: function(ease) { @@ -209,148 +70,6 @@ // Finally draw the tooltip this.tooltip.transition(easingDecimal).draw(); }, - events: function(e) { - - - - this.lastActive = this.lastActive || []; - - // Find Active Elements - if (e.type == 'mouseout') { - this.active = []; - } else { - this.active = function() { - switch (this.options.hover.mode) { - case 'single': - return this.getElementAtEvent(e); - case 'label': - return this.getElementsAtEvent(e); - case 'dataset': - return this.getDatasetAtEvent(e); - default: - return e; - } - }.call(this); - } - - // On Hover hook - if (this.options.hover.onHover) { - this.options.hover.onHover.call(this, this.active); - } - - if (e.type == 'mouseup' || e.type == 'click') { - if (this.options.onClick) { - this.options.onClick.call(this, e, this.active); - } - } - - var dataset; - var index; - // Remove styling for last active (even if it may still be active) - if (this.lastActive.length) { - switch (this.options.hover.mode) { - case 'single': - dataset = this.data.datasets[this.lastActive[0]._datasetIndex]; - index = this.lastActive[0]._index; - - this.lastActive[0]._model.backgroundColor = this.lastActive[0].custom && this.lastActive[0].custom.backgroundColor ? this.lastActive[0].custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.rectangle.backgroundColor); - this.lastActive[0]._model.borderColor = this.lastActive[0].custom && this.lastActive[0].custom.borderColor ? this.lastActive[0].custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.rectangle.borderColor); - this.lastActive[0]._model.borderWidth = this.lastActive[0].custom && this.lastActive[0].custom.borderWidth ? this.lastActive[0].custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.rectangle.borderWidth); - break; - case 'label': - for (var i = 0; i < this.lastActive.length; i++) { - dataset = this.data.datasets[this.lastActive[i]._datasetIndex]; - index = this.lastActive[i]._index; - - this.lastActive[i]._model.backgroundColor = this.lastActive[i].custom && this.lastActive[i].custom.backgroundColor ? this.lastActive[i].custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.rectangle.backgroundColor); - this.lastActive[i]._model.borderColor = this.lastActive[i].custom && this.lastActive[i].custom.borderColor ? this.lastActive[i].custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.rectangle.borderColor); - this.lastActive[i]._model.borderWidth = this.lastActive[i].custom && this.lastActive[i].custom.borderWidth ? this.lastActive[i].custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.rectangle.borderWidth); - } - break; - case 'dataset': - break; - default: - // Don't change anything - } - } - - // Built in hover styling - if (this.active.length && this.options.hover.mode) { - switch (this.options.hover.mode) { - case 'single': - dataset = this.data.datasets[this.active[0]._datasetIndex]; - index = this.active[0]._index; - - this.active[0]._model.backgroundColor = this.active[0].custom && this.active[0].custom.hoverBackgroundColor ? this.active[0].custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(this.active[0]._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - this.active[0]._model.borderColor = this.active[0].custom && this.active[0].custom.hoverBorderColor ? this.active[0].custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(this.active[0]._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - this.active[0]._model.borderWidth = this.active[0].custom && this.active[0].custom.hoverBorderWidth ? this.active[0].custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.active[0]._model.borderWidth); - break; - case 'label': - for (var i = 0; i < this.active.length; i++) { - dataset = this.data.datasets[this.active[i]._datasetIndex]; - index = this.active[i]._index; - - this.active[i]._model.backgroundColor = this.active[i].custom && this.active[i].custom.hoverBackgroundColor ? this.active[i].custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(this.active[i]._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - this.active[i]._model.borderColor = this.active[i].custom && this.active[i].custom.hoverBorderColor ? this.active[i].custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(this.active[i]._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - this.active[i]._model.borderWidth = this.active[i].custom && this.active[i].custom.hoverBorderWidth ? this.active[i].custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.active[i]._model.borderWidth); - } - break; - case 'dataset': - break; - default: - // Don't change anything - } - } - - - // Built in Tooltips - if (this.options.tooltips.enabled) { - - // The usual updates - this.tooltip.initialize(); - - // Active - if (this.active.length) { - this.tooltip._model.opacity = 1; - - helpers.extend(this.tooltip, { - _active: this.active, - }); - - this.tooltip.update(); - } else { - // Inactive - this.tooltip._model.opacity = 0; - } - } - - - this.tooltip.pivot(); - - // Hover animations - if (!this.animating) { - var changed; - - helpers.each(this.active, function(element, index) { - if (element !== this.lastActive[index]) { - changed = true; - } - }, this); - - // If entering, leaving, or changing elements, animate the change via pivot - if ((!this.lastActive.length && this.active.length) || - (this.lastActive.length && !this.active.length) || - (this.lastActive.length && this.active.length && changed)) { - - this.stop(); - this.render(this.options.hoverAnimationDuration); - } - } - - // Remember Last Active - this.lastActive = this.active; - return this; - }, }); diff --git a/src/controllers/controller.canvas.rectangular.js b/src/controllers/controller.canvas.rectangular.js index 22caa778c..a4a75cef0 100644 --- a/src/controllers/controller.canvas.rectangular.js +++ b/src/controllers/controller.canvas.rectangular.js @@ -68,11 +68,11 @@ if (this.lastActive.length) { switch (this.chartInstance.options.hover.mode) { case 'single': - this.elementController.updatePointElementAppearance(this.lastActive[0], this.lastActive[0]._datasetIndex, this.lastActive[0]._index); + this.elementController.resetElementAppearance(this.lastActive[0], this.lastActive[0]._datasetIndex, this.lastActive[0]._index); break; case 'label': for (var i = 0; i < this.lastActive.length; i++) { - this.elementController.updatePointElementAppearance(this.lastActive[i], this.lastActive[i]._datasetIndex, this.lastActive[i]._index); + this.elementController.resetElementAppearance(this.lastActive[i], this.lastActive[i]._datasetIndex, this.lastActive[i]._index); } break; case 'dataset': @@ -86,11 +86,11 @@ if (this.active.length && this.chartInstance.options.hover.mode) { switch (this.chartInstance.options.hover.mode) { case 'single': - this.elementController.setPointHoverStyle(this.active[0]); + this.elementController.setElementHoverStyle(this.active[0]); break; case 'label': for (var i = 0; i < this.active.length; i++) { - this.elementController.setPointHoverStyle(this.active[i]); + this.elementController.setElementHoverStyle(this.active[i]); } break; case 'dataset': diff --git a/src/controllers/controller.elements.rectangular.js b/src/controllers/controller.elements.rectangular.js index a23949b9d..469aa0188 100644 --- a/src/controllers/controller.elements.rectangular.js +++ b/src/controllers/controller.elements.rectangular.js @@ -23,13 +23,19 @@ Chart.RectangularElementController.prototype.eachLine = function eachLine(callback) { helpers.each(this.chartInstance.data.datasets, function(dataset, datasetIndex) { - callback.call(this, dataset, datasetIndex) + if (dataset.metaDataset && dataset.metaDataset instanceof Chart.Line) { + callback.call(this, dataset, datasetIndex) + } }, this); }; - Chart.RectangularElementController.prototype.eachPoint = function eachPoint(callback) { + Chart.RectangularElementController.prototype.eachRectangle = function(callback) { helpers.each(this.chartInstance.data.datasets, function(dataset, datasetIndex) { - helpers.each(dataset.metaData, callback, this, dataset.metaData, datasetIndex); + helpers.each(dataset.metaData, function(element, index) { + if (element instanceof Chart.Rectangle) { + callback(element, index, dataset, datasetIndex); + } + }, this); }, this); }; @@ -61,13 +67,35 @@ } }; + Chart.RectangularElementController.prototype.addRectangle = function(dataset, datasetIndex, index) { + if (dataset) { + dataset.metaData = dataset.metaData || new Array(this.chartInstance.data.datasets[datasetIndex].data.length); + + if (index < dataset.metaData.length) { + dataset.metaData[index] = new Chart.Rectangle({ + _chart: this.chartInstance.chart, + _datasetIndex: datasetIndex, + _index: index, + }); + } + } + }; + Chart.RectangularElementController.prototype.resetElements = function resetElements() { - // Update the points - this.resetPoints(); + helpers.each(this.chartInstance.data.datasets, function(dataset, datasetIndex) { + // All elements must be the same type for the given dataset so we are fine to check just the first one + if (dataset.metaData[0] instanceof Chart.Point) { + // Have points. Update all of them + this.resetDatasetPoints(dataset, datasetIndex); + } else if (dataset.metaData[0] instanceof Chart.Rectangle) { + // Have rectangles (bars) + this.resetDatasetRectangles(dataset, datasetIndex); + } + }, this); }; - Chart.RectangularElementController.prototype.resetPoints = function() { - this.eachPoint(function(point, index, dataset, datasetIndex) { + Chart.RectangularElementController.prototype.resetDatasetPoints = function resetDatasetPoints(dataset, datasetIndex) { + helpers.each(dataset.metaData, function(point, index){ var xScale = this.getScaleForId(this.chartInstance.data.datasets[datasetIndex].xAxisID); var yScale = this.getScaleForId(this.chartInstance.data.datasets[datasetIndex].yAxisID); @@ -100,15 +128,75 @@ this.updatePointElementAppearance(point, datasetIndex, index); }, this); - this.updateBezierControlPoints(); + this.updateBezierControlPoints(dataset); + }; + + Chart.RectangularElementController.prototype.resetDatasetRectangles = function resetDatasetRectangles(dataset, datasetIndex) { + helpers.each(dataset.metaData, function(rectangle, index) { + var xScale = this.getScaleForId(this.chartInstance.data.datasets[datasetIndex].xAxisID); + var yScale = this.getScaleForId(this.chartInstance.data.datasets[datasetIndex].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.chartInstance.chart, + _xScale: xScale, + _yScale: yScale, + _datasetIndex: datasetIndex, + _index: index, + + // Desired view properties + _model: { + x: xScale.calculateBarX(this.chartInstance.data.datasets.length, datasetIndex, index), + y: yScalePoint, + + // Tooltip + label: this.chartInstance.data.labels[index], + datasetLabel: this.chartInstance.data.datasets[datasetIndex].label, + + // Appearance + base: yScale.calculateBarBase(datasetIndex, index), + width: xScale.calculateBarWidth(this.chartInstance.data.datasets.length), + }, + }); + + this.updateRectangleElementAppearance(rectangle, datasetIndex, index); + rectangle.pivot(); + }, this); + }; + + Chart.RectangularElementController.prototype.resetElementAppearance = function(element, datasetIndex, index) { + if (element instanceof Chart.Point) { + this.updatePointElementAppearance(element, datasetIndex, index); + } else if (element instanceof Chart.Rectangle) { + this.updateRectangleElementAppearance(element, datasetIndex, index); + } }; Chart.RectangularElementController.prototype.updateElements = function updateElements() { // Update the lines this.updateLines(); - // Update the points - this.updatePoints(); + helpers.each(this.chartInstance.data.datasets, function(dataset, datasetIndex) { + // All elements must be the same type for the given dataset so we are fine to check just the first one + if (dataset.metaData[0] instanceof Chart.Point) { + // Have points. Update all of them + this.updatePoints(dataset, datasetIndex); + } else if (dataset.metaData[0] instanceof Chart.Rectangle) { + // Have rectangles (bars) + this.updateRectangles(dataset, datasetIndex); + } + }, this); }; Chart.RectangularElementController.prototype.updateLines = function updateLines() { @@ -151,8 +239,8 @@ }); }; - Chart.RectangularElementController.prototype.updatePoints = function() { - this.eachPoint(function(point, index, dataset, datasetIndex) { + Chart.RectangularElementController.prototype.updatePoints = function updatePoints(dataset, datasetIndex) { + helpers.each(dataset.metaData, function(point, index) { var xScale = this.getScaleForId(this.chartInstance.data.datasets[datasetIndex].xAxisID); var yScale = this.getScaleForId(this.chartInstance.data.datasets[datasetIndex].yAxisID); @@ -174,10 +262,10 @@ this.updatePointElementAppearance(point, datasetIndex, index); }, this); - this.updateBezierControlPoints(); + this.updateBezierControlPoints(dataset); }; - Chart.RectangularElementController.prototype.updatePointElementAppearance = function(point, datasetIndex, index) { + Chart.RectangularElementController.prototype.updatePointElementAppearance = function updatePointElementAppearance(point, datasetIndex, index) { helpers.extend(point._model, { // Appearance tension: point.custom && point.custom.tension ? point.custom.tension : this.chartInstance.options.elements.line.tension, @@ -192,7 +280,57 @@ }); }; - Chart.RectangularElementController.prototype.setPointHoverStyle = function(point) { + Chart.RectangularElementController.prototype.updateRectangles = function updateRectangles(dataset, datasetIndex) { + helpers.each(dataset.metaData, function(rectangle, index){ + var xScale = this.getScaleForId(this.chartInstance.data.datasets[datasetIndex].xAxisID); + var yScale = this.getScaleForId(this.chartInstance.data.datasets[datasetIndex].yAxisID); + + helpers.extend(rectangle, { + // Utility + _chart: this.chartInstance.chart, + _xScale: xScale, + _yScale: yScale, + _datasetIndex: datasetIndex, + _index: index, + + // Desired view properties + _model: { + x: xScale.calculateBarX(this.chartInstance.data.datasets.length, datasetIndex, index), + y: yScale.calculateBarY(datasetIndex, index), + + // Appearance + base: yScale.calculateBarBase(datasetIndex, index), + width: xScale.calculateBarWidth(this.chartInstance.data.datasets.length), + + // Tooltip + label: this.chartInstance.data.labels[index], + datasetLabel: this.chartInstance.data.datasets[datasetIndex].label, + }, + }); + + this.updateRectangleElementAppearance(rectangle, datasetIndex, index); + rectangle.pivot(); + }, this); + }; + + Chart.RectangularElementController.prototype.updateRectangleElementAppearance = function updateRectangleElementAppearance(rectangle, datasetIndex, index) { + helpers.extend(rectangle._model, { + // Appearance + backgroundColor: rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.chartInstance.data.datasets[datasetIndex].backgroundColor, index, this.chartInstance.options.elements.rectangle.backgroundColor), + borderColor: rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.chartInstance.data.datasets[datasetIndex].borderColor, index, this.chartInstance.options.elements.rectangle.borderColor), + borderWidth: rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.chartInstance.data.datasets[datasetIndex].borderWidth, index, this.chartInstance.options.elements.rectangle.borderWidth), + }); + }; + + Chart.RectangularElementController.prototype.setElementHoverStyle = function setElementHoverStyle(element) { + if (element instanceof Chart.Point) { + this.setPointHoverStyle(element); + } else if (element instanceof Chart.Rectangle) { + this.setRectangleHoverStyle(element); + } + }; + + Chart.RectangularElementController.prototype.setPointHoverStyle = function setPointHoverStyle(point) { var dataset = this.chartInstance.data.datasets[point._datasetIndex]; var index = point._index; @@ -202,13 +340,22 @@ point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, point._model.borderWidth); }; - Chart.RectangularElementController.prototype.updateBezierControlPoints = function updateBezierControlPoints() { + Chart.RectangularElementController.prototype.setRectangleHoverStyle = function(rectangle) { + var dataset = this.chartInstance.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.borderWidth, index, rectangle._model.borderWidth); + }; + + Chart.RectangularElementController.prototype.updateBezierControlPoints = function updateBezierControlPoints(dataset) { // Update control points for the bezier curve - this.eachPoint(function(point, index, dataset, datasetIndex) { + helpers.each(dataset.metaData, function(point, index) { var controlPoints = helpers.splineCurve( - this.previousPoint(dataset, index)._model, + this.previousPoint(dataset.metaData, index)._model, point._model, - this.nextPoint(dataset, index)._model, + this.nextPoint(dataset.metaData, index)._model, point._model.tension );