@@ -330,11 +330,14 @@ describe('sankey tests', function() {
330330 } ) ;
331331
332332 describe ( 'lifecycle methods' , function ( ) {
333+ var gd ;
334+ beforeEach ( function ( ) {
335+ gd = createGraphDiv ( ) ;
336+ } ) ;
333337 afterEach ( destroyGraphDiv ) ;
334338
335339 it ( 'Plotly.deleteTraces with two traces removes the deleted plot' , function ( done ) {
336340
337- var gd = createGraphDiv ( ) ;
338341 var mockCopy = Lib . extendDeep ( { } , mock ) ;
339342 var mockCopy2 = Lib . extendDeep ( { } , mockDark ) ;
340343
@@ -363,7 +366,6 @@ describe('sankey tests', function() {
363366
364367 it ( 'Plotly.plot does not show Sankey if \'visible\' is false' , function ( done ) {
365368
366- var gd = createGraphDiv ( ) ;
367369 var mockCopy = Lib . extendDeep ( { } , mock ) ;
368370
369371 Plotly . plot ( gd , mockCopy )
@@ -386,7 +388,6 @@ describe('sankey tests', function() {
386388
387389 it ( '\'node\' remains visible even if \'value\' is very low' , function ( done ) {
388390
389- var gd = createGraphDiv ( ) ;
390391 var minimock = [ {
391392 type : 'sankey' ,
392393 node : {
@@ -408,7 +409,6 @@ describe('sankey tests', function() {
408409 } ) ;
409410
410411 it ( 'switch from normal to circular Sankey on react' , function ( done ) {
411- var gd = createGraphDiv ( ) ;
412412 var mockCopy = Lib . extendDeep ( { } , mock ) ;
413413 var mockCircularCopy = Lib . extendDeep ( { } , mockCircular ) ;
414414
@@ -424,7 +424,6 @@ describe('sankey tests', function() {
424424 } ) ;
425425
426426 it ( 'switch from circular to normal Sankey on react' , function ( done ) {
427- var gd = createGraphDiv ( ) ;
428427 var mockCircularCopy = Lib . extendDeep ( { } , mockCircular ) ;
429428
430429 Plotly . plot ( gd , mockCircularCopy )
@@ -448,20 +447,43 @@ describe('sankey tests', function() {
448447 } ) ;
449448 } ) ;
450449
451- it ( 'can create groups' , function ( done ) {
452- var gd = createGraphDiv ( ) ;
450+ it ( 'can create groups, restyle groups and properly update DOM' , function ( done ) {
453451 var mockCircularCopy = Lib . extendDeep ( { } , mockCircular ) ;
454- mockCircularCopy . data [ 0 ] . node . groups = [ [ 2 , 3 ] , [ 0 , 1 ] ] ;
452+ var firstGroup = [ [ 2 , 3 ] , [ 0 , 1 ] ] ;
453+ var newGroup = [ [ 2 , 3 ] ] ;
454+ mockCircularCopy . data [ 0 ] . node . groups = firstGroup ;
455+
455456 Plotly . plot ( gd , mockCircularCopy )
456457 . then ( function ( ) {
457- expect ( gd . _fullData [ 0 ] . node . groups ) . toEqual ( [ [ 2 , 3 ] , [ 0 , 1 ] ] ) ;
458- return Plotly . restyle ( gd , { 'node.groups' : [ [ [ 3 , 4 ] ] ] } ) ;
458+ expect ( gd . _fullData [ 0 ] . node . groups ) . toEqual ( firstGroup ) ;
459+ return Plotly . restyle ( gd , { 'node.groups' : [ newGroup ] } ) ;
459460 } )
460461 . then ( function ( ) {
461- expect ( gd . _fullData [ 0 ] . node . groups ) . toEqual ( [ [ 3 , 4 ] ] ) ;
462- destroyGraphDiv ( ) ;
463- done ( ) ;
464- } ) ;
462+ expect ( gd . _fullData [ 0 ] . node . groups ) . toEqual ( newGroup ) ;
463+
464+ // Check that all links have updated their links
465+ d3 . selectAll ( '.sankey .sankey-link' ) . each ( function ( d , i ) {
466+ var path = this . getAttribute ( 'd' ) ;
467+ expect ( path ) . toBe ( d . linkPath ( ) ( d ) , 'link ' + i + ' has wrong `d` attribute' ) ;
468+ } ) ;
469+
470+ // Check that ghost nodes used for animations:
471+ // 1) are drawn first so they apear behind
472+ var seeRealNode = false ;
473+ var sankeyNodes = d3 . selectAll ( '.sankey .sankey-node' ) ;
474+ sankeyNodes . each ( function ( d , i ) {
475+ if ( d . partOfGroup ) {
476+ if ( seeRealNode ) fail ( 'node ' + i + ' is a ghost node and should be behind' ) ;
477+ } else {
478+ seeRealNode = true ;
479+ }
480+ } ) ;
481+ // 2) have an element for each grouped node
482+ var L = sankeyNodes . filter ( function ( d ) { return d . partOfGroup ; } ) . size ( ) ;
483+ expect ( L ) . toBe ( newGroup . flat ( ) . length , 'does not have the right number of ghost nodes' ) ;
484+ } )
485+ . catch ( failTest )
486+ . then ( done ) ;
465487 } ) ;
466488 } ) ;
467489
0 commit comments