简体   繁体   中英

geographic sort function for d3's pack layout

Using d3's pack layout, I made some bubbles associated with states. Current test script: https://jsfiddle.net/80wjyxp4/4/ . They're colored according to region. You'll note Texas is in the "NW", California in the "SE", etc.

Question:

How would you geographically sort the circles in pack-layout?

One hack way might use the default d3.layout.pack.sort(null) . This sort starts with the first data point (in this case, AK) and then adds bubbles in a counterclockwise direction. I could hand-sort data to be input in an order that approximates state positions, and add in blank circles to move edge circles around.

I'm interested about better ideas. Would it be better to use a modified force layout, like http://bl.ocks.org/mbostock/1073373 ? The d3.geom.voronoi() seems useful.

在此处输入图片说明

On this http://bl.ocks.org/mbostock/1073373 look at these lines:

  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();

Each state acts like a multi-foci layout. Like this one: http://bl.ocks.org/mbostock/1021841

  1. Started with pack layout, to get circle radii
  2. used state centroids from this modified force layout http://bl.ocks.org/mbostock/1073373
  3. Contrived to avoid overlaps using collisions https://bl.ocks.org/mbostock/7881887

The code is here: https://jsfiddle.net/xyn85de1/ . It does NOT run because I can't get data for the topojson file, at http://bl.ocks.org/mbostock/raw/4090846/us.json , from the link, and the file is too large to copy-paste. Download to your own server then run.

It has a hover-title text and transitions in, but ends up looking like this:

泡泡

Spacing and stuff is modifiable with different parameters. The circles are approximately sorted geographically. MO is that big gold one in the middle; AK and HI are dark blue to the left; CA is lower left in pink; TX is at the bottom in light blue. And so on. Code: After collecting all data (location data for init position of circles), along with the state name, value, area (for color coding) into the nodes variable:

// 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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM