我正在研究D3 Globe的实施。我正在尝试在用户单击按钮时向地球添加路径,但这并不能证明是成功的。如果我一次添加所有路径没有问题,但如果我尝试在触发事件后添加它们,那么它将失败。我的jsfiddle:http://jsfiddle.net/Guill84/b6xvj76e/1/。我不认为JSON存在问题,因为它会按照预期在控制台中弹出。
失败的脚本可以在小提琴的底部找到。我将其粘贴在下面以便于参考:
$("#clickMe").click(function() {
data = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"name": "path1"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": "[[[116.4551,40.2539],[117.5977,44.3408],[116.4551,40.2539]]]"
},
"id": "RML"
},
{
"type": "Feature",
"properties": {
"name": "path2"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": "[[[116.4551,40.2539],[122.3438,41.0889],[116.4551,40.2539]]]"
},
"id": "RML"
},
{
"type": "Feature",
"properties": {
"name": "path3"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": "[[[116.4551,40.2539],[105.9961,37.3096],[116.4551,40.2539]]]"
},
"id": "RML"
},
{
"type": "Feature",
"properties": {
"name": "path4"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": "[[[116.4551,40.2539],[109.5996,35.6396],[116.4551,40.2539]]]"
},
"id": "RML"
}]}
console.log(data);
var svg = d3.select("#body");
flows = svg.selectAll("path")
.data(data)
.enter().append("svg:path")
.attr("d", clip)
.style("stroke", "black")
.attr("id", function(d) {
return d.properties.name.split(' ').join('_')
});
});
答案 0 :(得分:1)
问题是三个:
1)您的JSON结构存在问题:数组以字符串格式指定,因此clip
函数使用时会导致错误。
2)您正在绑定data
对象,而应该绑定data.features
,这是包含您需要创建的四个路径的数组。
3)选择将选择国家的现有路径。您可以通过向新路径添加类来避免这种情况。例如,将它们归类为flow
。
4)流路径在其渲染函数的范围内声明,因此无法在刷新函数上更新它们。
以下是您的代码,其中包含三个修复程序:
$("#clickMe").click(function () {
// 1) Arrays: Fixed arrays for coordinates so they are not serialized in a string
var data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"name": "path1"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": [[[116.4551, 40.2539], [117.5977, 44.3408], [116.4551, 40.2539]]]
},
"id": "RML"
},
{
"type": "Feature",
"properties": {
"name": "path2"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": [[[116.4551, 40.2539], [122.3438, 41.0889], [116.4551, 40.2539]]]
},
"id": "RML"
},
{
"type": "Feature",
"properties": {
"name": "path3"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": [[[116.4551, 40.2539], [105.9961, 37.3096], [116.4551, 40.2539]]]
},
"id": "RML"
},
{
"type": "Feature",
"properties": {
"name": "path4"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": [[[116.4551, 40.2539], [109.5996, 35.6396], [116.4551, 40.2539]]]
},
"id": "RML"
}
]
};
console.log(data);
var svg = d3.select("#body");
// 3) Selection: Add a class to avoid collision with existing paths
// 4) Using var declared outside so it can be used on the update function
flows = svg.selectAll("path.flow")
// 2) Data binding: Bind the features property instead, which is an array
.data(data.features);
// 3) Enter nodes: When appending them, class them as flow so they keep separated
flows.enter().append("svg:path")
.classed("flow", true)
.attr("d", clip)
.style("stroke", "black")
.style("stroke-width", "1px")
.attr("id", function (d) {
return d.properties.name.split(' ').join('_')
});
});
现在它可以工作,但我仍然看不到地球上添加的路径。 path
元素肯定会附加到svg
元素的DOM中,这可以解决您的初始问题;)
- 更新 -
如评论所示,增加的路径并未跟随地球的运动。这是因为路径被添加到svg
但未沿refresh()
功能的国家/地区形状更新(添加点4)。
为此,应在refresh()
函数中提供对这些路径的选择(它足以在脚本顶部声明var flows
),然后为此添加更新在该功能内选择。像这样:
function refresh(duration) {
(duration ? feature.transition().duration(duration) : feature).attr("d", clip);
// 4) Added the flows to the paths selection whose d attribute will be updated (only when present)
flows && (duration ? flows.transition().duration(duration) : flows).attr("d", clip);
}
在这个小提琴上可以看到一个完整的版本:http://jsfiddle.net/oscar_dr/0psy5udk/2/