@@ -13,6 +13,12 @@ var getModuleCalcData = require('../../plots/get_data').getModuleCalcData;
1313var plot = require ( './plot' ) ;
1414var fxAttrs = require ( '../../components/fx/layout_attributes' ) ;
1515
16+ var setCursor = require ( '../../lib/setcursor' ) ;
17+ var dragElement = require ( '../../components/dragelement' ) ;
18+ var prepSelect = require ( '../../plots/cartesian/select' ) . prepSelect ;
19+ var Lib = require ( '../../lib' ) ;
20+ var Registry = require ( '../../registry' ) ;
21+
1622var SANKEY = 'sankey' ;
1723
1824exports . name = SANKEY ;
@@ -24,6 +30,7 @@ exports.baseLayoutAttrOverrides = overrideAll({
2430exports . plot = function ( gd ) {
2531 var calcData = getModuleCalcData ( gd . calcdata , SANKEY ) [ 0 ] ;
2632 plot ( gd , calcData ) ;
33+ exports . updateFx ( gd ) ;
2734} ;
2835
2936exports . clean = function ( newFullData , newFullLayout , oldFullData , oldFullLayout ) {
@@ -32,5 +39,99 @@ exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout)
3239
3340 if ( hadPlot && ! hasPlot ) {
3441 oldFullLayout . _paperdiv . selectAll ( '.sankey' ) . remove ( ) ;
42+ oldFullLayout . _paperdiv . selectAll ( '.bgsankey' ) . remove ( ) ;
3543 }
3644} ;
45+
46+ exports . updateFx = function ( gd ) {
47+ for ( var i = 0 ; i < gd . _fullData . length ; i ++ ) {
48+ subplotUpdateFx ( gd , i ) ;
49+ }
50+ } ;
51+
52+ function subplotUpdateFx ( gd , index ) {
53+ var trace = gd . _fullData [ index ] ;
54+ var fullLayout = gd . _fullLayout ;
55+
56+ var dragMode = fullLayout . dragmode ;
57+ var cursor = fullLayout . dragmode === 'pan' ? 'move' : 'crosshair' ;
58+ var bgRect = trace . _bgRect ;
59+
60+ if ( dragMode === 'pan' || dragMode === 'zoom' ) return ;
61+
62+ setCursor ( bgRect , cursor ) ;
63+
64+ var xaxis = {
65+ _id : 'x' ,
66+ c2p : Lib . identity ,
67+ _offset : trace . _sankey . translateX ,
68+ _length : trace . _sankey . width
69+ } ;
70+ var yaxis = {
71+ _id : 'y' ,
72+ c2p : Lib . identity ,
73+ _offset : trace . _sankey . translateY ,
74+ _length : trace . _sankey . height
75+ } ;
76+
77+ // Note: dragOptions is needed to be declared for all dragmodes because
78+ // it's the object that holds persistent selection state.
79+ var dragOptions = {
80+ gd : gd ,
81+ element : bgRect . node ( ) ,
82+ plotinfo : {
83+ id : index ,
84+ xaxis : xaxis ,
85+ yaxis : yaxis ,
86+ fillRangeItems : Lib . noop
87+ } ,
88+ subplot : index ,
89+ // create mock x/y axes for hover routine
90+ xaxes : [ xaxis ] ,
91+ yaxes : [ yaxis ] ,
92+ doneFnCompleted : function ( selection ) {
93+ var traceNow = gd . _fullData [ index ] ;
94+ var newGroups ;
95+ var oldGroups = traceNow . node . groups . slice ( ) ;
96+ var newGroup = [ ] ;
97+
98+ function findNode ( pt ) {
99+ var nodes = traceNow . _sankey . graph . nodes ;
100+ for ( var i = 0 ; i < nodes . length ; i ++ ) {
101+ if ( nodes [ i ] . pointNumber === pt ) return nodes [ i ] ;
102+ }
103+ }
104+
105+ for ( var j = 0 ; j < selection . length ; j ++ ) {
106+ var node = findNode ( selection [ j ] . pointNumber ) ;
107+ if ( ! node ) continue ;
108+
109+ // If the node represents a group
110+ if ( node . group ) {
111+ // Add all its children to the current selection
112+ for ( var k = 0 ; k < node . childrenNodes . length ; k ++ ) {
113+ newGroup . push ( node . childrenNodes [ k ] . pointNumber ) ;
114+ }
115+ // Flag group for removal from existing list of groups
116+ oldGroups [ node . pointNumber - traceNow . node . _count ] = false ;
117+ } else {
118+ newGroup . push ( node . pointNumber ) ;
119+ }
120+ }
121+
122+ newGroups = oldGroups
123+ . filter ( Boolean )
124+ . concat ( [ newGroup ] ) ;
125+
126+ Registry . call ( '_guiRestyle' , gd , {
127+ 'node.groups' : [ newGroups ]
128+ } , index ) ;
129+ }
130+ } ;
131+
132+ dragOptions . prepFn = function ( e , startX , startY ) {
133+ prepSelect ( e , startX , startY , dragOptions , dragMode ) ;
134+ } ;
135+
136+ dragElement . init ( dragOptions ) ;
137+ }
0 commit comments