Skip to content

Commit 97b6562

Browse files
committed
feat: allow controlling component size units
Signed-off-by: Andres Correa Casablanca <castarco@coderspirit.xyz>
1 parent 2687851 commit 97b6562

File tree

2 files changed

+43
-33
lines changed

2 files changed

+43
-33
lines changed

src/BeautifulTree.tsx

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,29 @@ export interface BeautifulTreeProps {
77
readonly svgProps: {
88
readonly width: number
99
readonly height: number
10+
readonly sizeUnit?: '%' | 'em' | 'px' | 'rem'
1011
}
1112
readonly tree: Tree
1213
}
1314

14-
export function BeautifulTree(
15-
props: Readonly<BeautifulTreeProps>,
16-
): JSX.Element {
17-
const treeWithLayout = computeLeftShiftLayout(props.tree)
15+
export function BeautifulTree({
16+
id,
17+
svgProps,
18+
tree,
19+
}: Readonly<BeautifulTreeProps>): JSX.Element {
20+
const { tree: treeWithLayout, maxX, maxY } = computeLeftShiftLayout(tree)
1821
const orderedNodes = [...postOrderIterator(treeWithLayout)]
1922

20-
let maxX = 0
21-
let maxY = 0
22-
for (const node of orderedNodes) {
23-
if (node.meta.abstractPosition.x > maxX) {
24-
maxX = node.meta.abstractPosition.x
25-
}
26-
if (node.meta.abstractPosition.y > maxY) {
27-
maxY = node.meta.abstractPosition.y
28-
}
29-
}
23+
const { width, height, sizeUnit = 'px' } = svgProps
3024

3125
return (
3226
<svg
3327
xmlns="http://www.w3.org/2000/svg"
34-
id={props.id}
35-
viewBox={`0 0 ${props.svgProps.width} ${props.svgProps.height}`}
28+
id={id}
29+
viewBox={`0 0 ${width} ${height}`}
3630
style={{
37-
width: `${props.svgProps.width}px`,
38-
height: `${props.svgProps.height}px`,
31+
width: `${width}${sizeUnit}`,
32+
height: `${height}${sizeUnit}`,
3933
}}
4034
className={'beautiful-tree-react'}
4135
>
@@ -44,11 +38,12 @@ export function BeautifulTree(
4438
const aY = node.meta.abstractPosition.y
4539
return (
4640
<circle
47-
key={`${props.id}-node-${idx}`}
48-
cx={((aX + 1) * props.svgProps.width) / (maxX + 2)}
49-
cy={((aY + 1) * props.svgProps.height) / (maxY + 2)}
50-
stroke="blue"
51-
fill="purple"
41+
key={`${id}-node-${idx}`}
42+
className={'beautiful-tree-node'}
43+
cx={((aX + 1) * width) / (maxX + 2)}
44+
cy={((aY + 1) * height) / (maxY + 2)}
45+
stroke="black"
46+
fill="white"
5247
r="5"
5348
/>
5449
)

src/layouts.ts

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
import type { Tree, TreeChild, TreeWithLayout } from './types'
22

3+
export interface WrappedTreeWithLayout {
4+
readonly tree: Readonly<TreeWithLayout>
5+
readonly maxX: number
6+
readonly maxY: number
7+
}
8+
39
const _computeLeftShiftLayout = (
410
tree: Tree,
511
depth = 0,
612
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
7-
counters?: number[][],
8-
): TreeWithLayout => {
9-
counters ??= []
13+
counters: { layers: number[][]; maxX: number },
14+
): Readonly<TreeWithLayout> => {
15+
const layers = counters.layers
1016

11-
if (counters[depth] === undefined) {
12-
counters[depth] = []
17+
if (layers[depth] === undefined) {
18+
layers[depth] = []
1319
}
14-
const x = (counters[depth]?.at(-1) ?? -1) + 1
20+
const x = (layers[depth]?.at(-1) ?? -1) + 1
1521
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
16-
counters[depth]!.push(x)
22+
layers[depth]!.push(x)
23+
counters.maxX = Math.max(counters.maxX, x)
1724

1825
return {
1926
data: tree.data,
@@ -26,8 +33,16 @@ const _computeLeftShiftLayout = (
2633
isLeaf: tree.children === undefined || tree.children.length === 0,
2734
abstractPosition: { x, y: depth },
2835
},
29-
} satisfies TreeWithLayout
36+
} satisfies Readonly<TreeWithLayout>
3037
}
3138

32-
export const computeLeftShiftLayout: (tree: Tree) => TreeWithLayout =
33-
_computeLeftShiftLayout
39+
export const computeLeftShiftLayout = (
40+
tree: Readonly<Tree>,
41+
): Readonly<WrappedTreeWithLayout> => {
42+
const counters = { layers: [], maxX: 0 }
43+
return {
44+
tree: _computeLeftShiftLayout(tree, 0, counters),
45+
maxX: counters.maxX,
46+
maxY: counters.layers.length - 1,
47+
}
48+
}

0 commit comments

Comments
 (0)