【发布时间】:2015-03-12 04:21:14
【问题描述】:
我正在尝试将饼图与 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;
};
};
});
【问题讨论】:
-
我不知道具体怎么做,但是一个通用的策略是对顶层力布局中的每个节点使用
<g>。然后你可以在g中放入任何你想要的东西,包括由其他布局控制的元素。诀窍是在以后需要时跟踪不同的布局。您可以将它们放在一个数组中,但我更喜欢将它们放在生成内部元素的函数的本地变量中,或者将布局存储在数据元素中。
标签: javascript d3.js charts