mirror of
https://gitee.com/antv/g6.git
synced 2024-12-02 03:38:20 +08:00
303 lines
6.6 KiB
HTML
303 lines
6.6 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Dagre Layout</title>
|
|
</head>
|
|
<style>
|
|
.g6-tooltip {
|
|
border: 1px solid #e2e2e2;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
color: #545454;
|
|
background-color: rgba(255, 255, 255, 0.9);
|
|
padding: 10px 8px;
|
|
box-shadow: rgb(174, 174, 174) 0px 0px 10px;
|
|
}
|
|
</style>
|
|
<body>
|
|
<div id="mountNode"></div>
|
|
<script src="../build/dagre.js"></script>
|
|
<script src="../build/g6.js"></script>
|
|
<script>
|
|
const data = {
|
|
nodes: [{
|
|
id: '1',
|
|
label: '1'
|
|
},
|
|
{
|
|
id: '2',
|
|
label: '2'
|
|
},
|
|
{
|
|
id: '3',
|
|
label: '3'
|
|
},
|
|
{
|
|
id: '4',
|
|
label: '4'
|
|
},
|
|
{
|
|
id: '5',
|
|
label: '5'
|
|
},
|
|
{
|
|
id: '6',
|
|
label: '6'
|
|
},
|
|
{
|
|
id: '7',
|
|
label: '7'
|
|
},
|
|
{
|
|
id: '8',
|
|
label: '8',
|
|
isLeaf: true
|
|
},
|
|
{
|
|
id: '9',
|
|
label: '9',
|
|
isLeaf: true
|
|
},
|
|
{
|
|
id: '10',
|
|
label: '10',
|
|
isLeaf: true
|
|
},
|
|
{
|
|
id: '11',
|
|
label: '11',
|
|
isLeaf: true
|
|
},
|
|
{
|
|
id: '12',
|
|
label: '12',
|
|
isLeaf: true
|
|
},
|
|
{
|
|
id: '13',
|
|
label: '13',
|
|
isLeaf: true
|
|
},
|
|
{
|
|
id: '14',
|
|
label: '14',
|
|
isLeaf: true
|
|
},
|
|
{
|
|
id: '15',
|
|
label: '15',
|
|
isLeaf: true
|
|
},
|
|
{
|
|
id: '16',
|
|
label: '16',
|
|
isLeaf: true
|
|
},
|
|
{
|
|
id: '17',
|
|
label: '17',
|
|
isLeaf: true
|
|
},
|
|
{
|
|
id: '18',
|
|
label: '18',
|
|
isLeaf: true
|
|
},
|
|
{
|
|
id: '19',
|
|
label: '19',
|
|
isLeaf: true
|
|
}],
|
|
edges: [{
|
|
source: '1',
|
|
target: '2'
|
|
},
|
|
{
|
|
source: '1',
|
|
target: '3'
|
|
},
|
|
{
|
|
source: '3',
|
|
target: '4'
|
|
},
|
|
{
|
|
source: '2',
|
|
target: '5'
|
|
},
|
|
{
|
|
source: '5',
|
|
target: '6'
|
|
},
|
|
{
|
|
source: '5',
|
|
target: '7'
|
|
},
|
|
{
|
|
source: '7',
|
|
target: '8'
|
|
},
|
|
{
|
|
source: '6',
|
|
target: '9'
|
|
},
|
|
{
|
|
source: '6',
|
|
target: '10'
|
|
},
|
|
{
|
|
source: '6',
|
|
target: '11'
|
|
},
|
|
{
|
|
source: '6',
|
|
target: '12'
|
|
},
|
|
{
|
|
source: '6',
|
|
target: '13'
|
|
},
|
|
{
|
|
source: '6',
|
|
target: '14'
|
|
},
|
|
{
|
|
source: '4',
|
|
target: '15'
|
|
},
|
|
{
|
|
source: '4',
|
|
target: '16'
|
|
},
|
|
{
|
|
source: '4',
|
|
target: '17'
|
|
},
|
|
{
|
|
source: '4',
|
|
target: '18'
|
|
},
|
|
{
|
|
source: '4',
|
|
target: '19'
|
|
}]
|
|
};
|
|
|
|
const graph = new G6.Graph({
|
|
container: 'mountNode',
|
|
width: 1000,
|
|
height: 700,
|
|
modes: {
|
|
default: ['drag-node', 'drag-canvas']
|
|
},
|
|
defaultNode: {
|
|
shape: 'rect',// hexagon
|
|
color: 'steelblue'
|
|
},
|
|
defaultEdge: {
|
|
style: {
|
|
stroke: '#aaa'
|
|
}
|
|
}
|
|
});
|
|
const nodes = data.nodes;
|
|
const edges = data.edges;
|
|
const nodeMap = new Map();
|
|
const branchNodes = [];
|
|
const branchEdges = [];
|
|
const leafGroups = {};
|
|
const branchNodesMap = new Map();
|
|
const leafGroupOffset = 100;
|
|
// separate the leaves and branch nodes
|
|
nodes.forEach((node, i) => {
|
|
nodeMap.set(node.id, node);
|
|
if (node.isLeaf) {
|
|
node.size = 30;
|
|
node.shape = 'circle';
|
|
edges.forEach(edge => {
|
|
if (edge.source === node.id) {
|
|
node.parent = edge.target;
|
|
} else if (edge.target === node.id) {
|
|
node.parent = edge.source;
|
|
}
|
|
});
|
|
if (!leafGroups[node.parent]) leafGroups[node.parent] = [];
|
|
leafGroups[node.parent].push(node);
|
|
} else {
|
|
branchNodes.push(node);
|
|
branchNodesMap.set(node.id, node);
|
|
}
|
|
});
|
|
edges.forEach(edge => {
|
|
if (branchNodesMap.get(edge.source) !== undefined
|
|
&& branchNodesMap.get(edge.target) !== undefined) {
|
|
branchEdges.push(edge);
|
|
}
|
|
});
|
|
// layout the nodes with isLeaf === false by dagre
|
|
const dagreLayout = new G6.Layout['dagre']({
|
|
nodesep: 50,
|
|
ranksep: 10
|
|
});
|
|
dagreLayout.init({ nodes: branchNodes, edges: branchEdges });
|
|
dagreLayout.execute();
|
|
|
|
//layout the leaves with isLeaf === true by force
|
|
const forceLayoutsMap = new Map();
|
|
Object.keys(leafGroups).forEach(function(parentId){
|
|
const lg = leafGroups[parentId];
|
|
const parent = branchNodesMap.get(parentId);
|
|
const center = [ parent.x, parent.y + leafGroupOffset ];
|
|
const forceLayout = new G6.Layout['force']({
|
|
center,
|
|
linkDistance: 0,
|
|
nodeStrength: 30,
|
|
collideStrength: 0.7,
|
|
alphaDecay: 0.01,
|
|
preventOverlap: true,
|
|
tick: () => {
|
|
graph.refreshPositions();
|
|
}
|
|
});
|
|
forceLayout.init({ nodes: lg, edges: [] });
|
|
forceLayout.execute();
|
|
forceLayoutsMap.set(parentId, forceLayout);
|
|
});
|
|
|
|
graph.positionsAnimate();
|
|
|
|
graph.data(data);
|
|
graph.render();
|
|
|
|
function refreshDragedNodePosition(e) {
|
|
const model = e.item.get('model');
|
|
model.fx = e.x;
|
|
model.fy = e.y;
|
|
}
|
|
graph.on('node:dragstart', e => {
|
|
const model = e.item.get('model');
|
|
if (model.isLeaf) {
|
|
const layoutMethod = forceLayoutsMap.get(model.parent);
|
|
layoutMethod.ticking = false;
|
|
layoutMethod.forceSimulation.stop();
|
|
layoutMethod.execute();
|
|
refreshDragedNodePosition(e);
|
|
}
|
|
});
|
|
graph.on('node:drag', e => {
|
|
const model = e.item.get('model');
|
|
if (model.isLeaf) {
|
|
refreshDragedNodePosition(e);
|
|
}
|
|
});
|
|
graph.on('node:dragend', e => {
|
|
const model = e.item.get('model');
|
|
if (model.isLeaf) {
|
|
e.item.get('model').fx = null;
|
|
e.item.get('model').fy = null;
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |