【问题标题】:D3.js stick parent object in middle of the svgD3.js 将父对象粘贴在 svg 的中间
【发布时间】:2013-11-28 09:48:18
【问题描述】:

我已经修改了 Collapsible Force Layout http://mbostock.github.io/d3/talk/20111116/force-collapsible.html 例子:

...现在看起来像这样

现在所有圆圈都可以拖动。 我想在 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"}
     ]
 }

【问题讨论】:

    标签: javascript svg d3.js force-layout


    【解决方案1】:

    为此,您需要将相关节点的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

    【讨论】:

    • 谢谢。附加此代码后,中间的圆圈是固定的,但它不在中间。重新加载页面时位置随机变化。我想禁用中间的圆圈拖动效果。
    • 这是一个完美的答案。非常感谢您的大力帮助。
    猜你喜欢
    • 1970-01-01
    • 2019-06-27
    • 2015-03-26
    • 2020-10-19
    • 1970-01-01
    • 2017-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多