JavaScript/D3:"相同"函数调用产生不同的结果?

xia*_*012 1 javascript d3.js

这是关于D3中category10函数的混淆(jsfiddle-demo):

> var a = d3.scale.category10()
> a(0)
"#1f77b4"
> a(10) //the expected different color value
"#2ca02c"
Run Code Online (Sandbox Code Playgroud)

如果我直接调用返回的调用函数category10,事情会是这样的

> d3.scale.category10()(0)
"#1f77b4"
> d3.scale.category10()(10) //the SAME color! Why?
"#1f77b4"
Run Code Online (Sandbox Code Playgroud)

在我看来,调用d3.scale.category10()(10)应该产生与调用相同的值a(10).

这里出了什么问题?

Ray*_*din 5

每次调用都会d3.scale.category10()返回一个新的序数比例实例,因此通过调用它就像d3.scale.category10()(10)每次使用一个新实例一样.每个序数比例实例可以使用输入域显式配置(将输入值映射到输出颜色),也可以隐式执行,只需返回第一个输入值的第一个颜色,依此类推,将映射创建为你用吧.

在您的示例中,您在每次调用时都使用了一个新实例,因此无论您输入什么值,您都将获得第一个颜色.除非您明确配置输入域,否则即使您之前的示例也可能会导致一些意外行为.例如:

var a = d3.scale.category10()
a(0)  // => "#1f77b4"
a(10) // => "#ff7f0e"
var b = d3.scale.category10()
b(10) // => "#1f77b4"
b(0) // => "#ff7f0e"
Run Code Online (Sandbox Code Playgroud)

以下是无论您调用何种顺序,只要输入N,就可以将输入域设置为始终返回第N种颜色:

var a = d3.scale.category10().domain(d3.range(0,10));
a(0)  // => "#1f77b4"
a(1)  // => "#ff7f0e"
a(2)  // => "#2ca02c"
var b = d3.scale.category10().domain(d3.range(0,10));
b(2)  // => "#2ca02c"
b(1)  // => "#ff7f0e"
b(0)  // => "#1f77b4"
Run Code Online (Sandbox Code Playgroud)

BTW,顺便说一下,即使现在a(10)返回相同,a(0)但是因为10超出范围[0,10],从0开始到9结束,所以a(10)是未分配的输入并获得下一个颜色,恰好是首先.