mirror of
https://gitee.com/antv/g6.git
synced 2024-12-04 20:59:15 +08:00
fix: force layout overlap bug; add: tree and bubble leaves demo
This commit is contained in:
parent
75869536dc
commit
9c7e8f8118
302
demos/tree-and-bubble-leaves.html
Normal file
302
demos/tree-and-bubble-leaves.html
Normal file
@ -0,0 +1,302 @@
|
||||
<!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.excute();
|
||||
|
||||
//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: 50,
|
||||
preventOverlap: true,
|
||||
tick: () => {
|
||||
graph.refreshPositions();
|
||||
}
|
||||
});
|
||||
forceLayout.init({ nodes: lg, edges: [] });
|
||||
forceLayout.excute();
|
||||
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.excute();
|
||||
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>
|
@ -110,6 +110,7 @@ Layout.registerLayout('force', {
|
||||
* @param {object} simulation 力模拟模型
|
||||
*/
|
||||
overlapProcess(simulation) {
|
||||
const self = this;
|
||||
let nodeSize = self.nodeSize;
|
||||
if (!nodeSize) {
|
||||
nodeSize = d => {
|
||||
|
Loading…
Reference in New Issue
Block a user