@@ -2,31 +2,33 @@ import type { Tree, TreeChild, TreeWithLayout } from './types'
2
2
3
3
export interface WrappedTreeWithLayout {
4
4
readonly tree : Readonly < TreeWithLayout >
5
- readonly maxX : number
6
- readonly maxY : number
5
+ readonly mX : number
6
+ readonly mY : number
7
7
}
8
8
9
- const _computeLeftShiftLayout = (
9
+ const M = Math . max
10
+
11
+ const _computeNaiveLayout = (
10
12
tree : Tree ,
11
13
depth = 0 ,
12
14
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
13
- counters : { layers : number [ ] ; maxX : number } ,
15
+ counters : { l : number [ ] ; mX : number } ,
14
16
) : Readonly < TreeWithLayout > => {
15
- const layers = counters . layers
16
-
17
- const x = ( layers [ depth ] ?? - 1 ) + 1
18
- layers [ depth ] = x
19
- counters . maxX = Math . max ( counters . maxX , x )
17
+ const l = counters . l
18
+ const x = ( l [ depth ] ?? - 1 ) + 1
19
+ l [ depth ] = x
20
+ counters . mX = M ( counters . mX , x )
20
21
22
+ const tc = tree . children
21
23
return {
22
24
data : tree . data ,
23
- children : tree . children ?. map ( ( child : Readonly < TreeChild > ) => ( {
25
+ children : tc ?. map ( ( child : Readonly < TreeChild > ) => ( {
24
26
edgeData : child . edgeData ,
25
- node : _computeLeftShiftLayout ( child . node , depth + 1 , counters ) ,
27
+ node : _computeNaiveLayout ( child . node , depth + 1 , counters ) ,
26
28
} ) ) ,
27
29
meta : {
28
30
isRoot : depth === 0 ,
29
- isLeaf : tree . children === undefined || tree . children . length === 0 ,
31
+ isLeaf : tc === undefined || tc . length === 0 ,
30
32
pos : { x, y : depth } ,
31
33
} ,
32
34
} satisfies Readonly < TreeWithLayout >
@@ -35,11 +37,11 @@ const _computeLeftShiftLayout = (
35
37
export const computeNaiveLayout = (
36
38
tree : Readonly < Tree > ,
37
39
) : Readonly < WrappedTreeWithLayout > => {
38
- const counters = { layers : [ ] , maxX : 0 }
40
+ const counters = { l : [ ] , mX : 0 }
39
41
return {
40
- tree : _computeLeftShiftLayout ( tree , 0 , counters ) ,
41
- maxX : counters . maxX ,
42
- maxY : counters . layers . length - 1 ,
42
+ tree : _computeNaiveLayout ( tree , 0 , counters ) ,
43
+ mX : counters . mX ,
44
+ mY : counters . l . length - 1 ,
43
45
}
44
46
}
45
47
@@ -50,10 +52,10 @@ const _addMods = (
50
52
tree : DeepWriteable < TreeWithLayout > ,
51
53
modsum = 0 ,
52
54
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
53
- tracer : { maxX : number } ,
55
+ tracer : { mX : number } ,
54
56
) : void => {
55
57
tree . meta . pos . x += modsum
56
- tracer . maxX = Math . max ( tracer . maxX , tree . meta . pos . x )
58
+ tracer . mX = M ( tracer . mX , tree . meta . pos . x )
57
59
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
58
60
modsum += tree . meta . m ! // We know it's defined because we control when it's called
59
61
for ( const child of tree . children ?? [ ] ) {
@@ -67,16 +69,17 @@ const _computeCenter2Layout = (
67
69
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
68
70
offsets : number [ ] ,
69
71
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
70
- tracer : { maxX : number } ,
72
+ tracer : { mX : number } ,
71
73
) : DeepWriteable < TreeWithLayout > => {
72
- const children = tree . children ?. map ( ( child ) => ( {
74
+ const tc = tree . children
75
+ const children = tc ?. map ( ( child ) => ( {
73
76
edgeData : child . edgeData ,
74
77
node : _computeCenter2Layout ( child . node , depth + 1 , offsets , tracer ) ,
75
78
} ) )
76
79
77
80
let x : number
78
81
let m = 0
79
- const numChildren = tree . children ?. length ?? 0
82
+ const numChildren = tc ?. length ?? 0
80
83
if ( numChildren === 0 ) {
81
84
x = offsets [ depth ] ?? 0
82
85
} else if ( numChildren === 1 ) {
@@ -88,18 +91,18 @@ const _computeCenter2Layout = (
88
91
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
89
92
children ! [ numChildren - 1 ] ! . node . meta . pos . x ) *
90
93
0.5
91
- x = Math . max ( offsets [ depth ] ?? 0 , c )
94
+ x = M ( offsets [ depth ] ?? 0 , c )
92
95
m = x - c
93
96
}
94
- tracer . maxX = Math . max ( tracer . maxX , x )
97
+ tracer . mX = M ( tracer . mX , x )
95
98
offsets [ depth ] = 1 + x
96
99
97
100
return {
98
101
data : tree . data ,
99
102
children,
100
103
meta : {
101
104
isRoot : depth === 0 ,
102
- isLeaf : tree . children === undefined || tree . children . length === 0 ,
105
+ isLeaf : tc === undefined || tc . length === 0 ,
103
106
pos : { x, y : depth } ,
104
107
m,
105
108
} ,
@@ -115,24 +118,26 @@ const _inPlaceEvenSpacingUpdate = (
115
118
offsets : number [ ] ,
116
119
depth : number ,
117
120
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
118
- tracer : { maxX : number } ,
121
+ tracer : { mX : number } ,
119
122
) : void => {
123
+ const tm = tree . meta
124
+ const tmp = tm . pos
120
125
if ( numChildren === 0 ) {
121
- tree . meta . pos . x += shift
126
+ tmp . x += shift
122
127
} else if ( numChildren === 1 ) {
123
128
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
124
- tree . meta . pos . x = tree . children ! [ 0 ] ! . node . meta . pos . x
129
+ tmp . x = tree . children ! [ 0 ] ! . node . meta . pos . x
125
130
} else {
126
131
const c = // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
127
132
( tree . children ! [ 0 ] ! . node . meta . pos . x +
128
133
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
129
134
tree . children ! [ numChildren - 1 ] ! . node . meta . pos . x ) *
130
135
0.5
131
- tree . meta . pos . x = Math . max ( offsets [ depth ] ?? 0 , c )
136
+ tmp . x = M ( offsets [ depth ] ?? 0 , c )
132
137
}
133
- delete tree . meta . m
134
- tracer . maxX = Math . max ( tracer . maxX , tree . meta . pos . x )
135
- offsets [ depth ] = 1 + tree . meta . pos . x
138
+ delete tm . m
139
+ tracer . mX = M ( tracer . mX , tmp . x )
140
+ offsets [ depth ] = 1 + tmp . x
136
141
}
137
142
138
143
const _siblingsEvenSpacing = (
@@ -141,54 +146,53 @@ const _siblingsEvenSpacing = (
141
146
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
142
147
offsets : number [ ] ,
143
148
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
144
- tracer : { maxX : number } ,
149
+ tracer : { mX : number } ,
145
150
depth = 0 ,
146
151
shift = 0 ,
147
152
// eslint-disable-next-line sonarjs/cognitive-complexity
148
153
) : void => {
149
- const numChildren = tree . children ?. length ?? 0
154
+ const tc = tree . children
155
+ const numChildren = tc ?. length ?? 0
150
156
let lastFixedIdx : number | undefined
151
157
let maxSpacing = 1
152
- for ( const [ idx , child ] of ( tree . children ?? [ ] ) . entries ( ) ) {
153
- const isFixed = ( child . node . children ?. length ?? 0 ) > 0
158
+ for ( const [ idx , { node } ] of ( tc ?? [ ] ) . entries ( ) ) {
159
+ const isFixed = ( node . children ?. length ?? 0 ) > 0
154
160
if ( isFixed ) {
155
161
if ( lastFixedIdx !== undefined ) {
156
162
const spacing =
157
- ( child . node . meta . pos . x -
163
+ ( node . meta . pos . x -
158
164
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
159
- tree . children ! [ lastFixedIdx ] ! . node . meta . pos . x ) /
165
+ tc ! [ lastFixedIdx ] ! . node . meta . pos . x ) /
160
166
( idx - lastFixedIdx )
161
- maxSpacing = Math . max ( maxSpacing , spacing )
167
+ maxSpacing = M ( maxSpacing , spacing )
162
168
}
163
169
lastFixedIdx = idx
164
170
}
165
171
}
166
172
167
173
let accShift = shift
168
- for ( const [ idx , child ] of ( tree . children ?? [ ] ) . entries ( ) ) {
174
+ for ( const [ idx , { node } ] of ( tc ?? [ ] ) . entries ( ) ) {
169
175
if ( idx === 0 ) {
170
176
if ( numChildren > 1 ) {
171
- accShift = Math . max (
177
+ accShift = M (
172
178
0 ,
173
179
shift +
174
180
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
175
- tree . children ! [ 1 ] ! . node . meta . pos . x -
181
+ tc ! [ 1 ] ! . node . meta . pos . x -
176
182
maxSpacing -
177
- child . node . meta . pos . x ,
183
+ node . meta . pos . x ,
178
184
)
179
185
}
180
186
} else {
181
187
accShift =
182
188
shift +
183
- Math . max (
189
+ M (
184
190
0 ,
185
191
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
186
- tree . children ! [ idx - 1 ] ! . node . meta . pos . x +
187
- maxSpacing -
188
- child . node . meta . pos . x ,
192
+ tc ! [ idx - 1 ] ! . node . meta . pos . x + maxSpacing - node . meta . pos . x ,
189
193
)
190
194
}
191
- _siblingsEvenSpacing ( child . node , offsets , tracer , depth + 1 , accShift )
195
+ _siblingsEvenSpacing ( node , offsets , tracer , depth + 1 , accShift )
192
196
}
193
197
194
198
_inPlaceEvenSpacingUpdate ( numChildren , tree , shift , offsets , depth , tracer )
@@ -200,31 +204,32 @@ const _cousinsEvenSpacing = (
200
204
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
201
205
offsets : number [ ] ,
202
206
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
203
- tracer : { maxX : number } ,
207
+ tracer : { mX : number } ,
204
208
depth = 0 ,
205
209
shift = 0 ,
206
210
) : void => {
207
- const numChildren = tree . children ?. length ?? 0
211
+ const tc = tree . children
212
+ const numChildren = tc ?. length ?? 0
208
213
209
214
const nextOffset = offsets [ depth + 1 ]
210
215
let accShift = shift
211
216
if (
212
217
numChildren >= 2 &&
213
218
nextOffset !== undefined &&
214
219
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
215
- ( tree . children ! [ 0 ] ! . node . children ?. length ?? 0 ) === 0
220
+ ( tc ! [ 0 ] ! . node . children ?. length ?? 0 ) === 0
216
221
) {
217
222
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
218
- const mid = tree . children ! [ 1 ] ! . node . meta . pos . x - 1
223
+ const mid = tc ! [ 1 ] ! . node . meta . pos . x - 1
219
224
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
220
- accShift = shift + Math . max ( 0 , mid - tree . children ! [ 0 ] ! . node . meta . pos . x )
225
+ accShift = shift + M ( 0 , mid - tc ! [ 0 ] ! . node . meta . pos . x )
221
226
}
222
227
223
- for ( const [ idx , child ] of ( tree . children ?? [ ] ) . entries ( ) ) {
228
+ for ( const [ idx , { node } ] of ( tc ?? [ ] ) . entries ( ) ) {
224
229
if ( idx === 0 ) {
225
- _cousinsEvenSpacing ( child . node , offsets , tracer , depth + 1 , accShift )
230
+ _cousinsEvenSpacing ( node , offsets , tracer , depth + 1 , accShift )
226
231
} else {
227
- _cousinsEvenSpacing ( child . node , offsets , tracer , depth + 1 , shift )
232
+ _cousinsEvenSpacing ( node , offsets , tracer , depth + 1 , shift )
228
233
}
229
234
}
230
235
@@ -235,7 +240,7 @@ export const computeSmartLayout = (
235
240
tree : Readonly < Tree > ,
236
241
) : Readonly < WrappedTreeWithLayout > => {
237
242
const offsets : number [ ] = [ ]
238
- const tracer = { maxX : 0 }
243
+ const tracer = { mX : 0 }
239
244
240
245
const t = _computeCenter2Layout ( tree , 0 , offsets , tracer )
241
246
_addMods ( t , 0 , tracer )
@@ -245,7 +250,7 @@ export const computeSmartLayout = (
245
250
246
251
return {
247
252
tree : t ,
248
- maxY : offsets . length - 1 ,
249
- maxX : tracer . maxX ,
253
+ mY : offsets . length - 1 ,
254
+ mX : tracer . mX ,
250
255
}
251
256
}
0 commit comments