d3的包布局的地理排序功能

时间:2016-05-08 00:18:22

标签: javascript sorting d3.js geospatial circle-pack

使用d3的包布局,我制作了一些与状态相关的气泡。当前测试脚本:https://jsfiddle.net/80wjyxp4/4/。他们根据地区着色。您会注意到德克萨斯州位于" NW&#34 ;,加利福尼亚州的" SE"等等。

问题:

您如何按地理位置对包布局中的圆圈进行排序?

一种黑客方式可能会使用默认的d3.layout.pack.sort(null)。这种类型从第一个数据点(在本例中为AK)开始,然后以逆时针方向添加气泡。我可以按照接近状态位置的顺序手动对数据进行排序,并添加空白圆圈以移动边缘圆圈。

我对更好的想法感兴趣。使用修改后的力布局(如http://bl.ocks.org/mbostock/1073373)会更好吗? d3.geom.voronoi()似乎很有用。

enter image description here

2 个答案:

答案 0 :(得分:2)

http://bl.ocks.org/mbostock/1073373看这些行:

  states.features.forEach(function(d, i) {
    if (d.id === 2 || d.id === 15 || d.id === 72) return; // lower 48
    var centroid = path.centroid(d);  //   <===== polygon center
    if (centroid.some(isNaN)) return;
    centroid.x = centroid[0];              <==== polygon lat
    centroid.y = centroid[1];              <==== polygon lng
    centroid.feature = d;                  
    nodes.push(centroid);              <== made node array of centroids
  });
----------------
force
      .gravity(0)
      .nodes(nodes)           <==== asign array nodes to nodes
      .links(links)
      .linkDistance(function(d) { return d.distance; })
      .start();

每个州的行为都像是一个多焦点布局。像这样:http://bl.ocks.org/mbostock/1021841

答案 1 :(得分:0)

  1. 从包布局开始,获得圆半径
  2. 使用此修改后的力布局http://bl.ocks.org/mbostock/1073373
  3. 中的状态质心
  4. 旨在避免使用碰撞重叠https://bl.ocks.org/mbostock/7881887
  5. 代码在这里:https://jsfiddle.net/xyn85de1/。它不会运行,因为我无法从链接获取topojson文件的数据http://bl.ocks.org/mbostock/raw/4090846/us.json,并且该文件太大而无法复制粘贴。下载到您自己的服务器然后运行。

    它有一个悬停标题文字并转换,但最终看起来像这样:

    bubbles

    间距和填充可以使用不同的参数进行修改。圆圈大致按地理位置排序。 MO是中间的大金币; AK和HI左边是深蓝色; CA左下方呈粉红色; TX位于浅蓝色的底部。等等。 码: 收集所有数据(圆圈的初始位置的位置数据),以及状态名称,值,区域(用于颜色编码)到nodes变量:

    // circles
    var circles = svg.selectAll("g") //g
        .data(nodes)
        .enter()
        .append("g")
        .attr("transform", function(d) {
            return "translate(" + -d.x + "," + -d.y + ")";
        })
        .append("circle")
        .attr("transform", function(d) {
            return "translate(" + d.x + "," + d.y + ")";
        })
        .attr("r", function(d) {return d.r;})
        .attr("fill", function(d) { return color(d.area); })
        .call(force.drag); // lets you change the orientation
    
    // title text
    circles.append("title")
        .text(function(d) { return d.state + ": " + format(d.value) + " GWh"; });
    
    // // text // doesn't work :/ porque?
    // circles.append("text")
    //     .attr("dy", ".3em")
    //     //.style("text-anchor", "middle")
    //     .text(function(d) { return d.state.substring(0, d.r / 3); });
    
    // circle tick function
    function tick(e) {
        circles
            .each(collide(collision_alpha))
            .attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; });
    }
    
    // force
    force.nodes(nodes)
        .on("tick", tick)
        .start();