Data controllers should now rarely implement addElements and addElementAndReset but instead should define dataElementType (and optionally datasetElementType). Also remove some dead code (e.g. numBars, colorForNewElement, etc.).
require('./core/core.title')(Chart);
require('./core/core.tooltip')(Chart);
-require('./controllers/controller.bar')(Chart);
-require('./controllers/controller.bubble')(Chart);
-require('./controllers/controller.doughnut')(Chart);
-require('./controllers/controller.line')(Chart);
-require('./controllers/controller.polarArea')(Chart);
-require('./controllers/controller.radar')(Chart);
+require('./elements/element.arc')(Chart);
+require('./elements/element.line')(Chart);
+require('./elements/element.point')(Chart);
+require('./elements/element.rectangle')(Chart);
require('./scales/scale.category')(Chart);
require('./scales/scale.linear')(Chart);
require('./scales/scale.radialLinear')(Chart);
require('./scales/scale.time')(Chart);
-require('./elements/element.arc')(Chart);
-require('./elements/element.line')(Chart);
-require('./elements/element.point')(Chart);
-require('./elements/element.rectangle')(Chart);
+// Controllers must be loaded after elements
+// See Chart.core.datasetController.dataElementType
+require('./controllers/controller.bar')(Chart);
+require('./controllers/controller.bubble')(Chart);
+require('./controllers/controller.doughnut')(Chart);
+require('./controllers/controller.line')(Chart);
+require('./controllers/controller.polarArea')(Chart);
+require('./controllers/controller.radar')(Chart);
require('./charts/Chart.Bar')(Chart);
require('./charts/Chart.Bubble')(Chart);
};
Chart.controllers.bar = Chart.DatasetController.extend({
+
+ dataElementType: Chart.elements.Rectangle,
+
initialize: function(chart, datasetIndex) {
Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex);
// Use this to indicate that this is a bar dataset.
this.getMeta().bar = true;
},
+
// Get the number of datasets that display bars. We use this to correctly calculate the bar width
getBarCount: function getBarCount() {
var barCount = 0;
return barCount;
},
- addElements: function() {
- var meta = this.getMeta();
- helpers.each(this.getDataset().data, function(value, index) {
- meta.data[index] = meta.data[index] || new Chart.elements.Rectangle({
- _chart: this.chart.chart,
- _datasetIndex: this.index,
- _index: index
- });
- }, this);
- },
-
- addElementAndReset: function(index) {
- var rectangle = new Chart.elements.Rectangle({
- _chart: this.chart.chart,
- _datasetIndex: this.index,
- _index: index
- });
-
- var numBars = this.getBarCount();
-
- // Add to the points array and reset it
- this.getMeta().data.splice(index, 0, rectangle);
- this.updateElement(rectangle, index, true, numBars);
- },
-
update: function update(reset) {
- var numBars = this.getBarCount();
-
helpers.each(this.getMeta().data, function(rectangle, index) {
- this.updateElement(rectangle, index, reset, numBars);
+ this.updateElement(rectangle, index, reset);
}, this);
},
- updateElement: function updateElement(rectangle, index, reset, numBars) {
+ updateElement: function updateElement(rectangle, index, reset) {
var meta = this.getMeta();
var xScale = this.getScaleForId(meta.xAxisID);
var yScale = this.getScaleForId(meta.yAxisID);
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),
helpers.extend(rectangle, {
// Utility
- _chart: this.chart.chart,
_xScale: xScale,
_yScale: yScale,
_datasetIndex: this.index,
}
};
-
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);
- },
+ dataElementType: Chart.elements.Point,
update: function update(reset) {
var meta = this.getMeta();
helpers.each(points, function(point, index) {
this.updateElement(point, index, reset);
}, this);
-
},
updateElement: function(point, index, reset) {
helpers.extend(point, {
// Utility
- _chart: this.chart.chart,
_xScale: xScale,
_yScale: yScale,
_datasetIndex: this.index,
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];
Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({
- // no scales for doughnut
- linkScales: helpers.noop,
- addElements: function() {
- var _this = this;
- var meta = this.getMeta(),
- data = meta.data;
- helpers.each(_this.getDataset().data, function(value, index) {
- data[index] = data[index] || new Chart.elements.Arc({
- _chart: _this.chart.chart,
- _datasetIndex: _this.index,
- _index: index
- });
- });
- },
+ dataElementType: Chart.elements.Arc,
- addElementAndReset: function(index, colorForNewElement) {
- var _this = this;
- var arc = new Chart.elements.Arc({
- _chart: _this.chart.chart,
- _datasetIndex: _this.index,
- _index: index
- }),
- ds = _this.getDataset();
-
- if (colorForNewElement && helpers.isArray(ds.backgroundColor)) {
- ds.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);
- },
+ linkScales: helpers.noop,
// Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly
getRingIndex: function getRingIndex(datasetIndex) {
helpers.extend(arc, {
// Utility
- _chart: chart.chart,
_datasetIndex: _this.index,
_index: index,
};
Chart.controllers.line = Chart.DatasetController.extend({
- addElements: function() {
- var me = this;
- var meta = me.getMeta();
- var data = me.getDataset().data || [];
- var value, i, ilen;
-
- meta.dataset = meta.dataset || new Chart.elements.Line({
- _chart: me.chart.chart,
- _datasetIndex: me.index,
- _points: meta.data
- });
-
- for (i=0, ilen=data.length; i<ilen; ++i) {
- value = data[i];
- meta.data[i] = meta.data[i] || new Chart.elements.Point({
- _chart: me.chart.chart,
- _datasetIndex: me.index,
- _index: i
- });
- }
- },
+
+ datasetElementType: Chart.elements.Line,
+
+ dataElementType: Chart.elements.Point,
addElementAndReset: function(index) {
var me = this;
var options = me.chart.options;
- var point = new Chart.elements.Point({
- _chart: me.chart.chart,
- _datasetIndex: me.index,
- _index: index
- });
- // Add to the points array and reset it
- me.getMeta().data.splice(index, 0, point);
- me.updateElement(point, index, true);
+ Chart.DatasetController.prototype.addElementAndReset.call(me, index);
// Make sure bezier control points are updated
if (options.showLines && options.elements.line.tension !== 0) {
y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex, me.chart.isCombo);
// Utility
- point._chart = me.chart.chart;
point._xScale = xScale;
point._yScale = yScale;
point._datasetIndex = datasetIndex;
};
Chart.controllers.polarArea = Chart.DatasetController.extend({
- linkScales: helpers.noop,
- addElements: function() {
- var _this = this;
- var meta = this.getMeta();
- var data = meta.data;
- helpers.each(_this.getDataset().data, function(value, index) {
- data[index] = data[index] || new Chart.elements.Arc({
- _chart: _this.chart.chart,
- _datasetIndex: _this.index,
- _index: index
- });
- });
- },
+ dataElementType: Chart.elements.Arc,
- addElementAndReset: function(index) {
- var _this = this;
- 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);
- },
+ linkScales: helpers.noop,
update: function update(reset) {
var _this = this;
helpers.extend(arc, {
// Utility
- _chart: chart.chart,
_datasetIndex: _this.index,
_index: index,
_scale: scale,
var helpers = Chart.helpers;
-
Chart.defaults.radar = {
scale: {
type: "radialLinear"
};
Chart.controllers.radar = Chart.DatasetController.extend({
- linkScales: function() {
- // No need. Single scale only
- },
- addElements: function() {
- var meta = this.getMeta();
+ datasetElementType: Chart.elements.Line,
- meta.dataset = meta.dataset || new Chart.elements.Line({
- _chart: this.chart.chart,
- _datasetIndex: this.index,
- _points: meta.data,
- _loop: true
- });
+ dataElementType: Chart.elements.Point,
- 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
- });
+ linkScales: helpers.noop,
- // Add to the points array and reset it
- this.getMeta().data.splice(index, 0, point);
- this.updateElement(point, index, true);
+ addElementAndReset: function(index) {
+ Chart.DatasetController.prototype.addElementAndReset.call(this, index);
// Make sure bezier control points are updated
this.updateBezierControlPoints();
_datasetIndex: this.index,
// Data
_children: points,
+ _loop: true,
// Model
_model: {
// Appearance
};
helpers.extend(Chart.DatasetController.prototype, {
+
+ /**
+ * Element type used to generate a meta dataset (e.g. Chart.element.Line).
+ * @type {Chart.core.element}
+ */
+ datasetElementType: null,
+
+ /**
+ * Element type used to generate a meta data (e.g. Chart.element.Point).
+ * @type {Chart.core.element}
+ */
+ dataElementType: null,
+
initialize: function(chart, datasetIndex) {
this.chart = chart;
this.index = datasetIndex;
this.linkScales();
this.addElements();
},
+
updateIndex: function(datasetIndex) {
this.index = datasetIndex;
},
this.update(true);
},
+ createMetaDataset: function() {
+ var me = this;
+ var type = me.datasetElementType;
+ return type && new type({
+ _chart: me.chart.chart,
+ _datasetIndex: me.index
+ });
+ },
+
+ createMetaData: function(index) {
+ var me = this;
+ var type = me.dataElementType;
+ return type && new type({
+ _chart: me.chart.chart,
+ _datasetIndex: me.index,
+ _index: index
+ });
+ },
+
+ addElements: function() {
+ var me = this;
+ var meta = me.getMeta();
+ var data = me.getDataset().data || [];
+ var metaData = meta.data;
+ var i, ilen;
+
+ for (i=0, ilen=data.length; i<ilen; ++i) {
+ metaData[i] = metaData[i] || me.createMetaData(meta, i);
+ }
+
+ meta.dataset = meta.dataset || me.createMetaDataset();
+ },
+
+ addElementAndReset: function(index) {
+ var me = this;
+ var element = me.createMetaData(index);
+ me.getMeta().data.splice(index, 0, element);
+ me.updateElement(element, index, true);
+ },
+
buildOrUpdateElements: function buildOrUpdateElements() {
// Handle the number of data points changing
var meta = this.getMeta(),
}
},
- // Controllers should implement the following
- addElements: noop,
- addElementAndReset: noop,
+ update: noop,
+
draw: function(ease) {
var easingDecimal = ease || 1;
helpers.each(this.getMeta().data, function(element, index) {
element.transition(easingDecimal).draw();
});
},
+
removeHoverStyle: function(element, elementOpts) {
var dataset = this.chart.data.datasets[element._datasetIndex],
index = element._index,
model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);
model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);
},
+
setHoverStyle: function(element) {
var dataset = this.chart.data.datasets[element._datasetIndex],
index = element._index,
model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor));
model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));
model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
- },
- update: noop
+ }
});
Chart.DatasetController.extend = helpers.inherits;