hm
This commit is contained in:
parent
7455d630fc
commit
4d3fc2cd47
84 changed files with 3429 additions and 3480 deletions
|
|
@ -45,5 +45,83 @@
|
|||
return comps;
|
||||
}
|
||||
|
||||
global.TarinaiFamilyGraph = { connectedComponents };
|
||||
|
||||
|
||||
function addParentEdge(childId, parentId, known, parentsByChild, childrenByParent) {
|
||||
if (!childId || !parentId || childId === parentId || !known?.has?.(childId) || !known.has(parentId)) return false;
|
||||
if (!parentsByChild.has(childId)) parentsByChild.set(childId, new Set());
|
||||
if (!childrenByParent.has(parentId)) childrenByParent.set(parentId, new Set());
|
||||
parentsByChild.get(childId).add(parentId);
|
||||
childrenByParent.get(parentId).add(childId);
|
||||
return true;
|
||||
}
|
||||
|
||||
function buildRelationIndex(family = {}) {
|
||||
const known = new Set(Object.keys(family || {}));
|
||||
const parentsByChild = new Map();
|
||||
const childrenByParent = new Map();
|
||||
const addParent = (childId, parentId) => addParentEdge(childId, parentId, known, parentsByChild, childrenByParent);
|
||||
for (const n of Object.values(family || {})) {
|
||||
if (!n?.id) continue;
|
||||
for (const parentId of n.parents || []) addParent(n.id, parentId);
|
||||
for (const childId of n.children || []) addParent(childId, n.id);
|
||||
}
|
||||
return { parentsByChild, childrenByParent };
|
||||
}
|
||||
|
||||
function relationAllowsParentChild(family = {}, childId, parentId) {
|
||||
const child = family?.[childId];
|
||||
const parent = family?.[parentId];
|
||||
if (!child || !parent) return false;
|
||||
const childListsParent = Array.isArray(child.parents) && child.parents.includes(parentId);
|
||||
const parentListsChild = Array.isArray(parent.children) && parent.children.includes(childId);
|
||||
return childListsParent || parentListsChild;
|
||||
}
|
||||
|
||||
function relatedNodesFromIndex(family = {}, relationIndex = buildRelationIndex(family)) {
|
||||
const relatedIds = new Set();
|
||||
for (const n of Object.values(family || {})) {
|
||||
if (!n?.id) continue;
|
||||
const parents = relationIndex.parentsByChild.get(n.id) || new Set();
|
||||
const children = relationIndex.childrenByParent.get(n.id) || new Set();
|
||||
if (parents.size || children.size) relatedIds.add(n.id);
|
||||
for (const id of parents) relatedIds.add(id);
|
||||
for (const id of children) relatedIds.add(id);
|
||||
}
|
||||
return Array.from(relatedIds).map(id => family[id]).filter(Boolean);
|
||||
}
|
||||
|
||||
function buildLineageGraph(family = {}, nodes = relatedNodesFromIndex(family), relationIndex = buildRelationIndex(family)) {
|
||||
const graph = new Map();
|
||||
for (const n of nodes || []) if (n?.id) graph.set(n.id, new Set());
|
||||
const addGraphEdge = (a, b) => {
|
||||
if (!a || !b || !graph.has(a) || !graph.has(b)) return;
|
||||
graph.get(a).add(b);
|
||||
graph.get(b).add(a);
|
||||
};
|
||||
for (const n of nodes || []) {
|
||||
if (!n?.id) continue;
|
||||
const parentCandidates = new Set((n.parents || []).filter(Boolean));
|
||||
for (const parentId of relationIndex.parentsByChild.get(n.id) || []) parentCandidates.add(parentId);
|
||||
for (const parentId of parentCandidates) {
|
||||
if (parentId !== n.id && relationAllowsParentChild(family, n.id, parentId)) addGraphEdge(n.id, parentId);
|
||||
}
|
||||
const childCandidates = new Set((n.children || []).filter(Boolean));
|
||||
for (const childId of relationIndex.childrenByParent.get(n.id) || []) childCandidates.add(childId);
|
||||
for (const childId of childCandidates) {
|
||||
if (childId !== n.id && relationAllowsParentChild(family, childId, n.id)) addGraphEdge(n.id, childId);
|
||||
}
|
||||
}
|
||||
return graph;
|
||||
}
|
||||
|
||||
|
||||
global.TarinaiFamilyGraph = {
|
||||
connectedComponents,
|
||||
addParentEdge,
|
||||
buildRelationIndex,
|
||||
buildLineageGraph,
|
||||
relatedNodesFromIndex,
|
||||
relationAllowsParentChild,
|
||||
};
|
||||
})(typeof window !== "undefined" ? window : globalThis);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue