mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-19 16:26:43 +02:00
#5237 Enabling subgraphs using the unified renderer for flowcharts
This commit is contained in:
@@ -84,13 +84,17 @@ stateDiagram-v2
|
|||||||
if_state --> True : if n >= 0
|
if_state --> True : if n >= 0
|
||||||
</pre
|
</pre
|
||||||
>
|
>
|
||||||
<pre id="diagram" class="mermaid2">
|
<pre id="diagram" class="mermaid">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
A[Start] --> B{Is it?} --> B1 & B2
|
subgraph Apa
|
||||||
|
A[Start] --> B
|
||||||
|
end
|
||||||
|
Apa --> C
|
||||||
|
A --> C
|
||||||
|
|
||||||
</pre
|
</pre
|
||||||
>
|
>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid2">
|
||||||
%%{init: {"layout": "dagre", "mergeEdges": false} }%%
|
%%{init: {"layout": "dagre", "mergeEdges": false} }%%
|
||||||
flowchart LR
|
flowchart LR
|
||||||
A ==> B(This is B)
|
A ==> B(This is B)
|
||||||
@@ -213,12 +217,12 @@ stateDiagram-v2
|
|||||||
mermaid.initialize({
|
mermaid.initialize({
|
||||||
// theme: 'base',
|
// theme: 'base',
|
||||||
// handdrawnSeed: 12,
|
// handdrawnSeed: 12,
|
||||||
// look: 'handdrawn',
|
look: 'handdrawn',
|
||||||
'elk.nodePlacement.strategy': 'NETWORK_SIMPLEX',
|
// 'elk.nodePlacement.strategy': 'NETWORK_SIMPLEX',
|
||||||
layout: 'dagre',
|
// layout: 'dagre',
|
||||||
// layout: 'elk',
|
// layout: 'elk',
|
||||||
// layout: 'fixed',
|
// layout: 'fixed',
|
||||||
htmlLabels: false,
|
// htmlLabels: false,
|
||||||
flowchart: { titleTopMargin: 10 },
|
flowchart: { titleTopMargin: 10 },
|
||||||
// fontFamily: 'Caveat',
|
// fontFamily: 'Caveat',
|
||||||
fontFamily: 'Kalam',
|
fontFamily: 'Kalam',
|
||||||
|
@@ -775,20 +775,39 @@ export const getData = () => {
|
|||||||
// extract(getRootDocV2());
|
// extract(getRootDocV2());
|
||||||
// const diagramStates = getStates();
|
// const diagramStates = getStates();
|
||||||
const useRough = config.look === 'handdrawn';
|
const useRough = config.look === 'handdrawn';
|
||||||
|
const subGraphs = getSubGraphs();
|
||||||
|
log.info('Subgraphs - ', subGraphs);
|
||||||
|
const parentDB = new Map<string, string>();
|
||||||
|
const subGraphDB = new Map<string, boolean>();
|
||||||
|
|
||||||
|
for (let i = subGraphs.length - 1; i >= 0; i--) {
|
||||||
|
const subGraph = subGraphs[i];
|
||||||
|
if (subGraph.nodes.length > 0) {
|
||||||
|
subGraphDB.set(subGraph.id, true);
|
||||||
|
}
|
||||||
|
subGraph.nodes.forEach((id) => {
|
||||||
|
parentDB.set(id, subGraph.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const n = getVertices();
|
const n = getVertices();
|
||||||
n.forEach((vertex) => {
|
n.forEach((vertex) => {
|
||||||
|
let parentId = parentDB.get(vertex.id);
|
||||||
|
let isGroup = subGraphDB.get(vertex.id) || false;
|
||||||
|
|
||||||
const node: Node = {
|
const node: Node = {
|
||||||
id: vertex.id,
|
id: vertex.id,
|
||||||
label: vertex.text,
|
label: vertex.text,
|
||||||
labelStyle: '',
|
labelStyle: '',
|
||||||
|
parentId,
|
||||||
padding: config.flowchart?.padding || 8,
|
padding: config.flowchart?.padding || 8,
|
||||||
cssStyles: vertex.styles.join(' '),
|
cssStyles: vertex.styles.join(' '),
|
||||||
cssClasses: vertex.classes.join(' '),
|
cssClasses: vertex.classes.join(' '),
|
||||||
shape: getTypeFromVertex(vertex),
|
shape: getTypeFromVertex(vertex),
|
||||||
dir: vertex.dir,
|
dir: vertex.dir,
|
||||||
domId: vertex.domId,
|
domId: vertex.domId,
|
||||||
type: undefined,
|
type: isGroup ? 'group' : undefined,
|
||||||
isGroup: false,
|
isGroup,
|
||||||
useRough,
|
useRough,
|
||||||
};
|
};
|
||||||
nodes.push(node);
|
nodes.push(node);
|
||||||
@@ -823,7 +842,6 @@ export const getData = () => {
|
|||||||
// console.log('rawEdge SPLIT', rawEdge, index);
|
// console.log('rawEdge SPLIT', rawEdge, index);
|
||||||
edges.push(edge);
|
edges.push(edge);
|
||||||
});
|
});
|
||||||
console.log('edges SPLIT', edges);
|
|
||||||
|
|
||||||
//const useRough = config.look === 'handdrawn';
|
//const useRough = config.look === 'handdrawn';
|
||||||
|
|
||||||
|
@@ -159,10 +159,8 @@ export const validate = (graph) => {
|
|||||||
* @param {any} graph
|
* @param {any} graph
|
||||||
*/
|
*/
|
||||||
export const findNonClusterChild = (id, graph) => {
|
export const findNonClusterChild = (id, graph) => {
|
||||||
// const node = graph.node(id);
|
|
||||||
log.trace('Searching', id);
|
log.trace('Searching', id);
|
||||||
// const children = graph.children(id).reverse();
|
const children = graph.children(id).reverse();
|
||||||
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);
|
log.trace('This is a valid node', id);
|
||||||
|
@@ -8,17 +8,18 @@ import { createText } from '../createText.ts';
|
|||||||
import intersectRect from '../rendering-elements/intersect/intersect-rect.js';
|
import intersectRect from '../rendering-elements/intersect/intersect-rect.js';
|
||||||
import createLabel from './createLabel.js';
|
import createLabel from './createLabel.js';
|
||||||
import { createRoundedRectPathD } from './shapes/roundedRectPath.ts';
|
import { createRoundedRectPathD } from './shapes/roundedRectPath.ts';
|
||||||
|
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||||
|
|
||||||
const rect = (parent, node) => {
|
const rect = (parent, node) => {
|
||||||
log.info('Creating subgraph rect for ', node.id, node);
|
log.info('Creating subgraph rect for ', node.id, node);
|
||||||
const siteConfig = getConfig();
|
const siteConfig = getConfig();
|
||||||
|
const { themeVariables, handdrawnSeed } = siteConfig;
|
||||||
|
const { clusterBkg, clusterBorder } = themeVariables;
|
||||||
|
let { useRough } = node;
|
||||||
|
|
||||||
// Add outer g element
|
// Add outer g element
|
||||||
const shapeSvg = parent.insert('g').attr('class', 'cluster').attr('id', node.id);
|
const shapeSvg = parent.insert('g').attr('class', 'cluster').attr('id', node.id);
|
||||||
|
|
||||||
// add the rect
|
|
||||||
const rect = shapeSvg.insert('rect', ':first-child');
|
|
||||||
|
|
||||||
const useHtmlLabels = evaluate(siteConfig.flowchart.htmlLabels);
|
const useHtmlLabels = evaluate(siteConfig.flowchart.htmlLabels);
|
||||||
|
|
||||||
// Create the label and insert it after the rect
|
// Create the label and insert it after the rect
|
||||||
@@ -44,7 +45,6 @@ const rect = (parent, node) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const padding = 0 * node.padding;
|
const padding = 0 * node.padding;
|
||||||
const halfPadding = padding / 2;
|
|
||||||
|
|
||||||
const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width;
|
const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width;
|
||||||
if (node.width <= bbox.width + padding) {
|
if (node.width <= bbox.width + padding) {
|
||||||
@@ -53,17 +53,45 @@ const rect = (parent, node) => {
|
|||||||
node.diff = -node.padding / 2;
|
node.diff = -node.padding / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.trace('Data ', node, JSON.stringify(node));
|
const totalWidth = width + padding;
|
||||||
// center the rect around its coordinate
|
const totalHeight = node.height + padding;
|
||||||
rect
|
const x = node.x - totalWidth / 2;
|
||||||
.attr('style', node.cssStyles)
|
const y = node.y - totalHeight / 2;
|
||||||
.attr('rx', node.rx)
|
|
||||||
.attr('ry', node.ry)
|
|
||||||
.attr('x', node.x - width / 2)
|
|
||||||
.attr('y', node.y - node.height / 2 - halfPadding)
|
|
||||||
.attr('width', width)
|
|
||||||
.attr('height', node.height + padding);
|
|
||||||
|
|
||||||
|
log.trace('Data ', node, JSON.stringify(node));
|
||||||
|
let rect;
|
||||||
|
if (useRough) {
|
||||||
|
// @ts-ignore TODO: Fix rough typings
|
||||||
|
const rc = rough.svg(shapeSvg);
|
||||||
|
const options = userNodeOverrides(node, {
|
||||||
|
roughness: 0.7,
|
||||||
|
fill: clusterBkg,
|
||||||
|
// fill: 'red',
|
||||||
|
stroke: clusterBorder,
|
||||||
|
fillWeight: 3,
|
||||||
|
seed: handdrawnSeed,
|
||||||
|
stroke: clusterBorder,
|
||||||
|
});
|
||||||
|
const roughNode = rc.path(createRoundedRectPathD(x, y, totalWidth, totalHeight, 0), options);
|
||||||
|
// console.log('Rough node insert CXC', roughNode);
|
||||||
|
|
||||||
|
rect = shapeSvg.insert(() => {
|
||||||
|
console.log('Rough node insert CXC', roughNode);
|
||||||
|
return roughNode;
|
||||||
|
}, ':first-child');
|
||||||
|
} else {
|
||||||
|
// add the rect
|
||||||
|
rect = shapeSvg.insert('rect', ':first-child');
|
||||||
|
// center the rect around its coordinate
|
||||||
|
rect
|
||||||
|
.attr('style', node.cssStyles)
|
||||||
|
.attr('rx', node.rx)
|
||||||
|
.attr('ry', node.ry)
|
||||||
|
.attr('x', x)
|
||||||
|
.attr('y', y)
|
||||||
|
.attr('width', totalWidth)
|
||||||
|
.attr('height', totalHeight);
|
||||||
|
}
|
||||||
const { subGraphTitleTopMargin } = getSubGraphTitleMargins(siteConfig);
|
const { subGraphTitleTopMargin } = getSubGraphTitleMargins(siteConfig);
|
||||||
if (useHtmlLabels) {
|
if (useHtmlLabels) {
|
||||||
labelEl.attr(
|
labelEl.attr(
|
||||||
@@ -303,8 +331,8 @@ const divider = (parent, node) => {
|
|||||||
|
|
||||||
return { cluster: shapeSvg, labelBBox: { width: 0, height: 0 } };
|
return { cluster: shapeSvg, labelBBox: { width: 0, height: 0 } };
|
||||||
};
|
};
|
||||||
|
const squareRect = rect;
|
||||||
const shapes = { rect, roundedWithTitle, noteGroup, divider };
|
const shapes = { rect, squareRect, roundedWithTitle, noteGroup, divider };
|
||||||
|
|
||||||
let clusterElems = {};
|
let clusterElems = {};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user