feat(arch): arrows now rendered on diagram

This commit is contained in:
NicolasNewman 2024-04-04 13:47:01 -05:00
parent 2709c2d2e1
commit 6d5791a63a
5 changed files with 68 additions and 10 deletions

View File

@ -88,8 +88,10 @@ function addEdges(lines: ArchitectureLine[], cy: cytoscape.Core) {
id: `${line.lhs_id}-${line.rhs_id}`,
source: line.lhs_id,
sourceDir: line.lhs_dir,
sourceArrow: line.lhs_into,
target: line.rhs_id,
targetDir: line.rhs_dir,
targetArrow: line.rhs_into,
},
});
});

View File

@ -58,6 +58,9 @@ const getStyles: DiagramStylesProvider = (options: ArchitectureStyleOptions) =>
stroke-width: 3;
stroke: #777;
}
.arrow {
fill: #777;
}
.section-root rect, .section-root path, .section-root circle, .section-root polygon {
fill: #333;
}

View File

@ -5,6 +5,7 @@ import type { D3Element } from '../../mermaidAPI.js';
export type ArchitectureDirection = 'L' | 'R' | 'T' | 'B';
export type ArchitectureDirectionX = Extract<ArchitectureDirection, 'L' | 'R'>;
export type ArchitectureDirectionY = Extract<ArchitectureDirection, 'T' | 'B'>;
export const ArchitectureDirectionName = {
L: 'left',
R: 'right',
@ -12,6 +13,20 @@ export const ArchitectureDirectionName = {
B: 'bottom',
} as const;
export const ArchitectureDirectionArrow = {
L: (scale: number) => `${scale},${scale / 2} 0,${scale} 0,0`,
R: (scale: number) => `0,${scale / 2} ${scale},0 ${scale},${scale}`,
T: (scale: number) => `0,0 ${scale},0 ${scale / 2},${scale}`,
B: (scale: number) => `${scale / 2},0 ${scale},${scale} 0,${scale}`,
} as const;
export const ArchitectureDirectionArrowShift = {
L: (orig: number, iconSize: number, arrowSize: number) => orig - iconSize / 2 - arrowSize + 2,
R: (orig: number, iconSize: number, arrowSize: number) => orig + iconSize / 2 - 2,
T: (orig: number, iconSize: number, arrowSize: number) => orig - iconSize / 2 - arrowSize + 2,
B: (orig: number, iconSize: number, arrowSize: number) => orig + iconSize / 2 - 2,
} as const;
export const getOppositeArchitectureDirection = function (
x: ArchitectureDirection
): ArchitectureDirection {

View File

@ -18,9 +18,9 @@
<GROUP,SERVICE>\([\w]*\) return 'icon';
<GROUP,SERVICE>\[[\w ]*\] return 'title';
[\w]+ { this.begin('LINE'); return 'id'; }
<LINE>\<[L|R|T|B]"-" return 'ARROW_LEFT_INTO';
<LINE>\([L|R|T|B]"-" return 'ARROW_LEFT_INTO';
<LINE>[L|R|T|B]"-" return 'ARROW_LEFT';
<LINE>"-"[L|R|T|B]\> return 'ARROW_RIGHT_INTO';
<LINE>"-"[L|R|T|B]\) return 'ARROW_RIGHT_INTO';
<LINE>"-"[L|R|T|B] return 'ARROW_RIGHT';
<LINE>[\w]+ return 'id';
<LINE>\[[\w ]*\] return 'title';

View File

@ -1,9 +1,13 @@
import type { D3Element } from '../../mermaidAPI.js';
import { createText } from '../../rendering-util/createText.js';
import type {
ArchitectureDB,
ArchitectureDirection,
ArchitectureService,
import {
ArchitectureDirectionArrow,
type ArchitectureDB,
type ArchitectureDirection,
type ArchitectureService,
ArchitectureDirectionArrowShift,
isArchitectureDirectionX,
isArchitectureDirectionY,
} from './architectureTypes.js';
import type { MermaidConfig } from '../../config.type.js';
import type cytoscape from 'cytoscape';
@ -16,8 +20,10 @@ declare module 'cytoscape' {
id: string;
source: string;
sourceDir: ArchitectureDirection;
sourceArrow?: boolean;
target: string;
targetDir: ArchitectureDirection;
targetArrow?: boolean;
[key: string]: any;
};
interface EdgeSingular {
@ -70,19 +76,51 @@ declare module 'cytoscape' {
}
export const drawEdges = function (edgesEl: D3Element, cy: cytoscape.Core) {
const iconSize = getConfigField('iconSize');
const halfIconSize = iconSize / 2;
const arrowSize = iconSize / 6;
const halfArrowSize = arrowSize / 2;
cy.edges().map((edge, id) => {
const data = edge.data();
const { source, sourceDir, sourceArrow, target, targetDir, targetArrow } = edge.data();
if (edge[0]._private.bodyBounds) {
const bounds = edge[0]._private.rscratch;
log.trace('Edge: ', id, data);
edgesEl
.insert('path')
const g = edgesEl.insert('g');
g.insert('path')
.attr(
'd',
`M ${bounds.startX},${bounds.startY} L ${bounds.midX},${bounds.midY} L${bounds.endX},${bounds.endY} `
)
.attr('class', 'edge');
if (sourceArrow) {
console.log(`New source arrow: ${sourceDir} for ${source}`);
const xShift = isArchitectureDirectionX(sourceDir)
? ArchitectureDirectionArrowShift[sourceDir](bounds.startX, iconSize, arrowSize)
: bounds.startX - halfArrowSize;
const yShift = isArchitectureDirectionY(sourceDir)
? ArchitectureDirectionArrowShift[sourceDir](bounds.startY, iconSize, arrowSize)
: bounds.startY - halfArrowSize;
g.insert('polygon')
.attr('points', ArchitectureDirectionArrow[sourceDir](arrowSize))
.attr('transform', `translate(${xShift},${yShift})`)
.attr('class', 'arrow');
}
if (targetArrow) {
console.log(`New target arrow: ${targetDir} for ${target}`);
const xShift = isArchitectureDirectionX(targetDir)
? ArchitectureDirectionArrowShift[targetDir](bounds.endX, iconSize, arrowSize)
: bounds.endX - halfArrowSize;
const yShift = isArchitectureDirectionY(targetDir)
? ArchitectureDirectionArrowShift[targetDir](bounds.endY, iconSize, arrowSize)
: bounds.endY - halfArrowSize;
g.insert('polygon')
.attr('points', ArchitectureDirectionArrow[targetDir](arrowSize))
.attr('transform', `translate(${xShift},${yShift})`)
.attr('class', 'arrow');
}
}
});
};