将圈子排列成行

时间:2019-04-30 07:44:18

标签: javascript d3.js

我正在尝试采用长度为50的数组,并在将数据用d3绑定到圆上时对这些圆的附加方式进行一些控制。以50个圆圈为例,我想要5行10列圆圈。我能想到的最好的是以下片段:

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 circData = new Array(50);

var rowMarker = 1;

graphGroup.selectAll('circle')
    .data(circData)
    .enter()
    .append('circle')
    .attr('cx', function(d,i) { return i*30})
    .attr('cy', function(d,i) {
      if (i%10) {
        rowMarker += 1;
      }
      return rowMarker*30;
    })
    .attr('r', 10)
    .style('fill', 'gray');
<script src="https://d3js.org/d3.v5.min.js"></script>

应该发生的情况是,每当函数将索引rowMarker的深度增加十个元素时,i就会达到新的整数增量。然而,似乎正在发生的事情是,正在添加圆圈,以使它们的y属性值大于如果仅每行更新rowMarker时它们的期望值。

问题

有没有一种方法可以帮助我将圆映射到5x10“圆矩阵”中的数据,就像我上面尝试过的那样?如果是这样,需要什么逻辑?

1 个答案:

答案 0 :(得分:2)

您的代码存在的问题是...

if (i%10)

...除第一个true值(即零)和10的倍数之外的所有内容均为i

但是,除此之外,您的方法似乎不必要地复杂。您只需设置最大列数即可。

var maxColumn = 10;

...,然后对xy值都使用模运算符:

.attr('cx', function(d, i) {
    return (i % maxColumn) * 30
})
.attr('cy', function(d, i) {
    return (~~(i / maxColumn) % maxColumn) * 30
})

这是您所做的更改的代码:

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 circData = new Array(50);

var maxColumn = 10;

graphGroup.selectAll('circle')
  .data(circData)
  .enter()
  .append('circle')
  .attr('cx', function(d, i) {
    return (i % maxColumn) * 30
  })
  .attr('cy', function(d, i) {
    return (~~(i / maxColumn) % maxColumn) * 30
  })
  .attr('r', 10)
  .style('fill', 'gray');
<script src="https://d3js.org/d3.v5.min.js"></script>