我目前正在 d3 中开发一个项目,在该项目中,我从一个 csv 文件创建了一个嵌套的 json 对象(参见代码片段)它有多个键和一系列值,我想在 map 上绘制这些值。
0:
key: "Islamic State of Iraq and the Levant (ISIL)"
values:
kills: 30889
map_data:
Array(4287)
[0 … 99]
0: {longitude: "44.290423", latitude: "33.297678", nkill: "28", nwound: "50", city: "Baghdad", …}
1: {longitude: "44.356585", latitude: "32.985052", nkill: "0", nwound: "4", city: "Latifiyah", …}
1:
key: "Taliban"
values:
kills: 24482
map_data:
Array(6575)
[0 … 99]
0: {longitude: "", latitude: "", nkill: "0", nwound: "0", city: "Unknown", …}
1: {longitude: "65.675942", latitude: "31.617667", nkill: "0", nwound: "0", city: "Kandahar", …}
[edit] 我想为 map_data 数组中的每个项目投影一个圆圈,但圆圈属性只采用一个值,如 Shashank 评论中所述。有没有其他方法可以在属性中获取我的正确数据?
g.selectAll("circle")
.data(topgroups)
.enter()
.append("a")
.attr("xlink:href", function(d) {
return "https://www.google.com/search?q="+d.key;}
)
.append("circle")
.attr("cx", function(d) {
d.values.map_data.map(function (t) {
return projection([t.Longitude, t.Latitude])[0];
})
})
.attr("cy", function(d) {
d.values.map_data.map(function (t) {
return projection([t.Longitude, t.Latitude])[1];
})
})
.attr("r", function(d) {
d.values.map_data.map(function (t) {
return t.nkill/500;
})
})
.style("fill", "red");
最佳答案
感谢您返回确切的要求和更多代码。事情是这样的:
您正试图绑定(bind)一个对象,而您总是必须将一个数组绑定(bind)到 D3 中的一个选择。
因为您需要为 map_data
数组中的每个项目设置圆圈,所以您必须将此数组绑定(bind)到 d3.selectAll('circle')
查看 this link了解有关 D3 中数据绑定(bind)的更多信息。
这是执行上述操作的代码片段,并将圆圈连同属性 cx
、cy
和 r
根据您的分配初始要求,即调用 projection
等
它包含一个类似于您的示例数组,但请确保您提供数据的代码片段而不是屏幕截图
var topgroups = {
key: 'ISIL',
values: {
kills: 30899,
map_data: [
{
city: "A",
latitude: '20',
longitude: '40',
nkill: 100
},
{
city: "B",
latitude: '90',
longitude: '50',
nkill: 200
},
{
city: "C",
latitude: '120',
longitude: '140',
nkill: 300
},
{
city: "D",
latitude: '120',
longitude: '250',
nkill: 400
}
]
}
};
function projection(lt, long) {
return [lt, long];
}
d3.select('body').append('svg')
.attr('width', 400).attr('height', 350)
.append('g').attr('class', 'circles');
var circles = d3.select('svg g.circles').selectAll('circle')
.data(topgroups.values.map_data);
circles.enter().append('circle')
.attr('cx', function(d) {
return projection(+d.latitude, +d.longitude)[0];
}).attr('cy', function(d) {
return projection(+d.latitude, +d.longitude)[1];
})
.attr('r', function(d) {
return d.nkill/40;
});
<script src="https://d3js.org/d3.v4.min.js"></script>
希望这对您有所帮助。
编辑: 最初在图像中,它显示为一个对象,因此显示为上述代码。无论如何,我认为如果它是一个数组,你会从那里拿走它。这是简单的enter/update/exit 模式。
这是一个片段:
var topgroups = [
{
key: 'ISIL',
values: {
kills: 30899,
map_data: [
{
city: "A",
latitude: '20',
longitude: '40',
nkill: 100
},
{
city: "B",
latitude: '90',
longitude: '50',
nkill: 200
},
{
city: "C",
latitude: '120',
longitude: '140',
nkill: 300
},
{
city: "D",
latitude: '120',
longitude: '250',
nkill: 400
}
]
}
},
{
key: 'ISIL2',
values: {
kills: 308990,
map_data: [
{
city: "E",
latitude: '100',
longitude: '40',
nkill: 100
},
{
city: "F",
latitude: '10',
longitude: '120',
nkill: 200
}
]
}
}
];
function projection(lt, long) {
return [lt, long];
}
var svg = d3.select('body').append('svg')
.attr('width', 400).attr('height', 350);
var g = svg.selectAll('g.circles').data(topgroups);
g.enter().append('g').attr('class', 'circles').attr('data-key', function(d) { return d.key; });
var circles = d3.selectAll('svg g.circles').selectAll('circle')
.data(function(d) {
return d.values.map_data;
});
circles.enter().append('circle')
.attr('cx', function(d) {
return projection(+d.latitude, +d.longitude)[0];
}).attr('cy', function(d) {
return projection(+d.latitude, +d.longitude)[1];
})
.attr('r', function(d) {
return d.nkill/40;
});
<script src="https://d3js.org/d3.v4.min.js"></script>
希望这对您有所帮助。 :)
关于javascript - 在 d3/javascript 中使用嵌套数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48094823/