2019-08-20 17:17:56 +08:00
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="en">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
|
|
|
<title>Document</title>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<div id="mountNode"></div>
|
|
|
|
|
</body>
|
|
|
|
|
<script src="./assets/dagre.js"></script>
|
|
|
|
|
<script src="../build/g6.js"></script>
|
|
|
|
|
<script>
|
|
|
|
|
/**
|
|
|
|
|
* node 特殊属性
|
|
|
|
|
*/
|
|
|
|
|
const nodeExtraAttrs = {
|
|
|
|
|
begin: {
|
|
|
|
|
fill: "#9FD4FB"
|
|
|
|
|
},
|
|
|
|
|
end: {
|
|
|
|
|
fill: "#C2E999"
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
|
nodes: [
|
|
|
|
|
{
|
|
|
|
|
id: "1",
|
|
|
|
|
label: "请求回放1(开始)",
|
|
|
|
|
type: "begin"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: "2",
|
|
|
|
|
label: "交易创建"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: "3",
|
|
|
|
|
label: "请求回放3"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: "4",
|
|
|
|
|
label: "请求回放4"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: "5",
|
|
|
|
|
label: "请求回放5"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: "6",
|
|
|
|
|
label: "请求回放6"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: "7",
|
|
|
|
|
label: "请求回放2(结束)",
|
|
|
|
|
type: "end"
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
edges: [
|
|
|
|
|
{
|
|
|
|
|
source: "1",
|
|
|
|
|
target: "2"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
source: "1",
|
|
|
|
|
target: "3"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
source: "2",
|
|
|
|
|
target: "5"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
source: "5",
|
|
|
|
|
target: "6"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
source: "6",
|
|
|
|
|
target: "7"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
source: "3",
|
|
|
|
|
target: "4"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
source: "4",
|
|
|
|
|
target: "7"
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 自定义节点
|
|
|
|
|
*/
|
|
|
|
|
G6.registerNode(
|
2019-09-30 13:19:00 +08:00
|
|
|
|
"rect-node",
|
2019-08-20 17:17:56 +08:00
|
|
|
|
{
|
|
|
|
|
drawShape: function drawShape(cfg, group) {
|
|
|
|
|
var rect = group.addShape("rect", {
|
|
|
|
|
attrs: {
|
|
|
|
|
x: -75,
|
|
|
|
|
y: -25,
|
|
|
|
|
width: 150,
|
|
|
|
|
height: 50,
|
|
|
|
|
radius: 4,
|
|
|
|
|
fill: "#FFD591",
|
|
|
|
|
fillOpacity: 1,
|
|
|
|
|
...nodeExtraAttrs[cfg.type]
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return rect;
|
|
|
|
|
},
|
|
|
|
|
getAnchorPoints: function getAnchorPoints() {
|
|
|
|
|
return [[0, 0.5], [1, 0.5]];
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
"single-shape"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 自定义带箭头的贝塞尔曲线 edge
|
|
|
|
|
*/
|
2019-09-30 13:19:00 +08:00
|
|
|
|
G6.registerEdge("line-with-point", {
|
2019-08-20 17:17:56 +08:00
|
|
|
|
itemType: "edge",
|
|
|
|
|
draw: function draw(cfg, group) {
|
|
|
|
|
const startPoint = cfg.startPoint;
|
|
|
|
|
const endPoint = cfg.endPoint;
|
|
|
|
|
const centerPoint = {
|
|
|
|
|
x: (startPoint.x + endPoint.x) / 2,
|
|
|
|
|
y: (startPoint.y + endPoint.y) / 2
|
|
|
|
|
};
|
|
|
|
|
// 控制点坐标
|
|
|
|
|
const controlPoint = {
|
|
|
|
|
x: (startPoint.x + centerPoint.x) / 2,
|
|
|
|
|
y: startPoint.y
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
console.log(cfg, startPoint, endPoint);
|
|
|
|
|
|
|
|
|
|
// 为了更好的展示效果, 对称贝塞尔曲线需要连到箭头根部
|
|
|
|
|
const path = group.addShape("path", {
|
|
|
|
|
attrs: {
|
|
|
|
|
path: [
|
|
|
|
|
["M", startPoint.x, startPoint.y],
|
|
|
|
|
[
|
|
|
|
|
"Q",
|
|
|
|
|
controlPoint.x + 8,
|
|
|
|
|
controlPoint.y,
|
|
|
|
|
centerPoint.x,
|
|
|
|
|
centerPoint.y
|
|
|
|
|
],
|
|
|
|
|
["T", endPoint.x - 8, endPoint.y],
|
|
|
|
|
["L", endPoint.x, endPoint.y]
|
|
|
|
|
],
|
|
|
|
|
stroke: "#ccc",
|
|
|
|
|
lineWidth: 1.6,
|
|
|
|
|
endArrow: {
|
|
|
|
|
path: "M 4,0 L -4,-4 L -4,4 Z",
|
|
|
|
|
d: 4
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 计算贝塞尔曲线上的中心点
|
|
|
|
|
// 参考资料 https://stackoverflow.com/questions/54216448/how-to-find-a-middle-point-of-a-beizer-curve
|
|
|
|
|
// const lineCenterPoint = {
|
|
|
|
|
// x:
|
|
|
|
|
// (1 / 8) * startPoint.x +
|
|
|
|
|
// (3 / 8) * (controlPoint.x + 8) +
|
|
|
|
|
// (3 / 8) * centerPoint.x +
|
|
|
|
|
// (1 / 8) * (endPoint.x - 8),
|
|
|
|
|
// y:
|
|
|
|
|
// (1 / 8) * startPoint.y +
|
|
|
|
|
// (3 / 8) * controlPoint.y +
|
|
|
|
|
// (3 / 8) * centerPoint.y +
|
|
|
|
|
// (1 / 8) * endPoint.y
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
// 在贝塞尔曲线中心点上添加圆形
|
|
|
|
|
const { source, target } = cfg;
|
|
|
|
|
group.addShape("circle", {
|
|
|
|
|
attrs: {
|
|
|
|
|
id: `statusNode${source}-${target}`,
|
|
|
|
|
r: 6,
|
|
|
|
|
x: centerPoint.x,
|
|
|
|
|
y: centerPoint.y,
|
|
|
|
|
fill: cfg.active ? "#AB83E4" : "#ccc"
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return path;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const g = new dagre.graphlib.Graph();
|
|
|
|
|
g.setDefaultEdgeLabel(function() { return {}; });
|
|
|
|
|
g.setGraph({ rankdir: 'LR' });
|
|
|
|
|
|
|
|
|
|
data.nodes.forEach(node => {
|
|
|
|
|
g.setNode(node.id + '', { width: 150, height: 50 });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
data.edges.forEach(edge => {
|
|
|
|
|
edge.source = edge.source + '';
|
|
|
|
|
edge.target = edge.target + '';
|
|
|
|
|
g.setEdge(edge.source, edge.target);
|
|
|
|
|
});
|
|
|
|
|
dagre.layout(g);
|
|
|
|
|
|
|
|
|
|
let coord;
|
|
|
|
|
g.nodes().forEach((node, i) => {
|
|
|
|
|
coord = g.node(node);
|
|
|
|
|
data.nodes[i].x = coord.x;
|
|
|
|
|
data.nodes[i].y = coord.y;
|
|
|
|
|
});
|
|
|
|
|
g.edges().forEach((edge, i) => {
|
|
|
|
|
coord = g.edge(edge);
|
|
|
|
|
const startPoint = coord.points[0];
|
|
|
|
|
const endPoint = coord.points[coord.points.length - 1];
|
|
|
|
|
data.edges[i].startPoint = startPoint;
|
|
|
|
|
data.edges[i].endPoint = endPoint;
|
|
|
|
|
data.edges[i].controlPoints = coord.points.slice(
|
|
|
|
|
1,
|
|
|
|
|
coord.points.length - 1
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const graph = new G6.Graph({
|
|
|
|
|
container: "mountNode",
|
|
|
|
|
width: 1000,
|
|
|
|
|
height: 800,
|
|
|
|
|
defaultNode: {
|
2019-09-30 13:19:00 +08:00
|
|
|
|
shape: "rect-node",
|
2019-08-20 17:17:56 +08:00
|
|
|
|
labelCfg: {
|
|
|
|
|
style: {
|
|
|
|
|
fill: "#fff",
|
|
|
|
|
fontSize: 14
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
defaultEdge: {
|
2019-09-30 13:19:00 +08:00
|
|
|
|
shape: "line-with-point",
|
|
|
|
|
style: {
|
2019-08-20 17:17:56 +08:00
|
|
|
|
endArrow: true,
|
|
|
|
|
lineWidth: 2,
|
|
|
|
|
stroke: "#ccc"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
graph.data(data);
|
|
|
|
|
graph.render();
|
|
|
|
|
|
|
|
|
|
graph.on('edge:click', evt => {
|
|
|
|
|
const { target } = evt
|
|
|
|
|
const type = target.get('type')
|
|
|
|
|
if(type === 'circle') {
|
|
|
|
|
// 点击边上的circle
|
|
|
|
|
alert('你点击的是边上的圆点')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
</html>
|