Skip to content

Commit 4118288

Browse files
sspanakbkrem
authored andcommitted
Individual node shapes (#82)
* each node can now have individual shape * updated unit tests * updated README.md
1 parent 697387a commit 4118288

File tree

3 files changed

+85
-1
lines changed

3 files changed

+85
-1
lines changed

README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,58 @@ This is to prevent breaking the legacy usage of `circleRadius` + styling via `no
140140
**From v1.5.x onwards, it is therefore recommended to pass all node styling properties through `shapeProps`**.
141141

142142

143+
### Individual `shapeProps`
144+
`shapeProps` can be passed to a given node individually. The shape is optionally added as `shape` property to input data. This allows for setting style, shape and size of nodes independently (see [Styling](#styling)).
145+
146+
The usage example above can be extended to include individual `shapeProps`:
147+
```jsx
148+
import React from 'react';
149+
import Tree from 'react-d3-tree';
150+
151+
const myTreeData = [
152+
{
153+
name: 'Parent Node',
154+
attributes: {
155+
keyA: 'val A',
156+
keyB: 'val B',
157+
keyC: 'val C',
158+
},
159+
shape: {
160+
shapeProps: {
161+
fill: 'blue',
162+
},
163+
},
164+
children: [
165+
{
166+
name: 'Inner Node',
167+
attributes: {
168+
keyA: 'val A',
169+
keyB: 'val B',
170+
keyC: 'val C',
171+
},
172+
shape: {
173+
shape: 'rect',
174+
shapeProps: {
175+
width: 20,
176+
height: 20,
177+
x: -10,
178+
y: -10,
179+
fill: red,
180+
},
181+
},
182+
},
183+
{
184+
name: 'Level 2: B',
185+
},
186+
],
187+
},
188+
];
189+
190+
...
191+
192+
```
193+
In the above, "Parent Node" will only be blue, but it will keep the default size and geometrical shape. "Inner Node", however, will completely change to a red rectangle with the given dimensions. Omitting `shape`, will keep node's default appearance.
194+
143195
## Styling
144196
The tree's `styles` prop may be used to override any of the tree's default styling.
145197
The following object shape is expected by `styles`:

src/Tree/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ export default class Tree extends React.Component {
385385
{nodes.map(nodeData => (
386386
<Node
387387
key={nodeData.id}
388-
nodeSvgShape={nodeSvgShape}
388+
nodeSvgShape={{ ...nodeSvgShape, ...nodeData.shape }}
389389
nodeLabelComponent={nodeLabelComponent}
390390
nodeSize={nodeSize}
391391
orientation={orientation}

src/Tree/tests/index.test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,38 @@ describe('<Tree />', () => {
3232
expect(renderedComponent.find(Node).length).toBe(nodeCount);
3333
});
3434

35+
it('passes individual `shapeProps` to the specified <Node /> only', () => {
36+
const svgShapeMock = {
37+
shape: 'circle',
38+
shapeProps: {
39+
r: 3,
40+
fill: 'red',
41+
},
42+
};
43+
const mockTree = [
44+
{
45+
name: 'Top Level',
46+
parent: 'null',
47+
shape: svgShapeMock,
48+
children: [
49+
{
50+
name: 'Inner',
51+
parent: 'Top Level',
52+
},
53+
],
54+
},
55+
];
56+
57+
const renderedComponent = mount(<Tree data={mockTree} />);
58+
const parentNode = renderedComponent.find(Node).first();
59+
expect(parentNode).not.toBeUndefined();
60+
expect(parentNode.props().nodeSvgShape).toEqual(svgShapeMock);
61+
62+
const childNode = renderedComponent.find(Node).last();
63+
expect(childNode).not.toBeUndefined();
64+
expect(childNode.props().nodeSvgShape).not.toEqual(svgShapeMock);
65+
});
66+
3567
it('maps every parent-child relation onto a <Link />', () => {
3668
const linkCount = 2;
3769
const renderedComponent = shallow(<Tree data={mockData} />);

0 commit comments

Comments
 (0)