Skip to content

Commit

Permalink
Merge pull request #4268 from Valentine14th/bug/4023-image-rendering
Browse files Browse the repository at this point in the history
fix: image rendering in nodes
  • Loading branch information
jgreywolf authored Apr 10, 2023
2 parents f08778d + 9bb0cef commit 727bf30
Show file tree
Hide file tree
Showing 11 changed files with 354 additions and 292 deletions.
10 changes: 10 additions & 0 deletions cypress/integration/rendering/flowchart-v2.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,16 @@ A ~~~ B
{ titleTopMargin: 0 }
);
});
it('4023: Should render html labels with images and-or text correctly', () => {
imgSnapshotTest(
`flowchart TD
B[<img src='https://mermaid.js.org/mermaid-logo.svg'>]
B-->C[<img src="https://mermaid.js.org/mermaid-logo.svg"> more text <img src='https://mermaid.js.org/mermaid-logo.svg'>]
B-->D(<img src='https://mermaid.js.org/mermaid-logo.svg'> some text)
B-->E(plain)`,
{}
);
});
describe('Markdown strings flowchart (#4220)', () => {
describe('html labels', () => {
it('With styling and classes', () => {
Expand Down
2 changes: 1 addition & 1 deletion docs/config/setup/modules/mermaidAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ mermaid.initialize(config);

#### Defined in

[mermaidAPI.ts:667](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L667)
[mermaidAPI.ts:673](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L673)

## Functions

Expand Down
76 changes: 39 additions & 37 deletions packages/mermaid/src/dagre-wrapper/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { insertCluster, clear as clearClusters } from './clusters';
import { insertEdgeLabel, positionEdgeLabel, insertEdge, clear as clearEdges } from './edges';
import { log } from '../logger';

const recursiveRender = (_elem, graph, diagramtype, parentCluster) => {
const recursiveRender = async (_elem, graph, diagramtype, parentCluster) => {
log.info('Graph in recursive render: XXX', graphlibJson.write(graph), parentCluster);
const dir = graph.graph().rankdir;
log.trace('Dir in recursive render - dir:', dir);
Expand All @@ -35,44 +35,46 @@ const recursiveRender = (_elem, graph, diagramtype, parentCluster) => {

// Insert nodes, this will insert them into the dom and each node will get a size. The size is updated
// to the abstract node and is later used by dagre for the layout
graph.nodes().forEach(function (v) {
const node = graph.node(v);
if (parentCluster !== undefined) {
const data = JSON.parse(JSON.stringify(parentCluster.clusterData));
// data.clusterPositioning = true;
log.info('Setting data for cluster XXX (', v, ') ', data, parentCluster);
graph.setNode(parentCluster.id, data);
if (!graph.parent(v)) {
log.trace('Setting parent', v, parentCluster.id);
graph.setParent(v, parentCluster.id, data);
await Promise.all(
graph.nodes().map(async function (v) {
const node = graph.node(v);
if (parentCluster !== undefined) {
const data = JSON.parse(JSON.stringify(parentCluster.clusterData));
// data.clusterPositioning = true;
log.info('Setting data for cluster XXX (', v, ') ', data, parentCluster);
graph.setNode(parentCluster.id, data);
if (!graph.parent(v)) {
log.trace('Setting parent', v, parentCluster.id);
graph.setParent(v, parentCluster.id, data);
}
}
}
log.info('(Insert) Node XXX' + v + ': ' + JSON.stringify(graph.node(v)));
if (node && node.clusterNode) {
// const children = graph.children(v);
log.info('Cluster identified', v, node.width, graph.node(v));
const o = recursiveRender(nodes, node.graph, diagramtype, graph.node(v));
const newEl = o.elem;
updateNodeBounds(node, newEl);
node.diff = o.diff || 0;
log.info('Node bounds (abc123)', v, node, node.width, node.x, node.y);
setNodeElem(newEl, node);
log.info('(Insert) Node XXX' + v + ': ' + JSON.stringify(graph.node(v)));
if (node && node.clusterNode) {
// const children = graph.children(v);
log.info('Cluster identified', v, node.width, graph.node(v));
const o = await recursiveRender(nodes, node.graph, diagramtype, graph.node(v));
const newEl = o.elem;
updateNodeBounds(node, newEl);
node.diff = o.diff || 0;
log.info('Node bounds (abc123)', v, node, node.width, node.x, node.y);
setNodeElem(newEl, node);

log.warn('Recursive render complete ', newEl, node);
} else {
if (graph.children(v).length > 0) {
// This is a cluster but not to be rendered recursively
// Render as before
log.info('Cluster - the non recursive path XXX', v, node.id, node, graph);
log.info(findNonClusterChild(node.id, graph));
clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node };
// insertCluster(clusters, graph.node(v));
log.warn('Recursive render complete ', newEl, node);
} else {
log.info('Node - the non recursive path', v, node.id, node);
insertNode(nodes, graph.node(v), dir);
if (graph.children(v).length > 0) {
// This is a cluster but not to be rendered recursively
// Render as before
log.info('Cluster - the non recursive path XXX', v, node.id, node, graph);
log.info(findNonClusterChild(node.id, graph));
clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node };
// insertCluster(clusters, graph.node(v));
} else {
log.info('Node - the non recursive path', v, node.id, node);
await insertNode(nodes, graph.node(v), dir);
}
}
}
});
})
);

// Insert labels, this will insert them into the dom so that the width can be calculated
// Also figure out which edges point to/from clusters and adjust them accordingly
Expand Down Expand Up @@ -146,7 +148,7 @@ const recursiveRender = (_elem, graph, diagramtype, parentCluster) => {
return { elem, diff };
};

export const render = (elem, graph, markers, diagramtype, id) => {
export const render = async (elem, graph, markers, diagramtype, id) => {
insertMarkers(elem, markers, diagramtype, id);
clearNodes();
clearEdges();
Expand All @@ -157,7 +159,7 @@ export const render = (elem, graph, markers, diagramtype, id) => {
adjustClustersAndEdges(graph);
log.warn('Graph after:', graphlibJson.write(graph));
// log.warn('Graph ever after:', graphlibJson.write(graph.node('A').graph));
recursiveRender(elem, graph, diagramtype);
await recursiveRender(elem, graph, diagramtype);
};

// const shapeDefinitions = {};
Expand Down
72 changes: 39 additions & 33 deletions packages/mermaid/src/dagre-wrapper/nodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import note from './shapes/note';
import { parseMember } from '../diagrams/class/svgDraw';
import { evaluate } from '../diagrams/common/common';

const question = (parent, node) => {
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
const question = async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);

const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
Expand Down Expand Up @@ -69,8 +69,8 @@ const choice = (parent, node) => {
return shapeSvg;
};

const hexagon = (parent, node) => {
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
const hexagon = async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);

const f = 4;
const h = bbox.height + node.padding;
Expand All @@ -96,8 +96,8 @@ const hexagon = (parent, node) => {
return shapeSvg;
};

const rect_left_inv_arrow = (parent, node) => {
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
const rect_left_inv_arrow = async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);

const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
Expand All @@ -122,8 +122,8 @@ const rect_left_inv_arrow = (parent, node) => {
return shapeSvg;
};

const lean_right = (parent, node) => {
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
const lean_right = async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);

const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
Expand All @@ -145,8 +145,8 @@ const lean_right = (parent, node) => {
return shapeSvg;
};

const lean_left = (parent, node) => {
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
const lean_left = async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);

const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
Expand All @@ -168,8 +168,8 @@ const lean_left = (parent, node) => {
return shapeSvg;
};

const trapezoid = (parent, node) => {
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
const trapezoid = async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);

const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
Expand All @@ -191,8 +191,8 @@ const trapezoid = (parent, node) => {
return shapeSvg;
};

const inv_trapezoid = (parent, node) => {
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
const inv_trapezoid = async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);

const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
Expand All @@ -214,8 +214,8 @@ const inv_trapezoid = (parent, node) => {
return shapeSvg;
};

const rect_right_inv_arrow = (parent, node) => {
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
const rect_right_inv_arrow = async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);

const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
Expand All @@ -238,8 +238,8 @@ const rect_right_inv_arrow = (parent, node) => {
return shapeSvg;
};

const cylinder = (parent, node) => {
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
const cylinder = async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);

const w = bbox.width + node.padding;
const rx = w / 2;
Expand Down Expand Up @@ -310,8 +310,13 @@ const cylinder = (parent, node) => {
return shapeSvg;
};

const rect = (parent, node) => {
const { shapeSvg, bbox, halfPadding } = labelHelper(parent, node, 'node ' + node.classes, true);
const rect = async (parent, node) => {
const { shapeSvg, bbox, halfPadding } = await labelHelper(
parent,
node,
'node ' + node.classes,
true
);

// add the rect
const rect = shapeSvg.insert('rect', ':first-child');
Expand Down Expand Up @@ -352,8 +357,8 @@ const rect = (parent, node) => {
return shapeSvg;
};

const labelRect = (parent, node) => {
const { shapeSvg } = labelHelper(parent, node, 'label', true);
const labelRect = async (parent, node) => {
const { shapeSvg } = await labelHelper(parent, node, 'label', true);

log.trace('Classes = ', node.classes);
// add the rect
Expand Down Expand Up @@ -539,8 +544,8 @@ const rectWithTitle = (parent, node) => {
return shapeSvg;
};

const stadium = (parent, node) => {
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
const stadium = async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);

const h = bbox.height + node.padding;
const w = bbox.width + h / 4 + node.padding;
Expand All @@ -565,8 +570,8 @@ const stadium = (parent, node) => {
return shapeSvg;
};

const circle = (parent, node) => {
const { shapeSvg, bbox, halfPadding } = labelHelper(parent, node, undefined, true);
const circle = async (parent, node) => {
const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, undefined, true);
const circle = shapeSvg.insert('circle', ':first-child');

// center the circle around its coordinate
Expand All @@ -590,8 +595,8 @@ const circle = (parent, node) => {
return shapeSvg;
};

const doublecircle = (parent, node) => {
const { shapeSvg, bbox, halfPadding } = labelHelper(parent, node, undefined, true);
const doublecircle = async (parent, node) => {
const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, undefined, true);
const gap = 5;
const circleGroup = shapeSvg.insert('g', ':first-child');
const outerCircle = circleGroup.insert('circle');
Expand Down Expand Up @@ -626,8 +631,8 @@ const doublecircle = (parent, node) => {
return shapeSvg;
};

const subroutine = (parent, node) => {
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
const subroutine = async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);

const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
Expand Down Expand Up @@ -976,7 +981,7 @@ const shapes = {

let nodeElems = {};

export const insertNode = (elem, node, dir) => {
export const insertNode = async (elem, node, dir) => {
let newEl;
let el;

Expand All @@ -989,9 +994,9 @@ export const insertNode = (elem, node, dir) => {
target = node.linkTarget || '_blank';
}
newEl = elem.insert('svg:a').attr('xlink:href', node.link).attr('target', target);
el = shapes[node.shape](newEl, node, dir);
el = await shapes[node.shape](newEl, node, dir);
} else {
el = shapes[node.shape](elem, node, dir);
el = await shapes[node.shape](elem, node, dir);
newEl = el;
}
if (node.tooltip) {
Expand All @@ -1017,6 +1022,7 @@ export const clear = () => {

export const positionNode = (node) => {
const el = nodeElems[node.id];

log.trace(
'Transforming node',
node.diff,
Expand Down
9 changes: 7 additions & 2 deletions packages/mermaid/src/dagre-wrapper/shapes/note.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ import { log } from '../../logger';
import { getConfig } from '../../config';
import intersect from '../intersect/index.js';

const note = (parent, node) => {
const note = async (parent, node) => {
const useHtmlLabels = node.useHtmlLabels || getConfig().flowchart.htmlLabels;
if (!useHtmlLabels) {
node.centerLabel = true;
}
const { shapeSvg, bbox, halfPadding } = labelHelper(parent, node, 'node ' + node.classes, true);
const { shapeSvg, bbox, halfPadding } = await labelHelper(
parent,
node,
'node ' + node.classes,
true
);

log.info('Classes = ', node.classes);
// add the rect
Expand Down
Loading

0 comments on commit 727bf30

Please sign in to comment.