Skip to content

Commit a8d149d

Browse files
committed
Re-implement stable zoom listener
1 parent 43b8482 commit a8d149d

File tree

1 file changed

+28
-23
lines changed

1 file changed

+28
-23
lines changed

src/Tree/index.js

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { PropTypes } from 'react';
22
import { TransitionGroup } from 'react-transition-group';
3-
import { layout } from 'd3';
3+
import { layout, select, behavior, event } from 'd3';
44
import clone from 'clone';
55
import uuid from 'uuid';
66

@@ -15,7 +15,6 @@ export default class Tree extends React.Component {
1515
this.state = {
1616
initialRender: true,
1717
data: this.assignInternalProperties(clone(props.data)),
18-
zoom: undefined,
1918
};
2019
this.findNodesById = this.findNodesById.bind(this);
2120
this.collapseNode = this.collapseNode.bind(this);
@@ -24,6 +23,7 @@ export default class Tree extends React.Component {
2423

2524

2625
componentDidMount() {
26+
this.bindZoomListener();
2727
// TODO find better way of setting initialDepth, re-render here is suboptimal
2828
this.setState({ initialRender: false }); // eslint-disable-line
2929
}
@@ -62,20 +62,24 @@ export default class Tree extends React.Component {
6262
*
6363
* @return {void}
6464
*/
65-
// bindZoomListener() {
66-
// const { zoomable, scaleExtent } = this.props;
67-
// const svg = select('.svg');
68-
//
69-
// if (zoomable) {
70-
// this.setState({ zoom: 'scale(1)' });
71-
// svg.call(behavior.zoom()
72-
// .scaleExtent([scaleExtent.min, scaleExtent.max])
73-
// .on('zoom', () => {
74-
// this.setState({ zoom: `scale(${event.scale})` });
75-
// })
76-
// );
77-
// }
78-
// }
65+
bindZoomListener() {
66+
const { zoomable, scaleExtent, translate } = this.props;
67+
const svg = select('.rd3t-svg');
68+
const g = select('.rd3t-g');
69+
70+
if (zoomable) {
71+
svg.call(behavior.zoom()
72+
.scaleExtent([scaleExtent.min, scaleExtent.max])
73+
.on('zoom', () => {
74+
g.attr('transform',
75+
`translate(${event.translate}) scale(${event.scale})`
76+
);
77+
})
78+
// Offset so that first pan and zoom does not jump back to [0,0] coords
79+
.translate([translate.x, translate.y])
80+
);
81+
}
82+
}
7983

8084

8185
/**
@@ -223,6 +227,7 @@ export default class Tree extends React.Component {
223227
<svg className="rd3t-svg" width="100%" height="100%">
224228
<TransitionGroup
225229
component="g"
230+
className="rd3t-g"
226231
transform={`translate(${translate.x},${translate.y})`}
227232
>
228233
{nodes.map((nodeData) =>
@@ -263,8 +268,8 @@ Tree.defaultProps = {
263268
depthFactor: undefined,
264269
collapsible: true,
265270
initialDepth: undefined,
266-
// zoomable: true,
267-
// scaleExtent: { min: 0.1, max: 1 },
271+
zoomable: true,
272+
scaleExtent: { min: 0.1, max: 1 },
268273
};
269274

270275
Tree.propTypes = {
@@ -285,9 +290,9 @@ Tree.propTypes = {
285290
depthFactor: PropTypes.number,
286291
collapsible: PropTypes.bool,
287292
initialDepth: PropTypes.number,
288-
// zoomable: PropTypes.bool,
289-
// scaleExtent: PropTypes.shape({
290-
// min: PropTypes.number,
291-
// max: PropTypes.number,
292-
// }),
293+
zoomable: PropTypes.bool,
294+
scaleExtent: PropTypes.shape({
295+
min: PropTypes.number,
296+
max: PropTypes.number,
297+
}),
293298
};

0 commit comments

Comments
 (0)