Skip to content

Commit 6cfd42d

Browse files
committed
Adds depthFactor prop + unit test (#5)
1 parent 616f840 commit 6cfd42d

File tree

3 files changed

+33
-8
lines changed

3 files changed

+33
-8
lines changed

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)