绘图链接不会影响力向图的物理

时间:2018-08-06 10:09:58

标签: javascript d3.js

我需要在力导向图中的节点之间绘制一些链接,但我希望这些链接不影响图的物理性质。还有其他可以影响物理的链接。

在所附的示例中,我想绘制定义为“ links2”的链接,但仅“遵循”该图的其余部分的布局。我希望这些线可以作为模拟的一部分进行动画处理,但不影响最终图形。

我已经手动绘制了最终结果的样子。

Manually drawn desired result

我不知道如何单独引用属于力布局的节点。

  var nodes = [
    { name: "node0" },
    { name: "node1" },
    { name: "node2" },
    { name: "node3" },
    { name: "node4" },
    { name: "node5" },
    { name: "node6" },
    { name: "node7" },
    { name: "node8" },
    { name: "node9" },
    { name: "node10" },
    { name: "node11" },
    { name: "node12" },
    { name: "node13" },
    { name: "node14" },
    { name: "node15" },
    { name: "node16" },
    { name: "node17" },
    { name: "node18" },
    { name: "node19" }
  ];

  var links = [
    { source: 0, target: 9 },
    { source: 1, target: 9 },
    { source: 2, target: 9 },
    { source: 3, target: 9 },
    { source: 4, target: 9 },
    { source: 5, target: 9 },
    { source: 6, target: 9 },
    { source: 7, target: 9 },
    { source: 8, target: 9 },
    { source: 10, target: 19 },
    { source: 11, target: 19 },
    { source: 12, target: 19 },
    { source: 13, target: 19 },
    { source: 14, target: 19 },
    { source: 15, target: 19 },
    { source: 16, target: 19 },
    { source: 17, target: 19 },
    { source: 18, target: 19 }
  ];

var links2 = [
    { source: 0, target: 10 },
    { source: 1, target: 11 },
    { source: 2, target: 12 },
    { source: 3, target: 13 }
]
  
  var width = 700;
  var height = 300;

  var force = d3.layout.force()
    .nodes(nodes)
    .links(links)
    .size([width, height])
    .linkDistance(50)
    .charge(-700)
    .on("tick", tick)
    .start();

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

  var colors = d3.scale.category10();

  var line = svg.append("g").selectAll("line")
    .data(force.links())
    .enter().append("line")
    .attr('class', 'link')
    .attr('stroke', function(d, i) {
      return colors(i);
    })

  var circle = svg.append("g").selectAll("circle")
    .data(force.nodes())
    .enter().append("circle")
    .attr("r", 8)
    .attr('class', 'circle')
    .attr('fill', function(d, i) {
      return colors(i);
    })
    .call(force.drag);

  var text = svg.append("g").selectAll("text")
    .data(force.nodes())
    .enter().append("text")
    .attr("x", 14)
    .attr("y", ".31em")
    .text(function(d) {
      return d.name;
    });

  function tick() {
    line.attr({
      x1: function(d) {
        return d.source.x;
      },
      y1: function(d) {
        return d.source.y;
      },
      x2: function(d) {
        return d.target.x;
      },
      y2: function(d) {
        return d.target.y;
      }
    });
    circle.attr("transform", transform);
    text.attr("transform", transform);
  }

  function transform(d) {
    return "translate(" + d.x + "," + d.y + ")";
  }
  .link {
    fill: none;
    stroke-width: 1.5px;
  }
  
  circle {
    stroke: black;
    stroke-width: 1.5px;
  }
  
  text {
    font: 10px sans-serif;
    pointer-events: none;
  }
  
  #graph {
    position: absolute;
    top: 0px;
    left: 0px;
  }
<script src="https://d3js.org/d3.v3.min.js"></script>
<!DOCTYPE html>
<meta charset="utf-8">
<body>
  <div id="root">
    <div style="background-color:lightgrey" id="graph" height="800px" width="800px">
    </div>
  </div>
</body>

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

您的link2通过索引引用节点,因此在对勾中使用该索引在节点数组中进行索引。最好对不同类型的链接和节点使用类。

与强制无关的链接带有破折号。

var nodes = [
  { name: "node0" },
  { name: "node1" },
  { name: "node2" },
  { name: "node3" },
  { name: "node4" },
  { name: "node5" },
  { name: "node6" },
  { name: "node7" },
  { name: "node8" },
  { name: "node9" },
  { name: "node10" },
  { name: "node11" },
  { name: "node12" },
  { name: "node13" },
  { name: "node14" },
  { name: "node15" },
  { name: "node16" },
  { name: "node17" },
  { name: "node18" },
  { name: "node19" }
];

var links = [
  { source: 0, target: 9 },
  { source: 1, target: 9 },
  { source: 2, target: 9 },
  { source: 3, target: 9 },
  { source: 4, target: 9 },
  { source: 5, target: 9 },
  { source: 6, target: 9 },
  { source: 7, target: 9 },
  { source: 8, target: 9 },
  { source: 10, target: 19 },
  { source: 11, target: 19 },
  { source: 12, target: 19 },
  { source: 13, target: 19 },
  { source: 14, target: 19 },
  { source: 15, target: 19 },
  { source: 16, target: 19 },
  { source: 17, target: 19 },
  { source: 18, target: 19 }
];

var links2 = [
    { source: 0, target: 10 },
    { source: 1, target: 11 },
    { source: 2, target: 12 },
    { source: 3, target: 13 }
]

var width = 700;
var height = 300;

var force = d3.layout.force()
  .nodes(nodes)
  .links(links)
  .size([width, height])
  .linkDistance(50)
  .charge(-700)
  .on("tick", tick)
  .start();

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

var colors = d3.scale.category10();

var line = svg.append("g").selectAll(".link")
  .data(force.links())
  .enter().append("line")
  .attr('class', 'link')
  .attr('stroke', function(d, i) { return colors(i); });

var line2 = svg.append("g").selectAll(".link2")
  .data(links2)
  .enter().append("line")
  .attr('class', 'link2')
  .attr('stroke-dasharray', '5,5')
  .attr('stroke', function(d, i) { return colors(i); });

var circle = svg.append("g").selectAll(".circle")
  .data(force.nodes())
  .enter().append("circle")
  .attr("r", 8)
  .attr('class', 'circle')
  .attr('fill', function(d, i) {
    return colors(i);
  })
  .call(force.drag);

var text = svg.append("g").selectAll("text")
  .data(force.nodes())
  .enter().append("text")
  .attr("x", 14)
  .attr("y", ".31em")
  .text(function(d) {
    return d.name;
  });

function tick() {
  line.attr({
    x1: function(d) { return d.source.x; },
    y1: function(d) { return d.source.y; },
    x2: function(d) { return d.target.x; },
    y2: function(d) { return d.target.y; }
  });
  line2.attr({
    x1: function(d) { return nodes[d.source].x; },
    y1: function(d) { return nodes[d.source].y; },
    x2: function(d) { return nodes[d.target].x; },
    y2: function(d) { return nodes[d.target].y; }
  });
  circle.attr("transform", transform);
  text.attr("transform", transform);
}

function transform(d) {
  return "translate(" + d.x + "," + d.y + ")";
}
.link {
    fill: none;
    stroke-width: 1.5px;
  }
  
  circle {
    stroke: black;
    stroke-width: 1.5px;
  }
  
  text {
    font: 10px sans-serif;
    pointer-events: none;
  }
  
  #graph {
    position: absolute;
    top: 0px;
    left: 0px;
  }
<script src="https://d3js.org/d3.v3.min.js"></script>
<!DOCTYPE html>
<meta charset="utf-8">
<body>
  <div id="root">
    <div style="background-color:lightgrey" id="graph" height="800px" width="800px">
    </div>
  </div>
</body>