people tags #387
This commit is contained in:
parent
fecbf0ec3b
commit
88f39c2bab
@ -31,6 +31,10 @@ else
|
|||||||
.ft-heart { font-size: 13px; fill: #a0455c; }
|
.ft-heart { font-size: 13px; fill: #a0455c; }
|
||||||
.ft-line { fill: none; stroke: #a99a7c; stroke-width: 1.5; }
|
.ft-line { fill: none; stroke: #a99a7c; stroke-width: 1.5; }
|
||||||
.ft-line-spouse { stroke-dasharray: 3,3; }
|
.ft-line-spouse { stroke-dasharray: 3,3; }
|
||||||
|
/* sibling relation with no recorded shared parent - deliberately plainer than the
|
||||||
|
spouse dashing (finer dots, lighter/grayer) and gets no heart icon, so it doesn't
|
||||||
|
read as a marriage or as a confirmed shared-parent claim */
|
||||||
|
.ft-line-sibling { stroke-dasharray: 1,3; stroke: #a0a0a0; }
|
||||||
.ft-tooltip-panel {
|
.ft-tooltip-panel {
|
||||||
position: absolute; top: 10px; left: 10px; max-width: 300px;
|
position: absolute; top: 10px; left: 10px; max-width: 300px;
|
||||||
background: #fffdf7; border: 1px solid #8b6b4a; border-radius: 8px;
|
background: #fffdf7; border: 1px solid #8b6b4a; border-radius: 8px;
|
||||||
|
|||||||
@ -54,21 +54,17 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// A sibling pair where only one side has a recorded parent (e.g. a sibling relation was
|
// NOTE: a recorded Sibling relation deliberately does not say which parent(s), if any, are
|
||||||
// entered but no separate parent relation for the other sibling) used to leave the parentless
|
// shared (see PersonRelationType.Sibling's own doc comment: "doesn't require either parent
|
||||||
// sibling with no parent at all, turning them into their own disconnected chart root instead
|
// to be known/recorded") - a text might call two people brothers without saying whether
|
||||||
// of being drawn next to their actual family. Have the parentless sibling inherit the same
|
// they share a father, a mother, or both. So siblingPairs is intentionally NOT turned into
|
||||||
// parent(s), purely so the drawing places them together - this doesn't change any real data.
|
// addParentChild() calls here (an earlier version of this code did exactly that, inheriting
|
||||||
siblingPairs.forEach(function (pair) {
|
// ALL of the known sibling's recorded parents onto the parentless one - fabricating a
|
||||||
var a = pair[0], b = pair[1];
|
// specific shared-parentage claim the source material never made, and quietly corrupting
|
||||||
var aHasParent = parentsOf[a] && parentsOf[a].length > 0;
|
// isRoot/parentsOf for that person everywhere else in this function too, e.g. the gender
|
||||||
var bHasParent = parentsOf[b] && parentsOf[b].length > 0;
|
// tie-break above). Instead, a parentless sibling is drawn as a plain "sibling, parentage
|
||||||
if (aHasParent && !bHasParent) {
|
// unspecified" attachment beside whichever sibling does have a known position - see
|
||||||
parentsOf[a].forEach(function (p) { addParentChild(p, b); });
|
// tryAttachSibling below.
|
||||||
} else if (bHasParent && !aHasParent) {
|
|
||||||
parentsOf[b].forEach(function (p) { addParentChild(p, a); });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.keys(childrenOf).forEach(function (k) { childrenOf[k] = dedup(childrenOf[k]); });
|
Object.keys(childrenOf).forEach(function (k) { childrenOf[k] = dedup(childrenOf[k]); });
|
||||||
Object.keys(parentsOf).forEach(function (k) { parentsOf[k] = dedup(parentsOf[k]); });
|
Object.keys(parentsOf).forEach(function (k) { parentsOf[k] = dedup(parentsOf[k]); });
|
||||||
@ -122,6 +118,10 @@
|
|||||||
// akhakhafrasiyab.ir's chart
|
// akhakhafrasiyab.ir's chart
|
||||||
var attachedTo = {}; // spouseId -> primaryId
|
var attachedTo = {}; // spouseId -> primaryId
|
||||||
var attachedList = {}; // primaryId -> [spouseId,...]
|
var attachedList = {}; // primaryId -> [spouseId,...]
|
||||||
|
var attachedAsSibling = {}; // spouseId -> true, for ids attached via tryAttachSibling below -
|
||||||
|
// drawBox/the attached-box renderer uses this to draw a plain line
|
||||||
|
// with no heart icon, instead of implying a marriage that was
|
||||||
|
// never recorded
|
||||||
|
|
||||||
function tryAttach(primaryId, spouseId) {
|
function tryAttach(primaryId, spouseId) {
|
||||||
if (attachedTo[spouseId] !== undefined || spouseId === primaryId) return false;
|
if (attachedTo[spouseId] !== undefined || spouseId === primaryId) return false;
|
||||||
@ -144,6 +144,25 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Siblings with no (or no other) known position are drawn beside whichever sibling does have
|
||||||
|
// one - purely a placement choice, not a parentage claim (see the long comment above
|
||||||
|
// siblingPairs). Deliberately reuses tryAttach's own "isRoot && no children of their own"
|
||||||
|
// guard, so this never steals a sibling who already has a real, independently-documented
|
||||||
|
// position (their own recorded parents, or children) in the tree.
|
||||||
|
function tryAttachSibling(primaryId, siblingId) {
|
||||||
|
if (tryAttach(primaryId, siblingId)) {
|
||||||
|
attachedAsSibling[siblingId] = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
siblingPairs.forEach(function (pair) {
|
||||||
|
var a = pair[0], b = pair[1];
|
||||||
|
if (attachedTo[a] !== undefined || attachedTo[b] !== undefined) return;
|
||||||
|
if (tryAttachSibling(a, b)) return;
|
||||||
|
tryAttachSibling(b, a);
|
||||||
|
});
|
||||||
|
|
||||||
var topLevelRoots = allIds.filter(function (id) { return isRoot[id] && attachedTo[id] === undefined; });
|
var topLevelRoots = allIds.filter(function (id) { return isRoot[id] && attachedTo[id] === undefined; });
|
||||||
|
|
||||||
function subtreeContains(rootId, targetId, guard) {
|
function subtreeContains(rootId, targetId, guard) {
|
||||||
@ -188,6 +207,7 @@
|
|||||||
primaryParentOf: primaryParentOf,
|
primaryParentOf: primaryParentOf,
|
||||||
secondaryParentOf: secondaryParentOf,
|
secondaryParentOf: secondaryParentOf,
|
||||||
attachedList: attachedList,
|
attachedList: attachedList,
|
||||||
|
attachedAsSibling: attachedAsSibling,
|
||||||
topLevelRoots: topLevelRoots,
|
topLevelRoots: topLevelRoots,
|
||||||
nodeX: nodeX,
|
nodeX: nodeX,
|
||||||
nodeDepth: nodeDepth
|
nodeDepth: nodeDepth
|
||||||
@ -307,15 +327,21 @@
|
|||||||
var attached = layoutInfo.attachedList[id] || [];
|
var attached = layoutInfo.attachedList[id] || [];
|
||||||
var edgeX = p.x + size.w / 2;
|
var edgeX = p.x + size.w / 2;
|
||||||
attached.forEach(function (spouseId, i) {
|
attached.forEach(function (spouseId, i) {
|
||||||
|
var isSibling = !!layoutInfo.attachedAsSibling[spouseId];
|
||||||
var attSize = boxSizeFor(layoutInfo.persons[spouseId], ATTACH_W, BOX_H);
|
var attSize = boxSizeFor(layoutInfo.persons[spouseId], ATTACH_W, BOX_H);
|
||||||
var ax = edgeX + ATTACH_GAP + attSize.w / 2;
|
var ax = edgeX + ATTACH_GAP + attSize.w / 2;
|
||||||
var ay = p.y;
|
var ay = p.y;
|
||||||
drawBox(spouseId, ax, ay, attSize.w, attSize.h, spouseId === requestedRootId);
|
drawBox(spouseId, ax, ay, attSize.w, attSize.h, spouseId === requestedRootId);
|
||||||
line(edgeX, p.y, ax - attSize.w / 2, ay, 'ft-line ft-line-spouse');
|
// a sibling drawn this way is placed next to the OTHER sibling purely for layout -
|
||||||
|
// it is not a marriage, so it gets a plain neutral connector and no heart icon (see
|
||||||
|
// the long comment above siblingPairs/tryAttachSibling in buildLayout)
|
||||||
|
line(edgeX, p.y, ax - attSize.w / 2, ay, isSibling ? 'ft-line ft-line-sibling' : 'ft-line ft-line-spouse');
|
||||||
|
if (!isSibling) {
|
||||||
var heartX = edgeX + ATTACH_GAP / 2;
|
var heartX = edgeX + ATTACH_GAP / 2;
|
||||||
var heart = el('text', { x: heartX, y: ay + 4, 'text-anchor': 'middle', 'class': 'ft-heart' });
|
var heart = el('text', { x: heartX, y: ay + 4, 'text-anchor': 'middle', 'class': 'ft-heart' });
|
||||||
heart.textContent = '♥';
|
heart.textContent = '♥';
|
||||||
nodesGroup.appendChild(heart);
|
nodesGroup.appendChild(heart);
|
||||||
|
}
|
||||||
maxX = Math.max(maxX, ax + attSize.w / 2);
|
maxX = Math.max(maxX, ax + attSize.w / 2);
|
||||||
edgeX = ax + attSize.w / 2 + ATTACH_GAP;
|
edgeX = ax + attSize.w / 2 + ATTACH_GAP;
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user