如何在D3.js中响应屏幕/浏览器大小制作强制布局graphics

我有一个使用强制布局的graphics,但它具有固定宽度w和高度h

 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])与这个有什么关系。

请介绍一下如何使用force布局图来使用viewBoxpreserveAspectRatio属性。

问题不在.size() ,这是你在.attr("width", w) .attr("height", h)指定SVG尺寸。 删除这两个属性,你会得到它的权利…

 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/

解决scheme显示在这里: 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()。

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 dx; }) .attr("cy", function(d) { return dy; }); }); }; draw_graph(data);