D3 Force Layout - 子图聚类功能

时间:2013-05-13 14:54:03

标签: javascript graph d3.js force-layout

我想要使用D3力布局显示一些数据。如果这是一个天真的问题,或者我在问题标题中使用的术语不准确,请道歉。我找不到我想要的答案。

我做了一个小提示,展示了我在这里的内容:

http://jsfiddle.net/stevendwood/f3GJT/8/

enter image description here

在示例中,我有一个节点(0),它有很多链接。另一个节点(16)具有较少量的链路,0和16都连接到15。

所以我想要的是0和16是小集群,它们的连接节点出现在它们周围的一个漂亮的圆圈中。

我徒劳地尝试根据链接的数量来定制费用,但我认为我想要做的是以某种方式使节点更多地吸引他们所连接的节点,而不是吸引他们没有连接的节点。

如果可能,我想要这样的事情:

enter image description here

var w = 500,
h = 500,
nodes = [],
links = [];

/* Fake up some data */
for (var i=0; i<20; i++) {
    nodes.push({
        name: ""+i
    });
}

for (i=0; i<16; i++) {
    links.push({
        source: nodes[i],
        target: nodes[0]
    });
}

links.push({
     source: nodes[16],
     target: nodes[15]
});

for (i=17; i<20; i++) {

    links.push({
        source: nodes[i],
        target: nodes[16]
    });
}

var countLinks = function(n) {
    var count = 0;
    links.forEach(function(l) {
        if (l.source === n || l.target === n) {
            count++;
        }
    });

    return count;
}

/////////////////////////////////////////////

var vis = d3.select("body").append("svg:svg")
    .attr("width", w)
    .attr("height", h);

var force = d3.layout.force()
    .nodes(nodes)
    .links([])
    .gravity(0.05)
    .charge(function(d) {
        return countLinks(d) * -50;     
     })
    .linkDistance(300)
    .size([w, h]);


 var link = vis.selectAll(".link")
        .data(links)
        .enter().append("line")
        .attr("class", "link")
        .attr("stroke", "#CCC")
        .attr("fill", "none");

 var node = vis.selectAll("circle.node")
     .data(nodes)
     .enter().append("g")
     .attr("class", "node")
     .call(force.drag);

node.append("svg:circle")
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; })
    .attr("r", 14)
    .style("fill", "#CCC")
    .style("stroke", "#AAA")
    .style("stroke-width", 1.5)

node.append("text").text(function(d) { return d.name; })
    .attr("x", -6)
    .attr("y", 6);

force.on("tick", function(e) {
    node.attr("transform", function(d, i) {
        return "translate(" + d.x + "," + d.y + ")"; 
    });

    link.attr("x1", function(d)   { return d.source.x; })
        .attr("y1", function(d)   { return d.source.y; })
        .attr("x2", function(d)   { return d.target.x; })
        .attr("y2", function(d)   { return d.target.y; }) 
});

force.start();

1 个答案:

答案 0 :(得分:5)

为什么在声明力布局时省略了链接?如果你重新添加它们,它看起来更接近你想要的东西:

var force = d3.layout.force()
    .nodes(nodes)
    //.links([])
    .links(links)
    .gravity(0.1)
    .charge(-400)
    .linkDistance(75)
    .size([w, h]);

http://jsfiddle.net/f3GJT/11/

enter image description here