mirror of
https://gitee.com/antv/g6.git
synced 2024-12-05 05:09:07 +08:00
refactor(util): refactor radial layout method & add demo
This commit is contained in:
parent
cad47b4b25
commit
004cb3ce56
1224
demos/assets/hierarchy.js
Normal file
1224
demos/assets/hierarchy.js
Normal file
File diff suppressed because it is too large
Load Diff
151
demos/tree-graph.html
Normal file
151
demos/tree-graph.html
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
<script src="../test/unit/graph/tree-graph-spec.js"></script>
|
||||||
|
</head>
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<select id="layout">
|
||||||
|
<option value="dendrogram">基础树</option>
|
||||||
|
<option value="compactBox">紧凑树</option>
|
||||||
|
</select>
|
||||||
|
<input type="checkbox" id="radial" /><label for="radial">环形布局</label>
|
||||||
|
<div id="mountNode"></div>
|
||||||
|
<script src="assets/hierarchy.js"></script>
|
||||||
|
<script src="../build/g6.js"></script>
|
||||||
|
<script>
|
||||||
|
let currentLayout = 'dendrogram';
|
||||||
|
let radial = false;
|
||||||
|
const layouts = {
|
||||||
|
dendrogram: function(data) {
|
||||||
|
return Hierarchy.dendrogram(data, {
|
||||||
|
direction: 'LR', // H / V / LR / RL / TB / BT
|
||||||
|
nodeSep: 50,
|
||||||
|
rankSep: 100
|
||||||
|
})},
|
||||||
|
compactBox: function(data) {
|
||||||
|
return Hierarchy.compactBox(data, { direction: 'LR' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const graph = new G6.TreeGraph({
|
||||||
|
container: 'mountNode',
|
||||||
|
width: 500,
|
||||||
|
height: 500,
|
||||||
|
pixelRatio: 2,
|
||||||
|
modes: {
|
||||||
|
default: [{
|
||||||
|
type: 'collapse-expand',
|
||||||
|
onChange(item, collapsed) {
|
||||||
|
const data = item.get('model').data;
|
||||||
|
data.collapsed = collapsed;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}, 'drag-canvas']
|
||||||
|
},
|
||||||
|
layout: layouts.dendrogram
|
||||||
|
});
|
||||||
|
const data = {
|
||||||
|
isRoot: true,
|
||||||
|
id: 'Root',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'SubTreeNode1',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'SubTreeNode1.1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'SubTreeNode1.2'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'SubTreeNode2',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'SubTreeNode2.1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'SubTreeNode2.2',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'SubTreeNode1.2.1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'SubTreeNode1.2.2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'SubTreeNode1.2.3'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
id: 'SubTreeNode3'
|
||||||
|
}, {
|
||||||
|
id: 'SubTreeNode4'
|
||||||
|
}, {
|
||||||
|
id: 'SubTreeNode5'
|
||||||
|
}, {
|
||||||
|
id: 'SubTreeNode6'
|
||||||
|
}, {
|
||||||
|
id: 'SubTreeNode7',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'SubTreeNode3.1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'SubTreeNode3.2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'SubTreeNode3.3'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
id: 'SubTreeNode8'
|
||||||
|
}, {
|
||||||
|
id: 'SubTreeNode9'
|
||||||
|
}, {
|
||||||
|
id: 'SubTreeNode10'
|
||||||
|
}, {
|
||||||
|
id: 'SubTreeNode11'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
graph.data(data);
|
||||||
|
graph.render();
|
||||||
|
graph.fitView();
|
||||||
|
document.getElementById('radial').addEventListener('change', e => {
|
||||||
|
if (e.target.checked) {
|
||||||
|
graph.set('layout', (data) => {
|
||||||
|
data = layouts[currentLayout](data);
|
||||||
|
G6.Util.radialLayout(data);
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
graph.render();
|
||||||
|
graph.fitView();
|
||||||
|
} else {
|
||||||
|
radial = false;
|
||||||
|
graph.set('layout', layouts[currentLayout]);
|
||||||
|
graph.render();
|
||||||
|
graph.fitView();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
document.getElementById('layout').addEventListener('change', (e) => {
|
||||||
|
const layout = e.target.value;
|
||||||
|
if (currentLayout !== layout) {
|
||||||
|
currentLayout = layout;
|
||||||
|
graph.set('layout', layouts[currentLayout]);
|
||||||
|
graph.render();
|
||||||
|
if (radial) {
|
||||||
|
G6.Util.radialLayout(graph, 'LR');
|
||||||
|
}
|
||||||
|
graph.fitView();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -124,7 +124,7 @@ module.exports = {
|
|||||||
x: data.x,
|
x: data.x,
|
||||||
y: data.y
|
y: data.y
|
||||||
};
|
};
|
||||||
if (!point.x || !point.y) {
|
if (Util.isNil(point.x) || Util.isNil(point.y)) {
|
||||||
const model = node.get('parent').get('model');
|
const model = node.get('parent').get('model');
|
||||||
point.x = model.x;
|
point.x = model.x;
|
||||||
point.y = model.y;
|
point.y = model.y;
|
||||||
|
@ -4,6 +4,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const MathUtil = require('./math');
|
const MathUtil = require('./math');
|
||||||
|
const BaseUtil = require('./base');
|
||||||
|
|
||||||
|
function traverse(data, fn) {
|
||||||
|
if (fn(data) === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BaseUtil.each(data.children, child => {
|
||||||
|
traverse(child, fn);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const GraphicUtil = {
|
const GraphicUtil = {
|
||||||
getBBox(element, parent) {
|
getBBox(element, parent) {
|
||||||
@ -30,12 +40,15 @@ const GraphicUtil = {
|
|||||||
maxY: rightBottom.y
|
maxY: rightBottom.y
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
radialLayout(graph, layout) {
|
traverseTree(data, fn) {
|
||||||
|
if (typeof fn !== 'function') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
traverse(data, fn);
|
||||||
|
},
|
||||||
|
radialLayout(data, layout) {
|
||||||
// 布局方式有 H / V / LR / RL / TB / BT
|
// 布局方式有 H / V / LR / RL / TB / BT
|
||||||
const VERTICAL_LAYOUTS = [ 'V', 'TB', 'BT' ];
|
const VERTICAL_LAYOUTS = [ 'V', 'TB', 'BT' ];
|
||||||
const width = graph.get('width');
|
|
||||||
const height = graph.get('height');
|
|
||||||
const radius = Math.min(width, height);
|
|
||||||
const min = {
|
const min = {
|
||||||
x: Infinity,
|
x: Infinity,
|
||||||
y: Infinity
|
y: Infinity
|
||||||
@ -52,32 +65,31 @@ const GraphicUtil = {
|
|||||||
radScale = 'x';
|
radScale = 'x';
|
||||||
rScale = 'y';
|
rScale = 'y';
|
||||||
}
|
}
|
||||||
graph.get('nodes').forEach(node => {
|
let count = 0;
|
||||||
const model = node.get('model');
|
this.traverseTree(data, node => {
|
||||||
if (model.x > max.x) {
|
count++;
|
||||||
max.x = model.x;
|
if (node.x > max.x) {
|
||||||
|
max.x = node.x;
|
||||||
}
|
}
|
||||||
if (model.x < min.x) {
|
if (node.x < min.x) {
|
||||||
min.x = model.x;
|
min.x = node.x;
|
||||||
}
|
}
|
||||||
if (model.y > max.y) {
|
if (node.y > max.y) {
|
||||||
max.y = model.y;
|
max.y = node.y;
|
||||||
}
|
}
|
||||||
if (model.y < min.y) {
|
if (node.y < min.y) {
|
||||||
min.y = model.y;
|
min.y = node.y;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const avgRad = Math.PI * 2 / graph.get('nodes').length;
|
const avgRad = Math.PI * 2 / count;
|
||||||
const radDiff = max[radScale] - min[radScale];
|
const radDiff = max[radScale] - min[radScale];
|
||||||
graph.get('nodes').forEach(node => {
|
this.traverseTree(data, node => {
|
||||||
const model = node.get('model');
|
const radial = (node[radScale] - min[radScale]) / radDiff * (Math.PI * 2 - avgRad) + avgRad;
|
||||||
const radial = (model[radScale] - min[radScale]) / radDiff * (Math.PI * 2 - avgRad) + avgRad;
|
const r = node[rScale];
|
||||||
const r = model[rScale] / max[rScale] * radius;
|
node.x = r * Math.cos(radial);
|
||||||
model.x = r * Math.cos(radial);
|
node.y = r * Math.sin(radial);
|
||||||
model.y = r * Math.sin(radial);
|
|
||||||
});
|
});
|
||||||
graph.refreshPositions();
|
return data;
|
||||||
graph.fitView();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -441,7 +441,7 @@ describe('tree graph with layout', () => {
|
|||||||
graph.emit('node:click', { item: parent });
|
graph.emit('node:click', { item: parent });
|
||||||
}, 600);
|
}, 600);
|
||||||
});
|
});
|
||||||
const treeData = {
|
/* const treeData = {
|
||||||
isRoot: true,
|
isRoot: true,
|
||||||
id: 'Root',
|
id: 'Root',
|
||||||
children: [
|
children: [
|
||||||
@ -535,5 +535,5 @@ describe('tree graph with layout', () => {
|
|||||||
graph.data(treeData);
|
graph.data(treeData);
|
||||||
graph.render();
|
graph.render();
|
||||||
G6.Util.radialLayout(graph, 'TB');
|
G6.Util.radialLayout(graph, 'TB');
|
||||||
});
|
});*/
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user