使D3力导向图响应并遵守边界框

时间:2015-05-05 15:52:53

标签: d3.js box bounding responsiveness

我有一个通过D3生成的力导向图,它与我发现的响应代码或边界框代码不匹配。由于我所有圈子的半径各不相同,我认为它会丢掉一些东西......任何帮助都会受到赞赏!

我必须在线上使用自定义长度,因为如果由于半径不相同而没有手动将它们分开,节点会相互碰撞。

(请不要将我链接到带有代码的d3页面,我已经尝试过了,但是如果您认为它可以解决这个问题,我可能会把它放在错误的位置。我也尝试发布一个图片,但我没有足够的声誉。)

var width = 876,
    height = 600;

var color = d3.scale.category20();

var force = d3.layout.force()
    .charge(-1010)
    .linkDistance(function(d) { return  d.distance; })
    .size([width, height])
    .gravity(0.7);
    
        
var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);
    
var tip = d3.tip()
    .attr('class', 'd3-tip')
    .offset([-5, 0])
    .html(function (d) {
    return  d.name + "  (" + d.instances + ")";
})
    svg.call(tip);

d3.json("datawords.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")
      .attr("width", function(d) { return d.totalLength; })
      .style("stroke-width", function(d) { return Math.sqrt(d.value); });

  var node = svg.selectAll(".node")
      .data(graph.nodes)
.enter().append("circle")
      .attr("class", "node")
      .attr("r", function(d) {return d.instances;})
      .style("fill", function(d) { return color(d.instances); })
      .call(force.drag)
    .on('mouseover', tip.show)
    .on('mouseout', tip.hide)
    .on('click', connectedNodes)


  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("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });

    node.each(collide(0.5))
    });

    
    //Toggle stores whether the highlighting is on
var toggle = 0;
//Create an array logging what is connected to what
var linkedByIndex = {};
for (i = 0; i < graph.nodes.length; i++) {
    linkedByIndex[i + "," + i] = 1;
};
graph.links.forEach(function (d) {
    linkedByIndex[d.source.index + "," + d.target.index] = 1;
});
//This function looks up whether a pair are neighbours
function neighboring(a, b) {
    return linkedByIndex[a.index + "," + b.index];
}
function connectedNodes() {
    if (toggle == 0) {
        //Reduce the opacity of all but the neighbouring nodes
        d = d3.select(this).node().__data__;
        node.style("opacity", function (o) {
            return neighboring(d, o) | neighboring(o, d) ? 1 : 0.1;
        });
        link.style("opacity", function (o) {
            return d.index==o.source.index | d.index==o.target.index ? 1 : 0.1;
        });
        //Reduce the op
        toggle = 1;
    } else {
        //Put them back to opacity=1
        node.style("opacity", 1);
        link.style("opacity", 1);
        toggle = 0;
    };
};
    
    var padding = 10, // separation between circles
    radius=15;

    function collide(alpha) {
  var quadtree = d3.geom.quadtree(graph.nodes);
  return function(d) {
    var rb = 4*radius + padding,
        nx1 = d.x - rb,
        nx2 = d.x + rb,
        ny1 = d.y - rb,
        ny2 = d.y + rb;
    
    quadtree.visit(function(quad, x1, y1, x2, y2) {
      if (quad.point && (quad.point !== d)) {
        var x = d.x - quad.point.x,
            y = d.y - quad.point.y,
            l = Math.sqrt(x * x + y * y);
          if (l < rb) {
          l = (l - rb) / l * alpha;
          d.x -= x *= l;
          d.y -= y *= l;
          quad.point.x += x;
          quad.point.y += y;
        }
      }
      return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
    });
  };
};
    window.addEventListener('resize', resize); 

function resize() {
    width = window.innerWidth, height = window.innerHeight;
    svg.attr("width", width).attr("height", height);
    force.size([width, height]).resume();
}
});

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

.link {
  stroke: #999;
  stroke-opacity: .6;
}
    
    .node-active{
  stroke: #555;
  stroke-width: 1.5px;
}
    
        .node:hover{
  stroke: #555;
  stroke-width: 1.5px;
}
    marker {
display:none;
    }
    
    .d3-tip {
  line-height: 1;
  font-weight: bold;
  padding: 12px;
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  border-radius: 2px;
}

.d3-tip.n:after {
  margin: -1px 0 0 0;
  top: 200%;
  left: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="d3/d3tip.js"></script>
    <div class="graph"></div>
</body>

0 个答案:

没有答案