mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-14 12:59:46 +02:00
#1295 Edges between subgraphs
This commit is contained in:
@@ -14,6 +14,9 @@
|
|||||||
.arrowheadPath {fill: red;}
|
.arrowheadPath {fill: red;}
|
||||||
|
|
||||||
.edgePath .path {stroke: red;}
|
.edgePath .path {stroke: red;}
|
||||||
|
.mermaid2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -33,14 +36,72 @@
|
|||||||
C --> D
|
C --> D
|
||||||
C --> D
|
C --> D
|
||||||
</div>
|
</div>
|
||||||
<div class="mermaid" style="width: 100%; height: 100%">
|
<div class="mermaid2" style="width: 100%; height: 100%; display: none">
|
||||||
flowchart LR
|
graph LR
|
||||||
G-->H
|
a --> b
|
||||||
G-->H
|
|
||||||
subgraph id1 [Test]
|
subgraph id1 [Test]
|
||||||
H
|
a --apa--> c
|
||||||
|
b
|
||||||
|
c-->b
|
||||||
|
b-->H
|
||||||
end
|
end
|
||||||
|
G-->H
|
||||||
|
G-->c
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 100%; height: 100%">
|
||||||
|
flowchart TB
|
||||||
|
a --> b
|
||||||
|
|
||||||
|
subgraph id1 [Test]
|
||||||
|
a --apa--> c
|
||||||
|
b
|
||||||
|
c-->b
|
||||||
|
b-->H
|
||||||
|
end
|
||||||
|
G-->H
|
||||||
|
G-->id1
|
||||||
|
id1 --> I
|
||||||
|
I --> G
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 100%; height: 100%">
|
||||||
|
flowchart RL
|
||||||
|
a --> b
|
||||||
|
|
||||||
|
subgraph id1 [Test]
|
||||||
|
a --apa--> c
|
||||||
|
b
|
||||||
|
c-->b
|
||||||
|
b-->H
|
||||||
|
end
|
||||||
|
G-->H
|
||||||
|
G-->id1
|
||||||
|
id1 --> I
|
||||||
|
I --> G
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 100%; height: 100%">
|
||||||
|
flowchart RL
|
||||||
|
|
||||||
|
subgraph id1 [Test]
|
||||||
|
a
|
||||||
|
end
|
||||||
|
b-->id1
|
||||||
|
</div>
|
||||||
|
<div class="mermaid" style="width: 100%; height: 100%">
|
||||||
|
flowchart RL
|
||||||
|
|
||||||
|
subgraph id1 [Test1]
|
||||||
|
a
|
||||||
|
end
|
||||||
|
subgraph id2 [Test2]
|
||||||
|
b
|
||||||
|
end
|
||||||
|
a --> id2
|
||||||
|
a --> b
|
||||||
|
b-->id1
|
||||||
|
id1 --> id2
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<script src="./mermaid.js"></script>
|
<script src="./mermaid.js"></script>
|
||||||
<script>
|
<script>
|
||||||
@@ -53,7 +114,8 @@
|
|||||||
// gantt: { axisFormat: '%m/%d/%Y' },
|
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||||
sequence: { actorMargin: 50, showSequenceNumbers: true },
|
sequence: { actorMargin: 50, showSequenceNumbers: true },
|
||||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||||
fontFamily: '"arial", sans-serif'
|
fontFamily: '"arial", sans-serif',
|
||||||
|
curve: 'linear',
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</script>
|
</script>
|
||||||
|
@@ -32,7 +32,7 @@ const rect = (parent, node) => {
|
|||||||
.attr('width', node.width + padding)
|
.attr('width', node.width + padding)
|
||||||
.attr('height', node.height + padding);
|
.attr('height', node.height + padding);
|
||||||
|
|
||||||
logger.info('bbox', bbox.width, node.x, node.width);
|
// logger.info('bbox', bbox.width, node.x, node.width);
|
||||||
// Center the label
|
// Center the label
|
||||||
// label.attr('transform', 'translate(' + adj + ', ' + (node.y - node.height / 2) + ')');
|
// label.attr('transform', 'translate(' + adj + ', ' + (node.y - node.height / 2) + ')');
|
||||||
label.attr(
|
label.attr(
|
||||||
@@ -57,7 +57,7 @@ const rect = (parent, node) => {
|
|||||||
|
|
||||||
const shapes = { rect };
|
const shapes = { rect };
|
||||||
|
|
||||||
const clusterElems = {};
|
let clusterElems = {};
|
||||||
|
|
||||||
export const insertCluster = (elem, node) => {
|
export const insertCluster = (elem, node) => {
|
||||||
clusterElems[node.id] = shapes[node.shape](elem, node);
|
clusterElems[node.id] = shapes[node.shape](elem, node);
|
||||||
@@ -70,6 +70,10 @@ export const getClusterTitleWidth = (elem, node) => {
|
|||||||
return width;
|
return width;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const clear = () => {
|
||||||
|
clusterElems = {};
|
||||||
|
};
|
||||||
|
|
||||||
export const positionCluster = node => {
|
export const positionCluster = node => {
|
||||||
const el = clusterElems[node.id];
|
const el = clusterElems[node.id];
|
||||||
el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');
|
el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');
|
||||||
|
@@ -1,9 +1,14 @@
|
|||||||
import { logger } from '../logger'; // eslint-disable-line
|
import { logger } from '../logger'; // eslint-disable-line
|
||||||
import createLabel from './createLabel';
|
import createLabel from './createLabel';
|
||||||
import * as d3 from 'd3';
|
import * as d3 from 'd3';
|
||||||
|
import inter from './intersect/index.js';
|
||||||
import { getConfig } from '../config';
|
import { getConfig } from '../config';
|
||||||
|
|
||||||
const edgeLabels = {};
|
let edgeLabels = {};
|
||||||
|
|
||||||
|
export const clear = () => {
|
||||||
|
edgeLabels = {};
|
||||||
|
};
|
||||||
|
|
||||||
export const insertEdgeLabel = (elem, edge) => {
|
export const insertEdgeLabel = (elem, edge) => {
|
||||||
// Create the actual text element
|
// Create the actual text element
|
||||||
@@ -30,7 +35,6 @@ export const insertEdgeLabel = (elem, edge) => {
|
|||||||
|
|
||||||
export const positionEdgeLabel = edge => {
|
export const positionEdgeLabel = edge => {
|
||||||
const el = edgeLabels[edge.id];
|
const el = edgeLabels[edge.id];
|
||||||
logger.info(edge.id, el);
|
|
||||||
el.attr('transform', 'translate(' + edge.x + ', ' + edge.y + ')');
|
el.attr('transform', 'translate(' + edge.x + ', ' + edge.y + ')');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,9 +51,128 @@ export const positionEdgeLabel = edge => {
|
|||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
|
|
||||||
export const insertEdge = function(elem, edge) {
|
const outsideNode = (node, point) => {
|
||||||
|
const x = node.x;
|
||||||
|
const y = node.y;
|
||||||
|
const dx = Math.abs(point.x - x);
|
||||||
|
const dy = Math.abs(point.y - y);
|
||||||
|
const w = node.width / 2;
|
||||||
|
const h = node.height / 2;
|
||||||
|
if (dx > w || dy > h) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
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) => {
|
||||||
|
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;
|
||||||
|
let q = h - dy;
|
||||||
|
|
||||||
|
logger.info('q och r', q, r);
|
||||||
|
|
||||||
|
const Q = Math.abs(outsidePoint.y - insidePoint.y);
|
||||||
|
const R = Math.abs(outsidePoint.x - insidePoint.x);
|
||||||
|
// if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h || false) { // eslint-disable-line
|
||||||
|
// // Intersection is top or bottom of rect.
|
||||||
|
|
||||||
|
// r = (R * q) / Q;
|
||||||
|
|
||||||
|
// return {
|
||||||
|
// x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - r,
|
||||||
|
// y: insidePoint.y + q
|
||||||
|
// };
|
||||||
|
// } else {
|
||||||
|
q = (Q * r) / R;
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - r,
|
||||||
|
y: insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q
|
||||||
|
};
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
export const insertEdge = function(elem, edge, clusterDb) {
|
||||||
|
let points = edge.points;
|
||||||
|
if (edge.toCluster) {
|
||||||
|
logger.trace('edge', edge);
|
||||||
|
logger.trace('cluster', clusterDb[edge.toCluster]);
|
||||||
|
points = [];
|
||||||
|
let lastPointOutside;
|
||||||
|
let isInside = false;
|
||||||
|
edge.points.forEach(point => {
|
||||||
|
const node = clusterDb[edge.toCluster].node;
|
||||||
|
|
||||||
|
if (!outsideNode(node, point) && !isInside) {
|
||||||
|
logger.info('inside', edge.toCluster, point);
|
||||||
|
|
||||||
|
// First point inside the rect
|
||||||
|
const insterection = intersection(node, lastPointOutside, point);
|
||||||
|
logger.info('intersect', inter.rect(node, lastPointOutside));
|
||||||
|
points.push(insterection);
|
||||||
|
// points.push(insterection);
|
||||||
|
isInside = true;
|
||||||
|
} else {
|
||||||
|
if (!isInside) points.push(point);
|
||||||
|
}
|
||||||
|
lastPointOutside = point;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edge.fromCluster) {
|
||||||
|
logger.info('edge', edge);
|
||||||
|
logger.info('cluster', clusterDb[edge.toCluster]);
|
||||||
|
const updatedPoints = [];
|
||||||
|
let lastPointOutside;
|
||||||
|
let isInside = false;
|
||||||
|
for (let i = points.length - 1; i >= 0; i--) {
|
||||||
|
const point = points[i];
|
||||||
|
const node = clusterDb[edge.fromCluster].node;
|
||||||
|
|
||||||
|
if (!outsideNode(node, point) && !isInside) {
|
||||||
|
logger.info('inside', edge.toCluster, point);
|
||||||
|
|
||||||
|
// First point inside the rect
|
||||||
|
const insterection = intersection(node, lastPointOutside, point);
|
||||||
|
logger.info('intersect', inter.rect(node, lastPointOutside));
|
||||||
|
updatedPoints.unshift(insterection);
|
||||||
|
// points.push(insterection);
|
||||||
|
isInside = true;
|
||||||
|
} else {
|
||||||
|
if (!isInside) updatedPoints.unshift(point);
|
||||||
|
}
|
||||||
|
lastPointOutside = point;
|
||||||
|
}
|
||||||
|
points = updatedPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info('Points', points);
|
||||||
|
|
||||||
// The data for our line
|
// The data for our line
|
||||||
const lineData = edge.points.filter(p => !Number.isNaN(p.y));
|
const lineData = points.filter(p => !Number.isNaN(p.y));
|
||||||
|
|
||||||
// This is the accessor function we talked about above
|
// This is the accessor function we talked about above
|
||||||
const lineFunction = d3
|
const lineFunction = d3
|
||||||
@@ -59,14 +182,25 @@ export const insertEdge = function(elem, edge) {
|
|||||||
})
|
})
|
||||||
.y(function(d) {
|
.y(function(d) {
|
||||||
return d.y;
|
return d.y;
|
||||||
})
|
});
|
||||||
.curve(d3.curveBasis);
|
// .curve(d3.curveBasis);
|
||||||
|
|
||||||
const svgPath = elem
|
const svgPath = elem
|
||||||
.append('path')
|
.append('path')
|
||||||
.attr('d', lineFunction(lineData))
|
.attr('d', lineFunction(lineData))
|
||||||
.attr('id', edge.id)
|
.attr('id', edge.id)
|
||||||
.attr('class', 'transition');
|
.attr('class', 'transition');
|
||||||
|
|
||||||
|
// edge.points.forEach(point => {
|
||||||
|
// elem
|
||||||
|
// .append('circle')
|
||||||
|
// .style('stroke', 'red')
|
||||||
|
// .style('fill', 'red')
|
||||||
|
// .attr('r', 1)
|
||||||
|
// .attr('cx', point.x)
|
||||||
|
// .attr('cy', point.y);
|
||||||
|
// });
|
||||||
|
|
||||||
let url = '';
|
let url = '';
|
||||||
if (getConfig().state.arrowMarkerAbsolute) {
|
if (getConfig().state.arrowMarkerAbsolute) {
|
||||||
url =
|
url =
|
||||||
@@ -79,6 +213,6 @@ export const insertEdge = function(elem, edge) {
|
|||||||
url = url.replace(/\)/g, '\\)');
|
url = url.replace(/\)/g, '\\)');
|
||||||
}
|
}
|
||||||
|
|
||||||
svgPath.attr('marker-end', 'url(' + url + '#' + 'extensionEnd' + ')');
|
svgPath.attr('marker-end', 'url(' + url + '#' + 'normalEnd' + ')');
|
||||||
svgPath.attr('marker-start', 'url(' + url + '#' + 'extensionStart' + ')');
|
// svgPath.attr('marker-start', 'url(' + url + '#' + 'normalStart' + ')');
|
||||||
};
|
};
|
||||||
|
@@ -1,12 +1,23 @@
|
|||||||
import dagre from 'dagre';
|
import dagre from 'dagre';
|
||||||
import insertMarkers from './markers';
|
import insertMarkers from './markers';
|
||||||
import { insertNode, positionNode } from './nodes';
|
import { insertNode, positionNode, clearNodes } from './nodes';
|
||||||
import { insertCluster } from './clusters';
|
import { insertCluster, clearClusters } from './clusters';
|
||||||
import { insertEdgeLabel, positionEdgeLabel, insertEdge } from './edges';
|
import { insertEdgeLabel, positionEdgeLabel, insertEdge, clearEdges } from './edges';
|
||||||
import { logger } from '../logger';
|
import { logger } from '../logger';
|
||||||
|
|
||||||
|
let clusterDb = {};
|
||||||
|
|
||||||
|
const translateClusterId = id => {
|
||||||
|
if (clusterDb[id]) return clusterDb[id].id;
|
||||||
|
return id;
|
||||||
|
};
|
||||||
|
|
||||||
export const render = (elem, graph) => {
|
export const render = (elem, graph) => {
|
||||||
insertMarkers(elem);
|
insertMarkers(elem);
|
||||||
|
clusterDb = {};
|
||||||
|
clearNodes();
|
||||||
|
clearEdges();
|
||||||
|
clearClusters();
|
||||||
|
|
||||||
const clusters = elem.insert('g').attr('class', 'clusters'); // eslint-disable-line
|
const clusters = elem.insert('g').attr('class', 'clusters'); // eslint-disable-line
|
||||||
const edgePaths = elem.insert('g').attr('class', 'edgePaths');
|
const edgePaths = elem.insert('g').attr('class', 'edgePaths');
|
||||||
@@ -17,27 +28,41 @@ export const render = (elem, graph) => {
|
|||||||
// to the abstract node and is later used by dagre for the layout
|
// to the abstract node and is later used by dagre for the layout
|
||||||
graph.nodes().forEach(function(v) {
|
graph.nodes().forEach(function(v) {
|
||||||
const node = graph.node(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') {
|
if (node.type !== 'group') {
|
||||||
insertNode(nodes, graph.node(v));
|
insertNode(nodes, graph.node(v));
|
||||||
} else {
|
} else {
|
||||||
// const width = getClusterTitleWidth(clusters, node);
|
// const width = getClusterTitleWidth(clusters, node);
|
||||||
// const children = graph.children(v);
|
const children = graph.children(v);
|
||||||
|
logger.info('Cluster identified', node.id, children[0]);
|
||||||
// nodes2expand.push({ id: children[0], width });
|
// nodes2expand.push({ id: children[0], width });
|
||||||
|
clusterDb[node.id] = { id: children[0] };
|
||||||
|
logger.info('Clusters ', clusterDb);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// nodes2expand.forEach(item => {
|
// Insert labels, this will insert them into the dom so that the width can be calculated
|
||||||
// const node = graph.node(item.id);
|
// Also figure out which edges point to/from clusters and adjust them accordingly
|
||||||
// node.width = item.width;
|
// 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
|
||||||
|
|
||||||
// Inster labels, this will insert them into the dom so that the width can be calculated
|
|
||||||
graph.edges().forEach(function(e) {
|
graph.edges().forEach(function(e) {
|
||||||
logger.trace('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(graph.edge(e)));
|
const edge = graph.edge(e);
|
||||||
insertEdgeLabel(edgeLabels, graph.edge(e));
|
// logger.info('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) {
|
||||||
|
graph.removeEdge(e.v, e.w, e.name);
|
||||||
|
if (v !== e.v) edge.fromCluster = e.v;
|
||||||
|
if (w !== e.w) edge.toCluster = e.w;
|
||||||
|
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.info('#############################################');
|
logger.info('#############################################');
|
||||||
logger.info('### Layout ###');
|
logger.info('### Layout ###');
|
||||||
logger.info('#############################################');
|
logger.info('#############################################');
|
||||||
@@ -46,11 +71,12 @@ export const render = (elem, graph) => {
|
|||||||
// Move the nodes to the correct place
|
// Move the nodes to the correct place
|
||||||
graph.nodes().forEach(function(v) {
|
graph.nodes().forEach(function(v) {
|
||||||
const node = graph.node(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') {
|
if (node.type !== 'group') {
|
||||||
positionNode(node);
|
positionNode(node);
|
||||||
} else {
|
} else {
|
||||||
insertCluster(clusters, node);
|
insertCluster(clusters, node);
|
||||||
|
clusterDb[node.id].node = node;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -59,7 +85,7 @@ export const render = (elem, graph) => {
|
|||||||
const edge = graph.edge(e);
|
const edge = graph.edge(e);
|
||||||
logger.trace('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge));
|
logger.trace('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge));
|
||||||
|
|
||||||
insertEdge(edgePaths, edge);
|
insertEdge(edgePaths, edge, clusterDb);
|
||||||
positionEdgeLabel(edge);
|
positionEdgeLabel(edge);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@@ -8,7 +8,7 @@ import ellipse from './intersect-ellipse';
|
|||||||
import polygon from './intersect-polygon';
|
import polygon from './intersect-polygon';
|
||||||
import rect from './intersect-rect';
|
import rect from './intersect-rect';
|
||||||
|
|
||||||
module.exports = {
|
export default {
|
||||||
node,
|
node,
|
||||||
circle,
|
circle,
|
||||||
ellipse,
|
ellipse,
|
||||||
|
@@ -2,6 +2,7 @@ const intersectRect = (node, point) => {
|
|||||||
var x = node.x;
|
var x = node.x;
|
||||||
var y = node.y;
|
var y = node.y;
|
||||||
|
|
||||||
|
console.log(node, point);
|
||||||
// Rectangle intersection algorithm from:
|
// Rectangle intersection algorithm from:
|
||||||
// http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes
|
// http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes
|
||||||
var dx = point.x - x;
|
var dx = point.x - x;
|
||||||
|
@@ -101,6 +101,37 @@ const insertMarkers = elem => {
|
|||||||
.attr('orient', 'auto')
|
.attr('orient', 'auto')
|
||||||
.append('path')
|
.append('path')
|
||||||
.attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z');
|
.attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z');
|
||||||
|
|
||||||
|
elem
|
||||||
|
.append('marker')
|
||||||
|
.attr('id', 'normalEnd')
|
||||||
|
.attr('viewBox', '0 0 10 10')
|
||||||
|
.attr('refX', 9)
|
||||||
|
.attr('refY', 5)
|
||||||
|
.attr('markerUnits', 'strokeWidth')
|
||||||
|
.attr('markerWidth', 8)
|
||||||
|
.attr('markerHeight', 6)
|
||||||
|
.attr('orient', 'auto')
|
||||||
|
.append('path')
|
||||||
|
.attr('d', 'M 0 0 L 10 5 L 0 10 z')
|
||||||
|
.attr('class', 'arrowheadPath')
|
||||||
|
.style('stroke-width', 1)
|
||||||
|
.style('stroke-dasharray', '1,0');
|
||||||
|
elem
|
||||||
|
.append('marker')
|
||||||
|
.attr('id', 'normalStart')
|
||||||
|
.attr('viewBox', '0 0 10 10')
|
||||||
|
.attr('refX', 9)
|
||||||
|
.attr('refY', 5)
|
||||||
|
.attr('markerUnits', 'strokeWidth')
|
||||||
|
.attr('markerWidth', 8)
|
||||||
|
.attr('markerHeight', 6)
|
||||||
|
.attr('orient', 'auto')
|
||||||
|
.append('path')
|
||||||
|
.attr('d', 'M 0 0 L 10 5 L 0 10 z')
|
||||||
|
.attr('class', 'arrowheadPath')
|
||||||
|
.style('stroke-width', 1)
|
||||||
|
.style('stroke-dasharray', '1,0');
|
||||||
};
|
};
|
||||||
|
|
||||||
export default insertMarkers;
|
export default insertMarkers;
|
||||||
|
@@ -47,11 +47,14 @@ const rect = (parent, node) => {
|
|||||||
|
|
||||||
const shapes = { rect };
|
const shapes = { rect };
|
||||||
|
|
||||||
const nodeElems = {};
|
let nodeElems = {};
|
||||||
|
|
||||||
export const insertNode = (elem, node) => {
|
export const insertNode = (elem, node) => {
|
||||||
nodeElems[node.id] = shapes[node.shape](elem, node);
|
nodeElems[node.id] = shapes[node.shape](elem, node);
|
||||||
};
|
};
|
||||||
|
export const clear = () => {
|
||||||
|
nodeElems = {};
|
||||||
|
};
|
||||||
|
|
||||||
export const positionNode = node => {
|
export const positionNode = node => {
|
||||||
const el = nodeElems[node.id];
|
const el = nodeElems[node.id];
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as d3 from 'd3';
|
import * as d3 from 'd3';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger'; // eslint-disable-line
|
||||||
import utils from '../../utils';
|
import utils from '../../utils';
|
||||||
import { getConfig } from '../../config';
|
import { getConfig } from '../../config';
|
||||||
import common from '../common/common';
|
import common from '../common/common';
|
||||||
@@ -88,7 +88,7 @@ export const addSingleLink = function(_start, _end, type, linktext) {
|
|||||||
let end = _end;
|
let end = _end;
|
||||||
if (start[0].match(/\d/)) start = MERMAID_DOM_ID_PREFIX + start;
|
if (start[0].match(/\d/)) start = MERMAID_DOM_ID_PREFIX + start;
|
||||||
if (end[0].match(/\d/)) end = MERMAID_DOM_ID_PREFIX + end;
|
if (end[0].match(/\d/)) end = MERMAID_DOM_ID_PREFIX + end;
|
||||||
logger.info('Got edge...', start, end);
|
// logger.info('Got edge...', start, end);
|
||||||
|
|
||||||
const edge = { start: start, end: end, type: undefined, text: '' };
|
const edge = { start: start, end: end, type: undefined, text: '' };
|
||||||
linktext = type.text;
|
linktext = type.text;
|
||||||
|
Reference in New Issue
Block a user