diff --git a/src/controllers/controller.bar.js b/src/controllers/controller.bar.js index 6f9724e8b..6b3962281 100644 --- a/src/controllers/controller.bar.js +++ b/src/controllers/controller.bar.js @@ -107,9 +107,7 @@ this.update(true); }, - update: function(reset) { - var numBars = this.getBarCount(); - + buildOrUpdateElements: function buildOrUpdateElements() { var numData = this.getDataset().data.length; var numRectangles = this.getDataset().metaData.length; @@ -123,6 +121,10 @@ this.addElementAndReset(index); } } + }, + + update: function update(reset) { + var numBars = this.getBarCount(); helpers.each(this.getDataset().metaData, function(rectangle, index) { this.updateElement(rectangle, index, reset, numBars); diff --git a/src/controllers/controller.doughnut.js b/src/controllers/controller.doughnut.js index d4586b4fc..da3386e31 100644 --- a/src/controllers/controller.doughnut.js +++ b/src/controllers/controller.doughnut.js @@ -84,20 +84,7 @@ this.update(true); }, - update: function(reset) { - - this.chart.outerRadius = Math.max((helpers.min([this.chart.chart.width, this.chart.chart.height]) / 2) - this.chart.options.elements.arc.borderWidth / 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.data.datasets.length; - - this.getDataset().total = 0; - helpers.each(this.getDataset().data, function(value) { - this.getDataset().total += Math.abs(value); - }, this); - - this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.index); - this.innerRadius = this.outerRadius - this.chart.radiusLength; - + buildOrUpdateElements: function buildOrUpdateElements() { // Make sure we have metaData for each data point var numData = this.getDataset().data.length; var numArcs = this.getDataset().metaData.length; @@ -112,6 +99,21 @@ this.addElementAndReset(index); } } + }, + + update: function update(reset) { + + this.chart.outerRadius = Math.max((helpers.min([this.chart.chart.width, this.chart.chart.height]) / 2) - this.chart.options.elements.arc.borderWidth / 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.data.datasets.length; + + this.getDataset().total = 0; + helpers.each(this.getDataset().data, function(value) { + this.getDataset().total += Math.abs(value); + }, this); + + this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.index); + this.innerRadius = this.outerRadius - this.chart.radiusLength; helpers.each(this.getDataset().metaData, function(arc, index) { this.updateElement(arc, index, reset); diff --git a/src/controllers/controller.line.js b/src/controllers/controller.line.js index 608b5d704..6014a9306 100644 --- a/src/controllers/controller.line.js +++ b/src/controllers/controller.line.js @@ -101,14 +101,7 @@ this.update(true); }, - update: function(reset) { - var line = this.getDataset().metaDataset; - var points = this.getDataset().metaData; - - var yScale = this.getScaleForId(this.getDataset().yAxisID); - var xScale = this.getScaleForId(this.getDataset().xAxisID); - var scaleBase; - + buildOrUpdateElements: function buildOrUpdateElements() { // Handle the number of data points changing var numData = this.getDataset().data.length; var numPoints = this.getDataset().metaData.length; @@ -123,6 +116,15 @@ this.addElementAndReset(index); } } + }, + + update: function update(reset) { + var line = this.getDataset().metaDataset; + var points = this.getDataset().metaData; + + var yScale = this.getScaleForId(this.getDataset().yAxisID); + var xScale = this.getScaleForId(this.getDataset().xAxisID); + var scaleBase; if (yScale.min < 0 && yScale.max < 0) { scaleBase = yScale.getPixelForValue(yScale.max); diff --git a/src/controllers/controller.polarArea.js b/src/controllers/controller.polarArea.js index d832f09d1..3776184ad 100644 --- a/src/controllers/controller.polarArea.js +++ b/src/controllers/controller.polarArea.js @@ -79,7 +79,24 @@ this.update(true); }, - update: function(reset) { + buildOrUpdateElements: function buildOrUpdateElements() { + // Handle the number of data points changing + var numData = this.getDataset().data.length; + var numPoints = this.getDataset().metaData.length; + + // Make sure that we handle number of datapoints changing + if (numData < numPoints) { + // Remove excess bars for data points that have been removed + this.getDataset().metaData.splice(numData, numPoints - numData) + } else if (numData > numPoints) { + // Add new elements + for (var index = numPoints; index < numData; ++index) { + this.addElementAndReset(index); + } + } + }, + + update: function update(reset) { Chart.scaleService.fitScalesForChart(this, this.chart.width, this.chart.height); //this.chart.scale.setScaleSize(); diff --git a/src/controllers/controller.radar.js b/src/controllers/controller.radar.js index ce597d720..85cf5a459 100644 --- a/src/controllers/controller.radar.js +++ b/src/controllers/controller.radar.js @@ -95,7 +95,24 @@ this.update(true); }, - update: function(reset) { + buildOrUpdateElements: function buildOrUpdateElements() { + // Handle the number of data points changing + var numData = this.getDataset().data.length; + var numPoints = this.getDataset().metaData.length; + + // Make sure that we handle number of datapoints changing + if (numData < numPoints) { + // Remove excess bars for data points that have been removed + this.getDataset().metaData.splice(numData, numPoints - numData) + } else if (numData > numPoints) { + // Add new elements + for (var index = numPoints; index < numData; ++index) { + this.addElementAndReset(index); + } + } + }, + + update: function update(reset) { var line = this.getDataset().metaDataset; var points = this.getDataset().metaData; diff --git a/src/core/core.controller.js b/src/core/core.controller.js index 614b0579d..3cf57687d 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -75,52 +75,6 @@ return this; }, - addDataset: function addDataset(dataset, index) { - if (index !== undefined) { - this.data.datasets.splice(index, 0, dataset); - } else { - this.data.datasets.push(dataset); - } - - this.buildOrUpdateControllers(); - dataset.controller.reset(); // so that animation looks ok - this.update(); - }, - removeDataset: function removeDataset(index) { - this.data.datasets.splice(index, 1); - this.buildOrUpdateControllers(); - this.update(); - }, - - // Add data to the given dataset - // @param data: the data to add - // @param {Number} datasetIndex : the index of the dataset to add to - // @param {Number} index : the index of the data - addData: function addData(data, datasetIndex, index) { - if (datasetIndex < this.data.datasets.length) { - if (index === undefined) { - index = this.data.datasets[datasetIndex].data.length; - } - - var addElementArgs = [index]; - for (var i = 3; i < arguments.length; ++i) { - addElementArgs.push(arguments[i]); - } - - this.data.datasets[datasetIndex].data.splice(index, 0, data); - this.data.datasets[datasetIndex].controller.addElementAndReset.apply(this.data.datasets[datasetIndex].controller, addElementArgs); - this.update(); - } - }, - - removeData: function removeData(datasetIndex, index) { - if (datasetIndex < this.data.datasets.length) { - this.data.datasets[datasetIndex].data.splice(index, 1); - this.data.datasets[datasetIndex].controller.removeElement(index); - this.update(); - } - }, - resize: function resize(silent) { this.stop(); var canvas = this.chart.canvas; @@ -210,7 +164,7 @@ Chart.scaleService.fitScalesForChart(this, this.chart.width, this.chart.height); }, - buildOrUpdateControllers: function() { + buildOrUpdateControllers: function buildOrUpdateControllers(resetNewControllers) { helpers.each(this.data.datasets, function(dataset, datasetIndex) { var type = dataset.type || this.config.type; if (dataset.controller) { @@ -218,6 +172,10 @@ return; } dataset.controller = new Chart.controllers[type](this, datasetIndex); + + if (resetNewControllers) { + dataset.controller.reset(); + } }, this); }, @@ -227,10 +185,18 @@ }, this); }, - update: function update(animationDuration, lazy) { - // This will loop through any data and do the appropriate element update for the type Chart.scaleService.fitScalesForChart(this, this.chart.width, this.chart.height); + + // Make sure dataset controllers are updated and new controllers are reset + this.buildOrUpdateControllers(true); + + // Make sure all dataset controllers have correct meta data counts + helpers.each(this.data.datasets, function(dataset, datasetIndex) { + dataset.controller.buildOrUpdateElements(); + }, this); + + // This will loop through any data and do the appropriate element update for the type helpers.each(this.data.datasets, function(dataset, datasetIndex) { dataset.controller.update(); }, this); @@ -288,10 +254,6 @@ this.tooltip.transition(easingDecimal).draw(); }, - - - - // 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) { @@ -333,9 +295,9 @@ for (var datasetIndex = 0; datasetIndex < this.data.datasets.length; datasetIndex++) { for (var elementIndex = 0; elementIndex < this.data.datasets[datasetIndex].metaData.length; elementIndex++) { if (this.data.datasets[datasetIndex].metaData[elementIndex].inLabelRange(eventPosition.x, eventPosition.y)) { - helpers.each(this.data.datasets[datasetIndex].metaData, function(element, index) { - elementsArray.push(element); - }, this); + helpers.each(this.data.datasets[datasetIndex].metaData, function(element, index) { + elementsArray.push(element); + }, this); } } } diff --git a/test/controller.bar.tests.js b/test/controller.bar.tests.js index df27506a1..c20dd7cf8 100644 --- a/test/controller.bar.tests.js +++ b/test/controller.bar.tests.js @@ -194,6 +194,7 @@ describe('Bar controller tests', function() { var controller = new Chart.controllers.bar(chart, 1); chart.data.datasets[1].data = [1, 2]; // remove 2 items + controller.buildOrUpdateElements(); controller.update(); expect(chart.data.datasets[1].metaData.length).toBe(2); @@ -236,6 +237,7 @@ describe('Bar controller tests', function() { }); chart.data.datasets[1].data = [1, 2, 3]; + controller.buildOrUpdateElements(); controller.update(); expect(chart.data.datasets[1].metaData.length).toBe(3); // should add a new meta data item diff --git a/test/controller.doughnut.tests.js b/test/controller.doughnut.tests.js index cef606263..d4ff2ff51 100644 --- a/test/controller.doughnut.tests.js +++ b/test/controller.doughnut.tests.js @@ -205,6 +205,7 @@ describe('Doughnut controller tests', function() { // Change the amount of data and ensure that arcs are updated accordingly chart.data.datasets[0].data = [1, 2]; // remove 2 elements from dataset 0 + controller.buildOrUpdateElements(); controller.update(); expect(chart.data.datasets[0].metaData.length).toBe(2); @@ -213,6 +214,7 @@ describe('Doughnut controller tests', function() { // Add data chart.data.datasets[0].data = [1, 2, 3, 4]; + controller.buildOrUpdateElements(); controller.update(); expect(chart.data.datasets[0].metaData.length).toBe(4);