refactor(types): separate ClusterNodes

Fixes: 7401cb8f6a
This commit is contained in:
Alois Klink
2024-10-30 18:34:52 +09:00
parent 93e20fdaa3
commit a381ab6c41
4 changed files with 50 additions and 15 deletions

View File

@@ -893,7 +893,7 @@ const addNodeFromVertex = (
node.cssCompiledStyles = getCompiledStyles(vertex.classes); node.cssCompiledStyles = getCompiledStyles(vertex.classes);
node.cssClasses = vertex.classes.join(' '); node.cssClasses = vertex.classes.join(' ');
} else { } else {
nodes.push({ const baseNode = {
id: vertex.id, id: vertex.id,
label: vertex.text, label: vertex.text,
labelStyle: '', labelStyle: '',
@@ -902,10 +902,8 @@ const addNodeFromVertex = (
cssStyles: vertex.styles, cssStyles: vertex.styles,
cssCompiledStyles: getCompiledStyles(['default', 'node', ...vertex.classes]), cssCompiledStyles: getCompiledStyles(['default', 'node', ...vertex.classes]),
cssClasses: 'default ' + vertex.classes.join(' '), cssClasses: 'default ' + vertex.classes.join(' '),
shape: getTypeFromVertex(vertex),
dir: vertex.dir, dir: vertex.dir,
domId: vertex.domId, domId: vertex.domId,
isGroup,
look, look,
link: vertex.link, link: vertex.link,
linkTarget: vertex.linkTarget, linkTarget: vertex.linkTarget,
@@ -916,7 +914,20 @@ const addNodeFromVertex = (
assetWidth: vertex.assetWidth, assetWidth: vertex.assetWidth,
assetHeight: vertex.assetHeight, assetHeight: vertex.assetHeight,
constraint: vertex.constraint, constraint: vertex.constraint,
}); };
if (isGroup) {
nodes.push({
...baseNode,
isGroup: true,
shape: 'rect',
});
} else {
nodes.push({
...baseNode,
isGroup: false,
shape: getTypeFromVertex(vertex),
});
}
} }
}; };

View File

@@ -471,6 +471,13 @@ const shapes = {
let clusterElems = new Map(); let clusterElems = new Map();
/**
* @typedef {keyof typeof shapes} ClusterShapeID
*/
/**
* @param {import('../types.js').ClusterNode} node - Shape defaults to 'rect'
*/
export const insertCluster = async (elem, node) => { export const insertCluster = async (elem, node) => {
const shape = node.shape || 'rect'; const shape = node.shape || 'rect';
const cluster = await shapes[shape](elem, node); const cluster = await shapes[shape](elem, node);

View File

@@ -1,6 +1,6 @@
import { log } from '../../logger.js'; import { log } from '../../logger.js';
import { shapes } from './shapes.js'; import { shapes } from './shapes.js';
import type { Node, ShapeRenderOptions } from '../types.js'; import type { Node, NonClusterNode, ShapeRenderOptions } from '../types.js';
import type { SVGGroup } from '../../mermaid.js'; import type { SVGGroup } from '../../mermaid.js';
import type { D3Selection } from '../../types.js'; import type { D3Selection } from '../../types.js';
import type { graphlib } from 'dagre-d3-es'; import type { graphlib } from 'dagre-d3-es';
@@ -10,7 +10,11 @@ type NodeElement = D3Selection<SVGAElement> | Awaited<ReturnType<ShapeHandler>>;
const nodeElems = new Map<string, NodeElement>(); const nodeElems = new Map<string, NodeElement>();
export async function insertNode(elem: SVGGroup, node: Node, renderOptions: ShapeRenderOptions) { export async function insertNode(
elem: SVGGroup,
node: NonClusterNode,
renderOptions: ShapeRenderOptions
) {
let newEl: NodeElement | undefined; let newEl: NodeElement | undefined;
let el; let el;

View File

@@ -1,5 +1,6 @@
export type MarkdownWordType = 'normal' | 'strong' | 'em'; export type MarkdownWordType = 'normal' | 'strong' | 'em';
import type { MermaidConfig } from '../config.type.js'; import type { MermaidConfig } from '../config.type.js';
import type { ClusterShapeID } from './rendering-elements/clusters.js';
import type { ShapeID } from './rendering-elements/shapes.js'; import type { ShapeID } from './rendering-elements/shapes.js';
export interface MarkdownWord { export interface MarkdownWord {
content: string; content: string;
@@ -9,8 +10,7 @@ export type MarkdownLine = MarkdownWord[];
/** Returns `true` if the line fits a constraint (e.g. it's under 𝑛 chars) */ /** Returns `true` if the line fits a constraint (e.g. it's under 𝑛 chars) */
export type CheckFitFunction = (text: MarkdownLine) => boolean; export type CheckFitFunction = (text: MarkdownLine) => boolean;
// Common properties for any node in the system interface BaseNode {
export interface Node {
id: string; id: string;
label?: string; label?: string;
description?: string[]; description?: string[];
@@ -38,7 +38,6 @@ export interface Node {
linkTarget?: string; linkTarget?: string;
tooltip?: string; tooltip?: string;
padding?: number; //REMOVE?, use from LayoutData.config - Keep, this could be shape specific padding?: number; //REMOVE?, use from LayoutData.config - Keep, this could be shape specific
shape?: ShapeID;
isGroup: boolean; isGroup: boolean;
width?: number; width?: number;
height?: number; height?: number;
@@ -75,6 +74,22 @@ export interface Node {
constraint?: 'on' | 'off'; constraint?: 'on' | 'off';
} }
/**
* Group/cluster nodes, e.g. nodes that contain other nodes.
*/
export interface ClusterNode extends BaseNode {
shape?: ClusterShapeID;
isGroup: true;
}
export interface NonClusterNode extends BaseNode {
shape?: ShapeID;
isGroup: false;
}
// Common properties for any node in the system
export type Node = ClusterNode | NonClusterNode;
// Common properties for any edge in the system // Common properties for any edge in the system
export interface Edge { export interface Edge {
id: string; id: string;
@@ -118,9 +133,9 @@ export interface RectOptions {
} }
// Extending the Node interface for specific types if needed // Extending the Node interface for specific types if needed
export interface ClassDiagramNode extends Node { export type ClassDiagramNode = Node & {
memberData: any; // Specific property for class diagram nodes memberData: any; // Specific property for class diagram nodes
} };
// Specific interfaces for layout and render data // Specific interfaces for layout and render data
export interface LayoutData { export interface LayoutData {
@@ -154,13 +169,11 @@ export interface ShapeRenderOptions {
dir?: Node['dir']; dir?: Node['dir'];
} }
export interface KanbanNode extends Node { export type KanbanNode = Node & {
// Kanban specif data // Kanban specif data
priority?: 'Very High' | 'High' | 'Medium' | 'Low' | 'Very Low'; priority?: 'Very High' | 'High' | 'Medium' | 'Low' | 'Very Low';
ticket?: string; ticket?: string;
assigned?: string; assigned?: string;
icon?: string; icon?: string;
level: number; level: number;
rx: number; };
ry: number;
}