mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-07 17:46:44 +02:00
#1295 Fix for intersection calculation for edges to clusters and adding concurrency in stateDiagrams as clusters
This commit is contained in:
@@ -32,13 +32,31 @@
|
||||
G-->c
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||
flowchart LR
|
||||
subgraph id1 [Test]
|
||||
b
|
||||
end
|
||||
a-->id1
|
||||
stateDiagram-v2
|
||||
[*] --> monkey
|
||||
state monkey {
|
||||
Sitting
|
||||
--
|
||||
Eating
|
||||
}
|
||||
</div>
|
||||
<div class="mermaid mermaid-apa" style="width: 100%; height: 20%;">
|
||||
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||
stateDiagram-v2
|
||||
state Active {
|
||||
[*] --> NumLockOff
|
||||
NumLockOff --> NumLockOn : EvNumLockPressed
|
||||
NumLockOn --> NumLockOff : EvNumLockPressed
|
||||
--
|
||||
[*] --> CapsLockOff
|
||||
CapsLockOff --> CapsLockOn : EvCapsLockPressed
|
||||
CapsLockOn --> CapsLockOff : EvCapsLockPressed
|
||||
--
|
||||
[*] --> ScrollLockOff
|
||||
ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
|
||||
ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
|
||||
}
|
||||
</div>
|
||||
<div class="mermaid2 mermaid-apa" style="width: 100%; height: 20%;">
|
||||
stateDiagram
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
@@ -51,16 +69,40 @@
|
||||
Moving --> Still
|
||||
Moving --> Crash
|
||||
Crash --> [*]
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 100%;">
|
||||
stateDiagram-v2
|
||||
[*] --> First
|
||||
First --> Second
|
||||
% First --> Third
|
||||
|
||||
state First {
|
||||
[*] --> fir
|
||||
fir --> [*]
|
||||
}
|
||||
state Second {
|
||||
[*] --> sec
|
||||
sec --> [*]
|
||||
}
|
||||
</div>
|
||||
<div class="mermaid" style="width: 100%; height: 100%;">
|
||||
stateDiagram-v2
|
||||
State1: The state with a note
|
||||
note right of State1
|
||||
Important information! You can write
|
||||
notes.
|
||||
end note
|
||||
State1 --> State2
|
||||
note left of State2 : This is the note to the left.
|
||||
stateDiagram-v2
|
||||
[*] --> First
|
||||
First --> Second
|
||||
First --> Third
|
||||
|
||||
state First {
|
||||
[*] --> fir
|
||||
fir --> [*]
|
||||
}
|
||||
state Second {
|
||||
[*] --> sec
|
||||
sec --> [*]
|
||||
}
|
||||
state Third {
|
||||
[*] --> thi
|
||||
thi --> [*]
|
||||
}
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 100%;">
|
||||
stateDiagram-v2
|
||||
|
@@ -7,12 +7,10 @@ Explains the representation of various objects used to render the flow charts an
|
||||
Sample object:
|
||||
```json
|
||||
{
|
||||
"labelType":"svg",
|
||||
"labelStyle":"",
|
||||
"shape":"rect",
|
||||
"label":{},
|
||||
"labelText":"Test",
|
||||
"rx":0,"ry":0,
|
||||
"rx":0,
|
||||
"ry":0,
|
||||
"class":"default",
|
||||
"style":"",
|
||||
"id":"Test",
|
||||
@@ -24,18 +22,16 @@ This is set by the renderer of the diagram and insert the data that the wrapper
|
||||
|
||||
| property | description |
|
||||
| ---------- | ----------------------------------------------------------------------------------------------------------- |
|
||||
| labelType | If the label should be html label or a svg label. Should we continue to support both? |
|
||||
| labelStyle | Css styles for the label. Not currently used. |
|
||||
| shape | The shape of the node. Currently on rect is suppoerted. This will change. |
|
||||
| label | ?? |
|
||||
| labelStyle | Css styles for the label. User for instance for stylling the labels for clusters |
|
||||
| shape | The shape of the node. |
|
||||
| labelText | The text on the label |
|
||||
| rx | The corner radius - maybe part of the shape instead? |
|
||||
| ry | The corner radius - maybe part of the shape instead? |
|
||||
| class | Class to be set for the shape |
|
||||
| rx | The corner radius - maybe part of the shape instead? Used for rects. |
|
||||
| ry | The corner radius - maybe part of the shape instead? Used for rects. |
|
||||
| classes | Classes to be set for the shape. Not used |
|
||||
| style | Css styles for the actual shape |
|
||||
| id | id of the shape |
|
||||
| type | if set to group then this node indicates *a cluster*. |
|
||||
| padding | Padding. Passed from the renderr as this might differ between react for different diagrams. Maybe obsolete. |
|
||||
| padding | Padding. Passed from the render as this might differ between different diagrams. Maybe obsolete. |
|
||||
|
||||
|
||||
# edge
|
||||
|
@@ -1,8 +1,10 @@
|
||||
const createLabel = (vertexText, style) => {
|
||||
const svgLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
svgLabel.setAttribute('style', style.replace('color:', 'fill:'));
|
||||
|
||||
const rows = vertexText.split(/\n|<br\s*\/?>/gi);
|
||||
let rows = [];
|
||||
if (vertexText) {
|
||||
rows = vertexText.split(/\n|<br\s*\/?>/gi);
|
||||
}
|
||||
|
||||
for (let j = 0; j < rows.length; j++) {
|
||||
const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
|
||||
|
@@ -63,34 +63,17 @@ const outsideNode = (node, point) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
// const intersection = (node, outsidePoint, insidePoint) => {
|
||||
// const x = node.x;
|
||||
// const y = node.y;
|
||||
|
||||
// const dx = Math.abs(x - insidePoint.x);
|
||||
// const w = node.width / 2;
|
||||
// let r = w - dx;
|
||||
// const dy = Math.abs(y - insidePoint.y);
|
||||
// const h = node.height / 2;
|
||||
// const q = h - dy;
|
||||
|
||||
// const Q = Math.abs(outsidePoint.y - insidePoint.y);
|
||||
// const R = Math.abs(outsidePoint.x - insidePoint.x);
|
||||
// r = (R * q) / Q;
|
||||
|
||||
// return { x: insidePoint.x + r, y: insidePoint.y + q };
|
||||
// };
|
||||
const intersection = (node, outsidePoint, insidePoint) => {
|
||||
// logger.info('intersection', outsidePoint, insidePoint, node);
|
||||
logger.info('intersection o:', outsidePoint, ' i:', insidePoint, node);
|
||||
const x = node.x;
|
||||
const y = node.y;
|
||||
|
||||
const dx = Math.abs(x - insidePoint.x);
|
||||
const w = node.width / 2;
|
||||
let r = w - dx;
|
||||
let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx;
|
||||
const dy = Math.abs(y - insidePoint.y);
|
||||
const h = node.height / 2;
|
||||
let q = h - dy;
|
||||
let q = insidePoint.y < outsidePoint.y ? h - dy : h - dy;
|
||||
|
||||
const Q = Math.abs(outsidePoint.y - insidePoint.y);
|
||||
const R = Math.abs(outsidePoint.x - insidePoint.x);
|
||||
@@ -105,9 +88,10 @@ const intersection = (node, outsidePoint, insidePoint) => {
|
||||
};
|
||||
} else {
|
||||
q = (Q * r) / R;
|
||||
r = (R * q) / Q;
|
||||
|
||||
return {
|
||||
x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - r,
|
||||
x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x + dx - w,
|
||||
y: insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q
|
||||
};
|
||||
}
|
||||
@@ -117,8 +101,8 @@ export const insertEdge = function(elem, edge, clusterDb, diagramType) {
|
||||
logger.info('\n\n\n\n');
|
||||
let points = edge.points;
|
||||
if (edge.toCluster) {
|
||||
// logger.info('edge', edge);
|
||||
// logger.info('to cluster', clusterDb[edge.toCluster]);
|
||||
logger.info('edge', edge);
|
||||
logger.info('to cluster', clusterDb[edge.toCluster]);
|
||||
points = [];
|
||||
let lastPointOutside;
|
||||
let isInside = false;
|
||||
@@ -126,13 +110,12 @@ export const insertEdge = function(elem, edge, clusterDb, diagramType) {
|
||||
const node = clusterDb[edge.toCluster].node;
|
||||
|
||||
if (!outsideNode(node, point) && !isInside) {
|
||||
// logger.info('inside', edge.toCluster, point);
|
||||
logger.info('inside', edge.toCluster, point, lastPointOutside);
|
||||
|
||||
// First point inside the rect
|
||||
const insterection = intersection(node, lastPointOutside, point);
|
||||
// logger.info('intersect', inter.rect(node, lastPointOutside));
|
||||
logger.info('intersect', insterection);
|
||||
points.push(insterection);
|
||||
// points.push(insterection);
|
||||
isInside = true;
|
||||
} else {
|
||||
if (!isInside) points.push(point);
|
||||
@@ -142,8 +125,8 @@ export const insertEdge = function(elem, edge, clusterDb, diagramType) {
|
||||
}
|
||||
|
||||
if (edge.fromCluster) {
|
||||
// logger.info('edge', edge);
|
||||
// logger.info('from cluster', clusterDb[edge.toCluster]);
|
||||
logger.info('edge', edge);
|
||||
logger.info('from cluster', clusterDb[edge.toCluster]);
|
||||
const updatedPoints = [];
|
||||
let lastPointOutside;
|
||||
let isInside = false;
|
||||
@@ -152,7 +135,7 @@ export const insertEdge = function(elem, edge, clusterDb, diagramType) {
|
||||
const node = clusterDb[edge.fromCluster].node;
|
||||
|
||||
if (!outsideNode(node, point) && !isInside) {
|
||||
// logger.info('inside', edge.toCluster, point);
|
||||
logger.info('inside', edge.toCluster, point);
|
||||
|
||||
// First point inside the rect
|
||||
const insterection = intersection(node, lastPointOutside, point);
|
||||
@@ -162,7 +145,7 @@ export const insertEdge = function(elem, edge, clusterDb, diagramType) {
|
||||
isInside = true;
|
||||
} else {
|
||||
// at the outside
|
||||
// logger.info('Outside point', point);
|
||||
logger.info('Outside point', point);
|
||||
if (!isInside) updatedPoints.unshift(point);
|
||||
}
|
||||
lastPointOutside = point;
|
||||
@@ -170,10 +153,6 @@ export const insertEdge = function(elem, edge, clusterDb, diagramType) {
|
||||
points = updatedPoints;
|
||||
}
|
||||
|
||||
// logger.info('Poibts', points);
|
||||
|
||||
// logger.info('Edge', edge);
|
||||
|
||||
// The data for our line
|
||||
const lineData = points.filter(p => !Number.isNaN(p.y));
|
||||
|
||||
|
@@ -7,8 +7,28 @@ import { logger } from '../logger';
|
||||
|
||||
let clusterDb = {};
|
||||
|
||||
const translateClusterId = id => {
|
||||
if (clusterDb[id]) return clusterDb[id].id;
|
||||
const getAnchorId = (id, graph, nodes) => {
|
||||
// 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;
|
||||
};
|
||||
|
||||
@@ -24,24 +44,24 @@ export const render = (elem, graph, markers, diagramtype, id) => {
|
||||
const edgeLabels = elem.insert('g').attr('class', 'edgeLabels');
|
||||
const nodes = elem.insert('g').attr('class', 'nodes');
|
||||
|
||||
logger.warn('graph', graph);
|
||||
|
||||
// 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);
|
||||
logger.warn('Node ' + v + ': ' + JSON.stringify(graph.node(v)));
|
||||
logger.info('Node ' + v + ': ' + JSON.stringify(graph.node(v)));
|
||||
if (node.type !== 'group') {
|
||||
insertNode(nodes, graph.node(v));
|
||||
} else {
|
||||
// const width = getClusterTitleWidth(clusters, node);
|
||||
const children = graph.children(v);
|
||||
|
||||
logger.info('Cluster identified', node.id, children[0]);
|
||||
// nodes2expand.push({ id: children[0], width });
|
||||
clusterDb[node.id] = { id: children[0] };
|
||||
logger.info('Clusters ', clusterDb);
|
||||
// clusterDb[node.id] = { id: node.id + '_anchor' };
|
||||
}
|
||||
});
|
||||
logger.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
|
||||
@@ -49,21 +69,37 @@ export const render = (elem, graph, markers, diagramtype, id) => {
|
||||
// TODO: pick optimal child in the cluster to us as link anchor
|
||||
graph.edges().forEach(function(e) {
|
||||
const edge = graph.edge(e);
|
||||
logger.warn('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(e));
|
||||
// logger.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(graph.edge(e)));
|
||||
const v = translateClusterId(e.v);
|
||||
const w = translateClusterId(e.w);
|
||||
if (v !== e.v || w !== e.w) {
|
||||
logger.trace('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(e));
|
||||
logger.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(graph.edge(e)));
|
||||
|
||||
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]
|
||||
);
|
||||
if (clusterDb[e.v] || clusterDb[e.w]) {
|
||||
logger.info('Fixing and trixing - rwemoving', 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);
|
||||
graph.setEdge(v, w, edge, e.name);
|
||||
}
|
||||
insertEdgeLabel(edgeLabels, edge);
|
||||
});
|
||||
|
||||
graph.edges().forEach(function(e) {
|
||||
logger.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(e));
|
||||
logger.trace('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(e));
|
||||
});
|
||||
logger.info('#############################################');
|
||||
logger.info('### Layout ###');
|
||||
@@ -74,7 +110,7 @@ export const render = (elem, graph, markers, diagramtype, id) => {
|
||||
// Move the nodes to the correct place
|
||||
graph.nodes().forEach(function(v) {
|
||||
const node = graph.node(v);
|
||||
logger.info('Node ' + v + ': ' + JSON.stringify(graph.node(v)));
|
||||
logger.trace('Node ' + v + ': ' + JSON.stringify(graph.node(v)));
|
||||
if (node.type !== 'group') {
|
||||
positionNode(node);
|
||||
} else {
|
||||
@@ -86,7 +122,7 @@ export const render = (elem, graph, markers, diagramtype, id) => {
|
||||
// Move the edge labels to the correct place after layout
|
||||
graph.edges().forEach(function(e) {
|
||||
const edge = graph.edge(e);
|
||||
logger.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge);
|
||||
logger.trace('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge);
|
||||
|
||||
insertEdge(edgePaths, edge, clusterDb, diagramtype);
|
||||
positionEdgeLabel(edge);
|
||||
|
@@ -130,10 +130,8 @@ export const addVertices = function(vert, g, svgId) {
|
||||
}
|
||||
// Add the node
|
||||
g.setNode(vertex.id, {
|
||||
labelType: 'svg',
|
||||
labelStyle: styles.labelStyle,
|
||||
shape: _shape,
|
||||
label: vertexNode,
|
||||
labelText: vertexText,
|
||||
rx: radious,
|
||||
ry: radious,
|
||||
@@ -146,10 +144,8 @@ export const addVertices = function(vert, g, svgId) {
|
||||
});
|
||||
|
||||
logger.info('setNode', {
|
||||
labelType: 'svg',
|
||||
labelStyle: styles.labelStyle,
|
||||
shape: _shape,
|
||||
label: vertexNode,
|
||||
labelText: vertexText,
|
||||
rx: radious,
|
||||
ry: radious,
|
||||
|
@@ -1,4 +1,7 @@
|
||||
import { logger } from '../../logger';
|
||||
import { generateId } from '../../utils';
|
||||
|
||||
const clone = o => JSON.parse(JSON.stringify(o));
|
||||
|
||||
let rootDoc = [];
|
||||
const setRootDoc = o => {
|
||||
@@ -22,6 +25,34 @@ const docTranslator = (parent, node, first) => {
|
||||
}
|
||||
|
||||
if (node.doc) {
|
||||
const doc = [];
|
||||
// Check for concurrency
|
||||
let i = 0;
|
||||
let currentDoc = [];
|
||||
for (i = 0; i < node.doc.length; i++) {
|
||||
if (node.doc[i].type === 'divider') {
|
||||
// debugger;
|
||||
const newNode = clone(node.doc[i]);
|
||||
newNode.doc = clone(currentDoc);
|
||||
doc.push(newNode);
|
||||
currentDoc = [];
|
||||
} else {
|
||||
currentDoc.push(node.doc[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// If any divider was encountered
|
||||
if (doc.length > 0 && currentDoc.length > 0) {
|
||||
const newNode = {
|
||||
stmt: 'state',
|
||||
id: generateId(),
|
||||
type: 'divider',
|
||||
doc: clone(currentDoc)
|
||||
};
|
||||
doc.push(clone(newNode));
|
||||
node.doc = doc;
|
||||
}
|
||||
|
||||
node.doc.forEach(docNode => docTranslator(node, docNode, true));
|
||||
}
|
||||
}
|
||||
@@ -31,8 +62,14 @@ const getRootDocV2 = () => {
|
||||
return { id: 'root', doc: rootDoc };
|
||||
};
|
||||
|
||||
const extract = doc => {
|
||||
const extract = _doc => {
|
||||
// const res = { states: [], relations: [] };
|
||||
let doc;
|
||||
if (_doc.doc) {
|
||||
doc = _doc.doc;
|
||||
} else {
|
||||
doc = _doc;
|
||||
}
|
||||
// let doc = root.doc;
|
||||
// if (!doc) {
|
||||
// doc = root;
|
||||
@@ -40,6 +77,8 @@ const extract = doc => {
|
||||
logger.info(doc);
|
||||
clear();
|
||||
|
||||
logger.info('Extract', doc);
|
||||
|
||||
doc.forEach(item => {
|
||||
if (item.stmt === 'state') {
|
||||
addState(item.id, item.type, item.doc, item.description, item.note);
|
||||
|
@@ -72,10 +72,8 @@ const setupNode = (g, parent, node, altFlag) => {
|
||||
}
|
||||
|
||||
const nodeData = {
|
||||
labelType: 'svg',
|
||||
labelStyle: '',
|
||||
shape: nodeDb[node.id].shape,
|
||||
label: node.id,
|
||||
labelText: nodeDb[node.id].description,
|
||||
classes: nodeDb[node.id].classes, //classStr,
|
||||
style: '', //styles.style,
|
||||
@@ -87,10 +85,8 @@ const setupNode = (g, parent, node, altFlag) => {
|
||||
if (node.note) {
|
||||
// Todo: set random id
|
||||
const noteData = {
|
||||
labelType: 'svg',
|
||||
labelStyle: '',
|
||||
shape: 'note',
|
||||
label: node.id,
|
||||
labelText: node.note.text,
|
||||
classes: 'statediagram-note', //classStr,
|
||||
style: '', //styles.style,
|
||||
@@ -99,10 +95,8 @@ const setupNode = (g, parent, node, altFlag) => {
|
||||
padding: 15 //getConfig().flowchart.padding
|
||||
};
|
||||
const groupData = {
|
||||
labelType: 'svg',
|
||||
labelStyle: '',
|
||||
shape: 'noteGroup',
|
||||
label: node.id + '----parent',
|
||||
labelText: node.note.text,
|
||||
classes: nodeDb[node.id].classes, //classStr,
|
||||
style: '', //styles.style,
|
||||
@@ -133,8 +127,7 @@ const setupNode = (g, parent, node, altFlag) => {
|
||||
classes: 'note-edge',
|
||||
arrowheadStyle: 'fill: #333',
|
||||
labelpos: 'c',
|
||||
labelType: 'text',
|
||||
label: ''
|
||||
labelType: 'text'
|
||||
});
|
||||
} else {
|
||||
g.setNode(node.id, nodeData);
|
||||
@@ -143,12 +136,12 @@ const setupNode = (g, parent, node, altFlag) => {
|
||||
|
||||
if (parent) {
|
||||
if (parent.id !== 'root') {
|
||||
logger.trace('Setting node ', node.id, ' to be child of its parent ', parent.id);
|
||||
logger.info('Setting node ', node.id, ' to be child of its parent ', parent.id);
|
||||
g.setParent(node.id, parent.id);
|
||||
}
|
||||
}
|
||||
if (node.doc) {
|
||||
logger.trace('Adding nodes children ');
|
||||
logger.info('Adding nodes children ');
|
||||
setupDoc(g, node, node.doc, !altFlag);
|
||||
}
|
||||
};
|
||||
@@ -168,8 +161,7 @@ const setupDoc = (g, parent, doc, altFlag) => {
|
||||
labelStyle: '',
|
||||
arrowheadStyle: 'fill: #333',
|
||||
labelpos: 'c',
|
||||
labelType: 'text',
|
||||
label: ''
|
||||
labelType: 'text'
|
||||
};
|
||||
let startId = item.state1.id;
|
||||
let endId = item.state2.id;
|
||||
@@ -214,7 +206,7 @@ export const draw = function(text, id) {
|
||||
compound: true
|
||||
})
|
||||
.setGraph({
|
||||
rankdir: 'LR',
|
||||
rankdir: 'TB',
|
||||
nodesep: nodeSpacing,
|
||||
ranksep: rankSpacing,
|
||||
marginx: 8,
|
||||
@@ -224,8 +216,8 @@ export const draw = function(text, id) {
|
||||
return {};
|
||||
});
|
||||
|
||||
// logger.info(stateDb.getRootDoc());
|
||||
stateDb.extract(stateDb.getRootDocV2().doc);
|
||||
logger.info(stateDb.getRootDocV2());
|
||||
stateDb.extract(stateDb.getRootDocV2());
|
||||
logger.info(stateDb.getRootDocV2());
|
||||
setupNode(g, undefined, stateDb.getRootDocV2(), true);
|
||||
|
||||
|
16
src/utils.js
16
src/utils.js
@@ -210,6 +210,19 @@ export const getStylesFromArray = arr => {
|
||||
return { style: style, labelStyle: labelStyle };
|
||||
};
|
||||
|
||||
let cnt = 0;
|
||||
export const generateId = () => {
|
||||
cnt++;
|
||||
return (
|
||||
'id-' +
|
||||
Math.random()
|
||||
.toString(36)
|
||||
.substr(2, 12) +
|
||||
'-' +
|
||||
cnt
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
detectType,
|
||||
isSubstringInArray,
|
||||
@@ -217,5 +230,6 @@ export default {
|
||||
calcLabelPosition,
|
||||
calcCardinalityPosition,
|
||||
formatUrl,
|
||||
getStylesFromArray
|
||||
getStylesFromArray,
|
||||
generateId
|
||||
};
|
||||
|
Reference in New Issue
Block a user