![](/img/trans.png)
[英]Passing in variable amount of parameters to a function that looks like “function(*x)” 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
“函數”如何接收 d
的值 。
我認為,要使此代碼有意義,我需要了解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 ... ])
指定的間隔中的值,並返回由.domain([d3.min ..., d3.max ... ])
指定的間隔中的值.range([0, w])
。 它還說該函數返回的值應該是“ nice”(. .nice()
),即被截斷為沒有幾個小數。 根據這些規范構建的功能將分配給xScale
變量。
稍后,您可以在d3.svg.line
生成器中使用此函數,就像d3.scale.linear
一樣, d3.scale.linear
函數/對象生成(因此, 生成器 )一個函數,在這種情況下,當將數據集提供給輸入,返回一個可用作svg path
元素的d
屬性的字符串,以繪制所需的路徑。 該函數被分配給變量lineFun
(有趣的部分!)。
使用d3.svg.line生成器構建的lineFun函數將數據集作為輸入:
lineFun(ds.monthlySales)
然后,對於數據集中的每個數據點,它會將其作為輸入傳遞給訪問器函數( d
參數的來源),以便它們可以為該數據點創建ax和y值。 因此,訪問器函數通常是根據數據點的某些屬性來接受數據點並返回值的函數。 因此,例如:
function (d) {return xScale(d.month);
給定一個數據點d
,當將數據點的month
屬性作為輸入傳遞時,xScale函數返回該值。
我知道我沒有寫出最清晰的解釋,但我希望它能對您有所幫助。
關鍵點是:
d3.scale.linear
和d3.svg.line
是生成器:它們生成並返回一個函數 來自https://github.com/mbostock/d3/wiki/SVG-Shapes#path-data-generators
路徑生成器(例如d3.svg.line返回的路徑生成器)既是對象也是函數。 即:您可以像調用其他任何函數一樣調用生成器,並且生成器具有更改其行為的其他方法。 像D3中的其他類一樣,路徑生成器遵循方法鏈接模式,在此方法中,setter方法返回生成器本身,從而允許在簡潔的語句中調用多個setter。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.