diff --git a/docs/configuration/legend.md b/docs/configuration/legend.md index ece5ceb7037..3144a79495a 100644 --- a/docs/configuration/legend.md +++ b/docs/configuration/legend.md @@ -65,7 +65,8 @@ Namespace: `options.plugins.legend.labels` | `sort` | `function` | `null` | Sorts legend items. Type is : `sort(a: LegendItem, b: LegendItem, data: ChartData): number;`. Receives 3 parameters, two [Legend Items](#legend-item-interface) and the chart data. The return value of the function is a number that indicates the order of the two legend item parameters. The ordering matches the [return value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#description) of `Array.prototype.sort()` | [`pointStyle`](elements.md#point-styles) | [`pointStyle`](elements.md#types) | `'circle'` | If specified, this style of point is used for the legend. Only used if `usePointStyle` is true. | `textAlign` | `string` | `'center'` | Horizontal alignment of the label text. Options are: `'left'`, `'right'` or `'center'`. -| `usePointStyle` | `boolean` | `false` | Label style will match corresponding point style (size is based on the minimum value between boxWidth and font.size). +| `usePointStyle` | `boolean` | `false` | Label style will match corresponding point style (size is based on pointStyleWidth or the minimum value between boxWidth and font.size). +| `pointStyleWidth` | `number` | `null` | If `usePointStyle` is true, the width of the point style used for the legend (only for `circle`, `rect` and `line` point stlye). ## Legend Title Configuration diff --git a/src/helpers/helpers.canvas.js b/src/helpers/helpers.canvas.js index 54ce2cd54f6..98e6705be2f 100644 --- a/src/helpers/helpers.canvas.js +++ b/src/helpers/helpers.canvas.js @@ -127,7 +127,11 @@ export function clearCanvas(canvas, ctx) { } export function drawPoint(ctx, options, x, y) { - let type, xOffset, yOffset, size, cornerRadius; + drawPointLegend(ctx, options, x, y, null); +} + +export function drawPointLegend(ctx, options, x, y, w) { + let type, xOffset, yOffset, size, cornerRadius, width; const style = options.pointStyle; const rotation = options.rotation; const radius = options.radius; @@ -154,7 +158,11 @@ export function drawPoint(ctx, options, x, y) { switch (style) { // Default includes circle default: - ctx.arc(x, y, radius, 0, TAU); + if (w) { + ctx.ellipse(x, y, w / 2, radius, 0, 0, TAU); + } else { + ctx.arc(x, y, radius, 0, TAU); + } ctx.closePath(); break; case 'triangle': @@ -186,7 +194,8 @@ export function drawPoint(ctx, options, x, y) { case 'rect': if (!rotation) { size = Math.SQRT1_2 * radius; - ctx.rect(x - size, y - size, 2 * size, 2 * size); + width = w ? w / 2 : size; + ctx.rect(x - width, y - size, 2 * width, 2 * size); break; } rad += QUARTER_PI; @@ -227,7 +236,7 @@ export function drawPoint(ctx, options, x, y) { ctx.lineTo(x - yOffset, y + xOffset); break; case 'line': - xOffset = Math.cos(rad) * radius; + xOffset = w ? w / 2 : Math.cos(rad) * radius; yOffset = Math.sin(rad) * radius; ctx.moveTo(x - xOffset, y - yOffset); ctx.lineTo(x + xOffset, y + yOffset); diff --git a/src/plugins/plugin.legend.js b/src/plugins/plugin.legend.js index 02fa12ae1a8..7c67cb52def 100644 --- a/src/plugins/plugin.legend.js +++ b/src/plugins/plugin.legend.js @@ -1,7 +1,7 @@ import defaults from '../core/core.defaults'; import Element from '../core/core.element'; import layouts from '../core/core.layouts'; -import {addRoundedRectPath, drawPoint, renderText} from '../helpers/helpers.canvas'; +import {addRoundedRectPath, drawPointLegend, renderText} from '../helpers/helpers.canvas'; import { callback as call, valueOrDefault, toFont, toPadding, getRtlAdapter, overrideTextDirection, restoreTextDirection, @@ -18,7 +18,7 @@ const getBoxSize = (labelOpts, fontSize) => { if (labelOpts.usePointStyle) { boxHeight = Math.min(boxHeight, fontSize); - boxWidth = Math.min(boxWidth, fontSize); + boxWidth = labelOpts.pointStyleWidth || Math.min(boxWidth, fontSize); } return { @@ -316,7 +316,7 @@ export class Legend extends Element { // Recalculate x and y for drawPoint() because its expecting // x and y to be center of figure (instead of top left) const drawOptions = { - radius: boxWidth * Math.SQRT2 / 2, + radius: boxHeight * Math.SQRT2 / 2, pointStyle: legendItem.pointStyle, rotation: legendItem.rotation, borderWidth: lineWidth @@ -325,7 +325,7 @@ export class Legend extends Element { const centerY = y + halfFontSize; // Draw pointStyle as legend symbol - drawPoint(ctx, drawOptions, centerX, centerY); + drawPointLegend(ctx, drawOptions, centerX, centerY, boxWidth); } else { // Draw box as legend symbol // Adjust position when boxHeight < fontSize (want it centered) diff --git a/types/helpers/helpers.canvas.d.ts b/types/helpers/helpers.canvas.d.ts index 44e570e653e..e6961af9355 100644 --- a/types/helpers/helpers.canvas.d.ts +++ b/types/helpers/helpers.canvas.d.ts @@ -18,6 +18,8 @@ export interface DrawPointOptions { export function drawPoint(ctx: CanvasRenderingContext2D, options: DrawPointOptions, x: number, y: number): void; +export function drawPointLegend(ctx: CanvasRenderingContext2D, options: DrawPointOptions, x: number, y: number, w: number): void; + /** * Converts the given font object into a CSS font string. * @param font a font object