javascript - 在 d3 force layout 中自动生成链接

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

最佳答案

根据您的描述创建 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)

关于javascript - 在 d3 force layout 中自动生成链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40373084/

相关文章:

javascript - 如何访问使用 LINK 标签加载的第 3 方样式表的源代码?

javascript - 是否有任何简写方法将以标题作为第一个数组的字符串数组转换为数组对象?

json - 纯文本到 json 格式转换成 sublime 文本

javascript - Meteor js,如何获得更新整个客户端文档的副作用

javascript - 如何使用meteor.js监控浏览器中的数据传输?

javascript - Nette - 片段更新

javascript - 继续执行脚本之前等待 AJAX 响应

php - 如何在 PHP 中从查询创建 JSON

javascript - 如何在更新 mongo 文档时使用变量?

javascript - Node.JS + mySQL -> 如何进行ajax调用并访问server.js上的数据?