people tags #387
This commit is contained in:
parent
872a8aab61
commit
a0a7558d8b
@ -43,14 +43,31 @@
|
|||||||
(spouseOf[b] = spouseOf[b] || []).push(a);
|
(spouseOf[b] = spouseOf[b] || []).push(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var siblingPairs = [];
|
||||||
(data.relations || []).forEach(function (r) {
|
(data.relations || []).forEach(function (r) {
|
||||||
if (r.relationType === 0 || r.relationType === 3) {
|
if (r.relationType === 0 || r.relationType === 3) {
|
||||||
addParentChild(r.person1Id, r.person2Id);
|
addParentChild(r.person1Id, r.person2Id);
|
||||||
} else if (r.relationType === 2) {
|
} else if (r.relationType === 2) {
|
||||||
addSpouse(r.person1Id, r.person2Id);
|
addSpouse(r.person1Id, r.person2Id);
|
||||||
|
} else if (r.relationType === 1) {
|
||||||
|
siblingPairs.push([r.person1Id, r.person2Id]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// A sibling pair where only one side has a recorded parent (e.g. a sibling relation was
|
||||||
|
// entered but no separate parent relation for the other sibling) used to leave the parentless
|
||||||
|
// sibling with no parent at all, turning them into their own disconnected chart root instead
|
||||||
|
// of being drawn next to their actual family. Have the parentless sibling inherit the same
|
||||||
|
// parent(s), purely so the drawing places them together - this doesn't change any real data.
|
||||||
|
siblingPairs.forEach(function (pair) {
|
||||||
|
var a = pair[0], b = pair[1];
|
||||||
|
var aHasParent = parentsOf[a] && parentsOf[a].length > 0;
|
||||||
|
var bHasParent = parentsOf[b] && parentsOf[b].length > 0;
|
||||||
|
if (aHasParent && !bHasParent) {
|
||||||
|
parentsOf[a].forEach(function (p) { addParentChild(p, b); });
|
||||||
|
} else if (bHasParent && !aHasParent) {
|
||||||
|
parentsOf[b].forEach(function (p) { addParentChild(p, a); });
|
||||||
}
|
}
|
||||||
// relationType === 1 (Sibling) isn't needed for layout: siblings normally end up
|
|
||||||
// adjacent anyway once they share a primaryParentOf below.
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.keys(childrenOf).forEach(function (k) { childrenOf[k] = dedup(childrenOf[k]); });
|
Object.keys(childrenOf).forEach(function (k) { childrenOf[k] = dedup(childrenOf[k]); });
|
||||||
@ -226,6 +243,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
var maxX = 0, maxY = 0;
|
var maxX = 0, maxY = 0;
|
||||||
|
var drawnPos = {}; // id -> {x,y} for every box actually drawn (primary nodes and attached spouses)
|
||||||
|
|
||||||
function drawBox(id, x, y, w, h, isRequested) {
|
function drawBox(id, x, y, w, h, isRequested) {
|
||||||
var p = layoutInfo.persons[id];
|
var p = layoutInfo.persons[id];
|
||||||
@ -244,6 +262,7 @@
|
|||||||
nodesGroup.appendChild(g);
|
nodesGroup.appendChild(g);
|
||||||
maxX = Math.max(maxX, x + w / 2);
|
maxX = Math.max(maxX, x + w / 2);
|
||||||
maxY = Math.max(maxY, y + h / 2);
|
maxY = Math.max(maxY, y + h / 2);
|
||||||
|
drawnPos[id] = { x: x, y: y };
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(layoutInfo.nodeX).forEach(function (idStr) {
|
Object.keys(layoutInfo.nodeX).forEach(function (idStr) {
|
||||||
@ -296,21 +315,34 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
svg.removeAttribute('viewBox'); // pan/zoom via transform, not viewBox, once we have a canvas group
|
svg.removeAttribute('viewBox'); // pan/zoom via transform, not viewBox, once we have a canvas group
|
||||||
var svgWidth = Math.max(container.clientWidth, maxX + MARGIN);
|
// The SVG element is always sized to the CONTAINER - never to the full tree - so it acts as a
|
||||||
var svgHeight = Math.max(container.clientHeight, maxY + MARGIN);
|
// fixed "viewport" onto the (possibly much larger) tree, which is panned/zoomed via the canvas
|
||||||
|
// group's transform below. Previously this grew the SVG itself to (maxX+MARGIN)/(maxY+MARGIN)
|
||||||
|
// whenever the tree was bigger than the container; combined with the page's RTL layout and the
|
||||||
|
// container's overflow:hidden, that pinned the oversized SVG's right edge to the container's
|
||||||
|
// right edge, which could hide the requested root's own subtree entirely if it was laid out
|
||||||
|
// toward the left - with nothing below ever panning the view back to it.
|
||||||
|
var svgWidth = container.clientWidth || (maxX + MARGIN);
|
||||||
|
var svgHeight = container.clientHeight || (maxY + MARGIN);
|
||||||
svg.setAttribute('width', svgWidth);
|
svg.setAttribute('width', svgWidth);
|
||||||
svg.setAttribute('height', svgHeight);
|
svg.setAttribute('height', svgHeight);
|
||||||
|
|
||||||
// pan + zoom - a small, dependency-free version of the usual SVG drag/wheel recipe
|
// pan + zoom - a small, dependency-free version of the usual SVG drag/wheel recipe
|
||||||
var scale = 1;
|
var scale = 1;
|
||||||
// The tree itself is only (maxX + MARGIN) x (maxY + MARGIN) "big", but the SVG element is
|
// Center the initial view on the requested root's own drawn position (falling back to an
|
||||||
// stretched to fill the whole container (so there's room to pan around a small tree) - drawn
|
// attached/spouse box's position if that's how it was drawn) so the person actually asked for
|
||||||
// at a bare translate(0,0), that left it pinned to the top-left corner instead of centered
|
// is what's visible first, rather than whatever subtree happened to land at low x. When the
|
||||||
// whenever the tree is smaller than the container (e.g. a two-person tree in a wide panel).
|
// whole tree already fits inside the viewport, center the whole tree instead (matches the old,
|
||||||
// Starting the pan offset centered - rather than at (0,0) - fixes that without changing how
|
// still-correct behavior for small trees).
|
||||||
// panning/zooming themselves work.
|
var tx, ty;
|
||||||
var tx = Math.max(0, (svgWidth - (maxX + MARGIN)) / 2);
|
if ((maxX + MARGIN) <= svgWidth && (maxY + MARGIN) <= svgHeight) {
|
||||||
var ty = Math.max(0, (svgHeight - (maxY + MARGIN)) / 2);
|
tx = Math.max(0, (svgWidth - (maxX + MARGIN)) / 2);
|
||||||
|
ty = Math.max(0, (svgHeight - (maxY + MARGIN)) / 2);
|
||||||
|
} else {
|
||||||
|
var focus = drawnPos[requestedRootId] || { x: (maxX + MARGIN) / 2, y: (maxY + MARGIN) / 2 };
|
||||||
|
tx = svgWidth / 2 - focus.x;
|
||||||
|
ty = svgHeight / 2 - focus.y;
|
||||||
|
}
|
||||||
var dragging = false, lastX = 0, lastY = 0;
|
var dragging = false, lastX = 0, lastY = 0;
|
||||||
|
|
||||||
function applyTransform() {
|
function applyTransform() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user