I'm trying to link my .csv stored in github to the my d3 code. Does anybody know if there is anything that I'm missing? I was able to do it with LeafLet not with D3. Any help would be highly appreciated. Thanks!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3!!</title>
</head>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.js">
</script>
<script src="https://d3js.org/d3-selection-multi.v0.4.min.js"></script>
<script>
var outerWidth=500;
var outerheight=250;
var margin={left:-50, top:0, right:-50, bottom:0};
var xColumn="longitude";
var yColumn="latitude";
var rColumn="population";
var peoplePerPixel=1000000;
var innerWidth=outerWidth - margin.left - margin.right;
var innerHeight=outerheight - margin.top - margin.bottom;
var svg=d3.select("body").append("svg")
.attr("width", outerWidth)
.attr("height", outerheight);
var g= svg.append("g")
.attr("transform", "translate (" + margin.left + "," +margin.top +")");
var xScale= d3.scaleLog()
.range([0,innerWidth]);
var yScale= d3.scaleLog()
.range([innerHeight,0]);
var rScale= d3.scaleSqrt();
function render (data){
xScale.domain(d3.extent(data, function (d){return d[xColumn]; }));
yScale.domain(d3.extent(data, function (d){return d[yColumn]; }));
rScale.domain([0, d3.max(data, function (d){return d[xColumn]; })]);
var circles= svg.selectAll("circle").data(data);
circles.enter().append("circle");
circles
.attr("cx", function(d){ return xScale(d[xColumn]);})
.attr("cy", function(d){ return yScale(d[yColumn]);})
.attr("r", function(d){ return rScale(d[rColumn]);});
circles.exit().remove();
}
function type(d) {
d.latitude=+d.latitude;
d.longitude=+d.longitude;
d.population=+d.population;
return d;
}
var data =
d3.csv(
"https://raw.githubusercontent.com/Pre60/myTest/master/map_cities.csv",
type, render)
</script>
</body>
</html>
You have some problems here:
You're setting the attributes to an "update" selection. This will not work (unless you call the function twice). It has to be:
circles.enter() .append("circle") .attr("cx", function(d) { //etc...
because of that, there were no circles in your SVG. However, changing that point #1 shows you two additional problems:
You're using a scaleLog
with a domain that crosses zero. There is no log
of zero (actually, it is minus infinity). As the API clearly says:
As log(0) = -∞, a log scale domain must be strictly-positive or strictly-negative; the domain must not include or cross zero.
So, use a linear scale instead.
You are using the wrong property for the radii. It should be rColumn
.
You forgot to set the range of the rScale
.
All together, this is your (almost) working code:
<script src="https://d3js.org/d3.v4.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.js"> </script> <script src="https://d3js.org/d3-selection-multi.v0.4.min.js"></script> <script> var outerWidth = 500; var outerheight = 250; var margin = { left: -50, top: 0, right: -50, bottom: 0 }; var xColumn = "longitude"; var yColumn = "latitude"; var rColumn = "population"; var peoplePerPixel = 1000000; var innerWidth = outerWidth - margin.left - margin.right; var innerHeight = outerheight - margin.top - margin.bottom; var svg = d3.select("body").append("svg") .attr("width", outerWidth) .attr("height", outerheight); var g = svg.append("g") .attr("transform", "translate (" + margin.left + "," + margin.top + ")"); var xScale = d3.scaleLinear() .range([0, innerWidth]); var yScale = d3.scaleLinear() .range([innerHeight, 0]); var rScale = d3.scaleSqrt().range([1, 5]); function render(data) { xScale.domain(d3.extent(data, function(d) { return d[xColumn]; })); yScale.domain(d3.extent(data, function(d) { return d[yColumn]; })); rScale.domain([0, d3.max(data, function(d) { return d[rColumn]; })]); var circles = svg.selectAll("circle").data(data); circles.enter().append("circle").attr("cx", function(d) { return xScale(d[xColumn]); }) .attr("cy", function(d) { return yScale(d[yColumn]); }) .attr("r", function(d) { return rScale(d[rColumn]); }); circles.exit().remove(); } function type(d) { d.latitude = +d.latitude; d.longitude = +d.longitude; d.population = +d.population; return d; } var data = d3.csv( "https://raw.githubusercontent.com/Pre60/myTest/master/map_cities.csv", type, render) </script>
PS: There is no difference in writing var data = d3.csv(url, callback)
, since d3.csv
doesn't return anything (actually, it returns an object related to the request). So, just drop that var data
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.