Skip to content

Commit 78b55c0

Browse files
committed
Reflow graph on subscribed prop change (#42)
1 parent 8d1d5bf commit 78b55c0

File tree

3 files changed

+30
-9
lines changed

3 files changed

+30
-9
lines changed

src/Node/index.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,21 @@ export default class Node extends React.Component {
3030
}
3131

3232
componentWillUpdate(nextProps) {
33-
const shouldTransform = this.shouldNodeTransform(this.props, nextProps);
34-
if (shouldTransform) {
35-
const transform = this.setTransformOrientation(
36-
nextProps.nodeData.x,
37-
nextProps.nodeData.y,
38-
nextProps.orientation,
39-
);
40-
this.applyTransform(transform, nextProps.transitionDuration);
41-
}
33+
const transform = this.setTransformOrientation(
34+
nextProps.nodeData.x,
35+
nextProps.nodeData.y,
36+
nextProps.orientation,
37+
);
38+
this.applyTransform(transform, nextProps.transitionDuration);
39+
}
40+
41+
shouldComponentUpdate(nextProps) {
42+
return this.shouldNodeTransform(this.props, nextProps);
4243
}
4344

4445
shouldNodeTransform(ownProps, nextProps) {
4546
return (
47+
nextProps.subscriptions !== ownProps.subscriptions ||
4648
nextProps.nodeData.x !== ownProps.nodeData.x ||
4749
nextProps.nodeData.y !== ownProps.nodeData.y ||
4850
nextProps.orientation !== ownProps.orientation
@@ -161,6 +163,7 @@ Node.propTypes = {
161163
name: PropTypes.string.isRequired,
162164
attributes: PropTypes.object,
163165
textLayout: PropTypes.object.isRequired,
166+
subscriptions: PropTypes.object.isRequired, // eslint-disable-line react/no-unused-prop-types
164167
circleRadius: PropTypes.number,
165168
styles: PropTypes.object,
166169
};

src/Node/tests/index.test.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ describe('<Node />', () => {
3737
x: 10,
3838
y: -10,
3939
},
40+
subscriptions: {},
4041
styles: {},
4142
};
4243

@@ -212,6 +213,16 @@ describe('<Node />', () => {
212213
).toBe(true);
213214
});
214215

216+
it('updates its position if any subscribed top-level props change', () => {
217+
const subscriptions = { x: 12, y: 10, initialDepth: undefined };
218+
const renderedComponent = mount(<Node {...mockProps} subscriptions={subscriptions} />);
219+
const nextProps = { ...mockProps, subscriptions: { ...subscriptions, initialDepth: 1 } };
220+
221+
expect(
222+
renderedComponent.instance().shouldNodeTransform(renderedComponent.props(), nextProps),
223+
).toBe(true);
224+
});
225+
215226
it('allows passing SVG shape elements + shapeProps to be used as the node element', () => {
216227
const fixture = { shape: 'ellipse', shapeProps: { rx: 20, ry: 10 } };
217228
const props = { ...mockProps, nodeSvgShape: fixture };

src/Tree/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,10 +250,16 @@ export default class Tree extends React.Component {
250250
transitionDuration,
251251
zoomable,
252252
textLayout,
253+
nodeSize,
254+
depthFactor,
255+
initialDepth,
256+
separation,
253257
circleRadius,
254258
styles,
255259
} = this.props;
256260

261+
const subscriptions = { ...nodeSize, ...separation, depthFactor, initialDepth };
262+
257263
return (
258264
<div className={`rd3t-tree-container ${zoomable ? 'rd3t-grabbable' : undefined}`}>
259265
<svg className="rd3t-svg" width="100%" height="100%">
@@ -285,6 +291,7 @@ export default class Tree extends React.Component {
285291
onClick={this.handleNodeToggle}
286292
textLayout={textLayout}
287293
circleRadius={circleRadius}
294+
subscriptions={subscriptions}
288295
styles={styles.nodes}
289296
/>
290297
))}

0 commit comments

Comments
 (0)