时间:2015-12-16 17:17:04

标签: d3.js

this example by Mike Bostock可以看到,可以将轴显示为圆形图形。在链接的例子中,有三个轴(其间的区域大小相等)似乎是由这行代码创建的

var angle = d3.scale.ordinal().domain(d3.range(4)).rangePoints([0, 2 * Math.PI]),

svg.selectAll(".axis")
    .data(d3.range(3))
  .enter().append("line")
    .attr("class", "axis")
    .attr("transform", function(d) { return "rotate(" + degrees(angle(d)) + ")"; })
    .attr("x1", radius.range()[0])
    .attr("x2", radius.range()[1]);

使用该示例,我能够使用此代码创建一个包含六个轴(,每个轴之间的间距相等)的图形,覆盖整个圆圈

var angle = d3.scale.ordinal().domain(["one", "two", "three", "four", "five", "six"]).range([0, 45, 90, 135, 180, 225])

然后

svg.selectAll(".axis").data(d3.range(7))
//code omitted

但是,通过这样做(我预期会这样),我无法创建一个包含9个轴(中间间距相等)的圆

var angle = d3.scale.ordinal()
   .domain(["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"])
  .range([0, 45, 90, 135, 180, 225, 270, 315, 360]);

svg.selectAll(".axis").data(d3.range(10))
    //code omitted

这样做的结果是轴开始第二次围绕圆圈。

问题:是否有一种模式可以遵循以在每个之间具有相等间距的圆圈中显示任意数量的轴?如果是这样,请解释两个成功尝试背后的d3原则以及上面显示和链接的一个不成功的尝试。

更新

虽然删除了对度数的调用,但是将轴放在正确的位置,(然后在节点代码中删除对度数的调用,将轴上的节点放在右轴上),链接没有正确排列,即它们不是以轴线开始和结束,而是浮动不固定。您可以在此图片enter image description here

中查看问题

这是链接的代码(注意它没有对度数的调用)

svg.selectAll(".link")
    .data(linx)
  .enter().append("path")
    .attr("class", "link")
    .attr("class", function(d) {  return "link " + d.Class})
    .attr("d", link()
    .angle(function(d) { return angle(d.X); })
    .radius(function(d) { return radius(d.Y); }))
    .on("mouseover", linkMouseover)
    .on("mouseout", mouseout);

它调用一个链接函数(也没有调用度,所以我不知道为什么链接在轴的位置开始和结束)我来自Mike Bostock的hive实现

function link() {

       var source = function(d) { return d.Source; },
      target = function(d) { return d.Target; },
      angle = function(d) { return d.angle; },
      startRadius = function(d) { return d.radius; },
      endRadius = startRadius,
      arcOffset = -Math.PI / 2;

  function link(d, i) {
    // console.log(d, i, "interior link func");
    var s = node(source, this, d, i),
        t = node(target, this, d, i),
        x;
    if (t.a < s.a) x = t, t = s, s = x;
    if (t.a - s.a > Math.PI) s.a += 2 * Math.PI;
    var a1 = s.a + (t.a - s.a) / 3,
        a2 = t.a - (t.a - s.a) / 3;
    return s.r0 - s.r1 || t.r0 - t.r1
        ? "M" + Math.cos(s.a) * s.r0 + "," + Math.sin(s.a) * s.r0
        + "L" + Math.cos(s.a) * s.r1 + "," + Math.sin(s.a) * s.r1
        + "C" + Math.cos(a1) * s.r1 + "," + Math.sin(a1) * s.r1
        + " " + Math.cos(a2) * t.r1 + "," + Math.sin(a2) * t.r1
        + " " + Math.cos(t.a) * t.r1 + "," + Math.sin(t.a) * t.r1
        + "L" + Math.cos(t.a) * t.r0 + "," + Math.sin(t.a) * t.r0
        + "C" + Math.cos(a2) * t.r0 + "," + Math.sin(a2) * t.r0
        + " " + Math.cos(a1) * s.r0 + "," + Math.sin(a1) * s.r0
        + " " + Math.cos(s.a) * s.r0 + "," + Math.sin(s.a) * s.r0
        : "M" + Math.cos(s.a) * s.r0 + "," + Math.sin(s.a) * s.r0
        + "C" + Math.cos(a1) * s.r1 + "," + Math.sin(a1) * s.r1
        + " " + Math.cos(a2) * t.r1 + "," + Math.sin(a2) * t.r1
        + " " + Math.cos(t.a) * t.r1 + "," + Math.sin(t.a) * t.r1;
  }

  function node(method, thiz, d, i) {
    var node = method.call(thiz, d, i),
        a = +(typeof angle === "function" ? angle.call(thiz, node, i) : angle) + arcOffset,
        r0 = +(typeof startRadius === "function" ? startRadius.call(thiz, node, i) : startRadius),
        r1 = (startRadius === endRadius ? r0 : +(typeof endRadius === "function" ? endRadius.call(thiz, node, i) : endRadius));
    return {r0: r0, r1: r1, a: a};
  }

  link.source = function(_) {
    if (!arguments.length) return source;
    source = _;
    return link;
  };

  link.target = function(_) {
    if (!arguments.length) return target;
    target = _;
    return link;
  };

  link.angle = function(_) {
    if (!arguments.length) return angle;
    angle = _;
    return link;
  };

  link.radius = function(_) {
    if (!arguments.length) return startRadius;
    startRadius = endRadius = _;
    return link;
  };

  link.startRadius = function(_) {
    if (!arguments.length) return startRadius;
    startRadius = _;
    return link;
  };

  link.endRadius = function(_) {
    if (!arguments.length) return endRadius;
    endRadius = _;
    return link;
  };

  return link;
}

1 个答案:

答案 0 :(得分:1)

你已经有度数角度,你不需要使用degree()函数。如果您取消调用,一切都会正常。