@@ -52,11 +52,20 @@ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || func
52
52
function _defineProperty ( obj , key , value ) { if ( key in obj ) { Object . defineProperty ( obj , key , { value : value , enumerable : true , configurable : true , writable : true } ) ; } else { obj [ key ] = value ; } return obj ; }
53
53
54
54
var pathDimensionFunctions = {
55
+ /**
56
+ * Draw a bezier path from startPt to endPt.
57
+ *
58
+ * @param {Object } startPt - Object with x and y coordinates.
59
+ * @param {Object } endPt - Object with x and y coordinates.
60
+ * @param {Number[] } [ledgeWidths] - Little widths of line right before/after node. To allow for horizontal arrow.
61
+ * @returns {string } 'd' attribute value for an SVG path.
62
+ */
55
63
'drawBezierEdge' : function drawBezierEdge ( startPt , endPt , columnSpacing , rowSpacing , nodeEdgeLedgeWidths ) {
56
64
var ledgeWidths = nodeEdgeLedgeWidths ;
57
65
var path = d3 . path ( ) ;
58
66
path . moveTo ( startPt . x , startPt . y ) ;
59
- path . lineTo ( startPt . x + ledgeWidths [ 0 ] , startPt . y ) ;
67
+ path . lineTo ( startPt . x + ledgeWidths [ 0 ] , startPt . y ) ; // First ledge
68
+
60
69
var nodeXDif = Math . abs ( endPt . x - startPt . x ) ;
61
70
var bezierStartPt = {
62
71
'x' : startPt . x + ledgeWidths [ 0 ] ,
@@ -67,8 +76,11 @@ var pathDimensionFunctions = {
67
76
'y' : endPt . y
68
77
} ;
69
78
70
- if ( nodeXDif > columnSpacing ) {
71
- bezierStartPt . x += Math . max ( 0 , nodeXDif - columnSpacing * ( Math . abs ( endPt . y - startPt . y ) / rowSpacing * 2.5 ) ) ;
79
+ if ( nodeXDif > columnSpacing
80
+ /* && Math.abs(endPt.y - startPt.y) <= this.props.rowSpacing * 2*/
81
+ ) {
82
+ // Draw straight line until last section. Length depending on how close together y-axes are (revert to default bezier if far apart).
83
+ bezierStartPt . x += Math . max ( 0 , nodeXDif - columnSpacing * ( Math . abs ( endPt . y - startPt . y ) / rowSpacing * 2.5 ) ) ; //path.lineTo(bezierStartPt.x, bezierStartPt.y);
72
84
}
73
85
74
86
var bezierXDif = Math . abs ( bezierStartPt . x - bezierEndPt . x ) ;
@@ -81,13 +93,18 @@ var pathDimensionFunctions = {
81
93
} ] ;
82
94
83
95
if ( startPt . x > endPt . x ) {
96
+ // Our input edge appears AFTER the target.
97
+ //var dif = Math.min(1, 5 / Math.max(1, Math.abs(endPt.y - startPt.y) )) * (this.props.rowSpacing || 75);
84
98
var dif = Math . max ( rowSpacing || 75 ) ;
85
99
controlPoints [ 0 ] . y += dif * ( endPt . y >= startPt . y ? 1 : - 1 ) ;
86
100
controlPoints [ 1 ] . y += dif * ( endPt . y - startPt . y > rowSpacing ? - 1 : 1 ) ;
87
101
controlPoints [ 1 ] . x = endPt . x - Math . abs ( endPt . x - startPt . x ) * .5 ;
88
102
}
89
103
90
- path . bezierCurveTo ( controlPoints [ 0 ] . x , controlPoints [ 0 ] . y , controlPoints [ 1 ] . x , controlPoints [ 1 ] . y , bezierEndPt . x , endPt . y ) ;
104
+ path . bezierCurveTo ( controlPoints [ 0 ] . x , controlPoints [ 0 ] . y , // - pathAscend,
105
+ controlPoints [ 1 ] . x , controlPoints [ 1 ] . y , // + pathAscend,
106
+ bezierEndPt . x , endPt . y ) ; // Final ledge
107
+
91
108
path . lineTo ( endPt . x , endPt . y ) ;
92
109
return path . toString ( ) ;
93
110
} ,
@@ -120,15 +137,21 @@ var pathDimensionFunctions = {
120
137
adjVertices [ adjVertices . length - 2 ] [ 0 ] -= nodeEdgeLedgeWidths [ 0 ] ;
121
138
}
122
139
123
- adjVertices [ 0 ] [ 0 ] = startPt && startPt . x || adjVertices [ 0 ] [ 0 ] ;
124
- adjVertices [ adjVertices . length - 1 ] [ 0 ] = endPt && endPt . x || adjVertices [ adjVertices . length - 1 ] [ 0 ] ;
140
+ adjVertices [ 0 ] [ 0 ] = startPt && startPt . x || adjVertices [ 0 ] [ 0 ] ; // + nodeEdgeLedgeWidths[0];
141
+
142
+ adjVertices [ adjVertices . length - 1 ] [ 0 ] = endPt && endPt . x || adjVertices [ adjVertices . length - 1 ] [ 0 ] ; // - nodeEdgeLedgeWidths[1];
143
+
125
144
var lineGenFxn = d3 . line ( ) . x ( function ( d ) {
126
145
return d [ 0 ] ;
127
146
} ) . y ( function ( d ) {
128
147
return d [ 1 ] ;
129
148
} ) . curve ( d3 . curveMonotoneX ) ;
130
149
return lineGenFxn ( adjVertices ) ;
131
150
} ,
151
+
152
+ /**
153
+ * @deprecated
154
+ */
132
155
'drawStraightEdge' : function drawStraightEdge ( startPt , endPt ) {
133
156
var path = d3 . path ( ) ;
134
157
path . moveTo ( startPt . x , startPt . y ) ;
@@ -139,7 +162,9 @@ var pathDimensionFunctions = {
139
162
} ;
140
163
exports . pathDimensionFunctions = pathDimensionFunctions ;
141
164
142
- var Edge = function ( _React$Component ) {
165
+ var Edge =
166
+ /*#__PURE__*/
167
+ function ( _React$Component ) {
143
168
_inherits ( Edge , _React$Component ) ;
144
169
145
170
_createClass ( Edge , null , [ {
@@ -150,7 +175,11 @@ var Edge = function (_React$Component) {
150
175
} , {
151
176
key : "isRelated" ,
152
177
value : function isRelated ( edge , selectedNode ) {
153
- return _Node [ "default" ] . isRelated ( edge . source , selectedNode ) ;
178
+ return _Node [ "default" ] . isRelated ( edge . source , selectedNode ) ; // Enable the following later _if_ we go beyond 1 input node deep.
179
+ //return (
180
+ // Node.isRelated(edge.source, selectedNode) ||
181
+ // Node.isRelated(edge.target, selectedNode)
182
+ //);
154
183
}
155
184
} , {
156
185
key : "isDistantlySelected" ,
@@ -250,7 +279,9 @@ var Edge = function (_React$Component) {
250
279
251
280
_this = _possibleConstructorReturn ( this , _getPrototypeOf ( Edge ) . call ( this , props ) ) ;
252
281
_this . generatePathDimension = _this . generatePathDimension . bind ( _assertThisInitialized ( _this ) ) ;
253
- _this . transitionPathDimensions = _this . transitionPathDimensions . bind ( _assertThisInitialized ( _this ) ) ;
282
+ _this . transitionPathDimensions = _this . transitionPathDimensions . bind ( _assertThisInitialized ( _this ) ) ; // Create own memoized copy/instance of intensive static functions.
283
+ // Otherwise if left static, will be re-ran each time as many edges call it.
284
+
254
285
_this . memoized = {
255
286
isDistantlySelected : ( 0 , _memoizeOne [ "default" ] ) ( Edge . isDistantlySelected ) ,
256
287
isRelated : ( 0 , _memoizeOne [ "default" ] ) ( Edge . isRelated ) ,
@@ -265,7 +296,9 @@ var Edge = function (_React$Component) {
265
296
_this . getComputedProperties = _this . getComputedProperties . bind ( _assertThisInitialized ( _this ) ) ;
266
297
_this . state = {
267
298
'pathDimension' : _this . generatePathDimension ( )
268
- } ;
299
+ } ; // Alternative implementation of transition -
300
+ // adjust pathRef.current `d` attribute manually
301
+
269
302
_this . pathRef = _react [ "default" ] . createRef ( ) ;
270
303
return _this ;
271
304
}
@@ -297,6 +330,11 @@ var Edge = function (_React$Component) {
297
330
distantlySelected : distantlySelected
298
331
} ;
299
332
}
333
+ /**
334
+ * If any of our nodes' coordinates have updated, update state.pathDimension either via a D3 animation tween acting on setState or instantly via setState.
335
+ * Whether instant or gradual dimension update is based on result of `this.shouldDoTransitionOfEdge()` : boolean
336
+ */
337
+
300
338
} , {
301
339
key : "componentDidUpdate" ,
302
340
value : function componentDidUpdate ( pastProps ) {
@@ -309,20 +347,25 @@ var Edge = function (_React$Component) {
309
347
310
348
if ( Edge . didNodeCoordinatesChange ( this . props , pastProps ) ) {
311
349
if ( ! this . shouldDoTransitionOfEdge ( ) ) {
350
+ // Instant
312
351
this . setState ( {
313
352
'pathDimension' : this . generatePathDimension ( )
314
353
} ) ;
315
354
} else {
355
+ // Animate
316
356
var startEndPtCoords = [ {
317
357
'x' : pastProps . startX ,
318
358
'y' : pastProps . startY
319
- } , {
359
+ } , // StartA
360
+ {
320
361
'x' : startX ,
321
362
'y' : startY
322
- } , {
363
+ } , // StartB
364
+ {
323
365
'x' : pastProps . endX ,
324
366
'y' : pastProps . endY
325
- } , {
367
+ } , // StartA
368
+ {
326
369
'x' : endX ,
327
370
'y' : endY
328
371
} ] ;
@@ -334,6 +377,7 @@ var Edge = function (_React$Component) {
334
377
}
335
378
}
336
379
} else if ( ! _underscore [ "default" ] . isEqual ( this . getPathOffsets ( ) , this . getPathOffsets ( pastProps ) ) ) {
380
+ // Instant
337
381
this . setState ( {
338
382
'pathDimension' : this . generatePathDimension ( )
339
383
} ) ;
@@ -359,18 +403,35 @@ var Edge = function (_React$Component) {
359
403
if ( this . props [ propKeys [ i ] ] !== nextProps [ propKeys [ i ] ] ) {
360
404
return true ;
361
405
}
362
- }
406
+ } // If state.pathDimension changes we _do not_ update, since DOM elements should already be transitioned.
407
+
363
408
364
409
return false ;
365
410
}
366
411
} , {
367
412
key : "shouldDoTransitionOfEdge" ,
368
413
value : function shouldDoTransitionOfEdge ( ) {
369
414
var props = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : this . props ;
370
- if ( props . noTransition ) return false ;
415
+ if ( props . noTransition ) return false ; // Until we adjust all Edges to transition within a single DOM update/redraw,
416
+ // we optimize by not transitioning unless <= 50 edges.
417
+ // This is because each Edge currently launches own transition
418
+ // which cascades into an exponential number of transitions/viewport-updates.
419
+
371
420
if ( props . edgeCount > 60 ) return false ;
372
421
return true ;
373
422
}
423
+ /**
424
+ * Transitions edge dimensions over time.
425
+ * Updates `state.pathDimension` incrementally using d3.transition().
426
+ *
427
+ * @todo
428
+ * In future, all transitions could be done in `EdgesLayer` instead of `Edge`,
429
+ * this would allow us to batch all the DOM updates into a single function wrapped
430
+ * in a `requestAnimationFrame` call. This will require some dynamic programming as
431
+ * well as caching of ege:node-coords to detect changes and run transitions.
432
+ * The changeTween itself should transition _all_ Edges that need to be transitioned.
433
+ */
434
+
374
435
} , {
375
436
key : "transitionPathDimensions" ,
376
437
value : function transitionPathDimensions ( startPtA , startPtB , endPtA , endPtB , startVertices , endVertices ) {
@@ -388,7 +449,8 @@ var Edge = function (_React$Component) {
388
449
} ) ;
389
450
}
390
451
391
- var pathElem = this . pathRef . current ;
452
+ var pathElem = this . pathRef . current ; // Necessary if using alternate transition approach(es).
453
+
392
454
if ( ! pathElem ) return ;
393
455
d3 . select ( this ) . interrupt ( ) . transition ( ) . ease ( d3 . easeQuadOut ) . duration ( 500 ) . tween ( "changeDimension" , function changeTween ( ) {
394
456
return function ( t ) {
0 commit comments