Skip to content

Commit 1bffaa5

Browse files
sspanakbkrem
authored andcommitted
Fixed onUpdate receiving incorrect 'translate' and 'zoom' on force update (#79)
1 parent d940b7c commit 1bffaa5

File tree

2 files changed

+38
-16
lines changed

2 files changed

+38
-16
lines changed

src/Tree/index.js

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ export default class Tree extends React.Component {
3232
this.handleOnMouseOutCb = this.handleOnMouseOutCb.bind(this);
3333
}
3434

35+
componentWillMount() {
36+
this.internalState.d3 = this.calculateD3Geometry(this.props);
37+
}
38+
3539
componentDidMount() {
3640
this.bindZoomListener(this.props);
3741
this.internalState.initialRender = false;
@@ -57,6 +61,8 @@ export default class Tree extends React.Component {
5761
});
5862
}
5963

64+
this.internalState.d3 = this.calculateD3Geometry(nextProps);
65+
6066
// If zoom-specific props change -> rebind listener with new values
6167
if (
6268
!deepEqual(this.props.translate, nextProps.translate) ||
@@ -110,7 +116,7 @@ export default class Tree extends React.Component {
110116
translate: { x: event.translate[0], y: event.translate[1] },
111117
});
112118
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] };
114120
}
115121
})
116122
// 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 {
309315
return { nodes, links };
310316
}
311317

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+
312344
render() {
313345
const { nodes, links } = this.generateTree();
314346
const {
315347
nodeSvgShape,
316348
nodeLabelComponent,
317349
orientation,
318-
translate,
319350
pathFunc,
320351
transitionDuration,
321352
zoomable,
@@ -328,21 +359,10 @@ export default class Tree extends React.Component {
328359
allowForeignObjects,
329360
styles,
330361
} = this.props;
362+
const { translate, scale } = this.internalState.d3;
331363

332364
const subscriptions = { ...nodeSize, ...separation, depthFactor, initialDepth };
333365

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-
346366
return (
347367
<div className={`rd3t-tree-container ${zoomable ? 'rd3t-grabbable' : undefined}`}>
348368
<svg className="rd3t-svg" width="100%" height="100%">

src/Tree/tests/index.test.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,11 @@ describe('<Tree />', () => {
180180
});
181181

182182
it('respects `scaleExtent` constraints on initital display', () => {
183-
const scaleExtent = { min: 0.2, max: 1.5 };
183+
const scaleExtent = { min: 0.2, max: 0.8 };
184184

185-
let renderedComponent = shallow(<Tree data={mockData} scaleExtent={scaleExtent} zoom={2} />);
185+
let renderedComponent = shallow(
186+
<Tree data={mockData} scaleExtent={scaleExtent} zoom={0.9} />,
187+
);
186188
expect(renderedComponent.find(TransitionGroup).prop('transform')).toContain(
187189
`scale(${scaleExtent.max})`,
188190
);

0 commit comments

Comments
 (0)