graph functionality

This commit is contained in:
2026-08-15 00:51:51 +02:00
parent caa16a0ce8
commit b3afd64769
6 changed files with 79 additions and 9 deletions
+38 -2
View File
@@ -23,6 +23,7 @@
$(id).classList.toggle("hidden", id !== viewId);
}
$("page-action-links").classList.toggle("hidden", viewId !== "page-view");
$("context-link").classList.toggle("hidden", !(state.currentPage && ["page-view", "editor-view", "history-view"].includes(viewId)));
document.body.classList.toggle("editor-mode", viewId === "editor-view");
}
@@ -1182,7 +1183,7 @@
return { nodes: state.pages, edges };
}
function renderWikiGraph(data) {
function renderWikiGraph(data, focusSlug = null) {
const svg = $("wiki-graph");
svg.replaceChildren();
@@ -1222,7 +1223,7 @@
for (const page of nodes) {
const position = positions.get(page.slug);
const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
group.setAttribute("class", "wiki-graph-node");
group.setAttribute("class", page.slug === focusSlug ? "wiki-graph-node wiki-graph-node-focus" : "wiki-graph-node");
group.setAttribute("transform", `translate(${position.x} ${position.y})`);
group.setAttribute("tabindex", "0");
group.setAttribute("role", "link");
@@ -1259,6 +1260,7 @@
]);
renderToc([], () => {});
show("graph-view");
$("graph-title").textContent = tr("wiki-graph", "Wiki graph");
const data = await loadGraphData();
$("graph-summary").textContent = tr("graph-summary", "{pages} pages, {links} links")
@@ -1267,6 +1269,39 @@
renderWikiGraph(data);
}
async function showContextGraph() {
if (!state.currentPage) return;
const page = state.currentPage;
state.previousView = "page-view";
renderBreadcrumbs([
{ label: state.siteTitle, href: "/" },
{ label: page.title, href: `#/${encodeURIComponent(page.slug)}` },
{ label: tr("context", "context") }
]);
renderToc([], () => {});
show("graph-view");
$("graph-title").textContent = tr("context-graph", "Context graph");
const data = await loadGraphData();
const relatedSlugs = new Set([page.slug]);
const contextEdges = [];
for (const edge of data.edges) {
if (edge.from === page.slug || edge.to === page.slug) {
relatedSlugs.add(edge.from);
relatedSlugs.add(edge.to);
contextEdges.push(edge);
}
}
const contextNodes = data.nodes.filter((node) => relatedSlugs.has(node.slug));
$("graph-summary").textContent = tr("context-graph-summary", "{pages} related pages, {links} links")
.replace("{pages}", String(Math.max(0, contextNodes.length - 1)))
.replace("{links}", String(contextEdges.length));
renderWikiGraph({ nodes: contextNodes, edges: contextEdges }, page.slug);
}
function setConnectionStatus(status) {
const node = $("connection-status");
node.classList.remove("hidden", "online", "offline");
@@ -1339,6 +1374,7 @@
});
$("todo-link").addEventListener("click", (event) => { event.preventDefault(); showTodos().catch((error) => console.error(error)); });
$("graph-link").addEventListener("click", (event) => { event.preventDefault(); showGraph().catch((error) => console.error(error)); });
$("context-link").addEventListener("click", (event) => { event.preventDefault(); showContextGraph().catch((error) => console.error(error)); });
$("logout-link").addEventListener("click", async (event) => {
event.preventDefault();
await api("/api/logout", { method: "POST", body: "{}" });