From: Evert Timberg Date: Sun, 13 Dec 2015 19:35:40 +0000 (-0500) Subject: All dataset controllers now inherit from a common base class Chart.DatasetController... X-Git-Tag: 2.0.0-beta2~21^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=139cbe1c642390aa40a7a39391b9df9aace6b84f;p=thirdparty%2FChart.js.git All dataset controllers now inherit from a common base class Chart.DatasetController. This makes writing external controllers much easier --- diff --git a/src/controllers/controller.bar.js b/src/controllers/controller.bar.js index a97e284e0..c1c667d33 100644 --- a/src/controllers/controller.bar.js +++ b/src/controllers/controller.bar.js @@ -30,39 +30,7 @@ }, }; - Chart.controllers.bar = function(chart, datasetIndex) { - this.initialize.call(this, chart, datasetIndex); - }; - - helpers.extend(Chart.controllers.bar.prototype, { - - initialize: function(chart, datasetIndex) { - this.chart = chart; - this.index = datasetIndex; - this.linkScales(); - this.addElements(); - }, - updateIndex: function(datasetIndex) { - this.index = datasetIndex; - }, - linkScales: function() { - if (!this.getDataset().xAxisID) { - this.getDataset().xAxisID = this.chart.options.scales.xAxes[0].id; - } - - if (!this.getDataset().yAxisID) { - this.getDataset().yAxisID = this.chart.options.scales.yAxes[0].id; - } - }, - - getDataset: function() { - return this.chart.data.datasets[this.index]; - }, - - getScaleForID: function(scaleID) { - return this.chart.scales[scaleID]; - }, - + Chart.controllers.bar = Chart.DatasetController.extend({ // Get the number of datasets that display bars. We use this to correctly calculate the bar width getBarCount: function getBarCount() { var barCount = 0; @@ -102,30 +70,6 @@ this.getDataset().metaData.splice(index, 0, rectangle); }, - removeElement: function(index) { - this.getDataset().metaData.splice(index, 1); - }, - - reset: function() { - this.update(true); - }, - - buildOrUpdateElements: function buildOrUpdateElements() { - var numData = this.getDataset().data.length; - var numRectangles = this.getDataset().metaData.length; - - // Make sure that we handle number of datapoints changing - if (numData < numRectangles) { - // Remove excess bars for data points that have been removed - this.getDataset().metaData.splice(numData, numRectangles - numData); - } else if (numData > numRectangles) { - // Add new elements - for (var index = numRectangles; index < numData; ++index) { - this.addElementAndReset(index); - } - } - }, - update: function update(reset) { var numBars = this.getBarCount(); @@ -136,8 +80,8 @@ updateElement: function updateElement(rectangle, index, reset, numBars) { - var xScale = this.getScaleForID(this.getDataset().xAxisID); - var yScale = this.getScaleForID(this.getDataset().yAxisID); + var xScale = this.getScaleForId(this.getDataset().xAxisID); + var yScale = this.getScaleForId(this.getDataset().yAxisID); var yScalePoint; @@ -181,8 +125,8 @@ calculateBarBase: function(datasetIndex, index) { - var xScale = this.getScaleForID(this.getDataset().xAxisID); - var yScale = this.getScaleForID(this.getDataset().yAxisID); + var xScale = this.getScaleForId(this.getDataset().xAxisID); + var yScale = this.getScaleForId(this.getDataset().yAxisID); var base = 0; @@ -225,11 +169,8 @@ getRuler: function() { - var xScale = this.getScaleForID(this.getDataset().xAxisID); - var yScale = this.getScaleForID(this.getDataset().yAxisID); - /*var datasetCount = !this.chart.isCombo ? this.chart.data.datasets.length : helpers.where(this.chart.data.datasets, function(ds) { - return ds.type == 'bar'; - }).length;*/ + var xScale = this.getScaleForId(this.getDataset().xAxisID); + var yScale = this.getScaleForId(this.getDataset().yAxisID); var datasetCount = this.getBarCount(); var tickWidth = (function() { @@ -258,7 +199,7 @@ calculateBarWidth: function() { - var xScale = this.getScaleForID(this.getDataset().xAxisID); + var xScale = this.getScaleForId(this.getDataset().xAxisID); var ruler = this.getRuler(); if (xScale.options.stacked) { @@ -285,8 +226,8 @@ calculateBarX: function(index, datasetIndex) { - var yScale = this.getScaleForID(this.getDataset().yAxisID); - var xScale = this.getScaleForID(this.getDataset().xAxisID); + var yScale = this.getScaleForId(this.getDataset().yAxisID); + var xScale = this.getScaleForId(this.getDataset().xAxisID); var barIndex = this.getBarIndex(datasetIndex); var ruler = this.getRuler(); @@ -307,8 +248,8 @@ calculateBarY: function(index, datasetIndex) { - var xScale = this.getScaleForID(this.getDataset().xAxisID); - var yScale = this.getScaleForID(this.getDataset().yAxisID); + var xScale = this.getScaleForId(this.getDataset().xAxisID); + var yScale = this.getScaleForId(this.getDataset().yAxisID); var value = this.getDataset().data[index]; diff --git a/src/controllers/controller.bubble.js b/src/controllers/controller.bubble.js index d0d653870..bce235c2a 100644 --- a/src/controllers/controller.bubble.js +++ b/src/controllers/controller.bubble.js @@ -31,40 +31,7 @@ }; - Chart.controllers.bubble = function(chart, datasetIndex) { - this.initialize.call(this, chart, datasetIndex); - }; - - helpers.extend(Chart.controllers.bubble.prototype, { - - initialize: function(chart, datasetIndex) { - this.chart = chart; - this.index = datasetIndex; - this.linkScales(); - this.addElements(); - }, - updateIndex: function(datasetIndex) { - this.index = datasetIndex; - }, - - linkScales: function() { - if (!this.getDataset().xAxisID) { - this.getDataset().xAxisID = this.chart.options.scales.xAxes[0].id; - } - - if (!this.getDataset().yAxisID) { - this.getDataset().yAxisID = this.chart.options.scales.yAxes[0].id; - } - }, - - getDataset: function() { - return this.chart.data.datasets[this.index]; - }, - - getScaleForId: function(scaleID) { - return this.chart.scales[scaleID]; - }, - + Chart.controllers.bubble = Chart.DatasetController.extend({ addElements: function() { this.getDataset().metaData = this.getDataset().metaData || []; @@ -90,31 +57,6 @@ // Add to the points array this.getDataset().metaData.splice(index, 0, point); - - }, - removeElement: function(index) { - this.getDataset().metaData.splice(index, 1); - }, - - reset: function() { - this.update(true); - }, - - 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) { diff --git a/src/controllers/controller.doughnut.js b/src/controllers/controller.doughnut.js index 2c37b9b90..a38c904d7 100644 --- a/src/controllers/controller.doughnut.js +++ b/src/controllers/controller.doughnut.js @@ -86,29 +86,11 @@ }); - Chart.controllers.doughnut = Chart.controllers.pie = function(chart, datasetIndex) { - this.initialize.call(this, chart, datasetIndex); - }; - - helpers.extend(Chart.controllers.doughnut.prototype, { - - initialize: function(chart, datasetIndex) { - this.chart = chart; - this.index = datasetIndex; - this.linkScales(); - this.addElements(); - }, - updateIndex: function(datasetIndex) { - this.index = datasetIndex; - }, + Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({ linkScales: function() { // no scales for doughnut }, - getDataset: function() { - return this.chart.data.datasets[this.index]; - }, - addElements: function() { this.getDataset().metaData = this.getDataset().metaData || []; helpers.each(this.getDataset().data, function(value, index) { @@ -137,29 +119,6 @@ // Add to the points array this.getDataset().metaData.splice(index, 0, arc); }, - removeElement: function(index) { - this.getDataset().metaData.splice(index, 1); - }, - reset: function() { - this.update(true); - }, - - buildOrUpdateElements: function buildOrUpdateElements() { - // Make sure we have metaData for each data point - var numData = this.getDataset().data.length; - var numArcs = this.getDataset().metaData.length; - - // Make sure that we handle number of datapoints changing - if (numData < numArcs) { - // Remove excess bars for data points that have been removed - this.getDataset().metaData.splice(numData, numArcs - numData); - } else if (numData > numArcs) { - // Add new elements - for (var index = numArcs; index < numData; ++index) { - this.addElementAndReset(index); - } - } - }, getVisibleDatasetCount: function getVisibleDatasetCount() { return helpers.where(this.chart.data.datasets, function(ds) { return helpers.isDatasetVisible(ds); }).length; diff --git a/src/controllers/controller.line.js b/src/controllers/controller.line.js index 8d0ad0eb1..4776f7f73 100644 --- a/src/controllers/controller.line.js +++ b/src/controllers/controller.line.js @@ -24,40 +24,7 @@ }; - Chart.controllers.line = function(chart, datasetIndex) { - this.initialize.call(this, chart, datasetIndex); - }; - - helpers.extend(Chart.controllers.line.prototype, { - - initialize: function(chart, datasetIndex) { - this.chart = chart; - this.index = datasetIndex; - this.linkScales(); - this.addElements(); - }, - updateIndex: function(datasetIndex) { - this.index = datasetIndex; - }, - - linkScales: function() { - if (!this.getDataset().xAxisID) { - this.getDataset().xAxisID = this.chart.options.scales.xAxes[0].id; - } - - if (!this.getDataset().yAxisID) { - this.getDataset().yAxisID = this.chart.options.scales.yAxes[0].id; - } - }, - - getDataset: function() { - return this.chart.data.datasets[this.index]; - }, - - getScaleForId: function(scaleID) { - return this.chart.scales[scaleID]; - }, - + Chart.controllers.line = Chart.DatasetController.extend({ addElements: function() { this.getDataset().metaData = this.getDataset().metaData || []; @@ -93,30 +60,6 @@ // Make sure bezier control points are updated this.updateBezierControlPoints(); }, - removeElement: function(index) { - this.getDataset().metaData.splice(index, 1); - }, - - reset: function() { - this.update(true); - }, - - 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; diff --git a/src/controllers/controller.polarArea.js b/src/controllers/controller.polarArea.js index 8b5ceef41..7dbd3ea28 100644 --- a/src/controllers/controller.polarArea.js +++ b/src/controllers/controller.polarArea.js @@ -79,34 +79,10 @@ } }; - Chart.controllers.polarArea = function(chart, datasetIndex) { - this.initialize.call(this, chart, datasetIndex); - }; - - helpers.extend(Chart.controllers.polarArea.prototype, { - - initialize: function(chart, datasetIndex) { - this.chart = chart; - this.index = datasetIndex; - this.linkScales(); - this.addElements(); - }, - updateIndex: function(datasetIndex) { - this.index = datasetIndex; - }, - + Chart.controllers.polarArea = Chart.DatasetController.extend({ linkScales: function() { // no scales for doughnut }, - - getDataset: function() { - return this.chart.data.datasets[this.index]; - }, - - getScaleForId: function(scaleID) { - return this.chart.scales[scaleID]; - }, - addElements: function() { this.getDataset().metaData = this.getDataset().metaData || []; helpers.each(this.getDataset().data, function(value, index) { @@ -131,31 +107,6 @@ // Add to the points array this.getDataset().metaData.splice(index, 0, arc); }, - removeElement: function(index) { - this.getDataset().metaData.splice(index, 1); - }, - - reset: function() { - this.update(true); - }, - - 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); - } - } - }, - getVisibleDatasetCount: function getVisibleDatasetCount() { return helpers.where(this.chart.data.datasets, function(ds) { return helpers.isDatasetVisible(ds); }).length; }, @@ -276,14 +227,6 @@ return (2 * Math.PI) / (this.getDataset().data.length - numNaN); } - }, - updateScaleRange: function() { - helpers.extend(this.chart.scale, { - size: helpers.min([this.chart.width, this.chart.height]), - xCenter: this.chart.width / 2, - yCenter: this.chart.height / 2 - }); - }, - + } }); }).call(this); diff --git a/src/controllers/controller.radar.js b/src/controllers/controller.radar.js index 9bec21e2b..6d808c67a 100644 --- a/src/controllers/controller.radar.js +++ b/src/controllers/controller.radar.js @@ -18,35 +18,11 @@ }, }; - Chart.controllers.radar = function(chart, datasetIndex) { - this.initialize.call(this, chart, datasetIndex); - }; - - - helpers.extend(Chart.controllers.radar.prototype, { - - initialize: function(chart, datasetIndex) { - this.chart = chart; - this.index = datasetIndex; - this.linkScales(); - this.addElements(); - }, - updateIndex: function(datasetIndex) { - this.index = datasetIndex; - }, - + Chart.controllers.radar = Chart.DatasetController.extend({ linkScales: function() { // No need. Single scale only }, - getDataset: function() { - return this.chart.data.datasets[this.index]; - }, - - getScaleForId: function(scaleID) { - return this.chart.scales[scaleID]; - }, - addElements: function() { this.getDataset().metaData = this.getDataset().metaData || []; @@ -87,30 +63,6 @@ // Make sure bezier control points are updated this.updateBezierControlPoints(); }, - removeElement: function(index) { - this.getDataset().metaData.splice(index, 1); - }, - - reset: function() { - this.update(true); - }, - - 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) { @@ -246,9 +198,5 @@ 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); } - }); - - - }).call(this); diff --git a/src/core/core.datasetController.js b/src/core/core.datasetController.js new file mode 100644 index 000000000..2f1d366ec --- /dev/null +++ b/src/core/core.datasetController.js @@ -0,0 +1,77 @@ +(function() { + + "use strict"; + + //Declare root variable - window in the browser, global on the server + var root = this, + Chart = root.Chart, + helpers = Chart.helpers; + + + // Base class for all dataset controllers (line, bar, etc) + Chart.DatasetController = function(chart, datasetIndex) { + this.initialize.call(this, chart, datasetIndex); + }; + + helpers.extend(Chart.DatasetController.prototype, { + initialize: function(chart, datasetIndex) { + this.chart = chart; + this.index = datasetIndex; + this.linkScales(); + this.addElements(); + }, + updateIndex: function(datasetIndex) { + this.index = datasetIndex; + }, + + linkScales: function() { + if (!this.getDataset().xAxisID) { + this.getDataset().xAxisID = this.chart.options.scales.xAxes[0].id; + } + + if (!this.getDataset().yAxisID) { + this.getDataset().yAxisID = this.chart.options.scales.yAxes[0].id; + } + }, + + getDataset: function() { + return this.chart.data.datasets[this.index]; + }, + + getScaleForId: function(scaleID) { + return this.chart.scales[scaleID]; + }, + + reset: function() { + this.update(true); + }, + + buildOrUpdateElements: function buildOrUpdateElements() { + // Handle the number of data points changing + var numData = this.getDataset().data.length; + var numMetaData = this.getDataset().metaData.length; + + // Make sure that we handle number of datapoints changing + if (numData < numMetaData) { + // Remove excess bars for data points that have been removed + this.getDataset().metaData.splice(numData, numMetaData - numData); + } else if (numData > numMetaData) { + // Add new elements + for (var index = numMetaData; index < numData; ++index) { + this.addElementAndReset(index); + } + } + }, + + // Controllers should implement the following + addElements: helpers.noop, + addElementAndReset: helpers.noop, + draw: helpers.noop, + removeHoverStyle: helpers.noop, + setHoverStyle: helpers.noop, + update: helpers.noop, + }); + + Chart.DatasetController.extend = helpers.inherits; + +}).call(this); diff --git a/src/core/core.tooltip.js b/src/core/core.tooltip.js index cbc3111b0..bad1189f3 100644 --- a/src/core/core.tooltip.js +++ b/src/core/core.tooltip.js @@ -152,7 +152,7 @@ // Args are: (tooltipItem, data) getBeforeBody: function() { var lines = this._options.tooltips.callbacks.beforeBody.apply(this, arguments); - return helpers.isArray(lines) ? lines : [lines]; + return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : []; }, // Args are: (tooltipItem, data) @@ -173,7 +173,7 @@ // Args are: (tooltipItem, data) getAfterBody: function() { var lines = this._options.tooltips.callbacks.afterBody.apply(this, arguments); - return helpers.isArray(lines) ? lines : [lines]; + return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : []; }, // Get the footer and beforeFooter and afterFooter lines @@ -323,11 +323,11 @@ tooltipHeight += vm.title.length ? vm.titleMarginBottom : 0; // Title's bottom Margin tooltipHeight += combinedBodyLength * vm.bodyFontSize; // Body Lines - tooltipHeight += (combinedBodyLength - 1) * vm.bodySpacing; // Body Line Spacing + tooltipHeight += combinedBodyLength ? (combinedBodyLength - 1) * vm.bodySpacing : 0; // Body Line Spacing tooltipHeight += vm.footer.length ? vm.footerMarginTop : 0; // Footer Margin tooltipHeight += vm.footer.length * (vm.footerFontSize); // Footer Lines - tooltipHeight += (vm.footer.length - 1) * vm.footerSpacing; // Footer Line Spacing + tooltipHeight += vm.footer.length ? (vm.footer.length - 1) * vm.footerSpacing : 0; // Footer Line Spacing // Width var tooltipWidth = 0; diff --git a/test/controller.bar.tests.js b/test/controller.bar.tests.js index 14cd977a4..f01d9a301 100644 --- a/test/controller.bar.tests.js +++ b/test/controller.bar.tests.js @@ -142,33 +142,6 @@ describe('Bar controller tests', function() { expect(chart.data.datasets[1].metaData[3] instanceof Chart.elements.Rectangle).toBe(true); }); - it('should remove elements', function() { - var chart = { - data: { - datasets: [{}, { - data: [10, 15, 0, -4] - }] - }, - config: { - type: 'bar' - }, - options: { - scales: { - xAxes: [{ - id: 'firstXScaleID' - }], - yAxes: [{ - id: 'firstYScaleID' - }] - } - } - }; - - var controller = new Chart.controllers.bar(chart, 1); - controller.removeElement(1); - expect(chart.data.datasets[1].metaData.length).toBe(3); - }); - it('should update elements', function() { var data = { datasets: [{ diff --git a/test/controller.doughnut.tests.js b/test/controller.doughnut.tests.js index 7328b48af..865d7b8cd 100644 --- a/test/controller.doughnut.tests.js +++ b/test/controller.doughnut.tests.js @@ -41,25 +41,6 @@ describe('Doughnut controller tests', function() { expect(chart.data.datasets[0].metaData[3] instanceof Chart.elements.Arc).toBe(true); }); - it ('Should remove elements', function() { - var chart = { - data: { - datasets: [{ - data: [10, 15, 0, 4] - }] - }, - config: { - type: 'doughnut' - }, - options: { - } - }; - - var controller = new Chart.controllers.doughnut(chart, 0); - controller.removeElement(1); - expect(chart.data.datasets[0].metaData.length).toBe(3); - }); - it ('Should reset and update elements', function() { var chart = { chartArea: { diff --git a/test/controller.line.tests.js b/test/controller.line.tests.js index f813bb55d..1b918dff9 100644 --- a/test/controller.line.tests.js +++ b/test/controller.line.tests.js @@ -76,33 +76,6 @@ describe('Line controller tests', function() { expect(chart.data.datasets[0].metaDataset instanceof Chart.elements.Line).toBe(true); // 1 line element }); - it('should remove elements', function() { - var chart = { - data: { - datasets: [{ - data: [10, 15, 0, -4] - }] - }, - config: { - type: 'line' - }, - options: { - scales: { - xAxes: [{ - id: 'firstXScaleID' - }], - yAxes: [{ - id: 'firstYScaleID' - }] - } - } - }; - - var controller = new Chart.controllers.line(chart, 0); - controller.removeElement(0); - expect(chart.data.datasets[0].metaData.length).toBe(3); - }); - it('should draw all elements', function() { var chart = { data: {