You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.5 KiB
145 lines
4.5 KiB
4 years ago
|
/**
|
||
|
* Chord layout
|
||
|
* @module echarts/layout/Chord
|
||
|
* @author pissang(http://github.com/pissang)
|
||
|
*/
|
||
|
define(function (require) {
|
||
|
|
||
|
var ChordLayout = function (opts) {
|
||
|
|
||
|
opts = opts || {};
|
||
|
|
||
|
/**
|
||
|
* 是否排序组(即图的节点), 可以是`ascending`, `descending`, 或者为空不排序
|
||
|
* @type {string}
|
||
|
*/
|
||
|
this.sort = opts.sort || null;
|
||
|
/**
|
||
|
* 是否排序子组(即图中每个节点的邻接边), 可以是`ascending`, `descending`, 或者为空不排序
|
||
|
* @type {string}
|
||
|
*/
|
||
|
this.sortSub = opts.sortSub || null;
|
||
|
|
||
|
this.padding = 0.05;
|
||
|
|
||
|
this.startAngle = opts.startAngle || 0;
|
||
|
this.clockWise = opts.clockWise == null ? false : opts.clockWise;
|
||
|
|
||
|
this.center = opts.center || [0, 0];
|
||
|
|
||
|
this.directed = true;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* 对指定的一个或多个 Graph 运行 chord 布局
|
||
|
* 可以有多个 Graph, 后面几个 Graph 的节点是第一个 Graph 的节点的子集(ID一一对应)
|
||
|
*
|
||
|
* 布局结果保存在第一个 Graph 的每个节点的 layout.startAngle 和 layout.endAngle.
|
||
|
* 以及每个图的边的 layout.startAngle 和 layout.endAngle
|
||
|
*
|
||
|
* @param {Array.<module:echarts/data/Graph>|module:echarts/data/Graph} graphs
|
||
|
*/
|
||
|
ChordLayout.prototype.run = function (graphs) {
|
||
|
if (!(graphs instanceof Array)) {
|
||
|
graphs = [graphs];
|
||
|
}
|
||
|
|
||
|
var gl = graphs.length;
|
||
|
if (!gl) {
|
||
|
return;
|
||
|
}
|
||
|
var graph0 = graphs[0];
|
||
|
var nl = graph0.nodes.length;
|
||
|
|
||
|
var groups = [];
|
||
|
var sumSize = 0;
|
||
|
|
||
|
// 使用第一个 graph 的节点
|
||
|
for (var i = 0; i < nl; i++) {
|
||
|
var g0node = graph0.nodes[i];
|
||
|
var group = {
|
||
|
size: 0,
|
||
|
subGroups: [],
|
||
|
node: g0node
|
||
|
};
|
||
|
groups.push(group);
|
||
|
|
||
|
var sumWeight = 0;
|
||
|
|
||
|
// 合并所有 Graph 的 边
|
||
|
for (var k = 0; k < graphs.length; k++) {
|
||
|
var graph = graphs[k];
|
||
|
var node = graph.getNodeById(g0node.id);
|
||
|
// 节点可能没有值被过滤掉了
|
||
|
if (!node) {
|
||
|
continue;
|
||
|
}
|
||
|
group.size += node.layout.size;
|
||
|
// PENDING
|
||
|
var edges = this.directed ? node.outEdges : node.edges;
|
||
|
for (var j = 0; j < edges.length; j++) {
|
||
|
var e = edges[j];
|
||
|
var w = e.layout.weight;
|
||
|
group.subGroups.push({
|
||
|
weight: w,
|
||
|
edge: e,
|
||
|
graph: graph
|
||
|
});
|
||
|
sumWeight += w;
|
||
|
}
|
||
|
}
|
||
|
sumSize += group.size;
|
||
|
|
||
|
// Sum sub group weights to group size
|
||
|
var multiplier = group.size / sumWeight;
|
||
|
for (var j = 0; j < group.subGroups.length; j++) {
|
||
|
group.subGroups[j].weight *= multiplier;
|
||
|
}
|
||
|
|
||
|
if (this.sortSub === 'ascending') {
|
||
|
group.subGroups.sort(compareSubGroups);
|
||
|
}
|
||
|
else if (this.sort === 'descending') {
|
||
|
group.subGroups.sort(compareSubGroups);
|
||
|
group.subGroups.reverse();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (this.sort === 'ascending') {
|
||
|
groups.sort(compareGroups);
|
||
|
}
|
||
|
else if (this.sort === 'descending') {
|
||
|
groups.sort(compareGroups);
|
||
|
groups.reverse();
|
||
|
}
|
||
|
|
||
|
var multiplier = (Math.PI * 2 - this.padding * nl) / sumSize;
|
||
|
var angle = this.startAngle;
|
||
|
var sign = this.clockWise ? 1 : -1;
|
||
|
// Calculate angles
|
||
|
for (var i = 0; i < nl; i++) {
|
||
|
var group = groups[i];
|
||
|
group.node.layout.startAngle = angle;
|
||
|
group.node.layout.endAngle = angle + sign * group.size * multiplier;
|
||
|
|
||
|
group.node.layout.subGroups = [];
|
||
|
for (var j = 0; j < group.subGroups.length; j++) {
|
||
|
var subGroup = group.subGroups[j];
|
||
|
subGroup.edge.layout.startAngle = angle;
|
||
|
angle += sign * subGroup.weight * multiplier;
|
||
|
subGroup.edge.layout.endAngle = angle;
|
||
|
}
|
||
|
angle = group.node.layout.endAngle + sign * this.padding;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
var compareSubGroups = function (a, b) {
|
||
|
return a.weight - b.weight;
|
||
|
};
|
||
|
|
||
|
var compareGroups = function (a, b) {
|
||
|
return a.size - b.size;
|
||
|
};
|
||
|
|
||
|
return ChordLayout;
|
||
|
});
|