自动生成链接在d3强制布局

automatically generating links in d3 force layout

本文关键字:布局 d3 链接 自动生成      更新时间:2023-09-26

使用D3.js的强制布局,我试图使链接根据节点数据自动生成。节点已经完全按照预期出现。

数据库json字符串使用以下格式:

{
 "id": 1,
 "title": "name"
}, 
{
 "id": 2,
 "title": "other name",
 "primaryDependants": 1
}

我基本上是想让它说:

'对于每个节点,检查它是否有primaryDependant属性,如果有,则在该节点和标识为主依赖的节点之间建立链接。'

然而,我以前没有处理过力图,教程很少,所以我真的很纠结如何在不破坏代码的情况下对代码进行任何更改。目前它是基于这里的答案,我使用流星框架,如果这是任何相关的。

Template.tree.rendered = function () {
  var graph = new myGraph("#svgdiv");
  Lessons.find().observe({ 
    added: function (doc) { 
      graph.addNode(doc._id, doc.title); 
    },
    removed: function (doc) { 
      graph.removeNode(doc._id); 
    }
  });
function myGraph(el) { 
  w = 1500,
  h = 1000; 
  var svg = d3.select(el) 
    .append("svg") 
    .attr("width", w)
    .attr("height", h)
    .attr("pointer-events", "all") 
    svg.append("rect") 
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("fill", "lightgrey");
  var vis = svg.append('g'); 
  var force2 = d3.layout.force(); 
  var links = force2.links(); 
  var nodes = force2.nodes(); 
  var update = function () { 
    var link = vis.selectAll("line") 
      .data(links, function(d) {return d.source.id + "-" + d.target.id;}); 
    link.enter().append("line") 
      .attr("id",function(d){return d.source.id + "-" + d.target.id;}) 
      .attr("class","link"); 
    link.append("title") 
    .text(function(d){
      return d.value;
    });
    link.exit().remove();
    var node = vis.selectAll("g") 
      .data(nodes, function(d) { return d.id;}); 
    var nodeEnter = node.enter() 
      .append("g") 
        .call(force2.drag)
      .append("circle") 
        .attr("r", 8)
        .attr("fill", "#585858")
        .attr("stroke", "#008db7")
        .attr("stroke-width", 3)
        .attr("id", function(e) { return "Node;"+e.id;})
        .attr("class", ( function(f){return f.id;}));
    node.exit().remove(); 
    force2.on("tick", function() { 
      node.attr("transform", function(g) { return "translate(" + g.x + "," + g.y + ")"; }); 
      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; });
    });
    force2 
      .gravity(.02)
      .linkDistance( 200 ) 
      .size([w, h])
      .start();
  };
  update(); 
  var findNode = function(id) { 
    for (var i in nodes) {
      if (nodes[i]["id"] === id) return nodes[i];};
  };
  var findNodeIndex = function(id) { 
    for (var i=0;i<nodes.length;i++) {
      if (nodes[i].id==id){
        return i;
      }
    };
  };
  this.addNode = function (id, title) { 
    nodes.push({"id":id,"title":title});
    update(); 
  };
  this.addLink = function (source, target, value) {
    links.push({"source":findNode(source),"target":findNode(target),"value":value});
    update();
  }; 
  this.removeNode = function (id) { 
    var i = 0;
    var n = findNode(id);
    nodes.splice(findNodeIndex(id),1); 
    update(); 
  };
}

根据描述创建links数组:

var dataset = [{
 "id": 1,
 "title": "name"
}, 
{
 "id": 2,
 "title": "other name",
 "primaryDependants": 1
}];
var links = [];
dataset.forEach(function(d){
  if(d.primaryDependants){
    links.push({source: d.id,
                target: d.primaryDependants});
    }});
console.log(links)