2023-09-05 11:13:27 +02:00
|
|
|
import { getStylesFromArray } from '../../utils.js';
|
2023-09-14 10:11:43 +02:00
|
|
|
import { insertNode, positionNode } from '../../dagre-wrapper/nodes.js';
|
2023-09-05 11:13:27 +02:00
|
|
|
import { getConfig } from '../../config.js';
|
|
|
|
import { ContainerElement } from 'd3';
|
|
|
|
import type { Block } from './blockTypes.js';
|
|
|
|
import { BlockDB } from './blockDB.js';
|
|
|
|
|
2023-10-03 12:56:47 +02:00
|
|
|
function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
|
2023-09-05 11:13:27 +02:00
|
|
|
const vertex = block;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Variable for storing the classes for the vertex
|
|
|
|
*
|
|
|
|
* @type {string}
|
|
|
|
*/
|
|
|
|
let classStr = 'default';
|
|
|
|
if ((vertex?.classes?.length || []) > 0) {
|
|
|
|
classStr = vertex.classes.join(' ');
|
|
|
|
}
|
|
|
|
classStr = classStr + ' flowchart-label';
|
|
|
|
|
|
|
|
// We create a SVG label, either by delegating to addHtmlLabel or manually
|
|
|
|
let vertexNode;
|
|
|
|
const labelData = { width: 0, height: 0 };
|
|
|
|
|
|
|
|
let radious = 0;
|
|
|
|
let _shape = '';
|
|
|
|
let layoutOptions = {};
|
|
|
|
// Set the shape based parameters
|
|
|
|
switch (vertex.type) {
|
|
|
|
case 'round':
|
|
|
|
radious = 5;
|
|
|
|
_shape = 'rect';
|
|
|
|
break;
|
|
|
|
case 'square':
|
|
|
|
_shape = 'rect';
|
|
|
|
break;
|
|
|
|
case 'diamond':
|
|
|
|
_shape = 'question';
|
|
|
|
layoutOptions = {
|
|
|
|
portConstraints: 'FIXED_SIDE',
|
|
|
|
};
|
|
|
|
break;
|
|
|
|
case 'hexagon':
|
|
|
|
_shape = 'hexagon';
|
|
|
|
break;
|
|
|
|
case 'odd':
|
|
|
|
_shape = 'rect_left_inv_arrow';
|
|
|
|
break;
|
|
|
|
case 'lean_right':
|
|
|
|
_shape = 'lean_right';
|
|
|
|
break;
|
|
|
|
case 'lean_left':
|
|
|
|
_shape = 'lean_left';
|
|
|
|
break;
|
|
|
|
case 'trapezoid':
|
|
|
|
_shape = 'trapezoid';
|
|
|
|
break;
|
|
|
|
case 'inv_trapezoid':
|
|
|
|
_shape = 'inv_trapezoid';
|
|
|
|
break;
|
|
|
|
case 'odd_right':
|
|
|
|
_shape = 'rect_left_inv_arrow';
|
|
|
|
break;
|
|
|
|
case 'circle':
|
|
|
|
_shape = 'circle';
|
|
|
|
break;
|
|
|
|
case 'ellipse':
|
|
|
|
_shape = 'ellipse';
|
|
|
|
break;
|
|
|
|
case 'stadium':
|
|
|
|
_shape = 'stadium';
|
|
|
|
break;
|
|
|
|
case 'subroutine':
|
|
|
|
_shape = 'subroutine';
|
|
|
|
break;
|
|
|
|
case 'cylinder':
|
|
|
|
_shape = 'cylinder';
|
|
|
|
break;
|
|
|
|
case 'group':
|
|
|
|
_shape = 'rect';
|
|
|
|
break;
|
|
|
|
case 'doublecircle':
|
|
|
|
_shape = 'doublecircle';
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
_shape = 'rect';
|
|
|
|
}
|
|
|
|
|
|
|
|
// const styles = getStylesFromArray(vertex.styles);
|
|
|
|
const styles = getStylesFromArray([]);
|
|
|
|
|
|
|
|
// Use vertex id as text in the box if no text is provided by the graph definition
|
|
|
|
const vertexText = vertex.label;
|
|
|
|
|
2023-09-05 15:15:08 +02:00
|
|
|
const bounds = vertex.size || { width: 0, height: 0, x: 0, y: 0 };
|
2023-09-05 11:13:27 +02:00
|
|
|
// Add the node
|
|
|
|
const node = {
|
|
|
|
labelStyle: styles.labelStyle,
|
|
|
|
shape: _shape,
|
|
|
|
labelText: vertexText,
|
|
|
|
// labelType: vertex.labelType,
|
|
|
|
rx: radious,
|
|
|
|
ry: radious,
|
|
|
|
class: classStr,
|
|
|
|
style: styles.style,
|
|
|
|
id: vertex.id,
|
|
|
|
// link: vertex.link,
|
|
|
|
// linkTarget: vertex.linkTarget,
|
|
|
|
// tooltip: diagObj.db.getTooltip(vertex.id) || '',
|
|
|
|
// domId: diagObj.db.lookUpDomId(vertex.id),
|
|
|
|
// haveCallback: vertex.haveCallback,
|
|
|
|
// width: vertex.type === 'group' ? 500 : undefined,
|
|
|
|
// dir: vertex.dir,
|
2023-09-05 15:15:08 +02:00
|
|
|
width: bounds.width,
|
|
|
|
height: bounds.height,
|
|
|
|
x: bounds.x,
|
|
|
|
y: bounds.y,
|
|
|
|
positioned,
|
2023-09-05 11:13:27 +02:00
|
|
|
type: vertex.type,
|
|
|
|
// props: vertex.props,
|
|
|
|
padding: getConfig()?.flowchart?.padding || 0,
|
|
|
|
};
|
|
|
|
return node;
|
|
|
|
}
|
2023-09-05 15:15:08 +02:00
|
|
|
type IOperation = (elem: any, block: any, db: any) => Promise<void>;
|
2023-09-05 11:13:27 +02:00
|
|
|
async function calculateBlockSize(elem: any, block: any, db: any) {
|
2023-09-05 15:15:08 +02:00
|
|
|
const node = getNodeFromBlock(block, db, false);
|
2023-10-03 12:56:47 +02:00
|
|
|
if (node.type === 'group') {
|
|
|
|
return;
|
|
|
|
}
|
2023-09-05 11:13:27 +02:00
|
|
|
|
|
|
|
// Add the element to the DOM to size it
|
|
|
|
const nodeEl = await insertNode(elem, node);
|
|
|
|
const boundingBox = nodeEl.node().getBBox();
|
|
|
|
const obj = db.getBlock(node.id);
|
|
|
|
obj.size = { width: boundingBox.width, height: boundingBox.height, x: 0, y: 0, node: nodeEl };
|
2023-09-05 15:15:08 +02:00
|
|
|
console.log('Here boundsíng', boundingBox.width);
|
2023-09-05 11:13:27 +02:00
|
|
|
db.setBlock(obj);
|
2023-09-05 15:15:08 +02:00
|
|
|
nodeEl.remove();
|
2023-09-05 11:13:27 +02:00
|
|
|
}
|
|
|
|
|
2023-09-05 15:15:08 +02:00
|
|
|
export async function insertBlockPositioned(elem: any, block: any, db: any) {
|
|
|
|
console.log('Here insertBlockPositioned');
|
|
|
|
const node = getNodeFromBlock(block, db, true);
|
2023-10-03 12:56:47 +02:00
|
|
|
// if (node.type === 'composite') {
|
|
|
|
// return;
|
|
|
|
// }
|
2023-09-05 15:15:08 +02:00
|
|
|
// Add the element to the DOM to size it
|
|
|
|
const obj = db.getBlock(node.id);
|
|
|
|
const nodeEl = await insertNode(elem, node);
|
2023-09-14 10:11:43 +02:00
|
|
|
positionNode(node);
|
2023-09-05 15:15:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export async function performOperations(
|
|
|
|
elem: ContainerElement,
|
|
|
|
blocks: Block[],
|
|
|
|
db: BlockDB,
|
|
|
|
operation: IOperation
|
|
|
|
) {
|
2023-09-05 11:13:27 +02:00
|
|
|
for (const block of blocks) {
|
2023-09-05 15:15:08 +02:00
|
|
|
await operation(elem, block, db);
|
2023-09-05 11:13:27 +02:00
|
|
|
if (block.children) {
|
2023-09-05 15:15:08 +02:00
|
|
|
await performOperations(elem, block.children, db, operation);
|
2023-09-05 11:13:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-05 15:15:08 +02:00
|
|
|
export async function calculateBlockSizes(elem: ContainerElement, blocks: Block[], db: BlockDB) {
|
|
|
|
await performOperations(elem, blocks, db, calculateBlockSize);
|
|
|
|
}
|
2023-09-05 11:13:27 +02:00
|
|
|
|
2023-09-05 15:15:08 +02:00
|
|
|
export async function insertBlocks(elem: ContainerElement, blocks: Block[], db: BlockDB) {
|
|
|
|
await performOperations(elem, blocks, db, insertBlockPositioned);
|
2023-09-05 11:13:27 +02:00
|
|
|
}
|