#5237 passing cssStyles and cssCompiled style arrays

This commit is contained in:
Knut Sveidqvist 2024-06-17 15:42:45 +02:00
parent 5bd3a28667
commit a6f3316ddb
8 changed files with 255 additions and 52 deletions

View File

@ -54,21 +54,39 @@ export function stateDomId(itemId = '', counter = 0, type = '', typeSpacer = DOM
return `${DOMID_STATE}-${itemId}${typeStr}-${counter}`; return `${DOMID_STATE}-${itemId}${typeStr}-${counter}`;
} }
const setupDoc = (parentParsedItem, doc, diagramStates, nodes, edges, altFlag, look) => { const setupDoc = (parentParsedItem, doc, diagramStates, nodes, edges, altFlag, look, classes) => {
// graphItemCount = 0; // graphItemCount = 0;
log.trace('items', doc); log.trace('items', doc);
doc.forEach((item) => { doc.forEach((item) => {
switch (item.stmt) { switch (item.stmt) {
case STMT_STATE: case STMT_STATE:
dataFetcher(parentParsedItem, item, diagramStates, nodes, edges, altFlag, look); dataFetcher(parentParsedItem, item, diagramStates, nodes, edges, altFlag, look, classes);
break; break;
case DEFAULT_STATE_TYPE: case DEFAULT_STATE_TYPE:
dataFetcher(parentParsedItem, item, diagramStates, nodes, edges, altFlag, look); dataFetcher(parentParsedItem, item, diagramStates, nodes, edges, altFlag, look, classes);
break; break;
case STMT_RELATION: case STMT_RELATION:
{ {
dataFetcher(parentParsedItem, item.state1, diagramStates, nodes, edges, altFlag, look); dataFetcher(
dataFetcher(parentParsedItem, item.state2, diagramStates, nodes, edges, altFlag, look); parentParsedItem,
item.state1,
diagramStates,
nodes,
edges,
altFlag,
look,
classes
);
dataFetcher(
parentParsedItem,
item.state2,
diagramStates,
nodes,
edges,
altFlag,
look,
classes
);
const edgeData = { const edgeData = {
id: 'edge' + graphItemCount, id: 'edge' + graphItemCount,
start: item.state1.id, start: item.state1.id,
@ -135,7 +153,7 @@ let cssClasses = newClassesList(); // style classes defined by a classDef
* @param nodes * @param nodes
* @param nodeData * @param nodeData
*/ */
function insertOrUpdateNode(nodes, nodeData) { function insertOrUpdateNode(nodes, nodeData, classes) {
if (!nodeData.id || nodeData.id === '</join></fork>' || nodeData.id === '</choice>') { if (!nodeData.id || nodeData.id === '</join></fork>' || nodeData.id === '</choice>') {
return; return;
} }
@ -143,29 +161,62 @@ function insertOrUpdateNode(nodes, nodeData) {
//Populate node style attributes if nodeData has classes defined //Populate node style attributes if nodeData has classes defined
if (nodeData.cssClasses) { if (nodeData.cssClasses) {
nodeData.cssClasses.split(' ').forEach((cssClass) => { nodeData.cssClasses.split(' ').forEach((cssClass) => {
if (cssClasses[cssClass]) { if (classes.get(cssClass)) {
cssClasses[cssClass].styles.forEach((style) => { const classDef = classes.get(cssClass);
// Populate nodeData with style attributes specifically to be used by rough.js // classDef.styles.forEach((style) => {
if (style && style.startsWith('fill:')) { // nodeData.cssCompiledStyles += style + ',';
nodeData.backgroundColor = style.replace('fill:', ''); // // Populate nodeData with style attributes specifically to be used by rough.js
} // if (style && style.startsWith('fill:')) {
if (style && style.startsWith('stroke:')) { // nodeData.backgroundColor = style.replace('fill:', '');
nodeData.borderColor = style.replace('stroke:', ''); // }
} // if (style && style.startsWith('stroke:')) {
if (style && style.startsWith('stroke-width:')) { // nodeData.borderColor = style.replace('stroke:', '');
nodeData.borderWidth = style.replace('stroke-width:', ''); // }
} // if (style && style.startsWith('stroke-width:')) {
// nodeData.borderWidth = style.replace('stroke-width:', '');
// }
nodeData.cssStyles += style + ';'; // nodeData.cssStyles += style + ';';
}); // });
cssClasses[cssClass].textStyles.forEach((style) => {
nodeData.labelStyle += style + ';'; // classDef.textStyles.forEach((style) => {
if (style && style.startsWith('fill:')) { // nodeData.labelStyle += style + ';';
nodeData.labelTextColor = style.replace('fill:', ''); // if (style && style.startsWith('fill:')) {
} // nodeData.labelTextColor = style.replace('fill:', '');
}); // }
// });
nodeData.cssCompiledStyles = [...nodeData.cssCompiledStyles, ...classDef.styles];
} }
}); });
//Populate node style attributes if nodeData has classes defined
if (nodeData.cssStyles) {
// nodeData.cssStyles.split(' ').forEach((csStyle) => {
// if (classes[cssClass]) {
// classes[cssClass].styles.forEach((style) => {
// // Populate nodeData with style attributes specifically to be used by rough.js
// if (style && style.startsWith('fill:')) {
// nodeData.backgroundColor = style.replace('fill:', '');
// }
// if (style && style.startsWith('stroke:')) {
// nodeData.borderColor = style.replace('stroke:', '');
// }
// if (style && style.startsWith('stroke-width:')) {
// nodeData.borderWidth = style.replace('stroke-width:', '');
// }
// nodeData.cssStyles += style + ';';
// });
// classes[cssClass].textStyles.forEach((style) => {
// nodeData.labelStyle += style + ';';
// if (style && style.startsWith('fill:')) {
// nodeData.labelTextColor = style.replace('fill:', '');
// }
// });
// }
// });
}
// nodeData.labelTextColor = '#ffffff';
// nodeData.labelStyle = 'color:#ffffff';
// nodeData.cssStyles = 'fill:#f77';
} }
const existingNodeData = nodes.find((node) => node.id === nodeData.id); const existingNodeData = nodes.find((node) => node.id === nodeData.id);
if (existingNodeData) { if (existingNodeData) {
@ -197,7 +248,7 @@ function getClassesFromDbInfo(dbInfoItem) {
} }
//add comma for all other classes //add comma for all other classes
else { else {
classStr += dbInfoItem.classes[i] + ' '; classStr += dbInfoItem.classes[i] + ',';
} }
} }
return classStr; return classStr;
@ -206,9 +257,41 @@ function getClassesFromDbInfo(dbInfoItem) {
} }
} }
} }
export const dataFetcher = (parent, parsedItem, diagramStates, nodes, edges, altFlag, look) => { /**
* Get classes from the db for the info item.
* If there aren't any or if dbInfoItem isn't defined, return an empty string.
* Else create 1 string from the list of classes found
*
* @param {undefined | null | object} dbInfoItem
* @returns {string}
*/
function getStylesFromDbInfo(dbInfoItem) {
if (dbInfoItem === undefined || dbInfoItem === null) {
return;
} else {
if (dbInfoItem.styles) {
return dbInfoItem.styles;
} else {
return [];
}
}
}
export const dataFetcher = (
parent,
parsedItem,
diagramStates,
nodes,
edges,
altFlag,
look,
classes
) => {
const itemId = parsedItem.id; const itemId = parsedItem.id;
const classStr = getClassesFromDbInfo(diagramStates.get(itemId)); const dbState = diagramStates.get(itemId);
const classStr = getClassesFromDbInfo(dbState);
const style = getStylesFromDbInfo(dbState);
log.info('dataFetcher parsedItem', parsedItem, dbState, style);
if (itemId !== 'root') { if (itemId !== 'root') {
let shape = SHAPE_STATE; let shape = SHAPE_STATE;
@ -229,6 +312,7 @@ export const dataFetcher = (parent, parsedItem, diagramStates, nodes, edges, alt
shape, shape,
description: common.sanitizeText(itemId, getConfig()), description: common.sanitizeText(itemId, getConfig()),
cssClasses: `${classStr} ${CSS_DIAGRAM_STATE}`, cssClasses: `${classStr} ${CSS_DIAGRAM_STATE}`,
cssStyles: style,
}; };
} }
@ -287,7 +371,8 @@ export const dataFetcher = (parent, parsedItem, diagramStates, nodes, edges, alt
shape: newNode.shape, shape: newNode.shape,
label: newNode.description, label: newNode.description,
cssClasses: newNode.cssClasses, cssClasses: newNode.cssClasses,
cssStyles: '', cssCompiledStyles: [],
cssStyles: newNode.cssStyles,
id: itemId, id: itemId,
dir: newNode.dir, dir: newNode.dir,
domId: stateDomId(itemId, graphItemCount), domId: stateDomId(itemId, graphItemCount),
@ -319,7 +404,8 @@ export const dataFetcher = (parent, parsedItem, diagramStates, nodes, edges, alt
label: parsedItem.note.text, label: parsedItem.note.text,
cssClasses: CSS_DIAGRAM_NOTE, cssClasses: CSS_DIAGRAM_NOTE,
// useHtmlLabels: false, // useHtmlLabels: false,
cssStyles: '', // styles.style, cssStyles: [],
cssCompilesStyles: [],
id: itemId + NOTE_ID + '-' + graphItemCount, id: itemId + NOTE_ID + '-' + graphItemCount,
domId: stateDomId(itemId, graphItemCount, NOTE), domId: stateDomId(itemId, graphItemCount, NOTE),
type: newNode.type, type: newNode.type,
@ -334,7 +420,7 @@ export const dataFetcher = (parent, parsedItem, diagramStates, nodes, edges, alt
shape: SHAPE_NOTEGROUP, shape: SHAPE_NOTEGROUP,
label: parsedItem.note.text, label: parsedItem.note.text,
cssClasses: newNode.cssClasses, cssClasses: newNode.cssClasses,
cssStyles: '', // styles.style, cssStyles: [],
id: itemId + PARENT_ID, id: itemId + PARENT_ID,
domId: stateDomId(itemId, graphItemCount, PARENT), domId: stateDomId(itemId, graphItemCount, PARENT),
type: 'group', type: 'group',
@ -352,11 +438,11 @@ export const dataFetcher = (parent, parsedItem, diagramStates, nodes, edges, alt
nodeData.parentId = parentNodeId; nodeData.parentId = parentNodeId;
//insert groupData //insert groupData
insertOrUpdateNode(nodes, groupData); insertOrUpdateNode(nodes, groupData, classes);
//insert noteData //insert noteData
insertOrUpdateNode(nodes, noteData); insertOrUpdateNode(nodes, noteData, classes);
//insert nodeData //insert nodeData
insertOrUpdateNode(nodes, nodeData); insertOrUpdateNode(nodes, nodeData, classes);
let from = itemId; let from = itemId;
let to = noteData.id; let to = noteData.id;
@ -382,12 +468,12 @@ export const dataFetcher = (parent, parsedItem, diagramStates, nodes, edges, alt
look, look,
}); });
} else { } else {
insertOrUpdateNode(nodes, nodeData); insertOrUpdateNode(nodes, nodeData, classes);
} }
} }
if (parsedItem.doc) { if (parsedItem.doc) {
log.trace('Adding nodes children '); log.trace('Adding nodes children ');
setupDoc(parsedItem, parsedItem.doc, diagramStates, nodes, edges, !altFlag, look); setupDoc(parsedItem, parsedItem.doc, diagramStates, nodes, edges, !altFlag, look, classes);
} }
}; };

View File

@ -217,4 +217,45 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
}); });
}); });
}); });
describe('style statement for a state (style)', () => {
describe('defining (style)', () => {
it('has "style" as a keyword, an id, and can set a css style attribute', function () {
stateDiagram.parser.parse(`
stateDiagram-v2
style id1 background:#bbb;`);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
// const styleClasses = stateDb.getClasses();
// expect(styleClasses.get('exampleClass').styles.length).toEqual(1);
// expect(styleClasses.get('exampleClass').styles[0]).toEqual('background:#bbb');
});
it('has handles multiple ids', function () {
stateDiagram.parser.parse(`
stateDiagram-v2
style id1,id2 background:#bbb;`);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
// const styleClasses = stateDb.getClasses();
// expect(styleClasses.get('exampleClass').styles.length).toEqual(1);
// expect(styleClasses.get('exampleClass').styles[0]).toEqual('background:#bbb');
});
// it('can define multiple attributes separated by commas', function () {
// stateDiagram.parser.parse(
// 'stateDiagram-v2\n classDef exampleClass background:#bbb, font-weight:bold, font-style:italic;'
// );
// stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
// const styleClasses = stateDb.getClasses();
// expect(styleClasses.get('exampleClass').styles.length).toEqual(3);
// expect(styleClasses.get('exampleClass').styles[0]).toEqual('background:#bbb');
// expect(styleClasses.get('exampleClass').styles[1]).toEqual('font-weight:bold');
// expect(styleClasses.get('exampleClass').styles[2]).toEqual('font-style:italic');
// });
});
});
}); });

View File

@ -27,6 +27,13 @@
%x CLASSDEFID %x CLASSDEFID
%x CLASS %x CLASS
%x CLASS_STYLE %x CLASS_STYLE
// Style statement states
%x STYLE
%x STYLE_IDS
%x STYLEDEF_STYLES
%x STYLEDEF_STYLEOPTS
%x NOTE %x NOTE
%x NOTE_ID %x NOTE_ID
%x NOTE_TEXT %x NOTE_TEXT
@ -75,6 +82,10 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
<CLASS>(\w+)+((","\s*\w+)*) { this.popState(); this.pushState('CLASS_STYLE'); return 'CLASSENTITY_IDS' } <CLASS>(\w+)+((","\s*\w+)*) { this.popState(); this.pushState('CLASS_STYLE'); return 'CLASSENTITY_IDS' }
<CLASS_STYLE>[^\n]* { this.popState(); return 'STYLECLASS' } <CLASS_STYLE>[^\n]* { this.popState(); return 'STYLECLASS' }
<INITIAL,struct>"style"\s+ { this.pushState('STYLE'); return 'style'; }
<STYLE>[\w,]+\s+ { this.popState(); this.pushState('STYLEDEF_STYLES'); return 'STYLE_IDS' }
<STYLEDEF_STYLES>[^\n]* { this.popState(); return 'STYLEDEF_STYLEOPTS' }
"scale"\s+ { this.pushState('SCALE'); /* console.log('Got scale', yytext);*/ return 'scale'; } "scale"\s+ { this.pushState('SCALE'); /* console.log('Got scale', yytext);*/ return 'scale'; }
<SCALE>\d+ return 'WIDTH'; <SCALE>\d+ return 'WIDTH';
<SCALE>\s+"width" {this.popState();} <SCALE>\s+"width" {this.popState();}
@ -168,6 +179,7 @@ line
statement statement
: classDefStatement : classDefStatement
| styleStatement
| cssClassStatement | cssClassStatement
| idStatement { /* console.log('got id', $1); */ | idStatement { /* console.log('got id', $1); */
$$=$1; $$=$1;
@ -246,6 +258,12 @@ classDefStatement
} }
; ;
styleStatement
: style STYLE_IDS STYLEDEF_STYLEOPTS {
$$ = { stmt: 'style', id: $2.trim(), styleClass: $3.trim() };
}
;
cssClassStatement cssClassStatement
: class CLASSENTITY_IDS STYLECLASS { : class CLASSENTITY_IDS STYLECLASS {
//console.log('apply class: id(s): ',$2, ' style class: ', $3); //console.log('apply class: id(s): ',$2, ' style class: ', $3);

View File

@ -14,6 +14,7 @@ export const STMT_STATE = 'state';
export const STMT_RELATION = 'relation'; export const STMT_RELATION = 'relation';
// parsed statement type for a classDef // parsed statement type for a classDef
export const STMT_CLASSDEF = 'classDef'; export const STMT_CLASSDEF = 'classDef';
export const STMT_STYLEDEF = 'style';
// parsed statement type for applyClass // parsed statement type for applyClass
export const STMT_APPLYCLASS = 'applyClass'; export const STMT_APPLYCLASS = 'applyClass';
@ -64,6 +65,7 @@ export default {
STMT_STATE, STMT_STATE,
STMT_RELATION, STMT_RELATION,
STMT_CLASSDEF, STMT_CLASSDEF,
STMT_STYLEDEF,
STMT_APPLYCLASS, STMT_APPLYCLASS,
DEFAULT_STATE_TYPE, DEFAULT_STATE_TYPE,
DIVIDER_TYPE, DIVIDER_TYPE,

View File

@ -18,6 +18,7 @@ import {
STMT_STATE, STMT_STATE,
STMT_RELATION, STMT_RELATION,
STMT_CLASSDEF, STMT_CLASSDEF,
STMT_STYLEDEF,
STMT_APPLYCLASS, STMT_APPLYCLASS,
DEFAULT_STATE_TYPE, DEFAULT_STATE_TYPE,
DIVIDER_TYPE, DIVIDER_TYPE,
@ -171,9 +172,10 @@ const extract = (_doc) => {
log.info(doc); log.info(doc);
clear(true); clear(true);
log.info('Extract', doc); log.info('Extract initial document:', doc);
doc.forEach((item) => { doc.forEach((item) => {
log.warn('Statement', item.stmt);
switch (item.stmt) { switch (item.stmt) {
case STMT_STATE: case STMT_STATE:
addState( addState(
@ -193,8 +195,20 @@ const extract = (_doc) => {
case STMT_CLASSDEF: case STMT_CLASSDEF:
addStyleClass(item.id.trim(), item.classes); addStyleClass(item.id.trim(), item.classes);
break; break;
case STMT_STYLEDEF:
{
const ids = item.id.trim().split(',');
const styles = item.styleClass.split(',');
ids.forEach((id) => {
const state = getState(id);
if (state !== undefined) {
state.styles = styles;
}
});
}
break;
case STMT_APPLYCLASS: case STMT_APPLYCLASS:
setCssClass(item.id.trim(), item.styleClass); setStyle(item.id.trim(), item.styleClass);
break; break;
} }
}); });
@ -203,7 +217,7 @@ const extract = (_doc) => {
const config = getConfig(); const config = getConfig();
const look = config.look; const look = config.look;
resetDataFetching(); resetDataFetching();
dataFetcher(undefined, getRootDocV2(), diagramStates, nodes, edges, true, look); dataFetcher(undefined, getRootDocV2(), diagramStates, nodes, edges, true, look, classes);
nodes.forEach((node) => { nodes.forEach((node) => {
if (Array.isArray(node.label)) { if (Array.isArray(node.label)) {
// add the rest as description // add the rest as description
@ -538,7 +552,7 @@ export const setCssClass = function (itemIds, cssClassName) {
export const setStyle = function (itemId, styleText) { export const setStyle = function (itemId, styleText) {
const item = getState(itemId); const item = getState(itemId);
if (item !== undefined) { if (item !== undefined) {
item.textStyles.push(styleText); item.styles.push(styleText);
} }
}; };

View File

@ -2,13 +2,18 @@ import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js';
import intersect from '../intersect/index.js'; import intersect from '../intersect/index.js';
import type { Node, RectOptions } from '$root/rendering-util/types.d.ts'; import type { Node, RectOptions } from '$root/rendering-util/types.d.ts';
import { createRoundedRectPathD } from './roundedRectPath.js'; import { createRoundedRectPathD } from './roundedRectPath.js';
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js'; import {
userNodeOverrides,
styles2String,
} 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'; import { getConfig } from '$root/diagram-api/diagramAPI.js';
import { log } from '$root/logger.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 { look } = getConfig();
const { labelStyles, nodeStyles } = styles2String(node);
node.labelStyle = labelStyles;
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
const totalWidth = Math.max(bbox.width + options.labelPaddingX * 2, node?.width || 0); const totalWidth = Math.max(bbox.width + options.labelPaddingX * 2, node?.width || 0);
@ -16,6 +21,8 @@ export const drawRect = async (parent: SVGAElement, node: Node, options: RectOpt
const x = -totalWidth / 2; const x = -totalWidth / 2;
const y = -totalHeight / 2; const y = -totalHeight / 2;
log.info('IPI node = ', node);
let rect; let rect;
node.look = look; node.look = look;
let { rx, ry } = node; let { rx, ry } = node;
@ -44,7 +51,7 @@ export const drawRect = async (parent: SVGAElement, node: Node, options: RectOpt
rect rect
.attr('class', 'basic label-container') .attr('class', 'basic label-container')
.attr('style', cssStyles) .attr('style', nodeStyles)
.attr('rx', rx) .attr('rx', rx)
.attr('data-id', 'abc') .attr('data-id', 'abc')
.attr('data-et', 'node') .attr('data-et', 'node')

View File

@ -1,5 +1,6 @@
import { getConfig } from '$root/diagram-api/diagramAPI.js'; import { getConfig } from '$root/diagram-api/diagramAPI.js';
import type { Node } from '$root/rendering-util/types.d.ts'; import type { Node } from '$root/rendering-util/types.d.ts';
import styles from '../../../../dist/diagrams/packet/styles';
// Striped fill like start or fork nodes in state diagrams // Striped fill like start or fork nodes in state diagrams
export const solidStateFill = (color: string) => { export const solidStateFill = (color: string) => {
@ -15,28 +16,61 @@ export const solidStateFill = (color: string) => {
}; };
}; };
export const compileStyles = (node: Node) => {
// node.cssCompiledStyles is an array of strings in the form of 'key: value' where jey is the css property and value is the value
// the array is the styles of node node from the classes it is using
// node.cssStyles is an array of styles directly set on the node
// concat the arrays and remove duplicates such that the values from node.cssStyles are used if there are duplicates
return [...(node.cssCompiledStyles || []), ...(node.cssStyles || [])];
};
export const styles2Map = (styles: string[]) => {
const styleMap = new Map();
styles.forEach((style) => {
const [key, value] = style.split(':');
styleMap.set(key.trim(), value.trim());
});
return styleMap;
};
export const styles2String = (node: Node) => {
const styles = compileStyles(node);
const labelStyles: string[] = [];
const nodeStyles: string[] = [];
styles.forEach((style) => {
const [key, value] = style.split(':');
if (key === 'color') {
labelStyles.push(style);
} else {
nodeStyles.push(style);
}
});
return { labelStyles: labelStyles.join(';'), nodeStyles: nodeStyles.join(';') };
};
// Striped fill like start or fork nodes in state diagrams // Striped fill like start or fork nodes in state diagrams
// TODO remove any // TODO remove any
export const userNodeOverrides = (node: Node, options: any) => { export const userNodeOverrides = (node: Node, options: any) => {
const { themeVariables, handdrawnSeed } = getConfig(); const { themeVariables, handdrawnSeed } = getConfig();
const { nodeBorder, mainBkg } = themeVariables; const { nodeBorder, mainBkg } = themeVariables;
const styles = compileStyles(node);
// index the style array to a map object
const styleMap = styles2Map(styles);
const result = Object.assign( const result = Object.assign(
{ {
roughness: 0.7, roughness: 0.7,
fill: mainBkg, fill: styleMap.get('fill') || mainBkg,
fillStyle: 'hachure', // solid fill fillStyle: 'hachure', // solid fill
fillWeight: 3.5, fillWeight: 3.5,
stroke: nodeBorder, stroke: styleMap.get('stroke') || nodeBorder,
seed: handdrawnSeed, seed: handdrawnSeed,
strokeWidth: 1.3, strokeWidth: 1.3,
}, },
options options
); );
if (node.backgroundColor) {
result.fill = node.backgroundColor;
}
if (node.borderColor) {
result.stroke = node.borderColor;
}
return result; return result;
}; };

View File

@ -35,6 +35,7 @@ export const labelHelper = async (parent, node, _classes) => {
useHtmlLabels, useHtmlLabels,
width: node.width || getConfig().flowchart.wrappingWidth, width: node.width || getConfig().flowchart.wrappingWidth,
cssClasses: 'markdown-node-label', cssClasses: 'markdown-node-label',
style: node.labelStyle,
}); });
// Get the size of the label // Get the size of the label
let bbox = text.getBBox(); let bbox = text.getBBox();