Render the pedigree top-down as a family tree
Replace the indented ancestry list with a top-down chart: the dog on top, sire (left) and dam (right) branching below, connected by lines drawn with each node's CSS ::before/::after (a nested <ul>/<li> tree). It shows three generations by default and each dog expands to trace the line further back; deeper levels get wide, so the view scrolls horizontally.
This commit is contained in:
+16
-13
@@ -2459,7 +2459,7 @@
|
||||
const pedBtn = document.getElementById("pedigree-btn");
|
||||
const pedRefresh = document.getElementById("pedigree-refresh");
|
||||
|
||||
const PED_OPEN_DEPTH = 4; // generations shown expanded by default; deeper collapse
|
||||
const PED_OPEN_DEPTH = 3; // show 3 generations expanded by default; deeper collapses
|
||||
let pedPollTimer = null;
|
||||
let pedNodes = {}; // latest ancestry map, for the progress count
|
||||
|
||||
@@ -2646,12 +2646,18 @@
|
||||
}
|
||||
|
||||
// The tree is ahnentafel-indexed: the dog is position 1, its sire 2n and dam
|
||||
// 2n+1. We build recursively (sire above dam) and collapse below PED_OPEN_DEPTH.
|
||||
// 2n+1. We render it top-down like a family tree — the dog on top, parents
|
||||
// branching below — as a nested <ul>/<li> so CSS can draw the connectors.
|
||||
// Built recursively (sire left, dam right) and collapsed below PED_OPEN_DEPTH.
|
||||
function renderTree(nodes) {
|
||||
pedNodes = nodes;
|
||||
pedTree.textContent = "";
|
||||
const root = buildPedNode(nodes, 1, 0);
|
||||
if (root) pedTree.append(root);
|
||||
if (!root) return;
|
||||
const ul = document.createElement("ul");
|
||||
ul.className = "ped-tree-h";
|
||||
ul.append(root);
|
||||
pedTree.append(ul);
|
||||
}
|
||||
|
||||
function buildPedNode(nodes, pos, depth) {
|
||||
@@ -2660,8 +2666,7 @@
|
||||
const hasDam = !!nodes[String(pos * 2 + 1)];
|
||||
if (!n && !hasSire && !hasDam) return null;
|
||||
|
||||
const wrap = document.createElement("div");
|
||||
wrap.className = "ped-node";
|
||||
const li = document.createElement("li");
|
||||
|
||||
const card = document.createElement("div");
|
||||
card.className = "ped-card";
|
||||
@@ -2682,32 +2687,30 @@
|
||||
r.textContent = n.reg;
|
||||
card.append(r);
|
||||
}
|
||||
li.append(card);
|
||||
|
||||
if (hasSire || hasDam) {
|
||||
const kids = document.createElement("div");
|
||||
kids.className = "ped-children";
|
||||
const kids = document.createElement("ul");
|
||||
const s = buildPedNode(nodes, pos * 2, depth + 1);
|
||||
const d = buildPedNode(nodes, pos * 2 + 1, depth + 1);
|
||||
if (s) { s.classList.add("ped-sire"); kids.append(s); }
|
||||
if (d) { d.classList.add("ped-dam"); kids.append(d); }
|
||||
|
||||
const collapsed = depth >= PED_OPEN_DEPTH;
|
||||
if (collapsed) wrap.classList.add("collapsed");
|
||||
if (collapsed) li.classList.add("collapsed");
|
||||
const toggle = document.createElement("button");
|
||||
toggle.type = "button";
|
||||
toggle.className = "ped-toggle";
|
||||
toggle.setAttribute("aria-label", "Toggle ancestors");
|
||||
toggle.textContent = collapsed ? "+" : "−";
|
||||
toggle.addEventListener("click", () => {
|
||||
const nowCollapsed = wrap.classList.toggle("collapsed");
|
||||
const nowCollapsed = li.classList.toggle("collapsed");
|
||||
toggle.textContent = nowCollapsed ? "+" : "−";
|
||||
});
|
||||
card.prepend(toggle);
|
||||
wrap.append(card, kids);
|
||||
} else {
|
||||
wrap.append(card);
|
||||
li.append(kids);
|
||||
}
|
||||
return wrap;
|
||||
return li;
|
||||
}
|
||||
|
||||
// ---------- changelog dialog ----------
|
||||
|
||||
Reference in New Issue
Block a user