<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定義流程圖</title>
<style>::-webkit-scrollbar{display:none;}html,body{overflow:hidden;margin:0;}</style>
</head>
<body>
<div id="mountNode"></div>
<script>/*Fixing iframe window.innerHeight 0 issue in Safari*/document.body.clientHeight;</script>
<script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.g6-3.1.0/build/g6.js"></script>
<script src="https://gw.alipayobjects.com/os/lib/dagre/0.8.4/dist/dagre.min.js"></script>
<script>
var _extends = Object.assign || function(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
/**
* 本案例演示如何使用G6自定義流程圖:
* 1、如何使用G6繪制流程圖;
* 2、如何在貝塞爾曲線上面自定義icon;
* 3、如何響應貝塞爾曲線上icon的點擊事件。
*
* by 一之
*
*/
/**
* node 特殊屬性
*/
var nodeExtraAttrs = {
begin: {
fill: "#9FD4FB"
},
end: {
fill: "#C2E999"
}
};
var 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("node", {
drawShape: function drawShape(cfg, group) {
var rect = group.addShape("rect", {
attrs: _extends({
x: -75,
y: -25,
width: 150,
height: 50,
radius: 4,
fill: "#FFD591",
fillOpacity: 1
}, nodeExtraAttrs[cfg.type])
});
return rect;
},
// 設置狀態
setState: function setState(name, value, item) {
var group = item.getContainer();
var shape = group.get("children")[0]; // 順序根據 draw 時確定
if (name === "selected") {
if (value) {
shape.attr("fill", "#F6C277");
} else {
shape.attr("fill", "#FFD591");
}
}
},
getAnchorPoints: function getAnchorPoints() {
return [[0, 0.5], [1, 0.5]];
}
}, "single-shape");
/**
* 自定義 edge 中心關系節點
*/
G6.registerNode("statusNode", {
drawShape: function drawShape(cfg, group) {
var circle = group.addShape("circle", {
attrs: {
x: 0,
y: 0,
r: 6,
fill: cfg.active ? "#AB83E4" : "#ccc"
}
});
return circle;
}
}, "single-shape");
/**
* 自定義帶箭頭的貝塞爾曲線 edge
*/
G6.registerEdge("line-with-arrow", {
itemType: "edge",
draw: function draw(cfg, group) {
var startPoint = cfg.startPoint;
var endPoint = cfg.endPoint;
var centerPoint = {
x: (startPoint.x + endPoint.x) / 2,
y: (startPoint.y + endPoint.y) / 2
};
// 控制點坐標
var controlPoint = {
x: (startPoint.x + centerPoint.x) / 2,
y: startPoint.y
};
console.log(cfg, startPoint, endPoint);
// 為了更好的展示效果, 對稱貝塞爾曲線需要連到箭頭根部
var 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
// 具體Util方法可以參考G:https://github.com/antvis/g/blob/4.x/packages/g-math/src/quadratic.ts
// 在貝塞爾曲線中心點上添加圓形
var source = cfg.source,
target = cfg.target;
group.addShape("circle", {
attrs: {
id: "statusNode" + source + "-" + target,
r: 6,
x: centerPoint.x,
y: centerPoint.y,
fill: cfg.active ? "#AB83E4" : "#ccc"
}
});
return path;
}
});
var g = new dagre.graphlib.Graph();
g.setDefaultEdgeLabel(function() {
return {};
});
g.setGraph({
rankdir: 'LR'
});
data.nodes.forEach(function(node) {
g.setNode(node.id + '', {
width: 150,
height: 50
});
});
data.edges.forEach(function(edge) {
edge.source = edge.source + '';
edge.target = edge.target + '';
g.setEdge(edge.source, edge.target);
});
dagre.layout(g);
var coord = void 0;
g.nodes().forEach(function(node, i) {
coord = g.node(node);
data.nodes[i].x = coord.x;
data.nodes[i].y = coord.y;
});
g.edges().forEach(function(edge, i) {
coord = g.edge(edge);
var startPoint = coord.points[0];
var 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);
});
var graph = new G6.Graph({
container: "mountNode",
width: 1000,
height: 800,
modes: {
default: ['drag-canvas']
},
defaultNode: {
shape: "node",
labelCfg: {
style: {
fill: "#fff",
fontSize: 14
}
}
},
defaultEdge: {
shape: "line-with-arrow"
},
edgeStyle: {
default: {
endArrow: true,
lineWidth: 2,
stroke: "#ccc"
}
}
});
graph.data(data);
graph.render();
graph.on('edge:click', function(evt) {
var target = evt.target;
var type = target.get('type');
if (type === 'circle') {
// 點擊邊上的circle
alert('你點擊的是邊上的圓點');
}
});
</script>
</body>
</html>