]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Implement legend.align: 'start', 'center', 'end' (#6141)
authorDave Kichler <dkichler@gmail.com>
Sat, 23 Mar 2019 09:25:17 +0000 (02:25 -0700)
committerSimon Brunel <simonbrunel@users.noreply.github.com>
Sat, 23 Mar 2019 09:25:17 +0000 (10:25 +0100)
New `options.legend.align`config option for controlling alignment of legend blocks in horizontal/vertical legends.

39 files changed:
docs/configuration/legend.md
src/plugins/plugin.legend.js
test/fixtures/plugin.legend/legend-doughnut-bottom-center-mulitiline.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-bottom-center-mulitiline.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-bottom-center-single.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-bottom-center-single.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-bottom-end-mulitiline.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-bottom-end-mulitiline.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-bottom-start-mulitiline.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-bottom-start-mulitiline.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-left-center-mulitiline.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-left-center-mulitiline.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-left-center-single.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-left-center-single.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-left-default-center.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-left-default-center.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-left-end-mulitiline.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-left-end-mulitiline.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-left-start-mulitiline.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-left-start-mulitiline.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-right-center-mulitiline.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-right-center-mulitiline.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-right-center-single.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-right-center-single.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-right-default-center.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-right-default-center.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-right-end-mulitiline.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-right-end-mulitiline.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-right-start-mulitiline.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-right-start-mulitiline.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-top-center-mulitiline.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-top-center-mulitiline.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-top-center-single.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-top-center-single.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-top-end-mulitiline.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-top-end-mulitiline.png [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-top-start-mulitiline.json [new file with mode: 0644]
test/fixtures/plugin.legend/legend-doughnut-top-start-mulitiline.png [new file with mode: 0644]
test/specs/plugin.legend.tests.js

index c7d124868edd6790aa9f195cc147b6c1373604a4..f8ce7eb5a1788755d81e3cfece2dd0e1f27e84d0 100644 (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.
index 2c6870b279d722d0e4c2561b441bd082f40cd7ee..d3fd5e35f0491a83c23eeb1c2dd4211b24a2fcb8 100644 (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;
                                }
-
                        });
                }
        },
diff --git a/test/fixtures/plugin.legend/legend-doughnut-bottom-center-mulitiline.json b/test/fixtures/plugin.legend/legend-doughnut-bottom-center-mulitiline.json
new file mode 100644 (file)
index 0000000..22837c7
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-bottom-center-mulitiline.png b/test/fixtures/plugin.legend/legend-doughnut-bottom-center-mulitiline.png
new file mode 100644 (file)
index 0000000..bad5076
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-bottom-center-mulitiline.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-bottom-center-single.json b/test/fixtures/plugin.legend/legend-doughnut-bottom-center-single.json
new file mode 100644 (file)
index 0000000..82e462f
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-bottom-center-single.png b/test/fixtures/plugin.legend/legend-doughnut-bottom-center-single.png
new file mode 100644 (file)
index 0000000..139a16b
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-bottom-center-single.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-bottom-end-mulitiline.json b/test/fixtures/plugin.legend/legend-doughnut-bottom-end-mulitiline.json
new file mode 100644 (file)
index 0000000..630b81e
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-bottom-end-mulitiline.png b/test/fixtures/plugin.legend/legend-doughnut-bottom-end-mulitiline.png
new file mode 100644 (file)
index 0000000..e7fc84b
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-bottom-end-mulitiline.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-bottom-start-mulitiline.json b/test/fixtures/plugin.legend/legend-doughnut-bottom-start-mulitiline.json
new file mode 100644 (file)
index 0000000..4544602
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-bottom-start-mulitiline.png b/test/fixtures/plugin.legend/legend-doughnut-bottom-start-mulitiline.png
new file mode 100644 (file)
index 0000000..32700c1
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-bottom-start-mulitiline.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-left-center-mulitiline.json b/test/fixtures/plugin.legend/legend-doughnut-left-center-mulitiline.json
new file mode 100644 (file)
index 0000000..6665193
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-left-center-mulitiline.png b/test/fixtures/plugin.legend/legend-doughnut-left-center-mulitiline.png
new file mode 100644 (file)
index 0000000..5160e35
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-left-center-mulitiline.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-left-center-single.json b/test/fixtures/plugin.legend/legend-doughnut-left-center-single.json
new file mode 100644 (file)
index 0000000..4723a86
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-left-center-single.png b/test/fixtures/plugin.legend/legend-doughnut-left-center-single.png
new file mode 100644 (file)
index 0000000..72072bf
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-left-center-single.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-left-default-center.json b/test/fixtures/plugin.legend/legend-doughnut-left-default-center.json
new file mode 100644 (file)
index 0000000..bb48a27
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-left-default-center.png b/test/fixtures/plugin.legend/legend-doughnut-left-default-center.png
new file mode 100644 (file)
index 0000000..3d98298
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-left-default-center.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-left-end-mulitiline.json b/test/fixtures/plugin.legend/legend-doughnut-left-end-mulitiline.json
new file mode 100644 (file)
index 0000000..662b167
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-left-end-mulitiline.png b/test/fixtures/plugin.legend/legend-doughnut-left-end-mulitiline.png
new file mode 100644 (file)
index 0000000..46c6014
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-left-end-mulitiline.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-left-start-mulitiline.json b/test/fixtures/plugin.legend/legend-doughnut-left-start-mulitiline.json
new file mode 100644 (file)
index 0000000..1d4dc1f
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-left-start-mulitiline.png b/test/fixtures/plugin.legend/legend-doughnut-left-start-mulitiline.png
new file mode 100644 (file)
index 0000000..91c0c31
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-left-start-mulitiline.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-right-center-mulitiline.json b/test/fixtures/plugin.legend/legend-doughnut-right-center-mulitiline.json
new file mode 100644 (file)
index 0000000..5131989
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-right-center-mulitiline.png b/test/fixtures/plugin.legend/legend-doughnut-right-center-mulitiline.png
new file mode 100644 (file)
index 0000000..72cbe90
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-right-center-mulitiline.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-right-center-single.json b/test/fixtures/plugin.legend/legend-doughnut-right-center-single.json
new file mode 100644 (file)
index 0000000..9cb2ecc
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-right-center-single.png b/test/fixtures/plugin.legend/legend-doughnut-right-center-single.png
new file mode 100644 (file)
index 0000000..aa8c104
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-right-center-single.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-right-default-center.json b/test/fixtures/plugin.legend/legend-doughnut-right-default-center.json
new file mode 100644 (file)
index 0000000..8376207
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-right-default-center.png b/test/fixtures/plugin.legend/legend-doughnut-right-default-center.png
new file mode 100644 (file)
index 0000000..1ba7052
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-right-default-center.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-right-end-mulitiline.json b/test/fixtures/plugin.legend/legend-doughnut-right-end-mulitiline.json
new file mode 100644 (file)
index 0000000..183959b
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-right-end-mulitiline.png b/test/fixtures/plugin.legend/legend-doughnut-right-end-mulitiline.png
new file mode 100644 (file)
index 0000000..00e3664
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-right-end-mulitiline.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-right-start-mulitiline.json b/test/fixtures/plugin.legend/legend-doughnut-right-start-mulitiline.json
new file mode 100644 (file)
index 0000000..292ab69
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-right-start-mulitiline.png b/test/fixtures/plugin.legend/legend-doughnut-right-start-mulitiline.png
new file mode 100644 (file)
index 0000000..73c51c0
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-right-start-mulitiline.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-top-center-mulitiline.json b/test/fixtures/plugin.legend/legend-doughnut-top-center-mulitiline.json
new file mode 100644 (file)
index 0000000..8bb57e4
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-top-center-mulitiline.png b/test/fixtures/plugin.legend/legend-doughnut-top-center-mulitiline.png
new file mode 100644 (file)
index 0000000..f3b552a
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-top-center-mulitiline.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-top-center-single.json b/test/fixtures/plugin.legend/legend-doughnut-top-center-single.json
new file mode 100644 (file)
index 0000000..310ad75
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-top-center-single.png b/test/fixtures/plugin.legend/legend-doughnut-top-center-single.png
new file mode 100644 (file)
index 0000000..6aac522
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-top-center-single.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-top-end-mulitiline.json b/test/fixtures/plugin.legend/legend-doughnut-top-end-mulitiline.json
new file mode 100644 (file)
index 0000000..b150ef7
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-top-end-mulitiline.png b/test/fixtures/plugin.legend/legend-doughnut-top-end-mulitiline.png
new file mode 100644 (file)
index 0000000..e6e56e4
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-top-end-mulitiline.png differ
diff --git a/test/fixtures/plugin.legend/legend-doughnut-top-start-mulitiline.json b/test/fixtures/plugin.legend/legend-doughnut-top-start-mulitiline.json
new file mode 100644 (file)
index 0000000..ca21119
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/fixtures/plugin.legend/legend-doughnut-top-start-mulitiline.png b/test/fixtures/plugin.legend/legend-doughnut-top-start-mulitiline.png
new file mode 100644 (file)
index 0000000..2e7e7fe
Binary files /dev/null and b/test/fixtures/plugin.legend/legend-doughnut-top-start-mulitiline.png differ
index e970c596a82a7c75052c7faa2e9e44153223c82d..18829cac04ac38b05f5c400834448157e917fa3b 100644 (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() {
                });
        });
 });
+