[英]Guarantee the number of ticks in D3
I have a X axis that has this kind of data: 我有一个具有此类数据的X轴:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
Sequential numbers. 序号。 I want to have a bottom axis with X ticks but want to always include the first and the last item—which, in this case is:
1
and 15
respectively. 我希望有一个带有X刻度的底轴,但要始终包含第一项和最后一项,在这种情况下,它们分别是:
1
和15
。
The problem with d3.ticks
is that it sometimes doesn't return the last tick. d3.ticks
的问题在于它有时不返回最后的刻度。 And I can't use nice: true
because all ticks should be numbers that exist in the data set. 而且我不能使用
nice: true
因为所有刻度都应该是数据集中存在的数字。
Thoughts? 有什么想法吗?
EDIT : The goal is to find an even space between ticks considering that the first and the last tick should be always present. 编辑 :目的是考虑到第一个和最后一个刻度应始终存在,从而在刻度之间找到一个均匀的间隔。
In your specific situation you can use d3.range
to generate the ticks, that you'll pass to your axis' tickValues
method. 在您的特定情况下,可以使用
d3.range
生成刻度,然后将其传递给轴的tickValues
方法。 For instance: 例如:
const scale = d3.scaleLinear([0, 15], [0, 1]); const numberOfTicks = 7; const tickStep = (scale.domain()[1] - scale.domain()[0]) / (numberOfTicks - 1); const myTicks = d3.range(scale.domain()[0], scale.domain()[1] + tickStep, tickStep); console.log(myTicks)
<script src="https://d3js.org/d3.v5.min.js"></script>
However, due to the floating-point precision issues, you may have an unexpected length for your array depending on the combination of domain/number of ticks. 但是,由于浮点精度问题,取决于域/滴答数的组合,数组的长度可能会超出预期。 For instance, using
[8,15]
as the domain and 7 ticks: 例如,使用
[8,15]
作为域并[8,15]
7:
const scale = d3.scaleLinear([8, 15], [0, 1]); const numberOfTicks = 7; const tickStep = (scale.domain()[1] - scale.domain()[0]) / (numberOfTicks - 1); const myTicks = d3.range(scale.domain()[0], scale.domain()[1] + tickStep, tickStep); console.log(myTicks)
<script src="https://d3js.org/d3.v5.min.js"></script>
As you can see, we have 8 elements in the array, not 7. 如您所见,数组中有8个元素,而不是7个。
For dealing with those cases, you can just pass the number of ticks to d3.range
and deal with the math using map
: 为了处理这些情况,您可以将滴答数传递给
d3.range
并使用map
处理数学:
const scale = d3.scaleLinear().domain([8, 15]); const numberOfTicks = 7; const tickStep = (scale.domain()[1] - scale.domain()[0]) / (numberOfTicks - 1); const myTicks = d3.range(numberOfTicks) .map(d => scale.domain()[0] + d * tickStep); console.log(myTicks);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
The previous examples generate evenly spaced ticks. 前面的示例生成均匀间隔的刻度。 However, I suppose you want integers as values.
但是,我想您希望将整数用作值。 In that case, pay attention to the fact that you cannot have both integers and evenly spaced ticks for all possible combinations of domain and number of ticks.
在这种情况下,请注意以下事实:域和滴答声数量的所有可能组合都不能同时包含整数和均匀间隔的滴答声。
To get integers, just round the values: 要获取整数,只需将值取整:
const scale = d3.scaleLinear([0, 15], [0, 1]); const numberOfTicks = 7; const tickStep = (scale.domain()[1] - scale.domain()[0]) / (numberOfTicks - 1); const myTicks = d3.range(scale.domain()[0], scale.domain()[1] + tickStep, tickStep) .map(d => Math.round(d)) console.log(myTicks)
<script src="https://d3js.org/d3.v5.min.js"></script>
And here the same approach as the third snippet, doing all the math in the map
and using [8,15]
as an example: 这里与第三个代码段相同,在
map
进行所有数学运算,并以[8,15]
为例:
const scale = d3.scaleLinear().domain([8, 15]); const numberOfTicks = 7; const tickStep = (scale.domain()[1] - scale.domain()[0]) / (numberOfTicks - 1); const myTicks = d3.range(numberOfTicks) .map(d => Math.round(scale.domain()[0] + d * tickStep)); console.log(myTicks);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.