@figtreejs/core 0.0.1-beta.1 → 0.1.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@figtreejs/core",
3
- "version": "0.0.1-beta.1",
3
+ "version": "0.1.0-beta.3",
4
4
  "description": "A react component library for phylogenetic visualization and app building",
5
5
  "repository": {
6
6
  "type": "git",
@@ -41,7 +41,7 @@
41
41
  ]
42
42
  },
43
43
  "dependencies": {
44
- "@react-spring/web": "^9.7.5",
44
+ "@react-spring/web": "^10.0.3",
45
45
  "abs-svg-path": "^0.1.1",
46
46
  "d3-array": "^3.2.4",
47
47
  "d3-format": "^3.1.0",
@@ -56,7 +56,6 @@
56
56
  "devDependencies": {
57
57
  "@figtreejs/eslint-config": "*",
58
58
  "@figtreejs/typescript-config": "*",
59
- "@microsoft/api-extractor": "^7.55.1",
60
59
  "@testing-library/react": "^16.3.0",
61
60
  "@types/abs-svg-path": "^0.1.3",
62
61
  "@types/d3-array": "^3.2.2",
@@ -64,6 +63,7 @@
64
63
  "@types/d3-scale": "^4.0.9",
65
64
  "@types/d3-shape": "^3.1.7",
66
65
  "@types/d3-time-format": "^4.0.3",
66
+ "@types/react": "^19.2.14",
67
67
  "@vitejs/plugin-react": "^5.1.0",
68
68
  "jsdom": "^27.1.0",
69
69
  "typescript": "^5.9.3",
@@ -73,7 +73,7 @@
73
73
  "vitest": "^4.0.8"
74
74
  },
75
75
  "peerDependencies": {
76
- "react": "^18.3.1",
77
- "react-dom": "^18.3.1"
76
+ "react": "^19.2.0",
77
+ "react-dom": "^19.2.0"
78
78
  }
79
79
  }
@@ -1,7 +1,13 @@
1
1
  //TODO test immutable tree include tests that check nodes to roots update as well.
2
2
 
3
3
  import { notNull, u } from "../../../utils/maybe";
4
- import { ImmutableTree } from "./immutable-tree";
4
+ import {
5
+ ImmutableTree,
6
+ postOrderIterator,
7
+ preOrderIterator,
8
+ psuedoRootPostOrderIterator,
9
+ psuedoRootPreOrderIterator,
10
+ } from "./immutable-tree";
5
11
  import { describe, it, expect } from "vitest";
6
12
 
7
13
  describe("ImmutableTree", () => {
@@ -156,3 +162,42 @@ describe("testing annotating", () => {
156
162
  annotatedTree.getAnnotation(A, "state");
157
163
  });
158
164
  });
165
+ //. -----2 (A)
166
+ // |
167
+ // -------1
168
+ // | |
169
+ // 0 ------3 (B)
170
+ // |
171
+ // -----4 (C)
172
+ describe("Tree traversals", () => {
173
+ it("preOrder", () => {
174
+ const tree = ImmutableTree.fromNewick("((A:1,B:1):1,C:2);");
175
+ const nodes = [...preOrderIterator(tree)];
176
+ expect(nodes.map((n) => n.number)).toEqual([0, 1, 2, 3, 4]);
177
+ });
178
+
179
+ it("postOrder", () => {
180
+ const tree = ImmutableTree.fromNewick("((A:1,B:1):1,C:2);");
181
+ const nodes = [...postOrderIterator(tree)];
182
+ expect(nodes.map((n) => n.number)).toEqual([2, 3, 1, 4, 0]);
183
+ });
184
+
185
+ it("pseudoRootPostOrder", () => {
186
+ const tree = ImmutableTree.fromNewick("((A:1,B:1):1,C:2);");
187
+ const nodes = [...psuedoRootPostOrderIterator(tree, tree.getNode("A"))];
188
+ expect(nodes.map((n) => n.number)).toEqual([3, 4, 0, 1, 2]);
189
+ });
190
+
191
+ it("pseudoRootPreOrder", () => {
192
+ const tree = ImmutableTree.fromNewick("((A:1,B:1):1,C:2);");
193
+ const nodes = [...psuedoRootPreOrderIterator(tree, tree.getNode("A"))];
194
+ expect(nodes.map((n) => n.number)).toEqual([2, 1, 3, 0, 4]);
195
+ });
196
+
197
+ it("pseudoRootPreOrder", () => {
198
+ const tree = ImmutableTree.fromNewick("((A:1,B:1):1,C:2);");
199
+ const rooted = tree.reroot(tree.getNode("A"));
200
+ const nodes = [...psuedoRootPreOrderIterator(rooted, tree.getNode("A"))];
201
+ expect(nodes.map((n) => n.number)).toEqual([2, 0, 1, 3, 4]);
202
+ });
203
+ });
@@ -1200,24 +1200,47 @@ export function* preOrderIterator(
1200
1200
  yield* traverse(node);
1201
1201
  }
1202
1202
 
1203
- //TODO return the node and edge length of direction
1204
- export function* psuedoRootPreOrderIterator(
1203
+ type PseudoNode = NodeRef & {
1204
+ pseudoChildren: NodeRef[];
1205
+ pseudoLength: number | undefined;
1206
+ pseudoParent: NodeRef | undefined;
1207
+ };
1208
+ // children order will matter but parents are always added after children
1209
+ export function* psuedoRootPostOrderIterator(
1205
1210
  tree: Tree,
1206
1211
  node: NodeRef | undefined = undefined,
1207
- sort: (a: NodeRef, b: NodeRef) => number = (a, b) => a.number - b.number,
1208
- ): Generator<NodeRef> {
1212
+ // sort: (a: NodeRef, b: NodeRef) => number = (a, b) => a.number - b.number,
1213
+ ): Generator<PseudoNode> {
1209
1214
  const traverse = function* (
1210
1215
  node: NodeRef,
1211
1216
  visited: number | undefined = undefined,
1212
- ): Generator<NodeRef> {
1213
- yield tree.getNode(node.number); // get from tree so we keep proxy when used in draft
1214
- const branches = [...tree.getChildren(node), tree.getParent(node)].filter(
1215
- (n) => n.number !== visited,
1216
- ); //
1217
- branches.sort(sort);
1218
- for (const branch of branches) {
1219
- yield* traverse(branch, node.number);
1217
+ ): Generator<PseudoNode> {
1218
+ // get from tree so we keep proxy when used in draft
1219
+ const branches = [...tree.getChildren(node)];
1220
+ if (!tree.isRoot(node)) {
1221
+ branches.push(tree.getParent(node));
1222
+ }
1223
+ const pseudoChildren = branches.filter((n) => n.number !== visited);
1224
+ const pseudoParent = branches.find((node) => node.number === visited);
1225
+ // branches.sort(sort);
1226
+ let pseudoLength = undefined;
1227
+ if (!tree.isRoot(node) && pseudoParent === tree.getParent(node)) {
1228
+ // the root will not have a parent
1229
+ pseudoLength = tree.getLength(node);
1230
+ } else {
1231
+ if (pseudoParent !== undefined) {
1232
+ pseudoLength = tree.getLength(pseudoParent);
1233
+ }
1234
+ }
1235
+ for (const someKid of pseudoChildren) {
1236
+ yield* traverse(someKid, node.number);
1220
1237
  }
1238
+ yield {
1239
+ ...tree.getNode(node.number),
1240
+ pseudoLength,
1241
+ pseudoChildren,
1242
+ pseudoParent,
1243
+ };
1221
1244
  };
1222
1245
 
1223
1246
  if (node === undefined) {
@@ -1226,24 +1249,44 @@ export function* psuedoRootPreOrderIterator(
1226
1249
  yield* traverse(node);
1227
1250
  }
1228
1251
 
1229
- export function* psuedoRootPostOrderIterator(
1252
+ // children order will matter but parents are always added after children
1253
+ export function* psuedoRootPreOrderIterator(
1230
1254
  tree: Tree,
1231
1255
  node: NodeRef | undefined = undefined,
1232
- sort: (a: NodeRef, b: NodeRef) => number = (a, b) => a.number - b.number,
1233
- ): Generator<NodeRef> {
1256
+ // sort: (a: NodeRef, b: NodeRef) => number = (a, b) => a.number - b.number,
1257
+ ): Generator<PseudoNode> {
1234
1258
  const traverse = function* (
1235
1259
  node: NodeRef,
1236
1260
  visited: number | undefined = undefined,
1237
- ): Generator<NodeRef> {
1261
+ ): Generator<PseudoNode> {
1238
1262
  // get from tree so we keep proxy when used in draft
1239
- const branches = [...tree.getChildren(node), tree.getParent(node)].filter(
1240
- (n) => n.number !== visited,
1241
- );
1242
- branches.sort(sort);
1243
- for (const branch of branches) {
1244
- yield* traverse(branch, node.number);
1263
+ const branches = [...tree.getChildren(node)];
1264
+ if (!tree.isRoot(node)) {
1265
+ branches.push(tree.getParent(node));
1266
+ }
1267
+ const pseudoChildren = branches.filter((n) => n.number !== visited);
1268
+ const pseudoParent = branches.find((node) => node.number === visited);
1269
+ // branches.sort(sort);
1270
+ let pseudoLength = undefined;
1271
+ if (!tree.isRoot(node) && pseudoParent === tree.getParent(node)) {
1272
+ // the root will not have a parent
1273
+ pseudoLength = tree.getLength(node);
1274
+ } else {
1275
+ if (pseudoParent !== undefined) {
1276
+ pseudoLength = tree.getLength(pseudoParent);
1277
+ }
1278
+ }
1279
+
1280
+ yield {
1281
+ ...tree.getNode(node.number),
1282
+ pseudoLength,
1283
+ pseudoChildren,
1284
+ pseudoParent,
1285
+ };
1286
+
1287
+ for (const someKid of pseudoChildren) {
1288
+ yield* traverse(someKid, node.number);
1245
1289
  }
1246
- yield tree.getNode(node.number);
1247
1290
  };
1248
1291
 
1249
1292
  if (node === undefined) {
@@ -1251,6 +1294,59 @@ export function* psuedoRootPostOrderIterator(
1251
1294
  }
1252
1295
  yield* traverse(node);
1253
1296
  }
1297
+
1298
+ // children order will matter but parents are always added after children
1299
+ export function* pseudoTipIterator(
1300
+ tree: Tree,
1301
+ node: NodeRef | undefined,
1302
+ pseudoParent: NodeRef | undefined,
1303
+ ): Generator<PseudoNode> {
1304
+ const traverse = function* (
1305
+ node: NodeRef,
1306
+ visited: number | undefined = undefined,
1307
+ ): Generator<PseudoNode> {
1308
+ // get from tree so we keep proxy when used in draft
1309
+ const branches = [...tree.getChildren(node)];
1310
+ if (!tree.isRoot(node)) {
1311
+ branches.push(tree.getParent(node));
1312
+ }
1313
+ const pseudoChildren = branches.filter((n) => n.number !== visited);
1314
+ const pseudoParent = branches.find((node) => node.number === visited);
1315
+ // branches.sort(sort);
1316
+ let pseudoLength = undefined;
1317
+ if (!tree.isRoot(node) && pseudoParent === tree.getParent(node)) {
1318
+ // the root will not have a parent
1319
+ pseudoLength = tree.getLength(node);
1320
+ } else {
1321
+ if (pseudoParent !== undefined) {
1322
+ pseudoLength = tree.getLength(pseudoParent);
1323
+ }
1324
+ }
1325
+
1326
+ if (pseudoChildren.length == 0) {
1327
+ yield {
1328
+ ...tree.getNode(node.number),
1329
+ pseudoLength,
1330
+ pseudoChildren,
1331
+ pseudoParent,
1332
+ };
1333
+ } else {
1334
+ for (const someKid of pseudoChildren) {
1335
+ yield* traverse(someKid, node.number);
1336
+ }
1337
+ }
1338
+ };
1339
+
1340
+ if (node === undefined) {
1341
+ node = tree.getRoot();
1342
+ }
1343
+ if (pseudoParent !== undefined) {
1344
+ yield* traverse(node, pseudoParent.number);
1345
+ } else {
1346
+ yield* traverse(node);
1347
+ }
1348
+ }
1349
+
1254
1350
  export function* postOrderIterator(
1255
1351
  tree: Tree,
1256
1352
  node: NodeRef | undefined = undefined,
@@ -1,5 +1,5 @@
1
1
  import type { ImmutableTree, NodeRef } from "../../evo";
2
- import { preOrderIterator, tipIterator } from "../../evo";
2
+ import { pseudoTipIterator, psuedoRootPreOrderIterator } from "../../evo";
3
3
  import type { NodeLabelType } from "../types";
4
4
  import { notNull } from "../../utils/maybe";
5
5
  import type { FunctionalVertex } from "../types";
@@ -25,47 +25,63 @@ type data = {
25
25
 
26
26
  export function radialLayout(
27
27
  tree: ImmutableTree,
28
- options: { spread?: number } = {},
28
+ options: { spread?: number; root?: NodeRef; startAngle?: number } = {},
29
29
  ): (node: NodeRef) => FunctionalVertex {
30
- const { spread = 1 } = options;
30
+ const {
31
+ spread = 1,
32
+ root = tree.getRoot(),
33
+ startAngle = (2.5 * Math.PI) / 2,
34
+ } = options;
35
+
31
36
  console.log("radial layout with spread", spread);
32
37
  const map = new Map<NodeRef, FunctionalVertex>();
33
38
 
39
+ const fakeThroughRoot = tree.isRoot(root) && tree.getChildCount(root) == 2;
40
+
34
41
  const dataStack: data[] = [
35
42
  {
36
- angleStart: 0,
37
- angleEnd: 2 * Math.PI,
43
+ angleStart: startAngle,
44
+ angleEnd: startAngle + 2 * Math.PI,
38
45
  xpos: 0,
39
46
  ypos: 0,
40
47
  level: 0,
41
- number: tree.getRoot().number,
48
+ number: root.number,
42
49
  },
43
50
  ]; // TODO start tree.
44
- for (const node of preOrderIterator(tree)) {
51
+
52
+ for (const node of psuedoRootPreOrderIterator(tree, root)) {
45
53
  const data = dataStack.pop();
46
54
  notNull(data, `Internal Error, hit the end of the data stack unexpectedly`);
47
55
  const { angleStart, angleEnd, xpos, ypos, level } = data;
48
56
 
49
- const branchAngle = (angleStart + angleEnd) / 2.0;
57
+ const branchAngle = (angleEnd + angleStart) / 2.0;
50
58
 
51
- const length = !tree.isRoot(node) ? tree.getLength(node) : 0;
59
+ const length = node.pseudoLength !== undefined ? node.pseudoLength : 0;
52
60
 
53
61
  const directionX = Math.cos(branchAngle);
54
62
  const directionY = Math.sin(branchAngle);
55
63
  const x = xpos + length * directionX;
56
64
  const y = ypos + length * directionY;
57
65
 
58
- const leftLabel = tree.getChildCount(node) > 0;
66
+ // we want to give the impression we are traversing from the root.
67
+ const directionalUpdate = tree.isRoot(tree.getNode(node.number))
68
+ ? 0
69
+ : node.pseudoParent === undefined ||
70
+ node.pseudoParent.number !== tree.getParent(node).number
71
+ ? -Math.PI
72
+ : 0;
73
+ const nTheta = normalizeAngle(branchAngle - directionalUpdate);
74
+
75
+ const leftLabel = node.pseudoChildren.length > 0;
59
76
  let dx, dy;
60
77
  if (!leftLabel) {
61
- dx = Math.cos(branchAngle);
62
- dy = Math.sin(branchAngle);
78
+ dx = Math.cos(nTheta);
79
+ dy = Math.sin(nTheta);
63
80
  } else {
64
- dx = Math.cos(branchAngle);
65
- dy = Math.sin(branchAngle);
81
+ dx = Math.cos(nTheta);
82
+ dy = Math.sin(nTheta);
66
83
  }
67
84
 
68
- const nTheta = normalizeAngle(branchAngle);
69
85
  const vertex = {
70
86
  x,
71
87
  y,
@@ -81,11 +97,13 @@ export function radialLayout(
81
97
  } as NodeLabelType,
82
98
  };
83
99
 
84
- if (tree.getChildCount(node) > 0) {
100
+ if (node.pseudoChildren.length > 0) {
85
101
  const childLeafs: number[] = [];
86
102
  let totalLeafs = 0;
87
- for (let i = 0; i < tree.getChildCount(node); i++) {
88
- const leafCount = [...tipIterator(tree, tree.getChild(node, i))].length;
103
+ for (let i = 0; i < node.pseudoChildren.length; i++) {
104
+ const leafCount = [
105
+ ...pseudoTipIterator(tree, node.pseudoChildren[i], node.pseudoParent),
106
+ ].length;
89
107
  childLeafs[i] = leafCount;
90
108
  totalLeafs += leafCount;
91
109
  }
@@ -93,15 +111,25 @@ export function radialLayout(
93
111
  let span = angleEnd - angleStart;
94
112
  let updatedAngleStart = angleStart;
95
113
 
96
- if (tree.getRoot() !== node) {
114
+ // We don't want to adjust our path when we hit a degree 2 node or the root
115
+ // if we start at the root has 2 children. In that case we want the roo
116
+ // to sit on the middle of branch (even though it is really encoded as two branches)
117
+
118
+ if (node.pseudoChildren.length > 1) {
97
119
  // span *= 1.0 + ((safeOpts.spread * Math.PI / 180) / 10.0);
98
- span *= 1.0 + (spread * Math.PI) / 180 / 10.0;
99
- updatedAngleStart = branchAngle - span / 2.0;
120
+ console.log(fakeThroughRoot);
121
+ if (!fakeThroughRoot || !tree.isRoot(tree.getNode(node.number))) {
122
+ // this bumps the start angle so branches don't make a straight line.
123
+ // we want to inheret the open space from out parent, but also we want
124
+ // between 0 and 0.1 PI seem to be OK.
125
+ // this shoots for numbers between 0 and 100
126
+ span *= 1.0 + (spread / 1000) * Math.PI;
127
+ updatedAngleStart = branchAngle - span / 2.0;
128
+ }
100
129
  }
101
-
130
+ console.log("here");
102
131
  let a2 = updatedAngleStart;
103
-
104
- for (let i = tree.getChildCount(node) - 1; i > -1; i--) {
132
+ for (let i = node.pseudoChildren.length - 1; i > -1; i--) {
105
133
  // i think we need to go in reverse order here
106
134
  const a1 = a2;
107
135
  a2 = a1 + (span * childLeafs[i]) / totalLeafs;
@@ -111,11 +139,11 @@ export function radialLayout(
111
139
  xpos: x,
112
140
  ypos: y,
113
141
  level: level + 1,
114
- number: tree.getChild(node, i).number,
142
+ number: node.pseudoChildren[i].number,
115
143
  });
116
144
  }
117
145
  }
118
- map.set(node, vertex);
146
+ map.set(tree.getNode(node.number), vertex);
119
147
  }
120
148
 
121
149
  return function (node: NodeRef): FunctionalVertex {
@@ -469,25 +469,25 @@ exports[`Branch labels > renders a tree node labels in radial layout 1`] = `
469
469
  class="branch-layer"
470
470
  >
471
471
  <path
472
- d="M 303.9999492243224 284.97489210109876 C303.9999492243224,284.97489210109876 227.99989844864467,189.9497842021975 227.99989844864467,189.9497842021975 C227.99989844864467,189.9497842021975 189.9998730608058,142.43723025274684 170.99986036688637,118.68095327802152 C170.99986036688637,118.68095327802152 161.49985401992666,106.80281479065886 156.7498508464468,100.86374554697753 C156.7498508464468,100.86374554697753 154.37484925970688,97.89421092513686 153.1873484663369,96.40944361421654 C153.1873484663369,96.40944361421654 152.59359806965193,95.66705995875637 152.29672287130944,95.29586813102628 C152.29672287130944,95.29586813102628 151.99984767296695,94.92467630329621 151.99984767296695,94.92467630329621 "
472
+ d="M 306.5924779152444 95.03594795523999 C306.5924779152444,95.03594795523999 233.18495583048883,190.07189591047998 233.18495583048883,190.07189591047998 C233.18495583048883,190.07189591047998 196.48119478811105,237.5898698881 178.12931426692217,261.34885687690996 C178.12931426692217,261.34885687690996 168.95337400632775,273.22835037131495 164.36540387603054,279.1680971185175 C164.36540387603054,279.1680971185175 162.07141881088194,282.1379704921187 160.92442627830764,283.6229071789194 C160.92442627830764,283.6229071789194 160.35093001202046,284.3653755223197 160.06418187887687,284.7366096940199 C160.06418187887687,284.7366096940199 159.7774337457333,285.10784386572 159.7774337457333,285.10784386572 "
473
473
  fill="none"
474
474
  stroke="black"
475
475
  stroke-width="2"
476
476
  />
477
477
  <path
478
- d="M 151.99984767296695 94.92467630329621 C151.99984767296695,94.92467630329621 190.12010533393422,47.462338151648105 190.12010533393422,47.462338151648105 C190.12010533393422,47.462338151648105 209.18023416441787,23.731169075824052 218.71029857965968,11.865584537912026 C218.71029857965968,11.865584537912026 223.4753307872806,5.932792268956013 225.85784689109104,2.9663961344780065 C225.85784689109104,2.9663961344780065 227.04910494299628,1.4831980672390033 227.64473396894888,0.7415990336195016 C227.64473396894888,0.7415990336195016 227.9425484819252,0.3707995168097508 228.09145573841334,0.1853997584048754 C228.09145573841334,0.1853997584048754 228.2403629949015,0 228.2403629949015,0 "
478
+ d="M 159.7774337457333 285.10784386572 C159.7774337457333,285.10784386572 79.88871687286665,293.2946004927189 79.88871687286665,293.2946004927189 C79.88871687286665,293.2946004927189 39.944358436433326,297.38797880621837 19.972179218216663,299.4346679629681 C19.972179218216663,299.4346679629681 9.986089609108332,300.45801254134295 4.993044804554166,300.96968483053035 C4.993044804554166,300.96968483053035 2.496522402277083,301.2255209751241 1.2482612011385414,301.3534390474209 C1.2482612011385414,301.3534390474209 0.6241306005692707,301.41739808356937 0.31206530028463536,301.4493776016436 C0.31206530028463536,301.4493776016436 0,301.4813571197178 0,301.4813571197178 "
479
479
  fill="none"
480
480
  stroke="black"
481
481
  stroke-width="2"
482
482
  />
483
483
  <path
484
- d="M 151.99984767296695 94.92467630329621 C151.99984767296695,94.92467630329621 75.99992383648348,95.0249491830781 75.99992383648348,95.0249491830781 C75.99992383648348,95.0249491830781 37.99996191824174,95.07508562296906 18.99998095912087,95.10015384291452 C18.99998095912087,95.10015384291452 9.499990479560434,95.11268795288726 4.749995239780217,95.11895500787364 C4.749995239780217,95.11895500787364 2.3749976198901086,95.12208853536683 1.1874988099450543,95.12365529911341 C1.1874988099450543,95.12365529911341 0.5937494049725272,95.12443868098671 0.2968747024862636,95.12483037192337 C0.2968747024862636,95.12483037192337 0,95.12522206286 0,95.12522206286 "
484
+ d="M 159.7774337457333 285.10784386572 C159.7774337457333,285.10784386572 196.69432122862028,332.55392193286 196.69432122862028,332.55392193286 C196.69432122862028,332.55392193286 215.15276497006377,356.27696096643 224.38198684078552,368.138480483215 C224.38198684078552,368.138480483215 228.9965977761464,374.06924024160753 231.30390324382682,377.03462012080377 C231.30390324382682,377.03462012080377 232.45755597766703,378.5173100604019 233.03438234458713,379.25865503020094 C233.03438234458713,379.25865503020094 233.3227955280472,379.6293275151005 233.46700211977725,379.81466375755025 C233.46700211977725,379.81466375755025 233.61120871150726,380 233.61120871150726,380 "
485
485
  fill="none"
486
486
  stroke="black"
487
487
  stroke-width="2"
488
488
  />
489
489
  <path
490
- d="M 303.9999492243224 284.97489210109876 C303.9999492243224,284.97489210109876 341.99997461216117,332.48744605054935 341.99997461216117,332.48744605054935 C341.99997461216117,332.48744605054935 360.9999873060806,356.2437230252747 370.4999936530403,368.12186151263734 C370.4999936530403,368.12186151263734 375.24999682652015,374.06093075631867 377.6249984132601,377.0304653781593 C377.6249984132601,377.0304653781593 378.81249920663004,378.51523268907965 379.406249603315,379.2576163445398 C379.406249603315,379.2576163445398 379.7031248016575,379.62880817226994 379.85156240082875,379.81440408613497 C379.85156240082875,379.81440408613497 380,380 380,380 "
490
+ d="M 306.5924779152444 95.03594795523999 C306.5924779152444,95.03594795523999 343.2962389576222,47.517973977619995 343.2962389576222,47.517973977619995 C343.2962389576222,47.517973977619995 361.6481194788111,23.758986988809998 370.8240597394056,11.879493494404999 C370.8240597394056,11.879493494404999 375.4120298697028,5.939746747202499 377.7060149348514,2.9698733736012497 C377.7060149348514,2.9698733736012497 378.8530074674257,1.4849366868006248 379.4265037337128,0.7424683434003124 C379.4265037337128,0.7424683434003124 379.7132518668564,0.3712341717001562 379.8566259334282,0.1856170858500781 C379.8566259334282,0.1856170858500781 380,0 380,0 "
491
491
  fill="none"
492
492
  stroke="black"
493
493
  stroke-width="2"
@@ -500,7 +500,7 @@ exports[`Branch labels > renders a tree node labels in radial layout 1`] = `
500
500
  <text
501
501
  alignment-baseline="baseline"
502
502
  text-anchor="middle"
503
- transform="translate(227.99989844864467,183.9497842021975) rotate(0)"
503
+ transform="translate(233.18495583048883,184.07189591047998) rotate(0)"
504
504
  >
505
505
  Label!
506
506
  </text>
@@ -509,7 +509,7 @@ exports[`Branch labels > renders a tree node labels in radial layout 1`] = `
509
509
  <text
510
510
  alignment-baseline="baseline"
511
511
  text-anchor="middle"
512
- transform="translate(190.12010533393422,41.462338151648105) rotate(0)"
512
+ transform="translate(79.88871687286665,287.2946004927189) rotate(0)"
513
513
  >
514
514
  Label!
515
515
  </text>
@@ -518,7 +518,7 @@ exports[`Branch labels > renders a tree node labels in radial layout 1`] = `
518
518
  <text
519
519
  alignment-baseline="baseline"
520
520
  text-anchor="middle"
521
- transform="translate(75.99992383648348,89.0249491830781) rotate(0)"
521
+ transform="translate(196.69432122862028,326.55392193286) rotate(0)"
522
522
  >
523
523
  Label!
524
524
  </text>
@@ -527,7 +527,7 @@ exports[`Branch labels > renders a tree node labels in radial layout 1`] = `
527
527
  <text
528
528
  alignment-baseline="baseline"
529
529
  text-anchor="middle"
530
- transform="translate(341.99997461216117,326.48744605054935) rotate(0)"
530
+ transform="translate(343.2962389576222,41.517973977619995) rotate(0)"
531
531
  >
532
532
  Label!
533
533
  </text>
@@ -553,25 +553,25 @@ exports[`Branch labels > renders a tree node labels in radial layout 1`] = `
553
553
  class="branch-layer"
554
554
  >
555
555
  <path
556
- d="M 303.9999492243224 284.97489210109876 C303.9999492243224,284.97489210109876 227.99989844864467,189.9497842021975 227.99989844864467,189.9497842021975 C227.99989844864467,189.9497842021975 189.9998730608058,142.43723025274684 170.99986036688637,118.68095327802152 C170.99986036688637,118.68095327802152 161.49985401992666,106.80281479065886 156.7498508464468,100.86374554697753 C156.7498508464468,100.86374554697753 154.37484925970688,97.89421092513686 153.1873484663369,96.40944361421654 C153.1873484663369,96.40944361421654 152.59359806965193,95.66705995875637 152.29672287130944,95.29586813102628 C152.29672287130944,95.29586813102628 151.99984767296695,94.92467630329621 151.99984767296695,94.92467630329621 "
556
+ d="M 306.5924779152444 95.03594795523999 C306.5924779152444,95.03594795523999 233.18495583048883,190.07189591047998 233.18495583048883,190.07189591047998 C233.18495583048883,190.07189591047998 196.48119478811105,237.5898698881 178.12931426692217,261.34885687690996 C178.12931426692217,261.34885687690996 168.95337400632775,273.22835037131495 164.36540387603054,279.1680971185175 C164.36540387603054,279.1680971185175 162.07141881088194,282.1379704921187 160.92442627830764,283.6229071789194 C160.92442627830764,283.6229071789194 160.35093001202046,284.3653755223197 160.06418187887687,284.7366096940199 C160.06418187887687,284.7366096940199 159.7774337457333,285.10784386572 159.7774337457333,285.10784386572 "
557
557
  fill="none"
558
558
  stroke="black"
559
559
  stroke-width="2"
560
560
  />
561
561
  <path
562
- d="M 151.99984767296695 94.92467630329621 C151.99984767296695,94.92467630329621 190.12010533393422,47.462338151648105 190.12010533393422,47.462338151648105 C190.12010533393422,47.462338151648105 209.18023416441787,23.731169075824052 218.71029857965968,11.865584537912026 C218.71029857965968,11.865584537912026 223.4753307872806,5.932792268956013 225.85784689109104,2.9663961344780065 C225.85784689109104,2.9663961344780065 227.04910494299628,1.4831980672390033 227.64473396894888,0.7415990336195016 C227.64473396894888,0.7415990336195016 227.9425484819252,0.3707995168097508 228.09145573841334,0.1853997584048754 C228.09145573841334,0.1853997584048754 228.2403629949015,0 228.2403629949015,0 "
562
+ d="M 159.7774337457333 285.10784386572 C159.7774337457333,285.10784386572 79.88871687286665,293.2946004927189 79.88871687286665,293.2946004927189 C79.88871687286665,293.2946004927189 39.944358436433326,297.38797880621837 19.972179218216663,299.4346679629681 C19.972179218216663,299.4346679629681 9.986089609108332,300.45801254134295 4.993044804554166,300.96968483053035 C4.993044804554166,300.96968483053035 2.496522402277083,301.2255209751241 1.2482612011385414,301.3534390474209 C1.2482612011385414,301.3534390474209 0.6241306005692707,301.41739808356937 0.31206530028463536,301.4493776016436 C0.31206530028463536,301.4493776016436 0,301.4813571197178 0,301.4813571197178 "
563
563
  fill="none"
564
564
  stroke="black"
565
565
  stroke-width="2"
566
566
  />
567
567
  <path
568
- d="M 151.99984767296695 94.92467630329621 C151.99984767296695,94.92467630329621 75.99992383648348,95.0249491830781 75.99992383648348,95.0249491830781 C75.99992383648348,95.0249491830781 37.99996191824174,95.07508562296906 18.99998095912087,95.10015384291452 C18.99998095912087,95.10015384291452 9.499990479560434,95.11268795288726 4.749995239780217,95.11895500787364 C4.749995239780217,95.11895500787364 2.3749976198901086,95.12208853536683 1.1874988099450543,95.12365529911341 C1.1874988099450543,95.12365529911341 0.5937494049725272,95.12443868098671 0.2968747024862636,95.12483037192337 C0.2968747024862636,95.12483037192337 0,95.12522206286 0,95.12522206286 "
568
+ d="M 159.7774337457333 285.10784386572 C159.7774337457333,285.10784386572 196.69432122862028,332.55392193286 196.69432122862028,332.55392193286 C196.69432122862028,332.55392193286 215.15276497006377,356.27696096643 224.38198684078552,368.138480483215 C224.38198684078552,368.138480483215 228.9965977761464,374.06924024160753 231.30390324382682,377.03462012080377 C231.30390324382682,377.03462012080377 232.45755597766703,378.5173100604019 233.03438234458713,379.25865503020094 C233.03438234458713,379.25865503020094 233.3227955280472,379.6293275151005 233.46700211977725,379.81466375755025 C233.46700211977725,379.81466375755025 233.61120871150726,380 233.61120871150726,380 "
569
569
  fill="none"
570
570
  stroke="black"
571
571
  stroke-width="2"
572
572
  />
573
573
  <path
574
- d="M 303.9999492243224 284.97489210109876 C303.9999492243224,284.97489210109876 341.99997461216117,332.48744605054935 341.99997461216117,332.48744605054935 C341.99997461216117,332.48744605054935 360.9999873060806,356.2437230252747 370.4999936530403,368.12186151263734 C370.4999936530403,368.12186151263734 375.24999682652015,374.06093075631867 377.6249984132601,377.0304653781593 C377.6249984132601,377.0304653781593 378.81249920663004,378.51523268907965 379.406249603315,379.2576163445398 C379.406249603315,379.2576163445398 379.7031248016575,379.62880817226994 379.85156240082875,379.81440408613497 C379.85156240082875,379.81440408613497 380,380 380,380 "
574
+ d="M 306.5924779152444 95.03594795523999 C306.5924779152444,95.03594795523999 343.2962389576222,47.517973977619995 343.2962389576222,47.517973977619995 C343.2962389576222,47.517973977619995 361.6481194788111,23.758986988809998 370.8240597394056,11.879493494404999 C370.8240597394056,11.879493494404999 375.4120298697028,5.939746747202499 377.7060149348514,2.9698733736012497 C377.7060149348514,2.9698733736012497 378.8530074674257,1.4849366868006248 379.4265037337128,0.7424683434003124 C379.4265037337128,0.7424683434003124 379.7132518668564,0.3712341717001562 379.8566259334282,0.1856170858500781 C379.8566259334282,0.1856170858500781 380,0 380,0 "
575
575
  fill="none"
576
576
  stroke="black"
577
577
  stroke-width="2"
@@ -584,7 +584,7 @@ exports[`Branch labels > renders a tree node labels in radial layout 1`] = `
584
584
  <text
585
585
  alignment-baseline="baseline"
586
586
  text-anchor="middle"
587
- transform="translate(227.99989844864467,183.9497842021975) rotate(0)"
587
+ transform="translate(233.18495583048883,184.07189591047998) rotate(0)"
588
588
  >
589
589
  Label!
590
590
  </text>
@@ -593,7 +593,7 @@ exports[`Branch labels > renders a tree node labels in radial layout 1`] = `
593
593
  <text
594
594
  alignment-baseline="baseline"
595
595
  text-anchor="middle"
596
- transform="translate(190.12010533393422,41.462338151648105) rotate(0)"
596
+ transform="translate(79.88871687286665,287.2946004927189) rotate(0)"
597
597
  >
598
598
  Label!
599
599
  </text>
@@ -602,7 +602,7 @@ exports[`Branch labels > renders a tree node labels in radial layout 1`] = `
602
602
  <text
603
603
  alignment-baseline="baseline"
604
604
  text-anchor="middle"
605
- transform="translate(75.99992383648348,89.0249491830781) rotate(0)"
605
+ transform="translate(196.69432122862028,326.55392193286) rotate(0)"
606
606
  >
607
607
  Label!
608
608
  </text>
@@ -611,7 +611,7 @@ exports[`Branch labels > renders a tree node labels in radial layout 1`] = `
611
611
  <text
612
612
  alignment-baseline="baseline"
613
613
  text-anchor="middle"
614
- transform="translate(341.99997461216117,326.48744605054935) rotate(0)"
614
+ transform="translate(343.2962389576222,41.517973977619995) rotate(0)"
615
615
  >
616
616
  Label!
617
617
  </text>