]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Add pointStyleWidth option for legend (#10412)
authorDominic Jean <touletan@hotmail.com>
Mon, 18 Jul 2022 10:49:08 +0000 (06:49 -0400)
committerGitHub <noreply@github.com>
Mon, 18 Jul 2022 10:49:08 +0000 (06:49 -0400)
* add pointStyleWidth for legend

* add drawPointLegend to keep drawPoint signature

docs/configuration/legend.md
src/helpers/helpers.canvas.js
src/plugins/plugin.legend.js
types/helpers/helpers.canvas.d.ts

index ece5ceb7037ab3dddd1adf847c28436bcfaf2563..3144a79495a9e1463d51feacef5772f8dbeb9645 100644 (file)
@@ -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
 
index 54ce2cd54f6a1a39c863fe080d0df978bba16f02..98e6705be2fc27d0a64bf32a9e0ba6585c9387da 100644 (file)
@@ -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);
index 02fa12ae1a87924d81b1f22dc9cfc9f07864dc7d..7c67cb52def7b895b9a5ac3fa6b4ee8692faf91e 100644 (file)
@@ -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)
index 44e570e653ee02883ff3cb6e6977ea4f5585a2d4..e6961af9355ff179fb2296bb0620ead615d8b50b 100644 (file)
@@ -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