【问题标题】:Group shapes/counties together by a list of attributes with D3.js使用 D3.js 通过属性列表将形状/县组合在一起
【发布时间】:2020-12-29 17:09:42
【问题描述】:

有没有办法用 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>

【问题讨论】:

    标签: javascript d3.js topojson


    【解决方案1】:

    topojson 库具有合并方法。由于您使用的是 topojson,因此合并功能相当简单。 但是,如果您计划进行多次合并并有静态分组,则可能首选创建合并数据以提供服务(而不是在每次加载时在浏览器中合并),这可能只涉及保存下面由 topojson.merge 创建的 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.
        })) 
      })
    

    这会返回一个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>

    【讨论】:

    • 哈,哈,你赢了我这个time...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 2018-04-11
    • 1970-01-01
    • 2017-04-25
    相关资源
    最近更新 更多