根据for循环的索引查找小数指数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了根据for循环的索引查找小数指数相关的知识,希望对你有一定的参考价值。
用户选择一个数字,然后d3.js应显示多个圆圈。我有一个用于为圆圈指定颜色的数组:
var color =["red","blue", "yellow", "orange",....., ]
●如果用户选择593,则前500个圆圈应为红色(color[0]
),接下来的90个应为蓝色(color[1]
),最后3个圆圈(color[2]
)应为黄色因为
593= 500+90+3 = 5*10^2+9*10^1+3*10^0
或者
var number = 593
var number_as_array = number.toString().split('');
然后
593 = 5*number_as_array[0]*10^number_as_array.length-0-1 + 9*number_as_array[1]*10^number_as_array.length-1-1+ 3*number_as_array[2]*10^number_as_array.length-2-1
●如果用户选择4168,则前4000个圆圈应为红色,下一个100应为蓝色,下一个为60黄色,最后一个为橙色
要为每个圆圈指定颜色,我用它来创建一个带有for循环的JS对象构建数组
var data=[]
for (index =0; index< number; index++){
circle= {};
circle.cx = circle_x;
circle.cy = circle_y;
circle.color = color[????]
data.push(circle);
如何根据上述条件将颜色分配给circle.color
?
不要从其他答案中减少,这是另一种方法。
取一个给定的总圈数,它会检查总数中需要多少有效数字(向下舍入),以便任何给定的索引小于舍入总数。
我不确定这是否完全合理,所以我将使用一个例子:
如果共有132个圈子:
- 索引0到99将小于100(132向下舍入,有一个有效数字)。
- 索引100到129将小于130(132向下舍入,有两位有效数字)。
- 索引130和131将小于132(132具有所有有效数字)。
这是一个快速演示(行数为50个圆圈):
var svg = d3.select("body")
.append("svg")
.attr("width",510)
.attr("height",510);
var n = 377;
var color = d3.scaleOrdinal()
.range(["steelblue","orange","crimson","lawngreen","pink"])
var digits = Math.floor(Math.log10(n));
var circles = svg.selectAll("circle")
.data(d3.range(n))
.enter()
.append("circle")
.attr("cx",function(d,i) { return i%50 * 10 + 5 })
.attr("cy",function(d,i) { return Math.floor(i/50) * 10 + 5 })
.attr("r",5)
.attr("fill", function(d,i) {
var exp = digits;
while (i < Math.floor(n/Math.pow(10,digits-exp))*Math.pow(10,digits-exp)) {
exp--;
}
return color(exp);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
var color = ["red","orange", "yellow", "green", "blue", "indigo", "violet"];
var circleCount = "4192"; // use string
var length = circleCount.length;
var counter = [];
for (var i = 0; i < length; i++) {
var digit = circleCount.substring(i, i+1);
var exponent = length - i - 1;
var number = digit * Math.pow(10, exponent);
counter.push(number); // might have to use .unshift instead of .push
}
console.log(counter);
for (var i = 0; i < counter.length; i++) {
for (var j = 0; j < counter[i]; j++) {
drawCircle(color[i]);
}
}
这是使用D3的Threshold Scales的完美案例:你给它N个数字,你想要颜色之间的中断,N + 1颜色返回任何输入值。以下是文档中的示例:
var color = d3.scaleThreshold() .domain([0, 1]) .range(["red", "white", "green"]); color(-1); // "red" color(0); // "white" color(0.5); // "white" color(1); // "green" color(1000); // "green"
因此,您的案例的挑战是如何将(例如)593的示例输入转换为两个数字[500,590]的数组:
var sinput = 593 + ""; // make the input a string
var digits = sinput.split("").slice(0, -1); // use all digits but the last one
var breaks = digits.map((d, i, a) =>
+(a.slice(0, i+1).join("")) * Math.pow(10, a.length-i)
);
var colors = ["red", "blue", "yellow", "orange"];
var tScale = d3.scaleThreshold()
.domain(breaks)
.range(colors);
任何<500映射到“红色”,从500 - 589映射到“蓝色”,并且≥590映射到“黄色”。除非使用4位数字作为输入,否则不使用附加范围颜色(“橙色”)。
注意:此逻辑假定输入数字至少为2位数。
您现在可以在创建圆圈时指定颜色 - 而不是使用.attr("color", (d, i) => tScale(i))
之类的语法在数据数组中预先填充颜色
其他方法似乎过于复杂。您可以将数字拆分为数字,然后根据索引创建所需的10 ^ digitIndex圆圈颜色。我已经包含一行来检查数字是不是太大了。
function mapColors(num) {
var color =['red','blue', 'yellow', 'orange'];
// If the number is longer than the color array, return undefined
if ((''+num).length > color.length) return;
return (''+num).split('').reduce(function (acc, n, i, arr) {
for (var j=n*Math.pow(10, arr.length-i-1); j; --j) {
acc.push({'color':color[i]});
// Add more circle properties here
}
return acc;
}, []);
}
console.log(mapColors(23));
以上是关于根据for循环的索引查找小数指数的主要内容,如果未能解决你的问题,请参考以下文章
根据向量大小在 for 循环内擦除 std::vector 的索引