Javascript D3 序数和线性尺度之间的差异

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29785238/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:58:40  来源:igfitidea点击:

D3 difference between ordinal and linear scales

javascriptd3.js

提问by Bill

var xScale = d3.scale.ordinal().domain([0, d3.max(data)]).rangeRoundBands([0, w], .1);
var yScale = d3.scale.linear().domain([0, data.length]).range([h, 0]);

I'm confused about when to use ordinalor linearscale in D3.

我对何时在 D3 中使用序数线性比例感到困惑。

Below is what I've discovered from the API doc, still bit lost... if anyone can help, it would be much appreciated.

以下是我从 API 文档中发现的内容,仍然有点丢失……如果有人可以提供帮助,将不胜感激。

ordinal(x)

序数(x)

Given a value x in the input domain, returns the corresponding value in the output range.

给定输入域中的值 x,返回输出范围中的相应值。

If the range was specified explicitly (as by range, but not rangeBands, rangeRoundBands or rangePoints), and the given value x is not in the scale's domain, then x is implicitly added to the domain; subsequent invocations of the scale given the same value x will return the same value y from the range.

如果范围是明确指定的(如按范围,但不是按范围,rangeRoundBands 或 rangePoints),并且给定的值 x 不在刻度的域中,则 x 被隐式添加到域中;给定相同值 x 的刻度的后续调用将从范围中返回相同的值 y。

d3.scale.linear()

d3.scale.linear()

Constructs a new linear scale with the default domain [0,1] and the default range [0,1]. Thus, the default linear scale is equivalent to the identity function for numbers; for example linear(0.5) returns 0.5.

使用默认域 [0,1] 和默认范围 [0,1] 构造一个新的线性标度。因此,默认的线性标度相当于数字的恒等函数;例如 linear(0.5) 返回 0.5。

回答by Oleg

As for Ordinal Scales:

至于序数尺度

Ordinal scales have a discrete domain, such as a set of names or categories.

An ordinal scale's values must be coercible to a string, and the stringified version of the domain value uniquely identifies the corresponding range value.

序数尺度具有离散域,例如一组名称或类别。

序数标度的值必须可强制转换为字符串,并且域值的字符串化版本唯一标识相应的范围值。

So, as an example, a domain of an ordinal scale may contain names, like so:

因此,举个例子,一个有序规模的域可能包含名称,如下所示:

var ordinalScale = d3.scale.ordinal()
        .domain(['Alice', 'Bob'])
        .range([0, 100]);

ordinalScale('Alice'); // 0
ordinalScale('Bob'); // 100

Notice how all values are strings. They cannot be interpolated. What is between 'Alice' and 'Bob'? I don't know. Neither does D3.

注意所有值都是字符串。它们不能被插值。“爱丽丝”和“鲍勃”之间是什么?我不知道。D3也不行。

Now, as for Quantitative Scales(e.g. Linear Scales):

现在,对于定量尺度(例如线性尺度):

Quantitative scales have a continuous domain, such as the set of real numbers, or dates.

定量尺度具有连续域,例如实数集或日期。

As an example, you can construct the following scale:

例如,您可以构建以下比例:

var linearScale = d3.scale.linear()
        .domain([0, 10])
        .range([0, 100]);

linearScale(0); // 0
linearScale(5); // 50
linearScale(10); // 100

Notice how D3 is able to interpolate 5 even if we haven't specified it explicitly in the domain.

请注意 D3 如何能够插入 5,即使我们没有在域中明确指定它。

Take a look at this jsfiddleto see the above code in action.

看看这个 jsfiddle,看看上面的代码在起作用

回答by figurine

In D3.js scales transform a number from the domain to the range. For a linear scale the domain will be a continuous variable, with an unlimited range of values, which can be then transformed to a continuous range. For ordinal scales there will be a discrete domain, for example months of the year where there are limited range of possible values that may be ordered but aren't continuous. The API docs on Githubcan probably explain the difference better than I have

在 D3.js 中,scales 将数字从域转换为范围。对于线性尺度,域将是一个连续变量,具有无限范围的值,然后可以将其转换为连续范围。对于序数尺度,将有一个离散域,例如一年中的几个月,其中可以排序但不连续的可能值范围有限。Github 上API 文档可能比我更好地解释了差异

回答by Alireza

OK, we can start learning it with using both with the same data to see differences(I'm using d3 v4), imagine we have the data below with using ordinaland linearscales:

好的,我们可以开始学习它,同时使用相同的数据来查看差异(我使用的是 d3 v4),想象一下我们有下面的数据,使用 usingordinallinearscales:

const data = [1, 2, 3, 4, 5];

const scaleLinear = d3.scaleLinear()
  .domain([0, Math.max(...data)]).range([1, 100]);

const scaleOrdinal = d3.scaleOrdinal()
  .domain(data).range(['one', 'two', 'three', 'four', 'five']);

Now we start calling them to see the result:

现在我们开始调用它们以查看结果:

scaleLinear(1); //20
scaleOrdinal(1); //one

scaleLinear(2); //40
scaleOrdinal(2); //two

scaleLinear(5); //100
scaleOrdinal(5); //five

Look at the functions and the results we get, as you see in the ordinal one we map the data to our range, while in the linear one we stretch to the range, so in these cases for example scaleLinear(1) will return 20... our domain max is 100 and 100 divided by 5 is equal 20, so scaleLinear(1)is 20and scaleLinear(2)is 40...

看看我们得到的函数和结果,正如你在序数函数中看到的,我们将数据映射到我们的范围,而在线性函数中,我们拉伸到范围,因此在这些情况下,例如scaleLinear(1) 将返回 20。 .. 我们的域最大值是 100,100 除以 5 等于 20,所以scaleLinear(1)20scaleLinear(2)40...

But as you see, scaleOrdinal(1)is map to the array in the range, so it's equal to oneand scaleOrdinal(2)it's equal to two...

但是如您所见,scaleOrdinal(1)映射到范围内的数组,因此它等于1scaleOrdinal(2)等于2...

So that's how you can use these scales, scaleLinearis useful for many things including present the scale on page, but scaleOrdinalmore useful for getting the data in order, that's how it's explained in the documentation:

这就是您可以使用这些比例的方法,scaleLinear对许多事情都很有用,包括在页面上显示比例,但scaleOrdinal对于按顺序获取数据更有用,这就是文档中的解释:

# d3.scaleLinear() <>

Constructs a new continuous scale with the unit domain [0, 1], the unit range [0, 1], the default interpolator and clamping disabled. Linear scales are a good default choice for continuous quantitative data because they preserve proportional differences. Each range value y can be expressed as a function of the domain value x: y = mx + b.

# d3.scaleLinear() <>

使用单位域 [0, 1]、单位范围 [0, 1]、默认插值器和钳位禁用构造一个新的连续比例尺。线性尺度是连续定量数据的一个很好的默认选择,因为它们保留了比例差异。每个范围值 y 可以表示为域值 x 的函数:y = mx + b。



d3.scaleOrdinal([range]) <>

Constructs a new ordinal scale with an empty domain and the specified range. If a range is not specified, it defaults to the empty array; an ordinal scale always returns undefined until a non-empty range is defined.

d3.scaleOrdinal([range]) <>

构造一个具有空域和指定范围的新序数标度。如果未指定范围,则默认为空数组;在定义非空范围之前,序数比例始终返回 undefined。

Also this is a good example from d3 in depth using both ordinal and linear scales at the same time:

这也是同时使用序数和线性尺度的深度 d3 的一个很好的例子:

var myData = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

var linearScale = d3.scaleLinear()
  .domain([0, 11])
  .range([0, 600]);

var ordinalScale = d3.scaleOrdinal()
  .domain(myData)
  .range(['black', '#ccc', '#ccc']);

d3.select('#wrapper')
  .selectAll('text')
  .data(myData)
  .enter()
  .append('text')
  .attr('x', function(d, i) {
    return linearScale(i);
  })
  .text(function(d) {
    return d;
  })
  .style('fill', function(d) {
    return ordinalScale(d);
  });
body {
  font-family: "Helvetica Neue", Helvetica, sans-serif;
  font-size: 14px;
  color: #333;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script>

<svg width="800" height="60">
   <g id="wrapper" transform="translate(100, 40)">
   </g>
</svg>