|
1 |
| -<svg width="100%" height="100%" xmlns:svg="http://www.w3.org/1999/html"> |
2 |
| - <svg:foreignObject height="0" width="0" overflow="visible"> |
| 1 | +<svg |
| 2 | + class="roadmap-container" |
| 3 | + width="100%" |
| 4 | + height="100%" |
| 5 | + xmlns:svg="http://www.w3.org/1999/html" |
| 6 | +> |
| 7 | + <svg:foreignObject |
| 8 | + style="transform: translateX(calc(50% - {{ layoutEl.clientWidth / 2 }}px))" |
| 9 | + height="0" |
| 10 | + width="0" |
| 11 | + overflow="visible" |
| 12 | + > |
3 | 13 | <div
|
4 |
| - class="relative flex h-fit w-fit translate-x-80 translate-y-16 flex-col items-center gap-16" |
| 14 | + #layoutEl |
| 15 | + class="relative flex h-fit w-fit translate-y-16 flex-col items-center gap-16" |
5 | 16 | >
|
6 | 17 | @for (layer of roadmapLayers(); track layer.parentNode.id) {
|
7 | 18 | <div #layerEl class="flex w-full flex-col items-center gap-16">
|
|
14 | 25 | width="100"
|
15 | 26 | xmlns="http://www.w3.org/2000/svg"
|
16 | 27 | >
|
17 |
| - <svg:defs> |
| 28 | + <defs> |
18 | 29 | <marker
|
19 | 30 | id="arrowhead"
|
20 | 31 | markerWidth="6"
|
|
25 | 36 | >
|
26 | 37 | <polygon points="0 0, 6 4, 0 8" fill="#FDF5FD" />
|
27 | 38 | </marker>
|
28 |
| - </svg:defs> |
| 39 | + </defs> |
29 | 40 | <line
|
30 | 41 | [attr.y2]="layerHeightWithGap"
|
31 | 42 | x1="50"
|
|
49 | 60 |
|
50 | 61 | <!-- layer child nodes-->
|
51 | 62 | @if (layer.childNodes?.length) {
|
| 63 | + @let shift = |
| 64 | + (allChildNodesEl.clientWidth / 2 - leftChildNodesEl.clientWidth || |
| 65 | + 0) - 32; |
52 | 66 | <div
|
53 | 67 | #allChildNodesEl
|
54 |
| - class="translate-x-[{{ |
55 |
| - allChildNodesEl.clientWidth - leftChildNodesEl.clientWidth |
56 |
| - }}px] flex gap-12" |
| 68 | + class="flex gap-16" |
| 69 | + style="transform: translate({{ shift }}px)" |
57 | 70 | >
|
58 | 71 | <div #leftChildNodesEl class="flex gap-12">
|
| 72 | + @let centerShift = layerEl.clientWidth / 2 - shift; |
59 | 73 | @for (node of layer.childNodes | leftSlice; track node.id) {
|
60 |
| - <div class="flex gap-10"> |
| 74 | + @let arrowShift = |
| 75 | + secondaryNode.offsetLeft - |
| 76 | + centerShift + |
| 77 | + secondaryNode.clientWidth / 2; |
| 78 | + <svg |
| 79 | + [attr.height]="64" |
| 80 | + style="position: absolute; top: -64px; left: {{ |
| 81 | + centerShift |
| 82 | + }}px" |
| 83 | + overflow="visible" |
| 84 | + width="1" |
| 85 | + xmlns="http://www.w3.org/2000/svg" |
| 86 | + > |
| 87 | + <svg:path |
| 88 | + [attr.d]="arrowShift | secondaryArrow: $first" |
| 89 | + fill="none" |
| 90 | + stroke="#FDF5FD" |
| 91 | + stroke-width="2" |
| 92 | + stroke-linecap="round" |
| 93 | + stroke-linejoin="round" |
| 94 | + /> |
| 95 | + </svg> |
| 96 | + <div #secondaryNode> |
61 | 97 | @if (node.nodeType === 'secondary') {
|
62 | 98 | <al-ui-roadmap-secondary-node [node]="node" />
|
63 | 99 | } @else if (node.nodeType === 'cluster') {
|
|
69 | 105 | }
|
70 | 106 | </div>
|
71 | 107 | @for (node of layer.childNodes | rightSlice; track node.id) {
|
72 |
| - <div class="flex gap-10"> |
| 108 | + @let arrowShift = |
| 109 | + secondaryNode.offsetLeft - |
| 110 | + centerShift + |
| 111 | + secondaryNode.clientWidth / 2; |
| 112 | + <svg |
| 113 | + [attr.height]="64" |
| 114 | + style="position: absolute; top: -64px; left: {{ |
| 115 | + centerShift |
| 116 | + }}px" |
| 117 | + overflow="visible" |
| 118 | + width="1" |
| 119 | + xmlns="http://www.w3.org/2000/svg" |
| 120 | + > |
| 121 | + <svg:path |
| 122 | + [attr.d]="arrowShift | secondaryArrow: $last" |
| 123 | + fill="none" |
| 124 | + stroke="#FDF5FD" |
| 125 | + stroke-width="2" |
| 126 | + stroke-linecap="round" |
| 127 | + stroke-linejoin="round" |
| 128 | + /> |
| 129 | + </svg> |
| 130 | + <div #secondaryNode> |
73 | 131 | @if (node.nodeType === 'secondary') {
|
74 | 132 | <al-ui-roadmap-secondary-node [node]="node" />
|
75 | 133 | } @else if (node.nodeType === 'cluster') {
|
|
0 commit comments