Skip to content

力导向图

相关函数 v5

  • d3.forceSimulation() ,新建一个力导向图,
  • d3.forceSimulation().force(),添加或者移除一个力

数据

javascript
var svg = d3.select("svg");
var g = svg.append("g");

var nodes = [{ name: "A" }, { name: "B" }];

var edges = [{ source: 0, target: 1, relation: "关系", value: 1 }];

新建一个力导向图

javascript
var forceSimulation = d3
  .forceSimulation()
  .force("link", d3.forceLink())
  .force("charge", d3.forceManyBody());

设置一个颜色比例尺

javascript
var colorScale = d3
  .scaleOrdinal()
  .domain(d3.range(nodes.length))
  .range(d3.schemeCategory10);

生成节点数据

javascript
forceSimulation.nodes(nodes).on("tick", ticked);

生成边集数据

javascript
forceSimulation
  .force("link")
  .links(edges)
  .distance(function (d) {
    return d.value * 100;
  });

设置图形中心位置

javascript
forceSimulation
  .force("center")
  .x(width / 2)
  .y(height / 2);

绘制边

javascript
var links = g
  .append("g")
  .selectAll("line")
  .data(edges)
  .enter()
  .append("line")
  .attr("stroke", function (d, i) {
    return colorScale(i);
  })
  .attr("stroke-width", 1);

绘制边上的文字

javascript
var linksText = g
  .append("g")
  .selectAll("text")
  .data(edges)
  .enter()
  .append("text")
  .text(function (d) {
    return d.relation;
  });

建立分组

javascript
var gs = g
  .selectAll(".circleText")
  .data(nodes)
  .enter()
  .append("g")
  .attr("transform", function (d, i) {
    var cirX = d.x;
    var cirY = d.y;
    return "translate(" + cirX + "," + cirY + ")";
  })
  .call(d3.drag().on("start", started).on("drag", dragged).on("end", ended));

节点和文字

javascript
gs.append("circle")
  .attr("r", 10)
  .attr("fill", function (d, i) {
    return colorScale(i);
  });
gs.append("text")
  .attr("x", -10)
  .attr("y", -20)
  .attr("dy", 10)
  .text(function (d) {
    return d.name;
  });

ticked 函数

javascript
function ticked() {
  links
    .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;
    });

  linksText
    .attr("x", function (d) {
      return (d.source.x + d.target.x) / 2;
    })
    .attr("y", function (d) {
      return (d.source.y + d.target.y) / 2;
    });

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

拖曳函数

javascript
function started(d) {
  if (!d3.event.active) {
    forceSimulation.alphaTarget(0.8).restart();
  }
  d.fx = d.x;
  d.fy = d.y;
}
function dragged(d) {
  d.fx = d3.event.x;
  d.fy = d3.event.y;
}
function ended(d) {
  if (!d3.event.active) {
    forceSimulation.alphaTarget(0);
  }
  d.fx = null;
  d.fy = null;
}