@@ -32,6 +32,10 @@ export default class Tree extends React.Component {
32
32
this . handleOnMouseOutCb = this . handleOnMouseOutCb . bind ( this ) ;
33
33
}
34
34
35
+ componentWillMount ( ) {
36
+ this . internalState . d3 = this . calculateD3Geometry ( this . props ) ;
37
+ }
38
+
35
39
componentDidMount ( ) {
36
40
this . bindZoomListener ( this . props ) ;
37
41
this . internalState . initialRender = false ;
@@ -57,6 +61,8 @@ export default class Tree extends React.Component {
57
61
} ) ;
58
62
}
59
63
64
+ this . internalState . d3 = this . calculateD3Geometry ( nextProps ) ;
65
+
60
66
// If zoom-specific props change -> rebind listener with new values
61
67
if (
62
68
! deepEqual ( this . props . translate , nextProps . translate ) ||
@@ -110,7 +116,7 @@ export default class Tree extends React.Component {
110
116
translate : { x : event . translate [ 0 ] , y : event . translate [ 1 ] } ,
111
117
} ) ;
112
118
this . internalState . d3 . scale = event . scale ;
113
- this . internalState . d3 . translate = event . translate ;
119
+ this . internalState . d3 . translate = { x : event . translate [ 0 ] , y : event . translate [ 1 ] } ;
114
120
}
115
121
} )
116
122
// Offset so that first pan and zoom does not jump back to [0,0] coords
@@ -309,13 +315,38 @@ export default class Tree extends React.Component {
309
315
return { nodes, links } ;
310
316
}
311
317
318
+ /**
319
+ * calculateD3Geometry - Set initial zoom and position.
320
+ * Also limit zoom level according to `scaleExtent` on initial display. This is necessary,
321
+ * because the first time we are setting it as an SVG property, instead of going
322
+ * through D3's scaling mechanism, which would have picked up both properties.
323
+ *
324
+ * @param {object } nextProps
325
+ * @return {object } {translate: {x: number, y: number}, zoom: number }
326
+ */
327
+ calculateD3Geometry ( nextProps ) {
328
+ let scale ;
329
+
330
+ if ( nextProps . zoom > nextProps . scaleExtent . max ) {
331
+ scale = nextProps . scaleExtent . max ;
332
+ } else if ( nextProps . zoom < nextProps . scaleExtent . min ) {
333
+ scale = nextProps . scaleExtent . min ;
334
+ } else {
335
+ scale = nextProps . zoom ;
336
+ }
337
+
338
+ return {
339
+ translate : nextProps . translate ,
340
+ scale,
341
+ } ;
342
+ }
343
+
312
344
render ( ) {
313
345
const { nodes, links } = this . generateTree ( ) ;
314
346
const {
315
347
nodeSvgShape,
316
348
nodeLabelComponent,
317
349
orientation,
318
- translate,
319
350
pathFunc,
320
351
transitionDuration,
321
352
zoomable,
@@ -328,21 +359,10 @@ export default class Tree extends React.Component {
328
359
allowForeignObjects,
329
360
styles,
330
361
} = this . props ;
362
+ const { translate, scale } = this . internalState . d3 ;
331
363
332
364
const subscriptions = { ...nodeSize , ...separation , depthFactor, initialDepth } ;
333
365
334
- // Limit zoom level according to `scaleExtent` on initial display. This is necessary,
335
- // because the first time we are setting it as an SVG property, instead of going
336
- // through D3's scaling mechanism, which would have picked up both properties.
337
- let scale ;
338
- if ( this . props . zoom > this . props . scaleExtent . max ) {
339
- scale = this . props . scaleExtent . max ;
340
- } else if ( this . props . zoom < this . props . scaleExtent . min ) {
341
- scale = this . props . scaleExtent . min ;
342
- } else {
343
- scale = this . props . zoom ;
344
- }
345
-
346
366
return (
347
367
< div className = { `rd3t-tree-container ${ zoomable ? 'rd3t-grabbable' : undefined } ` } >
348
368
< svg className = "rd3t-svg" width = "100%" height = "100%" >
0 commit comments