javascript - Responsive force directed D3 graph with bounding box with different node radii -


i have responsive force directed graph, , it's working great, except can't stay within browser screen.

the d3 code suggested create bounding box :

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

however, not work, because i'm not defining width (it's responsive) , i'm not defining r because it's function, nodes different sizes.

i tried set:

var r= function(d) {return d.instances;}; 

because that's i'm putting node size from, doesn't work... of force directed examples see use same size nodes.. i'm not familiar enough javascript figure out workaround... help?

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>  <!doctype html>  <meta charset="utf-8">  <style type="text/css">        *{      margin:0;      padding:0;  }  /*  svg {      display: block;       width: 100%;       margin: 0;  }  */    .node {    stroke: #fff;    stroke-width: 1.5px;  }            #graph{       max-width:100%;       height:100vh ;      }    .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 {          display:none;      }    </style>  <body>       <div id="graph"></div>  <script src="d3/d3.js"></script>  <script src="d3/d3tip.js"></script>      <script type='text/javascript' src='http://code.jquery.com/jquery-1.11.0.js'></script>  <script>    var color = d3.scale.category20();    var force = d3.layout.force()      .charge(-2010)      .linkdistance(function(d) { return  d.distance; })  //    .size([width, height])      .gravity(0.7);        //var width = 1000,  //    height = 1000;                var svg = d3.select("#graph")      .append("svg")      .attr({          "width": "100%",          "height": "100%"        })  //    .attr("viewbox", "0 0 " + width + " " + height )      .attr("preserveaspectratio", "xmidymid meet")                   //.attr("pointer-events", "all")      .call(d3.behavior.zoom().on("zoom", redraw));        var vis = svg      .append('svg:g');    function redraw() {    vis.attr("transform",        "translate(" + d3.event.translate + ")"        + " scale(" + d3.event.scale + ")");  }        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) {      var link = vis.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 = vis.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        .nodes(graph.nodes)        .links(graph.links)        .start();      force.on("tick", function() {            node[0].x = svg / 2;      node[0].y = svg / 2;                      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 = math.max(r, math.min(width - r, d.x)); }) .attr("cy", function(d) { return d.y = math.max(r, math.min(height - r, d.y)); });                      node.attr("cx", function(d) { return d.x; })          .attr("cy", function(d) { return d.y; });              node.each(collide(0.5));      });                                ///////////////////              //toggle stores whether highlighting on  var toggle = 0;  //create array logging connected  var linkedbyindex = {};  (i = 0; < graph.nodes.length; i++) {      linkedbyindex[i + "," + i] = 1;  };  graph.links.foreach(function (d) {      linkedbyindex[d.source.index + "," + d.target.index] = 1;  });  //this function looks whether pair neighbours  function neighboring(a, b) {      return linkedbyindex[a.index + "," + b.index];  }  function connectednodes() {      if (toggle == 0) {          //reduce opacity of 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 op          toggle = 1;      } else {          //put them 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();  }  });            </script>  </body>

i cannot comment due level restrictions however, believe issue caused width/height variables. uncomment var width/height , change var width = innerwidth, height = innerheight;. in svg set attr .attr('width', width).attr('height', height);.


Comments

Popular posts from this blog

IF statement in MySQL trigger -

c++ - What does MSC in "// appease MSC" comments mean? -

javascript - Blogger related post gadget image Resize s72-c [ Need Expert Help ] -