layout - D3 : Multiple force layouts in one SVG?

标签 layout d3.js force-layout

我已经看到了在单个页面上创建多个强制布局的解决方案,其中每个布局都包含在其自己的SVG中。但是,我一直无法找到有关如何在单个SVG中包括多个力布局的帮助。每个布局都有自己的数据与之关联。

可以在http://jsfiddle.net/connorgr/SRAJa/中找到我当前正在做的示例。我已经在下面的代码中包含了关键部分。最终结果看起来非常糟糕,就像除了最后一个节点/链接数据外,其他所有元素都未激活(或删除)强制布局。有什么办法可以防止这种情况的发生?

由于要建立可视化的用例,我无法将数据合并在一起,只能使用一种布局。

/**
  * Creates a force layout in svgObj for each element in graphs
  * (svg) svgObj - The SVG to include the force layouts in
  * (json) graphs - An array of {"nodes":[...],"links":[...]} objects
  */
function generateMultiForce(svgObj, graphs) {
  for(var i=0; i < graphs.length; i++) {
    var graph = graphs[i];

    var graphArea = svgObj.append("g");

    var force = d3.layout.force()
        .charge(-200)
        .linkDistance(45)
        .size([width, height])
        .nodes(graph.nodes)
        .links(graph.links)
        .start();

    var link = graphArea.selectAll(".link")
        .data(graph.links)
        .enter().append("line")
          .attr("class", "link");

    var nodeGroup = graphArea.selectAll("g")
        .data(graph.nodes)
        .enter().append("g")
        .call(force.drag);

    var node = nodeGroup.append("circle")
        .attr("class", "node")
        .attr("r", 5)
        .style("fill", function(d) {
          return color(d.group); });

    var text = nodeGroup.append("text")
        .attr("x", 8)
        .attr("y", ".31em")
        .text(function(d) { return d.name; });

    force.on("tick", function() {
      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; });

      nodeGroup.attr("transform", function(d) {
          return "translate("+d.x+","+d.y+")";
        });
    });
  }
}

最佳答案

以下方法将力,节点和链接数据限制到其相应的力导向布局。这样,您可以在同一个SVG中添加任意数量的布局,而不会引起节点间干扰。每个布局可以单独设置格式。如果您确实希望布局彼此影响,则可以编辑它们各自的刻度功能。

function layout1(inputNodes, inputLinks) {
   var force = d3.layout.force();
   var nodes = force.nodes();
   var links = force.links();

   var update = function() {
      //append nodes and links from data

      force.on("tick",function(e){
         //tick movement

      }
   }
   for(var i=0; i<inputNodes.length; i++){
      nodes.push(inputNodes[i]);
   }
   for(var i=0; i<inputLinks.length; i++){
      links.push(inputLinks[i]);
   }
   update();
}

现在,第二个受力引导的布局可以具有相同的结构,并且也具有相同的变量名称:
function layout2(inputNodes, inputLinks) {
   var force = d3.layout.force();
   var nodes = force.nodes();
   var links = force.links();

   var update = function() {
      //append nodes and links from data

      force.on("tick",function(e){
         //tick movement

      }
   }
   for(var i=0; i<inputNodes.length; i++){
      nodes.push(inputNodes[i]);
   }
   for(var i=0; i<inputLinks.length; i++){
      links.push(inputLinks[i]);
   }
   update();
}

最后用任何数据实例化:
var layout1 = new layout1(inputNodes, inputLinks);
var layout2 = new layout2(inputNodes, inputLinks);

可以采用此方法动态创建多个布局。希望这接近您要寻找的东西。

关于layout - D3 : Multiple force layouts in one SVG?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16319199/

相关文章:

javascript - D3 力定向图 - 删除节点

安卓 - java.lang.UnsupportedOperationException : Can't convert to dimension: type=0x12

javascript - NVD3.js 将悬停/单击事件绑定(bind)到 xAxis 刻度 <line>

css - SVG 未在 Google map 的可见区域之外绘制

d3.js - ReactJS + d3JS 组件中 d3.event 为 null

javascript - 如何在力导向图中禁用动画?

javascript - D3 : move circle between two different g elements in force layout

layout - Latex:填充到一定宽度

安卓布局 : Why is my button always UNDERNEATH the ListView?

ios - 如何为 AVPlayerViewController 设置布局约束?