2012-08-13 42 views
45

我使用武力布局有一个图表,但它有一个固定的宽度w和高度h如何使力布局图中D3.js响应屏幕/浏览器的大小

var svg = d3.select("#viz").append("svg") 
      .attr("id", "playgraph") 
      .attr("width", w) 
      .attr("height", h) 

var force = d3.layout.force() 
       .nodes(nodes) 
       .links(links) 
       .charge(-1600) 
       .linkDistance(45) 
       .size([w, h]); 

这会导致SVG尽管屏幕或浏览器窗口大小发生变化,该图表不会缩小或缩小。为了使其响应(即自动调整自己),我尝试使用viewBoxpreserveAspectRatio属性:

var svg = d3.select("#viz").append("svg") 
      .attr("id", "playgraph") 
      .attr("width", w) 
      .attr("height", h) 
      .attr("viewBox", "0, 0, 600, 400") 
      .attr("preserveAspectRatio", "xMidYMid meet"); 

不幸的是,当我调整浏览器窗口大小没有任何反应并没有工作。我想知道力图的.size([w, h])与此有什么关系。

请阐明如何使用viewBoxpreserveAspectRatio属性与力布局图。

+0

您可能还希望将重画功能附加到'window.onresize'上 – Wex 2012-08-14 15:57:33

+0

这个问题相当陈旧,但对于那些觉得很有用的人来说,您可能还需要考虑将节点限制在一个有界的框中。在调整大小时,节点将保持在屏幕上。例如:http://bl.ocks.org/mbostock/1129492 – joshfindit 2016-08-01 16:25:46

回答

50

该问题不在.size()之内,这是您在说明SVG尺寸的.attr("width", w) .attr("height", h)。删除这两个属性,你会得到它的权利......

var svg = d3.select("#viz").append("svg") 
      .attr("id", "playgraph") 
      //better to keep the viewBox dimensions with variables 
      .attr("viewBox", "0 0 " + w + " " + h) 
      .attr("preserveAspectRatio", "xMidYMid meet"); 

http://jsfiddle.net/aaSjd/

+0

谢谢!所以现在svg图像调整大小。但是,如果不设置'attr(“width”,...)'和'attr(“height”,...)',图像的宽度/高度似乎是当前浏览器窗口的宽度/高度。有什么方法可以将'svg'元素的这两个维度设置在其他地方,而不会影响'viewBox'和'preserveAspectRatio'属性? – MLister 2012-08-14 16:08:29

+3

''应该让你开始。 – Duopixel 2012-08-14 23:09:40

4

Duopixel是非常接近我所需要的,只是我不知道他为什么两个嵌套<g>元素和附事件监听器到最外面的<g>(也需要在所有内容后面都有一个不可见的矩形,以便g对整个空间中的事件做出反应)。

将听众连接到<svg>本身更容易,然后您只需要一个内部<g>

这里是我的全屏力指向例如:

var width = 1000, 
    height = 1000; 

var color = d3.scale.category20(); 

var svg = d3.select("body") 
    .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 + ")"); 
} 

function draw_graph(graph) { 
    var force = d3.layout.force() 
     .charge(-120) 
     .linkDistance(30) 
     .nodes(graph.nodes) 
     .links(graph.links) 
     .size([width, height]) 
     .start(); 

    var link = vis.selectAll(".link") 
     .data(graph.links) 
     .enter().append("line") 
     .attr("class", "link") 
     .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", 5) 
     .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("cx", function(d) { return d.x; }) 
     .attr("cy", function(d) { return d.y; }); 
    }); 
}; 

draw_graph(data); 
8

这里展示的解决方案:http://bl.ocks.org/mbostock/3355967行之有效我!

window.addEventListener('resize', resize); 

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

确保在附加了所有行,节点等之后运行resize()。

相关问题