D3js:自动放置标签以避免重叠? (斥力)

2023-12-13

如何在地图标签上应用力排斥力,以便它们自动找到正确的位置?


博斯托克的《让我们制作一张地图》

迈克·博斯托克的让我们制作一张地图(下面的屏幕截图)。默认情况下,标签放置在点的坐标和多边形/多边形的坐标处path.centroid(d)+ 简单的左对齐或右对齐,因此它们经常发生冲突。

enter image description here

手工制作的标签位置

一项改进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; });

需要更好的解决方案

对于较大的地图和标签集来说,这是无法管理的。如何向这两个类添加力斥力:.place-label and .subunit-label?

这个问题是一场头脑风暴,因为我还没有截止日期,但我对此很好奇。我正在考虑这个问题作为 Migurski/ 的基本 D3js 实现Dymo.py。 Dymo.py 的 README.md 文档设定了一大组目标,从中选择核心需求和功能(20% 的工作,80% 的结果)。

  1. 初始安置:Bostock 在相对于地理点的左/右定位方面取得了良好的开端。
  2. 标签间排斥力:可能有不同的方法,Lars 和 Navarrc 分别提出了一种方法,
  3. 标签消灭:当一个标签的整体排斥力太强(因为被挤压在其他标签之间)时,一种标签消灭功能,消灭的优先级可以是随机的,也可以是基于population数据值,我们可以通过 Natural Earth .shapefile 获得。
  4. [奢华]标签与点的斥力:具有固定点和移动标签。但这是相当奢侈的。

我忽略标签排斥是否可以跨标签层和类别起作用。但让国家标签和城市标签不重叠也可能是一种奢侈。


在我看来,强制布局不适合在地图上放置标签的目的。原因很简单——标签应该尽可能靠近它们标记的位置,但强制布局没有强制执行这一点。事实上,就模拟而言,混合标签并没有什么坏处,这对于地图来说显然是不可取的。

可能会在力布局之上实现一些东西,将地点本身作为固定节点,并在地点与其标签之间产生吸引力,而标签之间的力将是排斥力。这可能需要修改力布局实现(或同时进行多个力布局),所以我不会走这条路。

我的解决方案仅依赖于碰撞检测:对于每对标签,检查它们是否重叠。如果是这种情况,请将它们移开,其中移动的方向和幅度来自重叠。这样,只有实际重叠的标签才会被移动,并且标签只会移动一点点。重复此过程,直到不再发生任何移动。

该代码有些复杂,因为检查重叠非常混乱。我不会在这里发布完整的代码,它可以在这个演示(请注意,我已将标签做得更大以夸大效果)。关键位如下所示:

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

整个事情远非完美——请注意,有些标签距离它们标记的位置相当远,但该方法是通用的,至少应该避免标签重叠。

enter image description here

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

D3js:自动放置标签以避免重叠? (斥力) 的相关文章

  • 如何同时使用 2 个范围滑块?

    我想使用 2 个范围滑块同时根据年龄和身高过滤表中的数据 我已经使用以下方法实现了 2 个范围滑块 年龄和身高 d3 slider js https github com MasterMaps d3 slider and a dc data
  • D3可折叠树不同节点颜色

    我在 d3 js 中有一个可折叠的树 我的目标是通过 类型 属性为节点着色 例如 类型 str 的节点应填充为红色 而类型 elem 的节点应填充为绿色 我就是无法让它发挥作用 有人能帮助我吗 这是我的代码
  • 从 csv 更新数据时,d3 在 setInterval 上闪烁文本

    我是 d3 的新人 学习了很多东西 我在更新从 csv 文件获取的数据时遇到了一些问题 我使用 setInterval 每秒更新数据 当它删除并再次插入数据时 它会闪烁几毫秒 表消失并生成新表 我究竟做错了什么 我怎样才能消除闪烁 感谢您的
  • SVG 路径超出 d3 画笔上的图表区域

    当我尝试刷动和缩放折线图的一部分时 所选区域的某些部分会呈现在图表之外 代码和行为再现可以在以下位置找到这个jsbin https jsbin com jamojonaqu edit js output 单击并拖动以选择一部分并放大 双击以
  • d3树计算所有孩子的数量

    我有一个基于以下内容的 d3 树 http bl ocks org mbostock 1093025 http bl ocks org mbostock 1093025 我如何计算所有孩子的数量 我已经尝试过这个 但是它计算了树中的所有行
  • Angular svg 或 canvas 使用颜色渐变

    我正在使用 Angular 和 d3 创建一个甜甜圈 在指令中 我可以非常简单地给填充区域指定颜色 在这个 plunker 中它是蓝色 但我想做的是让 SVG 平滑地改变其颜色 0 33 3 red 33 4 66 66 orange 66
  • 将 D3 svg 保存为高质量图像

    有没有办法将 D3 SVG 图像保存为高质量图像 如果是的话请解释一下 截至目前 我正在使用以下代码将 svg 保存为图像 但我得到的图像质量不高 var canvas1 document createElement canvas canv
  • 使用canvg将C3.js SVG可视化到Canvas - 折线图填充黑色矩形,“错误:元素'parsererror'尚未实现”

    我正在尝试使用 Canvg 将 SVG 转换为 Canvas 这里是jsfiddle http jsfiddle net sridev24 vcz468f9 我收到一条错误消息 错误 元素 parsererror 尚未实现 我可以理解 ca
  • 使用不同颜色的 dc.js 显示原始(有条件)拉丝未拉丝交叉过滤器条

    假设我们有以下 crossfilter dc js 应用程序 虽然这很好 但用户在刷牙时会失去对人群的 参考 我想要图表x y z and a在刷其他图表时保留 基础 柱 也许是不同的颜色 如下所示 我相信这可能需要更新dc renderA
  • d3.forcesimulation() 链接距离

    我在堆栈上查看了不同的链接距离 似乎为了改变链接距离 您需要实现一个函数 然后传递它来动态分配链接距离 如下所示 function linkDistance d return d distance 然后我认为我可以传递给 svg 但返回函数
  • 矩形相当于文本的文本锚点表示属性吗?

    是否有一个与文本的文本锚点表示属性等效的矩形 我希望能够从左侧 右侧或根据情况定位矩形 我知道这可以通过一些简单的计算来完成 但我只是想知道是否已经存在内置的东西 文本锚点演示属性上的链接 https developer mozilla o
  • 为什么这个标题图形不随世界更新

    对于以下内容 我很高兴组合框默认为世界 但当收音机被点击时 我也希望标题移回 世界 我该怎么做 我有这个笨蛋 http plnkr co edit 9FXJXVqLZLPFdDrmVJez p preview http plnkr co e
  • 谷歌 Android 地图 v2 MetersToEquatorPixel

    我目前的任务是将 Google Android 地图 v1 应用程序转换为 Google Android 地图 V2 应用程序 这个过程并不愉快 感谢谷歌 我的问题是 在之前的应用程序中 他们使用了 Google Android Maps
  • d3.js。带条的旋转地球仪

    我正在尝试创建带有像这样的酒吧的旋转地球仪这个例子 http data arts appspot com globe 你可以看我的例子here http jsfiddle net zeleniy jrh5xucs 一切都很顺利 直到酒吧超出
  • Webpack 不包括 ProvidePlugins

    我正在开发一个小型试用 Web 应用程序 它使用 vue webpack 模板 https github com vuejs templates webpack https github com vuejs templates webpac
  • 我可以补间 D3 弧的结束角度,但不能补间起始角度。我究竟做错了什么?

    我只是在玩这个演示并自己重新创建它 http bl ocks org mbostock 5100636 http bl ocks org mbostock 5100636 我可以定义一个新的 endAngle 并且它会很好地制作动画 但现在
  • 如何使用 Google Direction api 或 iPhone 应用程序的其他一些 api 比较两条路线

    我想比较两条路线以检查它们在我的 iPhone 应用程序中是否相同 有一个人X想要从A点到B点 另一个人想要从A1点到B1点 我可以使用谷歌的方向 API 获取 A 到 B 之间的路线 http maps googleapis com ma
  • 通过使用 Intents 使用预装的 Google 地图而不是自己的 Activity?

    我只是想知道是否可以将地理坐标传递给谷歌地图应用程序之二意图或类似的东西 我自己编写了一个用于显示路线 坐标等的应用程序 但是让谷歌地图本身显示这些不是更优雅吗 我不知道这是否可能 但也许你们中的一个人可以回答这个问题 如果这是可能的 是否
  • 加拿大人口普查地图分区 R

    我对 R 和映射非常陌生 我想创建某些数据的映射 我有一组名为 D Montreal 的数据 显示 2010 年前往蒙特利尔的加拿大人口普查部门游客来自哪个国家 我想使用此数据创建一个地图 以显示有多少人来自不同地区 也许可以通过对根据人数
  • 如何运行 D3 示例

    例如https observablehq com d3 zoomable treemap https observablehq com d3 zoomable treemap 如果将脚本片段粘贴到

随机推荐

  • 当位置设置为固定时,导航栏会缩小

    我目前遇到一个问题 当我将导航栏和横幅的位置设置为固定时 它们会缩小 我有很多事情 例如更改 z index 将其顶部位置设置为 0 添加自动边距等 但这些都不起作用 我希望有人能指出我的错误 这是我的html代码 html body ma
  • 有没有办法对VBS中存储的密码进行加密

    我有一个在工作中使用的 VBS 脚本 用于在连接到 Cisco 路由器和交换机时自动执行任务 包括自动执行登录过程 人们对于将密码存储在纯文本 VBS 文件中有些紧张 这并非没有道理 因此我为他们提供了每次提示输入密码或将其存储在脚本中的选
  • Canvas.toDataURL() 未捕获类型错误:未定义不是函数

    我正在使用一个名为 html2canvas 的插件将页面上的一些 html 转换为 canvas 元素 然后我想将该画布保存为图像 不幸的是我一直遇到标题中的错误 我尝试过使用不同的变量名 不同的 html 等 但不断遇到相同的错误 这是我
  • 复制 local = false 文件未找到异常问题

    嗨 我知道这个已被询问但并没有得到答复 当我想使用安装在 C Program files x86 Dummu API dll 上的 dll 时遇到问题 当我运行我的应用程序时 它抛出异常 无法加载文件或程序集 Dummy API Versi
  • 硒点击表td内的锚标记

    我的 html 代码如下所示 div class fd food search all fd loading style display block ul class fd breadcrumbs li a href class bread
  • 如何“加入”一个数组,将第一个要加入的字符添加到结果字符串的开头?

    我正在使用 Ruby on Rails 3 并且正在尝试join一个数组 特点 我阅读了 Ruby 文档关于那个 我的数组是 name1 name2 If I do name1 name2 join 结果是 name1 name2 我希望结
  • 类型别名的目的

    我想今天我终于明白什么是 typealias 了 我没有 让我们看一个例子 typealias Graph String String let futurama Graph you bender hermes scruffy bender
  • 从 iframe 访问父页面中的变量

    我有一个带有 iframe 的页面 其中包含 html 页面 我想从 iframe 中访问父页面中的 Javascript 变量 主页中变量的名称是observer 我已经尝试过这个 parent observer aadasds 但我收到
  • Distinct() 如何在对象列表中查找唯一元素

    有一个非常简单的类 public class LinkInformation public LinkInformation string link string text string group this Link link this T
  • 3D 三角形光栅化为体素网格

    序幕 这是将 3D 三角形光栅化为体素网格的问答 我被要求解决与以下相关的不同问题材料侵蚀 去除在制造过程模拟期间 这个问题背后的主要思想是如何移植基于扫描线的 2D 三角形光栅化 例如this转化为 3D 体素 所以问题是如何高效地光栅化
  • bash中删除长度小于2的单词

    我在 CentOS 5 5 上使用 bash 我有一个用空格分隔的字符串 并且该字符串只包含字母和数字 并且这个字符串可能有多余的空格 例如之间有超过1个空格 words and string exmple This is a lovey
  • 从 ASP.NET 5 中的 config.json 检索部分

    假设我有一个config json像这样 CustomSection A 1 B 2 我知道我可以使用IConfiguration对象获取特定设置 即configuration Get CustomSection A 但是我可以获取整个层次
  • 为什么我的帐户上的 OneNote API 延迟大约 3 天?

    简而言之 通过 OneNote API 获取笔记的页面信息有大约 3 天滞后的数据 为什么会出现这种情况 我假设只针对我 以及如何解决这个问题 我正在开发一个个人 R 程序来阅读我的 OneNote 笔记 大约一周前就启动并运行了 身份验证
  • 如何在textAngular编辑器中的范围var中删除占位符img?

    我在带有 Angular 的应用程序中使用 TextAngular 指令 当我插入 youTube 链接 通过工具栏按钮 时 它会在编辑器中显示占位符图像 我希望将所有 html 保存在 scope var 中 但不包含占位符 html 目
  • 将链表的头部移动到尾部

    我需要用 Java 编写一个方法 将链表中的第一个元素移动到最后一个位置 为了实现这一点 我相信我必须设置一个节点来引用 head 之后的第一个元素 然后将下一个节点设置为 null 我尝试用我的方法执行此操作 但是运行该方法时 输出不正确
  • java网络服务客户端

    我有 stfw 但我找不到一种简单 独立的方法来在 java 中创建 web 服务客户端 有人有这个的链接 样本吗 soapUI是一个测试 Web 服务的好工具 创建服务器存根来测试客户端或仅将客户端请求发送到任何 Web 服务非常简单
  • 发现 iOS 应用程序购买日期

    我明确不是指应用内购买 是否可以在 iOS 上找到应用程序本身的购买日期 我想奖励早期购买者 奖励早期用户 启动应用程序的用户 是not要走的路 我想奖励那些在 1 月 1 日到 1 月 31 日之间购买游戏的用户 甚至是在 2 月 28
  • WPF ComboBox:将 SelectedItem 设置为不在 ItemsSource -> 绑定奇怪中的项目

    我想要实现以下目标 我想要一个显示可用 COM 端口的组合框 启动时 并单击 刷新 按钮 我想获取可用的 COM 端口并将选择设置为最后选择的值 从应用程序设置中 如果设置中的值 最后一个 com 端口 不在值列表 可用 COM 端口 中
  • 在 Vortex86DX 上从头开始构建和编译 GCC 5.2.0 时出错

    为了升级 VortexDX86 定制 linuxgcc 3 2 3编译器 我正在尝试构建 GCC 5 2 0 编译器以支持最新的 C 11 标准 我已经从以下位置下载了它的源代码gcc gnu org并做了基于标准linux包构建器这个链接
  • D3js:自动放置标签以避免重叠? (斥力)

    如何在地图标签上应用力排斥力 以便它们自动找到正确的位置 博斯托克的 让我们制作一张地图 迈克 博斯托克的让我们制作一张地图 下面的屏幕截图 默认情况下 标签放置在点的坐标和多边形 多边形的坐标处path centroid d 简单的左对齐