我会这样做。
//generate a number between 11 and 99
var randNumber = Math.round(Math.random() * 90 + 11)
//Get difference when divide rand number by 10
var circleUnits = Math.round(randNumber%10);
//get how many 10's you can fit in what is left over
var circleTens = Math.round(randNumber-circleUnits)/10 ;
//use this data to generate arrays to work with
var circleUnitsData = d3.range(circleUnits).map(function(j, i) {return {
count : i,
radius: 15
}})
var circleTensData = d3.range(circleTens).map(function(j, i) {return {
count : i+1,
radius: 15
}})
这是我为十位生成圆圈的方法。因为每列总是会有 10 个圆圈(这就是我在上面将它除以 10 的原因):
var nodeRadius = 15;
var tensContainer = gTens.selectAll('circle') //put this outside the foreach so you don't overwrite any other circles
var difference = 5; //gap between circles
circleTensData.forEach(function(d ,i){
tensContainer.data([1,2,3,4,5,6,7,8,9,10])
.enter()
.append('circle')
.attr("cx",function(e,j) {
// console.log(e)
return 100 + i * nodeRadius*2 + (i*difference) //use i here to get what set of 10 it is in
})
.attr("cy", function(e,j) {
return 100 + j * nodeRadius*2 + (j*difference) //use j here to increment downwards
})
.attr("r", function(e) {
return nodeRadius //hard coded radius above
})
.attr("fill", "white")
.style("stroke", "black")
.style("stroke-width", 3);
})
那么单位就更容易了。为了计算出 x 位置,我将 10 的数据集的大小乘以节点的宽度加上差值,然后加上 40 来给它一个偏移量。所以每次刷新,单位都是向右40个单位:
var circlesUnits = gUnits.selectAll('circle')
.data(circleUnitsData)
.enter()
.append('circle')
.attr("cx", function(d) {
var i = circleTensData.length;
console.log(400 + i * nodeRadius*2 + (i*difference))
return 140 + i * nodeRadius*2 + (i*difference)
})
.attr("cy", function(d, i) {
return 100 + i * nodeRadius*2 + (i *difference)
})
.attr("r", function(d) {
return d.radius
})
.attr("fill", "white")
.style("stroke", "black")
.style("stroke-width", 3);
在刷新时,我添加了一个警报来显示随机数。
如果我误读了问题,或者有任何问题,请随时发表评论,我会调整。希望这可以帮助你:)
更新小提琴:https://jsfiddle.net/thatOneGuy/8hc0sfbg/1/
编辑
您说您不希望数字以 0 结尾。以下将起作用:
function getRand() {
var randNumber = Math.round(Math.random() * 90 + 11) // number between 0-99
if (randNumber % 10 == 0) { //if ends in 0 run again
return getRand();
}
return randNumber;
}
我已将代码包装在一个函数中,以便您可以在需要时调用它。所以上面的代码会在调用新函数时运行。单击“单击我”按钮运行该功能
更新小提琴:https://jsfiddle.net/thatOneGuy/8hc0sfbg/5/
编辑
您希望使圆圈居中。我会删除您设置的任何起始动作,即像这样设置 cx 和 cy 时:
return 100 + i * nodeRadius*2 + (i*difference)
只需去掉重置它的 100 即可。然后我会将它翻译一半的宽度并删除十位和单位边界框的一半宽度。哪个应该居中。像这样:
var circleContainer = d3.select('#circleContainer')
var circleTensContainer = d3.select('#tens')
var circleUnitsContainer = d3.select('#units')
var tensBBox = circleTensContainer.node().getBBox();
var unitsBBox = circleUnitsContainer.node().getBBox();
var containerSize = 40 + tensBBox.width + unitsBBox.width;
var thisMovX = svgWidth/2 - containerSize/2;
circleContainer.attr('transform', 'translate(' + thisMovX + ',0)' )
如果你也想让 y 居中,你可以做类似的事情。我也改变了你画线的地方。希望这会有所帮助:)
更新小提琴:https://jsfiddle.net/thatOneGuy/8hc0sfbg/8/