如何为气泡设置边界并根据命令触发移动?

2023-12-13

我在 D3 中有一个气泡图,我用它来显示每组有多少个气泡。这个版本一开始有大约 500 个气泡,我的完整版本有大约 3,000 个。

我在二维中挣扎。我试图让气泡在不在状态之间转换时保持原状,并且我还试图让气泡创建矩形形状。

这是一个demo的气泡图。我将添加代码,然后检查我所尝试的内容。

这是我的气泡的代码。

// Initial time and quarter
let time_so_far = 0;
let quarter = 0;
const tick_time = 100

// Forces
const radius = 1.5
const padding1 = 10;
const padding2 = 2;
const strength = 50
const veloc_decay = .99
const alpha = .05
const alpha_decay = 0
const alpha_min = 0.001
const alpha_Collision = .08;
const charge_strength = -.5
const charge_theta = .9

// Load data
Promise.all([
    d3.tsv("stages.tsv", d3.autoType),
    d3.tsv("customers.tsv", d3.autoType),
])

   // Once data is loaded...
   .then(function(files){
  // Prepare the data...

  const stage_data = files[0]
  const customer_data = files[1]

    // Consolidate stages by id.
    stage_data.forEach(d => {
        if (d3.keys(stakeholders).includes(d.id+"")) {
            stakeholders[d.id+""].push(d);
        } else {
            stakeholders[d.id+""] = [d];
        }
    });

    // Consolidate customers by week.
    customer_data.forEach(d => {
        if (d3.keys(customers).includes(d.week+"")) {
            customers[d.week+""].push(d);
        } else {
            customers[d.week+""] = [d];
        }
    });

    // Create node data.
    var nodes = d3.keys(stakeholders).map(function(d) {
        // Initialize count for each group.

        groups[stakeholders[d][0].stage].cnt += 1;

        return {
            id: "node"+d,
            x: groups[stakeholders[d][0].stage].x + Math.random(),
            y: groups[stakeholders[d][0].stage].y + Math.random(),
            r: radius,
            color: groups[stakeholders[d][0].stage].color,
            group: stakeholders[d][0].stage,
            timeleft: stakeholders[d][0].weeks,
            istage: 0,
            stages: stakeholders[d]
        }
    });

    // Circle for each node.
    const circle = svg.append("g")
        .selectAll("circle")
        .data(nodes)
        .join("circle")
          .attr("cx", d => d.x)
          .attr("cy", d => d.y)
          .attr("fill", d => d.color)
          .attr("r", d => d.r);

     // Forces
     const simulation = d3.forceSimulation(nodes)
         // .force("bounds", boxingForce)
         .force("x", d => d3.forceX(d.x))
         .force("y", d => d3.forceY(d.y))
         .force("cluster", forceCluster())
         .force("collide", forceCollide())
         .force("charge", d3.forceManyBody().strength(charge_strength).theta(charge_theta))
         // .force('center', d3.forceCenter(center_x, center_y))
         .alpha(alpha)
         .alphaDecay(alpha_decay)
         .alphaMin(alpha_min)
         .velocityDecay(veloc_decay)

     // Adjust position of circles.
      simulation.on("tick", () => {
          circle
          .attr("cx", d => Math.max(r, Math.min(500 - r, d.x)))
          .attr("cy", d => Math.max(r, Math.min(500 - r, d.y)))
          .attr("fill", d => groups[d.group].color);
          });

      // Force to increment nodes to groups.
      function forceCluster() {
        let nodes;

        function force(alpha) {
          const l = alpha * strength;
          for (const d of nodes) {
            d.vx -= (d.x - groups[d.group].x) * l;
            d.vy -= (d.y - groups[d.group].y) * l;
          }
        }
        force.initialize = _ => nodes = _;

        return force;
      }

      // Force for collision detection.
      function forceCollide() {
        let nodes;
        let maxRadius;

        function force() {
          const quadtree = d3.quadtree(nodes, d => d.x, d => d.y);
          for (const d of nodes) {
            const r = d.r + maxRadius;
            const nx1 = d.x - r, ny1 = d.y - r;
            const nx2 = d.x + r, ny2 = d.y + r;
            quadtree.visit((q, x1, y1, x2, y2) => {

              if (!q.length) do {
                if (q.data !== d) {
                  const r = d.r + q.data.r + (d.group === q.data.group ? padding1 : padding2);
                  let x = d.x - q.data.x, y = d.y - q.data.y, l = Math.hypot(x, y);
                  if (l < r) {
                    l = (l - r) / l * alpha_Collision;
                    d.x -= x *= l, d.y -= y *= l;
                    q.data.x += x, q.data.y += y;
                  }
                }
              } while (q = q.next);
              return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
            });
          }
        }

        force.initialize = _ => maxRadius = d3.max(nodes = _, d => d.r) + Math.max(padding1, padding2);

        return force;
      }

      // Make time pass. Adjust node stage as necessary.
      function timer() {
          // Ticker...

          nodes.forEach(function(o,i) {

              o.timeleft -= 1;
              if (o.timeleft == 0 && o.istage < o.stages.length-1) {
                  // Decrease counter for previous group.
                  groups[o.group].cnt -= 1;

                  // Update current node to new group.
                  o.istage += 1;
                  o.group = o.stages[o.istage].stage;
                  o.timeleft = o.stages[o.istage].weeks;

                  // Increment counter for new group.
                  groups[o.group].cnt += 1;
              }
          });

          // Previous quarter
          quarter = Math.floor(time_so_far / 12)

          // Increment time.
          time_so_far += 1;

          // goes by week, timer updates every quarter
          var current_quarter = Math.floor(time_so_far / 13) + 1

          // stop on the last quarter
          if(time_so_far == d3.keys(customers).length) { return }

          d3.select("#timecount .cnt").text(quarters[current_quarter]);


           // update counter
           d3.selectAll(".counter")
             .text(d => d.cnt)

           // Define length of a tick
           d3.timeout(timer, tick_time);

      } // @end timer()

      timer()


}); // end TSV

现在,我的泡泡在不断地移动。即使我让气泡的空间非常大而填充物非常小,它们也会继续移动。

我尝试过设置.alphaDecay()到一个大于的值0它让气泡停止移动,它们看起来相当不错,但它们没有能量在状态之间转换。

我想设置它,以便气泡在页面加载时找到它们的位置,然后它们不会移动,除了从no interactions to portfolio to partner类似于气泡图here.

另一个问题是气泡聚集成圆圈。我想让它们填充每个州的整个矩形背景。

根据迈克·博斯托克的comments,我添加了边界simulation.on功能。它可以在整个空间上设置边界,但不会单独将边界应用于每个状态,因此它们最终仍然聚集为圆圈。

我也尝试过约翰·格拉的 d3.forceBoundary但我遇到了同样的问题。

如何强制气泡保持在一个位置,并且仅在发生状态转换时才移动?如何让气泡在每个状态上聚集在矩形中?

编辑:我尝试设置 alphaDecay > 0 这样气泡就会初始化并停止移动,然后我在.on("tick",功能,但这只是让他们保持能量。

问题的核心是,我不知道如何施加力,让它们在可视化中从一种状态移动到另一种状态,但又不会导致它们混乱。

我的下一个尝试是创造一种不同的力量来改变状态而不是被创造。

Edit2:我有一个解决能源问题的解决方案。这有点老套。

I added o.statechange = 3if loop inside nodes.forEach(function(o,i) {我添加了o.statechange -= 1就在 if 循环之上。然后,在forceCluster我添加了

             for (var i = 0, n = nodes.length, node, k = alpha * strength; i < n; ++i) {
                node = nodes[i];
                if(node.statechange <= 0) { continue }
                node.vx -= (node.x - groups[node.group].x) * k;
                node.vy -= (node.y - groups[node.group].y) * k;
}

如果圆圈需要移动,这将为它们提供三个刻度的能量。否则,他们什么也得不到。 (上次编辑,此解决方法适用于少量节点,但随着节点数量变大而失败)


None

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

如何为气泡设置边界并根据命令触发移动? 的相关文章

  • 使用 jquery 淡入/淡出

    我正在研究我的学生项目 我是新的 jquery 对于该项目 我必须使用 jquery 来增强一些功能 并且我已经学到了很多来执行基本任务 但我陷入了一些非常令人困惑的事情 我的一个脚本实际上在鼠标悬停在功能上时更改了 div 容器的图像 功
  • 流媒体性能 - Canvas 与

    我正在开发一个应用程序 需要通过 webSocket 连接以每秒至少 30 帧的速度持续传输图像 我遇到了一些性能问题 并希望尽我所能进行优化 我想知道使用不断更新的图像之间的性能差异是什么 就像这样 img src someDynamic
  • Node.js Google-云存储上传目的地规范

    我有一个 Node js 服务器并且正在使用谷歌云上传一些图像文件的包Firebase 存储 上传本身工作正常 但 google cloud API 似乎只能将文件上传到 Firebase Storage 根文件夹 有没有办法指定远程位置来
  • 如何使用 Underscore 获取 JavaScript 数组中的重复项

    我有一个数组 我需要重复的项目并根据特定属性打印这些项目 我知道如何使用 underscore js 获取唯一项目 但我需要找到重复项而不是唯一值 var somevalue name john country spain name jan
  • Javascript 自时间戳以来经过的时间

    我试图通过将其存储在变量中来 缓存 一些信息 如果 2 分钟过去了 我想获取 实时 值 调用 url 如果 2 分钟还没有过去 我想从变量中获取数据 我基本上想要的是 if time passed is less than 2 minute
  • 如何根据另一个动态下拉列表的值创建动态下拉列表?

    我有一个下拉菜单 当我选择一个选项时 它会创建一个动态下拉菜单 到目前为止 一切都很好 但我想创建另一个动态下拉列表 现在基于另一个动态下拉列表的值 我该怎么做 第一个动态下拉列表有效 我猜第二个无效 因为动态变量 div 没有静态 ID
  • 使用 Charts.js 禁用动画

    我在使用 Charts js 关闭动画时遇到一些问题 这是我的代码 var pieData value 30 color F38630 value 50 color E0E4CC value 100 color 69D2E7 var myP
  • 如何更改点击事件上的引导插入符指向方向

    我正在使用 2 3 2 引导程序 因为当我单击菜单按钮时 我可以更改插入符号图标的位置 我需要当我单击图标插入符号向上时 当您单击另一个项目时 插入符号返回到初始状态 这怎么可能 导航代码 div div class container d
  • 如何获得相对于特定父级的偏移量?

    我想获取元素相对于的偏移量特定的父母不是直接的 也不是文档 我在互联网上查找并找到了offset http api jquery com offset and position http api jquery com position jQ
  • 无法提取 Typescript 中的对象值

    我一直在尝试将 JavaScript Web 表单转换为 Typescript 但无法弄清楚如何处理以下内容 在 JavaScript 中有效 let fieldValues JSON parse cookieData let keys O
  • jQuery 如何通过不同的列值计算表中的行数

    如何按表列计算不同的表行 Example table thead tr th NAME th th TECHNOLOGY th tr thead tbody tr td john td td jQuery td tr tr td mark
  • 根据数据更改图例颜色高图表

    我可以根据数据动态设置列的颜色 但无法弄清楚如何更改图例中的颜色 请注意 jsfiddle 最新的条形图是绿色的 但图例是蓝色的 有没有办法改变列颜色也会改变图例颜色 这是我用于列颜色的代码 jsfiddle http jsfiddle n
  • 'DOMException:使用'option:selected'选择器时无法在'Element'上执行'querySelectorAll'

    我正在运行一个页面 该页面在以下行中引发错误 var label select find option selected html select find option first html 为了完整起见 这里是完整的 jQuery 函数
  • 如何将输入字段值作为 URL 查询字符串传递,单击提交按钮将打开该字符串?

    我必须输入这样的字段
  • JavaScript 按名称获取当前作用域中的变量

    所以我有一个变量和该变量名称的字符串 function Factory string var foo bar console log foo is equal to this string 如果变量所在的对象是当前对象 如何从字符串文字中获
  • jQuery 单击附加元素不起作用

    我有一个数组 我正在从 Array 获取数据并在 jQuery Append to list 中使用它 但是当我单击列表项时 它只显示最后一个元素 var array 1 2 7 3 4 8 5 6 9 for var i 0 i lt a
  • 限制线的长度

    我正在尝试画一条代表 弹弓 的线 并且希望它具有最大拉伸长度 在 p5 中 我在位置和位置之间画了一条线 line posA x posA y posB x posB y posA 是鼠标 x 和 y posB 是画布上圆的位置 我想要做的
  • .parents() 没有 jquery - 或 querySelectorAll 为父母[重复]

    这个问题在这里已经有答案了 可能的重复 使用 matchesSelector js 检查 event target parentElement https stackoverflow com questions 12977658 check
  • 检测图像是否损坏或损坏

    我需要以编程方式检查用户在我的应用程序上选择作为壁纸的图像是否已损坏或损坏 基本上我为用户提供了选择自己的图像作为壁纸的选项 现在 当图像加载时 我只想检查它是否已损坏 如果您正在寻找 PHP 解决方案而不是 javascript 解决方案
  • 在 Map() 的条目上使用 Promise.all

    我正在使用 Map 来表示一些键 值对 let myMap new Map myMap set foo bar myMap set foo2 bar42 对于每个 Map 条目 我执行一个返回 Promise 的函数 所有这些 Promis

随机推荐

  • Cocos2d 获取当前时间(以毫秒为单位)

    我尝试用谷歌搜索 但仍然找不到最佳答案 我想要的很简单 我只想获取当前时间 以毫秒为单位 我怎样才能在 cocos2d 中做到这一点 首先 一个类变量 CGFloat gameTime 然后在你的类中初始化 self scheduleUpd
  • 简单的xml添加属性

    当我使用 PHP 在 XML 中添加新元素时 如何设置属性 我的PHP代码是这样的
  • 在C中将int数组更改为float数组

    有谁知道如何将整数数组转换为浮点数组 你的问题措辞不好 但是 假设您已经声明了整数数组 您可以尝试如下操作 instantiate float array float fArray sizeOfIntArray step through e
  • 阅读 SICP 时使用什么解释器? [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我正在阅读 SICP 书 网址为http mitpress mit edu sicp 要运行示例代码 我应该使用哪个解释器 我考虑过 Eclipse 的 Dandelion Lisp
  • 修改j2me midlet

    我想更改开源应用程序中的一些字符串 测试目的 所以我使用 jad 反编译器反编译我的应用程序 原始类文件http dl dropbox com u 32657135 YourTube class 发出命令Jad exe Yourtube j
  • 具有多个规则的 jQuery 表单验证插件

    我正在使用 jQueryValidation 插件 Problem 我想在一个输入字段中使用多个模式规则 例如 form validate rules email required true email true password requ
  • 每季度生成日期序列

    我想生成一个日期序列one quarter间隔 具有开始日期和结束日期 我有以下代码 gt seq as Date 1980 12 31 as Date 1985 06 30 by quarter 1 1980 12 31 1981 03
  • 在手机间隙运行 https 请求

    我正在iPhone中开发phone gap应用程序 我想使用JQuery getJSON url function 访问https json 请求 但仅在应用程序中它不会返回任何内容 但在正常的移动Safari中它工作正常 尽管它在phon
  • 如何使用 watchOS 2 SDK 构建应用程序

    在上次提交申请时 我们收到了此警告 WatchKit 支持无效 从 2018 年 4 月 1 日开始 提交到 Apple Watch App Store 的所有应用程序都必须使用 watchOS 2 SDK 或更高版本构建 检查您的部署目标
  • 仅沿第三维在 3D 逻辑数组中使用 Matlab“查找”

    我有一个 3D 逻辑数组 例如 A randi 0 1 x y z 其中 x y z 是整数 有没有办法找到每个 x y 沿第三维 z 的第一个真值 我可以像这样循环执行 B zeros x y for ix 1 x for iy 1 y
  • 如何将自定义ListAdapter设置为appwidget中的列表视图?

    我有一个列表视图 我需要为每个列表项提供一个自定义视图 因此我创建了一个自定义 ListAdapter 它提供了视图和布局 如下所示 但是如何使用 RemoteViews 将这个 listAdapter 设置为小部件中的 ListView
  • 程序集编号转 ascii

    我正在使用 intel 上的 at t 语法来处理汇编程序 我迷路了 如何将寄存器中的整数转换为 ASCII 数字 假设我想转换数字 10 我会将数字 10 放入寄存器 eax 中 如果我只是将数字 48 添加到 eax ascii 符号将
  • ZipArchive::close():读取错误:是一个目录

    我试图找出这个问题 但我无法想象为什么它一直发生 我正在将文件添加到 ZipArchive 当我尝试关闭它时 它收到目标是目录的错误 但我很确定事实并非如此 这是 zip 函数的代码 function create zip folder d
  • 打算打开Goog​​le身份验证器

    有没有办法通过 Intent 打开 Google Authenticator 如果是 是否可以使用已填充的密钥来打开它 以使其对用户实用 我有一个更通用的代码 因此 您只需将包名称作为参数发送给方法openApp Context conte
  • Meteor.js 应用程序模板中的多重收益

    我在布局文件中有一个用于iron router的通用 gt yield 它渲染我的页面 这些页面是模板 在我的一个页面中 我有一个侧面菜单 根据此菜单中的选择 我想在此页面中加载与此页面相关的不同模板 我怎样才能实现这个目标 我用iron
  • 使用 Matplotlib 绘制字典中的日期和关联值

    我有一本包含 Python 实例的字典datetime date和相关的数值 整数 类似这样的东西 但当然要大得多 datetime date 2016 5 31 27 datetime date 2016 9 1 87 我正在尝试使用 M
  • Jackson 动态更改 JsonIgnore

    我有一个类 里面也有变量 有时我想忽略某些字段 有时在反序列化时不想忽略 也许也在序列化时 我怎样才能在杰克逊做到这一点 对于序列化 过滤属性 博客文章应该有所帮助 反序列化方面的支持较少 因为更常见的是想要过滤掉写入的内容 一种可能的方法
  • 列表视图的自定义滚动条

    I have a task to create a custom scrollbar for list view and to my knowledge the way you can customize your scrollbar is
  • 解决 MySQL“无法重新打开表”错误

    我目前正忙于实现一个过滤器 我需要为每个要过滤的 标签 生成一个 INNER JOIN 子句 问题是 在执行完一大堆 SQL 之后 我有一个表 其中包含进行选择所需的所有信息 但对于每个生成的 INNER JOIN 我再次需要它 这基本上看
  • 如何为气泡设置边界并根据命令触发移动?

    我在 D3 中有一个气泡图 我用它来显示每组有多少个气泡 这个版本一开始有大约 500 个气泡 我的完整版本有大约 3 000 个 我在二维中挣扎 我试图让气泡在不在状态之间转换时保持原状 并且我还试图让气泡创建矩形形状 这是一个demo的