@@ -534,6 +534,59 @@ function linkPath() {
534534 return path ;
535535}
536536
537+ // Builds the permanent-label string for a link from textinfo / texttemplate.
538+ function linkTextGetter ( trace ) {
539+ var linkAttr = trace . link ;
540+ var textinfo = linkAttr . textinfo ;
541+ var texttemplate = linkAttr . texttemplate ;
542+ var vFmt = linkAttr . valueformat ;
543+ var vSuf = linkAttr . valuesuffix ;
544+ var flags = ( textinfo && textinfo !== 'none' ) ? textinfo . split ( '+' ) : [ ] ;
545+
546+ return function ( l , i ) {
547+ var valueLabel = Lib . numberFormat ( vFmt ) ( l . value ) + vSuf ;
548+
549+ var tt = Array . isArray ( texttemplate ) ? texttemplate [ i ] : texttemplate ;
550+ if ( tt ) {
551+ return Lib . texttemplateString ( {
552+ template : tt ,
553+ labels : { valueLabel : valueLabel } ,
554+ data : [ {
555+ label : l . label ,
556+ value : l . value ,
557+ source : l . source . label ,
558+ target : l . target . label ,
559+ customdata : l . customdata
560+ } ]
561+ } ) ;
562+ }
563+
564+ if ( ! flags . length ) return '' ;
565+ var parts = [ ] ;
566+ if ( flags . indexOf ( 'label' ) !== - 1 && l . label ) parts . push ( l . label ) ;
567+ if ( flags . indexOf ( 'value' ) !== - 1 ) parts . push ( valueLabel ) ;
568+ return parts . join ( '<br>' ) ;
569+ } ;
570+ }
571+
572+ // Positions a permanent link label at the link midpoint (layout frame) and keeps
573+ // the glyphs upright.
574+ function linkLabelTransform ( d ) {
575+ var l = d . link ;
576+ var midX , midY ;
577+ if ( l . circular ) {
578+ // same anchor as the hover label (see hoverCenterPosition in plot.js)
579+ midX = ( l . circularPathData . leftInnerExtent + l . circularPathData . rightInnerExtent ) / 2 ;
580+ midY = l . circularPathData . verticalFullExtent ;
581+ } else {
582+ midX = ( l . source . x1 + l . target . x0 ) / 2 ;
583+ midY = ( l . y0 + l . y1 ) / 2 ;
584+ }
585+ var p = d . parent ;
586+ var flip = p . horizontal ? '' : ( 'scale(-1,1)' + strRotate ( 90 ) ) ;
587+ return strTranslate ( midX , midY ) + flip ;
588+ }
589+
537590function nodeModel ( d , n ) {
538591 var tc = tinycolor ( n . color ) ;
539592 var zoneThicknessPad = c . nodePadAcross ;
@@ -607,6 +660,11 @@ function updateNodeShapes(sankeyNode) {
607660function updateShapes ( sankeyNode , sankeyLink ) {
608661 sankeyNode . call ( updateNodeShapes ) ;
609662 sankeyLink . attr ( 'd' , linkPath ( ) ) ;
663+ var linkNode = sankeyLink . node ( ) ;
664+ if ( linkNode ) {
665+ d3 . select ( linkNode . parentNode ) . selectAll ( '.' + c . cn . sankeyLinkLabel )
666+ . attr ( 'transform' , linkLabelTransform ) ;
667+ }
610668}
611669
612670function sizeNode ( rect ) {
@@ -966,6 +1024,39 @@ module.exports = function(gd, svg, calcData, layout, callbacks) {
9661024 . style ( 'opacity' , 0 )
9671025 . remove ( ) ;
9681026
1027+ var sankeyLinkLabel = sankeyLinks . selectAll ( '.' + c . cn . sankeyLinkLabel )
1028+ . data ( function ( d ) {
1029+ var getText = linkTextGetter ( d . trace ) ;
1030+ var out = [ ] ;
1031+ d . graph . links . forEach ( function ( l , i ) {
1032+ if ( ! l . value ) return ;
1033+ var txt = getText ( l , i ) ;
1034+ if ( ! txt ) return ;
1035+ var m = linkModel ( d , l , i ) ;
1036+ m . linkLabelText = txt ;
1037+ out . push ( m ) ;
1038+ } ) ;
1039+ return out ;
1040+ } , keyFun ) ;
1041+
1042+ sankeyLinkLabel . enter ( )
1043+ . append ( 'text' )
1044+ . classed ( c . cn . sankeyLinkLabel , true )
1045+ . attr ( 'text-anchor' , 'middle' )
1046+ . style ( 'pointer-events' , 'none' ) ;
1047+
1048+ sankeyLinkLabel
1049+ . attr ( 'data-notex' , 1 )
1050+ . text ( function ( d ) { return d . linkLabelText ; } )
1051+ . each ( function ( d ) {
1052+ var e = d3 . select ( this ) ;
1053+ Drawing . font ( e , d . link . trace . link . textfont ) ;
1054+ svgTextUtils . convertToTspans ( e , gd ) ;
1055+ } )
1056+ . attr ( 'transform' , linkLabelTransform ) ;
1057+
1058+ sankeyLinkLabel . exit ( ) . remove ( ) ;
1059+
9691060 var sankeyNodeSet = sankey . selectAll ( '.' + c . cn . sankeyNodeSet )
9701061 . data ( repeat , keyFun ) ;
9711062
0 commit comments