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

264 lines
5.5 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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",
{
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", {
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",
labelCfg: {
style: {
fill: "#fff",
fontSize: 14
}
}
},
defaultEdge: {
shape: "line-with-point",
style: {
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>