使用d3的包布局,我制作了一些与状态相关的气泡。当前测试脚本:https://jsfiddle.net/80wjyxp4/4/。他们根据地区着色。您会注意到德克萨斯州位于" NW&#34 ;,加利福尼亚州的" SE"等等。
问题:
您如何按地理位置对包布局中的圆圈进行排序?
一种黑客方式可能会使用默认的d3.layout.pack.sort(null)
。这种类型从第一个数据点(在本例中为AK)开始,然后以逆时针方向添加气泡。我可以按照接近状态位置的顺序手动对数据进行排序,并添加空白圆圈以移动边缘圆圈。
我对更好的想法感兴趣。使用修改后的力布局(如http://bl.ocks.org/mbostock/1073373)会更好吗? d3.geom.voronoi()
似乎很有用。
答案 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)
代码在这里:https://jsfiddle.net/xyn85de1/。它不会运行,因为我无法从链接获取topojson文件的数据http://bl.ocks.org/mbostock/raw/4090846/us.json,并且该文件太大而无法复制粘贴。下载到您自己的服务器然后运行。
它有一个悬停标题文字并转换,但最终看起来像这样:
间距和填充可以使用不同的参数进行修改。圆圈大致按地理位置排序。 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();