草庐IT

javascript - D3.js 版本 4 使节点具有粘性

coder 2025-01-27 原文

我是 D3 版本 4 的新用户,我在将固定节点功能添加到力导向布局时遇到问题。我相信这是通过将 d.fixed 设置为 true 在 v3 中实现的,但是我在将其转换为与 v4 兼容的内容时遇到了问题。我试过添加 simulation.fix,但如果不从模拟开始就修复节点,就无法将它集成到我现有的代码中。

理想情况下,我想添加一个双击监听器,将节点固定到位,并允许通过拖动功能对其进行定位,然后在再次双击时恢复模拟力。预先感谢您的帮助。

这是我的js:

<!--load svg-->
<svg width="1500" height="600"></svg>
 <!--begin javascript for d3 forced layout-->
<script>
var svgNetwork = d3.select("svg"),
    width = +svgNetwork.attr("width"),
    height = +svgNetwork.attr("height");


var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(data1) { return data1.id; }))
    .force("charge", d3.forceManyBody().strength(-1500))
    .force("center", d3.forceCenter(width / 2, height / 2));



//load  the node csv data and link csv data together - open node(open link(funtions for making chart))
d3.csv("nodes.csv", function (error1, data1) {
    if (error1) throw error1;
    console.log(data1);

    d3.csv("lines.csv", function (error2, data2) {
        if (error2) throw error2;
        console.log(data2);

        data1.forEach(function (data1){
            data1.group = +data1.group;
        });

        var lower = d3.min(data1, function(data1) {return data1.group;});
        var upper = d3.max(data1, function(data1) {return data1.group;});
        var color = d3.scaleLinear()
            .domain([lower, 0, upper])
            .range(["#2E64FE", "#E6E6E6", "red"]);


        var link = svgNetwork.append("g")
            .attr("class", "links")
            .selectAll("line")
            .data(data2)
            .enter()
                .append("line")
                .attr("stroke-width", function(data2) { return Math.sqrt(data2.value); })
            .attr("fill", "#777")
            .attr("stroke-opacity", "0.6");

    var node = svgNetwork.selectAll(".node")
         .data(data1)
             .enter()
                 .append("g");

        var circle = node.append("circle")
            .attr("id", function(data1) {return data1.id;})
            .attr("r", function(data1) {return data1.rad;})
            .attr("fill", function(data1) { return color(data1.group); })
            .style("stroke", function(data1) { return color(data1.group); })
            .style("stroke-width", "10px")
            .style("stroke-opacity", "0.9");    

        var label = node.append("svg:text")
            .text(function (data1) { return data1.id; })
            .style("text-anchor", "middle")
            .style("fill", "#000000")
            .style("font-family", "Arial")
            .style("font-size", "0.8em")
            .style("font-weight", "bold");

   node.call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended));


  simulation
      .nodes(data1)
      .on("tick", ticked);
  simulation.force("link")
      .links(data2);

  function ticked() {
    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", function(d) { return "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;
}

这是我的 node.csv 文件和 lines.csv 文件的示例:

节点.csv

id  group   rad
a   0.168316947 0.288907878
b   -0.38499088 1.012210504
c   -0.548386797    1.301376974
d   -0.215565786    2.456429671
e   -0.756094177    6.409396582
f   -0.538867892    1.804950731
g   -0.325232806    0.518895927
h   0.686157994 1.011850971
i   -0.723155438    5.853700074
j   2.008089674 2.73207752
k   -0.358621917    2.040722107
l   -0.393305984    3.221637083
m   -0.676289998    1.598250699
n   -0.950808451    26.26021586
o   0.134589658 0.270633823
p   -0.521333199    6.216421369
q   1.628300116 2.293471337
r   0.62673 2
s   -0.843711093    40.86067523

线条.csv

source  target  value
b   a   20
c   a   20
d   a   20
e   a   20
f   a   20
g   a   20
h   a   20
i   a   20
j   a   20
k   a   20
l   a   20
m   a   20
n   a   20
o   a   20
p   a   20
q   a   20
r   a   20
s   a   20

最佳答案

不确定是否需要答案,但我能够使节点具有粘性,实际上它是您代码中的一个非常简单的修复,我在 GitHub 上查看此问题时了解到它 - Issue #35

现在在 d3 库的 v4 中修复节点的想法非常简单,在您上面的代码中只需注释以下两行:

function dragended(d) {
  if (!d3.event.active) simulation.alphaTarget(0);
  //d.fx = null;
  //d.fy = null;
}

理论是,要修复节点,我们需要设置 node.fxnode.fy,您的代码实际上是在 dragged()<> 函数定义。

希望对我有所帮助,就像对我一样。

此处的文档中也提到了同样的内容 - D3 V4 - API

To fix a node in a given position, you may specify two additional properties:

  • fx - the node’s fixed x-position
  • fy - the node’s fixed y-position

关于javascript - D3.js 版本 4 使节点具有粘性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39168274/

有关javascript - D3.js 版本 4 使节点具有粘性的更多相关文章

  1. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  2. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  3. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  4. ruby-on-rails - 如果我将 ruby​​ 版本 2.5.1 与 rails 版本 2.3.18 一起使用会怎样? - 2

    如果我使用ruby​​版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby​​1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更

  5. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  6. ruby-on-rails - Rails 3.1 中具有相同形式的多个模型? - 2

    我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#

  7. ruby-on-rails - 如何在发布新的 Ruby 或 Rails 版本时收到通知? - 2

    有人知道在发布新版本的Ruby和Rails时收到电子邮件的方法吗?他们有邮件列表,RubyonRails有一个推特,但我不想听到那些随之而来的喧嚣,我只想知道什么时候发布新版本,尤其是那些有安全修复的版本。 最佳答案 从therailsblog获取提要.http://weblog.rubyonrails.org/feed/atom.xml 关于ruby-on-rails-如何在发布新的Ruby或Rails版本时收到通知?,我们在StackOverflow上找到一个类似的问题:

  8. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  9. ruby - 具有两个参数的 block - 2

    我从用户Hirolau那里找到了这段代码:defsum_to_n?(a,n)a.combination(2).find{|x,y|x+y==n}enda=[1,2,3,4,5]sum_to_n?(a,9)#=>[4,5]sum_to_n?(a,11)#=>nil我如何知道何时可以将两个参数发送到预定义方法(如find)?我不清楚,因为有时它不起作用。这是重新定义的东西吗? 最佳答案 如果您查看Enumerable#find的文档,您会发现它只接受一个block参数。您可以将它发送两次的原因是因为Ruby可以方便地让您根据它的“并行赋

  10. ruby-on-rails - 在 RSpec 中,如何以任意顺序期望具有不同参数的多条消息? - 2

    RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)

随机推荐