草庐IT

javascript - 在 D3 强制布局中,在根节点周围均匀地间隔节点

coder 2024-05-16 原文

我刚刚开始使用 D3,所以如果有人对我可能没有正确/优化地做的事情有任何一般性建议,请告诉我:)

我正在尝试创建一个力导向图,其中节点围绕中心根节点(以较大的尺寸标注)均匀分布(或足够接近)。

这是我尝试实现的布局示例(我知道它不会每次都一样):

我有下图:

var width = $("#theVizness").width(),
    height = $("#theVizness").height();

var color = d3.scale.ordinal().range(["#ff0000", "#fff000", "#ff4900"]);

var force = d3.layout.force()
    .charge(-120)
    .linkDistance(30)
    .size([width, height]);

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

var loading = svg.append("text")
    .attr("class", "loading")
    .attr("x", width / 2)
    .attr("y", height / 2)
    .attr("dy", ".35em")
    .style("text-anchor", "middle")
    .text("Loading...");

/*
ForceDirectData.json
{
    "nodes":[
      {"name":"File1.exe","colorGroup":0},
      {"name":"File2.exe","colorGroup":0},
      {"name":"File3.exe","colorGroup":0},
      {"name":"File4.exe","colorGroup":0},
      {"name":"File5.exe","colorGroup":0},
      {"name":"File6.exe","colorGroup":0},
      {"name":"File7.exe","colorGroup":0},
      {"name":"File8.exe","colorGroup":0},
      {"name":"File8.exe","colorGroup":0},
      {"name":"File9.exe","colorGroup":0}
    ],
    "links":[
      {"source":1,"target":0,"value":10},
      {"source":2,"target":0,"value":35},
      {"source":3,"target":0,"value":50},
      {"source":4,"target":0,"value":50},
      {"source":5,"target":0,"value":65},
      {"source":6,"target":0,"value":65},
      {"source":7,"target":0,"value":81},
      {"source":8,"target":0,"value":98},
      {"source":9,"target":0,"value":100}
    ]
}
*/

d3.json("https://dl.dropboxusercontent.com/u/5772230/ForceDirectData.json", function (error, json) {
    var nodes = json.nodes;
    force.nodes(nodes)
        .links(json.links)
        .linkDistance(function (d) {
            return d.value * 1.5;
        })
        .charge(function(d){
            var charge = -500;
            
            if (d.index === 0) charge = 0;
            
            return charge;
        })
        .friction(0.4);
    
    var link = svg.selectAll(".link")
        .data(json.links)
        .enter().append("line")
        .attr("class", "link")              
        .style("stroke-width", 1);
    
        var files = svg.selectAll(".file")
        .data(json.nodes)
        .enter().append("circle")
        .attr("class", "file")
        .attr("r", 10)
        .attr("fill", function (d) {
            return color(d.colorGroup);
        });
    var totalNodes = files[0].length;
    
    files.append("title")
        .text(function (d) { return d.name; });
    
    force.start();
    for (var i = totalNodes * totalNodes; i > 0; --i) force.tick();

    
    nodes[0].x = width / 2;
    nodes[0].y = height / 2;
    
    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; });
    
    files.attr("cx", function (d) { return d.x; })
        .attr("cy", function (d) { return d.y; })
        .attr("class", function(d){
            var classString = "file"
            
            if (d.index === 0) classString += " rootFile";
            
            return classString;
        })
        .attr("r", function(d){
            var radius = 10;
            
            if (d.index === 0) radius = radius * 2;
            
            return radius;
        });
    force.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; });

    files.attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });
  });
    
    loading.remove();
    
  }); 

JSFiddle

我已经尝试使用 charge() 方法来接近这个。我认为给根节点以外的每个节点更高的电荷可以实现这一点,但事实并非如此。

我该怎么做才能让子节点均匀分布在根节点周围?

最佳答案

是的,强制布局是适合您这种情况的完美工具。

你只需要改变布局的一点初始化,像这样

force.nodes(nodes)
    .links(json.links)
    .charge(function(d){
        var charge = -500;
        if (d.index === 0) charge = 10 * charge;
        return charge;
    });

瞧瞧

解释。我不得不删除 frictionlinkDistance 的设置,因为它们会以不好的方式影响放置。根节点的 charge 大 10 倍,因此所有其他节点都被显性地推离根节点。其他节点也相互排斥,最终达到完美对称。

Jsfiddle 是 here .


我从您的代码中看到,您试图通过利用依赖于数据的 linkDistance 来影响与根节点和其他节点的距离。但是,为此目的使用 linkStrength 可能会更好(尽管违反直觉),就像这样

force.nodes(nodes)
    .links(json.links)
    .linkStrength(function (d) {
        return d.value / 100.0;
    })
    .charge(function(d){
        var charge = -500;
        if (d.index === 0) charge = 10 * charge;
        return charge;
    });

但您需要进行试验。


为了居中和固定根节点,你可以使用这个

nodes[0].fixed = true;
nodes[0].x = width / 2;
nodes[0].y = height / 2;

但在布局初始化之前,如 this Jsfiddle.

关于javascript - 在 D3 强制布局中,在根节点周围均匀地间隔节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29639270/

有关javascript - 在 D3 强制布局中,在根节点周围均匀地间隔节点的更多相关文章

  1. ruby - nanoc 和多种布局 - 2

    是否可以为特定(或所有)项目使用多个布局?例如,我有几个项目,我想对其应用两种不同的布局。一个是绿色的,一个是蓝色的(但是)。我想将它们编译到我的输出目录中的两个不同文件夹中(例如v1和v2)。我一直在玩弄规则和编译block,但我不知道这是怎么回事。因为,每个项目在编译过程中只编译一次,我不能告诉nanoc第一次用layout1编译,第二次用layout2编译。我试过这样的东西,但它导致输出文件损坏。compile'*'doifitem.binary?#don’tfilterbinaryitemselsefilter:erblayout'layout1'layout'layout2'

  2. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  3. ruby - 强制浏览器下载文件而不是打开文件 - 2

    我要下载http://foobar.com/song.mp3作为song.mp3,而不是让Chrome在其native中打开它浏览器中的播放器。我怎样才能做到这一点? 最佳答案 您只需要确保发送这些header:Content-Disposition:attachment;filename=song.mp3;Content-Type:application/octet-streamContent-Transfer-Encoding:binarysend_file方法为您完成:get'/:file'do|file|file=File.

  4. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  5. ruby - 强制 Ruby 不以标准形式/科学记数法/指数记数法输出 float - 2

    我遇到了同样的问题here对于python,但对于ruby​​。我需要输出这样一个小数字:0.00001,而不是1e-5。有关我的特定问题的更多信息,我正在使用f.write("Mynumber:"+small_number.to_s+"\n")输出到一个文件对于我的问题,准确性不是什么大问题,所以只做一个if语句来检查是否small_number那么更通用的方法是什么? 最佳答案 f.printf"Mynumber:%.5f\n",small_number您可以将.5(小数点右侧5位数字)替换为您喜欢的任何特定格式大小,例如,%8

  6. 区块链入门教程(6)--WeBASE-Front节点前置服务安装 - 2

    文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定

  7. ruby - 选择包含子节点内文本的父节点 - 2

    基本上我想选择一个节点(div),其中它的子节点(h1,b,h3)包含指定的文本。Childtext1Childtext2...Childtext3我期待的是/html/div/而不是/html/div/h1我在下面有这个,但不幸的是返回了child,而不是div的xpath。expression="//div[contains(text(),'Childtext1')]"doc.xpath(expression)我期待的是/html/div/而不是/html/div/h1那么有没有一种方法可以简单地使用xpath语法来做到这一点? 最佳答案

  8. ruby-on-rails - 如何在 Rails 脚手架生成器上强制使用单数表名? - 2

    我正在使用遗留数据库并需要创建一些CRUD。我如何使用scaffold生成器并告诉他表的确切名称以避免复数化过程?表格也是西类牙语。 最佳答案 您可以只使用ActiveRecord::Base.table_name=方法手动设置表名。因此,在您的模型中您可以:classOrderDetail 关于ruby-on-rails-如何在Rails脚手架生成器上强制使用单数表名?,我们在StackOverflow上找到一个类似的问题: https://stackove

  9. ruby - 强制使用特定的 gem 版本作为默认版本? - 2

    假设我安装了三个gem:package-0.4.0、package-0.5.0和package-0.5.0-jbfink(我构建了-jbfink一个,因为我对0.5做了非常小的改动.0的来源,并希望将其与官方版本区分开来)。是否有gem(或其他命令)将其设为默认值?现在我已经安装了所有三个,但我的shell正在从package-0.5.0中获取可执行文件,我宁愿它默认为0.5.0-jbfink。将0.5.0-jbfink命名为0.5.1解决了这个问题,但我不想这样做,因为我不想与正式发布的0.5.1出现冲突。 最佳答案 转到conf

  10. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

随机推荐