简体   繁体   English

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

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

In my case i have dynamic data which loads into d3Js graph. 就我而言,我有加载到d3Js图形中的动态数据。 everything works perfeclty if i have userdata like : 如果我有像这样的用户数据,一切都会正常运行:

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

but the problem comes when i have a data like this: 但是问题出在我有这样的数据时:

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

then whole y axis have no labels at all. 那么整个y轴根本没有标签。 how do i show predefined labels in this case? 在这种情况下,如何显示预定义标签?

Here is the code to generate axis : 这是生成轴的代码:

                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();

The problem stems not from the fact that all your values are zero, but from the fact that all your values are the same and that your domain therefore has zero width (the max and min domain values are the same). 问题的根源不是所有值均为零,而是所有值都相同且域的宽度为零(最大和最小域值相同)。

The linear scale falls apart in this case, because you are telling to create a linear relationship such that both the start and end values of the range are equal to the same value in the domain. 在这种情况下,线性标度会崩溃,因为您要创建一个线性关系,以使范围的开始和结束值都等于域中的相同值。 You don't get a divide-by-zero error like you would if your range was zero width, but you don't get a meaningful scale, or meaningful tick values. 您不会得到零除错误,就像您的范围是零宽度时一样,但是没有有意义的比例或有意义的刻度值。

Even the .nice() function can't help you, since it's designed to extend the domain to the next tick value after determining an appropriate tick spacing based on your domain. 甚至.nice()函数也无济于事,因为它被设计为在根据您的域确定适当的刻度间隔后将域扩展到下一个刻度值。

Working fiddle based on your code, demonstrating the problem: 根据您的代码工作,演示了该问题:
http://fiddle.jshell.net/LJdZZ/ http://fiddle.jshell.net/LJdZZ/

How can you fix it? 您如何解决? You have to force the domain's start and end points to be different. 您必须强制域的起点和终点不同。 There are a few different approaches you can use, you'll have to decide which is appropriate for your data: 您可以使用几种不同的方法,必须确定哪种方法适合您的数据:

  • If you know that your domain is normally going to be small integers, you can add and subtract 1 from the max and min values: 如果您知道您的域通常是小整数,则可以从最大值和最小值中减去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(); 
  • If you will normally want the domain to include zero you can force it to include both zero and one: 如果通常希望该域包含零,则可以强制其同时包含零和一:

     y.domain(d3.extent(data.concat([{y:0},{y:1}]), function (d) { return dy; })) .nice(); 
  • If your data values and scale are likely to vary such that you don't want to force any values normally, you can check if the domain width is zero and only then set a specific domain: 如果您的数据值和小数位数可能会发生变化,以至于您不想正常强制使用任何值,则可以检查域宽度是否为零,然后仅设置一个特定域:

     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(); } 

Adaption of the fiddle with the last method implemented: 改编小提琴与最后实现的方法:
http://fiddle.jshell.net/LJdZZ/1/ http://fiddle.jshell.net/LJdZZ/1/

(You might want to make the domain check & correction a separate function that you call with the scale as a parameter. That way you can use it for both linear scales, without cluttering up your main code with extra variables.) (您可能希望将域检查和更正作为一个单独的函数,将比例尺作为参数来调用。这样,您就可以将其用于两个线性比例尺,而不会使主代码变得多余。)

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

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