@@ -115,8 +115,6 @@ function sankeyModel(layout, d, i) {
115115 node = sankeyNodes [ n ] ;
116116 node . width = width ;
117117 node . height = height ;
118- if ( node . parallel ) node . x = ( horizontal ? width : height ) * node . parallel ;
119- if ( node . perpendicular ) node . y = ( horizontal ? height : width ) * node . perpendicular ;
120118 }
121119
122120 switchToForceFormat ( nodes ) ;
@@ -180,9 +178,7 @@ function nodeModel(uniqueKeys, d, n) {
180178 zoneThicknessPad = c . nodePadAcross ,
181179 zoneLengthPad = d . nodePad / 2 ,
182180 visibleThickness = n . dx + 0.5 ,
183- visibleLength = n . dy - 0.5 ,
184- zoneThickness = visibleThickness + 2 * zoneThicknessPad ,
185- zoneLength = visibleLength + 2 * zoneLengthPad ;
181+ visibleLength = n . dy - 0.5 ;
186182
187183 var basicKey = n . label ;
188184 var foundKey = uniqueKeys [ basicKey ] ;
@@ -198,15 +194,15 @@ function nodeModel(uniqueKeys, d, n) {
198194 nodeLineWidth : d . nodeLineWidth ,
199195 textFont : d . textFont ,
200196 size : d . horizontal ? d . height : d . width ,
201- visibleWidth : Math . ceil ( d . horizontal ? visibleThickness : visibleLength ) ,
202- visibleHeight : Math . ceil ( d . horizontal ? visibleLength : visibleThickness ) ,
203- zoneX : d . horizontal ? - zoneThicknessPad : - zoneLengthPad ,
204- zoneY : d . horizontal ? - zoneLengthPad : - zoneThicknessPad ,
205- zoneWidth : d . horizontal ? zoneThickness : zoneLength ,
206- zoneHeight : d . horizontal ? zoneLength : zoneThickness ,
197+ visibleWidth : Math . ceil ( visibleThickness ) ,
198+ visibleHeight : Math . ceil ( visibleLength ) ,
199+ zoneX : - zoneThicknessPad ,
200+ zoneY : - zoneLengthPad ,
201+ zoneWidth : visibleThickness + 2 * zoneThicknessPad ,
202+ zoneHeight : visibleLength + 2 * zoneLengthPad ,
207203 labelY : d . horizontal ? n . dy / 2 + 1 : n . dx / 2 + 1 ,
208204 left : n . originalLayer === 1 ,
209- sizeAcross : d . horizontal ? d . width : d . height ,
205+ sizeAcross : d . width ,
210206 forceLayouts : d . forceLayouts ,
211207 horizontal : d . horizontal ,
212208 darkBackground : tc . getBrightness ( ) <= 128 ,
@@ -230,9 +226,7 @@ function crispLinesOnEnd(sankeyNode) {
230226function updateNodePositions ( sankeyNode ) {
231227 sankeyNode
232228 . attr ( 'transform' , function ( d ) {
233- return d . horizontal ?
234- 'translate(' + ( d . node . x - 0.5 ) + ', ' + ( d . node . y - d . node . dy / 2 + 0.5 ) + ')' :
235- 'translate(' + ( d . node . y - d . node . dy / 2 - 0.5 ) + ', ' + ( d . node . x + 0.5 ) + ')' ;
229+ return 'translate(' + ( d . node . x - 0.5 ) + ', ' + ( d . node . y - d . node . dy / 2 + 0.5 ) + ')' ;
236230 } ) ;
237231}
238232
@@ -259,20 +253,28 @@ function sizeNode(rect) {
259253 . attr ( 'height' , function ( d ) { return d . visibleHeight ; } ) ;
260254}
261255
262- function salientEnough ( d ) {
263- return d . link . dy > 1 || d . linkLineWidth > 0 ;
256+ function salientEnough ( d ) { return d . link . dy > 1 || d . linkLineWidth > 0 ; }
257+
258+ function sankeyTransform ( d ) {
259+ var offset = 'translate(' + d . translateX + ',' + d . translateY + ')' ;
260+ return offset + ( d . horizontal ? 'matrix(1 0 0 1 0 0)' : 'matrix(0 1 1 0 0 0)' ) ;
264261}
265262
266- function linksTransform ( d ) {
267- return d . horizontal ? 'matrix(1 0 0 1 0 0)' : 'matrix(0 1 1 0 0 0 )';
263+ function nodeCentering ( d ) {
264+ return 'translate(' + ( d . horizontal ? 0 : d . labelY ) + ' ' + ( d . horizontal ? d . labelY : 0 ) + ' )';
268265}
269266
270267function textGuidePath ( d ) {
271268 return d3 . svg . line ( ) ( [
272- [ d . horizontal ? ( d . left ? - d . sizeAcross : d . visibleWidth + c . nodeTextOffsetHorizontal ) : c . nodeTextOffsetHorizontal , d . labelY ] ,
273- [ d . horizontal ? ( d . left ? - c . nodeTextOffsetHorizontal : d . sizeAcross ) : d . visibleWidth - c . nodeTextOffsetHorizontal , d . labelY ]
269+ [ d . horizontal ? ( d . left ? - d . sizeAcross : d . visibleWidth + c . nodeTextOffsetHorizontal ) : c . nodeTextOffsetHorizontal , 0 ] ,
270+ [ d . horizontal ? ( d . left ? - c . nodeTextOffsetHorizontal : d . sizeAcross ) : d . visibleHeight - c . nodeTextOffsetHorizontal , 0 ]
274271 ] ) ; }
275272
273+ function sankeyInverseTransform ( d ) { return d . horizontal ? 'matrix(1 0 0 1 0 0)' : 'matrix(0 1 1 0 0 0)' ; }
274+ function textFlip ( d ) { return d . horizontal ? 'scale(1 1)' : 'scale(-1 1)' ; }
275+ function nodeTextColor ( d ) { return d . darkBackground && ! d . horizontal ? 'rgb(255,255,255)' : 'rgb(0,0,0)' ; }
276+ function nodeTextOffset ( d ) { return d . horizontal && d . left ? '100%' : '0%' ; }
277+
276278// event handling
277279
278280function attachPointerEvents ( selection , sankey , eventSet ) {
@@ -311,7 +313,7 @@ function attachDragHandler(sankeyNode, sankeyLink, callbacks) {
311313
312314 var dragBehavior = d3 . behavior . drag ( )
313315
314- . origin ( function ( d ) { return d . horizontal ? d . node : { x : d . node . y , y : d . node . x } ; } )
316+ . origin ( function ( d ) { return d . node ; } )
315317
316318 . on ( 'dragstart' , function ( d ) {
317319 if ( d . arrangement === 'fixed' ) return ;
@@ -335,8 +337,8 @@ function attachDragHandler(sankeyNode, sankeyLink, callbacks) {
335337
336338 . on ( 'drag' , function ( d ) {
337339 if ( d . arrangement === 'fixed' ) return ;
338- var x = d . horizontal ? d3 . event . x : d3 . event . y ;
339- var y = d . horizontal ? d3 . event . y : d3 . event . x ;
340+ var x = d3 . event . x ;
341+ var y = d3 . event . y ;
340342 if ( d . arrangement === 'snap' ) {
341343 d . node . x = x ;
342344 d . node . y = y ;
@@ -432,23 +434,20 @@ module.exports = function(svg, styledData, layout, callbacks) {
432434 . style ( 'left' , 0 )
433435 . style ( 'shape-rendering' , 'geometricPrecision' )
434436 . style ( 'pointer-events' , 'auto' )
435- . style ( 'box-sizing' , 'content-box' ) ;
437+ . style ( 'box-sizing' , 'content-box' )
438+ . attr ( 'transform' , sankeyTransform ) ;
436439
437- sankey
438- . attr ( 'transform' , function ( d ) { return 'translate(' + d . translateX + ',' + d . translateY + ')' ; } ) ;
440+ sankey . transition ( )
441+ . ease ( c . ease ) . duration ( c . duration )
442+ . attr ( 'transform' , sankeyTransform ) ;
439443
440444 var sankeyLinks = sankey . selectAll ( '.sankeyLinks' )
441445 . data ( repeat , keyFun ) ;
442446
443447 sankeyLinks . enter ( )
444448 . append ( 'g' )
445449 . classed ( 'sankeyLinks' , true )
446- . style ( 'fill' , 'none' )
447- . attr ( 'transform' , linksTransform ) ;
448-
449- sankeyLinks . transition ( )
450- . ease ( c . ease ) . duration ( c . duration )
451- . attr ( 'transform' , linksTransform ) ;
450+ . style ( 'fill' , 'none' ) ;
452451
453452 var sankeyLink = sankeyLinks . selectAll ( '.sankeyLink' )
454453 . data ( function ( d ) {
@@ -562,26 +561,42 @@ module.exports = function(svg, styledData, layout, callbacks) {
562561 . attr ( 'width' , function ( d ) { return d . zoneWidth ; } )
563562 . attr ( 'height' , function ( d ) { return d . zoneHeight ; } ) ;
564563
565- var nodeLabelGuide = sankeyNode . selectAll ( '.nodeLabelGuide' )
564+ var nodeCentered = sankeyNode . selectAll ( '.nodeCentered' )
565+ . data ( repeat ) ;
566+
567+ nodeCentered . enter ( )
568+ . append ( 'g' )
569+ . classed ( 'nodeCentered' , true )
570+ . attr ( 'transform' , nodeCentering ) ;
571+
572+ nodeCentered
573+ . transition ( )
574+ . ease ( c . ease ) . duration ( c . duration )
575+ . attr ( 'transform' , nodeCentering ) ;
576+
577+ var nodeLabelGuide = nodeCentered . selectAll ( '.nodeLabelGuide' )
566578 . data ( repeat ) ;
567579
568580 nodeLabelGuide . enter ( )
569581 . append ( 'path' )
570582 . classed ( 'nodeLabelGuide' , true )
571583 . attr ( 'id' , function ( d ) { return d . uniqueNodeLabelPathId ; } )
572- . attr ( 'd' , textGuidePath ) ;
584+ . attr ( 'd' , textGuidePath )
585+ . attr ( 'transform' , sankeyInverseTransform ) ;
573586
574587 nodeLabelGuide
575588 . transition ( )
576589 . ease ( c . ease ) . duration ( c . duration )
577- . attr ( 'd' , textGuidePath ) ;
590+ . attr ( 'd' , textGuidePath )
591+ . attr ( 'transform' , sankeyInverseTransform ) ;
578592
579- var nodeLabel = sankeyNode . selectAll ( '.nodeLabel' )
593+ var nodeLabel = nodeCentered . selectAll ( '.nodeLabel' )
580594 . data ( repeat ) ;
581595
582596 nodeLabel . enter ( )
583597 . append ( 'text' )
584598 . classed ( 'nodeLabel' , true )
599+ . attr ( 'transform' , textFlip )
585600 . style ( 'user-select' , 'none' )
586601 . style ( 'cursor' , 'default' )
587602 . style ( 'fill' , 'black' ) ;
@@ -592,18 +607,29 @@ module.exports = function(svg, styledData, layout, callbacks) {
592607 } )
593608 . each ( function ( d ) { Drawing . font ( nodeLabel , d . textFont ) ; } ) ;
594609
610+ nodeLabel
611+ . transition ( )
612+ . ease ( c . ease ) . duration ( c . duration )
613+ . attr ( 'transform' , textFlip ) ;
614+
595615 var nodeLabelTextPath = nodeLabel . selectAll ( '.nodeLabelTextPath' )
596616 . data ( repeat ) ;
597617
598618 nodeLabelTextPath . enter ( )
599619 . append ( 'textPath' )
600620 . classed ( 'nodeLabelTextPath' , true )
601621 . attr ( 'alignment-baseline' , 'middle' )
602- . attr ( 'xlink:href' , function ( d ) { return '#' + d . uniqueNodeLabelPathId ; } ) ;
622+ . attr ( 'xlink:href' , function ( d ) { return '#' + d . uniqueNodeLabelPathId ; } )
623+ . attr ( 'startOffset' , nodeTextOffset )
624+ . style ( 'fill' , nodeTextColor ) ;
603625
604626 nodeLabelTextPath
605627 . text ( function ( d ) { return d . horizontal || d . node . dy > 5 ? d . node . label : '' ; } )
606- . attr ( 'startOffset' , function ( d ) { return d . horizontal && d . left ? '100%' : '0%' ; } )
607- . style ( 'text-anchor' , function ( d ) { return d . horizontal && d . left ? 'end' : 'start' ; } )
608- . style ( 'fill' , function ( d ) { return d . darkBackground && ! d . horizontal ? 'white' : 'black' ; } ) ;
628+ . style ( 'text-anchor' , function ( d ) { return d . horizontal && d . left ? 'end' : 'start' ; } ) ;
629+
630+ nodeLabelTextPath
631+ . transition ( )
632+ . ease ( c . ease ) . duration ( c . duration )
633+ . attr ( 'startOffset' , nodeTextOffset )
634+ . style ( 'fill' , nodeTextColor ) ;
609635} ;
0 commit comments