了解阈值范围内的invertExtent

时间:2018-01-09 04:02:20

标签: javascript d3.js

我正在通过迈克博斯托克的等值线图(慢慢地),我正在写下每一点,以确保我理解它。我特别难以理解一点。该示例在线: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;
    }))

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

1 个答案:

答案 0 :(得分:4)

这实际上是在文档中描述的。如果你看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]

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

问题是,对于矩形'输入选择,您不能使用undefinednullundefined == nulltrue)的数组。那么,那些if做的是转换这个数组:

[[undefined,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,9],[9, undefined]]

进入这一个:

[[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,9],[9,10]]

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



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

<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;

现在和他们一起:

&#13;
&#13;
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);
  if (d[0] == null) d[0] = 0;
  if (d[1] == null) d[1] = 9;
  return d;
}))
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;

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

  

如果比例范围中的值数为N + 1,则比例域中的值数必须为N.如果域中的元素少于N个,则忽略该范围中的其他值。如果域中有多于N个元素,则某些输入的比例可能会返回未定义。