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

时间:2018-04-08 13:54:22

标签: d3.js

我对D3.js还不太新鲜。现在,我正致力于制作响应式条形图。我使用视图框使其在div中响应并使用DOM将高度和宽度设置为div的offsetWidth / Height。

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

以下是他们最终出现的截图:

enter image description here

我也在控制台中抛出了这个错误:

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

我认为错误与代码的这一部分有关,我将高度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 个答案:

答案 0 :(得分:2)

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

进行设置
yScale.domain(d3.extent(data, function(d) {
  return d.Total;
}));

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

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

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