5237 Better algorithm to pich replacement node when faking position for subgraphs

This commit is contained in:
Knut Sveidqvist
2024-06-11 13:27:51 +02:00
parent aaa4e8a794
commit 5f110e4cde
3 changed files with 85 additions and 14 deletions

View File

@@ -77,19 +77,58 @@
<body> <body>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid">
flowchart LR flowchart LR
subgraph Apa["Apa"] subgraph Apa["Apa"]
A["Start"] A["Start"]
B["This is B"] B["This is B"]
end
A --> B & C["C"]
Apa --> C
</pre
>
<pre id="diagram" class="mermaid">
flowchart LR
subgraph Apa["Apa"]
B["This is B"]
A["Start"]
end
A --> B & C["C"]
Apa --> C
</pre
>
<pre id="diagram" class="mermaid">
flowchart LR
subgraph Apa["Apa"]
subgraph Gorilla
A["Start"]
B["This is B"]
end end
end
A --> B & C["C"]
Gorilla --> C
</pre
>
<pre id="diagram" class="mermaid">
flowchart LR
subgraph Apa["Apa"]
subgraph Gorilla
A["Start"]
B["This is B"]
end
end
A --> B & C["C"] A --> B & C["C"]
Apa --> C Apa --> C
</pre </pre
> >
<pre id="diagram" class="mermaid2"> <pre id="diagram" class="mermaid2">
flowchart LR flowchart LR
subgraph Apa["Apa"] subgraph Apa["Apa"]
B --> B & C subgraph Gorilla
B["This is B"]
A["Start"]
end end
end
Apa --> C
A --> B & C["C"]
</pre </pre
> >
<pre id="diagram" class="mermaid2"> <pre id="diagram" class="mermaid2">

View File

@@ -8,6 +8,7 @@ export const findCommonAncestor = (id1: string, id2: string, treeData: TreeData)
const visited = new Set(); const visited = new Set();
let currentId = id1; let currentId = id1;
// Edge case with self edges
if (id1 === id2) { if (id1 === id2) {
return parentById[id1] || 'root'; return parentById[id1] || 'root';
} }

View File

@@ -152,27 +152,58 @@ export const validate = (graph) => {
return true; return true;
}; };
const findCommonEdges = (graph, id1, id2) => {
const edges1 = graph.edges().filter((edge) => edge.v === id1 || edge.w === id1);
const edges2 = graph.edges().filter((edge) => edge.v === id2 || edge.w === id2);
const edges1Prim = edges1.map((edge) => {
return { v: edge.v === id1 ? id2 : edge.v, w: edge.w === id1 ? id1 : edge.w };
});
const edges2Prim = edges2.map((edge) => {
return { v: edge.v, w: edge.w };
});
const result = edges1Prim.filter((edgeIn1) => {
return edges2Prim.filter((edge) => edgeIn1.v === edge.v && edgeIn1.w === edge.w).length > 0;
});
return result;
};
/** /**
* Finds a child that is not a cluster. When faking an edge between a node and a cluster. * Finds a child that is not a cluster. When faking an edge between a node and a cluster.
* *
* @param id * @param id
* @param {any} graph * @param {any} graph
*/ */
export const findNonClusterChild = (id, graph) => { export const findNonClusterChild = (id, graph, clusterId) => {
log.trace('Searching', id); const children = graph.children(id);
const children = graph.children(id).reverse();
log.trace('Searching children of id ', id, children); log.trace('Searching children of id ', id, children);
if (children.length < 1) { if (children.length < 1) {
log.trace('This is a valid node', id);
return id; return id;
} }
let reserve;
for (const child of children) { for (const child of children) {
const _id = findNonClusterChild(child, graph); const _id = findNonClusterChild(child, graph, clusterId);
// Edge chase where the cluster has an edge to a node and the selected
// child has a link to the same node
const commonEdges = findCommonEdges(graph, clusterId, _id);
if (_id) { if (_id) {
log.trace('Found replacement for', id, ' => ', _id); if (commonEdges.length > 0) {
return _id; // console.log(
// '\x1B[44;93;4m abc24 The replacement also has an edge',
// clusterId,
// ' => ',
// _id,
// graph.edges()
// );
reserve = _id;
} else {
return _id;
}
} }
} }
return reserve;
}; };
const getAnchorId = (id) => { const getAnchorId = (id) => {
@@ -207,10 +238,10 @@ export const adjustClustersAndEdges = (graph, depth) => {
'Cluster identified', 'Cluster identified',
id, id,
' Replacement id in edges: ', ' Replacement id in edges: ',
findNonClusterChild(id, graph) findNonClusterChild(id, graph, id)
); );
descendants[id] = extractDescendants(id, graph); descendants[id] = extractDescendants(id, graph);
clusterDb[id] = { id: findNonClusterChild(id, graph), clusterData: graph.node(id) }; clusterDb[id] = { id: findNonClusterChild(id, graph, id), clusterData: graph.node(id) };
} }
}); });