mirror of
https://gitee.com/antv/g6.git
synced 2024-12-06 05:38:47 +08:00
213 lines
5.1 KiB
HTML
213 lines
5.1 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html lang="en">
|
||
|
<head>
|
||
|
<meta charset="UTF-8">
|
||
|
<title>重新布局不改变视窗</title>
|
||
|
</head>
|
||
|
<body>
|
||
|
<button id='changeView'>改变布局</button>
|
||
|
<div id="mountNode"></div>
|
||
|
<script src="../build/g6.js"></script>
|
||
|
<script src="../build//grid.js"></script>
|
||
|
<script>
|
||
|
|
||
|
G6.registerBehavior('click-add-node', {
|
||
|
getEvents() {
|
||
|
return {
|
||
|
'node:click': 'onClick'
|
||
|
};
|
||
|
},
|
||
|
onClick(ev) {
|
||
|
const itemModel = ev.item.getModel();
|
||
|
clickedNodeId = itemModel.id;
|
||
|
const graph = this.graph;
|
||
|
const nodes = graph.getNodes();
|
||
|
const edges = graph.getEdges();
|
||
|
let newData;
|
||
|
if (itemModel.id == 2) {
|
||
|
newData = data2_m;
|
||
|
} else {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
let newNodeModels = newData.nodes;
|
||
|
let newEdgeModels = [];
|
||
|
// deduplication the items in newEdgeModels
|
||
|
newData.edges.forEach(e => {
|
||
|
let exist = false;
|
||
|
newEdgeModels.forEach(ne => {
|
||
|
if(ne.source === e.source && ne.target === e.target) exist = true;
|
||
|
});
|
||
|
if(!exist) {
|
||
|
newEdgeModels.push(e);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// for graph.changeData()
|
||
|
const allNodeModels = [];
|
||
|
const allEdgeModels = [];
|
||
|
|
||
|
// add new nodes to graph
|
||
|
const nodeMap = new Map();
|
||
|
nodes.forEach((n, i)=>{
|
||
|
const nModel = n.getModel();
|
||
|
nodeMap.set(nModel.id, i);
|
||
|
});
|
||
|
|
||
|
newNodeModels.forEach((nodeModel, i) => {
|
||
|
if (nodeMap.get(nodeModel.id) === undefined) {
|
||
|
// set the initial positions of the new nodes to the focus(clicked) node
|
||
|
nodeModel.x = itemModel.x;
|
||
|
nodeModel.y = itemModel.y;
|
||
|
const node = graph.addItem('node', nodeModel);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// add new edges to graph
|
||
|
const edgeMap = new Map();
|
||
|
edges.forEach((e, i)=>{
|
||
|
const eModel = e.getModel();
|
||
|
edgeMap.set(eModel.source+","+eModel.target, i);
|
||
|
});
|
||
|
|
||
|
const oldEdgeNum = edges.length;
|
||
|
newEdgeModels.forEach((em, i) => {
|
||
|
const exist = edgeMap.get(em.source+","+em.target);
|
||
|
if (exist === undefined) {
|
||
|
const edge = graph.addItem('edge', em);
|
||
|
edgeMap.set(em.source+","+em.target, oldEdgeNum+i);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
edges.forEach((e, i) => {
|
||
|
allEdgeModels.push(e.getModel());
|
||
|
});
|
||
|
|
||
|
nodes.forEach((n, i) => {
|
||
|
allNodeModels.push(n.getModel());
|
||
|
});
|
||
|
// the max degree about foces(clicked) node in the newly added data
|
||
|
const maxDegree = 4;
|
||
|
// the max degree about foces(clicked) node in the original data
|
||
|
const oMaxDegree = 3;
|
||
|
const unitRadius = 40;
|
||
|
const focusNodeId = "2";
|
||
|
// re-place the clicked node far away the exisiting items
|
||
|
// along the radius from center node to it
|
||
|
const vx = itemModel.x - focusNode.x;
|
||
|
const vy = itemModel.y - focusNode.y;
|
||
|
const vlength = Math.sqrt(vx*vx+vy*vy);
|
||
|
const ideallength = unitRadius * maxDegree + mainUnitRadius * oMaxDegree;
|
||
|
itemModel.x = ideallength * vx / vlength + focusNode.x;
|
||
|
itemModel.y = ideallength * vy / vlength + focusNode.y;
|
||
|
|
||
|
const subRadialLayout = new Radial({
|
||
|
center: [ itemModel.x, itemModel.y ],
|
||
|
maxIteration: 200,
|
||
|
focusNode: "2",
|
||
|
unitRadius,
|
||
|
linkDistance: 180
|
||
|
});
|
||
|
graph.addPlugin(subRadialLayout);
|
||
|
// only layout the newly added part around the clicked node
|
||
|
subRadialLayout.layout(
|
||
|
{
|
||
|
'nodes': newNodeModels,
|
||
|
'edges': newEdgeModels
|
||
|
}
|
||
|
);
|
||
|
graph.changeData({"nodes": allNodeModels, "edges": allEdgeModels});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
const grid = new Grid()
|
||
|
const graph = new G6.TreeGraph({
|
||
|
plugins: [grid],
|
||
|
container: 'mountNode',
|
||
|
width: 500,
|
||
|
height: 500,
|
||
|
defaultNode: {
|
||
|
size: [20, 20]
|
||
|
},
|
||
|
modes: {
|
||
|
default: [ 'drag-node', 'drag-canvas', {
|
||
|
type: 'collapse-expand',
|
||
|
onChange(item, collapsed) {
|
||
|
const data = item.getModel()
|
||
|
data.collapsed = collapsed
|
||
|
return true
|
||
|
}
|
||
|
} ]
|
||
|
},
|
||
|
nodeStyle: {
|
||
|
default: {
|
||
|
fill: '#40a9ff',
|
||
|
stroke: '#096dd9'
|
||
|
}
|
||
|
},
|
||
|
edgeStyle: {
|
||
|
default: {
|
||
|
stroke: '#A3B1BF'
|
||
|
}
|
||
|
},
|
||
|
defaultEdge: {
|
||
|
shape: 'cubic-horizontal'
|
||
|
},
|
||
|
layout: {
|
||
|
type: 'dendrogram',
|
||
|
nodeSep: 50,
|
||
|
rankSep: 100,
|
||
|
direction: 'LR'
|
||
|
}
|
||
|
});
|
||
|
|
||
|
let data = {
|
||
|
isRoot: true,
|
||
|
id: 'Root',
|
||
|
style: {
|
||
|
fill: 'red'
|
||
|
},
|
||
|
children: [
|
||
|
{
|
||
|
id: 'SubTreeNode1',
|
||
|
raw: {},
|
||
|
children: [
|
||
|
{
|
||
|
id: 'SubTreeNode1.1'
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
id: 'SubTreeNode2',
|
||
|
children: [
|
||
|
{
|
||
|
id: 'SubTreeNode2.1'
|
||
|
},
|
||
|
{
|
||
|
id: 'SubTreeNode2.2'
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
};
|
||
|
|
||
|
graph.data(data)
|
||
|
graph.render()
|
||
|
|
||
|
graph.fitView()
|
||
|
|
||
|
document.getElementById('changeView').addEventListener('click', (evt) => {
|
||
|
const matrix = G6.Util.clone(graph.get('group').getMatrix())
|
||
|
data.children.pop()
|
||
|
graph.changeData(data)
|
||
|
graph.get('group').setMatrix(matrix)
|
||
|
graph.paint()
|
||
|
})
|
||
|
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|