Scope font-size rules to fng-container to avoid overriding full-diagram styles
This commit is contained in:
@@ -64,15 +64,15 @@
|
|||||||
fill: rgba(255, 255, 255, 0.6);
|
fill: rgba(255, 255, 255, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Card text */
|
/* Card text — scoped to fng-container to avoid overriding full-diagram */
|
||||||
.person-card .person-name {
|
.fng-container .person-card .person-name {
|
||||||
font-size: 9px;
|
font-size: 8px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
fill: #212529;
|
fill: #212529;
|
||||||
dominant-baseline: auto;
|
dominant-baseline: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.person-card .person-dates {
|
.fng-container .person-card .person-dates {
|
||||||
font-size: 8px;
|
font-size: 8px;
|
||||||
fill: #6c757d;
|
fill: #6c757d;
|
||||||
dominant-baseline: auto;
|
dominant-baseline: auto;
|
||||||
|
|||||||
2
resources/js/family-nav-graph.min.js
vendored
2
resources/js/family-nav-graph.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -153,13 +153,13 @@ export function renderPersonCard(parent, person, config, onClick) {
|
|||||||
const firstName = data["first name"] || "";
|
const firstName = data["first name"] || "";
|
||||||
const lastName = data["last name"] || "";
|
const lastName = data["last name"] || "";
|
||||||
const displayName = formatDisplayName(firstName, lastName, data.fullName);
|
const displayName = formatDisplayName(firstName, lastName, data.fullName);
|
||||||
const maxTextWidth = w - textXOffset - 5;
|
const maxTextWidth = w - textXOffset;
|
||||||
|
|
||||||
g.append("text")
|
g.append("text")
|
||||||
.attr("class", "person-name")
|
.attr("class", "person-name")
|
||||||
.attr("x", textXOffset)
|
.attr("x", textXOffset)
|
||||||
.attr("y", h / 2 - 4)
|
.attr("y", h / 2 - 4)
|
||||||
.text(truncateText(displayName, maxTextWidth, 5.5));
|
.text(truncateText(displayName, maxTextWidth, 4.5));
|
||||||
|
|
||||||
// Dates line (compact)
|
// Dates line (compact)
|
||||||
const dates = formatDates(data.birthYear, data.deathYear, data.isDead);
|
const dates = formatDates(data.birthYear, data.deathYear, data.isDead);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export function computeLayout(persons, mainId, config) {
|
|||||||
if (pid !== mainId) activeSpouseIds.add(pid);
|
if (pid !== mainId) activeSpouseIds.add(pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (activeRootFamilies.length >= 2) {
|
if (activeRootFamilies.length >= 1 && rootSpouses.size >= 2) {
|
||||||
for (const sid of activeSpouseIds) {
|
for (const sid of activeSpouseIds) {
|
||||||
if (gen.has(sid)) gen.set(sid, 0.5);
|
if (gen.has(sid)) gen.set(sid, 0.5);
|
||||||
}
|
}
|
||||||
@@ -80,6 +80,17 @@ export function computeLayout(persons, mainId, config) {
|
|||||||
const ids = genGroups.get(g);
|
const ids = genGroups.get(g);
|
||||||
const ordered = orderGeneration(ids, g, mainId, families, personById, activeRootFamilies);
|
const ordered = orderGeneration(ids, g, mainId, families, personById, activeRootFamilies);
|
||||||
|
|
||||||
|
// Single active spouse staggered: position at right column (same x as S1)
|
||||||
|
if (g === 0.5 && activeRootFamilies.length === 1) {
|
||||||
|
const rowWidth = 2 * cw + hGap;
|
||||||
|
const rightX = -rowWidth / 2 + cw / 2 + cw + hGap;
|
||||||
|
for (const id of ordered) {
|
||||||
|
positions.set(id, { x: rightX, y: currentY });
|
||||||
|
}
|
||||||
|
currentY += ch + vGap * 0.6;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Multi-spouse children: position each family's children as
|
// Multi-spouse children: position each family's children as
|
||||||
// two side-by-side columns (1 card wide each) to stay within 2-card width
|
// two side-by-side columns (1 card wide each) to stay within 2-card width
|
||||||
if (g >= 1 && activeRootFamilies.length >= 2) {
|
if (g >= 1 && activeRootFamilies.length >= 2) {
|
||||||
@@ -433,7 +444,10 @@ function buildConnectors(families, positions, config, mainId, activeRootFamilies
|
|||||||
const halfH = config.cardHeight / 2;
|
const halfH = config.cardHeight / 2;
|
||||||
const cw = config.cardWidth;
|
const cw = config.cardWidth;
|
||||||
const vGap = config.verticalSpacing;
|
const vGap = config.verticalSpacing;
|
||||||
|
const rootPerson = personById.get(mainId);
|
||||||
|
const rootSpouseIds = rootPerson?.rels?.spouses || [];
|
||||||
const multiSpouse = activeRootFamilies.length >= 2;
|
const multiSpouse = activeRootFamilies.length >= 2;
|
||||||
|
const staggeredLayout = activeRootFamilies.length >= 1 && rootSpouseIds.length >= 2;
|
||||||
const rootPos = positions.get(mainId);
|
const rootPos = positions.get(mainId);
|
||||||
const margin = 12;
|
const margin = 12;
|
||||||
|
|
||||||
@@ -441,8 +455,8 @@ function buildConnectors(families, positions, config, mainId, activeRootFamilies
|
|||||||
const rootFamIdx = activeRootFamilies.indexOf(family);
|
const rootFamIdx = activeRootFamilies.indexOf(family);
|
||||||
const isActiveRootFamily = rootFamIdx >= 0;
|
const isActiveRootFamily = rootFamIdx >= 0;
|
||||||
|
|
||||||
// Multi-spouse active families get custom routing below
|
// Staggered/multi-spouse active families get custom routing below
|
||||||
if (isActiveRootFamily && multiSpouse) continue;
|
if (isActiveRootFamily && staggeredLayout) continue;
|
||||||
|
|
||||||
const parentPos = family.parents
|
const parentPos = family.parents
|
||||||
.map((pid) => positions.get(pid))
|
.map((pid) => positions.get(pid))
|
||||||
@@ -559,15 +573,50 @@ function buildConnectors(families, positions, config, mainId, activeRootFamilies
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Single active spouse staggered: root → S2 → children ──
|
||||||
|
if (!multiSpouse && staggeredLayout && rootPos) {
|
||||||
|
const family = activeRootFamilies[0];
|
||||||
|
const spouseId = family.parents.find((p) => p !== mainId);
|
||||||
|
const spousePos = spouseId ? positions.get(spouseId) : null;
|
||||||
|
const childPos = family.children
|
||||||
|
.map((cid) => ({ id: cid, ...positions.get(cid) }))
|
||||||
|
.filter((c) => c.x !== undefined);
|
||||||
|
|
||||||
|
if (spousePos && childPos.length > 0) {
|
||||||
|
const spouseBottomY = spousePos.y + halfH;
|
||||||
|
const childTopY = Math.min(...childPos.map((c) => c.y)) - halfH;
|
||||||
|
const gap = childTopY - spouseBottomY;
|
||||||
|
const coupleBarY = spouseBottomY + gap * 0.3;
|
||||||
|
|
||||||
|
// Root vertical down to couple bar
|
||||||
|
connections.push({
|
||||||
|
path: `M ${rootPos.x} ${rootPos.y + halfH} L ${rootPos.x} ${coupleBarY}`,
|
||||||
|
cssClass: "link couple-link",
|
||||||
|
});
|
||||||
|
// Horizontal couple bar from root to spouse
|
||||||
|
connections.push({
|
||||||
|
path: `M ${rootPos.x} ${coupleBarY} L ${spousePos.x} ${coupleBarY}`,
|
||||||
|
cssClass: "link couple-link",
|
||||||
|
});
|
||||||
|
// Spouse vertical down to couple bar
|
||||||
|
connections.push({
|
||||||
|
path: `M ${spousePos.x} ${spouseBottomY} L ${spousePos.x} ${coupleBarY}`,
|
||||||
|
cssClass: "link couple-link",
|
||||||
|
});
|
||||||
|
// Children from couple bar, spine centered between root and spouse
|
||||||
|
const spineX = (rootPos.x + spousePos.x) / 2;
|
||||||
|
drawChildConnectors(connections, childPos, spineX, coupleBarY, halfH, vGap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── Couple links for childless spouses (same row as root) ──
|
// ── Couple links for childless spouses (same row as root) ──
|
||||||
const rootPerson = personById.get(mainId);
|
|
||||||
const childlessActiveIds = new Set();
|
const childlessActiveIds = new Set();
|
||||||
for (const f of activeRootFamilies) {
|
for (const f of activeRootFamilies) {
|
||||||
for (const pid of f.parents) {
|
for (const pid of f.parents) {
|
||||||
if (pid !== mainId) childlessActiveIds.add(pid);
|
if (pid !== mainId) childlessActiveIds.add(pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rootPerson && rootPos && multiSpouse) {
|
if (rootPerson && rootPos && staggeredLayout) {
|
||||||
for (const sid of rootPerson.rels.spouses || []) {
|
for (const sid of rootPerson.rels.spouses || []) {
|
||||||
if (childlessActiveIds.has(sid)) continue;
|
if (childlessActiveIds.has(sid)) continue;
|
||||||
const spPos = positions.get(sid);
|
const spPos = positions.get(sid);
|
||||||
|
|||||||
Reference in New Issue
Block a user