@@ -551,6 +551,128 @@ describe("TEXT", () => {
551551 } ) ;
552552 } ) ;
553553
554+ describe ( "multiline data labels" , ( ) => {
555+ beforeAll ( ( ) => {
556+ args = {
557+ data : {
558+ columns : [
559+ [ "data1" , 100 , 200 , 150 ] ,
560+ [ "data2" , 80 , 120 , 90 ]
561+ ] ,
562+ type : "bar" ,
563+ labels : {
564+ format : ( v ) => {
565+ // Return multiline text with newline character
566+ return `Value:\n${ v } ` ;
567+ }
568+ }
569+ }
570+ } ;
571+ } ) ;
572+
573+ it ( "should render multiline labels with tspan elements" , ( ) => {
574+ const textElements = chart . $ . main . selectAll ( `.${ $TEXT . texts } text.${ $TEXT . text } ` ) ;
575+
576+ expect ( textElements . size ( ) ) . to . be . greaterThan ( 0 ) ;
577+
578+ // Check that multiline labels have tspan elements
579+ textElements . each ( function ( ) {
580+ const text = d3Select ( this ) ;
581+ const tspans = text . selectAll ( "tspan" ) ;
582+
583+ // Multiline labels should have 2 tspan elements
584+ expect ( tspans . size ( ) ) . to . be . equal ( 2 ) ;
585+ } ) ;
586+ } ) ;
587+
588+ it ( "should vertically center multiline labels" , ( ) => {
589+ const textElements = chart . $ . main . selectAll ( `.${ $TEXT . texts } text.${ $TEXT . text } ` ) ;
590+
591+ textElements . each ( function ( ) {
592+ const text = d3Select ( this ) ;
593+ const tspans = text . selectAll ( "tspan" ) ;
594+
595+ // Check that first tspan has negative dy for centering
596+ // When toMiddle is true, first tspan should have dy = -1 * (lines - 1) = -1em
597+ const firstTspan = tspans . nodes ( ) [ 0 ] ;
598+ const firstDy = d3Select ( firstTspan ) . attr ( "dy" ) ;
599+
600+ expect ( firstDy ) . to . be . equal ( "-1em" ) ;
601+
602+ // Second tspan should have dy = 1em
603+ const secondTspan = tspans . nodes ( ) [ 1 ] ;
604+ const secondDy = d3Select ( secondTspan ) . attr ( "dy" ) ;
605+
606+ expect ( secondDy ) . to . be . equal ( "1em" ) ;
607+ } ) ;
608+ } ) ;
609+
610+ it ( "should have correct text content in tspan elements" , ( ) => {
611+ const textElements = chart . $ . main . selectAll ( `.${ $TEXT . texts } text.${ $TEXT . text } ` ) ;
612+
613+ textElements . each ( function ( d ) {
614+ const text = d3Select ( this ) ;
615+ const tspans = text . selectAll ( "tspan" ) ;
616+ const nodes = tspans . nodes ( ) as Element [ ] ;
617+ const firstLine = nodes [ 0 ] ?. textContent ;
618+ const secondLine = nodes [ 1 ] ?. textContent ;
619+
620+ // First line should be "Value:"
621+ expect ( firstLine ) . to . be . equal ( "Value:" ) ;
622+
623+ // Second line should be the numeric value
624+ expect ( secondLine ) . to . match ( / ^ \d + $ / ) ;
625+ } ) ;
626+ } ) ;
627+
628+ it ( "set options: three line labels" , ( ) => {
629+ args . data . labels . format = ( v , id , i ) => {
630+ return `Line1:\n${ v } \nLine3` ;
631+ } ;
632+ } ) ;
633+
634+ it ( "should render three-line labels with correct vertical centering" , ( ) => {
635+ const textElements = chart . $ . main . selectAll ( `.${ $TEXT . texts } text.${ $TEXT . text } ` ) ;
636+
637+ textElements . each ( function ( ) {
638+ const text = d3Select ( this ) ;
639+ const tspans = text . selectAll ( "tspan" ) ;
640+
641+ // Three-line labels should have 3 tspan elements
642+ expect ( tspans . size ( ) ) . to . be . equal ( 3 ) ;
643+
644+ // Check dy values for vertical centering
645+ // For 3 lines with toMiddle=true: first dy = -2em, others = 1em
646+ const firstTspan = tspans . nodes ( ) [ 0 ] ;
647+ const firstDy = d3Select ( firstTspan ) . attr ( "dy" ) ;
648+ expect ( firstDy ) . to . be . equal ( "-2em" ) ;
649+
650+ // Second and third tspans should have dy = 1em
651+ const secondTspan = tspans . nodes ( ) [ 1 ] ;
652+ const secondDy = d3Select ( secondTspan ) . attr ( "dy" ) ;
653+ expect ( secondDy ) . to . be . equal ( "1em" ) ;
654+
655+ const thirdTspan = tspans . nodes ( ) [ 2 ] ;
656+ const thirdDy = d3Select ( thirdTspan ) . attr ( "dy" ) ;
657+ expect ( thirdDy ) . to . be . equal ( "1em" ) ;
658+ } ) ;
659+ } ) ;
660+
661+ it ( "should set x attribute to 0 for all tspan elements" , ( ) => {
662+ const textElements = chart . $ . main . selectAll ( `.${ $TEXT . texts } text.${ $TEXT . text } ` ) ;
663+
664+ textElements . each ( function ( ) {
665+ const text = d3Select ( this ) ;
666+ const tspans = text . selectAll ( "tspan" ) ;
667+
668+ tspans . each ( function ( ) {
669+ const tspan = d3Select ( this ) ;
670+ expect ( tspan . attr ( "x" ) ) . to . be . equal ( "0" ) ;
671+ } ) ;
672+ } ) ;
673+ } ) ;
674+ } ) ;
675+
554676 describe ( "on area chart" , ( ) => {
555677 beforeAll ( ( ) => {
556678 args = {
0 commit comments