我想在D3中将饼图与强制网络结合起来。我目前正在使用部队网络(如下所示)。我想将每个气泡变成饼图。这是可能的,因为它们具有不同的半径。任何一般方法将不胜感激。谢谢!
这是当前的javascript代码:
d3.json("data/d3data.json", function(error, graph) {
var new_nodes = convert(graph.nodes);
force
.nodes(new_nodes)
// .links(graph.links)
.start();
var root = new_nodes[0];
root.fixed = true;
var loading = svg.append("text")
.attr("x", width / 2)
.attr("y", height / 2)
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text("Simulating. One moment please…");
var node = svg.selectAll("svg")
.data(new_nodes)
.enter().append("svg")
.attr("width", function(d) { return Math.sqrt(d.followersCount/100)*2;})
.attr("height", function(d) { return Math.sqrt(d.followersCount/100)*2;});
var g = node.append("g")
.attr("transform", function(d) { return "translate(" + d.r + "," + d.r + ")"});
var g_2 = node.selectAll("g")
.data(function(d) {
console.log(pie(d.FFratio));
return pie(d.FFratio);})
.enter() .append("g");
g_2.append("path")
.attr("d", d3.svg.arc().outerRadius(10))
.style("fill", function (d, i) {
return color(i);
})
function tick(){
var node_x = 0;
var node_y = 0;
node.attr("x", function(d) { node_x = d.x; return d.x; })
.attr("y", function(d) { node_y = d.y;return d.y; });
}
loading.remove();
force.on("tick", function ticky(e){
var q = d3.geom.quadtree(graph.nodes),
i = 0,
n = graph.nodes.length;
while (++i < n) q.visit(collide(graph.nodes[i]));
tick();
});
function convert(node_list){
var result = [];
var current_node = {};
count = 0;
while (++count<node_list.length){
current_node = node_list[count];
current_node.r = Math.sqrt(current_node.followersCount/100);
var followingR = current_node.followingCount/(current_node.followersCount+current_node.followingCount)*100;
var followerR = 1 - followingR;
current_node.FFratio = [followingR, followerR];
result.push(current_node);
};
return result;
};
function collide(node) {
var node_r = Math.sqrt(node.followersCount/100),
r = node_r + 100,
nx1 = node.x - r,
nx2 = node.x + r,
ny1 = node.y - r,
ny2 = node.y + r;
return function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== node)) {
var x = node.x - quad.point.x,
y = node.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = node_r + Math.sqrt(quad.point.followersCount/100);
if (l < r) {
l = (l - r) / l * .5;
node.x -= x *= l;
node.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
};
};
});
答案 0 :(得分:5)
此处an example我刚刚根据clustered force layout进行了编码。
关键是用circle
替换聚类g
的力,然后你可以在其中循环并构建饼图:
var pies = svg.selectAll(".pie")
.data(nodes)
.enter().append("g")
.attr("class","pie")
.call(force.drag);
pies.each(function(d,i){
var pieG = d3.select(this);
var arc = d3.svg.arc()
.outerRadius(d.radius)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d;
});
var data = [Math.random(), Math.random(), Math.random(), Math.random()];
var g = pieG.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.attr("fill", function(d,i){
return colors(i);
})
});
产生这个: