11import { Element } from 'chart.js' ;
2- import { addRoundedRectPath , isArray , toFontString , toRadians , toTRBLCorners , valueOrDefault } from 'chart.js/helpers' ;
2+ import { addRoundedRectPath , isArray , toFont , toRadians , toTRBLCorners , valueOrDefault } from 'chart.js/helpers' ;
33import { clamp , clampAll , scaleValue , rotated } from '../helpers' ;
44
55const PI = Math . PI ;
@@ -181,8 +181,8 @@ LineAnnotation.defaults = {
181181 family : undefined ,
182182 lineHeight : undefined ,
183183 size : undefined ,
184- style : 'bold' ,
185- weight : undefined
184+ style : undefined ,
185+ weight : 'bold'
186186 } ,
187187 color : '#fff' ,
188188 xPadding : 6 ,
@@ -192,6 +192,8 @@ LineAnnotation.defaults = {
192192 xAdjust : 0 ,
193193 yAdjust : 0 ,
194194 textAlign : 'center' ,
195+ width : undefined ,
196+ height : undefined ,
195197 enabled : false ,
196198 content : null
197199 } ,
@@ -219,10 +221,11 @@ function calculateAutoRotation(line) {
219221
220222function drawLabel ( ctx , line , chartArea ) {
221223 const label = line . options . label ;
224+ const { borderWidth, xPadding, yPadding, content} = label ;
225+ const font = toFont ( label . font ) ;
226+ ctx . font = font . string ;
222227
223- ctx . font = toFontString ( label . font ) ;
224-
225- const { width, height} = measureLabel ( ctx , label ) ;
228+ const { width, height} = measureLabel ( ctx , label , font ) ;
226229 const rect = line . labelRect = calculateLabelPosition ( line , width , height , chartArea ) ;
227230
228231 ctx . translate ( rect . x , rect . y ) ;
@@ -244,27 +247,17 @@ function drawLabel(ctx, line, chartArea) {
244247 }
245248
246249 ctx . fillStyle = label . color ;
247- if ( isArray ( label . content ) ) {
248- ctx . textAlign = label . textAlign ;
249- const x = calculateLabelXAlignment ( label , width ) ;
250- let textYPosition = - ( height / 2 ) + label . yPadding ;
251- for ( let i = 0 ; i < label . content . length ; i ++ ) {
252- ctx . textBaseline = 'top' ;
253- ctx . fillText (
254- label . content [ i ] ,
255- x ,
256- textYPosition
257- ) ;
258- textYPosition += label . font . size + label . yPadding ;
259- }
260- } else if ( label . content instanceof Image ) {
261- const x = - ( width / 2 ) + label . xPadding ;
262- const y = - ( height / 2 ) + label . yPadding ;
263- ctx . drawImage ( label . content , x , y , width - ( 2 * label . xPadding ) , height - ( 2 * label . yPadding ) ) ;
250+ if ( content instanceof Image ) {
251+ const x = - ( width / 2 ) + xPadding + borderWidth / 2 ;
252+ const y = - ( height / 2 ) + yPadding + borderWidth / 2 ;
253+ ctx . drawImage ( content , x , y , width - ( 2 * xPadding ) - borderWidth , height - ( 2 * yPadding ) - borderWidth ) ;
264254 } else {
265- ctx . textAlign = 'center' ;
255+ const labels = isArray ( content ) ? content : [ content ] ;
256+ const x = calculateLabelXAlignment ( label , width ) ;
257+ const y = - ( labels . length - 1 ) * font . lineHeight / 2 ;
266258 ctx . textBaseline = 'middle' ;
267- ctx . fillText ( label . content , 0 , 0 ) ;
259+ ctx . textAlign = label . textAlign ;
260+ labels . forEach ( ( l , i ) => ctx . fillText ( l , x , y + ( i * font . lineHeight ) ) ) ;
268261 }
269262}
270263
@@ -281,11 +274,11 @@ function setBorderStyle(ctx, options) {
281274}
282275
283276function calculateLabelXAlignment ( label , width ) {
284- const { textAlign, xPadding} = label ;
277+ const { textAlign, xPadding, borderWidth } = label ;
285278 if ( textAlign === 'start' ) {
286- return - ( width / 2 ) + xPadding ;
279+ return - ( width / 2 ) + xPadding + borderWidth / 2 ;
287280 } else if ( textAlign === 'end' ) {
288- return + ( width / 2 ) - xPadding ;
281+ return + ( width / 2 ) - xPadding - borderWidth / 2 ;
289282 }
290283 return 0 ;
291284}
@@ -300,29 +293,32 @@ function getImageSize(size, value) {
300293}
301294
302295const widthCache = new Map ( ) ;
303- function measureLabel ( ctx , label ) {
296+ function measureLabel ( ctx , label , font ) {
304297 const content = label . content ;
298+ const borderWidth = label . borderWidth ;
299+
305300 if ( content instanceof Image ) {
306301 return {
307- width : getImageSize ( content . width , label . width ) + 2 * label . xPadding ,
308- height : getImageSize ( content . height , label . height ) + 2 * label . yPadding
302+ width : getImageSize ( content . width , label . width ) + 2 * label . xPadding + borderWidth ,
303+ height : getImageSize ( content . height , label . height ) + 2 * label . yPadding + borderWidth
309304 } ;
310305 }
311306 const lines = isArray ( content ) ? content : [ content ] ;
312307 const count = lines . length ;
313308 let width = 0 ;
314309 for ( let i = 0 ; i < count ; i ++ ) {
315310 const text = lines [ i ] ;
316- if ( ! widthCache . has ( text ) ) {
317- widthCache . set ( text , ctx . measureText ( text ) . width ) ;
311+ const key = font . string + '-' + text ;
312+ if ( ! widthCache . has ( key ) ) {
313+ widthCache . set ( key , ctx . measureText ( text ) . width ) ;
318314 }
319- width = Math . max ( width , widthCache . get ( text ) ) ;
315+ width = Math . max ( width , widthCache . get ( key ) ) ;
320316 }
321- width += 2 * label . xPadding ;
317+ width += 2 * label . xPadding + borderWidth ;
322318
323319 return {
324320 width,
325- height : count * label . font . size + ( ( count + 1 ) * label . yPadding )
321+ height : count * font . lineHeight + label . yPadding * 2 + borderWidth
326322 } ;
327323}
328324
0 commit comments