带有%份额的Zoomable Sunburst标记为

时间:2015-10-16 10:45:11

标签: d3.js percentage sunburst-diagram

我希望在标记的可缩放旭日图中显示每个块的百分比份额。我指的是http://bl.ocks.org/metmajer/5480307这个例子。  在这里我想要添加(%x)每个块的份额。请帮忙。

以下是我的index.html

<!DOCTYPE html>

<meta charset="utf-8"><style>

path {
  stroke: #fff;
  fill-rule: evenodd;
}

text {
  font-family: Arial, sans-serif;
  font-size: 12px;
}

</style> <body>
<script src="http://d3js.org/d3.v3.min.js">
</script> <script>

var width = 960,
    height = 700,
    radius = Math.min(width, height) / 2;

var x = d3.scale.linear()
    .range([0, 2 * Math.PI]);

var y = d3.scale.linear()
    .range([0, radius]);

var color = d3.scale.category20c();

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + width / 2 + "," + (height / 2 + 10) + ")");

var partition = d3.layout.partition()
    .value(function(d) { return d.size; });

var arc = d3.svg.arc()
    .startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); })
    .endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); })
    .innerRadius(function(d) { return Math.max(0, y(d.y)); })
    .outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });

d3.json("atmLeads.json", function(error, root) {
  var g = svg.selectAll("g")
      .data(partition.nodes(root))
    .enter().append("g");

  var path = g.append("path")
    .attr("d", arc).attr("class",function(d){return "ring_"+ d.depth;})
    .style("fill", function(d) { return color((d.children ? d : d.parent).name); })
    .on("click", click);

  var text = g.append("text")
    .attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; })
    .attr("x", function(d) { return y(d.y); })
    .attr("dx", "6") // margin
    .attr("dy", ".35em") // vertical-align
    .text(function(d) { return d.name; });

  function click(d) {
    // fade out all text elements
    text.transition().attr("opacity", 0);

    path.transition()
      .duration(750)
      .attrTween("d", arcTween(d))
      .each("end", function(e, i) {
          // check if the animated element's data e lies within the visible angle span given in d
          if (e.x >= d.x && e.x < (d.x + d.dx)) {
            // get a selection of the associated text element
            var arcText = d3.select(this.parentNode).select("text");
            // fade in the text element and recalculate positions
            arcText.transition().duration(750)
              .attr("opacity", 1)
              .attr("transform", function() { return "rotate(" + computeTextRotation(e) + ")" })
              .attr("x", function(d) { return y(d.y); });
          }
      });
  }
});

d3.select(self.frameElement).style("height", height + "px");

// Interpolate the scales!
function arcTween(d) {
  var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
      yd = d3.interpolate(y.domain(), [d.y, 1]),
      yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
  return function(d, i) {
    return i
        ? function(t) { return arc(d); }
        : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
  };
}

function computeTextRotation(d) {
  return (x(d.x + d.dx / 2) - Math.PI / 2) / Math.PI * 180;
}

</script> 

1 个答案:

答案 0 :(得分:1)

试试这段代码。

var path = g.append("path")
  .attr("d", arc).attr("class", function(d) {
    return "ring_" + d.depth;
  })
  .style("fill", function(d) {
    return color((d.children ? d : d.parent).name);
  })
  .on("click", click);

 var totalSize = path.node().__data__.value;

var text = g.append("text")
  .attr("transform", function(d) {
    return "rotate(" + computeTextRotation(d) + ")";
  })
  .attr("x", function(d) {
    return y(d.y);
  })
  .attr("dx", "6") // margin
  .attr("dy", ".35em") // vertical-align
  .text(function(d) {
    var percentage = (100 * d.value / totalSize).toPrecision(3);
    var percentageString = percentage + "%";
    if (percentage < 0.1) {
      percentageString = "< 0.1%";
    }
    return d.name +" "+percentageString;
  });

var width = 960,
  height = 700,
  radius = Math.min(width, height) / 2;

var x = d3.scale.linear()
  .range([0, 2 * Math.PI]);

var y = d3.scale.linear()
  .range([0, radius]);

var color = d3.scale.category20c();

var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + (height / 2 + 10) + ")");

var partition = d3.layout.partition()
  .value(function(d) {
    return d.size;
  });

var arc = d3.svg.arc()
  .startAngle(function(d) {
    return Math.max(0, Math.min(2 * Math.PI, x(d.x)));
  })
  .endAngle(function(d) {
    return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));
  })
  .innerRadius(function(d) {
    return Math.max(0, y(d.y));
  })
  .outerRadius(function(d) {
    return Math.max(0, y(d.y + d.dy));
  });

var root = {
  "name": "ATM Leads Converted",
  "size": 34752,
  "children": [

    {
      "name": "Converted",
      "size": 417
    }, {
      "name": "Failure",
      "size": 1366
    }, {
      "name": "Interested",
      "size": 916
    }, {
      "name": "No Value",
      "size": 48932
    }, {
      "name": "Not Interested",
      "size": 14479
    }, {
      "name": "Not contactable",
      "size": 2961
    },

    {
      "name": "Success",
      "size": 1142
    }, {
      "name": "Will Get Back",
      "size": 1564
    }, {
      "name": "Wrong Number",
      "size": 358
    }

  ]
};
var g = svg.selectAll("g")
  .data(partition.nodes(root))
  .enter().append("g");   

var path = g.append("path")
  .attr("d", arc).attr("class", function(d) {
    return "ring_" + d.depth;
  })
  .style("fill", function(d) {
    return color((d.children ? d : d.parent).name);
  })
  .on("click", click);

 var totalSize = path.node().__data__.value;

var text = g.append("text")
  .attr("transform", function(d) {
    return "rotate(" + computeTextRotation(d) + ")";
  })
  .attr("x", function(d) {
    return y(d.y);
  })
  .attr("dx", "6") // margin
  .attr("dy", ".35em") // vertical-align
  .text(function(d) {
    var percentage = (100 * d.value / totalSize).toPrecision(3);
    var percentageString = percentage + "%";
    if (percentage < 0.1) {
      percentageString = "< 0.1%";
    }
    return d.name +" "+percentageString;
  });

function click(d) {
  // fade out all text elements
  text.transition().attr("opacity", 0);

  path.transition()
    .duration(750)
    .attrTween("d", arcTween(d))
    .each("end", function(e, i) {
      // check if the animated element's data e lies within the visible angle span given in d
      if (e.x >= d.x && e.x < (d.x + d.dx)) {
        // get a selection of the associated text element
        var arcText = d3.select(this.parentNode).select("text");
        // fade in the text element and recalculate positions
        arcText.transition().duration(750)
          .attr("opacity", 1)
          .attr("transform", function() {
            return "rotate(" + computeTextRotation(e) + ")"
          })
          .attr("x", function(d) {
            return y(d.y);
          });
      }
    });
}


d3.select(self.frameElement).style("height", height + "px");

// Interpolate the scales!
function arcTween(d) {
  var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
    yd = d3.interpolate(y.domain(), [d.y, 1]),
    yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
  return function(d, i) {
    return i ? function(t) {
      return arc(d);
    } : function(t) {
      x.domain(xd(t));
      y.domain(yd(t)).range(yr(t));
      return arc(d);
    };
  };
}

function computeTextRotation(d) {
  return (x(d.x + d.dx / 2) - Math.PI / 2) / Math.PI * 180;
}
path {
  stroke: #fff;
  fill-rule: evenodd;
}
text {
  font-family: Arial, sans-serif;
  font-size: 12px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>