【问题标题】:Force network to fit bounding box with d3强制网络用 d3 拟合边界框
【发布时间】:2021-11-26 23:42:55
【问题描述】:

我正在尝试将我的网络放入一个 div 中。我使用了这个例子:https://bl.ocks.org/puzzler10/2531c035e8d514f125c4d15433f79d74,但在使用d3.json()时无法使其工作

这是我正在使用的代码。

<!DOCTYPE html>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>

html, body {
  height: 100%;
  margin: 0;
}

.links line {
  stroke: #999;
  stroke-opacity: 0.6;
}

.nodes circle {
  stroke: #fff;
  stroke-width: 1.5px;
}

text {
  font-family: sans-serif;
  font-size: 10px;
  color: black;
}

.sidebar {
  height: 100%;
  width: 0;
  margin-top:10%;
  margin-bottom:1.5%;
  margin-left:1.5%;
  position: absolute;
  z-index: 2000;
  top: 0;
  left: 0;
  bottom:0;
  background-color:rgba(240,240,240,0.6);
  overflow-x: hidden;
  transition: 0.5s;
  border-radius:5px;
  overflow: hidden;
}
    
.sidebar:hover {
  overflow-y: scroll;
}

svg{
  border: 1px solid black;
}

.container {
  display: flex;   
  justify-content: center
};


</style>

<div class="container">
<svg width="500" height="500"></svg>
</div>


<div id="mySidebar" class="sidebar">
  <p id="area"></p>
  <p id="desc"></p>
  <div>
    <img id="media" src="">
  </div>
  <p id="content"></p>
</div>


<script src="https://d3js.org/d3.v4.min.js"></script>
<script>


//Navbar navigation
function openNav() {
  document.getElementById("mySidebar").style.width = "350px";
}

function closeNav() {
  document.getElementById("mySidebar").style.width = "0";
}

//Graph options
var radius = 15;

var svg = d3.select("div#container")
  .append("svg")
  .attr("preserveAspectRatio", "xMinYMin meet")
  .attr("viewBox", "0 0 300 300")
  .classed("svg-content", true);

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

var color = d3.scaleOrdinal(d3.schemeCategory20);

var simulation = d3.forceSimulation()
                    .force("link", d3.forceLink().id(function(d) { return d.id; }))
                    .force("charge", d3.forceManyBody().strength(-2000))
                    .force("center", d3.forceCenter(width / 2, height / 2));


//Graph creation
d3.json("http://myjson.dit.upm.es/api/bins/10fx", function(error, graph) {
  if (error) throw error;
  var link = svg.append("g")
      .attr("class", "links")
      .selectAll("line")
      .data(graph.links)
      .enter().append("line")
      .attr("stroke-width", function(d) { return Math.sqrt(d.value); });

  var node = svg.append("g")
                .attr("class", "nodes")
                .selectAll("g")
                .data(graph.nodes)
                .enter().append("g")

  var circles = node.append("circle")
    .attr("r", 5)
    .attr("fill", function(d) { return color(d.group); });

  // Create a drag handler and append it to the node object instead
  var drag_handler = d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended);

  drag_handler(node);
  
  var labels = node.append("text")
      .text(function(d) {
        return d.id;
      })
      .attr('x', 6)
      .attr('y', 3);

  link.on("click", 
    function(d) {
      console.log(d.content);
      openNav();
      document.getElementById("content").innerHTML = d.content;
    },
  )

  node.append("title")
      .text(function(d) { return d.id; });

  simulation
      .nodes(graph.nodes)
      .on("tick", ticked);

  simulation.force("link")
      .links(graph.links);

  function ticked() {
    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 //This is where the "problem" seems to be located
        .attr("transform", function(d) {
          return "translate(" + d.x + "," + d.y + ")";
        })

  }
});

function dragstarted(d) {
  if (!d3.event.active) simulation.alphaTarget(0.3).restart();
  d.fx = d.x;
  d.fy = d.y;
}

function dragged(d) {
  d.fx = d3.event.x;
  d.fy = d3.event.y;
}

function dragended(d) {
  if (!d3.event.active) simulation.alphaTarget(0);
  d.fx = null;
  d.fy = null;
}

</script>

可以将网络约束到边界框的函数如下:

function ticked() {
   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 //This is where the "problem" seems to be located
       .attr("transform", function(d) {
         return "translate(" + d.x + "," + d.y + ")";
       })

 }

我尝试了很多东西,但无法成功。有什么想法吗?

【问题讨论】:

    标签: javascript d3.js bounding-box


    【解决方案1】:

    您共享的块中将节点保持在边界内的部分是

    node
        .attr("cx", function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); })
        .attr("cy", function(d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); });
    

    注意对Math.maxMath.min 的调用,以确保d.xd.y 保持在界限内。您的代码缺少这个。

    你可以做类似的事情:

    node
        .attr("transform", function(d) {
          d.x = Math.max(radius, Math.min(width - radius, d.x));
          d.y = Math.max(radius, Math.min(height - radius, d.y));
          return "translate(" + d.x + "," + d.y + ")";
        });
    

    这是一个更新的示例:

    <!DOCTYPE html>
    <meta charset="utf-8">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <style>
    
    html, body {
      height: 100%;
      margin: 0;
    }
    
    .links line {
      stroke: #999;
      stroke-opacity: 0.6;
    }
    
    .nodes circle {
      stroke: #fff;
      stroke-width: 1.5px;
    }
    
    text {
      font-family: sans-serif;
      font-size: 10px;
      color: black;
    }
    
    .sidebar {
      height: 100%;
      width: 0;
      margin-top:10%;
      margin-bottom:1.5%;
      margin-left:1.5%;
      position: absolute;
      z-index: 2000;
      top: 0;
      left: 0;
      bottom:0;
      background-color:rgba(240,240,240,0.6);
      overflow-x: hidden;
      transition: 0.5s;
      border-radius:5px;
      overflow: hidden;
    }
        
    .sidebar:hover {
      overflow-y: scroll;
    }
    
    svg{
      border: 1px solid black;
    }
    
    .container {
      display: flex;   
      justify-content: center
    };
    
    
    </style>
    
    <div class="container">
    <svg width="500" height="500"></svg>
    </div>
    
    
    <div id="mySidebar" class="sidebar">
      <p id="area"></p>
      <p id="desc"></p>
      <div>
        <img id="media" src="">
      </div>
      <p id="content"></p>
    </div>
    
    
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script>
    
    
    //Navbar navigation
    function openNav() {
      document.getElementById("mySidebar").style.width = "350px";
    }
    
    function closeNav() {
      document.getElementById("mySidebar").style.width = "0";
    }
    
    //Graph options
    var radius = 15;
    
    var svg = d3.select("div#container")
      .append("svg")
      .attr("preserveAspectRatio", "xMinYMin meet")
      .attr("viewBox", "0 0 300 300")
      .classed("svg-content", true);
    
    var svg = d3.select("svg"),
        width = +svg.attr("width"),
        height = +svg.attr("height");
    
    var color = d3.scaleOrdinal(d3.schemeCategory20);
    
    var simulation = d3.forceSimulation()
                        .force("link", d3.forceLink().id(function(d) { return d.id; }))
                        .force("charge", d3.forceManyBody().strength(-2000))
                        .force("center", d3.forceCenter(width / 2, height / 2));
    
    
    //Graph creation
    d3.json("http://myjson.dit.upm.es/api/bins/10fx", function(error, graph) {
      if (error) throw error;
      var link = svg.append("g")
          .attr("class", "links")
          .selectAll("line")
          .data(graph.links)
          .enter().append("line")
          .attr("stroke-width", function(d) { return Math.sqrt(d.value); });
    
      var node = svg.append("g")
                    .attr("class", "nodes")
                    .selectAll("g")
                    .data(graph.nodes)
                    .enter().append("g")
    
      var circles = node.append("circle")
        .attr("r", 5)
        .attr("fill", function(d) { return color(d.group); });
    
      // Create a drag handler and append it to the node object instead
      var drag_handler = d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended);
    
      drag_handler(node);
      
      var labels = node.append("text")
          .text(function(d) {
            return d.id;
          })
          .attr('x', 6)
          .attr('y', 3);
    
      link.on("click", 
        function(d) {
          console.log(d.content);
          openNav();
          document.getElementById("content").innerHTML = d.content;
        },
      )
    
      node.append("title")
          .text(function(d) { return d.id; });
    
      simulation
          .nodes(graph.nodes)
          .on("tick", ticked);
    
      simulation.force("link")
          .links(graph.links);
    
      function ticked() {
        node
            .attr("transform", function(d) {
              d.x = Math.max(radius, Math.min(width - radius, d.x));
              d.y = Math.max(radius, Math.min(height - radius, d.y));
              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; });
      }
    });
    
    function dragstarted(d) {
      if (!d3.event.active) simulation.alphaTarget(0.3).restart();
      d.fx = d.x;
      d.fy = d.y;
    }
    
    function dragged(d) {
      d.fx = d3.event.x;
      d.fy = d3.event.y;
    }
    
    function dragended(d) {
      if (!d3.event.active) simulation.alphaTarget(0);
      d.fx = null;
      d.fy = null;
    }
    
    </script>

    【讨论】:

      猜你喜欢
      • 2014-07-09
      • 2014-11-25
      • 2012-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-31
      • 2012-11-09
      相关资源
      最近更新 更多