0

我已经制作了一个平行坐标图,现在我想让它响应。
为了测试响应能力,我想首先让Mike Bostock 的这个例子是响应式的。

我面临的问题是,如果我将“svg”直接放在“body”标签内,它会完美运行。但是当我将“svg”放在一些 div 中时,调整窗口大小时图表会被裁剪。此外,svg 的高度被提到为 70%,如果我将其设为 80%,则图表将被裁剪而无需调整大小。我知道还有另一种选择是使用 viewBox 和 preserveAspectRatio,但我使用这种方法是因为它很容易理解,对于我或任何其他阅读我的代码的人来说。这是方法:

 d3.csv("data.csv",function(data){
  ....
 function resize(){
    width = parseInt(d3.select("#mychart").style("width")) - margin.left - margin.right,
      height = parseInt(d3.select("#mychart").style("height")) - margin.top - margin.bottom;

      x.rangePoints([0, width], 1);

      svg.select("#mychart")
          .attr("width", width + margin.left + margin.right)
          .attr("height", height + margin.top + margin.bottom);

      x.domain(dimensions = d3.keys(cars[0]).filter(function(d) {
            return d != "name" && (y[d] = d3.scale.linear()
                .domain(d3.extent(cars, function(p) { return +p[d]; }))
                .range([height, 0]));
          }));

      svg.selectAll(".line").attr("d", path);

      g = svg.selectAll(".dimension")
          .attr("transform", function(d) { return "translate(" + x(d) + ")"; });

      g.selectAll(".axis")
          .each(function(d) {d3.select(this).call(axis.scale(y[d])); })
        .append("text")
          .style("text-anchor", "middle")
          .attr("y", -9)
          .text(function(d) { return d; });
  }
  d3.select(window).on('resize', resize);
  resize();
});

是完整代码的 plunker 链接。有人可以指出代码有什么问题吗?

4

1 回答 1

0

这更多是关于理解CSS

具体来说,你可以给你的<svg>元素 a height100%然后设置包含元素的大小。

我的例子

在这里,<svg>总是有一个heightof 100%,而<div>包含 的<svg>有一个百分比height,它又是相对于.container-fluid容器的,它有一个绝对高度(在视口单位中)。

另外,看看这个答案

如果您想让 div 高度成为视口高度的百分比,则 div 的每个祖先(包括 和 )都必须具有 height: 100%,因此有一个明确的百分比高度链一直到 div。

或者,所有现代浏览器和 IE>=9 都支持相对于视口高度 (vh) 和视口宽度 (vw) 的新 CSS 单位:

这个答案

要使您的 SVG 填充 HTML 元素,请将 CSS 属性position:relativeposition:absoluteposition:fixed如果合适)放在包装器上,然后 [...]position:absolute<svg>元素上设置 CSS 属性以使其位于内部并填充您的 div。(如有必要,也申请left:0; top:0; width:100%; height:100%。)

您可以(像我一样)使用视口单位来设置包含的高度div

或者,您可以尝试使用该flexbox属性来定位您的.row元素。


此外,您的resize()功能可以大大简化。它需要做三件事:

  1. 更新范围
  2. 更新使用这些比例的任何属性
  3. 调用你的函数
  function resize() {
    width = parseInt(d3.select("#mychart").style("width")) - margin.left - margin.right,
    height = parseInt(d3.select("#mychart").style("height")) - margin.top - margin.bottom;

    x.rangePoints([0, width], 1);

    d3.values(y).forEach(function(scale) {
      scale.range([height, 0])
    })

    svg.selectAll(".line").attr("d", path);

    g = svg.selectAll(".dimension")
      .attr("transform", function(d) {
        return "translate(" + x(d) + ")";
      });

    g.selectAll(".axis").call(axis.scale(y[d]))
  }
于 2015-11-21T19:00:55.017 回答