d3中的axis.ticks详解

广告位招租
扫码页面底部二维码联系


本文作者:唐霜,转载请注明出处。原创内容,盗版必究。 d3中有一个和坐标轴相关的方法,即ax转载请注明出处:www.tangshuang.net【作者:唐霜】is.ticks().但是它的用法让人琢【版权所有】唐霜 www.tangshuang.net【本文受版权保护】磨不透,本文就试图通过一些案例来对其进行未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net详细的解释。

【原创不易,请尊重版权】【转载请注明来源】【转载请注明来源】【本文受版权保护】【版权所有】唐霜 www.tangshuang.net

axis.ticks()用来设定分段数量

著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】本文版权归作者所有,未经授权不得转载。

当通过比例尺创建一个y坐标轴的时候,可能本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net你只想让你的y轴坐标刻度只显示两个,即只【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。有收尾,怎么办?把ticks()参数设为【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。1即可:

【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】
let scale = d3.scale.linear()  .domain([0, 100])  .range([0, 300])
let axis = d3.svg.axis()
  .scale(scale)  .orient('left')  .ticks(1)

设为1表示整个y轴被分为1段,两头都会出原创内容,盗版必究。【作者:唐霜】现一个刻度,所以就会出现两个刻度。同样的【本文受版权保护】原创内容,盗版必究。道理,设置为2则会出现两段三个刻度,设置【作者:唐霜】著作权归作者所有,禁止商业用途转载。为5则会出现5段6个刻度。

【本文首发于唐霜的博客】【本文受版权保护】【版权所有】唐霜 www.tangshuang.net

然而,当你设置为3的时候,奇怪的事情发生转载请注明出处:www.tangshuang.net【转载请注明来源】了。并没有出现3段4个刻度的结果,而是出转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net现了2段3个刻度。这是怎么回事呢?

本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net

axis.ticks()的分段规则【转载请注明来源】

转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。【原创不易,请尊重版权】

之所以3不起作用了,是因为定义域doma【本文首发于唐霜的博客】本文作者:唐霜,转载请注明出处。in中的[0, 100]无法计算得出对应【本文受版权保护】【版权所有,侵权必究】的结果。在这个转载请注明出处:www.tangshuang.net回答里,mbostock指出,无论你怎么【作者:唐霜】【本文受版权保护】设定,ticks的参数实际上都是在2,5本文版权归作者所有,未经授权不得转载。【作者:唐霜】和10这三个中选。

【未经授权禁止转载】转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net

The default ticks fo未经授权,禁止复制转载。【本文首发于唐霜的博客】r quantitative scale【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】s are multiples of 2【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。, 5 and 10. You appe【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。ar to want multiples【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。 of 6; though unusua【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。l, this could make s【原创不易,请尊重版权】【版权所有,侵权必究】ense depending on th未经授权,禁止复制转载。【未经授权禁止转载】e nature of the unde本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。rlying data. So, whi【未经授权禁止转载】原创内容,盗版必究。le you can use axis.本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。ticks to increase or【原创不易,请尊重版权】【访问 www.tangshuang.net 获取更多精彩内容】 decrease the tick c未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。ount, it will always转载请注明出处:www.tangshuang.net原创内容,盗版必究。 return multiples of本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。 2, 5 and 10 — not 6未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】.

【原创不易,请尊重版权】【原创内容,转载请注明出处】未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】
本文版权归作者所有,未经授权不得转载。【访问 www.tangshuang.net 获取更多精彩内容】【未经授权禁止转载】未经授权,禁止复制转载。【未经授权禁止转载】

(实际上还支持0和1,当超过10之后下文原创内容,盗版必究。本文作者:唐霜,转载请注明出处。再做详说),所以你传入3实际上相当于传入【原创不易,请尊重版权】未经授权,禁止复制转载。2,传入4相当于传入5,传入6相当于传入【本文受版权保护】【未经授权禁止转载】5,传入8相当于传入10.也就是说你传入著作权归作者所有,禁止商业用途转载。【作者:唐霜】的值,首先和上面这几个备选参数去比较,越【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。接近哪一个,就用哪个作为值。所以当你传入转载请注明出处:www.tangshuang.net【转载请注明来源】接近10而距离另一个值更远的值时,就会相【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net当于传入10. 传入1.5时取1,传入1【版权所有,侵权必究】【版权所有,侵权必究】.6时取2.

本文作者:唐霜,转载请注明出处。【作者:唐霜】【转载请注明来源】

当超过10之后怎么算?传入大于10之后,著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net就以20,50和100来计算,当然,10本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。还是算数的,传入15相当于传入10,但是【转载请注明来源】本文版权归作者所有,未经授权不得转载。传入16就相当于传入20.这个规则跟10【版权所有,侵权必究】【作者:唐霜】以内其实差不多。

【本文受版权保护】【访问 www.tangshuang.net 获取更多精彩内容】【原创不易,请尊重版权】

axis.ticks()还和定义域相关【访问 www.tangshuang.net 获取更多精彩内容】

【转载请注明来源】【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。

上面的演示其实有一个隐含条件,就是我们的原创内容,盗版必究。未经授权,禁止复制转载。定义域规定为[0, 100],也就是说2著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】,5,10的规律是基于100来计算的,如【原创内容,转载请注明出处】【访问 www.tangshuang.net 获取更多精彩内容】果换成[0, 200], [0, 300【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。]结果又不一样,分段的时候,也不是简单的转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】把轴刻度上的数值改为对应的定义域的值而已著作权归作者所有,禁止商业用途转载。【本文受版权保护】

【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】【原创内容,转载请注明出处】

比如说,如果你的定义域为[0, 200]本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】,ticks传入4,那么可以得到分4段5【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】个刻度的轴。这和[0, 100]的结果大未经授权,禁止复制转载。未经授权,禁止复制转载。不相同,如果按照这个逻辑,100/4=2【转载请注明来源】【版权所有】唐霜 www.tangshuang.net5,为什么不分25为单位的刻度呢?

本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。【未经授权禁止转载】本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。

这里又有一个逻辑,就是分割出来的每一段的【本文受版权保护】【版权所有,侵权必究】值,也必须在1,2,5,10(及其10倍【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。值)中挑选,不能有3,6,8之类的个位值本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。出现。所以分出来的结果中,超出10的,个【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】位值只有0,不会有5,更别提其他值。超出著作权归作者所有,禁止商业用途转载。【作者:唐霜】100的,整体上又要遵循这个规律,如此类【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】推下去。
未经授权,禁止复制转载。原创内容,盗版必究。 但是正是由于这一规则,导致出现了一个界本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】面上的bug,比如定义域为[0, 300【关注微信公众号:wwwtangshuangnet】【本文受版权保护】],ticks为2,会出现什么结果?

【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】【作者:唐霜】本文作者:唐霜,转载请注明出处。

【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。【本文首发于唐霜的博客】

结果没有在轴末端显示300,而是在2/3【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】处显示了200. 这种情况,对于开发者而【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。言,也是应该注意和尽量避免的。为什么会出【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】现这个情况呢?

【转载请注明来源】【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net

当定义域上限为300的时候,分成2段,那【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net么每一段按理应该是150. 但是由于这个【作者:唐霜】转载请注明出处:www.tangshuang.net值超过了100,所以需要在十位数上进行观未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net察,发现十位数是5,这是不被允许的,单位本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】值超过100的,必须以100及其倍数作为【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。单位值,所以就会被重新计算。按照上文的规【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】则,150按照上文1.5的那种方法去思考【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net,应该使用100作为单位值。

【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net

看似去已经遵循规则了,但是并不是这样,当【本文受版权保护】【版权所有】唐霜 www.tangshuang.net你用100作为单位的时候,300会被分为本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net3段4个刻度,所以ticks的值应该是3【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】才对,而不是2. 我们用代码来实际验证一【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net下:

【未经授权禁止转载】未经授权,禁止复制转载。【本文首发于唐霜的博客】原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】
let scale = d3.scale.linear()
  .domain([0, 300])
  .range([0, 300])
let axis = d3.svg.axis()
  .scale(scale)
  .orient('left')
  .ticks(3)

你会发现,真的被分为了3段4个刻度。这完未经授权,禁止复制转载。【本文受版权保护】全打翻了我们上文提到的ticks值只能在【原创内容,转载请注明出处】【版权所有,侵权必究】2,5,10中挑选的设定。

【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。

当定义域为[0, 300]时,ticks【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】值为1和3时,我们都可以非常容易想象出结【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】果,但是为2时d3也无法按照预想结果处理【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。。也就出现了上图的尴尬局面。

著作权归作者所有,禁止商业用途转载。【作者:唐霜】【本文受版权保护】【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net

axis.ticks()根本不是用来决定【转载请注明来源】未经授权,禁止复制转载。分段数量的

本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。【转载请注明来源】本文作者:唐霜,转载请注明出处。

通过上面的一系列弯路,你或许已经隐隐察觉【未经授权禁止转载】原创内容,盗版必究。,ticks根本不是用来设定分段数量的。【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net真正的分段,是靠每一段的单位来确定的,比【作者:唐霜】【未经授权禁止转载】如说定义域为[0, 40]想分5段,那么【转载请注明来源】本文作者:唐霜,转载请注明出处。每一段长度应该为8,但是8根本不在2,5【本文首发于唐霜的博客】【原创内容,转载请注明出处】,10这个考虑范围内,同样的道理,[0,【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。 700]想分3段也分不出来。

著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】

真正的思考逻辑是,用1,2,5及其10倍未经授权,禁止复制转载。【原创不易,请尊重版权】数作为除数去计算。比如[0, 600],【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net用1,2,5及其10倍数去除,而不要用3【版权所有】唐霜 www.tangshuang.net【本文受版权保护】,6,9之类的数去除。600/50=12原创内容,盗版必究。本文作者:唐霜,转载请注明出处。,所以ticks填写12是可行著作权归作者所有,禁止商业用途转载。的,600/3=200,所以ticks填著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net写200是不行本文作者:唐霜,转载请注明出处。的。转载请注明出处:www.tangshuang.net

【转载请注明来源】本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。【转载请注明来源】

ticks的值填写什么,根本不是段数决定本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。的,而是除数决定的,先在脑海中想一下除数是否为1,2,5及其未经授权,禁止复制转载。【本文受版权保护】10倍数,(不是的话,放心,得不到你想要本文版权归作者所有,未经授权不得转载。【访问 www.tangshuang.net 获取更多精彩内容】的效果,)想一下除出来的结果,再填写这个原创内容,盗版必究。【版权所有,侵权必究】结果【作者:唐霜】

【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】【本文受版权保护】【原创内容,转载请注明出处】【转载请注明来源】

这里的定义域全部都是0开头的,实际上不一【本文受版权保护】本文作者:唐霜,转载请注明出处。定从0开始,比如[300, 600],这【转载请注明来源】本文版权归作者所有,未经授权不得转载。个时候被除数应该用300。

【原创不易,请尊重版权】【转载请注明来源】【原创不易,请尊重版权】【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。

如果你一不小心,填写了未经脑海计算的值,【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net会得到什么结果呢?d3会尽可能处理到与你【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。传入的值最接近的结果,但是有的时候就会变本文作者:唐霜,转载请注明出处。【未经授权禁止转载】成上面那图的最后的效果,会让人摸不着头脑【访问 www.tangshuang.net 获取更多精彩内容】【本文受版权保护】

【转载请注明来源】未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net

d3的代码是怎么处理axis.ticks【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】的?

【版权所有,侵权必究】【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net

到底ticks是怎么来处理传入的参数的,【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】还需要通过代码来研究。在d3中ticks【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。概念【本文受版权保护】是指,从一个值到另一个分割为特定数量的数著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】组:

【转载请注明来源】【未经授权禁止转载】【本文受版权保护】【作者:唐霜】

Returns an array of 【本文受版权保护】【作者:唐霜】approximately count未经授权,禁止复制转载。 + 1 uniformly-space【本文首发于唐霜的博客】未经授权,禁止复制转载。d, nicely-rounded va著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】lues between start【本文受版权保护】 and 【版权所有,侵权必究】stop未经授权,禁止复制转载。 (inclusive). Each v【未经授权禁止转载】未经授权,禁止复制转载。alue is a power of t转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。en multiplied by 1, 未经授权,禁止复制转载。【转载请注明来源】2 or 5.
【作者:唐霜】【原创不易,请尊重版权】 译:返回一个start到stop之间(未经授权,禁止复制转载。【转载请注明来源】包含stop)的接近count+1个值的【作者:唐霜】【转载请注明来源】数组,这个数组具有均匀的间隔(unifo【转载请注明来源】著作权归作者所有,禁止商业用途转载。rmly-spaced),进行了优雅地(【作者:唐霜】【本文首发于唐霜的博客】nicely)四舍五入(round)。每转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】个值都是1,2或5乘以10的幂(10x本文作者:唐霜,转载请注明出处。)。本文作者:唐霜,转载请注明出处。

著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。未经授权,禁止复制转载。【作者:唐霜】
【版权所有】唐霜 www.tangshuang.net【转载请注明来源】本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】未经授权,禁止复制转载。

而在axis.ticks上,也必然遵循这本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】一算法。它是以axis的domain作为【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】start和stop,以ticks的值作原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。为count,得到一个数组,这个数组里面【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】的值就一一对应每一个刻度的值。当然它们也【访问 www.tangshuang.net 获取更多精彩内容】【未经授权禁止转载】遵循10x【访问 www.tangshuang.net 获取更多精彩内容】的规则。【本文受版权保护】

本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。【未经授权禁止转载】

因此,从算法上讲,它根本不涉及我们上文提【版权所有,侵权必究】【作者:唐霜】到的“分多少段”的问题。

【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。【原创不易,请尊重版权】原创内容,盗版必究。【本文首发于唐霜的博客】

ticks的算法源码在【未经授权禁止转载】这里著作权归作者所有,禁止商业用途转载。,核心算法如下:【转载请注明来源】

未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。
var e10 = Math.sqrt(50),
    e5 = Math.sqrt(10),
    e2 = Math.sqrt(2);
export default function(start, stop, count) {
  var step = tickStep(start, stop, count);
  return range(
    Math.ceil(start / step) * step,
    Math.floor(stop / step) * step + step / 2, // inclusive
    step
  );
}
export function tickStep(start, stop, count) {
  var step0 = Math.abs(stop - start) / Math.max(0, count),
      step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),
      error = step0 / step1;
  if (error >= e10) step1 *= 10;
  else if (error >= e5) step1 *= 5;
  else if (error >= e2) step1 *= 2;
  return stop < start ? -step1 : step1;
}

tickSetp是用来计算step的,也【未经授权禁止转载】【原创内容,转载请注明出处】就是我们上文提到的“单位值”,所以可见d未经授权,禁止复制转载。未经授权,禁止复制转载。3代码内部还是考虑了“分段”问题的。通过本文作者:唐霜,转载请注明出处。【本文受版权保护】tickStep可以获得每一段的值,再用【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】这个值作为step参与range计算。总【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】之,最最核心的,就是tickStep函数著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。,它决定了你传入给ticks的参数,最后【原创内容,转载请注明出处】【版权所有,侵权必究】实现的效果。

【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。

2017-03-12 37095 ,

为价值买单,打赏一杯咖啡

本文价值370.95RMB