简体   繁体   English

保证D3中的滴答声数量

[英]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刻度的底轴,但要始终包含第一项和最后一项,在这种情况下,它们分别是: 115

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> 

Integers 整数

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM