D3 示例:看起来像一个 JavaScript 变量,但像一个函数一样调用
D3 example: looks like a javascript variable, but is called like a function
我试图理解D3示例中的Javascript代码是如何工作的。 对我来说没有意义的部分是buildLine()
函数中的xScale
和yScale
"函数"。
取xScale
,它看起来像一个实例化为值的简单变量:
var xScale = d3.scale.linear()
.domain([
d3.min(ds.monthlySales, function(d){ return d.month;}) ,
d3.max(ds.monthlySales, function(d){ return d.month;})
])
.range([0, w])
.nice();
。但是在buildLine()
中,似乎它们也被调用为函数:
var lineFun = d3.svg.line()
.x(function (d) {return xScale(d.month); } )
.y(function (d) {return yScale(d.sales); })
.interpolate("linear");
更具体地说,在:
.x(function (d) {return xScale(d.month); } )
。我不明白d
的价值来自哪里(以及它如何具有.month
属性(,最重要的是xScale
"函数"如何接收它。
我认为我需要理解Javascript的一个基本原则才能使这段代码有意义,但那可能是什么?
基础数据可以在此处看到:
https://github.com/bsullins/d3js-resources/blob/master/monthlySalesbyCategoryMultiple.json
整个源代码:
<!DOCTYPE html>
<html>
<head>
<script src="d3.min.js" charset="utf-8"></script>
</head>
<body>
<script>
var h=100;
var w=400;
var padding = 20;
//build line
function buildLine(ds) {
console.log('xscale-max: '+ d3.max(ds.monthlySales, function (d){ return d.month; }));
console.log('yscale-max: '+ d3.max(ds.monthlySales, function (d){ return d.sales; }));
//scales
var xScale = d3.scale.linear()
.domain([
d3.min(ds.monthlySales, function(d){ return d.month;}) ,
d3.max(ds.monthlySales, function(d){ return d.month;})
])
.range([0, w])
.nice();
var yScale = d3.scale.linear()
.domain([0, d3.max(ds.monthlySales, function(d){ return d.sales;})])
.range([h,0])
.nice();
var lineFun = d3.svg.line()
.x(function (d) {return xScale(d.month); } )
.y(function (d) {return yScale(d.sales); })
.interpolate("linear");
var svg = d3.select("body").append("svg").attr({ width:w, height:h});
var viz = svg.append("path")
.attr({
d: lineFun(ds.monthlySales),
"stroke" : "purple",
"stroke-width": 2,
"fill" : "none"
});
}
//show header
function showHeader(ds) {
d3.select("body").append("h1")
.text(ds.category + " Sales (2013)");
}
//get data and draw things
d3.json("https://api.github.com/repos/bsullins/d3js-resources/contents/monthlySalesbyCategoryMultiple.json", function(error, data) {
if(error) {
console.log(error);
} else {
console.log(data); //we're golden!
}
var decodedData = JSON.parse(window.atob(data.content));
console.log(decodedData.contents);
decodedData.contents.forEach(function(content){
ds=content;
console.log(ds);
showHeader(ds);
buildLine(ds);
})
});
</script>
</body>
</html>
javascript有第一类函数,所以xScale
是一个包含函数的变量。这意味着您可以传递它并调用它。
更具体地说,您发布的第一个代码片段构建了一个函数,该函数接受 .domain([d3.min ..., d3.max ... ])
指定的时间间隔内的值,并在 .range([0, w])
指定的时间间隔内返回值。它还说函数返回的值应该是"nice"(.nice()
(,即截断为没有几个小数。根据这些规范构建的函数将分配给xScale
变量。
稍后,您在d3.svg.line
生成器中使用此函数,该函数就像d3.scale.linear
生成(因此生成器(函数的函数/对象一样,在本例中是一个函数,当提供数据集作为输入时,返回一个字符串,您可以将其用作 svg path
元素的 d
属性来绘制您想要的路径。此函数分配给变量 lineFun
(有趣的部分!
lineFun 函数使用 d3.svg.line 生成器构建,将数据集作为输入:
lineFun(ds.monthlySales)
而且,对于数据集中的每个数据点,它将其作为输入传递给访问器函数(这是d
参数的来源(,以便它们可以从数据点创建 x 和 y 值。因此,访问器函数是接受数据点并返回值的函数,通常根据数据点的某些属性。因此,例如:
function (d) {return xScale(d.month);
给定一个数据点d
,返回 xScale 函数在将数据点的 month
属性作为输入传递时返回的值。
我知道我没有写最清楚的解释,但我希望它能对你有所帮助。
关键点是:
- 在 Javascript 中,函数可以分配给变量并作为参数传递,就像整数或字符串一样
-
d3.scale.linear
和d3.svg.line
是生成器:它们构建并返回一个函数 - 当给定数据作为输入时,D3 使用形状生成器返回用于绘制表示数据的路径的 SVG 属性。
从 https://github.com/mbostock/d3/wiki/SVG-Shapes#path-data-generators
路径生成器(例如 d3.svg.line 返回的路径生成器(既是对象又是函数。也就是说:您可以像调用任何其他函数一样调用生成器,并且生成器具有更改其行为的其他方法。与 D3 中的其他类一样,路径生成器遵循方法链接模式,其中 setter 方法返回生成器本身,允许在简洁的语句中调用多个资源库。
- 我可以在json对象中添加一个函数吗
- 如何在JQuery函数中定义一个值,然后调用另一个函数并使用该值
- 是否可以将一个函数输入连接到另一个函数调用的文本
- 在另一个函数中使用变量this
- 在另一个函数成功结束后调用该函数
- mongoose.connect undefined不是一个函数
- 监听器必须是一个函数
- 使用JS函数来使用另一个函数的语法?node.js
- 如何取消object.prototypes javascript的一个函数
- 从Chrome扩展名中的popup.html文件在background.js文件中运行一个函数
- 嵌套到另一个函数中的Fancybox函数;不起作用
- 如何在javascript中使用不止一个函数
- jQuery-在页面加载时执行一个函数
- jquery UI draggable:UI.children不是一个函数
- jQuery Mobile Undefined不是一个函数
- 如何在php中创建一个函数,该函数与文本区域一起工作,通过输入类似[color:red]的内容来打印具有等效颜色的文本
- javascript函数将数据添加到屏幕,但随后被另一个函数覆盖
- JS异常:animate不是一个函数
- 如何将一个函数附加到一个不存在的元素上
- JavaScript/jQuery-添加添加和删除类与下一个函数之间的延迟