2013-11-28 2 views
4

SVG Я модифицированный раскладке разборную Force http://mbostock.github.io/d3/talk/20111116/force-collapsible.html примера:D3.js придерживайтесь родительского объекта в середине

enter image description here

... и теперь он выглядит как этого

image

Теперь весь круг можно перетаскивать. Я хочу придерживаться среднего круга (синий круг) середина svg. Возможно ли это? Спасибо.

<script> 

    var width = 960, 
     height = 600, 
     root; 

    var force = d3.layout.force() 
     .linkDistance(175) 
     .charge(-200) 
     .gravity(0) 
     .size([width, height]) 
     .on("tick", tick); 

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

    var link = svg.selectAll(".link"), 
     node = svg.selectAll(".node"); 

    d3.json("graph.json", function(error, json) { 
     root = json; 
     update(); 
    }); 

    function update() { 
     var nodes = flatten(root), 
      links = d3.layout.tree().links(nodes); 

     // Restart the force layout. 
     force 
      .nodes(nodes) 
      .links(links) 
      .start(); 

     // Update links. 
     link = link.data(links, function(d) { return d.target.id; }); 

     link.exit().remove(); 

     link.enter().insert("line", ".node") 
      .attr("class", "link"); 

     // Update nodes. 
     node = node.data(nodes, function(d) { return d.id; }); 

     node.exit().remove(); 

     var nodeEnter = node.enter().append("g") 
      .attr("class", "node") 
      .on("click", click) 
      .call(force.drag) 
      .attr("href", function(d) { return d.link; }); 

    nodeEnter.append("svg:a") 
     .attr("xlink:href", function(d){return d.link;}) 
     .append("circle") 
      .attr("r", function(d) { return Math.sqrt(d.size)/10 || 4.5; }); 

     nodeEnter.append("text") 
      .attr("dy", ".35em") 
      .text(function(d) { return d.name; }); 

     node.select("circle") 
      .style("fill", color); 
    } 

    function tick() { 
     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; }); 

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

    function color(d) { 
     return d._children ? "#3182bd" // collapsed package 
      : d.children ? "#2F9BC1" // expanded package 
      : "#fd8d3c"; // leaf node 
    } 

    // Toggle children on click. 
    function click(obj) { 
     if (d3.event.defaultPrevented) return; // ignore drag 
     if (d.children) { 
     d._children = d.children; 
     d.children = null; 
     } else { 
     d.children = d._children; 
     d._children = null; 
     } 
     update(); 
    } 

    // Returns a list of all nodes under the root. 
    function flatten(root) { 
     var nodes = [], i = 0; 

     function recurse(node) { 
     if (node.children) node.children.forEach(recurse); 
     if (!node.id) node.id = ++i; 
     nodes.push(node); 
     } 

     recurse(root); 
     return nodes; 
    } 

    </script> 

JSON файл:

{ 
    "name": "Me", "size": 200000, "link": "http://google.com", 
    "children": [ 
     {"name": "Person 01", "size": 150000, "link": "http://google.com"}, 
     {"name": "Person 02", "size": 150000, "link": "http://yahoo.com"}, 
     {"name": "Person 03", "size": 150000, "link": "http://youtube.com"}, 
     {"name": "Person 04", "size": 150000, "link": "http://twitter.com"}, 
     {"name": "Person 05", "size": 150000, "link": "http://facebook.com"} 
    ] 
} 

ответ

3

Что вам нужно сделать для этого установить fixed свойство данного узла к true (см the documentation) после того, как установить его координаты центра, так что-то вроде

nodes.forEach(function(d) { 
    if(d._children || d.children) { 
    d.x = width/2, d.y = height/2; 
    d.fixed = true; 
    } 
}); 

сразу в начале функции update.

Если вы хотите отключить перетаскивание для этого узла, а также, вы можете сделать

nodeEnter.filter(function(d) { 
      return d.children === undefined && d._children === undefined; 
     }) 
     .call(force.drag); 

вместо вызова force.drag на всех узлах. Полный пример here.

+0

Спасибо. После добавления этого кода средний круг фиксирован, но он не посередине. Когда я перезагружаю страницу, позиция изменяется случайным образом. И я хочу отключить эффект перетаскивания среднего круга. –

+1

Я обновил ответ. –

+0

Это прекрасный ответ. Большое вам спасибо за вашу большую помощь. –

Смежные вопросы