@takagaki/cortex-decisions-viewer 0.4.5 → 0.4.6
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/dist/build.js +26 -23
- package/dist/render.js +5 -2
- package/package.json +1 -1
package/dist/build.js
CHANGED
|
@@ -472,7 +472,9 @@ function buildGraph(decisions, home, sections, content, targetUrls, repoBaseUrl,
|
|
|
472
472
|
for (const sec of sections)
|
|
473
473
|
for (const r of sec.records)
|
|
474
474
|
fileNameToId.set(r.fileName, r.id);
|
|
475
|
-
// 参照先ID
|
|
475
|
+
// 参照先IDから層を推定してノード化する。
|
|
476
|
+
// 外部リンク(http(s))はノード化せず null を返す(外部URLの点はグラフ肥大化=描画負荷の主因。
|
|
477
|
+
// リンク自体は各レコードの詳細・参照欄に残るため情報は失われない)。
|
|
476
478
|
const classifyTarget = (target) => {
|
|
477
479
|
if (nodes.has(target))
|
|
478
480
|
return target;
|
|
@@ -496,9 +498,7 @@ function buildGraph(decisions, home, sections, content, targetUrls, repoBaseUrl,
|
|
|
496
498
|
return addNode({ id: target, label, group, url });
|
|
497
499
|
}
|
|
498
500
|
else if (/^https?:\/\//.test(target)) {
|
|
499
|
-
|
|
500
|
-
label = target.replace(/^https?:\/\//, "").slice(0, 60);
|
|
501
|
-
return addNode({ id: target, label, group, url: target });
|
|
501
|
+
return null; // 外部リンクはノード化しない
|
|
502
502
|
}
|
|
503
503
|
else if (target.includes("/") || target.toLowerCase().endsWith(".md")) {
|
|
504
504
|
group = "silver"; // リポジトリ内ファイルへのパス参照 → GitHubのコピーへ飛べるようにする
|
|
@@ -508,35 +508,30 @@ function buildGraph(decisions, home, sections, content, targetUrls, repoBaseUrl,
|
|
|
508
508
|
}
|
|
509
509
|
return addNode({ id: target, label, group });
|
|
510
510
|
};
|
|
511
|
+
// 解決先が null(外部リンク等で非ノード化)の辺は張らない
|
|
512
|
+
const pushEdge = (fromId, target, rel) => {
|
|
513
|
+
if (target)
|
|
514
|
+
edges.push({ from: fromId, to: target, rel });
|
|
515
|
+
};
|
|
511
516
|
const addRelationEdges = (fromId, relations) => {
|
|
512
|
-
for (const r of relations)
|
|
513
|
-
|
|
514
|
-
}
|
|
517
|
+
for (const r of relations)
|
|
518
|
+
pushEdge(fromId, classifyTarget(r.target), r.rel);
|
|
515
519
|
};
|
|
516
520
|
const addSourceEdge = (fromId, source) => {
|
|
517
521
|
if (source && source.trim() !== "")
|
|
518
|
-
|
|
522
|
+
pushEdge(fromId, classifyTarget(source.trim()), "source");
|
|
519
523
|
};
|
|
520
524
|
const addReferenceEdges = (fromId, references) => {
|
|
525
|
+
// ref.url(http(s))は classifyTarget が null を返す=外部はノード化しない。
|
|
526
|
+
// URLが無い参照(課題キー・議事録ID等)は従来どおり該当ノードへ繋ぐ。
|
|
521
527
|
for (const ref of references) {
|
|
522
|
-
|
|
523
|
-
const id = addNode({
|
|
524
|
-
id: ref.url,
|
|
525
|
-
label: ref.label.slice(0, 60),
|
|
526
|
-
group: "external",
|
|
527
|
-
url: ref.url,
|
|
528
|
-
});
|
|
529
|
-
edges.push({ from: fromId, to: id, rel: "reference" });
|
|
530
|
-
}
|
|
531
|
-
else {
|
|
532
|
-
edges.push({ from: fromId, to: classifyTarget(ref.label), rel: "reference" });
|
|
533
|
-
}
|
|
528
|
+
pushEdge(fromId, classifyTarget(ref.url ?? ref.label), "reference");
|
|
534
529
|
}
|
|
535
530
|
};
|
|
536
531
|
const addLinkEdges = (fromId, links) => {
|
|
537
532
|
for (const link of links) {
|
|
538
533
|
const key = backlogViewKey(link);
|
|
539
|
-
|
|
534
|
+
pushEdge(fromId, classifyTarget(key ?? link), "link");
|
|
540
535
|
}
|
|
541
536
|
};
|
|
542
537
|
// Bronze/Silverのノードを先に登録する(Gold・Bronze/Silver双方からの参照が同一ノードに解決されるように)
|
|
@@ -573,7 +568,7 @@ function buildGraph(decisions, home, sections, content, targetUrls, repoBaseUrl,
|
|
|
573
568
|
}
|
|
574
569
|
for (const c of content) {
|
|
575
570
|
for (const e of c.edges) {
|
|
576
|
-
|
|
571
|
+
pushEdge(c.id, classifyTarget(e.target), e.rel);
|
|
577
572
|
}
|
|
578
573
|
}
|
|
579
574
|
// 自己ループと重複辺を除去する(同じURLが複数回貼られていても辺は1本)
|
|
@@ -587,7 +582,15 @@ function buildGraph(decisions, home, sections, content, targetUrls, repoBaseUrl,
|
|
|
587
582
|
seen.add(key);
|
|
588
583
|
return true;
|
|
589
584
|
});
|
|
590
|
-
|
|
585
|
+
// 描画対象は「レコード(Gold) or 辺に接続のあるノード」だけ。外部リンク除去で孤立した
|
|
586
|
+
// 非レコードノードは描画もされないため、ペイロードからも落としておく(初期ロードを軽くする)。
|
|
587
|
+
const usedIds = new Set();
|
|
588
|
+
for (const e of deduped) {
|
|
589
|
+
usedIds.add(e.from);
|
|
590
|
+
usedIds.add(e.to);
|
|
591
|
+
}
|
|
592
|
+
const prunedNodes = [...nodes.values()].filter((n) => n.recordId || usedIds.has(n.id));
|
|
593
|
+
return { nodes: prunedNodes, edges: deduped };
|
|
591
594
|
}
|
|
592
595
|
/**
|
|
593
596
|
* 各レコードの bodyHtml を out/bodies/<i>.html に書き出し、bodyRef にパスを設定して
|
package/dist/render.js
CHANGED
|
@@ -1013,7 +1013,7 @@ const CLIENT_JS = `
|
|
|
1013
1013
|
n.vx *= 0.85; n.vy *= 0.85;
|
|
1014
1014
|
n.x += n.vx * alpha; n.y += n.vy * alpha;
|
|
1015
1015
|
});
|
|
1016
|
-
if (alpha > 0.
|
|
1016
|
+
if (alpha > 0.0015) alpha *= 0.97; // 収束まで減衰しきる(下げ止まりさせず、整定後はループ側で物理計算を止める)
|
|
1017
1017
|
}
|
|
1018
1018
|
|
|
1019
1019
|
function nodeRadius(n) {
|
|
@@ -1257,6 +1257,7 @@ const CLIENT_JS = `
|
|
|
1257
1257
|
else if (n.url) window.open(n.url, "_blank", "noopener");
|
|
1258
1258
|
}
|
|
1259
1259
|
}
|
|
1260
|
+
if (draggingNode) alpha = Math.max(alpha, 0.2); // 動かした点の周りを少し整え直してから止まる
|
|
1260
1261
|
draggingNode = null;
|
|
1261
1262
|
panning = null;
|
|
1262
1263
|
canvas.classList.remove("dragging");
|
|
@@ -1282,7 +1283,9 @@ const CLIENT_JS = `
|
|
|
1282
1283
|
var running = true;
|
|
1283
1284
|
function loop() {
|
|
1284
1285
|
if (!running || !document.body.contains(canvas)) { running = false; return; }
|
|
1285
|
-
|
|
1286
|
+
// 収束後(alpha減衰しきり・無操作)は O(n²) の物理計算 tick を止める。これが「固まり続ける」主因。
|
|
1287
|
+
// ドラッグ/パン中は動かす必要があるので回す。描画(draw)はホバー演出・イントロのため毎フレーム続ける。
|
|
1288
|
+
if (alpha > 0.004 || draggingNode || panning) tick();
|
|
1286
1289
|
draw();
|
|
1287
1290
|
requestAnimationFrame(loop);
|
|
1288
1291
|
}
|