mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
Legend boxes support borderRadius (#8875)
This commit is contained in:
parent
7ee498e412
commit
d6d189c804
@ -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,
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
55
test/fixtures/plugin.legend/borderRadius/legend-border-radius.js
vendored
Normal file
55
test/fixtures/plugin.legend/borderRadius/legend-border-radius.js
vendored
Normal 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
|
||||
}
|
||||
}
|
||||
};
|
||||
BIN
test/fixtures/plugin.legend/borderRadius/legend-border-radius.png
vendored
Normal file
BIN
test/fixtures/plugin.legend/borderRadius/legend-border-radius.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@ -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,
|
||||
|
||||
6
types/index.esm.d.ts
vendored
6
types/index.esm.d.ts
vendored
@ -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
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user