Pacific-i64 commited on
Commit
c9ad58d
·
verified ·
1 Parent(s): 7851783

Make architecture connectors responsive

Browse files
Files changed (1) hide show
  1. index.html +59 -8
index.html CHANGED
@@ -392,14 +392,14 @@
392
  </div>
393
 
394
  <div class="tr-architecture" role="img" aria-label="The contextual hidden state enters both a shared SwiGLU branch and two selected residual experts. Token identity controls only the fixed route table.">
395
- <svg class="tr-lines" viewBox="0 0 1000 500" preserveAspectRatio="none" aria-hidden="true">
396
- <path d="M330 72 C280 120 210 140 205 190" fill="none" stroke="currentColor" stroke-width="1.5"/>
397
- <path class="active" d="M330 72 C410 115 550 135 580 190" fill="none" stroke="currentColor"/>
398
- <path class="active" d="M800 72 C850 110 860 135 850 190" fill="none" stroke="currentColor"/>
399
- <path class="active" d="M840 255 C790 270 730 250 690 225" fill="none" stroke="currentColor" stroke-dasharray="7 7"/>
400
- <path d="M220 310 C300 360 405 400 485 415" fill="none" stroke="currentColor" stroke-width="1.5"/>
401
- <path class="active" d="M630 310 C610 350 560 395 520 415" fill="none" stroke="currentColor"/>
402
- <path class="active" d="M535 420 C630 430 720 430 805 420" fill="none" stroke="currentColor"/>
403
  </svg>
404
 
405
  <div class="tr-node tr-context">
@@ -585,13 +585,64 @@
585
 
586
  const tabs = [...root.querySelectorAll(".tr-tab")];
587
  const panels = [...root.querySelectorAll(".tr-view")];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
588
  tabs.forEach((tab) => {
589
  tab.addEventListener("click", () => {
590
  tabs.forEach((item) => item.setAttribute("aria-selected", String(item === tab)));
591
  panels.forEach((panel) => panel.classList.toggle("is-active", panel.dataset.panel === tab.dataset.view));
 
592
  });
593
  });
594
 
 
 
 
 
 
 
 
 
595
  const updateArchitecture = (token) => {
596
  const route = routes[token];
597
  if (!route) return;
 
392
  </div>
393
 
394
  <div class="tr-architecture" role="img" aria-label="The contextual hidden state enters both a shared SwiGLU branch and two selected residual experts. Token identity controls only the fixed route table.">
395
+ <svg class="tr-lines" aria-hidden="true">
396
+ <path data-from=".tr-context" data-from-anchor="bottom" data-to=".tr-shared" data-to-anchor="top" fill="none" stroke="currentColor" stroke-width="1.5"/>
397
+ <path class="active" data-from=".tr-context" data-from-anchor="bottom" data-to=".tr-experts" data-to-anchor="top" fill="none" stroke="currentColor"/>
398
+ <path class="active" data-from=".tr-token" data-from-anchor="bottom" data-to=".tr-table" data-to-anchor="top" fill="none" stroke="currentColor"/>
399
+ <path class="active" data-from=".tr-table" data-from-anchor="left" data-to=".tr-experts" data-to-anchor="right" fill="none" stroke="currentColor" stroke-dasharray="7 7"/>
400
+ <path data-from=".tr-shared" data-from-anchor="bottom" data-to=".tr-sum" data-to-anchor="left" fill="none" stroke="currentColor" stroke-width="1.5"/>
401
+ <path class="active" data-from=".tr-experts" data-from-anchor="bottom" data-to=".tr-sum" data-to-anchor="top" fill="none" stroke="currentColor"/>
402
+ <path class="active" data-from=".tr-sum" data-from-anchor="right" data-to=".tr-output" data-to-anchor="left" fill="none" stroke="currentColor"/>
403
  </svg>
404
 
405
  <div class="tr-node tr-context">
 
585
 
586
  const tabs = [...root.querySelectorAll(".tr-tab")];
587
  const panels = [...root.querySelectorAll(".tr-view")];
588
+ const architecture = root.querySelector(".tr-architecture");
589
+ const lineLayer = root.querySelector(".tr-lines");
590
+
591
+ const anchorPoint = (element, anchor, bounds) => {
592
+ const rect = element.getBoundingClientRect();
593
+ const points = {
594
+ top: { x: rect.left + rect.width / 2, y: rect.top },
595
+ right: { x: rect.right, y: rect.top + rect.height / 2 },
596
+ bottom: { x: rect.left + rect.width / 2, y: rect.bottom },
597
+ left: { x: rect.left, y: rect.top + rect.height / 2 }
598
+ };
599
+ const point = points[anchor] || points.bottom;
600
+ return { x: point.x - bounds.left, y: point.y - bounds.top };
601
+ };
602
+
603
+ const updateConnectorPaths = () => {
604
+ if (!architecture || !lineLayer || !architecture.offsetParent) return;
605
+ const bounds = architecture.getBoundingClientRect();
606
+ if (!bounds.width || !bounds.height) return;
607
+ lineLayer.setAttribute("viewBox", `0 0 ${bounds.width} ${bounds.height}`);
608
+ lineLayer.querySelectorAll("[data-from][data-to]").forEach((path) => {
609
+ const from = architecture.querySelector(path.dataset.from);
610
+ const to = architecture.querySelector(path.dataset.to);
611
+ if (!from || !to) return;
612
+ const start = anchorPoint(from, path.dataset.fromAnchor, bounds);
613
+ const end = anchorPoint(to, path.dataset.toAnchor, bounds);
614
+ const dx = end.x - start.x;
615
+ const dy = end.y - start.y;
616
+ let d;
617
+ if (Math.abs(dx) > Math.abs(dy)) {
618
+ const direction = Math.sign(dx) || 1;
619
+ const bend = Math.max(32, Math.abs(dx) * 0.42);
620
+ d = `M ${start.x} ${start.y} C ${start.x + direction * bend} ${start.y}, ${end.x - direction * bend} ${end.y}, ${end.x} ${end.y}`;
621
+ } else {
622
+ const direction = Math.sign(dy) || 1;
623
+ const bend = Math.max(32, Math.abs(dy) * 0.42);
624
+ d = `M ${start.x} ${start.y} C ${start.x} ${start.y + direction * bend}, ${end.x} ${end.y - direction * bend}, ${end.x} ${end.y}`;
625
+ }
626
+ path.setAttribute("d", d);
627
+ });
628
+ };
629
+
630
  tabs.forEach((tab) => {
631
  tab.addEventListener("click", () => {
632
  tabs.forEach((item) => item.setAttribute("aria-selected", String(item === tab)));
633
  panels.forEach((panel) => panel.classList.toggle("is-active", panel.dataset.panel === tab.dataset.view));
634
+ if (tab.dataset.view === "overview") requestAnimationFrame(updateConnectorPaths);
635
  });
636
  });
637
 
638
+ if (architecture && "ResizeObserver" in window) {
639
+ const connectorResizeObserver = new ResizeObserver(() => requestAnimationFrame(updateConnectorPaths));
640
+ connectorResizeObserver.observe(architecture);
641
+ }
642
+ window.addEventListener("resize", updateConnectorPaths);
643
+ document.fonts?.ready.then(updateConnectorPaths);
644
+ requestAnimationFrame(updateConnectorPaths);
645
+
646
  const updateArchitecture = (token) => {
647
  const route = routes[token];
648
  if (!route) return;