【问题标题】:How do I change nodes to be rectangles instead of circles in a d3 force layout?如何在 d3 强制布局中将节点更改为矩形而不是圆形?
【发布时间】:2013-07-25 02:35:31
【问题描述】:

如何将以下d3 forced directed graph 中的节点改为矩形而不是圆形?

【问题讨论】:

    标签: d3.js force-layout d3-force-directed


    【解决方案1】:

    circle 更改为rect。删除 r 属性。添加widthheight 属性。将 fdg 中的 cxcy 更改为 xy

    var width = 960, height = 500;
    
    var rectWidth = 20, rectHeight = 10;
    
    var color = d3.scale.category20();
    
    var force = d3.layout.force()
      .charge(-120)
      .linkDistance(30)
      .size([width, height]);
    
    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height);
    
    d3.json("https://raw.githubusercontent.com/d3/d3-plugins/master/graph/data/miserables.json", function(error, graph) {
    
      force
        .nodes(graph.nodes)
        .links(graph.links)
        .start();
    
      var link = svg.selectAll(".link")
        .data(graph.links)
        .enter().append("line")
        .attr("class", "link")
        .style("stroke-width", function(d) { return Math.sqrt(d.value); });
    
      var node = svg.selectAll(".node")
        .data(graph.nodes)
        .enter().append("rect")
        .attr("class", "node")
        .attr("width", rectWidth)
        .attr("height", rectHeight)
        .style("fill", function(d) { return color(d.group); })
        .call(force.drag);
    
      node.append("title")
        .text(function(d) { return d.name; });
    
      force.on("tick", function() {
        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("x", function(d) { return d.x - rectWidth / 2; })
          .attr("y", function(d) { return d.y - rectHeight / 2; });
      });
    });
    .node {
      stroke: #fff;
      stroke-width: 1.5px;
    }
    
    .link {
      stroke: #999;
      stroke-opacity: .6;
    }
    <script src="http://d3js.org/d3.v3.min.js"></script>

    【讨论】:

    • @Journ 正方形是矩形的特例;)
    【解决方案2】:
    Here is a simple example of using Rectangles with a json file :
    
    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>
    
    .link {
      stroke: #000;
      stroke-width: 1.5px;
    }
    
    .node {
      cursor: move;
      fill: #ccc;
      stroke: #000;
      stroke-width: 1.5px;
    }
    
    .node.fixed {
      fill: #f00;
    }
    
    </style>
    <body>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    
    <script>
    
    var width = 960,
        height = 800;
    
    var force = d3.layout.force()
        .size([width, height])
        .charge(-400)
        .linkDistance(100)
        .on("tick", tick);
    
    var drag = force.drag();
        //.on("dragstart", dragstart);
    
    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, graph) {
      if (error) throw error;
    
      force
          .nodes(graph.nodes)
          .links(graph.links)
          .start();
    
      link = link.data(graph.links)
        .enter().append("line")
          .attr("class", "link");
    
      node = node.data(graph.nodes)
          .enter().append("rect")
          .attr("class", "node")
          .attr("width", 60)
          .attr("height", 60)
          .on("dblclick", dblclick)
          .call(drag);
    });
    
    function tick() {
      link.attr("x1", function(d) { return d.source.x+25; })
          .attr("y1", function(d) { return d.source.y+25; })
          .attr("x2", function(d) { return d.target.x+25; })
          .attr("y2", function(d) { return d.target.y+25; });
    
      node.attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; });
    }
    
    function dblclick(d) {
      d3.select(this).classed("fixed", d.fixed = false);
    }
    
    function dragstart(d) {
      d3.select(this).classed("fixed", d.fixed = true);
    }
    
    </script>
    
    The Json file is bellow. Give the exact path of your json file in the code:
    
    {
      "nodes": [
        {"x": 469, "y": 410},
        {"x": 493, "y": 364},
        {"x": 442, "y": 365},
        {"x": 467, "y": 314},
        {"x": 477, "y": 248},
        {"x": 425, "y": 207},
        {"x": 402, "y": 155},
        {"x": 369, "y": 196},
        {"x": 350, "y": 148},
        {"x": 539, "y": 222},
        {"x": 594, "y": 235},
        {"x": 582, "y": 185},
        {"x": 633, "y": 200}
      ],
      "links": [
        {"source":  0, "target":  1},
        {"source":  0, "target":  2},
        {"source":  0, "target":  3},
        {"source":  1, "target":  4},
        {"source":  1, "target":  5},
        {"source":  2, "target":  6},
        {"source":  2, "target":  7},
        {"source":  3, "target":  8},
        {"source":  3, "target":  9},
        {"source":  4, "target":  10},
        {"source":  5, "target":  11},
        {"source":  6, "target":  12}
      ]
    }
    

    【讨论】:

      【解决方案3】:

      您必须附加 rect SVG 元素,而不是 circle

      所以,在脚本中,它会显示:

      var node = svg.selectAll(".node")
            .data(graph.nodes)
          .enter().append("circle")
            .attr("class", "node")
            .attr("r", 5)
            .style("fill", function(d) { return color(d.group); })
            .call(force.drag);
      

      你应该把它改成这样:

      var node = svg.selectAll(".node")
            .data(graph.nodes)
          .enter().append("rect")
            .attr("class", "node")
            .attr("width", 40)
            .attr("height", 20)
            .style("fill", function(d) { return color(d.group); })
            .call(force.drag);
      

      而且,它显示在哪里:

      node.attr("cx", function(d) { return d.x; })
          .attr("cy", function(d) { return d.y; });
      

      改成:

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

      【讨论】:

      • 如果它帮助/解决了您的问题,请投票/接受答案。
      • 您应该搜索 SO 并为此发布另一个问题,因为它是一个不同的主题。
      • @AnthatiNagaraju 您永远不必标记已接受的答案,如果它解决了您的问题,请通过接受其中一个答案将其标记为已回答。
      猜你喜欢
      • 1970-01-01
      • 2019-02-11
      • 2014-02-09
      • 1970-01-01
      • 2018-01-28
      • 1970-01-01
      • 1970-01-01
      • 2021-02-23
      • 1970-01-01
      相关资源
      最近更新 更多