Meta info are now scoped by chart and moved under the dataset._meta map { chart.id -> meta }. Meta for a specific chart (and dataset) can be accessed using chart.getDatasetMeta(datasetIndex) or from the dataset controller using getMeta(). Note that helpers.uid() now generates an int (instead of a string) to make lookups in the _meta map faster.
},
addElements: function() {
- this.getDataset().metaData = this.getDataset().metaData || [];
+ var meta = this.getMeta();
helpers.each(this.getDataset().data, function(value, index) {
- this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Rectangle({
+ meta.data[index] = meta.data[index] || new Chart.elements.Rectangle({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
}, this);
},
+
addElementAndReset: function(index) {
- this.getDataset().metaData = this.getDataset().metaData || [];
var rectangle = new Chart.elements.Rectangle({
_chart: this.chart.chart,
_datasetIndex: this.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);
- this.getDataset().metaData.splice(index, 0, rectangle);
},
update: function update(reset) {
var numBars = this.getBarCount();
- helpers.each(this.getDataset().metaData, function(rectangle, index) {
+ helpers.each(this.getMeta().data, function(rectangle, index) {
this.updateElement(rectangle, index, reset, numBars);
}, this);
},
updateElement: function updateElement(rectangle, index, reset, numBars) {
-
- var xScale = this.getScaleForId(this.getDataset().xAxisID);
- var yScale = this.getScaleForId(this.getDataset().yAxisID);
+ var meta = this.getMeta();
+ var xScale = this.getScaleForId(meta.xAxisID);
+ var yScale = this.getScaleForId(meta.yAxisID);
var yScalePoint;
},
calculateBarBase: function(datasetIndex, index) {
-
- var xScale = this.getScaleForId(this.getDataset().xAxisID);
- var yScale = this.getScaleForId(this.getDataset().yAxisID);
+ var meta = this.getMeta();
+ var xScale = this.getScaleForId(meta.xAxisID);
+ var yScale = this.getScaleForId(meta.yAxisID);
var base = 0;
if (value < 0) {
for (var i = 0; i < datasetIndex; i++) {
var negDS = this.chart.data.datasets[i];
- if (helpers.isDatasetVisible(negDS) && negDS.yAxisID === yScale.id && negDS.bar) {
+ var negDSMeta = this.chart.getDatasetMeta(i);
+ if (helpers.isDatasetVisible(negDS) && negDSMeta.yAxisID === yScale.id && negDS.bar) {
base += negDS.data[index] < 0 ? negDS.data[index] : 0;
}
}
} else {
for (var j = 0; j < datasetIndex; j++) {
var posDS = this.chart.data.datasets[j];
- if (helpers.isDatasetVisible(posDS) && posDS.yAxisID === yScale.id && posDS.bar) {
+ var posDSMeta = this.chart.getDatasetMeta(j);
+ if (helpers.isDatasetVisible(posDS) && posDSMeta.yAxisID === yScale.id && posDS.bar) {
base += posDS.data[index] > 0 ? posDS.data[index] : 0;
}
}
},
getRuler: function() {
-
- var xScale = this.getScaleForId(this.getDataset().xAxisID);
- var yScale = this.getScaleForId(this.getDataset().yAxisID);
+ var meta = this.getMeta();
+ var xScale = this.getScaleForId(meta.xAxisID);
+ var yScale = this.getScaleForId(meta.yAxisID);
var datasetCount = this.getBarCount();
var tickWidth = (function() {
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);
},
calculateBarWidth: function() {
- var xScale = this.getScaleForId(this.getDataset().xAxisID);
+ var xScale = this.getScaleForId(this.getMeta().xAxisID);
var ruler = this.getRuler();
return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth;
},
},
calculateBarX: function(index, datasetIndex) {
-
- var yScale = this.getScaleForId(this.getDataset().yAxisID);
- var xScale = this.getScaleForId(this.getDataset().xAxisID);
+ 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();
},
calculateBarY: function(index, datasetIndex) {
-
- var xScale = this.getScaleForId(this.getDataset().xAxisID);
- var yScale = this.getScaleForId(this.getDataset().yAxisID);
+ var meta = this.getMeta();
+ var xScale = this.getScaleForId(meta.xAxisID);
+ var yScale = this.getScaleForId(meta.yAxisID);
var value = this.getDataset().data[index];
for (var i = 0; i < datasetIndex; i++) {
var ds = this.chart.data.datasets[i];
- if (helpers.isDatasetVisible(ds) && ds.bar && ds.yAxisID === yScale.id) {
+ var dsMeta = this.chart.getDatasetMeta(i);
+ if (helpers.isDatasetVisible(ds) && ds.bar && dsMeta.yAxisID === yScale.id) {
if (ds.data[index] < 0) {
sumNeg += ds.data[index] || 0;
} else {
} else {
return yScale.getPixelForValue(sumPos + value);
}
-
- return yScale.getPixelForValue(value);
}
return yScale.getPixelForValue(value);
draw: function(ease) {
var easingDecimal = ease || 1;
- helpers.each(this.getDataset().metaData, function(rectangle, index) {
+ 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();
Chart.controllers.bubble = Chart.DatasetController.extend({
addElements: function() {
-
- this.getDataset().metaData = this.getDataset().metaData || [];
-
+ var meta = this.getMeta();
helpers.each(this.getDataset().data, function(value, index) {
- this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({
+ meta.data[index] = meta.data[index] || new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
}, this);
},
addElementAndReset: function(index) {
- this.getDataset().metaData = this.getDataset().metaData || [];
var point = new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
- // Reset the point
+ // Add to the points array and reset it
+ this.getMeta().data.splice(index, 0, point);
this.updateElement(point, index, true);
-
- // Add to the points array
- this.getDataset().metaData.splice(index, 0, point);
},
update: function update(reset) {
- var points = this.getDataset().metaData;
-
- var yScale = this.getScaleForId(this.getDataset().yAxisID);
- var xScale = this.getScaleForId(this.getDataset().xAxisID);
+ 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) {
},
updateElement: function(point, index, reset) {
- var yScale = this.getScaleForId(this.getDataset().yAxisID);
- var xScale = this.getScaleForId(this.getDataset().xAxisID);
+ 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) {
var easingDecimal = ease || 1;
// Transition and Draw the Points
- helpers.each(this.getDataset().metaData, function(point, index) {
+ helpers.each(this.getMeta().data, function(point, index) {
point.transition(easingDecimal);
point.draw();
});
},
legend: {
labels: {
- generateLabels: function(data) {
+ generateLabels: function(chart) {
+ var data = chart.data;
if (data.labels.length && data.datasets.length) {
-
return data.labels.map(function(label, i) {
var ds = data.datasets[0];
- var arc = ds.metaData[i];
+ var arc = chart.getDatasetMeta(0).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);
},
addElements: function() {
- this.getDataset().metaData = this.getDataset().metaData || [];
+ var meta = this.getMeta();
helpers.each(this.getDataset().data, function(value, index) {
- this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Arc({
+ meta.data[index] = meta.data[index] || new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
}, this);
},
+
addElementAndReset: function(index, colorForNewElement) {
- this.getDataset().metaData = this.getDataset().metaData || [];
var arc = new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
this.getDataset().backgroundColor.splice(index, 0, colorForNewElement);
}
- // Reset the point
+ // Add to the points array and reset it
+ this.getMeta().data.splice(index, 0, arc);
this.updateElement(arc, index, true);
-
- // Add to the points array
- this.getDataset().metaData.splice(index, 0, arc);
},
getVisibleDatasetCount: function getVisibleDatasetCount() {
this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.getRingIndex(this.index));
this.innerRadius = this.outerRadius - this.chart.radiusLength;
- helpers.each(this.getDataset().metaData, function(arc, index) {
+ helpers.each(this.getMeta().data, function(arc, index) {
this.updateElement(arc, index, reset);
}, this);
},
if (index === 0) {
arc._model.startAngle = this.chart.options.rotation;
} else {
- arc._model.startAngle = this.getDataset().metaData[index - 1]._model.endAngle;
+ arc._model.startAngle = this.getMeta().data[index - 1]._model.endAngle;
}
arc._model.endAngle = arc._model.startAngle + arc._model.circumference;
draw: function(ease) {
var easingDecimal = ease || 1;
- helpers.each(this.getDataset().metaData, function(arc, index) {
+ helpers.each(this.getMeta().data, function(arc, index) {
arc.transition(easingDecimal).draw();
});
},
Chart.controllers.line = Chart.DatasetController.extend({
addElements: function() {
-
- this.getDataset().metaData = this.getDataset().metaData || [];
-
- this.getDataset().metaDataset = this.getDataset().metaDataset || new Chart.elements.Line({
+ var meta = this.getMeta();
+ meta.dataset = meta.dataset || new Chart.elements.Line({
_chart: this.chart.chart,
_datasetIndex: this.index,
- _points: this.getDataset().metaData
+ _points: meta.data
});
helpers.each(this.getDataset().data, function(value, index) {
- this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({
+ meta.data[index] = meta.data[index] || new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
}, this);
},
+
addElementAndReset: function(index) {
- this.getDataset().metaData = this.getDataset().metaData || [];
var point = new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
- // Reset the point
+ // Add to the points array and reset it
+ this.getMeta().data.splice(index, 0, point);
this.updateElement(point, index, true);
- // Add to the points array
- this.getDataset().metaData.splice(index, 0, point);
-
// 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 line = this.getDataset().metaDataset;
- var points = this.getDataset().metaData;
+ var meta = this.getMeta();
+ var line = meta.dataset;
+ var points = meta.data;
- var yScale = this.getScaleForId(this.getDataset().yAxisID);
- var xScale = this.getScaleForId(this.getDataset().xAxisID);
+ var yScale = this.getScaleForId(meta.yAxisID);
+ var xScale = this.getScaleForId(meta.xAxisID);
var scaleBase;
if (yScale.min < 0 && yScale.max < 0) {
},
updateElement: function(point, index, reset) {
- var yScale = this.getScaleForId(this.getDataset().yAxisID);
- var xScale = this.getScaleForId(this.getDataset().xAxisID);
+ 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) {
},
calculatePointY: function(value, index, datasetIndex, isCombo) {
-
- var xScale = this.getScaleForId(this.getDataset().xAxisID);
- var yScale = this.getScaleForId(this.getDataset().yAxisID);
+ var meta = this.getMeta();
+ var xScale = this.getScaleForId(meta.xAxisID);
+ var yScale = this.getScaleForId(meta.yAxisID);
if (yScale.options.stacked) {
updateBezierControlPoints: function() {
// Update bezier control points
- helpers.each(this.getDataset().metaData, function(point, index) {
+ var meta = this.getMeta();
+ helpers.each(meta.data, function(point, index) {
var controlPoints = helpers.splineCurve(
- helpers.previousItem(this.getDataset().metaData, index)._model,
+ helpers.previousItem(meta.data, index)._model,
point._model,
- helpers.nextItem(this.getDataset().metaData, index)._model,
- this.getDataset().metaDataset._model.tension
+ helpers.nextItem(meta.data, index)._model,
+ meta.dataset._model.tension
);
// Prevent the bezier going outside of the bounds of the graph
},
draw: function(ease) {
+ var meta = this.getMeta();
var easingDecimal = ease || 1;
// Transition Point Locations
- helpers.each(this.getDataset().metaData, function(point) {
+ helpers.each(meta.data, function(point) {
point.transition(easingDecimal);
});
// Transition and Draw the line
if (this.chart.options.showLines)
- this.getDataset().metaDataset.transition(easingDecimal).draw();
+ meta.dataset.transition(easingDecimal).draw();
// Draw the points
- helpers.each(this.getDataset().metaData, function(point) {
+ helpers.each(meta.data, function(point) {
point.draw();
});
},
},
legend: {
labels: {
- generateLabels: function(data) {
+ generateLabels: function(chart) {
+ var data = chart.data;
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
var ds = data.datasets[0];
- var arc = ds.metaData[i];
+ var arc = chart.getDatasetMeta(0).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);
linkScales: function() {
// no scales for doughnut
},
+
addElements: function() {
- this.getDataset().metaData = this.getDataset().metaData || [];
+ var meta = this.getMeta();
helpers.each(this.getDataset().data, function(value, index) {
- this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Arc({
+ meta.data[index] = meta.data[index] || new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
}, this);
},
+
addElementAndReset: function(index) {
- this.getDataset().metaData = this.getDataset().metaData || [];
var arc = new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
- // Reset the point
+ // Add to the points array and reset it
+ this.getMeta().data.splice(index, 0, arc);
this.updateElement(arc, index, true);
-
- // Add to the points array
- this.getDataset().metaData.splice(index, 0, arc);
},
getVisibleDatasetCount: function getVisibleDatasetCount() {
return helpers.where(this.chart.data.datasets, function(ds) {
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) {
+ helpers.each(this.getMeta().data, function(arc, index) {
this.updateElement(arc, index, reset);
}, this);
},
draw: function(ease) {
var easingDecimal = ease || 1;
- helpers.each(this.getDataset().metaData, function(arc, index) {
+ helpers.each(this.getMeta().data, function(arc, index) {
arc.transition(easingDecimal).draw();
});
},
},
addElements: function() {
+ var meta = this.getMeta();
- this.getDataset().metaData = this.getDataset().metaData || [];
-
- this.getDataset().metaDataset = this.getDataset().metaDataset || new Chart.elements.Line({
+ meta.dataset = meta.dataset || new Chart.elements.Line({
_chart: this.chart.chart,
_datasetIndex: this.index,
- _points: this.getDataset().metaData,
+ _points: meta.data,
_loop: true
});
helpers.each(this.getDataset().data, function(value, index) {
- this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({
+ meta.data[index] = meta.data[index] || new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
}, this);
},
addElementAndReset: function(index) {
- this.getDataset().metaData = this.getDataset().metaData || [];
var point = new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
- // Reset the point
+ // Add to the points array and reset it
+ this.getMeta().data.splice(index, 0, point);
this.updateElement(point, index, true);
- // Add to the points array
- this.getDataset().metaData.splice(index, 0, point);
-
// Make sure bezier control points are updated
this.updateBezierControlPoints();
},
update: function update(reset) {
-
- var line = this.getDataset().metaDataset;
- var points = this.getDataset().metaData;
+ var meta = this.getMeta();
+ var line = meta.dataset;
+ var points = meta.data;
var scale = this.chart.scale;
var scaleBase;
scaleBase = scale.getPointPositionForValue(0, 0);
}
- helpers.extend(this.getDataset().metaDataset, {
+ helpers.extend(meta.dataset, {
// Utility
_datasetIndex: this.index,
// Data
- _children: this.getDataset().metaData,
+ _children: points,
// Model
_model: {
// Appearance
}
});
- this.getDataset().metaDataset.pivot();
+ meta.dataset.pivot();
// Update Points
helpers.each(points, function(point, index) {
point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
},
updateBezierControlPoints: function() {
- helpers.each(this.getDataset().metaData, function(point, index) {
+ var meta = this.getMeta();
+ helpers.each(meta.data, function(point, index) {
var controlPoints = helpers.splineCurve(
- helpers.previousItem(this.getDataset().metaData, index, true)._model,
+ helpers.previousItem(meta.data, index, true)._model,
point._model,
- helpers.nextItem(this.getDataset().metaData, index, true)._model,
+ helpers.nextItem(meta.data, index, true)._model,
point._model.tension
);
},
draw: function(ease) {
+ var meta = this.getMeta();
var easingDecimal = ease || 1;
// Transition Point Locations
- helpers.each(this.getDataset().metaData, function(point, index) {
+ helpers.each(meta.data, function(point, index) {
point.transition(easingDecimal);
});
// Transition and Draw the line
- this.getDataset().metaDataset.transition(easingDecimal).draw();
+ meta.dataset.transition(easingDecimal).draw();
// Draw the points
- helpers.each(this.getDataset().metaData, function(point) {
+ helpers.each(meta.data, function(point) {
point.draw();
});
},
dataset.type = this.config.type;
}
+ var meta = this.getDatasetMeta(datasetIndex);
var type = dataset.type;
types.push(type);
- if (dataset.controller) {
- dataset.controller.updateIndex(datasetIndex);
+ if (meta.controller) {
+ meta.controller.updateIndex(datasetIndex);
} else {
- dataset.controller = new Chart.controllers[type](this, datasetIndex);
- newControllers.push(dataset.controller);
+ meta.controller = new Chart.controllers[type](this, datasetIndex);
+ newControllers.push(meta.controller);
}
}, this);
resetElements: function resetElements() {
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
- dataset.controller.reset();
- });
+ this.getDatasetMeta(datasetIndex).controller.reset();
+ }, this);
},
update: function update(animationDuration, lazy) {
// Make sure all dataset controllers have correct meta data counts
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
- dataset.controller.buildOrUpdateElements();
- });
+ this.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();
+ }, this);
Chart.layoutService.update(this, this.chart.width, this.chart.height);
// 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.getDatasetMeta(datasetIndex).controller.update();
+ }, this);
+
this.render(animationDuration, lazy);
Chart.pluginService.notifyPlugins('afterUpdate', [this]);
// Draw each dataset via its respective controller (reversed to support proper line stacking)
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
if (helpers.isDatasetVisible(dataset)) {
- dataset.controller.draw(ease);
+ this.getDatasetMeta(datasetIndex).controller.draw(ease);
}
- }, null, true);
+ }, this, true);
// Restore from the clipping operation
this.chart.ctx.restore();
// 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) {
+ var meta = this.getDatasetMeta(datasetIndex);
if (helpers.isDatasetVisible(dataset)) {
- helpers.each(dataset.metaData, function(element, index) {
+ helpers.each(meta.data, function(element, index) {
if (element.inRange(eventPosition.x, eventPosition.y)) {
elementsArray.push(element);
return elementsArray;
}
});
}
- });
+ }, this);
return elementsArray;
},
var found = (function() {
if (this.data.datasets) {
for (var i = 0; i < this.data.datasets.length; i++) {
+ var meta = this.getDatasetMeta(i);
if (helpers.isDatasetVisible(this.data.datasets[i])) {
- for (var j = 0; j < this.data.datasets[i].metaData.length; j++) {
- if (this.data.datasets[i].metaData[j].inRange(eventPosition.x, eventPosition.y)) {
- return this.data.datasets[i].metaData[j];
+ for (var j = 0; j < meta.data.length; j++) {
+ if (meta.data[j].inRange(eventPosition.x, eventPosition.y)) {
+ return meta.data[j];
}
}
}
- }
+ };
}
}).call(this);
return elementsArray;
}
- helpers.each(this.data.datasets, function(dataset, dsIndex) {
+ helpers.each(this.data.datasets, function(dataset, datasetIndex) {
+ var meta = this.getDatasetMeta(datasetIndex);
if (helpers.isDatasetVisible(dataset)) {
- elementsArray.push(dataset.metaData[found._index]);
+ elementsArray.push(meta.data[found._index]);
}
- });
+ }, this);
return elementsArray;
},
var elementsArray = this.getElementAtEvent(e);
if (elementsArray.length > 0) {
- elementsArray = this.data.datasets[elementsArray[0]._datasetIndex].metaData;
+ 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] = {
+ data: [],
+ dataset: null,
+ controller: null,
+ xAxisID: null,
+ yAxisID: null
+ };
+ }
+
+ return meta;
+ },
+
generateLegend: function generateLegend() {
return this.options.legendCallback(this);
},
}
}
- 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':
- this.data.datasets[this.lastActive[0]._datasetIndex].controller.removeHoverStyle(this.lastActive[0], this.lastActive[0]._datasetIndex, this.lastActive[0]._index);
+ this.getDatasetMeta(this.lastActive[0]._datasetIndex).controller.removeHoverStyle(this.lastActive[0], this.lastActive[0]._datasetIndex, this.lastActive[0]._index);
break;
case 'label':
case 'dataset':
for (var i = 0; i < this.lastActive.length; i++) {
if (this.lastActive[i])
- this.data.datasets[this.lastActive[i]._datasetIndex].controller.removeHoverStyle(this.lastActive[i], this.lastActive[i]._datasetIndex, this.lastActive[i]._index);
+ this.getDatasetMeta(this.lastActive[i]._datasetIndex).controller.removeHoverStyle(this.lastActive[i], this.lastActive[i]._datasetIndex, this.lastActive[i]._index);
}
break;
default:
if (this.active.length && this.options.hover.mode) {
switch (this.options.hover.mode) {
case 'single':
- this.data.datasets[this.active[0]._datasetIndex].controller.setHoverStyle(this.active[0]);
+ this.getDatasetMeta(this.active[0]._datasetIndex).controller.setHoverStyle(this.active[0]);
break;
case 'label':
case 'dataset':
for (var j = 0; j < this.active.length; j++) {
if (this.active[j])
- this.data.datasets[this.active[j]._datasetIndex].controller.setHoverStyle(this.active[j]);
+ this.getDatasetMeta(this.active[j]._datasetIndex).controller.setHoverStyle(this.active[j]);
}
break;
default:
},
linkScales: function() {
- if (!this.getDataset().xAxisID) {
- this.getDataset().xAxisID = this.chart.options.scales.xAxes[0].id;
- }
+ var meta = this.getMeta();
+ var dataset = this.getDataset();
- if (!this.getDataset().yAxisID) {
- this.getDataset().yAxisID = this.chart.options.scales.yAxes[0].id;
+ if (meta.xAxisID === null) {
+ meta.xAxisID = dataset.xAxisID || this.chart.options.scales.xAxes[0].id;
+ }
+ if (meta.yAxisID === null) {
+ meta.yAxisID = dataset.yAxisID || this.chart.options.scales.yAxes[0].id;
}
},
return this.chart.data.datasets[this.index];
},
+ getMeta: function() {
+ return this.chart.getDatasetMeta(this.index);
+ },
+
getScaleForId: function(scaleID) {
return this.chart.scales[scaleID];
},
buildOrUpdateElements: function buildOrUpdateElements() {
// Handle the number of data points changing
+ var meta = this.getMeta();
var numData = this.getDataset().data.length;
- var numMetaData = this.getDataset().metaData.length;
+ var numMetaData = meta.data.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);
+ meta.data.splice(numData, numMetaData - numData);
} else if (numData > numMetaData) {
// Add new elements
for (var index = numMetaData; index < numData; ++index) {
helpers.uid = (function() {
var id = 0;
return function() {
- return "chart-" + id++;
+ return id++;
};
})();
helpers.warn = function(str) {
// lineDashOffset :
// lineJoin :
// lineWidth :
- generateLabels: function(data) {
+ generateLabels: function(chart) {
+ var data = chart.data;
return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {
return {
text: dataset.label,
beforeBuildLabels: helpers.noop,
buildLabels: function() {
- this.legendItems = this.options.labels.generateLabels.call(this, this.chart.data);
+ this.legendItems = this.options.labels.generateLabels.call(this, this.chart);
if(this.options.reverse){
this.legendItems.reverse();
}
if (!helpers.isDatasetVisible(dataset)) {
return;
}
- var currentElement = dataset.metaData[element._index];
+
+ var meta = this._chartInstance.getDatasetMeta(datasetIndex);
+ var currentElement = meta.data[element._index];
if (currentElement) {
var yScale = element._yScale || element._scale; // handle radar || polarArea charts
datasetIndex: datasetIndex
});
}
- }, null);
+ }, this);
helpers.each(this._active, function(active) {
if (active) {
if (vm.title.length) {
ctx.textAlign = vm._titleAlign;
ctx.textBaseline = "top";
-
+
var titleColor = helpers.color(vm.titleColor);
ctx.fillStyle = titleColor.alpha(opacity * titleColor.alpha()).rgbString();
ctx.font = helpers.fontString(vm.titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
ctx.textAlign = vm._footerAlign;
ctx.textBaseline = "top";
-
+
var footerColor = helpers.color(vm.footerColor);
ctx.fillStyle = footerColor.alpha(opacity * footerColor.alpha()).rgbString();
ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
var hasPositiveValues = false;
var hasNegativeValues = false;
- helpers.each(this.chart.data.datasets, function(dataset) {
+ helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) {
+ var meta = this.chart.getDatasetMeta(datasetIndex);
if (valuesPerType[dataset.type] === undefined) {
valuesPerType[dataset.type] = {
positiveValues: [],
var positiveValues = valuesPerType[dataset.type].positiveValues;
var negativeValues = valuesPerType[dataset.type].negativeValues;
- if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) {
+ if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? meta.xAxisID === this.id : meta.yAxisID === this.id)) {
helpers.each(dataset.data, function(rawValue, index) {
var value = +this.getRightValue(rawValue);
}, this);
} else {
- helpers.each(this.chart.data.datasets, function(dataset) {
- if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) {
+ helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) {
+ var meta = this.chart.getDatasetMeta(datasetIndex);
+ if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? meta.xAxisID === this.id : meta.yAxisID === this.id)) {
helpers.each(dataset.data, function(rawValue, index) {
var value = +this.getRightValue(rawValue);
if (isNaN(value)) {
if (this.options.stacked) {
var valuesPerType = {};
- helpers.each(this.chart.data.datasets, function(dataset) {
- if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) {
+ helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) {
+ var meta = this.chart.getDatasetMeta(datasetIndex);
+ if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? meta.xAxisID === this.id : meta.yAxisID === this.id)) {
if (valuesPerType[dataset.type] === undefined) {
valuesPerType[dataset.type] = [];
}
}, this);
} else {
- helpers.each(this.chart.data.datasets, function(dataset) {
- if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) {
+ helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) {
+ var meta = this.chart.getDatasetMeta(datasetIndex);
+ if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? meta.xAxisID === this.id : meta.yAxisID === this.id)) {
helpers.each(dataset.data, function(rawValue, index) {
var value = +this.getRightValue(rawValue);
if (isNaN(value)) {