条形高度占据 viewBox 响应式 SVG 的整个高度

Posted

技术标签:

【中文标题】条形高度占据 viewBox 响应式 SVG 的整个高度【英文标题】:Bar height taking up entire height of viewBox responsive SVG 【发布时间】:2018-04-08 13:54:22 【问题描述】:

我对 D3.js 还是很陌生。现在,我正在制作一个响应式条形图。我正在使用视图框使其在 div 中响应并使用 DOM 将高度和宽度设置为 div 的 offsetWidth/Height。

但设置为 yScale 时,条形的高度似乎不正确。

这是它们最终出现的屏幕截图:

我也在控制台中被抛出此错误:

"d3.min.js:2 错误:属性高度:负值无效。("-78.69462281846592")"

我认为错误与这部分代码有关,我将高度 attr 设置为由 yScale 数据值减去的高度:

      var bars = svg.selectAll('.bar')
    .data(data)
    .enter()
    .append('rect')
    .attr('class', 'bar')
    .attr('x', function(d) 
      return xScale(d.Year);
    )
    .attr('y', function(d) 
      return yScale(d.Total);
    )
    .attr('width', xScale.bandwidth())
    .attr('height', function(d) 
      return height - yScale(d.Total);
    );

这是绘制条形图的整个函数:

  <style>
    #barchart 
      width: 75vw;
      height: 50vh;
    
  </style>

function draw(data) 

  var width = document.getElementById('barchart').offsetWidth,
    height = document.getElementById('barchart').offsetHeight;

  var svg = d3.select('#barchart')
    .append('svg')
    .attr('width', '100%')
    .attr('height', '100%')
    .attr('viewBox', '0 0 ' + width + ' ' + height)
    .append('g');

  var xScale = d3.scaleBand()
    .range([0, width])
    .padding(0.4);

  var yScale = d3.scaleLinear()
    .range([height, 0]);

  xScale.domain(data.map(function(d) 
    return d.Year;
  ));

  yScale.domain(data.map(function(d) 
    return d.Total;
  ));

  var x_xaxis = svg.append('g')
    .attr('transform', 'translate(' + 0 + ',' + 370 + ')')
    .call(d3.axisBottom(xScale));

  var y_axis = svg.append('g')
    .attr('transform', 'translate(' + 20 + ',' + 0 + ')')
    .call(d3.axisLeft(yScale)
      .ticks(100));

  var bars = svg.selectAll('.bar')
    .data(data)
    .enter()
    .append('rect')
    .attr('class', 'bar')
    .attr('x', function(d) 
      return xScale(d.Year);
    )
    .attr('y', function(d) 
      return yScale(d.Total);
    )
    .attr('width', xScale.bandwidth())
    .attr('height', function(d) 
      return height - yScale(d.Total);
    );



【问题讨论】:

【参考方案1】:

如果没有看到您的数据,很难给出完整的答案,但我确定问题在于您的 yScale 域设置不正确。它是线性的,所以它需要一个[minValue, maxValue] 的数组,你给它一个包含所有数据值的数组。尝试使用extent 设置它:

yScale.domain(d3.extent(data, function(d) 
  return d.Total;
));

通过这个你想从零开始,所以:

yScale.domain([0, d3.max(data, function(d) 
  return d.Total;
)]);

此外,您需要更具体地定义边距。看看这些modifications。

【讨论】:

@rainbowunicorn,查看上面的编辑并链接到 plunker。

以上是关于条形高度占据 viewBox 响应式 SVG 的整个高度的主要内容,如果未能解决你的问题,请参考以下文章

使用 Bootstrap 的响应式内联 SVG

如何使响应式 SVG 图像居中? [复制]

带有 viewBox 和宽度的 SVG 在 IE 中无法正确缩放高度

使用 VH 表示的高度对框 SVG 进行响应式拟合

SVG - 在响应线条中拉伸的圆圈

使用 recharts ( Barchart ) 为响应式图表设置高度和宽度