mirror of
https://gitee.com/antv/g6.git
synced 2024-12-05 05:09:07 +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 力模拟模型
|
* @param {object} simulation 力模拟模型
|
||||||
*/
|
*/
|
||||||
overlapProcess(simulation) {
|
overlapProcess(simulation) {
|
||||||
|
const self = this;
|
||||||
let nodeSize = self.nodeSize;
|
let nodeSize = self.nodeSize;
|
||||||
if (!nodeSize) {
|
if (!nodeSize) {
|
||||||
nodeSize = d => {
|
nodeSize = d => {
|
||||||
|
Loading…
Reference in New Issue
Block a user