在 D3js Force Graph 中添加和删除节点 [英] Adding and Removing Nodes in D3js Force Graph

查看:54
本文介绍了在 D3js Force Graph 中添加和删除节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从数据库加载 json 并创建一个加载良好的 json 文件.现在我不知道要采取哪些步骤来使力导向图中的节点具有响应性.我需要删除和添加新节点及其链接.

I am loading json from database and creating a json file which loads fine. Now I don't know which steps to take for making the nodes responsive in a Force-Directed Graph. I need to remove and add new nodes and their links.

force.nodes(json.nodes)
    .links(json.links)
    .start();

initNodes(json);

如何在不重置整个可视化的情况下使其更具动态性或更新它?

How can I make this more dynamic or update it without resetting the whole visualization?

我已经多次看到这个问题没有得到回答,所以我希望有人可以发帖并提供指导.

I have seen this question a couple of times not being answered so I hope someone can post and give a guide.

推荐答案

在我更好地理解添加初始节点集的方式之前,向我的 D3 力图添加节点/链接非常令人困惑.

Adding nodes/links to my D3 force graph was very confusing until I better understood the way I was adding the initial set of nodes.

假设 <g> 是您希望用于节点的:

Assuming a <g> is what you'd like to use for your nodes:

// Select the element where you'd like to create the force layout
var el = d3.select("#svg");

// This should not select anything
el.selectAll("g")

// Because it's being compared to the data in force.nodes() 
    .data(force.nodes())

// Calling `.enter()` below returns the difference in nodes between 
// the current selection and force.nodes(). At this point, there are
// no nodes in the selection, so `.enter()` should return 
// all of the nodes in force.nodes()
    .enter()

// Create the nodes
    .append("g")
    .attr("id", d.name)
    .classed("manipulateYourNewNode", true);

现在让我们创建一个函数,在图形初始化后将一个节点添加到布局中!

Now let's make that function that will add a node to the layout once the graph has been initialized!

newNodeData 是一个对象,其中包含您希望用于新节点的数据.connectToMe 是一个字符串,其中包含您要将新节点连接到的节点的唯一 ID.

newNodeData is an object with the data you'd like to use for your new node. connectToMe is a string containing the unique id of a node you'd like to connect your new node to.

function createNode (newNodeData, connectToMe) {
    force.nodes().push(newNodeData);
    el.selectAll("g")
       .data(force.nodes(), function(datum, index) { return index })

.data() 中作为可选的第二个参数给出的函数为选择中的每个节点运行一次,并为 force.nodes() 中的每个节点运行一次,根据返回值匹配它们.如果未提供函数,则调用回退函数,该函数返回 index(如上所述).

The function given as the optional second argument in .data() is run once for each node in the selection and again for each node in force.nodes(), matching them up based on the returned value. If no function is supplied, a fallback function is invoked, which returns the index (as above).

但是,您的新选择的索引(我相信顺序是随机的)和 force.nodes() 中的顺序之间很可能会发生争议.相反,您很可能需要该函数返回每个节点唯一的属性.

However, there's most likely going to be a dispute between the index of your new selection (I believe the order is random) and the order in force.nodes(). Instead you'll most likely need the function to return a property that is unique to each node.

这一次,.enter() 将只返回您尝试添加的节点作为 newData,因为 newData 的第二个参数没有找到它的键代码>.data().

This time, .enter() will only return the node you're trying to add as newData because no key was found for it by the second argument of .data().

       .enter()
       .insert("g", "#svg")
       .attr("id", d.name)
       .classed("manipulatYourNewNode", true);

    createLink(connectToMe, newNodeData.name);

    force.start();
}

函数 createLink(定义如下)在您的新节点和您选择的节点之间创建链接.

The function createLink (defined below) creates a link between your new node and your node of choice.

此外,d3js API 声明应该在更新布局后调用 force.start().

注意:在函数的最开始调用 force.stop() 对我来说是一个巨大的帮助,当我第一次尝试弄清楚如何添加节点时并链接到我的图表.

Note: Calling force.stop() at the very beginning of my function was a huge help for me when I was first trying to figure out how to add nodes and links to my graph.

function createLink (from, to) {
    var source = d3.select( "g#" + from ).datum(),
        target = d3.select( "g#" + to ).datum(),
        newLink = {
            source: source,
            target: target,
            value: 1
        };
    force.links().push(newLink);

下面的代码在以下假设下工作:

The code below works under the assumptions that:

  1. #links 是包含所有链接元素的包装元素
  2. 您的链接表示为 元素:

  1. #links is the wrapper element that contains all of your link elements
  2. Your links are represented as <line> elements:

d3.select("#links")
    .selectAll("line")
    .data(force.links())
    .enter()
    .append("line");

这篇关于在 D3js Force Graph 中添加和删除节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆