自动生成d3强制布局中的链接

时间:2016-11-02 05:32:49

标签: javascript json meteor d3.js

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

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

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

我基本上试着说:

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

然而,我之前没有处理过强制图,而且教程很少,所以我真的在努力解决如何在不破坏代码的情况下对代码进行任何更改。目前它基于the answer here,如果有任何相关性,我会使用Meteor框架。

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(); 
  };
}

1 个答案:

答案 0 :(得分:1)

根据您的说明创建links数组:

&#13;
&#13;
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)
&#13;
&#13;
&#13;