简体   繁体   中英

d3.csv linked GitHub

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:

  1. 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:

  2. 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.

  3. You are using the wrong property for the radii. It should be rColumn .

  4. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM