我有一个相对直截了当的问题:如何将x定义为我使用data.map和/或d3.tsv()解析的tsv文件返回的索引号?
请考虑以下代码:
d3.tsv("data.tsv", function(error, data) {
if (error) throw error;
data.forEach(function(d) {
d.x = +d.x;
d.y = +d.y;
});
我需要稍微修改这段代码,因为我的.tsv实际上只有1列数据,即y值。而不是进入.tsv并添加一个从1到n计数的新列,而不仅仅是将我的x值定义为+ d.y的索引是什么?
我尝试使用谷歌,但“索引”这个词是如此笼统,我只是得到了一堆没有达到我追求的文档。
希望这是一个快速修复,如果你有办法让我知道,
谢谢
答案 0 :(得分:4)
如果我得到了你需要的东西,你有两种方法可以做到。 您可以将新字段附加到从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值是如何不变。如果这是你想要的,请使用此方法。
如果您改为使用第二种方法,则此函数中的i
.attr('cx', function(d, i) {
// i => is the index of the loop, starting from 0
return i + 1;
})
将始终反映该特定数组中该数据的位置。所以通过这个
[{
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;
})