无法水平堆叠矩形

时间:2019-05-07 09:09:53

标签: javascript d3.js

我只是想找到最简单/最崇高的方式来创建单行堆叠的矩形。使用How to stack rects respective of previous rect's height?中的let计数器来存储先前的数据点可以正常工作,或者完全计算所有点也可以正常工作,如:http://bl.ocks.org/wpoely86/e285b8e4c7b84710e463。然而,这两项似乎都非常简单,似乎是一项简单的任务:找到将rect的x放在哪里以及该rect应该有多宽。在此代码段中,我采用了下面的let方法:

    var margins = {top:20, bottom:300, left:30, right:100};

var height = 600;
var width = 900;

var totalWidth = width+margins.left+margins.right;
var totalHeight = height+margins.top+margins.bottom;

var svg = d3.select('body')
    .append('svg')
    .attr('width', totalWidth)
    .attr('height', totalHeight);

var graphGroup = svg.append('g')
    .attr('transform', "translate("+margins.left+","+margins.top+")");

 var qScale = d3.scaleLinear()
    .range([749,0])
    .domain([0,20]);

var quartiles = [3.78, 6.69, 10.09];

let qCounter = 0;
let wCounter = 0;

graphGroup.selectAll('.markers')
    .data(quartiles)
    .enter()
    .append('rect')
    .attr('class', 'markers')
    .attr('x', function(d) {
      let previous = qCounter;
      return (qCounter += qScale(d), previous)
    })
    .attr('y', 50)
    .attr('width', function(d) {return 749-qScale(d); })
    .attr('height', 50)
    .style('fill', 'gray')
    .style('stroke', '3px');
<script src="https://d3js.org/d3.v5.min.js"></script>

它似乎无法正常工作,只有2个矩形。应该有3个,并且应该将它们堆叠在一起。它们的宽度由quartiles中的值确定。

问题

假设我的.attr('x')逻辑正确,如何确定矩形的正确宽度?

我遇到了同样的问题,因为如果我想尝试将rect的宽度计算为伪代码qScale(d[1]) - qScale(d[0]),那么我将无法引用先前的数据点。我必须为每个这样的属性创建另一个计数器吗?我使用的是d3 v5,真的没有更简单的方法来找到用于堆叠rect等的先前数据吗?

1 个答案:

答案 0 :(得分:2)

您的qScale范围是倒数,应该是:

.range([0, 749])

更好的是,您应该避免使用幻数:

.range([0, width])

这样做之后,将宽度更改为:

.attr('width', function(d) {
    return qScale(d);
})

以下是具有这些更改的代码,并使用色标来区分条形:

var margins = {
  top: 20,
  bottom: 300,
  left: 30,
  right: 100
};

var height = 600;
var width = 900;

var totalWidth = width + margins.left + margins.right;
var totalHeight = height + margins.top + margins.bottom;

var svg = d3.select('body')
  .append('svg')
  .attr('width', totalWidth)
  .attr('height', totalHeight);

var graphGroup = svg.append('g')
  .attr('transform', "translate(" + margins.left + "," + margins.top + ")");

var colors = d3.schemeCategory10;

var qScale = d3.scaleLinear()
  .range([0, width])
  .domain([0, 20]);

var quartiles = [3.78, 6.69, 10.09];

let qCounter = 0;
let wCounter = 0;

graphGroup.selectAll('.markers')
  .data(quartiles)
  .enter()
  .append('rect')
  .attr('class', 'markers')
  .attr('x', function(d) {
    let previous = qCounter;
    return (qCounter += qScale(d), previous)
  })
  .attr('y', 50)
  .attr('width', function(d) {
    return qScale(d);
  })
  .attr('height', 50)
  .style('fill', function(_, i) {
    return colors[i]
  })
  .style('stroke', '3px');
<script src="https://d3js.org/d3.v5.min.js"></script>