如何根据元素而不是节点顺序对 D3 力模拟节点进行分层?

2024-01-16

我有一个 D3 v4 力模拟,节点在屏幕上移动。每个节点都是由一个圆圈和其下方的一些文本组成的组。我如何排序,以便圆圈位于底层,文本始终位于顶层。一个圆圈与另一个圆圈重叠是可以的,但一个圆圈与文本顶部重叠是绝对不行的。这是我所拥有的。目前,位于另一个节点前面的节点的圆圈将与该节点的文本重叠。

  this.centerNode = this.d3Graph.selectAll(null)
          .data(this.nodes.slice(10,20))
          .enter()
          .append("g")

          this.centerNode.append("circle")
            .attr("class", "backCircle")
            .attr("r", 60)
            .attr("fill", "red")


            this.centerNode
            .append("text")
            .attr("fill", "black")
            .attr("font-size", "20px")
            .attr("y", -60)
            .text("test text" )

使用当前的方法无法达到预期的结果。原因很简单:每组都有一个文字和一个圆圈。然而,绘画顺序取决于组的顺序:

<g>
  <circle></circle>
  <text></text><!-- this text here... -->
</g>
<g>
  <circle></circle><!-- ...will be behind this circle here -->
  <text></text>
</g>
<!-- etc... -->

因此,将文本和里面的圆圈分组<g>元素,您将按照给定的顺序绘制组,从而在文本上绘制一个圆圈(给定组的圆圈绘制在它之前的所有组的文本上)。

这是一个演示(Baz圆圈将位于所有文本之上,并且Bar圆圈将位于顶部Foo text):

var width = 300;
var height = 200;

var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

var nodes = [{
  name: "Foo"
}, {
  name: "Bar"
}, {
  name: "Baz"
}];

var links = [{
  "source": 0,
  "target": 1
}, {
  "source": 0,
  "target": 2
}];

var simulation = d3.forceSimulation()
  .force("link", d3.forceLink())
  .force("charge", d3.forceManyBody())
  .force("center", d3.forceCenter(width / 2, height / 2));

var link = svg.selectAll(null)
  .data(links)
  .enter()
  .append("line")
  .style("stroke", "#ccc")
  .style("stroke-width", 1);

var color = d3.scaleOrdinal(d3.schemeCategory20);

var node = svg.selectAll(null)
  .data(nodes)
  .enter()
  .append("g")
  .call(d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended));

var nodeCircle = node.append("circle")
  .attr("r", 20)
  .attr("stroke", "gray")
  .attr("stroke-width", "2px")
  .attr("fill", function(d, i) {
    return color(i)
  });

var nodeTexts = node.append("text")
  .style("fill", "black")
  .attr("dx", 20)
  .attr("dy", 8)
  .text(function(d) {
    return d.name;
  });

simulation.nodes(nodes);
simulation.force("link")
  .links(links);

simulation.on("tick", function() {
  link.attr("x1", function(d) {
      return d.source.x;
    })
    .attr("y1", function(d) {
      return d.source.y;
    })
    .attr("x2", function(d) {
      return d.target.x;
    })
    .attr("y2", function(d) {
      return d.target.y;
    })

  node.attr("transform", (d) => "translate(" + d.x + "," + d.y + ")")

});

function dragstarted(d) {
  if (!d3.event.active) simulation.alphaTarget(0.3).restart();
  d.fx = d.x;
  d.fy = d.y;
}

function dragged(d) {
  d.fx = d3.event.x;
  d.fy = d3.event.y;
}

function dragended(d) {
  if (!d3.event.active) simulation.alphaTarget(0);
  d.fx = null;
  d.fy = null;
}
<script src="https://d3js.org/d3.v4.min.js"></script>

Solution

一种可能的解决方案是创建两个选择,一个用于圆圈,一个用于文本。附加圆圈before,以及文本later。记得用同样的nodes两者的数组:

var node = svg.selectAll(null)
  .data(nodes)
  .enter()
  .append("circle")
  //etc...

var nodeTexts = svg.selectAll(null)
  .data(nodes)
  .enter()
  .append("text")
  //etc...

这样,文本将是always在圆圈的顶部。

检查演示:

var width = 300;
var height = 200;

var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

var nodes = [{
  name: "Foo"
}, {
  name: "Bar"
}, {
  name: "Baz"
}];

var links = [{
  "source": 0,
  "target": 1
}, {
  "source": 0,
  "target": 2
}];

var simulation = d3.forceSimulation()
  .force("link", d3.forceLink())
  .force("charge", d3.forceManyBody())
  .force("center", d3.forceCenter(width / 2, height / 2));

var link = svg.selectAll(null)
  .data(links)
  .enter()
  .append("line")
  .style("stroke", "#ccc")
  .style("stroke-width", 1);

var color = d3.scaleOrdinal(d3.schemeCategory20);

var node = svg.selectAll(null)
  .data(nodes)
  .enter()
  .append("circle")
  .attr("r", 20)
  .attr("stroke", "gray")
  .attr("stroke-width", "2px")
  .attr("fill", function(d, i) {
    return color(i)
  })
  .call(d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended));

var nodeTexts = svg.selectAll(null)
  .data(nodes)
  .enter()
  .append("text")
  .style("fill", "black")
  .attr("dx", 20)
  .attr("dy", 8)
  .text(function(d) {
    return d.name;
  });

simulation.nodes(nodes);
simulation.force("link")
  .links(links);

simulation.on("tick", function() {
  link.attr("x1", function(d) {
      return d.source.x;
    })
    .attr("y1", function(d) {
      return d.source.y;
    })
    .attr("x2", function(d) {
      return d.target.x;
    })
    .attr("y2", function(d) {
      return d.target.y;
    })

  node.attr("transform", (d) => "translate(" + d.x + "," + d.y + ")")

  nodeTexts.attr("transform", (d) => "translate(" + d.x + "," + d.y + ")")
});

function dragstarted(d) {
  if (!d3.event.active) simulation.alphaTarget(0.3).restart();
  d.fx = d.x;
  d.fy = d.y;
}

function dragged(d) {
  d.fx = d3.event.x;
  d.fy = d3.event.y;
}

function dragended(d) {
  if (!d3.event.active) simulation.alphaTarget(0);
  d.fx = null;
  d.fy = null;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何根据元素而不是节点顺序对 D3 力模拟节点进行分层? 的相关文章

  • ie11 中的 SVG 问题

    我有一个 div 其高度设置为 320 像素 然后它的子元素宽度设置为 100 它的子文件是一个 SVG 文件 我将其宽度设置为容器的 200 在运行良好的 Chrome 和 Firefox 中 我得到了如下所示的漂亮图像 HTML 看起来
  • 动画 D3 地球仪 (d3.geo.azimuthal)

    我对 d3 javascript 库有疑问 我想使用方位角 http mbostock github com d3 talk 20111018 azimuthal html地球 我想从地球上的经度和纬度坐标插入点 并使地球动画化 而无需使用
  • 将 SVG 下载为 PNG 图像

    我想将 HTML 页面中的 SVG 元素下载为 PNG 格式 我尝试了此操作 但下载了一个空白的 PNG 图像 如何将我的 HTML SVG 下载为 PNG 我用过这个https bl ocks org biovisualize 81878
  • D3.以编程方式缩放后使用鼠标滚轮时缩放会跳转

    当我通过单击鼠标缩放到特定位置然后尝试平移或使用鼠标滚轮时 缩放行为会跳跃 看来我的缩放级别正在恢复 就像单击鼠标之前一样 这是我的事件处理程序 function click d var x y k if d centered d var
  • d3.js:在 SVG 线性渐变中过渡颜色?

    正如标题所说 使用D3 js 是否可以实现线性渐变的颜色过渡 例如 如果我有这个渐变 var gradient svg append svg defs append svg linearGradient attr id gradient a
  • 移动浏览器上带有阴影模糊的 SVG

    我正在努力在尽可能多的平台上制作带有阴影的 SVG 图标 我为此使用以下简单的 CSS test width 14px height 14px background image url images test svg background
  • 动画 SVG 在页面加载之前不会显示动画

    我的网站包含大量广告 加载需要一段时间 确切地说 这并不是一个问题 但我注意到任何 SVG 动画都会立即绘制第一帧 但动画只有在页面上的所有加载完成后才会出现 SVG 动画通常指示旋转器 加载图标 有没有办法立即启动SVG动画 或者如果我将
  • 如果满足条件,则在另一个转换期间添加并发转换

    我试图在转换运行时添加一个新的转换 条件是如果 bar1 宽度与 bar2 匹配 则条形会更改位置 我使用了transition tween来查看是否满足条件 当第二个转换开始时 第一个转换停止 我希望第一个转换继续运行直到其持续时间结束
  • 时间序列折线图与轴不同步

    本实验基于这个d3官方例子 http bost ocks org mike path 我想要实现的是可视化时间序列数据的最后 x 分钟 我有这个代码的副本jsfiddle http jsfiddle net 225dC 3 单击以添加新数据
  • 可以在 d3.js 中使用具有固定圆圈大小的圆圈包布局吗?

    此圆形包布局示例 http bl ocks org 4063269 http bl ocks org 4063269 非常适合我正在从事的项目 但是它会调整所有圆圈相对于彼此的大小 有没有一种简单的方法来指定每个圆的固定半径 我已经搜索了源
  • 在 D3 v4 中使用 Zoom.translateExtent 约束地图平移

    我正在尝试显示单个州的地图 并将缩放和平移限制在州的边界内 除了缩放状态路径以适应较小的容器时的平移约束之外 它大部分都在工作 我认为这归结于我不明白该使用什么参数zoom translateExtent 虽然我对此很陌生 所以它可能是别的
  • 窗口调整大小事件上的响应式画布

    我是画布概念的新手 我正在尝试使用 D3 js 绘制画布 我想让画布根据窗口屏幕大小进行响应 function onResize var element document getElementsByTagName canvas 0 var
  • 为什么 d3.js-lasso 不读取 svg 变量

    https jsfiddle net t52f1rn7 https jsfiddle net t52f1rn7 我正在尝试制作一个线条末端有圆圈的折线图 我想选择两个点并通过单击绘制线条 然后我找到了套索插件 我尝试将它用于相同的目的 选择
  • crossfilter - 计算具有属性的所有记录的百分比

    这是我的问题 我正在使用 python Flask 服务器从 mongo db 获取 json 数据 并在其中指定要导入的字段 此数据采用 json 格式 并且仅像这样获取 一旦通过 graphs js 中的 crossfilter 是否可
  • 如何在网站上使用 svg 元素制作块的屏幕截图?

    我在网站上创建了一个构造函数 其本质是将所选元素及其颜色 svg中的元素 添加到访问者选择的背景和背景颜色 png中的背景 中 然后必须单击 保存 结果 按钮并仅执行工作区的屏幕截图 我写了这个脚本 但它需要屏幕截图 但只有背景 并忽略选定
  • SVG 动画不适用于 Chrome 中的 favicon

    In the SVG 图标已设置 这是旋转内圆的SVG文件的内容 Favicon 动画在 Chrome 中根本不起作用 如何让它在 Chrome 中工作 在 Firefox 中可以正常工作 在 Edge 中则不行 但 Chrome 是最重要
  • SVG 到 Android 形状 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • d3.js - .exit().remove() 组元素不起作用

    我正在构建一个动态条形图 查看肯尼亚和坦桑尼亚男孩和女孩的考试成绩 用户可以从下拉菜单中选择他们想要查看哪个国家 肯尼亚 坦桑尼亚 和哪一年 2010 年 2011 年 的分数 我已清理所有数据并将其组织到单独的国家 地区年份 csv 文件
  • 如何在 React 组件中使用 CDN

    我正在尝试使用基于 D3 构建的库 称为 Greuler 来动态渲染图形 它的 npm 包似乎已损坏 当我改用 Greuler CDN 时 index html 中的测试图终于起作用了 但是 我正在开发一个 React 应用程序 并且我希望
  • 如何使用div绘制曲线?

    我需要使用 CSS 绘制两条曲线 我尝试过组装一些divs 使用CSSborder radius绘制弧形面板 但结果很糟糕 还有更好的算术吗 正如我之前在评论中提到的 请不要使用CSS用于实现复杂的曲线和形状 虽然仍然可以使用 CSS 来实

随机推荐

  • 如何在轮子中包含和安装测试文件并部署到 Databricks

    我正在开发一些在 Databricks 上运行的代码 鉴于 Databricks 无法在本地运行 我需要在 Databricks 集群上运行单元测试 问题是当我安装包含我的文件的轮子时 测试文件永远不会安装 如何安装测试文件 理想情况下我想
  • 如何在使用 VS Code 调试之前执行批处理文件

    我正在使用 Typescript nodeJS 和 VS Code 进行开发 使用 VS Code 进行调试 我的配置中有launch json type node request launch name Launch via NPM ru
  • 如何在 WPF ListView 中查看最后添加的列表视图项

    我正在使用视图模型绑定到列表视图 每次我在视图模型内部可观察集合中添加一个项目时 我都会使用 list Count 1 触发 LastIndex 属性 列表视图绑定到 VM 的 LastIndex 属性 并且列表视图正确选择添加到视图的最后
  • Typescript getter 和 setter 错误

    好吧 这是我第一天使用 typescript 做一些 Angular 2 我尝试制作一个简单的 getter 和 setter 服务 import Injectable from angular2 core Injectable expor
  • JPA:请帮助理解“join fetch”

    我有以下实体结构 业务 gt 营销活动 gt 促销 其中一个业务可以有许多营销活动 一个营销活动可以有许多促销活动 两个一对多关系都被声明为 LAZY 在我的代码中的一处 我需要急切地从 Business 中获取这两个集合 所以我这样做 Q
  • 在 data.table 中动态创建过滤表达式 (i)

    有一个data table library data table dd lt data table x 1 10 y 10 1 z 20 20 我可以使用过滤它 dd x in c 1 3 z in c 12 20 x y z 1 1 10
  • 如何屏蔽 EditText 以显示 dd/mm/yyyy 日期格式

    我怎样才能格式化EditText遵循 dd mm yyyy 格式化的方式与我们使用 a 格式化的方式相同TextWatcher to mask用户输入看起来像 0 05 我不是在谈论限制字符或验证日期 只是屏蔽到以前的格式 我写了这个Tex
  • 替换属于特定类的所有元素

    我试图开发一个嵌入式小部件 用户将包括一个anchor标签和页面中的 JavaScript 它将呈现内容 类似于嵌入式推文 a href http localhost 3000 user 13 target blank class my w
  • 添加新代码后 jQuery.keynav 不起作用

    我正在使用 jquery keynav 插件使用五个键在网页上执行导航 问题在于 我使用的是荧光笔 div 它引导用户浏览网页 可以获取 div 中的内容 文本等 并且可以执行多个操作 但荧光笔 div 不起作用 而是包含在网页 任何网页
  • JSTL 格式日期忽略区域设置

    我想用 JSTL 本地化日期 并且我正在尝试像下面那样执行此操作
  • 将数据结构从 java 传递到 perl(反之亦然)

    几天前 我询问了如何将数据结构从 java 传递到 perl 反之亦然 其中之一就是 JSON 我玩过它 主要使用 Gson for java 看起来相当不错 唯一的问题是我的数据结构内部有引用 同一数据结构内的其他对象 目前 每个此类引用
  • 词汇中的“这个”是什么? [复制]

    这个问题在这里已经有答案了 有人可以给我简单介绍一下词汇 this 吗 与函数表达式相比 箭头函数表达式 也称为胖箭头函数 具有更短的语法 并且在词法上绑定 this 值 不绑定自己的 this arguments super 或 new
  • 允许 this 引用转义

    我希望能帮助您理解 Java 并发实践 中的以下内容 调用可重写的实例方法 既不是 构造函数中的 private 或 Final 也可以允许 这个参考逃避 这里的 转义 是否仅仅意味着我们可能在实例完全构造之前调用实例方法 我没有看到 th
  • 将 OpenID 与 Zend Framework 结合使用

    我希望我的网站能够完全执行 Stackoverflow 使用 openId 所做的操作 我正在梳理资料来源 之前我也曾在 facebook 上这样做过 但是 OpenID 方面没有取得太大进展 我想做的只是检测是否有人登录了谷歌 如果他们获
  • php facebook sdk 不会在 wordpress 中创建用户

    编辑后的问题 我试图在我的 WordPress 网站上使用 Facebook 登录插件this sdk https stackoverflow com questions 6034813 facebook uncaught oauthexc
  • 选择本地视频并在HTML5视频播放器中播放(全部本地,同一文件夹)

    对于学校 我需要使用带有额外控件的 HTML5 视频播放器以及从本地驱动器选择文件的选项 该页面也在本地运行 所以没有上传 文件 HTML 和视频 位于同一本地文件夹中 对于选择的东西 我使用一个表格
  • .h、.lib 和 .dll 如何协同工作

    要使用 FreeGlut 库函数 我必须执行以下操作 添加 freeglut h 作为头文件 添加 freeGlut lib 作为资源文件 将 freeGlut dll 复制到我的 windows SysWOW64 文件夹 但是 整个系统
  • 将 Windows 身份验证与 ASP.NET MVC 结合使用

    我确信这是一个基本答案 但我的搜索能力今天对我没有帮助 我有一个 ASP NET MVC 2 NET 3 5 应用程序 它托管在 IIS 6 上 为了这个问题 我有两个网址 http example com http example com
  • 如何删除 Android Lollipop 中的前台通知?

    我希望停止 关闭媒体播放器服务的前台通知 这与 Google 的 Google Music 实现非常相似 例如 在 Google Music 中 如果您正在播放音乐 则无法将通知移开 但是 如果您暂停音乐 它就可以 这与 Android 4
  • 如何根据元素而不是节点顺序对 D3 力模拟节点进行分层?

    我有一个 D3 v4 力模拟 节点在屏幕上移动 每个节点都是由一个圆圈和其下方的一些文本组成的组 我如何排序 以便圆圈位于底层 文本始终位于顶层 一个圆圈与另一个圆圈重叠是可以的 但一个圆圈与文本顶部重叠是绝对不行的 这是我所拥有的 目前