Generate nice legend boxes for all current chart types

This commit is contained in:
Evert Timberg 2015-12-07 19:11:54 -05:00
parent bffbaf6b37
commit b0f69a1092
3 changed files with 64 additions and 29 deletions

View File

@ -37,7 +37,15 @@
legend: {
labels: {
generateLabels: function(data) {
return data.labels.slice();
return data.labels.map(function(label, i) {
return {
text: label,
fillStyle: data.datasets[0].backgroundColor[i],
// Extra data used for toggling the correct item
index: i
};
});
}
}
},

View File

@ -39,7 +39,15 @@
legend: {
labels: {
generateLabels: function(data) {
return data.labels.slice();
return data.labels.map(function(label, i) {
return {
text: label,
fillStyle: data.datasets[0].backgroundColor[i],
// Extra data used for toggling the correct item
index: i
};
});
}
}
},

View File

@ -24,9 +24,32 @@
},
// Generates labels shown in the legend
// Valid properties to return:
// text : text to display
// fillStyle : fill of coloured box
// strokeStyle: stroke of coloured box
// hidden : if this legend item refers to a hidden item
// lineCap : cap style for line
// lineDash
// lineDashOffset :
// lineJoin :
// lineWidth :
generateLabels: function(data) {
return data.datasets.map(function(dataset) {
return this.options.labels.callback.call(this, dataset);
return data.datasets.map(function(dataset, i) {
return {
text: this.options.labels.callback.call(this, dataset),
fillStyle: dataset.backgroundColor,
hidden: dataset.hidden,
lineCap: dataset.borderCapStyle,
lineDash: dataset.borderDash,
lineDashOffset: dataset.borderDashOffset,
lineJoin: dataset.borderJoinStyle,
lineWidth: dataset.borderWidth,
strokeStyle: dataset.borderColor,
// Below is extra data used for toggling the datasets
datasetIndex: i
};
}, this);
}
},
@ -116,7 +139,7 @@
beforeBuildLabels: helpers.noop,
buildLabels: function() {
this.labels = this.options.labels.generateLabels.call(this, this.chart.data);
this.legendItems = this.options.labels.generateLabels.call(this, this.chart.data);
},
afterBuildLabels: helpers.noop,
@ -151,14 +174,14 @@
// Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one
this.lineWidths = [0];
var totalHeight = this.labels.length ? this.options.labels.fontSize + (this.options.labels.padding) : 0;
var totalHeight = this.legendItems.length ? this.options.labels.fontSize + (this.options.labels.padding) : 0;
ctx.textAlign = "left";
ctx.textBaseline = 'top';
ctx.font = labelFont;
helpers.each(this.labels, function(label, i) {
var width = this.options.labels.boxWidth + (this.options.labels.fontSize / 2) + ctx.measureText(label).width;
helpers.each(this.legendItems, function(legendItem, i) {
var width = this.options.labels.boxWidth + (this.options.labels.fontSize / 2) + ctx.measureText(legendItem.text).width;
if (this.lineWidths[this.lineWidths.length - 1] + width >= this.width) {
totalHeight += this.options.labels.fontSize + (this.options.labels.padding);
this.lineWidths[this.lineWidths.length] = this.left;
@ -214,12 +237,8 @@
ctx.fillStyle = this.options.labels.fontColor; // render in correct colour
ctx.font = labelFont;
helpers.each(this.labels, function(label, i) {
var dataset = this.chart.data.datasets[i];
var backgroundColor = dataset.backgroundColor;
var borderColor = dataset.borderColor;
var textWidth = ctx.measureText(label).width;
helpers.each(this.legendItems, function(legendItem, i) {
var textWidth = ctx.measureText(legendItem.text).width;
var width = this.options.labels.boxWidth + (this.options.labels.fontSize / 2) + textWidth;
if (cursor.x + width >= this.width) {
@ -231,20 +250,20 @@
// Set the ctx for the box
ctx.save();
ctx.strokeStyle = dataset.borderColor || Chart.defaults.global.defaultColor;
ctx.fillStyle = dataset.backgroundColor || Chart.defaults.global.defaultColor;
if (dataset.metaDataset) {
// Is this a line-like element? If so, stroke the box
if (ctx.setLineDash) {
// IE 9 and 10 do not support line dash
ctx.setLineDash(dataset.borderDash || Chart.defaults.global.elements.line.borderDash);
}
var itemOrDefault = function(item, defaulVal) {
return item !== undefined ? item : defaulVal;
};
ctx.lineCap = dataset.borderCapStyle || Chart.defaults.global.elements.line.borderCapStyle;
ctx.lineDashOffset = dataset.borderDashOffset || Chart.defaults.global.elements.line.borderDashOffset;
ctx.lineJoin = dataset.borderJoinStyle || Chart.defaults.global.elements.line.borderJoinStyle;
ctx.lineWidth = dataset.borderWidth || Chart.defaults.global.elements.line.borderWidth;
ctx.fillStyle = itemOrDefault(legendItem.fillStyle, Chart.defaults.global.defaultColor);
ctx.lineCap = itemOrDefault(legendItem.lineCap, Chart.defaults.global.elements.line.borderCapStyle);
ctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, Chart.defaults.global.elements.line.borderDashOffset);
ctx.lineJoin = itemOrDefault(legendItem.lineJoin, Chart.defaults.global.elements.line.borderJoinStyle);
ctx.lineWidth = itemOrDefault(legendItem.lineWidth, Chart.defaults.global.elements.line.borderWidth);
ctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, Chart.defaults.global.defaultColor);
if (ctx.setLineDash) {
// IE 9 and 10 do not support line dash
ctx.setLineDash(itemOrDefault(legendItem.lineDash, Chart.defaults.global.elements.line.borderDash));
}
// Draw the box
@ -257,9 +276,9 @@
this.legendHitBoxes[i].top = cursor.y;
// Fill the actual label
ctx.fillText(label, this.options.labels.boxWidth + (this.options.labels.fontSize / 2) + cursor.x, cursor.y);
ctx.fillText(legendItem.text, this.options.labels.boxWidth + (this.options.labels.fontSize / 2) + cursor.x, cursor.y);
if (dataset.hidden) {
if (legendItem.hidden) {
// Strikethrough the text if hidden
ctx.beginPath();
ctx.lineWidth = 2;