在阈值范围内理解 invertExtent

Har*_*mer 4 javascript d3.js

我正在通过 Mike Bostock 的等值线图(缓慢地)工作,并在写下每一点以确保我理解它。我特别难以理解一点。该示例在线:https : //bl.ocks.org/mbostock/4060606

在代码中的某一点,Bostock 有一系列颜色,并将它们的反向范围(如果输入到色标中会产生该颜色的最小值和最大值)添加到地图中。对于每个“d”(两种颜色的数组),他使用 color.invertExtent(d) 来获得最小值和最大值。在函数结束时,他将“d”值(现在是两个数字的数组,最小值和最大值)返回到映射。这个我明白。

g.selectAll("rect")
  .data(color.range().map(function(d) {
      d = color.invertExtent(d);
      if (d[0] == null) d[0] = x.domain()[0];
      if (d[1] == null) d[1] = x.domain()[1];
      return d;
    }))
Run Code Online (Sandbox Code Playgroud)

但是,他还包括两个我不明白的“if”块。为什么它们是必要的?为什么这个双色数组的 d[0] 或 d[1] 永远等于“null”?为什么他将它们分配给 x.domain[0](在本例中为 600)和 x.domain[1] 为 860。在什么情况下“null”甚至会成为结果?

Ger*_*ado 7

这实际上在文档中有所描述。如果您查看threshold.invertExtent,您会看到:

为范围内的相应值返回域 [x0, x1] 中值的范围,表示从范围到域的逆映射。这种方法对于交互很有用,比如确定域中与鼠标下方像素位置相对应的值。例如:

var color = d3.scaleThreshold()
    .domain([0, 1])
    .range(["red", "white", "green"]);

color.invertExtent("red"); // [undefined, 0]
color.invertExtent("white"); // [0, 1]
color.invertExtent("green"); // [1, undefined]
Run Code Online (Sandbox Code Playgroud)

你看到那些了undefined吗?它们适用于范围的第一个和最后一个值。

问题是,对于矩形的输入选择,您不能使用带有undefinedor null( undefined == nullis true)的数组。所以,那些ifs 所做的是转换这个数组:

[[undefined,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,9],[9, undefined]]
Run Code Online (Sandbox Code Playgroud)

进入这个:

[[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,9],[9,10]]
Run Code Online (Sandbox Code Playgroud)

这是一个现场演示。首先,没有ifs:

var color = d3.scaleThreshold()
    .domain([0, 1])
    .range(["red", "white", "green"]);

color.invertExtent("red"); // [undefined, 0]
color.invertExtent("white"); // [0, 1]
color.invertExtent("green"); // [1, undefined]
Run Code Online (Sandbox Code Playgroud)
[[undefined,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,9],[9, undefined]]
Run Code Online (Sandbox Code Playgroud)

现在与他们:

[[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,9],[9,10]]
Run Code Online (Sandbox Code Playgroud)
var scale = d3.scaleThreshold()
  .domain(d3.range(1, 9, 1))
  .range(d3.range(9));

console.log(scale.range().map(function(d) {
  d = scale.invertExtent(d);
  return d;
}))
Run Code Online (Sandbox Code Playgroud)

最后,真正理解这一点的关键是了解阈值量表的工作原理。这是最重要的部分,注意元素的数量:

如果刻度范围内的值数为 N+1,则刻度域中的值数必须为 N。如果域中的元素少于 N,则忽略范围内的其他值。如果域中的元素多于 N,则对于某些输入,比例可能会返回 undefined。