@@ -56,10 +56,11 @@ export interface LineLabelSeries extends ChartSeries {
56
56
}
57
57
58
58
interface SizedSeries extends LineLabelSeries {
59
- textWrap : TextWrapGroup
59
+ textWrap : TextWrap | TextWrapGroup
60
60
annotationTextWrap ?: TextWrap
61
61
width : number
62
62
height : number
63
+ fontWeight ?: number
63
64
}
64
65
65
66
interface PlacedSeries extends SizedSeries {
@@ -162,7 +163,24 @@ class LineLabels extends React.Component<{
162
163
nonFocused && ! hovered
163
164
? BACKGROUND_TEXT_COLOR
164
165
: darkenColorForText ( series . color )
165
- return (
166
+ return series . textWrap instanceof TextWrap ? (
167
+ < Halo
168
+ id = { series . seriesName }
169
+ key = { series . seriesName }
170
+ show = { this . showTextOutline }
171
+ outlineColor = { this . textOutlineColor }
172
+ >
173
+ { series . textWrap . render ( labelText . x , labelText . y , {
174
+ textProps : {
175
+ fill : textColor ,
176
+ opacity : this . textOpacityForSeries ( series ) ,
177
+ textAnchor : this . anchor ,
178
+ // might override the textWrap's fontWeight
179
+ fontWeight : series . fontWeight ,
180
+ } ,
181
+ } ) }
182
+ </ Halo >
183
+ ) : (
166
184
< React . Fragment key = { series . seriesName } >
167
185
{ series . textWrap . render ( labelText . x , labelText . y , {
168
186
showTextOutline : this . showTextOutline ,
@@ -381,53 +399,85 @@ export class LineLegend extends React.Component<LineLegendProps> {
381
399
return this . props . verticalAlign ?? VerticalAlign . middle
382
400
}
383
401
384
- @computed . struct get sizedLabels ( ) : SizedSeries [ ] {
385
- const { fontSize, maxWidth } = this
386
- const maxTextWidth = maxWidth - DEFAULT_CONNECTOR_LINE_WIDTH
387
- const maxAnnotationWidth = Math . min ( maxTextWidth , 150 )
402
+ @computed private get textMaxWidth ( ) : number {
403
+ return this . maxWidth - DEFAULT_CONNECTOR_LINE_WIDTH
404
+ }
405
+
406
+ private makeLabelTextWrap (
407
+ series : LineLabelSeries
408
+ ) : TextWrap | TextWrapGroup {
409
+ if ( ! series . formattedValue ) {
410
+ return new TextWrap ( {
411
+ text : series . label ,
412
+ maxWidth : this . textMaxWidth ,
413
+ fontSize : this . fontSize ,
414
+ // focused labels are bold while non-focused labels are regular.
415
+ // if we used the actual font-weights to compute the layout,
416
+ // the layout would be jumpy since different font weights lead
417
+ // to different text widths. that's why we always use bold labels
418
+ // for comupting the layout.
419
+ fontWeight : 700 ,
420
+ } )
421
+ }
388
422
423
+ // text label fragment
424
+ const textLabel = { text : series . label , fontWeight : 700 }
425
+
426
+ // value label fragment
427
+ const newLine = series . placeFormattedValueInNewLine
428
+ ? "always"
429
+ : "avoid-wrap"
430
+ const valueLabel = {
431
+ text : series . formattedValue ,
432
+ fontWeight : 400 ,
433
+ newLine,
434
+ }
435
+
436
+ return new TextWrapGroup ( {
437
+ fragments : [ textLabel , valueLabel ] ,
438
+ maxWidth : this . textMaxWidth ,
439
+ fontSize : this . fontSize ,
440
+ } )
441
+ }
442
+
443
+ private makeAnnotationTextWrap (
444
+ series : LineLabelSeries
445
+ ) : TextWrap | undefined {
446
+ if ( ! series . annotation ) return undefined
447
+ const maxWidth = Math . min ( this . textMaxWidth , 150 )
448
+ return new TextWrap ( {
449
+ text : series . annotation ,
450
+ maxWidth,
451
+ fontSize : this . fontSize * 0.9 ,
452
+ lineHeight : 1 ,
453
+ } )
454
+ }
455
+
456
+ @computed . struct get sizedLabels ( ) : SizedSeries [ ] {
457
+ const { fontWeight : globalFontWeight } = this
389
458
return this . props . labelSeries . map ( ( label ) => {
390
- // if a formatted value is given, make the main label bold by default
391
- const fontWeight =
392
- this . fontWeight ?? ( label . formattedValue ? 700 : undefined )
393
-
394
- const mainLabel = { text : label . label , fontWeight }
395
- const valueLabel = label . formattedValue
396
- ? {
397
- text : label . formattedValue ,
398
- newLine : ( label . placeFormattedValueInNewLine
399
- ? "always"
400
- : "avoid-wrap" ) as "always" | "avoid-wrap" ,
401
- }
402
- : undefined
403
- const labelFragments = excludeUndefined ( [ mainLabel , valueLabel ] )
404
- const textWrap = new TextWrapGroup ( {
405
- fragments : labelFragments ,
406
- maxWidth : maxTextWidth ,
407
- fontSize,
408
- } )
409
- const annotationTextWrap = label . annotation
410
- ? new TextWrap ( {
411
- text : label . annotation ,
412
- maxWidth : maxAnnotationWidth ,
413
- fontSize : fontSize * 0.9 ,
414
- lineHeight : 1 ,
415
- } )
416
- : undefined
417
-
418
- const annotationWidth = annotationTextWrap
419
- ? annotationTextWrap . width
420
- : 0
459
+ const textWrap = this . makeLabelTextWrap ( label )
460
+ const annotationTextWrap = this . makeAnnotationTextWrap ( label )
461
+
462
+ const annotationWidth = annotationTextWrap ?. width ?? 0
421
463
const annotationHeight = annotationTextWrap
422
464
? ANNOTATION_PADDING + annotationTextWrap . height
423
465
: 0
424
466
467
+ // font weight priority:
468
+ // series focus state > globally set font weight > default font weight
469
+ const seriesFontWeight = label . focus ?. active ? 700 : undefined
470
+ const defaultFontWeight = label . formattedValue ? 700 : undefined
471
+ const fontWeight =
472
+ seriesFontWeight ?? globalFontWeight ?? defaultFontWeight
473
+
425
474
return {
426
475
...label ,
427
476
textWrap,
428
477
annotationTextWrap,
429
478
width : Math . max ( textWrap . width , annotationWidth ) ,
430
479
height : textWrap . height + annotationHeight ,
480
+ fontWeight,
431
481
}
432
482
} )
433
483
}
0 commit comments