fix(#5952): handled additional edge cases

This commit is contained in:
NicolasNewman
2024-11-15 10:27:20 -06:00
parent cb0a4703bd
commit 885ac6f947
2 changed files with 32 additions and 19 deletions

View File

@@ -219,13 +219,15 @@ const getEdges = (): ArchitectureEdge[] => state.records.edges;
*/ */
const getDataStructures = () => { const getDataStructures = () => {
if (state.records.dataStructures === undefined) { if (state.records.dataStructures === undefined) {
// Create an adjacency list of the diagram to perform BFS on // Tracks how groups are aligned with one another. Generated while creating the adj list
// Outer reduce applied on all services
// Inner reduce applied on the edges for a service
const groupAlignments: Record< const groupAlignments: Record<
string, string,
Record<string, Exclude<ArchitectureAlignment, 'bend'>> Record<string, Exclude<ArchitectureAlignment, 'bend'>>
> = {}; > = {};
// Create an adjacency list of the diagram to perform BFS on
// Outer reduce applied on all services
// Inner reduce applied on the edges for a service
const adjList = Object.entries(state.records.nodes).reduce< const adjList = Object.entries(state.records.nodes).reduce<
Record<string, ArchitectureDirectionPairMap> Record<string, ArchitectureDirectionPairMap>
>((prevOuter, [id, service]) => { >((prevOuter, [id, service]) => {

View File

@@ -159,11 +159,11 @@ function getAlignments(
/** /**
* Flattens the alignment object so nodes in different groups will be in the same alignment array IFF their groups don't connect in a conflicting alignment * Flattens the alignment object so nodes in different groups will be in the same alignment array IFF their groups don't connect in a conflicting alignment
* *
* i.e., two groups which connect horizontally should not have vertical alignments with one another * i.e., two groups which connect horizontally should not have nodes with vertical alignments to one another
* *
* See: #5952 * See: #5952
* *
* @param alignmentObj - alignment object with the outer key being the row/col and the inner key being the group name * @param alignmentObj - alignment object with the outer key being the row/col # and the inner key being the group name mapped to the nodes on that axis in the group
* @param alignmentDir - alignment direction * @param alignmentDir - alignment direction
* @returns flattened alignment object with an arbitrary key mapping to nodes in the same row/col * @returns flattened alignment object with an arbitrary key mapping to nodes in the same row/col
*/ */
@@ -173,24 +173,36 @@ function getAlignments(
): Record<string, string[]> => { ): Record<string, string[]> => {
return Object.entries(alignmentObj).reduce( return Object.entries(alignmentObj).reduce(
(prev, [dir, alignments]) => { (prev, [dir, alignments]) => {
// prev is the mapping of x/y coordinate to an array of the nodes in that row/column
let cnt = 0; let cnt = 0;
const arr = Object.entries(alignments); const arr = Object.entries(alignments); // [group name, array of nodes within the group on axis dir]
if (arr.length === 1) { if (arr.length === 1) {
// If only one group exists in the row/column, we don't need to do anything else
prev[dir] = arr[0][1]; prev[dir] = arr[0][1];
return prev; return prev;
} }
for (let i = 0; i < arr.length - 1; i += 1) { for (let i = 0; i < arr.length - 1; i++) {
const [aGroupId, aNodeIds] = arr[i]; for (let j = i + 1; j < arr.length; j++) {
const [bGroupId, bNodeIds] = arr[i + 1]; // Not optimal but arr will not grow large enough to be a concern
const alignment = groupAlignments[aGroupId][bGroupId]; const [aGroupId, aNodeIds] = arr[i];
if (alignment === alignmentDir) { const [bGroupId, bNodeIds] = arr[j];
prev[dir] ??= []; const alignment = groupAlignments[aGroupId]?.[bGroupId]; // Get how the two groups are intended to align (undefined if they aren't)
prev[dir] = [...prev[dir], ...aNodeIds, ...bNodeIds];
} else { if (alignment === alignmentDir) {
const keyA = `${dir}-${cnt++}`; // If the intended alignment between the two groups is the same as the alignment we are parsing
prev[keyA] = aNodeIds; prev[dir] ??= [];
const keyB = `${dir}-${cnt++}`; prev[dir] = [...prev[dir], ...aNodeIds, ...bNodeIds]; // add the node ids of both groups to the axis array in prev
prev[keyB] = bNodeIds; } else if (aGroupId === 'default' || bGroupId === 'default') {
// If either of the groups are in the default space (not in a group), use the same behavior as above
prev[dir] ??= [];
prev[dir] = [...prev[dir], ...aNodeIds, ...bNodeIds];
} else {
// Otherwise, the nodes in the two groups are not intended to align
const keyA = `${dir}-${cnt++}`;
prev[keyA] = aNodeIds;
const keyB = `${dir}-${cnt++}`;
prev[keyB] = bNodeIds;
}
} }
} }
@@ -376,7 +388,6 @@ function layoutArchitecture(
addServices(services, cy); addServices(services, cy);
addJunctions(junctions, cy); addJunctions(junctions, cy);
addEdges(edges, cy); addEdges(edges, cy);
// Use the spatial map to create alignment arrays for fcose // Use the spatial map to create alignment arrays for fcose
const alignmentConstraint = getAlignments(db, spatialMaps, groupAlignments); const alignmentConstraint = getAlignments(db, spatialMaps, groupAlignments);