Skip to content

Commit 120551c

Browse files
committed
docs: add proper readme
Signed-off-by: Andres Correa Casablanca <castarco@coderspirit.xyz>
1 parent aa16b91 commit 120551c

File tree

6 files changed

+155
-12
lines changed

6 files changed

+155
-12
lines changed

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ root = true
44
end_of_line = lf
55
insert_final_newline = true
66

7-
[*.{css,js,cjs,mjs,json,ts,cjs,mts,jsx,tsx}]
7+
[*.{css,js,cjs,mjs,json,ts,cjs,mts,jsx,tsx,md}]
88
charset = utf-8
99
indent_style = tab
1010
indent_size = 2

README.md

Lines changed: 144 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,146 @@
11
# Beautiful-Tree
22

3-
TODO
3+
<p align="center">
4+
<svg xmlns="http://www.w3.org/2000/svg" id="centered3-small-tree" viewBox="0 0 400 400" class="beautiful-tree-react" style="width: 300px; height: 300px;"><style>line{stroke:green;}
5+
circle,rect{stroke:green;fill:white;}
6+
div.beautiful-tree-node-content{margin:0;height:100%;width:100%;text-align:center;line-height:50px;font-size:25px;}</style><line class="beautiful-tree-edge" x1="175" y1="100" x2="100" y2="200"></line><line class="beautiful-tree-edge" x1="100" y1="200" x2="100" y2="300"></line><line class="beautiful-tree-edge" x1="175" y1="100" x2="250" y2="200"></line><line class="beautiful-tree-edge" x1="250" y1="200" x2="200" y2="300"></line><line class="beautiful-tree-edge" x1="250" y1="200" x2="300" y2="300"></line><circle class="beautiful-tree-node beautiful-tree-leaf" cx="100" cy="300" r="25"></circle><foreignObject x="75" y="275" width="50" height="50"><div class="beautiful-tree-node-content beautiful-tree-leaf">C</div></foreignObject><circle class="beautiful-tree-node" cx="100" cy="200" r="25"></circle><foreignObject x="75" y="175" width="50" height="50"><div class="beautiful-tree-node-content">B</div></foreignObject><circle class="beautiful-tree-node beautiful-tree-leaf" cx="200" cy="300" r="25"></circle><foreignObject x="175" y="275" width="50" height="50"><div class="beautiful-tree-node-content beautiful-tree-leaf">E</div></foreignObject><circle class="beautiful-tree-node beautiful-tree-leaf" cx="300" cy="300" r="25"></circle><foreignObject x="275" y="275" width="50" height="50"><div class="beautiful-tree-node-content beautiful-tree-leaf">F</div></foreignObject><circle class="beautiful-tree-node" cx="250" cy="200" r="25"></circle><foreignObject x="225" y="175" width="50" height="50"><div class="beautiful-tree-node-content">D</div></foreignObject><circle class="beautiful-tree-node beautiful-tree-root" cx="175" cy="100" r="25"></circle><foreignObject x="150" y="75" width="50" height="50"><div class="beautiful-tree-node-content beautiful-tree-root">A</div></foreignObject></svg>
7+
</p>
8+
9+
Beautiful-Tree is a lightweight & flexible library to draw trees as SVG images.
10+
11+
Some of its hightlights:
12+
- It is compatible with ESM, CJS, UMD and IIFE
13+
- Very lightweight (3.9Kb in its minimised ESM form, and 4.2Kb in its UMD form)
14+
- The generated trees can be styled with CSS
15+
16+
## Install
17+
18+
```bash
19+
# With NPM
20+
npm install @beautiful-tree/react
21+
22+
# With Yarn
23+
yarn add @beautiful-tree/react
24+
25+
# With PNPM
26+
pnpm add @beautiful-tree/react
27+
```
28+
29+
## Basic Usage
30+
31+
```jsx
32+
import { BeautifulTree } from '@beautiful-tree/react'
33+
34+
const tree = {
35+
data: { v: 'A' },
36+
children: [
37+
{
38+
node: {
39+
/* node data can contain any kews we want */
40+
data: { v: 'B' },
41+
children: [
42+
{
43+
/* we can annotate edges with arbitrary metadata */
44+
eData: { e: 0.5 },
45+
node: { data: { v: 'C' } }
46+
},
47+
],
48+
},
49+
},
50+
{
51+
node: {
52+
data: { v: 'D' },
53+
children: [
54+
{ node: { data: { v: 'E' } } },
55+
{ node: { data: { v: 'F' } } },
56+
],
57+
},
58+
},
59+
],
60+
}
61+
62+
// The 3 main properties that we must always set are:
63+
// - `id`: the id for the tree component
64+
// - `tree:`` the tree data structure that will be rendered
65+
// - `svgProps``: the proportions of the SVG "canvas".
66+
render(
67+
<BeautifulTree
68+
id={'my-tree'}
69+
tree={tree}
70+
svgProps={{
71+
width: 400,
72+
height: 400,
73+
// sizeUnit?: '%' | 'em' | 'px' | 'rem'
74+
}}
75+
/>
76+
)
77+
```
78+
79+
## Exposed CSS classes
80+
81+
- `beautiful-tree-react`: applies to the rendered SVG element.
82+
- `beautiful-tree-edge`: applies to all the rendered edges inside the SVG
83+
element.
84+
- `beautiful-tree-node`: applies to all the rendered nodes inside the SVG
85+
element.
86+
- `beautiful-tree-root`: applies only to the rendered _root_ node.
87+
- `beautiful-tree-leaf`: applies to all the rendered _leaf_ nodes inside the SVG
88+
element.
89+
- `beautiful-tree-node-content`: applies to all the `<div>` elements rendered
90+
inside nodes when using the [`getNodeContent`](#getnodecontent) prop.
91+
92+
## Other component props
93+
94+
We won't go into very deep details because TypeScript's autocomplete is enough
95+
to discover the aspects not mentioned here.
96+
97+
### `nodeShape`
98+
99+
Accepted values are `'circle'` and `'rect'`. It specifies which shape is used
100+
to render the tree nodes.
101+
102+
### `getNodeShape`
103+
104+
In case we want the shape of each node to depend on their associated metadata,
105+
we can pass a function that returns the desired shape for each individual node.
106+
107+
### `getNodeContent`
108+
109+
We can pass a function to read what's inside the `data` property of each node
110+
and return either a `string` value or a `JSX.Element` object that will be
111+
rendered inside the corresponding node.
112+
113+
### `computeLayout`
114+
115+
It specifies the function that is used to compute the tree layout.
116+
- By default it uses `computeSmartLayout`.
117+
- But we can also import a simpler layout `computeNaiveLayout`.
118+
119+
### `getNodeClass`
120+
121+
We can pass a function that takes each node object and returns a list of CSS
122+
classes that will be applied to it. This is useful if we want to make node
123+
styles depend on their associated data.
124+
125+
### `getEdgeClass`
126+
127+
We can pass a function that takes edge metadata as input and returns a list of
128+
CSS classes that will be applied to it. This is useful if we want to make edge
129+
styles depend on their associated data.
130+
131+
### `hCoef`
132+
133+
This parameter, mostly useful for the case when node's shape is `'rect'`, allows
134+
us to control the ratio aspect between height and width of a node. It must be
135+
between `0` and `1`, ideally above `0.5`.
136+
137+
## Future Plans
138+
139+
- Introduce a layout algorithm for dendrograms (with leafs all at the bottom
140+
level, instead of being at the level inmediately below their parents).
141+
- Introduce rotated versions of the tree layout (left-to-right, right-to-left,
142+
bottom-up)
143+
- Allow to use different edge "styles" between nodes (now it's just straight
144+
lines): splines, segmented lines with corners...
145+
- Release versions of this same library for other components systems, such as
146+
Vue, Svelte, Solidjs, and native Web Components.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@beautiful-tree/react",
3-
"version": "0.0.1",
3+
"version": "0.1.0",
44
"private": false,
55
"author": "Andres Correa Casablanca <castarco@coderspirit.xyz>",
66
"license": "MIT",

src/BeautifulTree.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { edgesIterator, postOrderIterator } from './traversal'
22
import { Fragment } from 'react'
33
import type { Tree } from './types'
44
import type { WrappedTreeWithLayout } from './layouts'
5+
import { computeSmartLayout } from './layouts'
56
export { computeNaiveLayout, computeSmartLayout } from './layouts'
67

78
export type CssClassesGetter = (
@@ -49,7 +50,7 @@ export function BeautifulTree({
4950
nodeShape,
5051
hCoef = 1,
5152
tree,
52-
computeLayout,
53+
computeLayout = computeSmartLayout,
5354
getNodeClass,
5455
getNodeShape,
5556
getNodeContent,

src/stories/BeautifulTree.stories.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ export const Centered3_Tree: Story = {
6969
},
7070
tree: smallTree,
7171
computeLayout: computeSmartLayout,
72-
getNodeClass: getCssFromNodeData,
73-
getEdgeClass: getCssFromEdgeData,
72+
getNodeContent: (data) => data?.['v']?.toString() ?? '',
7473
},
7574
}
7675

src/stories/treeFixtures.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,27 @@ export const getCssFromEdgeData = (
2424
}
2525

2626
export const smallTree: Tree = {
27-
data: { v: 42 },
27+
data: { v: 'A' },
2828
children: [
2929
{
3030
node: {
31-
data: { v: 43 },
31+
data: { v: 'B' },
3232
children: [
3333
{
34-
node: { data: { v: 45 } },
34+
node: { data: { v: 'C' } },
3535
},
3636
],
3737
},
3838
},
3939
{
4040
node: {
41-
data: { v: 44 },
41+
data: { v: 'D' },
4242
children: [
4343
{
44-
node: { data: { v: 46 } },
44+
node: { data: { v: 'E' } },
4545
},
4646
{
47-
node: { data: { v: 47 } },
47+
node: { data: { v: 'F' } },
4848
},
4949
],
5050
},

0 commit comments

Comments
 (0)