mirror of
https://gitee.com/antv/g6.git
synced 2024-12-05 05:09:07 +08:00
feat(tree-graph): add util method to convert tree layout to radial tree layout
This commit is contained in:
parent
e4c549b0a6
commit
cad47b4b25
@ -29,6 +29,55 @@ const GraphicUtil = {
|
||||
maxX: rightBottom.x,
|
||||
maxY: rightBottom.y
|
||||
};
|
||||
},
|
||||
radialLayout(graph, layout) {
|
||||
// 布局方式有 H / V / LR / RL / 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 = {
|
||||
x: Infinity,
|
||||
y: Infinity
|
||||
};
|
||||
const max = {
|
||||
x: -Infinity,
|
||||
y: -Infinity
|
||||
};
|
||||
// 默认布局是垂直布局TB,此时x对应rad,y对应r
|
||||
let rScale = 'x';
|
||||
let radScale = 'y';
|
||||
if (layout && VERTICAL_LAYOUTS.indexOf(layout) >= 0) {
|
||||
// 若是水平布局,y对应rad,x对应r
|
||||
radScale = 'x';
|
||||
rScale = 'y';
|
||||
}
|
||||
graph.get('nodes').forEach(node => {
|
||||
const model = node.get('model');
|
||||
if (model.x > max.x) {
|
||||
max.x = model.x;
|
||||
}
|
||||
if (model.x < min.x) {
|
||||
min.x = model.x;
|
||||
}
|
||||
if (model.y > max.y) {
|
||||
max.y = model.y;
|
||||
}
|
||||
if (model.y < min.y) {
|
||||
min.y = model.y;
|
||||
}
|
||||
});
|
||||
const avgRad = Math.PI * 2 / graph.get('nodes').length;
|
||||
const radDiff = max[radScale] - min[radScale];
|
||||
graph.get('nodes').forEach(node => {
|
||||
const model = node.get('model');
|
||||
const radial = (model[radScale] - min[radScale]) / radDiff * (Math.PI * 2 - avgRad) + avgRad;
|
||||
const r = model[rScale] / max[rScale] * radius;
|
||||
model.x = r * Math.cos(radial);
|
||||
model.y = r * Math.sin(radial);
|
||||
});
|
||||
graph.refreshPositions();
|
||||
graph.fitView();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -441,117 +441,99 @@ describe('tree graph with layout', () => {
|
||||
graph.emit('node:click', { item: parent });
|
||||
}, 600);
|
||||
});
|
||||
it('radial layout', () => {
|
||||
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();
|
||||
let minX = 999;
|
||||
let maxX = -999;
|
||||
let minY = 999;
|
||||
let maxY = -999;
|
||||
graph.get('nodes').forEach(node => {
|
||||
const model = node.get('model');
|
||||
if (model.x > maxX) {
|
||||
maxX = model.x;
|
||||
}
|
||||
if (model.x < minX) {
|
||||
minX = model.x;
|
||||
}
|
||||
if (model.y > maxY) {
|
||||
maxY = model.y;
|
||||
}
|
||||
if (model.y < minY) {
|
||||
minY = model.y;
|
||||
}
|
||||
});
|
||||
const deltaY = maxY - minY;
|
||||
const avgRad = Math.PI * 2 / graph.get('nodes').length;
|
||||
graph.get('nodes').forEach(node => {
|
||||
const model = node.get('model');
|
||||
const radial = ((model.y - minY) / deltaY) * (Math.PI * 2 - avgRad) + avgRad;
|
||||
const r = model.x;
|
||||
model.x = r * Math.cos(radial);
|
||||
model.y = r * Math.sin(radial);
|
||||
});
|
||||
graph.refreshPositions();
|
||||
graph.fitView();
|
||||
graph.addBehaviors({
|
||||
type: 'collapse-expand',
|
||||
onChange: (item, collapsed) => {
|
||||
const data = item.get('model').data;
|
||||
data.collapsed = collapsed;
|
||||
return true;
|
||||
const treeData = {
|
||||
isRoot: true,
|
||||
id: 'Root',
|
||||
children: [
|
||||
{
|
||||
id: 'SubTreeNode1',
|
||||
children: [
|
||||
{
|
||||
id: 'SubTreeNode1.1'
|
||||
},
|
||||
{
|
||||
id: 'SubTreeNode1.2'
|
||||
}
|
||||
]
|
||||
},
|
||||
animate: {
|
||||
duration: 500
|
||||
} }, 'default');
|
||||
{
|
||||
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'
|
||||
}
|
||||
]
|
||||
};
|
||||
it('radial layout', () => {
|
||||
graph.data(treeData);
|
||||
graph.render();
|
||||
G6.Util.radialLayout(graph, 'LR');
|
||||
});
|
||||
it('vertical layout to radial layout', () => {
|
||||
const graph = new G6.TreeGraph({
|
||||
container: div,
|
||||
width: 500,
|
||||
height: 500,
|
||||
pixelRatio: 2,
|
||||
modes: {
|
||||
default: [ 'drag-canvas' ]
|
||||
},
|
||||
layout: data => {
|
||||
count++;
|
||||
return Hierarchy.dendrogram(data, {
|
||||
direction: 'TB', // H / V / LR / RL / TB / BT
|
||||
nodeSep: 50,
|
||||
rankSep: 100
|
||||
});
|
||||
}
|
||||
});
|
||||
graph.data(treeData);
|
||||
graph.render();
|
||||
G6.Util.radialLayout(graph, 'TB');
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user