为什么我要按比例输入参数? [英] Why can I input an argument on a scale?
问题描述
我正在做一个简单的直方图:
I'm doing a simple histogram:
var width = 500,
height = 500,
padding = 50;
d3.csv('mydata.csv', function(data) {
var map = data.map(function(i) {
return parseInt(i.age)
})
var histogram = d3.layout.histogram()
.bins(7)(map)
console.log(histogram)
var y = d3.scale.linear()
.domain([0, d3.max(histogram.map(function(i) {
return i.length;
}))])
.range([0, height])
var x = d3.scale.linear()
.domain([0, d3.max(map)])
.range([0, width]);
var canvas = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height + padding);
var bars = canvas.selectAll(".bar").data(histogram)
.enter().append('g').attr('class', 'bar')
bars.append('rect')
.attr('x', function(d) {
return x(d.x);
})
.attr('y', 0)
.attr('width', function(d) {
return x(d.dx);
})
.attr('height', function(d) {
return y(d.y)
})
.attr('fill', 'purple')
})
I'm using Youtube to learn D3
scale
变量x
和y
不是函数,但是即使它们是函数,它们也没有参数.
The scale
variable x
and y
aren't functions, but even if they were functions they don't have parameters.
但是在bars.append('rect')
中,return x(d.x)
,return x(d.dx)
和return y(d.y)
的作用类似于具有参数的函数...
But In the bars.append('rect')
, return x(d.x)
, return x(d.dx)
and return y(d.y)
are acting like functions that also have parameters...
有人可以向我解释这怎么可能吗?
Can someone explain to me how is this possible?
推荐答案
您说的是...
比例变量x和y不是函数.
The scale variable x and y aren't functions.
嗯,那是不对的. D3秤(任何版本)都是功能.如果您使用的是D3 v3比例尺.
Well, that's incorrect. D3 scales (in any version) are functions. In you case, you have a D3 v3 scale.
为向您展示这是一个比例尺以及它采用的参数,让我们看一下D3 v3 源代码.这将带我们经历迷宫般的返回函数的函数.
To show you that this is a scale, and what argument it takes, let's see D3 v3 source code. It will take us through a labyrinth of functions returning functions.
这是d3.scale.linear()
函数:
d3.scale.linear = function() {
return d3_scale_linear([0, 1], [0, 1], d3_interpolate, false);
};
如您所见,它返回一个函数d3_scale_linear
.该函数有4个参数,前两个是默认范围和域.显然,您以后可以像以前一样更改范围和域.
As you can see, it returns a function, d3_scale_linear
. That function takes 4 arguments, the first two are the default range and domain. Obviously, you can change both the range and the domain later, as you did.
如果您查看d3_scale_linear
,您会看到它返回此函数:
If you look at d3_scale_linear
, you'll see that it returns this function:
function rescale() {
var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear,
uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;
output = linear(domain, range, uninterpolate, interpolate);
input = linear(range, domain, uninterpolate, d3_interpolate);
return scale;
}
依次返回此函数:
function scale(x) {
return output(x);
}
x
是使用时传递给刻度的参数,例如本例中的x(d.x)
.传递的参数为d.x
.
And that x
is the argument that you pass to the scale when you use it, like x(d.x)
in your example. The passed argument is d.x
.
仅出于完整性考虑,output
功能取决于执行实际工作的功能d3_scale_polylinear
或d3_scale_bilinear
:
Just for completeness, the output
function depends on either d3_scale_polylinear
or d3_scale_bilinear
, which are the functions that perform the real job:
function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
var u = uninterpolate(domain[0], domain[1]),
i = interpolate(range[0], range[1]);
return function(x) {
return i(u(x));
};
}
function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
var u = [],
i = [],
j = 0,
k = Math.min(domain.length, range.length) - 1;
if (domain[k] < domain[0]) {
domain = domain.slice().reverse();
range = range.slice().reverse();
}
while (++j <= k) {
u.push(uninterpolate(domain[j - 1], domain[j]));
i.push(interpolate(range[j - 1], range[j]));
}
return function(x) {
var j = d3.bisect(domain, x, 1, k) - 1;
return i[j](u[j](x));
};
}
这篇关于为什么我要按比例输入参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!