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

260 lines
6.1 KiB
HTML
Raw Normal View History

2019-08-20 17:17:56 +08:00
<!DOCTYPE html>
<html lang="en">
2020-02-14 10:10:54 +08:00
<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',
2019-08-20 17:17:56 +08:00
},
2020-02-14 10:10:54 +08:00
end: {
fill: '#C2E999',
2019-08-20 17:17:56 +08:00
},
2020-02-14 10:10:54 +08:00
};
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
{
2020-02-14 10:10:54 +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],
];
},
2019-08-20 17:17:56 +08:00
},
2020-02-14 10:10:54 +08:00
'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,
};
2019-08-20 17:17:56 +08:00
2020-02-14 10:10:54 +08:00
console.log(cfg, startPoint, endPoint);
// 为了更好的展示效果, 对称贝塞尔曲线需要连到箭头根部
const path = group.addShape('path', {
2019-08-20 17:17:56 +08:00
attrs: {
2020-02-14 10:10:54 +08:00
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,
},
},
2019-08-20 17:17:56 +08:00
});
2020-02-14 10:10:54 +08:00
// 计算贝塞尔曲线上的中心点
// 参考资料 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
// };
2019-08-20 17:17:56 +08:00
2020-02-14 10:10:54 +08:00
// 在贝塞尔曲线中心点上添加圆形
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',
},
});
2019-08-20 17:17:56 +08:00
2020-02-14 10:10:54 +08:00
return path;
},
2019-08-20 17:17:56 +08:00
});
2020-02-14 10:10:54 +08:00
const g = new dagre.graphlib.Graph();
g.setDefaultEdgeLabel(function() {
return {};
2019-08-20 17:17:56 +08:00
});
2020-02-14 10:10:54 +08:00
g.setGraph({ rankdir: 'LR' });
2019-08-20 17:17:56 +08:00
2020-02-14 10:10:54 +08:00
data.nodes.forEach(node => {
g.setNode(node.id + '', { width: 150, height: 50 });
});
2019-08-20 17:17:56 +08:00
2020-02-14 10:10:54 +08:00
data.edges.forEach(edge => {
edge.source = edge.source + '';
edge.target = edge.target + '';
g.setEdge(edge.source, edge.target);
});
dagre.layout(g);
2019-08-20 17:17:56 +08:00
2020-02-14 10:10:54 +08:00
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);
});
2019-08-20 17:17:56 +08:00
2020-02-14 10:10:54 +08:00
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',
2019-08-20 17:17:56 +08:00
style: {
2020-02-14 10:10:54 +08:00
endArrow: true,
lineWidth: 2,
stroke: '#ccc',
},
},
});
2019-08-20 17:17:56 +08:00
2020-02-14 10:10:54 +08:00
graph.data(data);
graph.render();
2019-08-20 17:17:56 +08:00
2020-02-14 10:10:54 +08:00
graph.on('edge:click', evt => {
const { target } = evt;
const type = target.get('type');
if (type === 'circle') {
// 点击边上的circle
alert('你点击的是边上的圆点');
}
});
</script>
</html>