Skip to content

Commit

Permalink
Update plugin.legend.js with a new option: 'align'. This allows the l…
Browse files Browse the repository at this point in the history
…egend to be aligned within its layout box.

The legend can be aligned in 3 ways 'start', 'center' (default), or 'end'.
Updated the legend help page to reflect these changes.
Add a number tests to test the new align option
  • Loading branch information
Eric Pattison committed Nov 29, 2018
1 parent f5437fe commit aca1195
Show file tree
Hide file tree
Showing 3 changed files with 342 additions and 11 deletions.
9 changes: 9 additions & 0 deletions docs/configuration/legend.md
Expand Up @@ -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'` | The 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.
Expand All @@ -22,6 +23,14 @@ Position of the legend. Options are:
* `'bottom'`
* `'right'`

## Align
The alignment of the legend.

* `'start'`
* `'center'` (default)
* `'end'`


## Legend Label Configuration

The legend label configuration is nested below the legend configuration using the `labels` key.
Expand Down
45 changes: 40 additions & 5 deletions src/plugins/plugin.legend.js
Expand Up @@ -11,6 +11,7 @@ defaults._set('global', {
legend: {
display: true,
position: 'top',
align: 'center',
fullWidth: true,
reverse: false,
weight: 1000,
Expand Down Expand Up @@ -407,24 +408,41 @@ var Legend = Element.extend({
ctx.stroke();
}
};
var itemHeight = fontSize + labelOpts.padding;

// Horizontal
var isHorizontal = me.isHorizontal();
if (isHorizontal) {
// default to center as this is the original behaviour of just position
var alignedX = me.left + ((legendWidth - lineWidths[0]) / 2);
if (opts.align === 'start') {
alignedX = me.left;
} else if (opts.align === 'end') {
alignedX = ((me.right - lineWidths[0]));
}
cursor = {
x: me.left + ((legendWidth - lineWidths[0]) / 2) + labelOpts.padding,
x: alignedX + labelOpts.padding,
y: me.top + labelOpts.padding,
line: 0
};
} else {
// default to top as this is the original behaviour of just position
var alignedY = me.top;
var maxItemsPerColumn = Math.floor((me.minSize.height - labelOpts.padding) / itemHeight);
var legendHeight = Math.min(me.legendItems.length, maxItemsPerColumn) * itemHeight + labelOpts.padding;
// var legendHeight = (fontSize + labelOpts.padding) * me.legendItems.length;
if (opts.align === 'end') {
alignedY = ((me.bottom - legendHeight));
} else if (opts.align === 'center') {
alignedY = (((me.bottom - legendHeight) / 2));
}
cursor = {
x: me.left + labelOpts.padding,
y: me.top + labelOpts.padding,
y: alignedY + labelOpts.padding,
line: 0
};
}

var itemHeight = fontSize + labelOpts.padding;
helpers.each(me.legendItems, function(legendItem, i) {
var textWidth = ctx.measureText(legendItem.text).width;
var width = boxWidth + (fontSize / 2) + textWidth;
Expand All @@ -438,11 +456,28 @@ 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;
// We must account for the align parameter when resetting the x position
alignedX = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);
if (opts.align === 'start') {
alignedX = me.left;
} else if (opts.align === 'end') {
alignedX = ((me.right - lineWidths[cursor.line]));
}
x = cursor.x = alignedX + labelOpts.padding;
}
} 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;
// We must account for the align parameter when resetting the y position
alignedY = me.top;
maxItemsPerColumn = Math.floor((me.minSize.height - labelOpts.padding) / itemHeight);
legendHeight = Math.min(me.legendItems.length, maxItemsPerColumn) * itemHeight + labelOpts.padding;
// var legendHeight = (fontSize + labelOpts.padding) * me.legendItems.length;
if (opts.align === 'end') {
alignedY = ((me.bottom - legendHeight));
} else if (opts.align === 'center') {
alignedY = (((me.bottom - legendHeight) / 2));
}
y = cursor.y = alignedY + labelOpts.padding;
cursor.line++;
}

Expand Down

0 comments on commit aca1195

Please sign in to comment.