admin管理员组文章数量:1331435
I am loading a GeoJSON data file that contains an array of objects, each object containing the vector information for a different country's outline. The same array element is being bound to every DOM element. I have e across this scope issue before in JavaScript but every change I made caused nothing to load.
I attached a jsfiddle. I use an example data file which seems to take a couple seconds to load.
My code from the jsfiddle looks like:
$(document).ready(function() {
d3.json(
".geojson",
function(error, data) {
var myGeoJSON = data.features;
for (i = 0; i < myGeoJSON.length; i++) {
var path = d3.geo.path();
var width = 960;
var height = 600;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.selectAll("path")
.data(data.features)
.enter().append("path")
.attr("d",path)
.attr("fill","#3e429a");
}
}
);
});
I am loading a GeoJSON data file that contains an array of objects, each object containing the vector information for a different country's outline. The same array element is being bound to every DOM element. I have e across this scope issue before in JavaScript but every change I made caused nothing to load.
I attached a jsfiddle. I use an example data file which seems to take a couple seconds to load.
My code from the jsfiddle looks like:
$(document).ready(function() {
d3.json(
"https://raw.githubusercontent./datasets/geo-boundaries-world-110m/master/countries.geojson",
function(error, data) {
var myGeoJSON = data.features;
for (i = 0; i < myGeoJSON.length; i++) {
var path = d3.geo.path();
var width = 960;
var height = 600;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.selectAll("path")
.data(data.features)
.enter().append("path")
.attr("d",path)
.attr("fill","#3e429a");
}
}
);
});
Share
Improve this question
edited Oct 12, 2015 at 4:42
approxiblue
7,12216 gold badges52 silver badges59 bronze badges
asked Oct 2, 2015 at 8:24
Four_loFour_lo
1,15010 silver badges28 bronze badges
7
- You're incrementing i, but you're not using i inside your loop, or myGeoJSON for that matter. – Eterm Commented Oct 2, 2015 at 8:27
- Sorry I will edit that it breaks if I increment i, brb with the error – Four_lo Commented Oct 2, 2015 at 8:36
- d3 es back w/ cannot read length of undefined – Four_lo Commented Oct 2, 2015 at 8:44
- So, I assume you checked that the data is OK? – Cool Blue Commented Oct 2, 2015 at 9:27
-
1
Data seems fine, you can use something like
.data([data.features[i]])
to load the polygons individually. Then you'd need also to center on the countries (scroll down a bit to see some countries in focus) – Pinguin Dirk Commented Oct 2, 2015 at 10:18
1 Answer
Reset to default 12 +100You don't need to loop through the array of features. Your data file is a FeatureCollection, which D3 can draw, either as a single path element:
svg.append("path").datum(data).attr("d", d3.geo.path());
or as separate path elements, one for each feature (country):
svg.selectAll("path").data(data.features)
.enter().append("path").attr("d", d3.geo.path())
By default D3 uses the projection d3.geo.albersUsa()
which brings Hawaii to Mexico and Alaska to just outside the tropics. You can switch to the equirectangular projection to see the whole world:
d3.json(
"https://raw.githubusercontent./datasets/geo-boundaries-world-110m/6cf0946a0f4d027d21686e8402f19b524c4f6385/countries.geojson",
function(error, data) {
var projection = d3.geo.equirectangular();
var path = d3.geo.path().projection(projection);
var width = 960;
var height = 600;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.selectAll("path")
.data(data.features)
.enter().append("path")
.attr("d", path)
.attr("fill", "#3e429a");
}
);
<script src="https://cdnjs.cloudflare./ajax/libs/d3/3.4.11/d3.min.js"></script>
Epilogue: I initially tried to use the more mon Mercator projection, only to find that it cannot handle Antarctica. D3 draws the shape for the continent, then fills the rest of the oceans instead.
In the same D3 forum thread, the author of D3 mentioned a bug in the TopoJSON tool used to generate maps, so it might be an issue with the data file you use. If you prefer Mercator, you might need to work with the maintainer of geo-boundaries-world-110m to fix the data file, or just exclude Antarctica from your maps.
Demo of Antarctica in Mercator:
d3.json(
"https://raw.githubusercontent./datasets/geo-boundaries-world-110m/6cf0946a0f4d027d21686e8402f19b524c4f6385/countries.geojson",
function(error, data) {
var projection = d3.geo.mercator();
var path = d3.geo.path().projection(projection);
var width = 960;
var height = 600;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var antarctica = data.features.splice(6, 1);
// now "data" has the rest of the world
svg.selectAll("path")
.data(antarctica)
.enter().append("path")
.attr("d", path)
.attr("stroke", "red").attr("stroke-width", 10)
// thick borders so we can see the odd paths
.attr("fill", "#3e429a");
}
);
<script src="https://cdnjs.cloudflare./ajax/libs/d3/3.4.11/d3.min.js"></script>
本文标签: javascriptD3jsJSON data array is binding the same array element to everythingStack Overflow
版权声明:本文标题:javascript - D3.js - JSON data array is binding the same array element to everything - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742260391a2442402.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论