Skip to content

Commit ca83a73

Browse files
stockiNailkurkle
andauthored
Add stroke width and color options to label text (#679)
* Add stroke width and color options to label text * fixes CC * uses strokeWidth to calculate label rect (not only TextMetrics). * adds textStrokeJoinStyle option * changes the stroke join style option description in the documentation * fixes typo in the join style options documentation * removes textStrokeJoinStyle option in favor to fixed 'round' * Update src/helpers/helpers.canvas.js Co-authored-by: Jukka Kurkela <[email protected]> * Update src/helpers/helpers.canvas.js Co-authored-by: Jukka Kurkela <[email protected]> Co-authored-by: Jukka Kurkela <[email protected]>
1 parent a0ae8a1 commit ca83a73

File tree

15 files changed

+281
-9
lines changed

15 files changed

+281
-9
lines changed

docs/guide/types/box.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ If one of the axes does not match an axis in the chart, the box will take the en
103103
| `borderColor` | Stroke color.
104104
| `borderDash` | Length and spacing of dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash).
105105
| `borderDashOffset` | Offset for border line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset).
106-
| `borderJoinStyle` | Border line joint style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin).
106+
| `borderJoinStyle` | Border line join style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin).
107107
| [`borderRadius`](#borderradius) | Radius of box rectangle (in pixels).
108108
| `borderShadowColor` | The color of the border shadow. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowColor).
109109
| `borderWidth` | Border line width (in pixels).
@@ -132,6 +132,8 @@ All of these options can be [Scriptable](../options#scriptable-options)
132132
| `padding` | [`Padding`](../options#padding) | `6` | The padding to add around the text label.
133133
| [`position`](#position) | `string`\|`{x: string, y: string}` | `'center'` | Anchor position of label in the box.
134134
| `textAlign` | `string` | `'start'` | Text alignment of label content when there's more than one line. Possible options are: `'left'`, `'start'`, `'center'`, `'end'`, `'right'`.
135+
| `textStrokeColor` | [`Color`](../options#color) | `undefined` | The color of the stroke around the text.
136+
| `textStrokeWidth` | `number` | `0` | Stroke width around the text.
135137
| `width` | `number`\|`string` | `undefined` | Overrides the width of the image or canvas element. Could be set in pixel by a number, or in percentage of current width of image or canvas element by a string. If undefined, uses the width of the image or canvas element. It is used only when the content is an image or canvas element.
136138
| `xAdjust` | `number` | `0` | Adjustment along x-axis (left-right) of label relative to computed position. Negative values move the label left, positive right.
137139
| `yAdjust` | `number` | `0` | Adjustment along y-axis (top-bottom) of label relative to computed position. Negative values move the label up, positive down.

docs/guide/types/label.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ The following options are available for label annotations.
7878
| [`shadowOffsetX`](#styling) | `number` | Yes | `0`
7979
| [`shadowOffsetY`](#styling) | `number` | Yes | `0`
8080
| [`textAlign`](#general) | `string` | Yes | `'center'`
81+
| [`textStrokeColor`](#styling) | [`Color`](../options#color) | Yes | `undefined`
82+
| [`textStrokeWidth`](#styling) | `number` | Yes | `0`
8183
| [`width`](#general) | `number`\|`string` | Yes | `undefined`
8284
| [`xAdjust`](#general) | `number` | Yes | `0`
8385
| [`xMax`](#general) | `number` \| `string` | Yes | `undefined`
@@ -128,14 +130,16 @@ The 4 coordinates, xMin, xMax, yMin, yMax are optional. If not specified, the bo
128130
| `borderColor` | Stroke color.
129131
| `borderDash` | Length and spacing of dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash).
130132
| `borderDashOffset` | Offset for border line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset).
131-
| `borderJoinStyle` | Border line joint style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin).
133+
| `borderJoinStyle` | Border line join style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin).
132134
| `borderShadowColor` | The color of the border shadow. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowColor).
133135
| `borderWidth` | Stroke width (in pixels).
134136
| `color` | Text color.
135137
| `font` | Text font.
136138
| `shadowBlur` | The amount of blur applied to shadow of the box where the label is located. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowBlur).
137139
| `shadowOffsetX` | The distance that shadow, of the box where the label is located, will be offset horizontally. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowOffsetX).
138140
| `shadowOffsetY` | The distance that shadow, of the box where the label is located, will be offset vertically. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowOffsetY).
141+
| `textStrokeColor` | The color of the stroke around the text.
142+
| `textStrokeWidth` | Stroke width around the text.
139143

140144
### Position
141145

@@ -218,7 +222,7 @@ All of these options can be [Scriptable](../options#scriptable-options).
218222
| `borderColor` | [`Color`](../options#color) | `undefined` | Stroke color of the pointer of the callout.
219223
| `borderDash` | `number[]` | `[]` | Length and spacing of dashes of callout. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash).
220224
| `borderDashOffset` | `number` | `0` | Offset for line dashes of callout. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset).
221-
| `borderJoinStyle` | `string` | `'miter'` | Border line joint style of the callout. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin).
225+
| `borderJoinStyle` | `string` | `'miter'` | Border line join style of the callout. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin).
222226
| `borderWidth` | `number` | `1` | Stroke width of the pointer of the callout.
223227
| `enabled` | `boolean` | `false` | If true, the callout is drawn.
224228
| `margin` | `number` | `5` | Amount of pixels between the label and the callout separator.

docs/guide/types/line.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ All of these options can be [Scriptable](../options#scriptable-options)
135135
| `borderColor` | [`Color`](../options#color) | `black` | The border line color.
136136
| `borderDash` | `number[]` | `[]` | Length and spacing of dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash).
137137
| `borderDashOffset` | `number` | `0` | Offset for border line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset).
138-
| `borderJoinStyle` | `string` | `'miter'` | Border line joint style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin).
138+
| `borderJoinStyle` | `string` | `'miter'` | Border line join style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin).
139139
| [`borderRadius`](#borderradius) | `number` \| `object` | `6` | Radius of label box corners in pixels.
140140
| `borderShadowColor` | [`Color`](../options#color) | `'transparent'` | The color of border shadow of the box where the label is located. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowColor).
141141
| `borderWidth` | `number` | `0` | The border line width (in pixels).
@@ -152,6 +152,8 @@ All of these options can be [Scriptable](../options#scriptable-options)
152152
| `shadowOffsetX` | `number` | `0` | The distance that shadow, of the box where the label is located, will be offset horizontally. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowOffsetX).
153153
| `shadowOffsetY` | `number` | `0` | The distance that shadow, of the box where the label is located, will be offset vertically. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowOffsetY).
154154
| `textAlign` | `string` | `'center'` | Text alignment of label content when there's more than one line. Possible options are: `'start'`, `'center'`, `'end'`.
155+
| `textStrokeColor` | [`Color`](../options#color) | `undefined` | The color of the stroke around the text.
156+
| `textStrokeWidth` | `number` | `0` | Stroke width around the text.
155157
| `width` | `number`\|`string` | `undefined` | Overrides the width of the image or canvas element. Could be set in pixel by a number, or in percentage of current width of image or canvas element by a string. If undefined, uses the width of the image or canvas element. It is used only when the content is an image or canvas element.
156158
| `xAdjust` | `number` | `0` | Adjustment along x-axis (left-right) of label relative to computed position. Negative values move the label left, positive right.
157159
| `xPadding` | `number` | `6` | Padding of label to add left/right. This is **deprecated**. Use `padding`.

docs/guide/types/polygon.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ The 4 coordinates, xMin, xMax, yMin, yMax are optional. If not specified, the bo
116116
| `borderCapStyle` | Cap style of the border of polygon. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap).
117117
| `borderDash` | Length and spacing of dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash).
118118
| `borderDashOffset` | Offset for line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset).
119-
| `borderJoinStyle` | Border line joint style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin).
119+
| `borderJoinStyle` | Border line join style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin).
120120
| `borderShadowColor` | The color of the border shadow. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowColor).
121121
| `borderWidth` | Stroke width.
122122
| `shadowBlur` | The amount of blur applied to shadow. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowBlur).

src/helpers/helpers.canvas.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,20 @@ export function measureLabelSize(ctx, options) {
7777
};
7878
}
7979
const font = toFont(options.font);
80+
const strokeWidth = options.textStrokeWidth;
8081
const lines = isArray(content) ? content : [content];
81-
const mapKey = lines.join() + font.string + (ctx._measureText ? '-spriting' : '');
82+
const mapKey = lines.join() + font.string + strokeWidth + (ctx._measureText ? '-spriting' : '');
8283
if (!widthCache.has(mapKey)) {
8384
ctx.save();
8485
ctx.font = font.string;
8586
const count = lines.length;
8687
let width = 0;
8788
for (let i = 0; i < count; i++) {
8889
const text = lines[i];
89-
width = Math.max(width, ctx.measureText(text).width);
90+
width = Math.max(width, ctx.measureText(text).width + strokeWidth);
9091
}
9192
ctx.restore();
92-
const height = count * font.lineHeight;
93+
const height = count * font.lineHeight + strokeWidth;
9394
widthCache.set(mapKey, {width, height});
9495
}
9596
return widthCache.get(mapKey);
@@ -123,6 +124,13 @@ export function drawBox(ctx, rect, options) {
123124
ctx.restore();
124125
}
125126

127+
/**
128+
* Draw a label with the size and the styling options.
129+
* @param {CanvasRenderingContext2D} ctx - chart canvas context
130+
* @param {{x: number, y: number, width: number, height: number}} rect - rect to map teh label
131+
* @param {Object} options - options to style the label
132+
* @returns {undefined}
133+
*/
126134
export function drawLabel(ctx, rect, options) {
127135
const content = options.content;
128136
if (isImageOrCanvas(content)) {
@@ -133,10 +141,26 @@ export function drawLabel(ctx, rect, options) {
133141
const font = toFont(options.font);
134142
const lh = font.lineHeight;
135143
const x = calculateTextAlignment(rect, options);
136-
const y = rect.y + (lh / 2);
144+
const y = rect.y + (lh / 2) + options.textStrokeWidth / 2;
145+
ctx.save();
137146
ctx.font = font.string;
138147
ctx.textBaseline = 'middle';
139148
ctx.textAlign = options.textAlign;
149+
if (setTextStrokeStyle(ctx, options)) {
150+
labels.forEach((l, i) => ctx.strokeText(l, x, y + (i * lh)));
151+
}
140152
ctx.fillStyle = options.color;
141153
labels.forEach((l, i) => ctx.fillText(l, x, y + (i * lh)));
154+
ctx.restore();
155+
}
156+
157+
function setTextStrokeStyle(ctx, options) {
158+
if (options.textStrokeWidth > 0) {
159+
// https://stackoverflow.com/questions/13627111/drawing-text-with-an-outer-stroke-with-html5s-canvas
160+
ctx.lineJoin = 'round';
161+
ctx.miterLimit = 2;
162+
ctx.lineWidth = options.textStrokeWidth;
163+
ctx.strokeStyle = options.textStrokeColor;
164+
return true;
165+
}
142166
}

src/types/box.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ BoxAnnotation.defaults = {
8080
padding: 6,
8181
position: 'center',
8282
textAlign: 'start',
83+
textStrokeColor: undefined,
84+
textStrokeWidth: 0,
8385
xAdjust: 0,
8486
yAdjust: 0,
8587
width: undefined

src/types/label.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ LabelAnnotation.defaults = {
9191
shadowOffsetX: 0,
9292
shadowOffsetY: 0,
9393
textAlign: 'center',
94+
textStrokeColor: undefined,
95+
textStrokeWidth: 0,
9496
width: undefined,
9597
xAdjust: 0,
9698
xMax: undefined,

src/types/line.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ LineAnnotation.defaults = {
268268
shadowOffsetX: 0,
269269
shadowOffsetY: 0,
270270
textAlign: 'center',
271+
textStrokeColor: undefined,
272+
textStrokeWidth: 0,
271273
width: undefined,
272274
xAdjust: 0,
273275
xPadding: undefined, // TODO: v2 remove support for xPadding
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
module.exports = {
2+
tolerance: 0.0315,
3+
config: {
4+
type: 'scatter',
5+
options: {
6+
scales: {
7+
x: {
8+
display: false,
9+
min: 0,
10+
max: 10
11+
},
12+
y: {
13+
display: false,
14+
min: 0,
15+
max: 10
16+
}
17+
},
18+
plugins: {
19+
annotation: {
20+
annotations: {
21+
box1: {
22+
type: 'box',
23+
xMin: 0.5,
24+
xMax: 9.5,
25+
yMin: 6.5,
26+
yMax: 9.5,
27+
backgroundColor: '#f5f5f5',
28+
borderColor: 'black',
29+
borderWidth: 1,
30+
label: {
31+
enabled: true,
32+
content: ['text stroke width 5', 'text stroke color red'],
33+
textStrokeWidth: 5,
34+
textStrokeColor: 'red',
35+
font: {
36+
size: 40
37+
}
38+
}
39+
},
40+
box2: {
41+
type: 'box',
42+
xMin: 0.5,
43+
xMax: 9.5,
44+
yMin: 4,
45+
yMax: 6,
46+
backgroundColor: '#f5f5f5',
47+
borderColor: 'black',
48+
borderWidth: 1,
49+
label: {
50+
enabled: true,
51+
textStrokeWidth: 3,
52+
color: 'white',
53+
content: 'text stroke width 3',
54+
font: {
55+
size: 30
56+
}
57+
}
58+
},
59+
box3: {
60+
type: 'box',
61+
xMin: 0.5,
62+
xMax: 9.5,
63+
yMin: 0.5,
64+
yMax: 3.5,
65+
backgroundColor: '#f5f5f5',
66+
borderColor: 'black',
67+
borderWidth: 1,
68+
label: {
69+
enabled: true,
70+
color: '#40E0D0',
71+
content: ['text stroke width 10', 'text stroke color turq'],
72+
textStrokeWidth: 10,
73+
textStrokeColor: 'black',
74+
font: {
75+
size: 40
76+
}
77+
}
78+
}
79+
}
80+
}
81+
}
82+
}
83+
}
84+
};
57.4 KB
Loading

0 commit comments

Comments
 (0)