繁体   English   中英

D3js:如果某一轴的数据为0,如何生成X轴标签/刻度?

[英]D3js: How to generate X axis labels/ticks if data for one of axis is 0?

就我而言,我有加载到d3Js图形中的动态数据。 如果我有像这样的用户数据,一切都会正常运行:

Name : bla, y: 1, x:1
Name : bla2, y: 1, x:2
Name : bla3, y: 3, x:3
Name : bla4, y: 7, x:4

但是问题出在我有这样的数据时:

Name : bla, y: 0, x:1
Name : bla2, y: 0, x:2
Name : bla3, y: 0, x:3
Name : bla4, y: 0, x:4

那么整个y轴根本没有标签。 在这种情况下,如何显示预定义标签?

这是生成轴的代码:

                var x = d3.scale.linear().range([0, width]);

            var y = d3.scale.linear().range([height, 0]);

            var xAxis = d3.svg.axis().scale(x).orient("bottom");

            var yAxis = d3.svg.axis().scale(y).orient("left");

                   y.domain(d3.extent(data, function(d) { return d.y; })).nice();
         x.domain([0, d3.max(data, function(d) { return d.x; })]).nice();

问题的根源不是所有值均为零,而是所有值都相同且域的宽度为零(最大和最小域值相同)。

在这种情况下,线性标度会崩溃,因为您要创建一个线性关系,以使范围的开始和结束值都等于域中的相同值。 您不会得到零除错误,就像您的范围是零宽度时一样,但是没有有意义的比例或有意义的刻度值。

甚至.nice()函数也无济于事,因为它被设计为在根据您的域确定适当的刻度间隔后将域扩展到下一个刻度值。

根据您的代码工作,演示了该问题:
http://fiddle.jshell.net/LJdZZ/

您如何解决? 您必须强制域的起点和终点不同。 您可以使用几种不同的方法,必须确定哪种方法适合您的数据:

  • 如果您知道您的域通常是小整数,则可以从最大值和最小值中减去1:

     y.domain(d3.extent(data, function (d) { return dy; }).map(function(d, i) { //map the two-element array returned by d3.extent if (i) return d+1; //if i=1 return d-1; //if i=0 }); ) .nice(); 
  • 如果通常希望该域包含零,则可以强制其同时包含零和一:

     y.domain(d3.extent(data.concat([{y:0},{y:1}]), function (d) { return dy; })) .nice(); 
  • 如果您的数据值和小数位数可能会发生变化,以至于您不想正常强制使用任何值,则可以检查域宽度是否为零,然后仅设置一个特定域:

     y.domain(d3.extent(data, function (d) { return dy; })) .nice(); var yDomain = y.domain(); if (yDomain[0] == yDomain[1] ) { y.domain([yDomain[0], yDomain[0] + 1]) .nice(); } 

改编小提琴与最后实现的方法:
http://fiddle.jshell.net/LJdZZ/1/

(您可能希望将域检查和更正作为一个单独的函数,将比例尺作为参数来调用。这样,您就可以将其用于两个线性比例尺,而不会使主代码变得多余。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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