2015-10-19 88 views
0

我正在嘗試創建一個顯示所有國家/地區名稱的d3地圖。D3地圖顯示國名

這個地球: globe map

當我嘗試顯示了國家,地球把這個爛攤子: mess globe

var app = angular.module("myapp", []); 
 

 
    app.directive("globe", function() { 
 
     return { 
 
      restrict : 'E', 
 
      scope  : { 
 
       data: '=?' 
 
      }, 
 
      template: 
 
      '<div class="globe-wrapper">' + 
 
       '<div class="globe"></div>' + 
 
       '<div class="info"></div>' + 
 
      '</div>', 
 
      link: link 
 
     }; 
 
     
 
     function link(scope, element, attrs) { 
 
      var width = 500, height = width, 
 
       projection, path, 
 
       svg, features, graticule, 
 
       mapJson = 'https://gist.githubusercontent.com/GordyD/49654901b07cb764c34f/raw/27eff6687f677c984a11f25977adaa4b9332a2a9/countries-and-states.json', 
 
       states, stateSet, countries, countrySet, zoom; 
 
      
 
      projection = d3.geo.orthographic() 
 
       .translate([width/2, height/2]) 
 
       .scale(250) 
 
       .clipAngle(90) 
 
       .precision(0.1) 
 
       .rotate([0, -30]); 
 
      
 
      path = d3.geo.path() 
 
       .projection(projection); 
 
      
 
      svg = d3.select(element[0]).select('.globe') 
 
       .append('svg') 
 
       .attr('width', width) 
 
       .attr('height', height) 
 
       .attr('viewBox', '0, 0, ' + width + ', ' + height); 
 
      
 
      features = svg.append('g'); 
 
      
 
      features.append('path') 
 
       .datum({type: 'Sphere'}) 
 
       .attr('class', 'background') 
 
       .attr('d', path); 
 
      
 
      graticule = d3.geo.graticule(); 
 

 
      features.append('path') 
 
       .datum(graticule) 
 
       .attr('class', 'graticule') 
 
       .attr('d', path); 
 
      
 
      zoom = d3.geo.zoom() 
 
       .projection(projection) 
 
       .scaleExtent([projection.scale() * 0.7, projection.scale() * 8]) 
 
       .on('zoom.redraw', function(){ 
 
       d3.event.sourceEvent.preventDefault(); 
 
       svg.selectAll('path').attr('d',path); 
 
       }); 
 
      
 
      d3.json(mapJson, function(error, world) { 
 
       states = topojson.feature(world, world.objects.states).features; 
 
       countries = topojson.feature(world, world.objects.countries).features; 
 
       
 
       stateSet = drawFeatureSet('state', states); 
 
       countrySet = drawFeatureSet('country', countries); 
 
       
 
       d3.selectAll('path').call(zoom); 
 
      }); 
 
      
 
      function drawFeatureSet(className, featureSet) { 
 
       var set = features.selectAll('.' + className) 
 
       .data(featureSet) 
 
       .enter() 
 
       .append('g') 
 
       .attr('class', className) 
 
       .attr('data-name', function(d) { 
 
        return d.properties.name; 
 
       }) 
 
       .attr('data-id', function(d) { 
 
        return d.id; 
 
       }); 
 
       
 
       set.append("text") 
 
         .attr("class", "country-label") 
 
         .attr("transform", function(d) { console.log("d", d); return "translate(" + \t  path.centroid(d) + ")"; }) 
 
         .text(function(d) { return d.properties.name; }) 
 
         .attr("x", function(d){ 
 
          return path.centroid(d)[0]; 
 
         }) 
 
         .attr("y", function(d){ 
 
          return path.centroid(d)[1]; 
 
         }); 
 
       
 
       set.append('path') 
 
       .attr('class', 'land') 
 
       .attr('d', path); 
 
       
 
       set.append('path') 
 
       .attr('class', 'overlay') 
 
       .attr('d', path) 
 
       .attr('style', function(d) { 
 
        if (scope.data[d.id]) { 
 
         return 'fill-opacity: ' + (scope.data[d.id]/100); 
 
        } 
 
       }) 
 
       .on('click', function(d) { 
 
        var val = (scope.data[d.id]) ? scope.data[d.id] : 0; 
 
        d3.select(element[0]).select('.info').html(d.properties.name + ': ' + val); 
 
        
 
        rotateToFocusOn(d); 
 
       }); 
 
       
 
       return set; 
 
      } 
 
      
 
      function rotateToFocusOn(x) { 
 
       var coords = d3.geo.centroid(x); 
 
       coords[0] = -coords[0]; 
 
       coords[1] = -coords[1]; 
 
       
 
       d3.transition() 
 
       .duration(1250) 
 
       .tween('rotate', function() { 
 
        var r = d3.interpolate(projection.rotate(), coords); 
 
        return function(t) { 
 
         projection.rotate(r(t)); 
 
         svg.selectAll('path').attr('d', path); 
 
        }; 
 
       }) 
 
       .transition(); 
 
      } 
 
     } 
 
    }); 
 

 
    app.controller("ctrl1",function($scope, $log) { 
 
     $scope.data = {}; 
 
    }); 
 

 
    app.run();
svg { 
 
    width: 100% 
 
} 
 

 
path { 
 
    fill: none; 
 
    stroke: black 
 
} 
 

 
.background { 
 
    fill: rgba(200,212,220,.5); 
 
    stroke-width: .8px; 
 
    stroke: black; 
 
} 
 

 
.graticule { 
 
    stroke: rgba(0,0,0, .2); 
 
    stroke-width: .5px; 
 
} 
 

 
.country { 
 
    cursor: pointer; 
 
} 
 

 
.country .land, .state .land { 
 
    fill: white; 
 
    stroke: rgba(0,0,0, .2); 
 
    stroke-width .3px; 
 
} 
 

 
.state .overlay { 
 
    fill: blue; 
 
    fill-opacity: 0; 
 
} 
 

 
.country .overlay { 
 
    fill: orange; 
 
    fill-opacity: 0; 
 
} 
 

 
.country-label { 
 
    fill: #777; 
 
    fill-opacity: .5; 
 
    font-size: 20px; 
 
    font-weight: 300; 
 
    text-anchor: middle; 
 
}
<script src="https://www.workshape.io/js/geo/d3.geo.zoom.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 

 
<div ng-app="myapp"> 
 
    <div ng-controller="ctrl1"> 
 
     <globe data="data"></globe> 
 
    </div> 
 
</div>

任何人都知道我怎麼能顯示的名稱這些國家的國家? 除了不在一起,旋轉地球上的名字變換地點。

回答

0

嘗試這種方式

   set.append("text") 
         .attr("class", "country-label") 
         .attr("transform", function(d) { console.log("d", d); return "translate(" +   path.centroid(d) + ")"; }) 
         .text(function(d) { return d.properties.name; }) 
         .attr("dx", function (d) { 
         return "0.3em"; 

        }) 
        .attr("dy", function (d) { 
         return "0.35em"; 
        }) 
        .style('fill', 'black');