在 D3 v4 中使 SVG 容器具有父容器的 100% 宽度和高度(而不是像素)

Posted

技术标签:

【中文标题】在 D3 v4 中使 SVG 容器具有父容器的 100% 宽度和高度(而不是像素)【英文标题】:Making SVG container 100% width and height of parent container in D3 v4 (instead of by pixels) 【发布时间】:2017-12-03 15:58:47 【问题描述】:

我有一个父容器 (div.barChartContainer),它的高度和宽度是从视口计算出来的,例如:width: calc(100vh - 200px)。 SVG 容器附加到 div.barChartContainer 元素。

我正在努力解决如何让 SVG 元素的宽度和高度达到其父元素的 100%,希望能得到一些帮助。现在我有静态像素数量(它目前可以正确渲染,但没有响应)。

谢谢!

  var margin = top: 20, right: 20, bottom: 30, left: 80,
          width = 960 - margin.left - margin.right,
          height = 500 - margin.top - margin.bottom;          
          // set the ranges
          var y = d3.scaleBand()
          .range([height, 0])
          .padding(0.4);
          var x = d3.scaleLinear()
          .range([0, width]);          
          var svg = d3.select(".barChartContainer").append("svg")
          .attr("width", width + margin.left + margin.right)
          .attr("height", height + margin.top + margin.bottom)
          .append("g")
          .attr("transform",
          "translate(" + margin.left + "," + margin.top + ")");

【问题讨论】:

这有用吗? ***.com/questions/9400615/… @RobinL - 是的,谢谢! 【参考方案1】:

解决方案是注释掉/删除宽度和高度属性值,而是添加以下两行:

//- .attr("width", width + margin.left + margin.right)
//- .attr("height", height + margin.top + margin.bottom)
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "0 0 960 500")

【讨论】:

只是一个警告; viewBox 属性区分大小写!注意它应该是camelCase。使用属性viewbox 将不起作用。还交叉链接其他类似的问题/答案:***.com/questions/9400615/…***.com/questions/11942500/… chartio.com/resources/tutorials/…【参考方案2】:

检查 svg 是否使用父级高度和宽度绘制。

参考:https://bl.ocks.org/curran/3a68b0c81991e2e94b19

var parentDiv = document.getElementById("parentDiv");
var svg = d3.select(parentDiv).append("svg");

function redraw(show) 

  // Extract the width and height that was computed by CSS.
  var width = parentDiv.clientWidth;
  var height = parentDiv.clientHeight;
  // Use the extracted size to set the size of an SVG element.
  svg
    .attr("width", width)
    .attr("height", height);
  if (show === false) 
    svg.style('visibility', 'hidden');
   else 
    svg.style('visibility', 'visible');
  

  svg.attr("style", "outline: thin solid red;")
    .append("circle")
    .attr("cx", 30)
    .attr("cy", 30)
    .attr("r", 20);


// Draw for the first time to initialize.
redraw(false);

// Redraw after sometime
setTimeout(redraw, 1000);
#parentDiv 
  height: calc(100vh - 100px); /** output container is small for display */ 
  width: calc(100vw - 100px);
  display: block;
  border: 1px solid red;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.10/d3.min.js"></script>
<div id="parentDiv"></div>

【讨论】:

@duhaime ,它根本没有重绘,因为它只是设置可见性,如果它已经尝试过,它不会产生影响。它只做了两次,即隐藏拳头,然后可见。我写的是setTimeout 而不是setInterval 哦,你是 100% 正确的!过失,我以某种方式阅读了setInterval

以上是关于在 D3 v4 中使 SVG 容器具有父容器的 100% 宽度和高度(而不是像素)的主要内容,如果未能解决你的问题,请参考以下文章

d3.js Map (<svg>) 自动适应父容器并随窗口调整大小

如何使用 D3.js 将图像添加到 svg 容器

d3.js - 当鼠标悬停在 SVG 容器上的这些元素上时,如何将光标设置为手?

如何在父容器中使所有 div 可拖动

SVG基础图形和D3.js

缩放 d3 v4 地图以适合 SVG(或根本不适合)