无法在d3.js中获取d的值

时间:2015-07-28 06:34:03

标签: javascript d3.js

我正在d3中构建一个饼图。在这里,我非常特别需要将标签挤出,并在切片刻度上附加水平线。 这是我的代码

svg.selectAll("g.arc")
.data(pie)
.enter()
.append("text")
.attr("text-anchor", "middle")
.attr("x", function(d) { 
    var a = 180-(d.startAngle + (d.endAngle - d.startAngle)/2)-45 - Math.PI/2;
    d.cx = Math.cos(a) * (radius - 75);
    return d.x =(width/3)+ Math.cos(a) * (oldRadius - 20);
})
.attr("y", function(d) {
    var a = 180-(d.startAngle + (d.endAngle - d.startAngle)/2)-45 - Math.PI/2;
    d.cy = Math.sin(a) * (radius - 75);
    return d.y =(height/2)- Math.sin(a) * (oldRadius - 20);
})
.text(function(d) { return d.value; })
.each(function(d) {
    var bbox = this.getBBox();
    d.sx = d.x - bbox.width/2 - 2;
    d.ox = d.x + bbox.width/2 + 2;
    d.sy = d.oy = d.y + 5;
});

svg.append("defs").append("marker")
.attr("id", "circ")
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("refX", 3)
.attr("refY", 3)
.append("circle")
.attr("cx", 3)
.attr("cy", 3)
.attr("r", 3);
svg.selectAll("g.arc")
        .data(pie)
        .enter()
.append("path")
.attr("class", "pointer")
.style("fill", "none")
.style("stroke", "black")
.attr("marker-end", "url(#circ)")
.attr("d", function(d,i) {
        alert(d.cx);
    if(d.cx > d.ox) {
        return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
    } else {
        return "M" + d.ox + "," + d.oy + "L" + d.sx + "," + d.sy + " " + d.cx + "," + d.cy;
    }
});

为此,我需要使用d变量中的某些值,如cx,ox,sx。我在第一个代码块中构建图表时设置这些值。 问题是当我在打印标签和刻度时尝试检索这些值时,我得到“未定义”的值。任何人都可以指出我在这里做错了什么,我需要改变一些东西吗? 提前致谢

1 个答案:

答案 0 :(得分:0)

小提琴在这里会有所帮助...... 我怀疑问题是你在追加路径时不需要以下两行:

.data(pie)
.enter()

这是重置数据。如果您只选择弧,svg.selectAll(" g.arc"),修改后的数据应该可用。

这是一个片段,其中的值不是未定义的(尽管使用上面的数学,这些行很不稳定)。



<!DOCTYPE html>
<html>
<meta charset="utf-8">
<style>
   body {
      font: 10px sans-serif;
   }
   .arc path {
      stroke: #fff;
   }
</style>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>

   var width = 200,
      height = 200,

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

   var color = d3.scale.ordinal()
      .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

   var data  = [
      {age: "<5", population: "2704659"},
      {age: "5-13", population: "4499890"},
      {age: "14-17", population: "2159981"},
      {age: "18-24", population: "3853788"},
      {age: "25-44", population: "14106543"},
      {age: "45-64", population: "8819342"},
      {age: "≥65", population: "612463"}];

   var arc = d3.svg.arc()
      .outerRadius(radius - 10)
      .innerRadius(0);

   var pie = d3.layout.pie()
      .sort(null)
      .value(function(d) { return d.population; });

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

   data.forEach(function(d) {
       d.population = +d.population;
   });

   var g = svg.selectAll(".arc")
      .data(pie(data))
      .enter().append("g")
      .attr("class", "arc");

   g.append("path")
      .attr("d", arc)
      .style("fill", function(d) { return color(d.data.age); });

   var oldRadius = radius / 2;

   svg.selectAll("g.arc")
      .append("text")
      .attr("text-anchor", "middle")
      .attr("x", function (d) {
         var a = 180 - (d.startAngle + (d.endAngle - d.startAngle) / 2) - 45 - Math.PI / 2;
         d.cx = Math.cos(a) * (radius - 75);
         d.x = (width / 3) + Math.cos(a) * (oldRadius - 20);
         return d.x;
      })
      .attr("y", function (d) {
         var a = 180 - (d.startAngle + (d.endAngle - d.startAngle) / 2) - 45 - Math.PI / 2;
         d.cy = Math.sin(a) * (radius - 75);
         d.y = (height / 2) - Math.sin(a) * (oldRadius - 20);
         return d.y;
      })
      .text(function (d) {
         return d.data.population;
      })
      .each(function (d) {
         var bbox = this.getBBox();
         d.sx = d.x - bbox.width / 2 - 2;
         d.ox = d.x + bbox.width / 2 + 2;
         d.sy = d.oy = d.y + 5;
      });

   svg.append("defs").append("marker")
      .attr("id", "circ")
      .attr("markerWidth", 6)
      .attr("markerHeight", 6)
      .attr("refX", 3)
      .attr("refY", 3)
      .append("circle")
      .attr("cx", 3)
      .attr("cy", 3)
      .attr("r", 3);
   svg.selectAll("g.arc")
      .append("path")
      .attr("class", "pointer")
      .style("fill", "none")
      .style("stroke", "black")
      .attr("marker-end", "url(#circ)")
      .attr("d", function (d, i) {
         if (d.cx > d.ox) {
            return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
         } else {
            return "M" + d.ox + "," + d.oy + "L" + d.sx + "," + d.sy + " " + d.cx + "," + d.cy;
         }
      });

</script>
</body>
</html>
&#13;
&#13;
&#13;