1616 <g v-for =" (node, index) in allNodes" :key =" 'node-' + index" :transform =" `translate(${node.x},${node.y})`" >
1717 <NuxtLink :to =" node.link" class =" node-link" >
1818 <rect :x =" !node.parent ? -60 : node.children.length == 0 ? -45 : -50"
19- :y =" !node.parent ? -60 : node.children.length == 0 ? -45 : -50"
20- :width =" !node.parent ? 120 : node.children.length == 0 ? 90 : 100"
21- :height =" !node.parent ? 120 : node.children.length == 0 ? 90 : 100"
22- class =" node-circle mask mask-squircle"
19+ :y =" !node.parent ? -60 : node.children.length == 0 ? -45 : -50"
20+ :width =" !node.parent ? 120 : node.children.length == 0 ? 90 : 100"
21+ :height =" !node.parent ? 120 : node.children.length == 0 ? 90 : 100" class =" node-circle mask mask-squircle"
2322 @click =" () => { toggleNode(node); closeNav(); }" />
2423 </NuxtLink >
2524 <text class =" node-text"
@@ -76,7 +75,7 @@ export default defineComponent({
7675 return {
7776 allNodes: [] as TreeNode [],
7877 connections: [] as Array <{ path: string }>,
79- radius: 150 ,
78+ radius: 15 ,
8079 angleStep: 45 ,
8180 isPanning: false ,
8281 startPanPosition: { x: 0 , y: 0 },
@@ -100,12 +99,12 @@ export default defineComponent({
10099 },
101100
102101 calculatePositions(node : Node , depth : number , angle : number , parentNode ? : TreeNode ): TreeNode {
103- const baseClusterRadius = 200
104- const extraRadiusIfHasChildren = Math .max (node .Children .length - 1 , 0 ) * 20
105- const clusterRadius = baseClusterRadius + extraRadiusIfHasChildren
102+ const baseClusterRadius = 200 ;
103+ const extraRadiusIfHasChildren = Math .max (node .Children .length - 1 , 0 ) * 20 ;
104+ const clusterRadius = baseClusterRadius + extraRadiusIfHasChildren ;
106105
107- const nodeX = parentNode ? parentNode .x + Math .cos (angle * Math .PI / 180 ) * clusterRadius : 0
108- const nodeY = parentNode ? parentNode .y + Math .sin (angle * Math .PI / 180 ) * clusterRadius : 0
106+ let nodeX = parentNode ? parentNode .x + Math .cos (angle * Math .PI / 180 ) * clusterRadius : 0 ;
107+ let nodeY = parentNode ? parentNode .y + Math .sin (angle * Math .PI / 180 ) * clusterRadius : 0 ;
109108
110109 const radialPosition: TreeNode = {
111110 x: nodeX ,
@@ -114,44 +113,58 @@ export default defineComponent({
114113 link: node .Value ?.path || ' /' ,
115114 children: [],
116115 parent: parentNode ,
117- expanded: true
116+ expanded: true ,
117+ };
118+
119+ // Resolve collisions
120+ const pushRadius = this .radius * 11 ;
121+ for (const existingNode of this .allNodes ) {
122+ const dx = radialPosition .x - existingNode .x ;
123+ const dy = radialPosition .y - existingNode .y ;
124+ const distance = Math .sqrt (dx * dx + dy * dy );
125+
126+ if (distance < pushRadius ) {
127+ const overlap = pushRadius - distance ;
128+ const angleToExistingNode = Math .atan2 (dy , dx );
129+
130+ // Push the node away
131+ radialPosition .x += Math .cos (angleToExistingNode ) * overlap ;
132+ radialPosition .y += Math .sin (angleToExistingNode ) * overlap ;
133+ }
118134 }
119135
120- this .allNodes .push (radialPosition )
136+ this .allNodes .push (radialPosition );
121137
122138 if (parentNode ) {
123139 this .connections .push ({
124- path: this .createConnectionPath (parentNode , radialPosition )
125- })
140+ path: this .createConnectionPath (parentNode , radialPosition ),
141+ });
126142 }
127143
128- const childCount = node .Children .length
144+ const childCount = node .Children .length ;
129145 if (childCount > 0 ) {
130- // Use a narrower spread for small clusters
131- const totalArc = childCount <= 3 ? 120 : childCount <= 6 ? 180 : 330
132- const spreadAngle = totalArc / (childCount || 1 )
146+ const totalArc = childCount <= 3 ? 120 : childCount <= 6 ? 180 : 330 ;
147+ const spreadAngle = totalArc / (childCount || 1 );
133148
134149 let baseAngleOffset =
135- ( parentNode ?.x === undefined || parentNode ?.y === undefined )
150+ parentNode ?.x === undefined || parentNode ?.y === undefined
136151 ? 0
137- : Math .atan2 (parentNode .y - nodeY , parentNode .x - nodeX ) * 180 / Math .PI
152+ : ( Math .atan2 (parentNode .y - nodeY , parentNode .x - nodeX ) * 180 ) / Math .PI ;
138153
139- baseAngleOffset = (baseAngleOffset + 360 ) % 360 // Normalize angle to [0, 360)
154+ baseAngleOffset = (baseAngleOffset + 360 ) % 360 ; // Normalize angle to [0, 360)
140155
141- let childAngle = baseAngleOffset + angle - ( totalArc / 2 )
156+ let childAngle = baseAngleOffset + angle - totalArc / 2 ;
142157
143158 for (const child of node .Children ) {
144- const childNode = this .calculatePositions (child , depth + 1 , childAngle , radialPosition )
145- radialPosition .children .push (childNode )
146- childAngle += spreadAngle
159+ const childNode = this .calculatePositions (child , depth + 1 , childAngle , radialPosition );
160+ radialPosition .children .push (childNode );
161+ childAngle += spreadAngle ;
147162 }
148163 }
149164
150-
151- return radialPosition
165+ return radialPosition ;
152166 },
153167
154-
155168 createConnectionPath(start : TreeNode , end : TreeNode ): string {
156169 return ` M ${start .x } ${start .y } Q ${(start .x + end .x ) / 2 } ${(start .y + end .y ) / 2 } ${end .x } ${end .y } `
157170 },
@@ -259,7 +272,7 @@ export default defineComponent({
259272 scale : 1.2 ;
260273}
261274
262- g :hover > .node-text {
275+ g :hover > .node-text {
263276 fill : var (--color-base-100 );
264277}
265278
0 commit comments