mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-28 07:03:17 +08:00
#1295 Recursive rendering, draft
This commit is contained in:
parent
8455db6fae
commit
22e17172dd
@ -70,7 +70,7 @@
|
||||
Moving --> Crash
|
||||
Crash --> [*]
|
||||
</div>
|
||||
<div class="mermaid" style="width: 100%; height: 100%;">
|
||||
<div class="mermaid2" style="width: 100%; height: 100%;">
|
||||
stateDiagram-v2
|
||||
[*] --> First
|
||||
First --> Second
|
||||
@ -84,6 +84,12 @@ stateDiagram-v2
|
||||
[*] --> sec
|
||||
sec --> [*]
|
||||
}
|
||||
</div>
|
||||
<div class="mermaid" style="width: 100%; height: 100%;">
|
||||
flowchart TD
|
||||
subgraph Apa
|
||||
a --> b
|
||||
end
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 100%;">
|
||||
stateDiagram-v2
|
||||
|
@ -1,8 +1,10 @@
|
||||
import intersectRect from './intersect/intersect-rect';
|
||||
import { logger } from '../logger'; // eslint-disable-line
|
||||
import { logger as log } from '../logger'; // eslint-disable-line
|
||||
import createLabel from './createLabel';
|
||||
|
||||
const rect = (parent, node) => {
|
||||
log.info('Creating subgraph rect for ', node.id, node);
|
||||
|
||||
// Add outer g element
|
||||
const shapeSvg = parent
|
||||
.insert('g')
|
||||
@ -22,7 +24,10 @@ const rect = (parent, node) => {
|
||||
|
||||
const padding = 0 * node.padding;
|
||||
const halfPadding = padding / 2;
|
||||
const width = node.width || 50;
|
||||
const height = node.height || 50;
|
||||
|
||||
log.info('Data ', node, JSON.stringify(node));
|
||||
// center the rect around its coordinate
|
||||
rect
|
||||
.attr('rx', node.rx)
|
||||
@ -32,7 +37,7 @@ const rect = (parent, node) => {
|
||||
.attr('width', node.width + padding)
|
||||
.attr('height', node.height + padding);
|
||||
|
||||
// logger.info('bbox', bbox.width, node.x, node.width);
|
||||
// log.info('bbox', bbox.width, node.x, node.width);
|
||||
// Center the label
|
||||
// label.attr('transform', 'translate(' + adj + ', ' + (node.y - node.height / 2) + ')');
|
||||
label.attr(
|
||||
@ -127,7 +132,7 @@ const roundedWithTitle = (parent, node) => {
|
||||
.attr('width', node.width + padding)
|
||||
.attr('height', node.height + padding - bbox.height - 3);
|
||||
|
||||
// logger.info('bbox', bbox.width, node.x, node.width);
|
||||
// log.info('bbox', bbox.width, node.x, node.width);
|
||||
// Center the label
|
||||
// label.attr('transform', 'translate(' + adj + ', ' + (node.y - node.height / 2) + ')');
|
||||
label.attr(
|
||||
@ -155,7 +160,9 @@ const shapes = { rect, roundedWithTitle, noteGroup };
|
||||
let clusterElems = {};
|
||||
|
||||
export const insertCluster = (elem, node) => {
|
||||
clusterElems[node.id] = shapes[node.shape](elem, node);
|
||||
log.info('Inserting cluster');
|
||||
const shape = node.shape || 'rect';
|
||||
clusterElems[node.id] = shapes[shape](elem, node);
|
||||
};
|
||||
export const getClusterTitleWidth = (elem, node) => {
|
||||
const label = createLabel(node.labelText, node.labelStyle);
|
||||
@ -170,6 +177,8 @@ export const clear = () => {
|
||||
};
|
||||
|
||||
export const positionCluster = node => {
|
||||
log.info('Position cluster');
|
||||
const el = clusterElems[node.id];
|
||||
|
||||
el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');
|
||||
};
|
||||
|
@ -1,62 +1,38 @@
|
||||
import dagre from 'dagre';
|
||||
import graphlib from 'graphlib';
|
||||
import insertMarkers from './markers';
|
||||
import { clear as cleargraphlib, clusterDb, adjustClustersAndEdges } from './mermaid-graphlib';
|
||||
import { insertNode, positionNode, clear as clearNodes } from './nodes';
|
||||
import { insertCluster, clear as clearClusters } from './clusters';
|
||||
import { updateNodeBounds } from './shapes/util';
|
||||
import {
|
||||
clear as clearGraphlib,
|
||||
clusterDb,
|
||||
adjustClustersAndEdges,
|
||||
findNonClusterChild
|
||||
} from './mermaid-graphlib';
|
||||
import { insertNode, positionNode, clear as clearNodes, setNodeElem } from './nodes';
|
||||
import { insertCluster, clear as clearClusters, positionCluster } from './clusters';
|
||||
import { insertEdgeLabel, positionEdgeLabel, insertEdge, clear as clearEdges } from './edges';
|
||||
import { logger } from '../logger';
|
||||
import { logger as log } from '../logger';
|
||||
|
||||
// let clusterDb = {};
|
||||
|
||||
const getAnchorId = id => {
|
||||
// Only insert an achor once
|
||||
if (clusterDb[id]) {
|
||||
// if (!clusterDb[id].inserted) {
|
||||
// // Create anchor node for cluster
|
||||
// const anchorData = {
|
||||
// shape: 'start',
|
||||
// labelText: '',
|
||||
// classes: '',
|
||||
// style: '',
|
||||
// id: id + '_anchor',
|
||||
// type: 'anchor',
|
||||
// padding: 0
|
||||
// };
|
||||
// insertNode(nodes, anchorData);
|
||||
|
||||
// graph.setNode(anchorData.id, anchorData);
|
||||
// graph.setParent(anchorData.id, id);
|
||||
// clusterDb[id].inserted = true;
|
||||
// }
|
||||
return clusterDb[id].id;
|
||||
}
|
||||
return id;
|
||||
};
|
||||
|
||||
const findNonClusterChild = (id, graph) => {
|
||||
const node = graph.node(id);
|
||||
logger.info('identified node', node);
|
||||
if (node.type !== 'group') {
|
||||
return node.id;
|
||||
const recursiveRender = (_elem, graph, diagramtype) => {
|
||||
const elem = _elem.insert('g').attr('class', 'root'); // eslint-disable-line
|
||||
if (!graph.nodes()) {
|
||||
log.info('No nodes found for', graph);
|
||||
} else {
|
||||
log.info('Recursive render', graph.edges());
|
||||
}
|
||||
logger.info('identified node Not', node.id);
|
||||
const children = graph.children(id);
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const _id = findNonClusterChild(children[i], graph);
|
||||
if (_id) {
|
||||
return _id;
|
||||
}
|
||||
if (graph.edges().length > 0) {
|
||||
log.info('Recursive edges', graph.edge(graph.edges()[0]));
|
||||
}
|
||||
};
|
||||
|
||||
export const render = (elem, graph, markers, diagramtype, id) => {
|
||||
insertMarkers(elem, markers, diagramtype, id);
|
||||
clearNodes();
|
||||
clearEdges();
|
||||
clearClusters();
|
||||
|
||||
adjustClustersAndEdges(graph);
|
||||
|
||||
const clusters = elem.insert('g').attr('class', 'clusters'); // eslint-disable-line
|
||||
const edgePaths = elem.insert('g').attr('class', 'edgePaths');
|
||||
const edgeLabels = elem.insert('g').attr('class', 'edgeLabels');
|
||||
@ -66,81 +42,115 @@ export const render = (elem, graph, markers, diagramtype, id) => {
|
||||
// to the abstract node and is later used by dagre for the layout
|
||||
graph.nodes().forEach(function(v) {
|
||||
const node = graph.node(v);
|
||||
logger.info('Node ' + v + ': ' + JSON.stringify(graph.node(v)));
|
||||
if (node.type !== 'group') {
|
||||
insertNode(nodes, graph.node(v));
|
||||
} else {
|
||||
log.info('(Insert) Node ' + v + ': ' + JSON.stringify(graph.node(v)));
|
||||
if (node.clusterNode) {
|
||||
// const children = graph.children(v);
|
||||
// logger.info('Cluster identified', node.id, children[0], findNonClusterChild(node.id, graph));
|
||||
// clusterDb[node.id] = { id: findNonClusterChild(node.id, graph) };
|
||||
log.info('Cluster identified', v, node, graph.node(v));
|
||||
const newEl = recursiveRender(clusters, node.graph, diagramtype);
|
||||
updateNodeBounds(node, newEl);
|
||||
setNodeElem(newEl, node);
|
||||
|
||||
log.info('Recursice render complete', newEl, node);
|
||||
} else {
|
||||
if (graph.children(v).length > 0) {
|
||||
// This is a cluster but not to be rendered recusively
|
||||
// Render as before
|
||||
log.info('Cluster - the non recursive path', 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);
|
||||
insertNode(nodes, graph.node(v));
|
||||
}
|
||||
}
|
||||
});
|
||||
logger.info('Clusters ', clusterDb);
|
||||
log.info('Clusters ', clusterDb);
|
||||
|
||||
// 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
|
||||
// Edges from/to clusters really points to the first child in the cluster.
|
||||
// TODO: pick optimal child in the cluster to us as link anchor
|
||||
graph.edges().forEach(function(e) {
|
||||
const edge = graph.edge(e);
|
||||
logger.trace('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(e));
|
||||
logger.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(graph.edge(e)));
|
||||
const edge = graph.edge(e.v, e.w, e.name);
|
||||
log.trace('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(e));
|
||||
log.info(
|
||||
'Edge ' + e.v + ' -> ' + e.w + ': ',
|
||||
e,
|
||||
' ',
|
||||
+JSON.stringify(graph.edge(e.v, e.w, e.name))
|
||||
);
|
||||
|
||||
let v = e.v;
|
||||
let w = e.w;
|
||||
// Check if link is either from or to a cluster
|
||||
logger.info(
|
||||
'Fix',
|
||||
clusterDb,
|
||||
'ids:',
|
||||
e.v,
|
||||
e.w,
|
||||
'Translateing: ',
|
||||
clusterDb[e.v],
|
||||
clusterDb[e.w]
|
||||
);
|
||||
log.info('Fix', clusterDb, 'ids:', e.v, e.w, 'Translateing: ', clusterDb[e.v], clusterDb[e.w]);
|
||||
if (clusterDb[e.v] || clusterDb[e.w]) {
|
||||
logger.info('Fixing and trixing - rwemoving', e.v, e.w, e.name);
|
||||
log.info('Fixing and trixing - removing', e.v, e.w, e.name);
|
||||
v = getAnchorId(e.v, graph, nodes);
|
||||
w = getAnchorId(e.w, graph, nodes);
|
||||
graph.removeEdge(e.v, e.w, e.name);
|
||||
if (v !== e.v) edge.fromCluster = e.v;
|
||||
if (w !== e.w) edge.toCluster = e.w;
|
||||
logger.info('Fixing Replacing with', v, w, e.name);
|
||||
log.info('Fixing Replacing with', v, w, e.name);
|
||||
graph.setEdge(v, w, edge, e.name);
|
||||
}
|
||||
insertEdgeLabel(edgeLabels, edge);
|
||||
});
|
||||
|
||||
graph.edges().forEach(function(e) {
|
||||
logger.trace('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(e));
|
||||
log.trace('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(e));
|
||||
});
|
||||
logger.info('#############################################');
|
||||
logger.info('### Layout ###');
|
||||
logger.info('#############################################');
|
||||
logger.info(graph);
|
||||
log.info('#############################################');
|
||||
log.info('### Layout ###');
|
||||
log.info('#############################################');
|
||||
log.info(graph);
|
||||
dagre.layout(graph);
|
||||
|
||||
// Move the nodes to the correct place
|
||||
graph.nodes().forEach(function(v) {
|
||||
const node = graph.node(v);
|
||||
logger.trace('Node ' + v + ': ' + JSON.stringify(graph.node(v)));
|
||||
if (node.type !== 'group') {
|
||||
positionNode(node);
|
||||
log.info('Position ' + v + ': ' + JSON.stringify(graph.node(v)));
|
||||
if (node && node.clusterNode) {
|
||||
// clusterDb[node.id].node = node;
|
||||
// positionNode(node);
|
||||
} else {
|
||||
insertCluster(clusters, node);
|
||||
clusterDb[node.id].node = node;
|
||||
// Non cluster node
|
||||
if (graph.children(v).length > 0) {
|
||||
// A cluster in the non-recurive way
|
||||
// positionCluster(node);
|
||||
insertCluster(clusters, node);
|
||||
clusterDb[node.id].node = node;
|
||||
} else {
|
||||
positionNode(node);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Move the edge labels to the correct place after layout
|
||||
graph.edges().forEach(function(e) {
|
||||
const edge = graph.edge(e);
|
||||
logger.trace('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge);
|
||||
log.trace('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge);
|
||||
|
||||
insertEdge(edgePaths, edge, clusterDb, diagramtype);
|
||||
positionEdgeLabel(edge);
|
||||
});
|
||||
|
||||
return elem;
|
||||
};
|
||||
|
||||
export const render = (elem, graph, markers, diagramtype, id) => {
|
||||
insertMarkers(elem, markers, diagramtype, id);
|
||||
clearNodes();
|
||||
clearEdges();
|
||||
clearClusters();
|
||||
clearGraphlib();
|
||||
|
||||
log.warn('Graph before:', graphlib.json.write(graph));
|
||||
adjustClustersAndEdges(graph);
|
||||
log.warn('Graph after:', graphlib.json.write(graph));
|
||||
|
||||
recursiveRender(elem, graph, diagramtype);
|
||||
};
|
||||
|
||||
// const shapeDefinitions = {};
|
||||
|
@ -13,7 +13,7 @@ export const clear = () => {
|
||||
};
|
||||
|
||||
const copy = (clusterId, graph, newGraph, rootId) => {
|
||||
logger.trace('Copying ', clusterId);
|
||||
logger.info('Copying ', clusterId, graph.node(clusterId));
|
||||
const nodes = graph.children(clusterId);
|
||||
nodes.forEach(node => {
|
||||
if (graph.children(node).length > 0) {
|
||||
@ -21,22 +21,29 @@ const copy = (clusterId, graph, newGraph, rootId) => {
|
||||
}
|
||||
|
||||
const data = graph.node(node);
|
||||
logger.trace(node, data, ' parent is ', clusterId);
|
||||
logger.info(node, data, ' parent is ', clusterId);
|
||||
newGraph.setNode(node, data);
|
||||
newGraph.setParent(node, clusterId);
|
||||
const edges = graph.edges(node);
|
||||
graph.removeNode(node);
|
||||
logger.trace('Edges', edges);
|
||||
logger.info('Copying Edges', edges);
|
||||
edges.forEach(edge => {
|
||||
const data = graph.edge(edge);
|
||||
// Do not copy edges in and out of the root cluster, they belong to the parent graph
|
||||
if (!(edge.v === rootId || edge.w === rootId)) {
|
||||
logger.trace('Copying as ', rootId, edge.v, edge.w, clusterId);
|
||||
newGraph.setEdge(edge.v, edge.w, data);
|
||||
} else {
|
||||
logger.trace('Skipping copy of edge as ', rootId, edge.v, edge.w, clusterId);
|
||||
logger.info('Edge', edge);
|
||||
const data = graph.edge(edge.v, edge.w, edge.name);
|
||||
logger.info('Edge data', data, rootId);
|
||||
try {
|
||||
// Do not copy edges in and out of the root cluster, they belong to the parent graph
|
||||
if (!(edge.v === rootId || edge.w === rootId)) {
|
||||
logger.info('Copying as ', edge.v, edge.w, data, edge.name);
|
||||
newGraph.setEdge(edge.v, edge.w, data, edge.name);
|
||||
logger.info('newgrapg edges ', newGraph.edges(), newGraph.edge(newGraph.edges()[0]));
|
||||
} else {
|
||||
logger.info('Skipping copy of edge as ', rootId, edge.v, edge.w, clusterId);
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error(e);
|
||||
}
|
||||
});
|
||||
graph.removeNode(node);
|
||||
});
|
||||
newGraph.setNode(clusterId, graph.node(clusterId));
|
||||
};
|
||||
@ -60,8 +67,8 @@ export const extractGraphFromCluster = (clusterId, graph) => {
|
||||
.setGraph({
|
||||
rankdir: 'TB',
|
||||
// Todo: set proper spacing
|
||||
nodesep: 10,
|
||||
ranksep: 10,
|
||||
nodesep: 50,
|
||||
ranksep: 50,
|
||||
marginx: 8,
|
||||
marginy: 8
|
||||
})
|
||||
@ -69,6 +76,26 @@ export const extractGraphFromCluster = (clusterId, graph) => {
|
||||
return {};
|
||||
});
|
||||
|
||||
// const conf = getConfig().flowchart;
|
||||
// const nodeSpacing = conf.nodeSpacing || 50;
|
||||
// const rankSpacing = conf.rankSpacing || 50;
|
||||
|
||||
// // Create the input mermaid.graph
|
||||
// const g = new graphlib.Graph({
|
||||
// multigraph: true,
|
||||
// compound: true
|
||||
// })
|
||||
// .setGraph({
|
||||
// rankdir: 'TB',
|
||||
// nodesep: nodeSpacing,
|
||||
// ranksep: rankSpacing,
|
||||
// marginx: 8,
|
||||
// marginy: 8
|
||||
// })
|
||||
// .setDefaultEdgeLabel(function() {
|
||||
// return {};
|
||||
// });
|
||||
|
||||
copy(clusterId, graph, clusterGraph, clusterId);
|
||||
|
||||
return clusterGraph;
|
||||
@ -100,7 +127,7 @@ export const validate = graph => {
|
||||
* @param {Finds a } id
|
||||
* @param {*} graph
|
||||
*/
|
||||
const findNonClusterChild = (id, graph) => {
|
||||
export const findNonClusterChild = (id, graph) => {
|
||||
// const node = graph.node(id);
|
||||
logger.trace('Searching', id);
|
||||
const children = graph.children(id);
|
||||
@ -141,7 +168,7 @@ export const adjustClustersAndEdges = graph => {
|
||||
graph.nodes().forEach(function(id) {
|
||||
const children = graph.children(id);
|
||||
if (children.length > 0) {
|
||||
logger.trace(
|
||||
logger.info(
|
||||
'Cluster identified',
|
||||
id,
|
||||
' Replacement id in edges: ',
|
||||
@ -157,13 +184,13 @@ export const adjustClustersAndEdges = graph => {
|
||||
const children = graph.children(id);
|
||||
const edges = graph.edges();
|
||||
if (children.length > 0) {
|
||||
logger.trace('Cluster identified', id);
|
||||
logger.info('Cluster identified', id);
|
||||
edges.forEach(edge => {
|
||||
logger.trace('Edge: ', edge, decendants[id]);
|
||||
logger.info('Edge: ', edge, decendants[id]);
|
||||
// Check if any edge leaves the cluster (not the actual cluster, thats a link from the box)
|
||||
if (edge.v !== id && edge.w !== id) {
|
||||
if (decendants[id].indexOf(edge.v) < 0 || decendants[id].indexOf(edge.w) < 0) {
|
||||
logger.trace('Edge: ', edge, ' leaves cluster ', id);
|
||||
logger.info('Edge: ', edge, ' leaves cluster ', id);
|
||||
clusterDb[id].externalConnections = true;
|
||||
}
|
||||
}
|
||||
@ -189,7 +216,13 @@ export const adjustClustersAndEdges = graph => {
|
||||
|
||||
// Create a new node in the original graph, this new node is not a cluster
|
||||
// but a regular node with the cluster dontent as a new attached graph
|
||||
graph.setNode(clusterId, { clusterNode: true, graph: clusterGraph });
|
||||
graph.setNode(clusterId, {
|
||||
clusterNode: true,
|
||||
id: clusterId,
|
||||
clusterData: clusterDb[clusterId],
|
||||
labelText: clusterDb[clusterId].labelText,
|
||||
graph: clusterGraph
|
||||
});
|
||||
|
||||
// The original edges in and out of the cluster is applied
|
||||
edges.forEach(edge => {
|
||||
@ -205,7 +238,7 @@ export const adjustClustersAndEdges = graph => {
|
||||
graph.edges().forEach(function(e) {
|
||||
const edge = graph.edge(e);
|
||||
logger.trace('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(e));
|
||||
logger.trace('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(graph.edge(e)));
|
||||
logger.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(graph.edge(e)));
|
||||
|
||||
let v = e.v;
|
||||
let w = e.w;
|
||||
|
@ -135,7 +135,7 @@ describe('Graphlib decorations', () => {
|
||||
expect(newGraph.edges('a')).toEqual([{ v: 'a', w: 'b' }]);
|
||||
});
|
||||
|
||||
it('It is possible to extract a clusters to a new graph 2', function () {
|
||||
it('It is possible to extract a clusters to a new graph 2 GLB1', function () {
|
||||
/*
|
||||
subgraph C1
|
||||
a --> b
|
||||
@ -163,7 +163,7 @@ describe('Graphlib decorations', () => {
|
||||
expect(g.children('C2')).toEqual([]);
|
||||
expect(g.edges()).toEqual([{ v: 'C1', w: 'C2' }]);
|
||||
|
||||
logger.info(C1.nodes());
|
||||
logger.info(g.nodes());
|
||||
expect(C1.nodes()).toEqual(['a', 'C1', 'b']);
|
||||
expect(C1.children('C1')).toEqual(['a', 'b']);
|
||||
expect(C1.edges()).toEqual([{ v: 'a', w: 'b' }]);
|
||||
@ -200,7 +200,7 @@ describe('Graphlib decorations', () => {
|
||||
expect(g.children('C1')).toEqual([]);
|
||||
});
|
||||
});
|
||||
it('Validate should detect edges between clusters and transform clusters', function () {
|
||||
it('Validate should detect edges between clusters and transform clusters GLB4', function () {
|
||||
/*
|
||||
a --> b
|
||||
subgraph C1
|
||||
@ -225,4 +225,29 @@ describe('Graphlib decorations', () => {
|
||||
expect(g.nodes().length).toBe(2);
|
||||
expect(validate(g)).toBe(true);
|
||||
});
|
||||
it('Validate should detect edges between clusters and transform clusters GLB5', function () {
|
||||
/*
|
||||
a --> b
|
||||
subgraph C1
|
||||
a
|
||||
end
|
||||
subgraph C2
|
||||
b
|
||||
end
|
||||
C1 -->
|
||||
*/
|
||||
g.setNode('a', { data: 1 });
|
||||
g.setNode('b', { data: 2 });
|
||||
g.setParent('a', 'C1');
|
||||
g.setParent('b', 'C2');
|
||||
g.setParent('C1', 'C2');
|
||||
// g.setEdge('a', 'b', { name: 'C1-internal-link' });
|
||||
g.setEdge('C1', 'C2', { name: 'C1-external-link' });
|
||||
|
||||
logger.info(g.nodes())
|
||||
adjustClustersAndEdges(g);
|
||||
logger.info(g.nodes())
|
||||
expect(g.nodes().length).toBe(2);
|
||||
expect(validate(g)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -387,6 +387,9 @@ let nodeElems = {};
|
||||
export const insertNode = (elem, node) => {
|
||||
nodeElems[node.id] = shapes[node.shape](elem, node);
|
||||
};
|
||||
export const setNodeElem = (elem, node) => {
|
||||
nodeElems[node.id] = elem;
|
||||
};
|
||||
export const clear = () => {
|
||||
nodeElems = {};
|
||||
};
|
||||
|
@ -314,8 +314,10 @@ export const draw = function(text, id) {
|
||||
|
||||
let subG;
|
||||
const subGraphs = flowDb.getSubGraphs();
|
||||
logger.info('Subgraphs - ', subGraphs);
|
||||
for (let i = subGraphs.length - 1; i >= 0; i--) {
|
||||
subG = subGraphs[i];
|
||||
logger.info('Subgraph - ', subG);
|
||||
flowDb.addVertex(subG.id, subG.title, 'group', undefined, subG.classes);
|
||||
}
|
||||
|
||||
@ -347,7 +349,7 @@ export const draw = function(text, id) {
|
||||
// Run the renderer. This is what draws the final graph.
|
||||
const element = d3.select('#' + id + ' g');
|
||||
render(element, g, ['point', 'circle', 'cross'], 'flowchart', id);
|
||||
dagre.layout(g);
|
||||
// dagre.layout(g);
|
||||
|
||||
element.selectAll('g.node').attr('title', function() {
|
||||
return flowDb.getTooltip(this.id);
|
||||
@ -378,27 +380,27 @@ export const draw = function(text, id) {
|
||||
// Index nodes
|
||||
flowDb.indexNodes('subGraph' + i);
|
||||
|
||||
// reposition labels
|
||||
for (i = 0; i < subGraphs.length; i++) {
|
||||
subG = subGraphs[i];
|
||||
// // reposition labels
|
||||
// for (i = 0; i < subGraphs.length; i++) {
|
||||
// subG = subGraphs[i];
|
||||
|
||||
if (subG.title !== 'undefined') {
|
||||
const clusterRects = document.querySelectorAll('#' + id + ' [id="' + subG.id + '"] rect');
|
||||
const clusterEl = document.querySelectorAll('#' + id + ' [id="' + subG.id + '"]');
|
||||
// if (subG.title !== 'undefined') {
|
||||
// const clusterRects = document.querySelectorAll('#' + id + ' [id="' + subG.id + '"] rect');
|
||||
// const clusterEl = document.querySelectorAll('#' + id + ' [id="' + subG.id + '"]');
|
||||
|
||||
const xPos = clusterRects[0].x.baseVal.value;
|
||||
const yPos = clusterRects[0].y.baseVal.value;
|
||||
const width = clusterRects[0].width.baseVal.value;
|
||||
const cluster = d3.select(clusterEl[0]);
|
||||
const te = cluster.select('.label');
|
||||
te.attr('transform', `translate(${xPos + width / 2}, ${yPos + 14})`);
|
||||
te.attr('id', id + 'Text');
|
||||
// const xPos = clusterRects[0].x.baseVal.value;
|
||||
// const yPos = clusterRects[0].y.baseVal.value;
|
||||
// const width = clusterRects[0].width.baseVal.value;
|
||||
// const cluster = d3.select(clusterEl[0]);
|
||||
// const te = cluster.select('.label');
|
||||
// te.attr('transform', `translate(${xPos + width / 2}, ${yPos + 14})`);
|
||||
// te.attr('id', id + 'Text');
|
||||
|
||||
for (let j = 0; j < subG.classes.length; j++) {
|
||||
clusterEl[0].classList.add(subG.classes[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// for (let j = 0; j < subG.classes.length; j++) {
|
||||
// clusterEl[0].classList.add(subG.classes[j]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Add label rects for non html labels
|
||||
if (!conf.htmlLabels) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user