mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-10-07 16:19:38 +02:00
Merge branch '5237-unified-layout-common-renderer' of github.com:mermaid-js/mermaid into alanaV11
This commit is contained in:
@@ -24,32 +24,32 @@ const clusterDb = {};
|
|||||||
|
|
||||||
export const addVertex = async (nodeEl, graph, nodeArr, node) => {
|
export const addVertex = async (nodeEl, graph, nodeArr, node) => {
|
||||||
const labelData = { width: 0, height: 0 };
|
const labelData = { width: 0, height: 0 };
|
||||||
const ports = [
|
// const ports = [
|
||||||
{
|
// {
|
||||||
id: node.id + '-west',
|
// id: node.id + '-west',
|
||||||
layoutOptions: {
|
// layoutOptions: {
|
||||||
'port.side': 'WEST',
|
// 'port.side': 'WEST',
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
id: node.id + '-east',
|
// id: node.id + '-east',
|
||||||
layoutOptions: {
|
// layoutOptions: {
|
||||||
'port.side': 'EAST',
|
// 'port.side': 'EAST',
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
id: node.id + '-south',
|
// id: node.id + '-south',
|
||||||
layoutOptions: {
|
// layoutOptions: {
|
||||||
'port.side': 'SOUTH',
|
// 'port.side': 'SOUTH',
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
id: node.id + '-north',
|
// id: node.id + '-north',
|
||||||
layoutOptions: {
|
// layoutOptions: {
|
||||||
'port.side': 'NORTH',
|
// 'port.side': 'NORTH',
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
];
|
// ];
|
||||||
|
|
||||||
let boundingBox;
|
let boundingBox;
|
||||||
const child = {
|
const child = {
|
||||||
@@ -103,7 +103,7 @@ export const addVertices = async function (nodeEl, nodeArr, graph, parentId) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const drawNodes = async (relX, relY, nodeArray, svg, subgraphsEl, depth) => {
|
const drawNodes = async (relX, relY, nodeArray, svg, subgraphsEl, depth) => {
|
||||||
Promise.all(
|
await Promise.all(
|
||||||
nodeArray.map(async function (node) {
|
nodeArray.map(async function (node) {
|
||||||
if (node) {
|
if (node) {
|
||||||
nodeDb[node.id] = node;
|
nodeDb[node.id] = node;
|
||||||
@@ -117,7 +117,7 @@ const drawNodes = async (relX, relY, nodeArray, svg, subgraphsEl, depth) => {
|
|||||||
height: node.height,
|
height: node.height,
|
||||||
};
|
};
|
||||||
if (node.isGroup) {
|
if (node.isGroup) {
|
||||||
console.log('Id abc88 subgraph = ', node.id, node.x, node.y, node.labelData);
|
log.debug('Id abc88 subgraph = ', node.id, node.x, node.y, node.labelData);
|
||||||
const subgraphEl = subgraphsEl.insert('g').attr('class', 'subgraph');
|
const subgraphEl = subgraphsEl.insert('g').attr('class', 'subgraph');
|
||||||
// TODO use faster way of cloning
|
// TODO use faster way of cloning
|
||||||
const clusterNode = JSON.parse(JSON.stringify(node));
|
const clusterNode = JSON.parse(JSON.stringify(node));
|
||||||
@@ -125,7 +125,7 @@ const drawNodes = async (relX, relY, nodeArray, svg, subgraphsEl, depth) => {
|
|||||||
clusterNode.y = node.offset.posY + node.height / 2;
|
clusterNode.y = node.offset.posY + node.height / 2;
|
||||||
await insertCluster(subgraphEl, clusterNode);
|
await insertCluster(subgraphEl, clusterNode);
|
||||||
|
|
||||||
console.log('Id (UIO)= ', node.id, node.width, node.shape, node.labels);
|
log.debug('Id (UIO)= ', node.id, node.width, node.shape, node.labels);
|
||||||
} else {
|
} else {
|
||||||
log.info(
|
log.info(
|
||||||
'Id NODE = ',
|
'Id NODE = ',
|
||||||
@@ -145,11 +145,14 @@ const drawNodes = async (relX, relY, nodeArray, svg, subgraphsEl, depth) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
nodeArray.forEach(function (node) {
|
|
||||||
if (node?.isGroup) {
|
await Promise.all(
|
||||||
drawNodes(relX + node.x, relY + node.y, node.children, svg, subgraphsEl, depth + 1);
|
nodeArray.map(async function (node) {
|
||||||
}
|
if (node?.isGroup) {
|
||||||
});
|
await drawNodes(relX + node.x, relY + node.y, node.children, svg, subgraphsEl, depth + 1);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getNextPort = (node, edgeDirection, graphDirection) => {
|
const getNextPort = (node, edgeDirection, graphDirection) => {
|
||||||
@@ -390,7 +393,7 @@ export const addEdges = async function (dataForLayout, graph, svg) {
|
|||||||
// calculate start and end points of the edge, note that the source and target
|
// calculate start and end points of the edge, note that the source and target
|
||||||
// can be modified for shapes that have ports
|
// can be modified for shapes that have ports
|
||||||
const { source, target, sourceId, targetId } = getEdgeStartEndPoint(edge, dir);
|
const { source, target, sourceId, targetId } = getEdgeStartEndPoint(edge, dir);
|
||||||
console.log('abc78 source and target', source, target);
|
log.debug('abc78 source and target', source, target);
|
||||||
// Add the edge to the graph
|
// Add the edge to the graph
|
||||||
graph.edges.push({
|
graph.edges.push({
|
||||||
id: 'e' + edge.start + edge.end,
|
id: 'e' + edge.start + edge.end,
|
||||||
@@ -518,8 +521,8 @@ export const render = async (data4Layout: LayoutData, svg, element, algorithm) =
|
|||||||
width: node?.labelData?.width || 50,
|
width: node?.labelData?.width || 50,
|
||||||
height: node?.labelData?.height || 50,
|
height: node?.labelData?.height || 50,
|
||||||
},
|
},
|
||||||
(node.width = node.width + 2 * node.paddding),
|
(node.width = node.width + 2 * node.padding),
|
||||||
console.log('UIO node label', node?.labelData?.width, node.padding),
|
log.debug('UIO node label', node?.labelData?.width, node.padding),
|
||||||
];
|
];
|
||||||
node.layoutOptions = {
|
node.layoutOptions = {
|
||||||
'spacing.baseValue': 30,
|
'spacing.baseValue': 30,
|
||||||
@@ -556,7 +559,7 @@ export const render = async (data4Layout: LayoutData, svg, element, algorithm) =
|
|||||||
const g = await elk.layout(elkGraph);
|
const g = await elk.layout(elkGraph);
|
||||||
|
|
||||||
// debugger;
|
// debugger;
|
||||||
drawNodes(0, 0, g.children, svg, subGraphsEl, 0);
|
await drawNodes(0, 0, g.children, svg, subGraphsEl, 0);
|
||||||
g.edges?.map((edge) => {
|
g.edges?.map((edge) => {
|
||||||
// (elem, edge, clusterDb, diagramType, graph, id)
|
// (elem, edge, clusterDb, diagramType, graph, id)
|
||||||
const startNode = nodeDb[edge.sources[0]];
|
const startNode = nodeDb[edge.sources[0]];
|
||||||
@@ -566,7 +569,7 @@ export const render = async (data4Layout: LayoutData, svg, element, algorithm) =
|
|||||||
const targetId = edge.end;
|
const targetId = edge.end;
|
||||||
|
|
||||||
const offset = calcOffset(sourceId, targetId, parentLookupDb);
|
const offset = calcOffset(sourceId, targetId, parentLookupDb);
|
||||||
console.log(
|
log.debug(
|
||||||
'offset',
|
'offset',
|
||||||
offset,
|
offset,
|
||||||
sourceId,
|
sourceId,
|
||||||
@@ -599,7 +602,7 @@ export const render = async (data4Layout: LayoutData, svg, element, algorithm) =
|
|||||||
// sw = Math.max(bbox.width, startNode.width, startNode.labels[0].width);
|
// sw = Math.max(bbox.width, startNode.width, startNode.labels[0].width);
|
||||||
sw = Math.max(startNode.width, startNode.labels[0].width + startNode.padding);
|
sw = Math.max(startNode.width, startNode.labels[0].width + startNode.padding);
|
||||||
// sw = startNode.width;
|
// sw = startNode.width;
|
||||||
console.log(
|
log.debug(
|
||||||
'UIO width',
|
'UIO width',
|
||||||
startNode.id,
|
startNode.id,
|
||||||
startNode.with,
|
startNode.with,
|
||||||
@@ -619,7 +622,7 @@ export const render = async (data4Layout: LayoutData, svg, element, algorithm) =
|
|||||||
const bbox = endNode.domId.node().getBBox();
|
const bbox = endNode.domId.node().getBBox();
|
||||||
ew = Math.max(startNode.width, endNode.labels[0].width + endNode.padding);
|
ew = Math.max(startNode.width, endNode.labels[0].width + endNode.padding);
|
||||||
|
|
||||||
console.log(
|
log.debug(
|
||||||
'UIO width',
|
'UIO width',
|
||||||
startNode.id,
|
startNode.id,
|
||||||
startNode.with,
|
startNode.with,
|
||||||
@@ -711,24 +714,24 @@ export const render = async (data4Layout: LayoutData, svg, element, algorithm) =
|
|||||||
};
|
};
|
||||||
|
|
||||||
function intersectLine(p1, p2, q1, q2) {
|
function intersectLine(p1, p2, q1, q2) {
|
||||||
console.log('UIO intersectLine', p1, p2, q1, q2);
|
log.debug('UIO intersectLine', p1, p2, q1, q2);
|
||||||
// Algorithm from J. Avro, (ed.) Graphics Gems, No 2, Morgan Kaufmann, 1994,
|
// Algorithm from J. Avro, (ed.) Graphics Gems, No 2, Morgan Kaufmann, 1994,
|
||||||
// p7 and p473.
|
// p7 and p473.
|
||||||
|
|
||||||
let a1, a2, b1, b2, c1, c2;
|
// let a1, a2, b1, b2, c1, c2;
|
||||||
let r1, r2, r3, r4;
|
// let r1, r2, r3, r4;
|
||||||
let denom, offset, num;
|
// let denom, offset, num;
|
||||||
let x, y;
|
// let x, y;
|
||||||
|
|
||||||
// Compute a1, b1, c1, where line joining points 1 and 2 is F(x,y) = a1 x +
|
// Compute a1, b1, c1, where line joining points 1 and 2 is F(x,y) = a1 x +
|
||||||
// b1 y + c1 = 0.
|
// b1 y + c1 = 0.
|
||||||
a1 = p2.y - p1.y;
|
const a1 = p2.y - p1.y;
|
||||||
b1 = p1.x - p2.x;
|
const b1 = p1.x - p2.x;
|
||||||
c1 = p2.x * p1.y - p1.x * p2.y;
|
const c1 = p2.x * p1.y - p1.x * p2.y;
|
||||||
|
|
||||||
// Compute r3 and r4.
|
// Compute r3 and r4.
|
||||||
r3 = a1 * q1.x + b1 * q1.y + c1;
|
const r3 = a1 * q1.x + b1 * q1.y + c1;
|
||||||
r4 = a1 * q2.x + b1 * q2.y + c1;
|
const r4 = a1 * q2.x + b1 * q2.y + c1;
|
||||||
|
|
||||||
// Check signs of r3 and r4. If both point 3 and point 4 lie on
|
// Check signs of r3 and r4. If both point 3 and point 4 lie on
|
||||||
// same side of line 1, the line segments do not intersect.
|
// same side of line 1, the line segments do not intersect.
|
||||||
@@ -737,13 +740,13 @@ function intersectLine(p1, p2, q1, q2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compute a2, b2, c2 where line joining points 3 and 4 is G(x,y) = a2 x + b2 y + c2 = 0
|
// Compute a2, b2, c2 where line joining points 3 and 4 is G(x,y) = a2 x + b2 y + c2 = 0
|
||||||
a2 = q2.y - q1.y;
|
const a2 = q2.y - q1.y;
|
||||||
b2 = q1.x - q2.x;
|
const b2 = q1.x - q2.x;
|
||||||
c2 = q2.x * q1.y - q1.x * q2.y;
|
const c2 = q2.x * q1.y - q1.x * q2.y;
|
||||||
|
|
||||||
// Compute r1 and r2
|
// Compute r1 and r2
|
||||||
r1 = a2 * p1.x + b2 * p1.y + c2;
|
const r1 = a2 * p1.x + b2 * p1.y + c2;
|
||||||
r2 = a2 * p2.x + b2 * p2.y + c2;
|
const r2 = a2 * p2.x + b2 * p2.y + c2;
|
||||||
|
|
||||||
// Check signs of r1 and r2. If both point 1 and point 2 lie
|
// Check signs of r1 and r2. If both point 1 and point 2 lie
|
||||||
// on same side of second line segment, the line segments do
|
// on same side of second line segment, the line segments do
|
||||||
@@ -753,29 +756,25 @@ function intersectLine(p1, p2, q1, q2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Line segments intersect: compute intersection point.
|
// Line segments intersect: compute intersection point.
|
||||||
denom = a1 * b2 - a2 * b1;
|
const denom = a1 * b2 - a2 * b1;
|
||||||
if (denom === 0) {
|
if (denom === 0) {
|
||||||
return /*COLLINEAR*/;
|
return /*COLLINEAR*/;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = Math.abs(denom / 2);
|
const offset = Math.abs(denom / 2);
|
||||||
|
|
||||||
// The denom/2 is to get rounding instead of truncating. It
|
// The denom/2 is to get rounding instead of truncating. It
|
||||||
// is added or subtracted to the numerator, depending upon the
|
// is added or subtracted to the numerator, depending upon the
|
||||||
// sign of the numerator.
|
// sign of the numerator.
|
||||||
num = b1 * c2 - b2 * c1;
|
num = b1 * c2 - b2 * c1;
|
||||||
x = num < 0 ? (num - offset) / denom : (num + offset) / denom;
|
const x = num < 0 ? (num - offset) / denom : (num + offset) / denom;
|
||||||
|
|
||||||
num = a2 * c1 - a1 * c2;
|
num = a2 * c1 - a1 * c2;
|
||||||
y = num < 0 ? (num - offset) / denom : (num + offset) / denom;
|
const y = num < 0 ? (num - offset) / denom : (num + offset) / denom;
|
||||||
|
|
||||||
return { x: x, y: y };
|
return { x: x, y: y };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param r1
|
|
||||||
* @param r2
|
|
||||||
*/
|
|
||||||
function sameSign(r1, r2) {
|
function sameSign(r1, r2) {
|
||||||
return r1 * r2 > 0;
|
return r1 * r2 > 0;
|
||||||
}
|
}
|
||||||
@@ -785,7 +784,6 @@ const diamondIntersection = (bounds, outsidePoint, insidePoint) => {
|
|||||||
|
|
||||||
const w = bounds.width; //+ bounds.padding;
|
const w = bounds.width; //+ bounds.padding;
|
||||||
const h = bounds.height; // + bounds.padding;
|
const h = bounds.height; // + bounds.padding;
|
||||||
const s = w + h;
|
|
||||||
|
|
||||||
const polyPoints = [
|
const polyPoints = [
|
||||||
{ x: x1, y: y1 - h / 2 },
|
{ x: x1, y: y1 - h / 2 },
|
||||||
@@ -815,8 +813,8 @@ const diamondIntersection = (bounds, outsidePoint, insidePoint) => {
|
|||||||
minY = Math.min(minY, polyPoints.y);
|
minY = Math.min(minY, polyPoints.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
const left = x1 - w / 2;
|
// const left = x1 - w / 2;
|
||||||
const top = y1 + h / 2;
|
// const top = y1 + h / 2;
|
||||||
|
|
||||||
for (let i = 0; i < polyPoints.length; i++) {
|
for (let i = 0; i < polyPoints.length; i++) {
|
||||||
const p1 = polyPoints[i];
|
const p1 = polyPoints[i];
|
||||||
@@ -837,7 +835,7 @@ const diamondIntersection = (bounds, outsidePoint, insidePoint) => {
|
|||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('UIO intersections', intersections);
|
log.debug('UIO intersections', intersections);
|
||||||
|
|
||||||
if (intersections.length > 1) {
|
if (intersections.length > 1) {
|
||||||
// More intersections, find the one nearest to edge end point
|
// More intersections, find the one nearest to edge end point
|
||||||
@@ -927,7 +925,7 @@ export const intersection = (node, outsidePoint, insidePoint) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const outsideNode = (node, point) => {
|
const outsideNode = (node, point) => {
|
||||||
console.log('Checking bounds ', node, point);
|
log.debug('Checking bounds ', node, point);
|
||||||
const x = node.x;
|
const x = node.x;
|
||||||
const y = node.y;
|
const y = node.y;
|
||||||
const dx = Math.abs(point.x - x);
|
const dx = Math.abs(point.x - x);
|
||||||
@@ -942,19 +940,15 @@ const outsideNode = (node, point) => {
|
|||||||
/**
|
/**
|
||||||
* This function will page a path and node where the last point(s) in the path is inside the node
|
* This function will page a path and node where the last point(s) in the path is inside the node
|
||||||
* and return an update path ending by the border of the node.
|
* and return an update path ending by the border of the node.
|
||||||
*
|
|
||||||
* @param {Array} _points
|
|
||||||
* @param {any} bounds
|
|
||||||
* @returns {Array} Points
|
|
||||||
*/
|
*/
|
||||||
const cutPathAtIntersect = (_points, bounds, isDiamond: boolean) => {
|
const cutPathAtIntersect = (_points, bounds, isDiamond: boolean) => {
|
||||||
console.log('UIO cutPathAtIntersect Points:', _points, 'node:', bounds, 'isDiamond', isDiamond);
|
log.debug('UIO cutPathAtIntersect Points:', _points, 'node:', bounds, 'isDiamond', isDiamond);
|
||||||
const points = [];
|
const points = [];
|
||||||
let lastPointOutside = _points[0];
|
let lastPointOutside = _points[0];
|
||||||
let isInside = false;
|
let isInside = false;
|
||||||
_points.forEach((point) => {
|
_points.forEach((point) => {
|
||||||
// const node = clusterDb[edge.toCluster].node;
|
// const node = clusterDb[edge.toCluster].node;
|
||||||
console.log(' checking point', point, bounds);
|
log.debug(' checking point', point, bounds);
|
||||||
|
|
||||||
// check if point is inside the boundary rect
|
// check if point is inside the boundary rect
|
||||||
if (!outsideNode(bounds, point) && !isInside) {
|
if (!outsideNode(bounds, point) && !isInside) {
|
||||||
@@ -984,13 +978,13 @@ const cutPathAtIntersect = (_points, bounds, isDiamond: boolean) => {
|
|||||||
if (!points.some((e) => e.x === inter.x && e.y === inter.y)) {
|
if (!points.some((e) => e.x === inter.x && e.y === inter.y)) {
|
||||||
points.push(inter);
|
points.push(inter);
|
||||||
} else {
|
} else {
|
||||||
console.log('abc88 no intersect', inter, points);
|
log.debug('abc88 no intersect', inter, points);
|
||||||
}
|
}
|
||||||
// points.push(inter);
|
// points.push(inter);
|
||||||
isInside = true;
|
isInside = true;
|
||||||
} else {
|
} else {
|
||||||
// Outside
|
// Outside
|
||||||
console.log('abc88 outside', point, lastPointOutside, points);
|
log.debug('abc88 outside', point, lastPointOutside, points);
|
||||||
lastPointOutside = point;
|
lastPointOutside = point;
|
||||||
// points.push(point);
|
// points.push(point);
|
||||||
if (!isInside) {
|
if (!isInside) {
|
||||||
@@ -998,6 +992,6 @@ const cutPathAtIntersect = (_points, bounds, isDiamond: boolean) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log('returning points', points);
|
log.debug('returning points', points);
|
||||||
return points;
|
return points;
|
||||||
};
|
};
|
||||||
|
@@ -7,10 +7,8 @@ import {
|
|||||||
styles2String,
|
styles2String,
|
||||||
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||||
import rough from 'roughjs';
|
import rough from 'roughjs';
|
||||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
|
||||||
|
|
||||||
export const drawRect = async (parent: SVGAElement, node: Node, options: RectOptions) => {
|
export const drawRect = async (parent: SVGAElement, node: Node, options: RectOptions) => {
|
||||||
const { look } = getConfig();
|
|
||||||
const { labelStyles, nodeStyles } = styles2String(node);
|
const { labelStyles, nodeStyles } = styles2String(node);
|
||||||
node.labelStyle = labelStyles;
|
node.labelStyle = labelStyles;
|
||||||
// console.log('IPI labelStyles:', labelStyles);
|
// console.log('IPI labelStyles:', labelStyles);
|
||||||
|
Reference in New Issue
Block a user