【问题标题】:D3: Using node attribute for links instead of index in arrayD3:对链接使用节点属性而不是数组中的索引
【发布时间】:2013-05-29 21:37:48
【问题描述】:

我是从事网络可视化工作的 D3.js 初学者,但我不知道如何正确指定我的力布局链接。问题在于,默认情况下,d3 将链接的“源”和“目标”解释为“节点”数组中节点的索引。但是,在我的数据中,源和目标是指节点的 ID 号,我存储在节点属性中。如何让链接指向node.id 而不是node.index?这是我想我应该这样做的地方:

var nodes = data.nodes;
var edges = data.edges;
var force = d3.layout.force()
            .nodes(d3.values(nodes))
            .links(edges)
            .size([w, h])
            .linkDistance(80)
            .charge(-500)
            .gravity(0.2)
            .on("tick", tick)
            .start();

...但我不确定我是否应该修改.nodes() 部分或.links() 部分。我尝试在它之前添加它:

var nodes = data.nodes;
for (var i = 0; i < nodes.length; i++) {
    nodes[i].index = nodes[i].id;
    console.log(i + " " + nodes[i].index + " " + nodes[i].id);
}

...但是当我创建力时,index 属性会被覆盖。

我阅读了this 的问题,但那里唯一的答案似乎有点不合时宜。他们还提到了“数据键”,但我在这些方面找不到太多信息,而且我不知道如何合并它们,因为我实际上并没有使用 enter() 函数。

【问题讨论】:

    标签: d3.js force-layout


    【解决方案1】:

    我不认为您可以强制 D3 使用属性 node.id 作为索引,但您可以处理链接以获得正确的引用:

    var edges = [];
    
    data.edges.forEach(function(e) { 
        // Get the source and target nodes
        var sourceNode = data.nodes.filter(function(n) { return n.id === e.source; })[0],
            targetNode = data.nodes.filter(function(n) { return n.id === e.target; })[0];
    
        // Add the edge to the array
        edges.push({source: sourceNode, target: targetNode});
    });
    
    var force = d3.layout.force()
        .nodes(data.nodes)
        .links(edges)
        // the rest of your code here
        .start();
    

    如果设置了强制布局会覆盖索引,但会保留链接中每个节点的源和目标的引用。

    【讨论】:

    • 这不起作用......“假设节点对象中的键是 id”是什么意思? data.nodes[] 不只是通过数组索引访问节点,而我应该以某种方式通过 id 来访问节点吗?
    • 是的,很抱歉,我对您的数据结构做出了错误的假设。我相应地更新了代码。
    • 好的,谢谢,这行得通!我还有一个边缘的type 属性,所以当我推动每个边缘时,我必须添加它,即edges.push({source: sourceNode, target: targetNode, type: e.type})
    • data.nodes.filter(function(n) { return n.id === e.source; })[0] 返回了什么?对原始节点数组中的对象的引用?您不应该只能指定对力布局图中存在的节点的引用吗?即,sourceNodetargetNode 可以是以下行中的对象似乎很奇怪:edges.push({source: sourceNode, target: targetNode});
    • 哦,我想这是可能的,因为最终 DOM 元素只是简单地绑定到节点数组中的相同节点对象。对吗?
    猜你喜欢
    • 1970-01-01
    • 2014-07-22
    • 2015-06-23
    • 2012-10-31
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 2019-09-04
    相关资源
    最近更新 更多