用 D3.js 按属性列表将 shapes/counties 组合在一起

Group shapes/counties together by a list of attributes with D3.js

有没有办法将某些县与 D3.js 组合在一起?

我正在显示美国的县级地图,我想在县组周围绘制边界或突出显示县组。

我有一个每个县的数组(通过 d.id 在绘制县时分配),但我不确定如何定位该属性或围绕一组具有这些属性的元素。

    <script>

    var svg = d3.select("svg");

    var path = d3.geoPath();

    d3.json("https://d3js.org/us-10m.v1.json", function(error, us) {
        if (error) throw error;

    // draw counties
    svg.append("g")
        .attr("class", "counties")
        .selectAll("path")
        .data(topojson.feature(us, us.objects.counties).features)
        .enter().append("path")
        .attr("d", path)
        .on("click", clicked)

    svg.append("path")
        .attr("class", "county-borders")
        .attr("d", path(topojson.mesh(us, us.objects.counties, function(a, b) { return a !== b; })));

    // draw states
    svg.append("g")
        .attr("class", "states")
        .selectAll("path")
        .data(topojson.feature(us, us.objects.states).features)
        .enter().append("path")
        .attr("d", path);

    svg.append("path")
        .attr("class", "state-borders")
        .attr("d", path(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; })));

    function clicked(d) {
        console.log(d.id);
    }


    var example_group = [45001, 45003, 45005, 45007, 45009, 45011];


});

    </script>

topojson 库具有合并方法。由于您使用的是 topojson,因此合并功能非常简单。 但是,如果您计划进行许多合并并且具有静态分组,则创建合并数据以提供服务(而不是在每次加载时在浏览器中合并)可能是首选,这可能只涉及保存由 [=36 创建的 geojson =] 下面。

首先,我们使用功能 ID 进行一些分组:

  // groups: 
  var groups = [
     [45001, 45003, 45005, 45007, 45009, 45011],
     [32023, 32003, 06027, 32017, 49053, 4015]
  ];

然后我们运行topojson.merge每一个:

  var groupedCounties = groups.map(function(group) {
    return topojson.merge(us, us.objects.counties.geometries.filter(function(d) {
        return group.indexOf(+d.id) > -1;  // Merge criteria.
    })) 
  })

这个returns一组geojson特征,所以我们可以直接用d3.geoPath。

现在我们只画它们:

  svg.selectAll(null)
    .data(groupedCounties)
    .enter()
   .append("path")
   .attr("d", path)
   ....
  

如下图:

var svg = d3.select("svg");

    var path = d3.geoPath();
    
    d3.json("https://d3js.org/us-10m.v1.json", function(error, us) {
        if (error) throw error;
        
 
        
        // for fitting in snippet view (somewhat)
        path.projection(d3.geoIdentity().fitSize([500,300],topojson.feature(us, us.objects.counties)))  
        
       
        svg.append("path")
        .attr("class", "county-borders")
        .attr("d", path(topojson.mesh(us, us.objects.counties, function(a, b) { return a !== b; })));

    // draw states
       svg.append("g")
        .attr("class", "states")
        .selectAll("path")
        .data(topojson.feature(us, us.objects.states).features)
        .enter().append("path")
        .attr("d", path);        
        
      // groups: 
      var example_group = [45001, 45003, 45005, 45007, 45009, 45011];
      var example_group2 = [32023,32003,06027,32017,49053,4015]; 
      // make an array of groups:
      var groups = [example_group,example_group2];

      // make features out of these:
      var groupedCounties = groups.map(function(group) {
        return topojson.merge(us, us.objects.counties.geometries.filter(function(d) { return group.indexOf(+d.id) > -1; }))
      })
      
      console.log(groupedCounties);
      
      // draw grouped features:
      svg.selectAll(null)
        .data(groupedCounties)
        .enter()
       .append("path")
       .attr("d", path)
       .style("fill", function(d,i) {
         return ["orange","steelblue"][i];
       })
      
      






});
.states{
  fill: none;
  stroke: black;
  stroke-width: 1px;
}


.county-borders {
  fill:none;
  stroke: #ccc;
  stroke-width: 1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<svg width="500" height="300"></svg>