d3/d3.layout.js

153 строки
3.4 KiB
JavaScript
Исходник Обычный вид История

d3["layout"] = {};
d3["layout"]["chord"] = function() {
var chord = {},
chords,
groups,
matrix,
n,
padding = 0,
sortGroups,
sortSubgroups,
sortChords;
function relayout() {
var subgroups = {},
groupSums = [],
groupIndex = d3.range(n),
subgroupIndex = [],
k,
x,
x0,
i,
j;
chords = [];
groups = [];
// Compute the sum.
k = 0, i = -1; while (++i < n) {
x = 0, j = -1; while (++j < n) {
x += matrix[i][j];
}
groupSums.push(x);
subgroupIndex.push(d3.range(n));
k += x;
}
// Sort groups…
if (sortGroups) {
groupIndex.sort(function(a, b) {
return sortGroups(groupSums[a], groupSums[b]);
});
}
// Sort subgroups…
if (sortSubgroups) {
subgroupIndex.forEach(function(d, i) {
d.sort(function(a, b) {
return sortSubgroups(matrix[i][a], matrix[i][b]);
});
});
}
// Convert the sum to scaling factor for [0, 2pi].
// TODO Allow start and end angle to be specified.
// TODO Allow padding to be specified as percentage?
k = (2 * Math.PI - padding * n) / k;
// Compute the start and end angle for each group and subgroup.
x = 0, i = -1; while (++i < n) {
x0 = x, j = -1; while (++j < n) {
var di = groupIndex[i],
dj = subgroupIndex[di][j],
v = matrix[di][dj];
subgroups[i + "-" + j] = {
"index": di,
"subindex": dj,
"startAngle": x,
"endAngle": x += v * k,
"value": v
};
}
groups.push({
"index": di,
"startAngle": x0,
"endAngle": x,
"value": (x - x0) / k
});
x += padding;
}
// Generate chords for each (non-empty) subgroup-subgroup link.
i = -1; while (++i < n) {
j = i - 1; while (++j < n) {
var source = subgroups[i + "-" + j],
target = subgroups[j + "-" + i];
if (source["value"] || target["value"]) {
chords.push({
"source": source,
"target": target
})
}
}
}
if (sortChords) resort();
}
function resort() {
chords.sort(function(a, b) {
a = Math.min(a["source"]["value"], a["target"]["value"]);
b = Math.min(b["source"]["value"], b["target"]["value"]);
return sortChords(a, b);
});
}
chord["matrix"] = function(x) {
if (!arguments.length) return matrix;
n = (matrix = x) && matrix.length;
chords = groups = null;
return chord;
};
chord["padding"] = function(x) {
if (!arguments.length) return padding;
padding = x;
chords = groups = null;
return chord;
};
chord["sortGroups"] = function(x) {
if (!arguments.length) return sortGroups;
sortGroups = x;
chords = groups = null;
return chord;
};
chord["sortSubgroups"] = function(x) {
if (!arguments.length) return sortSubgroups;
sortSubgroups = x;
chords = null;
return chord;
};
chord["sortChords"] = function(x) {
if (!arguments.length) return sortChords;
sortChords = x;
if (chords) resort();
return chord;
};
chord["chords"] = function() {
if (!chords) relayout();
return chords;
};
chord["groups"] = function() {
if (!groups) relayout();
return groups;
};
return chord;
};