Skip to content

Commit 7aa2a44

Browse files
committed
Implicit nested connections (#1204)
1 parent e319c92 commit 7aa2a44

File tree

3 files changed

+312
-77
lines changed

3 files changed

+312
-77
lines changed

source/grapher.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@
7979

8080
.cluster rect { stroke: #000; fill: #000; fill-opacity: 0.02; stroke-opacity: 0.06; stroke-width: 1px; }
8181

82+
.node-block > .node-block-background { fill: #fff; stroke: none; stroke-width: 0; }
83+
.node-block .edge-path { stroke: #000; stroke-width: 1px; fill: none; }
84+
8285
@keyframes pulse { from { stroke-dashoffset: 100px; } to { stroke-dashoffset: 0; } }
8386

8487
@media (prefers-color-scheme: dark) {
@@ -142,4 +145,7 @@
142145
.node-item-type-quantization path { fill: rgb(80, 40, 0, 0.7); }
143146
.node-item-type-attention path { fill: rgb(100, 50, 0, 0.7); }
144147
.node-item-type-custom path { fill: rgb(64, 64, 64, 0.7); }
148+
149+
.node-block > .node-block-background { fill: #404040; stroke: none; }
150+
.node-block .edge-path { stroke: #888; }
145151
}

source/grapher.js

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ grapher.Graph = class {
103103
return null;
104104
}
105105

106-
build(document) {
106+
build(document, origin) {
107107

108-
const origin = document.getElementById('origin');
108+
origin = origin || document.getElementById('origin');
109109

110110
const createGroup = (name) => {
111111
const element = document.createElementNS('http://www.w3.org/2000/svg', 'g');
@@ -214,7 +214,9 @@ grapher.Graph = class {
214214
const entry = this.node(key);
215215
if (this.children(key).length === 0) {
216216
const node = entry.label;
217-
node.measure();
217+
/* eslint-disable no-await-in-loop */
218+
await node.measure();
219+
/* eslint-enable no-await-in-loop */
218220
}
219221
}
220222
}
@@ -272,6 +274,10 @@ grapher.Graph = class {
272274
const fs = await import('fs');
273275
fs.writeFileSync(`dist/test/${this.identifier}.log`, state.log);
274276
}
277+
let minX = Infinity;
278+
let minY = Infinity;
279+
let maxX = -Infinity;
280+
let maxY = -Infinity;
275281
for (const node of nodes) {
276282
const label = this.node(node.v).label;
277283
label.x = node.x;
@@ -280,6 +286,18 @@ grapher.Graph = class {
280286
label.width = node.width;
281287
label.height = node.height;
282288
}
289+
const hw = (node.width || 0) / 2;
290+
const hh = (node.height || 0) / 2;
291+
minX = Math.min(minX, node.x - hw);
292+
minY = Math.min(minY, node.y - hh);
293+
maxX = Math.max(maxX, node.x + hw);
294+
maxY = Math.max(maxY, node.y + hh);
295+
}
296+
if (isFinite(minX)) {
297+
this.width = maxX - minX;
298+
this.height = maxY - minY;
299+
this.originX = minX;
300+
this.originY = minY;
283301
}
284302
for (const edge of edges) {
285303
const label = this.edge(edge.v, edge.w).label;
@@ -293,7 +311,8 @@ grapher.Graph = class {
293311
const entry = this.node(key);
294312
if (this.children(key).length === 0) {
295313
const node = entry.label;
296-
node.layout();
314+
// eslint-disable-next-line no-await-in-loop
315+
await node.layout();
297316
}
298317
}
299318
return '';
@@ -366,10 +385,11 @@ grapher.Node = class {
366385
this.element.appendChild(this.border);
367386
}
368387

369-
measure() {
388+
async measure() {
370389
this.height = 0;
371390
for (const block of this._blocks) {
372-
block.measure();
391+
// eslint-disable-next-line no-await-in-loop
392+
await block.measure();
373393
this.height += block.height;
374394
}
375395
this.width = Math.max(...this._blocks.map((block) => block.width));
@@ -378,13 +398,14 @@ grapher.Node = class {
378398
}
379399
}
380400

381-
layout() {
401+
async layout() {
382402
let y = 0;
383403
for (const block of this._blocks) {
384404
block.x = 0;
385405
block.y = y;
386406
block.width = this.width;
387-
block.layout();
407+
// eslint-disable-next-line no-await-in-loop
408+
await block.layout();
388409
y += block.height;
389410
}
390411
}
@@ -625,12 +646,14 @@ grapher.ArgumentList = class {
625646
}
626647
}
627648

628-
measure() {
649+
async measure() {
629650
this.width = 75;
630651
this.height = 3;
631652
for (let i = 0; i < this._items.length; i++) {
632653
const item = this._items[i];
633-
item.measure();
654+
/* eslint-disable no-await-in-loop */
655+
await item.measure();
656+
/* eslint-enable no-await-in-loop */
634657
this.height += item.height;
635658
this.width = Math.max(this.width, item.width);
636659
if (item.type === 'node' || item.type === 'node[]') {
@@ -645,13 +668,15 @@ grapher.ArgumentList = class {
645668
this.height += 3;
646669
}
647670

648-
layout() {
671+
async layout() {
649672
let y = 3;
650673
for (const item of this._items) {
651674
item.x = this.x;
652675
item.y = y;
653676
item.width = this.width;
654-
item.layout();
677+
/* eslint-disable no-await-in-loop */
678+
await item.layout();
679+
/* eslint-enable no-await-in-loop */
655680
y += item.height;
656681
}
657682
}
@@ -748,7 +773,7 @@ grapher.Argument = class {
748773
}
749774
}
750775

751-
measure() {
776+
async measure() {
752777
const yPadding = 1;
753778
const xPadding = 6;
754779
const size = this.text.getBBox();
@@ -758,32 +783,35 @@ grapher.Argument = class {
758783
this.height = this.bottom;
759784
if (this.type === 'node') {
760785
const node = this.content;
761-
node.measure();
786+
await node.measure();
762787
this.width = Math.max(150, this.width, node.width + (2 * xPadding));
763788
this.height += node.height + yPadding + yPadding + yPadding + yPadding;
764789
} else if (this.type === 'node[]') {
765790
for (const node of this.content) {
766-
node.measure();
791+
/* eslint-disable no-await-in-loop */
792+
await node.measure();
793+
/* eslint-enable no-await-in-loop */
767794
this.width = Math.max(150, this.width, node.width + (2 * xPadding));
768795
this.height += node.height + yPadding + yPadding + yPadding + yPadding;
769796
}
770797
}
771798
}
772799

773-
layout() {
800+
async layout() {
774801
const yPadding = 1;
775802
const xPadding = 6;
776803
let y = this.y + this.bottom;
777804
if (this.type === 'node') {
778805
const node = this.content;
779806
node.width = this.width - xPadding - xPadding;
780-
node.layout();
807+
await node.layout();
781808
node.x = this.x + xPadding + (node.width / 2);
782809
node.y = y + (node.height / 2) + yPadding + yPadding;
783810
} else if (this.type === 'node[]') {
784811
for (const node of this.content) {
785812
node.width = this.width - xPadding - xPadding;
786-
node.layout();
813+
// eslint-disable-next-line no-await-in-loop
814+
await node.layout();
787815
node.x = this.x + xPadding + (node.width / 2);
788816
node.y = y + (node.height / 2) + yPadding + yPadding;
789817
y += node.height + yPadding + yPadding + yPadding + yPadding;

0 commit comments

Comments
 (0)