如果我得到你需要什麼,你有這樣做的兩種方法。 你要麼附上一個新的領域,從AJAX調用返回的數據:
d3.tsv("data.tsv", function(error, data) {
if (error) throw error;
var myData = data.map(function(item, i) {
item.x = i + 1;
return item;
})
這將硬編碼每一個項目的位置,因爲它是從請求返回。
在很多情況下,雖然這不是必須的,但循環訪問D3中的選擇內的數據已經可以訪問索引。例如:
// later in your code
svg
.selectAll('circle')
.data(myData)
.enter()
.append('circle')
.attr('cx', function(d, i) {
// here the 2 arguments are:
// d => the data you passed in
// i => is the index of the loop, starting from 0
return i + 1;
})
編輯
在這兩種情況下,你會遍歷數組,因此性能命中反正是有(但除非你的數據集確實非常大,我不會擔心在所有)。
不僅僅是性能上的差異,它還是您預期使用量的差異。
如上所述,第一種方法將每個項目的位置存儲在數據集中,並且即使在您重新編碼陣列後也會始終反映該位置。 例如,假設這個CSV數據:
name age
John 24
Tom 32
Alan 22
第一種方法將創建該對象:
[{
name: "John",
age: 24,
x: 1
},
{
name: "Tom",
age: 32,
x: 2
},
{
name: "Alan",
age: 22,
x: 3
}]
也許以後你想從年輕的重新排序這個數組以上:
[{
name: "Alan",
age: 22,
x: 3
}, {
name: "John",
age: 24,
x: 1
},
{
name: "Tom",
age: 32,
x: 2
}]
注意x值是如何不變。如果這就是你想要的,使用這種方法。
如果改爲使用第二種方法,在這個函數
.attr('cx', function(d, i) {
// i => is the index of the loop, starting from 0
return i + 1;
})
i
的將總是反映數據的特定陣列中的位置。所以通過這個
[{
name: "John",
age: 24
},
{
name: "Tom",
age: 32
},
{
name: "Alan",
age: 22
}]
將導致
.attr('cx', function(d, i) {
// i === 0 => John
// i === 1 => Tom
// i === 2 => Alan
return i + 1;
})
雖然通過本:
[{
name: "Alan",
age: 22
}, {
name: "John",
age: 24
},
{
name: "Tom",
age: 32
}]
將導致:
.attr('cx', function(d, i) {
// i === 0 => Alan
// i === 1 => John
// i === 2 => Tom
return i + 1;
})
酷,謝謝!我不確定JS效率如何下降,硬編碼方法效率較低,對於大型數據集,它會很慢嗎?或者這兩種方法在這方面幾乎相同? –
@ArashHowaida它取決於。讓我更新答案來解釋它,只需一秒。 – Nobita
我明白了,現在很清楚。很好的解釋! –