在d3

时间:2018-05-02 12:57:52

标签: d3.js canvas

我在bl.ocks.org上玩一个D3示例Force Dragging

我正在从JSON文件加载节点,但我无法弄清楚如何设置节点的颜色(最初是任何颜色,但理想情况下我想提供JSON中节点的颜色)。

代码:(从bl.ocks.org复制)                         

var canvas = document.querySelector("canvas"),
    context = canvas.getContext("2d"),
    width = canvas.width,
    height = canvas.height;

var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) { return d.id; }))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(width / 2, height / 2));

d3.json("../data/prc_network.json", function(error, graph) {
  if (error) throw error;

  simulation
      .nodes(graph.nodes)
      .on("tick", ticked);

  simulation.force("link")
      .links(graph.links);

  d3.select(canvas)
      .call(d3.drag()
          .container(canvas)
          .subject(dragsubject)
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended));

  function ticked() {
    context.clearRect(0, 0, width, height);

    context.beginPath();
    graph.links.forEach(drawLink);
    context.strokeStyle = "#aaa";
    context.stroke();

    context.beginPath();
    graph.nodes.forEach(drawNode);
    context.fill();
    context.strokeStyle = "#fff";
    context.stroke();
  }

  function dragsubject() {
    return simulation.find(d3.event.x, d3.event.y);
  }
});

function dragstarted() {
  if (!d3.event.active) simulation.alphaTarget(0.3).restart();
  d3.event.subject.fx = d3.event.subject.x;
  d3.event.subject.fy = d3.event.subject.y;
}

function dragged() {
  d3.event.subject.fx = d3.event.x;
  d3.event.subject.fy = d3.event.y;
}

function dragended() {
  if (!d3.event.active) simulation.alphaTarget(0);

}

function drawLink(d) {
  context.moveTo(d.source.x, d.source.y);
  context.lineTo(d.target.x, d.target.y);
}

function drawNode(d) {
  context.moveTo(d.x + 3, d.y);
  context.arc(d.x, d.y, 3, 0, 2 * Math.PI);
}

</script>

1 个答案:

答案 0 :(得分:2)

每次要为一个节点着色时,您需要开始一个新路径 - 因为每个路径都有一个设置样式。为此,我们需要将所有节点绘制部分移动到drawNode函数而不是tick函数,以便我们可以单独设置每个节点的样式:

function drawNode(d) {
  context.beginPath(); 
  context.moveTo(d.x + 3, d.y);
  context.arc(d.x, d.y, 3, 0, 2 * Math.PI);
  context.fillStyle = d.color // or some other property that has a valid color
  context.fill();
  context.strokeStyle = "#fff";
  context.stroke();
}

我们还可以使用比例来获取某些属性并将其转换为颜色:

var colors = d3.scaleOrdinal().range(d3.schemeCategory20);

function drawNode(d) {
  context.beginPath(); 
  context.moveTo(d.x + 3, d.y);
  context.arc(d.x, d.y, 3, 0, 2 * Math.PI);
  context.fillStyle = colors(d.property);
  context.fill();
  context.strokeStyle = "#fff";
  context.stroke();
}

这是block使用节点组的基本示例(带基础数据)着色。