Skip to content

Commit d350fe6

Browse files
committed
Merge branch 'feature/5-add-fixed-depth' into develop
2 parents 749679b + 381d18f commit d350fe6

File tree

5 files changed

+48
-20
lines changed

5 files changed

+48
-20
lines changed

README.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,14 @@ class MyComponent extends Component {
5959
```
6060

6161
## Props
62-
| Property | Type | Options | Required? | Default | Description |
63-
|----------------|-----------------|-------------------------|-----------|-------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
64-
| `data` | `array` | | required | `undefined` | Single-element array containing hierarchical object (see `myTreeData` above); contains (at least) `name` and `parent` keys. |
65-
| `orientation` | `string` (enum) | `horizontal` `vertical` | | `horizontal` | `horizontal` - Tree expands left-to-right. `vertical` - Tree expands top-to-bottom |
66-
| `translate` | `object` | | | `{x: 0, y: 0}` | Translates the graph along the x/y axis by the specified amount of pixels (avoids the graph being stuck in the top left canvas corner) |
67-
| `pathFunc` | `string` (enum) | `diagonal` `elbow` | | `diagonal` | `diagonal` - Renders smooth, curved edges between parent-child nodes. `elbow` - Renders sharp edges at right angles between parent-child nodes |
68-
| `collapsible` | `bool` | | | `true` | Toggles ability to collapse/expand the tree's nodes by clicking them |
69-
| `initialDepth` | `number` | `0` or greater | | `undefined` | Sets the maximum node depth to which the tree is expanded on its initial render; tree renders to full depth if prop is omitted. |
70-
| `zoomable` | `bool` | | | `true` | Toggles ability to zoom in/out on the Tree by scaling the SVG element according to `props.scaleExtent` |
71-
| `scaleExtent` | `object` | | | `{min: 0.1, max: 1}` | Sets the minimum/maximum extent to which the tree can be scaled if `props.zoomable` is true |
62+
| Property | Type | Options | Required? | Default | Description |
63+
|----------------|-----------------|-------------------------|-----------|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
64+
| `data` | `array` | | required | `undefined` | Single-element array containing hierarchical object (see `myTreeData` above). <br /> Contains (at least) `name` and `parent` keys. |
65+
| `orientation` | `string` (enum) | `horizontal` `vertical` | | `horizontal` | `horizontal` - Tree expands left-to-right. <br /><br /> `vertical` - Tree expands top-to-bottom. |
66+
| `translate` | `object` | | | `{x: 0, y: 0}` | Translates the graph along the x/y axis by the specified amount of pixels (avoids the graph being stuck in the top left canvas corner). |
67+
| `pathFunc` | `string` (enum) | `diagonal` `elbow` | | `diagonal` | `diagonal` - Renders smooth, curved edges between parent-child nodes. <br /><br /> `elbow` - Renders sharp edges at right angles between parent-child nodes. |
68+
| `collapsible` | `bool` | | | `true` | Toggles ability to collapse/expand the tree's nodes by clicking them. |
69+
| `initialDepth` | `number` | `0..n` | | `undefined` | Sets the maximum node depth to which the tree is expanded on its initial render. <br /> Tree renders to full depth if prop is omitted. |
70+
| `zoomable` | `bool` | | | `true` | Toggles ability to zoom in/out on the Tree by scaling the SVG element according to `props.scaleExtent`. |
71+
| `scaleExtent` | `object` | | | `{min: 0.1, max: 1}` | Sets the minimum/maximum extent to which the tree can be scaled if `props.zoomable` is true. |
72+
| `depthFactor` | `number` | `-n..0..n` | | `undefined` | Ensures the tree takes up a fixed amount of space (`node.y = node.depth * depthFactor`), regardless of tree depth. <br /> **TIP**: Negative values invert the tree's direction. |

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
"build": "npm run clean && webpack --progress --colors --env build",
99
"dev": "npm run clean && webpack --progress --colors --watch --env dev",
1010
"lint": "eslint .",
11-
"test": "npm run lint && jest --coverage",
11+
"test": "npm run lint && jest --coverage --verbose",
1212
"test:clean": "rimraf ./coverage",
1313
"test:watch": "jest --watchAll",
14-
"coveralls": "cat ./coverage/lcov.info | coveralls"
14+
"coveralls": "cat ./coverage/lcov.info | coveralls",
15+
"show:cov": "open coverage/lcov-report/index.html"
1516
},
1617
"jest": {
1718
"collectCoverageFrom": [
@@ -63,6 +64,7 @@
6364
"react-addons-test-utils": "15.4.2",
6465
"react-dom": "15.4.2",
6566
"regenerator-runtime": "^0.10.5",
67+
"rimraf": "^2.6.1",
6668
"style-loader": "^0.17.0",
6769
"webpack": "2.4.1",
6870
"yargs": "7.1.0"

src/Node/index.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ import uuid from 'uuid';
44
import './style.css';
55

66
function Node(props) {
7-
const { nodeData, orientation } = props;
7+
const { nodeData, orientation, depthFactor } = props;
8+
9+
// Normalise node position for fixed depth
10+
if (depthFactor) {
11+
nodeData.y = nodeData.depth * depthFactor;
12+
}
13+
814
const transform = orientation === 'horizontal' ?
915
`translate(${nodeData.y},${nodeData.x})` :
1016
`translate(${nodeData.x},${nodeData.y})`;
@@ -70,6 +76,7 @@ Node.propTypes = {
7076
'vertical',
7177
]).isRequired,
7278
onClick: PropTypes.func,
79+
depthFactor: PropTypes.number,
7380
primaryLabel: PropTypes.string,
7481
primaryLabelStyle: PropTypes.object,
7582
secondaryLabels: PropTypes.object,

src/Node/tests/index.test.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ describe('<Node />', () => {
77
const nodeData = {
88
id: 'abc123',
99
name: 'mockNode',
10+
depth: 3,
1011
x: 123,
1112
y: 321,
1213
};
1314

14-
it('should have the correct `id` attribute value', () => {
15+
it('has the correct `id` attribute value', () => {
1516
const renderedComponent = shallow(
1617
<Node
1718
nodeData={nodeData}
@@ -22,7 +23,7 @@ describe('<Node />', () => {
2223
expect(renderedComponent.find('g').prop('id')).toBe(nodeData.id);
2324
});
2425

25-
it('should apply correct base className if `nodeData._children` is defined', () => {
26+
it('applies correct base className if `nodeData._children` is defined', () => {
2627
const noChildrenComponent = shallow(
2728
<Node
2829
nodeData={nodeData}
@@ -40,7 +41,7 @@ describe('<Node />', () => {
4041
expect(withChildrenComponent.prop('className')).toBe('nodeBase');
4142
});
4243

43-
it('should apply correct <circle> style prop if `nodeData._children` is defined', () => {
44+
it('applies correct <circle> style prop if `nodeData._children` is defined', () => {
4445
const leafCircleStyle = { fill: 'blue' };
4546
const circleStyle = { fill: 'green' };
4647
const noChildrenComponent = shallow(
@@ -64,7 +65,7 @@ describe('<Node />', () => {
6465
expect(withChildrenComponent.find('circle').prop('style')).toBe(circleStyle);
6566
});
6667

67-
it('should apply correct `transform` prop, depending on parent `orientation`', () => {
68+
it('applies correct `transform` prop, depending on parent `orientation`', () => {
6869
const horizontalTransform = `translate(${nodeData.y},${nodeData.x})`;
6970
const verticalTransform = `translate(${nodeData.x},${nodeData.y})`;
7071
const horizontalComponent = shallow(
@@ -96,7 +97,7 @@ describe('<Node />', () => {
9697
expect(renderedComponent.prop('onClick')).toBeDefined();
9798
});
9899

99-
it('should handle click events and pass the nodeId to onClick handler', () => {
100+
it('handles click events and pass the nodeId to onClick handler', () => {
100101
const onClickSpy = jest.fn();
101102
const renderedComponent = shallow(
102103
<Node
@@ -110,7 +111,7 @@ describe('<Node />', () => {
110111
expect(onClickSpy).toHaveBeenCalledWith(nodeData.id);
111112
});
112113

113-
it('should map each `props.secondaryLabels` to a <tspan> element', () => {
114+
it('maps each `props.secondaryLabels` to a <tspan> element', () => {
114115
const fixture = { keyA: 'valA', keyB: 'valB' };
115116
const renderedComponent = shallow(
116117
<Node
@@ -130,4 +131,18 @@ describe('<Node />', () => {
130131
n.text() === `keyB: ${fixture.keyB}`).length
131132
).toBe(1);
132133
});
134+
135+
it('mutates a node\'s `y` property according to `depthFactor`, when specified', () => {
136+
const depthFactor = 100;
137+
const expectedY = nodeData.depth * depthFactor;
138+
const renderedComponent = shallow(
139+
<Node
140+
nodeData={nodeData}
141+
orientation="vertical"
142+
depthFactor={depthFactor}
143+
/>
144+
);
145+
146+
expect(renderedComponent.prop('transform')).toBe(`translate(${nodeData.x},${expectedY})`);
147+
});
133148
});

src/Tree/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ export default class Tree extends React.Component {
206206
}
207207

208208
render() {
209-
const { orientation, translate, pathFunc } = this.props;
209+
const { orientation, translate, pathFunc, depthFactor } = this.props;
210210
const { nodes, links } = this.generateTree();
211211
return (
212212
<div className="treeContainer">
@@ -225,6 +225,7 @@ export default class Tree extends React.Component {
225225
<Node
226226
key={nodeData.id}
227227
orientation={orientation}
228+
depthFactor={depthFactor}
228229
textAnchor="start"
229230
nodeData={nodeData}
230231
primaryLabel={nodeData.name}
@@ -253,6 +254,7 @@ Tree.defaultProps = {
253254
orientation: 'horizontal',
254255
translate: { x: 0, y: 0 },
255256
pathFunc: 'diagonal',
257+
depthFactor: undefined,
256258
collapsible: true,
257259
initialDepth: undefined,
258260
zoomable: true,
@@ -273,6 +275,7 @@ Tree.propTypes = {
273275
'diagonal',
274276
'elbow',
275277
]),
278+
depthFactor: PropTypes.number,
276279
collapsible: PropTypes.bool,
277280
initialDepth: PropTypes.number,
278281
zoomable: PropTypes.bool,

0 commit comments

Comments
 (0)