2017-06-03 10 views
1

topojsonから各国のバウンディングボックスを取得したいのですが、それらをsvg四角形として追加すると、0,0に向かって一緒にバンドルされます。topojsonから個々の国のバウンディングボックスを取得する

enter image description here

アイブAPIを再読み込み、結合した座標の順で遊んが、それは何も変更しませんでした!また、国のパスでSVGメソッドgetBBox()を使用しようとしましたが、同じ結果が生成されました。

アイデア?これらの行で

var width = 700, 
    height = 400, 
    bboxes = []; 

d3.queue() 
    .defer(d3.json, "data/world.topojson") 
    .await(ready); 

//Map projection 
var proj = d3.geoMercator() 
    .scale(100) 
    .center([-0.0018057527730242487, 11.258678472759552]) //projection center 
    .translate([width/2, height/2]) //translate to center the map in view 

//Generate paths based on projection 
var myPath = d3.geoPath().projection(proj); 

var svg = d3.select("svg"), 
    width = +svg.attr("width"), 
    height = +svg.attr("height"); 

//Group for the map features 
var map = svg.append("g") 
    .attr("class", "map"); 


function ready(error, geodata) { 
    if (error) return console.log(error); //unknown error, check the console 

    //Create a path for each map feature in the data 
    map.selectAll("path") 
    .data(topojson.feature(geodata, geodata.objects.subunits).features) //generate features from TopoJSON 
    .enter() 
    .append("path") 
    .attr("class", "country") 
    .attr("id", function(d) { 
     return d.id; 
    }) 
    .attr("d", myPath); 

    bboxes = boundingExtent(topojson.feature(geodata, geodata.objects.subunits).features); 


    svg.selectAll("rect") 
    .data(bboxes) 
    .enter() 
    .append("rect") 
    .attr("id", function(d){ 
     return d.id; 
    }) 
    .attr("class", "bb") 
    .attr("x1", function(d) { 
     return d.x; 
    }) 
    .attr("y1", function(d) { 
     return d.y; 
    }) 
    .attr("width", function(d) { 
     return d.width; 
    }) 
    .attr("height", function(d) { 
     return d.height; 
    }) 
} 

function boundingExtent(features) { 
var bounds= []; 
    for (var x in features) { 
    var boundObj = {}; 
    thisBounds = myPath.bounds(features[x]); 
    boundObj.id = features[x].id; 
    boundObj.x = thisBounds[0][0]; 
    boundObj.y = thisBounds[0][1]; 
    boundObj.width = thisBounds[1][0] - thisBounds[0][0]; 
    boundObj.height = thisBounds[1][1] - thisBounds[0][1]; 
    boundObj.path = thisBounds; 
    bounds.push(boundObj) 
    } 
    return bounds; 
} 

function boundExtentBySvg(){ 
    var countries = svg.selectAll(".country") 
    countries.each(function(d){ 
     var box = d3.select(this).node().getBBox(); 
     bboxes.push({id: d.id, x: box.x, y : box.y, width: box.width, height : box.height}) 
    }) 
} 

答えて

2

.attr("x1", function(d) { 
    return d.x; 
}) 
.attr("y1", function(d) { 
    return d.y; 
}) 

rectx1またはy1の属性を持っていない、私はあなただけxyを意味だと思います。

はここで実行しているコードです(注、私はわずかなコードの変更を引き起こしたtopojsonファイルスイッチアウト):

<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
    <script data-require="[email protected]" data-semver="3.0.0" src="https://unpkg.com/[email protected]"></script> 
 
    </head> 
 

 
    <body> 
 
    <svg width="700" height="400"></svg> 
 
    <script> 
 
    var width = 700, 
 
     height = 400, 
 
     bboxes = []; 
 

 
    d3.queue() 
 
     .defer(d3.json, "https://unpkg.com/[email protected]/world/110m.json") 
 
     .await(ready); 
 

 
    //Map projection 
 
    var proj = d3.geoMercator() 
 
     .scale(100) 
 
     .center([-0.0018057527730242487, 11.258678472759552]) //projection center 
 
     .translate([width/2, height/2]) //translate to center the map in view 
 

 
    //Generate paths based on projection 
 
    var myPath = d3.geoPath().projection(proj); 
 

 
    var svg = d3.select("svg"), 
 
     width = +svg.attr("width"), 
 
     height = +svg.attr("height"); 
 

 
    //Group for the map features 
 
    var map = svg.append("g") 
 
     .attr("class", "map"); 
 

 

 
    function ready(error, geodata) { 
 
     
 
     if (error) return console.log(error); //unknown error, check the console 
 

 
     //Create a path for each map feature in the data 
 
     map.selectAll("path") 
 
     .data(topojson.feature(geodata, geodata.objects.countries).features) //generate features from TopoJSON 
 
     .enter() 
 
     .append("path") 
 
     .attr("class", "country") 
 
     .attr("id", function(d) { 
 
      return d.id; 
 
     }) 
 
     .attr("d", myPath); 
 

 
     bboxes = boundingExtent(topojson.feature(geodata, geodata.objects.countries).features); 
 

 

 
     svg.selectAll("rect") 
 
     .data(bboxes) 
 
     .enter() 
 
     .append("rect") 
 
     .attr("id", function(d) { 
 
      return d.id; 
 
     }) 
 
     .attr("class", "bb") 
 
     .attr("x", function(d) { 
 
      return d.x; 
 
     }) 
 
     .attr("y", function(d) { 
 
      return d.y; 
 
     }) 
 
     .attr("width", function(d) { 
 
      return d.width; 
 
     }) 
 
     .attr("height", function(d) { 
 
      return d.height; 
 
     }) 
 
     .style("fill", "none") 
 
     .style("stroke", "steelblue"); 
 
    } 
 

 
    function boundingExtent(features) { 
 
     var bounds = []; 
 
     for (var x in features) { 
 
     var boundObj = {}; 
 
     thisBounds = myPath.bounds(features[x]); 
 
     boundObj.id = features[x].id; 
 
     boundObj.x = thisBounds[0][0]; 
 
     boundObj.y = thisBounds[0][1]; 
 
     boundObj.width = thisBounds[1][0] - thisBounds[0][0]; 
 
     boundObj.height = thisBounds[1][1] - thisBounds[0][1]; 
 
     boundObj.path = thisBounds; 
 
     bounds.push(boundObj) 
 
     } 
 
     console.log(bounds) 
 
     
 
     return bounds; 
 
    } 
 

 
    function boundExtentBySvg() { 
 
     var countries = svg.selectAll(".country") 
 
     countries.each(function(d) { 
 
     var box = d3.select(this).node().getBBox(); 
 
     bboxes.push({ 
 
      id: d.id, 
 
      x: box.x, 
 
      y: box.y, 
 
      width: box.width, 
 
      height: box.height 
 
     }) 
 
     }) 
 
    } 
 
    </script> 
 
    </body> 
 

 
</html>

+0

マークそれだった、疲れた目はそれを見つけるcouldntの。自分自身に注意し、後で金曜日の夜に新しいコードを始めるのをやめてください! – Robatron

関連する問題