如何添加节点和链接而不输入d3力

我正在尝试更新节点和链接,但不想使用d3的enter模式。原因是我想要苗条的框架来做这件事以及处理所有渲染,我只想使用d3-force进行计算。

我使初始渲染工作正常,但是添加链接和节点存在以下问题:

  1. 添加链接使网络不断发展
  2. 链接似乎对图形布局没有任何影响,即它们似乎未添加到force.simulation
  3. 首先添加节点似乎可行,但是在添加链接后添加节点时,它们似乎并没有对其他节点施加压力。

这是我添加节点和链接的功能:

function addNode(){
    force.forceSimulation(data.nodes.push({"id": "116","group": 5,"index":data.nodes.length,"x":0,"y":0,"vx":0,"vy":0}))
    data=data
    graph.alpha(1.0).update()
    graph.restart()

}

function addLink(){
    let n=getRandomInt(0,data.nodes.length-1)
    let tn=getRandomInt(0,n)
    let sn=getRandomInt(n,data.nodes.length-1)

    graph.force("link",force.forceLink(data.links.push({'source':data.nodes[sn],'target':data.nodes[tn],'index':data.links.length,'value':getRandomInt(1,7)})))

    data=data

    graph.alpha(1.0).update()
    graph.restart()
}

我找到了this答案,但是他们使用merge并将其绑定到DOM元素。我不明白如何在不涉及DOM的情况下如何做到这一点,只是更新了javascript中的节点和链接数组,以使其在仿真中将d3力包括在内。

Here我在一个简化的REPL中拥有当前的模拟,您可以对其进行分叉和编辑。

s5705219 回答:如何添加节点和链接而不输入d3力

幸运的是,将d3力布局与DOM解除关联非常容易:力布局本身与DOM没有交互,它只是基于某些数据属性的物理计算。虽然添加和删除数据点(节点/链接)可能会有些棘手,但是无论D3是否渲染DOM,其他是否渲染还是完全不渲染力都相同。

在此处添加链接和节点:

function addNode(){
    force.forceSimulation(data.nodes.push({"id": "116","group": 5,"index":data.nodes.length,"x":0,"y":0,"vx":0,"vy":0}))
    data=data
    graph.alpha(1.0).update()
    graph.restart()
}

function addLink(){
    let n=getRandomInt(0,data.nodes.length-1)
    let tn=getRandomInt(0,n)
    let sn=getRandomInt(n,data.nodes.length-1)

    graph.force("link",force.forceLink(data.links.push({'source':data.nodes[sn],'target':data.nodes[tn],'index':data.links.length,'value':getRandomInt(1,7)})))

    data=data

    graph.alpha(1.0).update()
    graph.restart()
}

这里有几个问题:

  1. Array.push()不返回数组。它在适当的位置修改数组,在推送项目后返回数组的长度。这意味着您实际上并没有在力布局中添加节点。这将导致问题,因为强制布局需要对象而不是基元来表示节点。相反,只需推送节点/链接,然后将节点/链接数组传递到.nodes()或.links()

  2. force.forceSimulation()将创建一个新的强制布局生成器,这不是您想要的。您希望将节点添加到现有节点,因此我们可以改用graph.nodes()

  3. 没有force.update(),这会导致错误,因此,一旦冷却完成,您将无法重新启动模拟。我们可以删除这部分。

让我们看一下这两个函数的纠正效果:

function addNode(){
    data.nodes.push({"id": "116","vy":0})
    graph.nodes(data.nodes)
    data=data
    graph.alpha(1.0).restart()

}

function addLink(){
    let n=getRandomInt(0,data.nodes.length-1)

  data.links.push({'source':data.nodes[sn],7)})
    graph.force("link",force.forceLink(data.links))
    data=data
    graph.alpha(1.0).restart()

}

我不确定您为什么拥有data=data,没有它我看不出有什么不同,我会静静地认为这是框架的怪癖


一种更新链接的小方法:

您可以使用以下名称来访问已命名为“链接”的部队,并为其分配新的链接:

graph.force("link").links(data.links)

而不是:

graph.force("link",force.forceLink(data.links))

后者重现了力量,而前者只是对其进行了修改。

本文链接:https://www.f2er.com/3152942.html

大家都在问