Legend boxes support borderRadius (#8875)

This commit is contained in:
Evert Timberg 2021-04-10 15:05:34 -04:00 committed by GitHub
parent 7ee498e412
commit d6d189c804
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 106 additions and 3 deletions

View File

@ -84,6 +84,10 @@ Items passed to the legend `onClick` function are the ones returned from `labels
// Label that will be displayed
text: string,
// Border radius of the legend item.
// Introduced in 3.1.0
borderRadius?: number | BorderRadius,
// Index of the associated dataset
datasetIndex: number,

View File

@ -1,13 +1,14 @@
import defaults from '../core/core.defaults';
import Element from '../core/core.element';
import layouts from '../core/core.layouts';
import {drawPoint, renderText} from '../helpers/helpers.canvas';
import {addRoundedRectPath, drawPoint, renderText} from '../helpers/helpers.canvas';
import {
callback as call, valueOrDefault, toFont,
toPadding, getRtlAdapter, overrideTextDirection, restoreTextDirection,
clipArea, unclipArea
} from '../helpers/index';
import {_toLeftRightCenter, _alignStartEnd, _textX} from '../helpers/helpers.extras';
import {toTRBLCorners} from '../helpers/helpers.options';
/**
* @typedef { import("../platform/platform.base").ChartEvent } ChartEvent
*/
@ -341,10 +342,26 @@ export class Legend extends Element {
// Draw box as legend symbol
// Adjust position when boxHeight < fontSize (want it centered)
const yBoxTop = y + Math.max((fontSize - boxHeight) / 2, 0);
const xBoxLeft = rtlHelper.leftForLtr(x, boxWidth);
const borderRadius = toTRBLCorners(legendItem.borderRadius);
ctx.fillRect(rtlHelper.leftForLtr(x, boxWidth), yBoxTop, boxWidth, boxHeight);
ctx.beginPath();
if (Object.values(borderRadius).some(v => v !== 0)) {
addRoundedRectPath(ctx, {
x: xBoxLeft,
y: yBoxTop,
w: boxWidth,
h: boxHeight,
radius: borderRadius,
});
} else {
ctx.rect(xBoxLeft, yBoxTop, boxWidth, boxHeight);
}
ctx.fill();
if (lineWidth !== 0) {
ctx.strokeRect(rtlHelper.leftForLtr(x, boxWidth), yBoxTop, boxWidth, boxHeight);
ctx.stroke();
}
}
@ -653,6 +670,7 @@ export default {
pointStyle: pointStyle || style.pointStyle,
rotation: style.rotation,
textAlign: textAlign || style.textAlign,
borderRadius: 0, // TODO: v4, default to style.borderRadius
// Below is extra data used for toggling the datasets
datasetIndex: meta.index

View File

@ -0,0 +1,55 @@
module.exports = {
config: {
type: 'line',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [
{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1,
borderColor: '#FF0000',
backgroundColor: '#00FF00',
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 2,
borderColor: '#FF00FF',
backgroundColor: '#0000FF',
}
]
},
options: {
scales: {
x: {display: false},
y: {display: false}
},
plugins: {
title: false,
tooltip: false,
filler: false,
legend: {
labels: {
generateLabels: (chart) => {
const items = Chart.defaults.plugins.legend.labels.generateLabels(chart);
for (const item of items) {
item.borderRadius = 5;
}
return items;
}
}
}
}
}
},
options: {
spriteText: true,
canvas: {
width: 512,
height: 256
}
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -61,6 +61,7 @@ describe('Legend block tests', function() {
expect(chart.legend.legendItems).toEqual([{
text: 'dataset1',
borderRadius: 0,
fillStyle: '#f31',
fontColor: '#666',
hidden: false,
@ -76,6 +77,7 @@ describe('Legend block tests', function() {
datasetIndex: 0
}, {
text: 'dataset2',
borderRadius: 0,
fillStyle: 'rgba(0,0,0,0.1)',
fontColor: '#666',
hidden: true,
@ -91,6 +93,7 @@ describe('Legend block tests', function() {
datasetIndex: 1
}, {
text: 'dataset3',
borderRadius: 0,
fillStyle: 'rgba(0,0,0,0.1)',
fontColor: '#666',
hidden: false,
@ -137,6 +140,7 @@ describe('Legend block tests', function() {
expect(chart.legend.legendItems).toEqual([{
text: 'dataset1',
borderRadius: 0,
fillStyle: '#f31',
fontColor: '#666',
hidden: false,
@ -152,6 +156,7 @@ describe('Legend block tests', function() {
datasetIndex: 0
}, {
text: 'dataset2',
borderRadius: 0,
fillStyle: 'rgba(0,0,0,0.1)',
fontColor: '#666',
hidden: true,
@ -167,6 +172,7 @@ describe('Legend block tests', function() {
datasetIndex: 1
}, {
text: 'dataset3',
borderRadius: 0,
fillStyle: 'rgba(0,0,0,0.1)',
fontColor: '#666',
hidden: false,
@ -220,6 +226,7 @@ describe('Legend block tests', function() {
expect(chart.legend.legendItems).toEqual([{
text: 'dataset3',
borderRadius: 0,
fillStyle: 'rgba(0,0,0,0.1)',
fontColor: '#666',
hidden: false,
@ -235,6 +242,7 @@ describe('Legend block tests', function() {
datasetIndex: 2
}, {
text: 'dataset2',
borderRadius: 0,
fillStyle: 'rgba(0,0,0,0.1)',
fontColor: '#666',
hidden: true,
@ -250,6 +258,7 @@ describe('Legend block tests', function() {
datasetIndex: 1
}, {
text: 'dataset1',
borderRadius: 0,
fillStyle: '#f31',
fontColor: '#666',
hidden: false,
@ -308,6 +317,7 @@ describe('Legend block tests', function() {
expect(chart.legend.legendItems).toEqual([{
text: 'dataset1',
borderRadius: 0,
fillStyle: '#f31',
fontColor: '#666',
hidden: false,
@ -323,6 +333,7 @@ describe('Legend block tests', function() {
datasetIndex: 0
}, {
text: 'dataset3',
borderRadius: 0,
fillStyle: 'rgba(0,0,0,0.1)',
fontColor: '#666',
hidden: false,
@ -380,6 +391,7 @@ describe('Legend block tests', function() {
expect(chart.legend.legendItems).toEqual([{
text: 'dataset3',
borderRadius: 0,
fillStyle: 'rgba(0,0,0,0.1)',
fontColor: '#666',
hidden: false,
@ -395,6 +407,7 @@ describe('Legend block tests', function() {
datasetIndex: 2
}, {
text: 'dataset2',
borderRadius: 0,
fillStyle: 'rgba(0,0,0,0.1)',
fontColor: '#666',
hidden: true,
@ -410,6 +423,7 @@ describe('Legend block tests', function() {
datasetIndex: 1
}, {
text: 'dataset1',
borderRadius: 0,
fillStyle: '#f31',
fontColor: '#666',
hidden: false,
@ -542,6 +556,7 @@ describe('Legend block tests', function() {
expect(chart.legend.legendItems).toEqual([{
text: 'dataset1',
borderRadius: 0,
fillStyle: '#f31',
fontColor: '#666',
hidden: false,
@ -585,6 +600,7 @@ describe('Legend block tests', function() {
expect(chart.legend.legendItems).toEqual([{
text: 'dataset1',
borderRadius: 0,
fillStyle: 'rgb(50, 0, 0)',
fontColor: '#666',
hidden: false,
@ -643,6 +659,7 @@ describe('Legend block tests', function() {
expect(chart.legend.legendItems).toEqual([{
text: 'dataset1',
borderRadius: 0,
fillStyle: 'rgba(0,0,0,0.1)',
fontColor: '#666',
hidden: false,
@ -658,6 +675,7 @@ describe('Legend block tests', function() {
datasetIndex: 0
}, {
text: 'dataset2',
borderRadius: 0,
fillStyle: '#f31',
fontColor: '#666',
hidden: false,
@ -717,6 +735,7 @@ describe('Legend block tests', function() {
expect(chart.legend.legendItems).toEqual([{
text: 'dataset1',
borderRadius: 0,
fillStyle: 'rgba(0,0,0,0.1)',
fontColor: '#666',
hidden: false,
@ -732,6 +751,7 @@ describe('Legend block tests', function() {
datasetIndex: 0
}, {
text: 'dataset2',
borderRadius: 0,
fillStyle: '#f31',
fontColor: '#666',
hidden: false,

View File

@ -2009,6 +2009,12 @@ export interface LegendItem {
*/
text: string;
/**
* Border radius of the legend box
* @since 3.1.0
*/
borderRadius?: number | BorderRadius;
/**
* Index of the associated dataset
*/