- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如何在 map 标签上应用力排斥力,以便它们自动找到正确的位置?
<小时/>迈克博斯托克的 Let's Make a Map (下面的屏幕截图)。默认情况下,标签放置在点的坐标和多边形/多边形的 path.centroid(d)
+ 简单的左对齐或右对齐处,因此它们经常发生冲突。
一项改进 I met需要添加人为的 IF
修复,并根据需要添加尽可能多的修复,例如:
.attr("dy", function(d){ if(d.properties.name==="Berlin") {return ".9em"} })
随着需要重新调整的标签数量的增加,整体变得越来越脏:
//places's labels: point objects
svg.selectAll(".place-label")
.data(topojson.object(de, de.objects.places).geometries)
.enter().append("text")
.attr("class", "place-label")
.attr("transform", function(d) { return "translate(" + projection(d.coordinates) + ")"; })
.attr("dy", ".35em")
.text(function(d) { if (d.properties.name!=="Berlin"&&d.properties.name!=="Bremen"){return d.properties.name;} })
.attr("x", function(d) { return d.coordinates[0] > -1 ? 6 : -6; })
.style("text-anchor", function(d) { return d.coordinates[0] > -1 ? "start" : "end"; });
//districts's labels: polygons objects.
svg.selectAll(".subunit-label")
.data(topojson.object(de, de.objects.subunits).geometries)
.enter().append("text")
.attr("class", function(d) { return "subunit-label " + d.properties.name; })
.attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; })
.attr("dy", function(d){
//handmade IF
if( d.properties.name==="Sachsen"||d.properties.name==="Thüringen"|| d.properties.name==="Sachsen-Anhalt"||d.properties.name==="Rheinland-Pfalz")
{return ".9em"}
else if(d.properties.name==="Brandenburg"||d.properties.name==="Hamburg")
{return "1.5em"}
else if(d.properties.name==="Berlin"||d.properties.name==="Bremen")
{return "-1em"}else{return ".35em"}}
)
.text(function(d) { return d.properties.name; });
这对于较大的 map 和标签集来说是无法管理的。 如何向这两个类添加力排斥:.place-label
和 .subunit-label
?
这个问题是一场头脑 Storm ,因为我还没有截止日期,但我对此很好奇。我正在考虑这个问题作为 Migurski/Dymo.py 的基本 D3js 实现。 Dymo.py 的 README.md 文档设定了一大组目标,从中选择核心需求和功能(20% 的工作,80% 的结果)。
群体
数据值,我们可以通过 NaturalEarth 的 .shp 文件获取。我忽略标签排斥是否可以跨标签层和类别起作用。但让国家标签和城市标签不重叠也可能是一种奢侈。
最佳答案
在我看来,强制布局不适合在 map 上放置标签的目的。原因很简单——标签应该尽可能靠近它们标记的位置,但强制布局没有强制执行这一点。事实上,就模拟而言,混合标签并没有什么坏处,这对于 map 来说显然是不可取的。
可能会在力布局之上实现一些东西,将地点本身作为固定节点,并在地点与其标签之间产生吸引力,而标签之间的力将是排斥力。这可能需要修改强制布局实现(或同时多个强制布局),所以我不会走这条路。
我的解决方案仅依赖于碰撞检测:对于每对标签,检查它们是否重叠。如果是这种情况,请将它们移开,其中移动的方向和幅度来自重叠。这样,只有实际重叠的标签才会被移动,并且标签只会移动一点点。重复此过程,直到不再发生任何移动。
代码有些复杂,因为检查重叠非常困惑。我不会在这里发布完整的代码,它可以在 this demo 中找到。 (请注意,我已将标签做得更大以夸大效果)。关键部分如下所示:
function arrangeLabels() {
var move = 1;
while(move > 0) {
move = 0;
svg.selectAll(".place-label")
.each(function() {
var that = this,
a = this.getBoundingClientRect();
svg.selectAll(".place-label")
.each(function() {
if(this != that) {
var b = this.getBoundingClientRect();
if(overlap) {
// determine amount of movement, move labels
}
}
});
});
}
}
整个事情远非完美——请注意,有些标签距离它们标记的位置相当远,但该方法是通用的,至少应该避免标签重叠。
关于d3.js - D3js : Automatic labels placement to avoid overlaps?(力斥力),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17425268/
我需要可视化我正在处理的项目的节点树...数据结构如下所示: 构造函数: function Tree(x,y,node){ this.root = node; this.x = x;
我正在尝试使用 SFML 和 C++ 为炮塔游戏实现基本 AI,但我遇到了一些问题。该 AI 遵循在贝塞尔曲线中建立的一些航路点。首先,这条道路上只有一个敌人。为此,敌人必须计算他与实际位置之间的距离
我是一名优秀的程序员,十分优秀!