BibTest.js: Difference between revisions
From Illustrations in German Translations of Mark Twain's Works
No edit summary |
No edit summary |
||
| Line 63: | Line 63: | ||
// SIMPLE NETWORK GRAPH | // SIMPLE NETWORK GRAPH | ||
function buildNetwork() { | |||
const container = document.getElementById("networkView"); | |||
container.innerHTML = ""; | |||
const entries = | const entries = document.querySelectorAll(".bib-entry"); | ||
const | const tagNodes = new Map(); | ||
const entryNodes = []; | |||
tags | let centerX = 400; | ||
let centerY = 300; | |||
// 1. ENTRY NODES | |||
entries.forEach((entry, i) => { | |||
const node = document.createElement("div"); | |||
node.className = "node entry"; | |||
node.innerText = entry.querySelector("h3").innerText; | |||
let x = centerX + Math.cos(i) * 200; | |||
let y = centerY + Math.sin(i) * 200; | |||
node.style.left = x + "px"; | |||
node.style.top = y + "px"; | |||
container.appendChild(node); | |||
entryNodes.push({ node, entry, x, y }); | |||
// click highlight | |||
node.addEventListener("click", () => { | |||
document.querySelectorAll(".node").forEach(n => | |||
n.classList.remove("highlight") | |||
); | |||
node.classList.add("highlight"); | |||
}); | |||
// TAG LINKS | |||
const tags = entry.dataset.tags.split(" "); | |||
tags.forEach(tag => { | |||
if (!tagNodes.has(tag)) { | |||
const tnode = document.createElement("div"); | |||
tnode.className = "node tag"; | |||
tnode.innerText = tag; | |||
let tx = Math.random() * 600 + 100; | |||
let ty = Math.random() * 400 + 100; | |||
tnode.style.left = tx + "px"; | |||
tnode.style.top = ty + "px"; | |||
container.appendChild(tnode); | |||
tagNodes.set(tag, { node: tnode, x: tx, y: ty }); | |||
} | |||
}); | |||
}); | }); | ||
// | // 2. EDGES (entry → tag) | ||
entryNodes.forEach(e => { | |||
const tags = e.entry.dataset.tags.split(" "); | |||
tags.forEach(tag => { | |||
const t = tagNodes.get(tag); | |||
const line = document.createElement("div"); | |||
line.className = "edge"; | |||
const dx = t.x - e.x; | |||
const dy = t.y - e.y; | |||
const length = Math.sqrt(dx*dx + dy*dy); | |||
line.style.width = length + "px"; | |||
line.style.left = e.x + "px"; | |||
line.style.top = e.y + "px"; | |||
line.style.transform = `rotate(${Math.atan2(dy, dx)}rad)`; | |||
container.appendChild(line); | |||
}); | |||
}); | |||
} | } | ||
document.querySelectorAll(".expand-btn").forEach(btn => { | document.querySelectorAll(".expand-btn").forEach(btn => { | ||
| Line 120: | Line 174: | ||
? "Show Abstract" | ? "Show Abstract" | ||
: "Hide Abstract"; | : "Hide Abstract"; | ||
}); | |||
}); | |||
document.querySelectorAll(".view-btn").forEach(btn => { | |||
btn.addEventListener("click", () => { | |||
document.querySelectorAll(".view-btn") | |||
.forEach(b => b.classList.remove("active")); | |||
btn.classList.add("active"); | |||
const view = btn.dataset.view; | |||
document.getElementById("listView").style.display = | |||
view === "list" ? "block" : "none"; | |||
document.getElementById("networkView").classList.toggle( | |||
"hidden", | |||
view !== "network" | |||
); | |||
if (view === "network") { | |||
buildNetwork(); | |||
} | |||
}); | }); | ||
}); | }); | ||
Revision as of 21:58, 11 May 2026
const activeTags = new Set();
/* TAG CLICK HANDLING */
document.querySelectorAll(".tag").forEach(tag => {
tag.addEventListener("click", () => {
const value = tag.dataset.tag;
if (activeTags.has(value)) {
activeTags.delete(value);
tag.classList.remove("active");
} else {
activeTags.add(value);
tag.classList.add("active");
}
filterEntries();
});
});
/* FILTER FUNCTION */
function filterEntries() {
document.querySelectorAll(".bib-entry").forEach(entry => {
const entryTags = entry.dataset.tags.split(" ");
const matches =
[...activeTags].every(t => entryTags.includes(t));
if (activeTags.size === 0 || matches) {
entry.style.display = "block";
} else {
entry.style.display = "none";
}
});
}
document.querySelectorAll(".view-btn").forEach(btn => {
btn.addEventListener("click", () => {
document.querySelectorAll(".view-btn")
.forEach(b => b.classList.remove("active"));
btn.classList.add("active");
const view = btn.dataset.view;
document.getElementById("listView").style.display =
view === "list" ? "block" : "none";
document.getElementById("networkCanvas").style.display =
view === "network" ? "block" : "none";
drawNetwork();
});
});
// SIMPLE NETWORK GRAPH
function buildNetwork() {
const container = document.getElementById("networkView");
container.innerHTML = "";
const entries = document.querySelectorAll(".bib-entry");
const tagNodes = new Map();
const entryNodes = [];
let centerX = 400;
let centerY = 300;
// 1. ENTRY NODES
entries.forEach((entry, i) => {
const node = document.createElement("div");
node.className = "node entry";
node.innerText = entry.querySelector("h3").innerText;
let x = centerX + Math.cos(i) * 200;
let y = centerY + Math.sin(i) * 200;
node.style.left = x + "px";
node.style.top = y + "px";
container.appendChild(node);
entryNodes.push({ node, entry, x, y });
// click highlight
node.addEventListener("click", () => {
document.querySelectorAll(".node").forEach(n =>
n.classList.remove("highlight")
);
node.classList.add("highlight");
});
// TAG LINKS
const tags = entry.dataset.tags.split(" ");
tags.forEach(tag => {
if (!tagNodes.has(tag)) {
const tnode = document.createElement("div");
tnode.className = "node tag";
tnode.innerText = tag;
let tx = Math.random() * 600 + 100;
let ty = Math.random() * 400 + 100;
tnode.style.left = tx + "px";
tnode.style.top = ty + "px";
container.appendChild(tnode);
tagNodes.set(tag, { node: tnode, x: tx, y: ty });
}
});
});
// 2. EDGES (entry → tag)
entryNodes.forEach(e => {
const tags = e.entry.dataset.tags.split(" ");
tags.forEach(tag => {
const t = tagNodes.get(tag);
const line = document.createElement("div");
line.className = "edge";
const dx = t.x - e.x;
const dy = t.y - e.y;
const length = Math.sqrt(dx*dx + dy*dy);
line.style.width = length + "px";
line.style.left = e.x + "px";
line.style.top = e.y + "px";
line.style.transform = `rotate(${Math.atan2(dy, dx)}rad)`;
container.appendChild(line);
});
});
}
document.querySelectorAll(".expand-btn").forEach(btn => {
btn.addEventListener("click", () => {
const abstract =
btn.nextElementSibling;
abstract.classList.toggle("hidden");
btn.textContent =
abstract.classList.contains("hidden")
? "Show Abstract"
: "Hide Abstract";
});
});
document.querySelectorAll(".view-btn").forEach(btn => {
btn.addEventListener("click", () => {
document.querySelectorAll(".view-btn")
.forEach(b => b.classList.remove("active"));
btn.classList.add("active");
const view = btn.dataset.view;
document.getElementById("listView").style.display =
view === "list" ? "block" : "none";
document.getElementById("networkView").classList.toggle(
"hidden",
view !== "network"
);
if (view === "network") {
buildNetwork();
}
});
});