g6/demos/custom-edge-point-line.html

264 lines
5.5 KiB
HTML
Raw Normal View History

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(
"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
*/
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: {
shape: "rect-node",
2019-08-20 17:17:56 +08:00
labelCfg: {
style: {
fill: "#fff",
fontSize: 14
}
}
},
defaultEdge: {
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>