简体   繁体   English

d3.js-强制布局和节点位置

[英]d3.js - Force Layout and Node Positions

I forked and modified following JSfiddle . 我在JSfiddle之后进行了分叉和修改。 Here's the js-code 这是js代码

var graph = {
  "nodes": [{
    "name": "a",
    "group": 1
  }, {
    "name": "a",
    "group": 1
  }, {
    "name": "a",
    "group": 1
  }, {
    "name": "a",
    "group": 1
  }, {
    "name": "b",
    "group": 8
  }],
  "links": [{
    "source": 1,
    "target": 0,
    "value": 1
  }, {
    "source": 2,
    "target": 0,
    "value": 1
  }, {
    "source": 3,
    "target": 0,
    "value": 1
  }, {
    "source": 4,
    "target": 0,
    "value": 1
  }]
};
var width = 600,
  height = 600;

var color = d3.scale.category20();

var force = d3.layout.force()
  .charge(-120)
  .linkDistance(30)
  .size([width, height]);

var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height);

var drawGraph = function(graph) {
  force
    .nodes(graph.nodes)
    .links(graph.links)
    .start();

  var link = svg.selectAll(".link")
    .data(graph.links)
    .enter().append("line")
    .attr("class", "link")
    .style("stroke-width", function(d) {
      return Math.sqrt(d.value);
    });

  var gnodes = svg.selectAll('g.gnode')
    .data(graph.nodes)
    .enter()
    .append('g')
    .classed('gnode', true)
    .call(force.drag);

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

  node.append("title")
    .text(function(d) {
      return d.name;
    });

  var labels = gnodes.append("text")
    .text(function(d) {
      return d.name;
    })
    .attr('text-anchor', 'middle')
    .attr('font-size', 12.0)
    .attr('font-weight', 'bold')
    .attr('y', 2.5)
    .attr('fill', d3.rgb(50, 50, 50))
    .attr('class', 'node-label')
    .append("svg:title")
    .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;
      })
      .each(function(d) {
        console.log(Math.sqrt((d.source.x - d.target.x) * (d.source.x - d.target.x) + (d.source.y - d.target.y) * (d.source.y - d.target.y)));
      });

    gnodes.attr("transform", function(d) {
      return 'translate(' + [d.x, d.y] + ')';
    });
  });
};

drawGraph(graph);

Now here's my question: 现在这是我的问题:

(How) Is it possible to get and extract the node's positions after the Force-Directed Algorithm finished rendering? (如何)在力导向算法完成渲染之后是否可以获取和提取节点的位置? I need to save the node positions in a JSON to work with a pre-rendered svg graph in another framework. 我需要将节点位置保存在JSON中,以便在另一个框架中使用预渲染的svg图。 The best would be to have normalized position values, based on a canvas size 600*600 最好是基于画布尺寸600 * 600获得标准化的位置值

Thanks for your help! 谢谢你的帮助!

You can use end event of force which is triggered after all calculations are done. 您可以使用在所有计算完成后触发的force end事件。 After that you can get nodes via var nodes = force.nodes() and manipulate with them as you want. 之后,您可以通过var nodes = force.nodes()获取节点,并根据需要对其进行操作。

Here the fiddle - open your console, and after all calculation are done it should show nodes with positions. 这里的小提琴 -打开控制台,完成所有计算后,它应该显示带有位置的节点。

Please note that it will trigger after every manipulation, you should add some flag to not trigger this callback every time if you want. 请注意,它将在每次操作后触发,如果需要,您应该添加一些标志以使每次都不触发此回调。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM