Implement legend.align: 'start', 'center', 'end' (#6141)

New `options.legend.align`config option for controlling alignment of legend blocks in horizontal/vertical legends.
This commit is contained in:
Dave Kichler 2019-03-23 02:25:17 -07:00 committed by Simon Brunel
parent b9290a20de
commit 07fae6159e
39 changed files with 491 additions and 367 deletions

View File

@ -9,6 +9,7 @@ The legend configuration is passed into the `options.legend` namespace. The glob
| ---- | ---- | ------- | -----------
| `display` | `boolean` | `true` | Is the legend shown?
| `position` | `string` | `'top'` | Position of the legend. [more...](#position)
| `align` | `string` | `'center'` | Alignment of the legend. [more...](#align)
| `fullWidth` | `boolean` | `true` | Marks that this box should take the full width of the canvas (pushing down other boxes). This is unlikely to need to be changed in day-to-day use.
| `onClick` | `function` | | A callback that is called when a click event is registered on a label item.
| `onHover` | `function` | | A callback that is called when a 'mousemove' event is registered on top of a label item.
@ -23,6 +24,14 @@ Position of the legend. Options are:
* `'bottom'`
* `'right'`
## Align
Alignment of the legend. Options are:
* `'start'`
* `'center'`
* `'end'`
Defaults to `'center'` for unrecognized values.
## Legend Label Configuration
The legend label configuration is nested below the legend configuration using the `labels` key.

View File

@ -12,6 +12,7 @@ defaults._set('global', {
legend: {
display: true,
position: 'top',
align: 'center',
fullWidth: true,
reverse: false,
weight: 1000,
@ -102,18 +103,19 @@ function getBoxWidth(labelOpts, fontSize) {
var Legend = Element.extend({
initialize: function(config) {
helpers.extend(this, config);
var me = this;
helpers.extend(me, config);
// Contains hit boxes for each dataset (in dataset order)
this.legendHitBoxes = [];
me.legendHitBoxes = [];
/**
* @private
*/
this._hoveredItem = null;
me._hoveredItem = null;
// Are we in doughnut mode which has a different data type
this.doughnutMode = false;
me.doughnutMode = false;
},
// These methods are ordered by lifecycle. Utilities then follow.
@ -253,9 +255,9 @@ var Legend = Element.extend({
var boxWidth = getBoxWidth(labelOpts, fontSize);
var width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
if (i === 0 || lineWidths[lineWidths.length - 1] + width + labelOpts.padding > minSize.width) {
if (i === 0 || lineWidths[lineWidths.length - 1] + width + 2 * labelOpts.padding > minSize.width) {
totalHeight += fontSize + labelOpts.padding;
lineWidths[lineWidths.length - (i > 0 ? 0 : 1)] = labelOpts.padding;
lineWidths[lineWidths.length - (i > 0 ? 0 : 1)] = 0;
}
// Store the hitbox width and height here. Final position will be updated in `draw`
@ -274,27 +276,27 @@ var Legend = Element.extend({
} else {
var vPadding = labelOpts.padding;
var columnWidths = me.columnWidths = [];
var columnHeights = me.columnHeights = [];
var totalWidth = labelOpts.padding;
var currentColWidth = 0;
var currentColHeight = 0;
var itemHeight = fontSize + vPadding;
helpers.each(me.legendItems, function(legendItem, i) {
var boxWidth = getBoxWidth(labelOpts, fontSize);
var itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
// If too tall, go to new column
if (i > 0 && currentColHeight + itemHeight > minSize.height - vPadding) {
if (i > 0 && currentColHeight + fontSize + 2 * vPadding > minSize.height) {
totalWidth += currentColWidth + labelOpts.padding;
columnWidths.push(currentColWidth); // previous column width
columnHeights.push(currentColHeight);
currentColWidth = 0;
currentColHeight = 0;
}
// Get max width
currentColWidth = Math.max(currentColWidth, itemWidth);
currentColHeight += itemHeight;
currentColHeight += fontSize + vPadding;
// Store the hitbox width and height here. Final position will be updated in `draw`
hitboxes[i] = {
@ -307,6 +309,7 @@ var Legend = Element.extend({
totalWidth += currentColWidth;
columnWidths.push(currentColWidth);
columnHeights.push(currentColHeight);
minSize.width += totalWidth;
}
}
@ -329,6 +332,8 @@ var Legend = Element.extend({
var globalDefaults = defaults.global;
var defaultColor = globalDefaults.defaultColor;
var lineDefault = globalDefaults.elements.line;
var legendHeight = me.height;
var columnHeights = me.columnHeights;
var legendWidth = me.width;
var lineWidths = me.lineWidths;
@ -408,18 +413,29 @@ var Legend = Element.extend({
}
};
var alignmentOffset = function(dimension, blockSize) {
switch (opts.align) {
case 'start':
return labelOpts.padding;
case 'end':
return dimension - blockSize;
default: // center
return (dimension - blockSize + labelOpts.padding) / 2;
}
};
// Horizontal
var isHorizontal = me.isHorizontal();
if (isHorizontal) {
cursor = {
x: me.left + ((legendWidth - lineWidths[0]) / 2) + labelOpts.padding,
x: me.left + alignmentOffset(legendWidth, lineWidths[0]),
y: me.top + labelOpts.padding,
line: 0
};
} else {
cursor = {
x: me.left + labelOpts.padding,
y: me.top + labelOpts.padding,
y: me.top + alignmentOffset(legendHeight, columnHeights[0]),
line: 0
};
}
@ -438,12 +454,12 @@ var Legend = Element.extend({
if (i > 0 && x + width + labelOpts.padding > me.left + me.minSize.width) {
y = cursor.y += itemHeight;
cursor.line++;
x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2) + labelOpts.padding;
x = cursor.x = me.left + alignmentOffset(legendWidth, lineWidths[cursor.line]);
}
} else if (i > 0 && y + itemHeight > me.top + me.minSize.height) {
x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;
y = cursor.y = me.top + labelOpts.padding;
cursor.line++;
y = cursor.y = me.top + alignmentOffset(legendHeight, columnHeights[cursor.line]);
}
drawLegendBox(x, y, legendItem);
@ -459,7 +475,6 @@ var Legend = Element.extend({
} else {
cursor.y += itemHeight;
}
});
}
},

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
"datasets": [{
"data": [10, 20, 30, 40, 50, 60, 70, 10, 20, 30, 40, 50, 60, 70, 10, 20, 30, 20, 10],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "bottom",
"align": "center"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": [""],
"datasets": [{
"data": [10],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "bottom",
"align": "center"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
"datasets": [{
"data": [10, 20, 30, 40, 50, 60, 70, 10, 20, 30, 40, 50, 60, 70, 10],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "bottom",
"align": "end"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
"datasets": [{
"data": [10, 20, 30, 40, 50, 60, 70, 10, 20, 30, 40, 50, 60, 70, 10],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "bottom",
"align": "start"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
"datasets": [{
"data": [10, 20, 30, 40, 50, 60, 70, 10, 20, 30, 40, 50, 60, 70, 10, 20, 30],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "left",
"align": "center"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": [""],
"datasets": [{
"data": [10],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "left",
"align": "center"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -0,0 +1,24 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": ["", "", "", "", "", ""],
"datasets": [{
"data": [10, 20, 30, 40, 50],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "left"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
"datasets": [{
"data": [10, 20, 30, 40, 50, 60, 70, 10, 20, 30, 40, 50, 60, 70, 10, 20, 30],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "left",
"align": "end"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
"datasets": [{
"data": [10, 20, 30, 40, 50, 60, 70, 10, 20, 30, 40, 50, 60, 70, 10, 20, 30],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "left",
"align": "start"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
"datasets": [{
"data": [10, 20, 30, 40, 50, 60, 70, 10, 20, 30, 40, 50, 60, 70, 10, 20, 30],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "right",
"align": "center"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": [""],
"datasets": [{
"data": [10],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "right",
"align": "center"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,24 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": ["", "", "", "", "", ""],
"datasets": [{
"data": [10, 20, 30, 40, 50],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "right"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
"datasets": [{
"data": [10, 20, 30, 40, 50, 60, 70, 10, 20, 30, 40, 50, 60, 70, 10, 20, 30],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "right",
"align": "end"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
"datasets": [{
"data": [10, 20, 30, 40, 50, 60, 70, 10, 20, 30, 40, 50, 60, 70, 10, 20, 30],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "right",
"align": "start"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
"datasets": [{
"data": [10, 20, 30, 40, 50, 60, 70, 10, 20, 30, 40, 50, 60, 70, 10, 20, 30, 20, 10],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "top",
"align": "center"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": [""],
"datasets": [{
"data": [10],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "top",
"align": "center"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
"datasets": [{
"data": [10, 20, 30, 40, 50, 60, 70, 10, 20, 30, 40, 50, 60, 70, 10],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "top",
"align": "end"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,25 @@
{
"config": {
"type": "doughnut",
"data": {
"labels": ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
"datasets": [{
"data": [10, 20, 30, 40, 50, 60, 70, 10, 20, 30, 40, 50, 60, 70, 10],
"backgroundColor": "#00ff00",
"borderWidth": 0
}]
},
"options": {
"legend": {
"position": "top",
"align": "start"
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,9 +1,12 @@
// Test the rectangle element
describe('Legend block tests', function() {
describe('auto', jasmine.fixture.specs('plugin.legend'));
it('should have the correct default config', function() {
expect(Chart.defaults.global.legend).toEqual({
display: true,
position: 'top',
align: 'center',
fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
reverse: false,
weight: 1000,
@ -177,358 +180,6 @@ describe('Legend block tests', function() {
expect(makeChart).not.toThrow();
});
it('should draw correctly when the legend is positioned on the top', function() {
var chart = window.acquireChart({
type: 'bar',
data: {
datasets: [{
label: 'dataset1',
backgroundColor: '#f31',
borderCapStyle: 'butt',
borderDash: [2, 2],
borderDashOffset: 5.5,
data: []
}, {
label: 'dataset2',
hidden: true,
borderJoinStyle: 'miter',
data: []
}, {
label: 'dataset3',
borderWidth: 10,
borderColor: 'green',
data: []
}],
labels: []
}
});
expect(chart.legend.legendHitBoxes.length).toBe(3);
[
{h: 12, l: 106, t: 10, w: 93},
{h: 12, l: 209, t: 10, w: 93},
{h: 12, l: 312, t: 10, w: 93}
].forEach(function(expected, i) {
expect(chart.legend.legendHitBoxes[i].height).toBeCloseToPixel(expected.h);
expect(chart.legend.legendHitBoxes[i].left).toBeCloseToPixel(expected.l);
expect(chart.legend.legendHitBoxes[i].top).toBeCloseToPixel(expected.t);
expect(chart.legend.legendHitBoxes[i].width).toBeCloseToPixel(expected.w);
});
// NOTE(SB) We should get ride of the following tests and use image diff instead.
// For now, as discussed with Evert Timberg, simply comment out.
// See https://humblesoftware.github.io/js-imagediff/test.html
/* chart.legend.ctx = window.createMockContext();
chart.update();
expect(chart.legend.ctx .getCalls()).toEqual([{
"name": "measureText",
"args": ["dataset1"]
}, {
"name": "measureText",
"args": ["dataset2"]
}, {
"name": "measureText",
"args": ["dataset3"]
}, {
"name": "measureText",
"args": ["dataset1"]
}, {
"name": "measureText",
"args": ["dataset2"]
}, {
"name": "measureText",
"args": ["dataset3"]
}, {
"name": "setLineWidth",
"args": [0.5]
}, {
"name": "setStrokeStyle",
"args": ["#666"]
}, {
"name": "setFillStyle",
"args": ["#666"]
}, {
"name": "measureText",
"args": ["dataset1"]
}, {
"name": "save",
"args": []
}, {
"name": "setFillStyle",
"args": ["#f31"]
}, {
"name": "setLineCap",
"args": ["butt"]
}, {
"name": "setLineDashOffset",
"args": [5.5]
}, {
"name": "setLineJoin",
"args": ["miter"]
}, {
"name": "setLineWidth",
"args": [3]
}, {
"name": "setStrokeStyle",
"args": ["rgba(0,0,0,0.1)"]
}, {
"name": "setLineDash",
"args": [
[2, 2]
]
}, {
"name": "strokeRect",
"args": [114, 110, 40, 12]
}, {
"name": "fillRect",
"args": [114, 110, 40, 12]
}, {
"name": "restore",
"args": []
}, {
"name": "fillText",
"args": ["dataset1", 160, 110]
}, {
"name": "measureText",
"args": ["dataset2"]
}, {
"name": "save",
"args": []
}, {
"name": "setFillStyle",
"args": ["rgba(0,0,0,0.1)"]
}, {
"name": "setLineCap",
"args": ["butt"]
}, {
"name": "setLineDashOffset",
"args": [0]
}, {
"name": "setLineJoin",
"args": ["miter"]
}, {
"name": "setLineWidth",
"args": [3]
}, {
"name": "setStrokeStyle",
"args": ["rgba(0,0,0,0.1)"]
}, {
"name": "setLineDash",
"args": [
[]
]
}, {
"name": "strokeRect",
"args": [250, 110, 40, 12]
}, {
"name": "fillRect",
"args": [250, 110, 40, 12]
}, {
"name": "restore",
"args": []
}, {
"name": "fillText",
"args": ["dataset2", 296, 110]
}, {
"name": "beginPath",
"args": []
}, {
"name": "setLineWidth",
"args": [2]
}, {
"name": "moveTo",
"args": [296, 116]
}, {
"name": "lineTo",
"args": [376, 116]
}, {
"name": "stroke",
"args": []
}, {
"name": "measureText",
"args": ["dataset3"]
}, {
"name": "save",
"args": []
}, {
"name": "setFillStyle",
"args": ["rgba(0,0,0,0.1)"]
}, {
"name": "setLineCap",
"args": ["butt"]
}, {
"name": "setLineDashOffset",
"args": [0]
}, {
"name": "setLineJoin",
"args": ["miter"]
}, {
"name": "setLineWidth",
"args": [10]
}, {
"name": "setStrokeStyle",
"args": ["green"]
}, {
"name": "setLineDash",
"args": [
[]
]
}, {
"name": "strokeRect",
"args": [182, 132, 40, 12]
}, {
"name": "fillRect",
"args": [182, 132, 40, 12]
}, {
"name": "restore",
"args": []
}, {
"name": "fillText",
"args": ["dataset3", 228, 132]
}]);*/
});
it('should draw correctly when the legend is positioned on the left', function() {
var chart = window.acquireChart({
type: 'bar',
data: {
datasets: [{
label: 'dataset1',
backgroundColor: '#f31',
borderCapStyle: 'butt',
borderDash: [2, 2],
borderDashOffset: 5.5,
data: []
}, {
label: 'dataset2',
hidden: true,
borderJoinStyle: 'miter',
data: []
}, {
label: 'dataset3',
borderWidth: 10,
borderColor: 'green',
data: []
}],
labels: []
},
options: {
legend: {
position: 'left'
}
}
});
expect(chart.legend.legendHitBoxes.length).toBe(3);
[
{h: 12, l: 10, t: 16, w: 93},
{h: 12, l: 10, t: 38, w: 93},
{h: 12, l: 10, t: 60, w: 93}
].forEach(function(expected, i) {
expect(chart.legend.legendHitBoxes[i].height).toBeCloseToPixel(expected.h);
expect(chart.legend.legendHitBoxes[i].left).toBeCloseToPixel(expected.l);
expect(chart.legend.legendHitBoxes[i].top).toBeCloseToPixel(expected.t);
expect(chart.legend.legendHitBoxes[i].width).toBeCloseToPixel(expected.w);
});
});
it('should draw correctly when the legend is positioned on the top and has multiple rows', function() {
var chart = window.acquireChart({
type: 'bar',
data: {
datasets: Array.apply(null, Array(9)).map(function() {
return {
label: ' ',
data: []
};
}),
labels: []
}
});
expect(chart.legend.left).toBeCloseToPixel(0);
expect(chart.legend.top).toBeCloseToPixel(0);
expect(chart.legend.width).toBeCloseToPixel(512);
expect(chart.legend.height).toBeCloseToPixel(54);
expect(chart.legend.legendHitBoxes.length).toBe(9);
[
{h: 12, l: 24, t: 10, w: 49},
{h: 12, l: 83, t: 10, w: 49},
{h: 12, l: 142, t: 10, w: 49},
{h: 12, l: 202, t: 10, w: 49},
{h: 12, l: 261, t: 10, w: 49},
{h: 12, l: 320, t: 10, w: 49},
{h: 12, l: 380, t: 10, w: 49},
{h: 12, l: 439, t: 10, w: 49},
{h: 12, l: 231, t: 32, w: 49}
].forEach(function(expected, i) {
expect(chart.legend.legendHitBoxes[i].height).toBeCloseToPixel(expected.h);
expect(chart.legend.legendHitBoxes[i].left).toBeCloseToPixel(expected.l);
expect(chart.legend.legendHitBoxes[i].top).toBeCloseToPixel(expected.t);
expect(chart.legend.legendHitBoxes[i].width).toBeCloseToPixel(expected.w);
});
});
it('should draw correctly when the legend is positioned on the left and has multiple columns', function() {
var chart = window.acquireChart({
type: 'bar',
data: {
datasets: Array.apply(null, Array(22)).map(function() {
return {
label: ' ',
data: []
};
}),
labels: []
},
options: {
legend: {
position: 'left'
}
}
});
expect(chart.legend.left).toBeCloseToPixel(0);
expect(chart.legend.top).toBeCloseToPixel(6);
expect(chart.legend.width).toBeCloseToPixel(128);
expect(chart.legend.height).toBeCloseToPixel(476);
expect(chart.legend.legendHitBoxes.length).toBe(22);
[
{h: 12, l: 10, t: 16, w: 49},
{h: 12, l: 10, t: 38, w: 49},
{h: 12, l: 10, t: 60, w: 49},
{h: 12, l: 10, t: 82, w: 49},
{h: 12, l: 10, t: 104, w: 49},
{h: 12, l: 10, t: 126, w: 49},
{h: 12, l: 10, t: 148, w: 49},
{h: 12, l: 10, t: 170, w: 49},
{h: 12, l: 10, t: 192, w: 49},
{h: 12, l: 10, t: 214, w: 49},
{h: 12, l: 10, t: 236, w: 49},
{h: 12, l: 10, t: 258, w: 49},
{h: 12, l: 10, t: 280, w: 49},
{h: 12, l: 10, t: 302, w: 49},
{h: 12, l: 10, t: 324, w: 49},
{h: 12, l: 10, t: 346, w: 49},
{h: 12, l: 10, t: 368, w: 49},
{h: 12, l: 10, t: 390, w: 49},
{h: 12, l: 10, t: 412, w: 49},
{h: 12, l: 10, t: 434, w: 49},
{h: 12, l: 10, t: 456, w: 49},
{h: 12, l: 69, t: 16, w: 49}
].forEach(function(expected, i) {
expect(chart.legend.legendHitBoxes[i].height).toBeCloseToPixel(expected.h);
expect(chart.legend.legendHitBoxes[i].left).toBeCloseToPixel(expected.l);
expect(chart.legend.legendHitBoxes[i].top).toBeCloseToPixel(expected.t);
expect(chart.legend.legendHitBoxes[i].width).toBeCloseToPixel(expected.w);
});
});
it('should not draw legend items outside of the chart bounds', function() {
var chart = window.acquireChart(
{
@ -704,3 +355,4 @@ describe('Legend block tests', function() {
});
});
});