D3:如何为物品指定尺寸,颜色(碰撞检测可视化)

时间:2014-07-26 11:19:57

标签: javascript svg d3.js

我是D3的新手,并根据D3js.io网站(http://bl.ocks.org/mbostock/3231298)上的碰撞检测可视化示例构建了以下可视化。

我希望能够在我的图表中指定每个10个球的大小和颜色,但我不明白该怎么做。目前,代码依赖于随机生成的大小,并且球都是黑色的。有人可以解释我如何做出这些改变吗?

理想情况下,我希望能够为10个球中的每个球指定十六进制代码和特定的px宽度。

我的代码粘贴在下面,也在Codepen上:http://codepen.io/msummers40/pen/LiBmr

提前感谢您的帮助。

马特

<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

var width = 500,
    height = 400;

var nodes = d3.range(11).map(function() { return {radius: Math.random() * 33 + 4}; }),
    root = nodes[0],
    color = d3.scale.category20();

root.radius = 80;
root.fixed = true;

var force = d3.layout.force()
    .gravity(0.05)
    .charge(function(d, i) { return i ? 0 : -2000; })
    .nodes(nodes)
    .size([width, height]);

force.start();

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

svg.selectAll("circle")
    .data(nodes.slice(1))
  .enter().append("circle")
    .attr("r", function(d) { return d.radius; })
    .style("fill", function(d) { return d.color; });


force.on("tick", function(e) {
  var q = d3.geom.quadtree(nodes),
      i = 0,
      n = nodes.length;

  while (++i < n) q.visit(collide(nodes[i]));

  svg.selectAll("circle")
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
});

svg.on("mousemove", function() {
  var p1 = d3.mouse(this);
  root.px = p1[0];
  root.py = p1[1];
  force.resume();
});

function collide(node) {
  var r = node.radius + 1,
      nx1 = node.x - r,
      nx2 = node.x + r,
      ny1 = node.y - r,
      ny2 = node.y + r;
  return function(quad, x1, y1, x2, y2) {
    if (quad.point && (quad.point !== node)) {
      var x = node.x - quad.point.x,
          y = node.y - quad.point.y,
          l = Math.sqrt(x * x + y * y),
          r = node.radius + quad.point.radius;
      if (l < r) {
        l = (l - r) / l * .5;
        node.x -= x *= l;
        node.y -= y *= l;
        quad.point.x += x;
        quad.point.y += y;
      }
    }
    return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
  };
}

</script>

</html>

2 个答案:

答案 0 :(得分:2)

圆圈的半径和填充颜色在此代码中设置(特别是最后两行):

svg.selectAll("circle")
  .data(nodes.slice(1))
  .enter().append("circle")
  .attr("r", function(d) { return d.radius; })
  .style("fill", function(d, i) { return color(i % 3); });

半径直接来自数据,它的生成方式如下:

{radius: Math.random() * 33 + 4}

要设置每个圆的特定半径,请更改返回的内容。如果要明确指定半径,请使用以下静态数据:

var nodes = [{radius: 1}, {radius: 2}, ...];

同样适用于填充颜色。您可以向数据添加另一个属性以指定颜色(看起来您已尝试执行此操作):

var nodes = [{radius: 1, color: "red"}, {radius: 2, color: "blue"}, ...];

答案 1 :(得分:1)

你几乎拥有它,但风格方法不合适。您应该更改为 attr('fill'),然后使用您的色标:

svg.selectAll("circle")
  .data(nodes.slice(1))
  .enter().append("circle")
  .attr("r", function(d) { return d.radius; })
  .attr("fill", function(d) { return color(d.index);  });

你可以为尺寸或其他任何东西做同样的事情