2013-03-02 55 views
1

在这个例子中(http://bl.ocks.org/mbostock/938288)我这样做:中心定位的基于力的有向图

var data0 = [ 
     {name:'bob', connections: ['jane', 'tom', 'sue']}, 
     {name:'jane', connections: ['bob', 'sue']}, 
     {name:'sue', connections: ['tom', 'bob', 'jane', 'tom']}, 
     {name: 'tom', connections: []} 
    ]; 

    var data1 = [ 
      {"name":"Salvation Army", "connections": []}, 
      {"name":"Northwestern University", "connections": []}, 
      {"name":"William Dicket", "connections": []}, 
      {"name":"Scott Saff", "connections": []}, 
      {"name":"City Co", "connections": []}, 
      {"name":"Action 1", "connections": []}, 
      {"name":"Action 2", "connections": []}, 
      {"name":"Action 3", "connections": []}, 
      {"name":"Action 4", "connections": []}, 
      {"name":"Action 5", "connections": []}, 
      {"name":"Action 6", "connections": []}, 
      {"name":"Action 7", "connections": []}, 
      {"name":"Action 8", "connections": []}, 
      {"name":"Action 9", "connections": []}, 
      {"name":"Action 10", "connections": []}, 
      {"name":"Action 11", "connections": []} 
      ] 


    var w = 500, 
     h = 500, 
     angle = d3.scale.ordinal().domain(d3.range(0, data1.length)).rangeBands([0, 2 * Math.PI]); 

     line = d3.svg.chord() 
     .startAngle(function(d) { return (d.startAngle + d.endAngle)/2; }) 
     .endAngle(function(d) { return (d.startAngle + d.endAngle)/2; }) 
     .radius(h/2 - 20); 

     var angles = {}, 
     connections = []; 


     data1.forEach(function(d, i) { 
      var a = angle(i) 
      angles[d.name] = { 
      startAngle: a, 
      endAngle: a + angle.rangeBand()/2 
      } 
     }) 

     data1.forEach(function(p) { 
      p.connections.forEach(function(c) { 
      connections.push({ 
       source: angles[p.name], 
       target: angles[c] 
      }) 
      }) 
     }) 


    var force = self.force = d3.layout.force() 
    .nodes(data0) 
    .distance(10) 
    .charge(-100) 
    .size([200, 200]) 
    .start(); 

    var vis = d3.select("body").append("svg:svg") 
     .attr("width", w) 
     .attr("height", h) 
     .append("svg:g") 
     .attr("transform", "translate(" + w/2 + "," + h/2 + ")"); 

     var node = vis.selectAll("g.node") 
     .data(data0) 
     .enter().append("svg:g") 
     .call(force.drag); 

     node.append("circle") 
      .attr("r", 10); 

    var path = vis.selectAll("path") 
     .data(data1) 
     .enter().append("svg:path") 
     .attr("d", d3.svg.arc() 
     .innerRadius(h/2 - 20) 
     .outerRadius(h/2 - 10) 
     .startAngle(function(d, i) { return angles[d.name].startAngle }) 
     .endAngle(function(d, i) { return angles[d.name].endAngle; })) 
     //.call(force.drag); 


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

    }); 

我的问题是:我怎么能移动内部节点的弧圆的中心?

比你好!

编辑:

我能够到中心节点或多或少在中间。但现在,我有严重的问题添加外部网段和内部节点之间的链接。 在这jsfiddle(http://jsfiddle.net/dinosaur/SFYrJ/),你可以看到,有一个外部链接,但链接的长度太短... 有任何想法?

var data0 = [ 
    {name:'bob', "connections": ['jane', 'tom', 'sue']}, 
    {name:'jane', "connections": ['bob', 'sue']}, 
    {name:'sue', "connections": ['tom', 'bob', 'jane', 'tom']}, 
    {name: 'tom', "connections": []} 
]; 

var data1 = [ 
     {"name":"City Co"}, 
     {"name":"Action 1"}, 
     {"name":"Action 2"}, 
     {"name":"Action 3"}, 
     {"name":"Action 4"}, 
     {"name":"Action 5"}, 
     {"name":"Action 6"}, 
     {"name":"Action 7"}, 
     {"name":"Action 8"}, 
     {"name":"Action 9"}, 
     {"name":"Action 10"}, 
     {"name":"Action 11"} 
     ] 

var links = [ 
      {"source":1,"target":6,"value":10}, 
      {"source":6,"target":7,"value":10}, 
      {"source":7,"target":8,"value":10}, 
      ] 


var w = 500, 
    h = 500, 
    angle = d3.scale.ordinal().domain(d3.range(0, data0.length)).rangeBands([0, 2 * Math.PI]); 

var data12 = data0.concat(data1) 

    /* 
    line = d3.svg.chord() 
    .startAngle(function(d) { return (d.startAngle + d.endAngle)/2; }) 
    .endAngle(function(d) { return (d.startAngle + d.endAngle)/2; }) 
    .radius(h/2 - 20); 
    */ 
    var angles = {}, 
    connections = []; 


    data0.forEach(function(d, i) { 
     var a = angle(i) 
     angles[d.name] = { 
     startAngle: a, 
     endAngle: a + angle.rangeBand()/2 
     } 
    }) 
/* 
    data1.forEach(function(p) { 
     p.connections.forEach(function(c) { 
     connections.push({ 
      source: angles[p.name], 
      target: angles[c] 
     }) 
     }) 
    }) 
*/ 

非常感谢! Jan

回答

2

您针对节点的目标索引与data1之前的节点数据集具有data0不同。所以,简单的解决方案是:

var data12 = data1.concat(data0) 

,而不是当前:

var data12 = data0.concat(data1) 

Fiddle

但是,如果你现在想得之间的联系可能不是完美的解决方案data1中的对象。所以我建议使用自定义标识符,如this example