d3.js:在地图上生成饼图,意外的NaN

时间:2015-12-21 16:14:11

标签: d3.js

数据

我有一个.csv,其中包含以下格式的数据:

  

城市,行业,X,非X,纬度,经度,总计

目标

我制作了该国家/地区的地图,并在每个首都创建了一些g元素(使用latitudelongitude数据)。在每个g元素中,我想创建一个饼图,显示XNon-X的比例。我希望每个馅饼的半径是Total的函数。

代码

跳过创建地图等,这是我创建饼图的功能(向下滚动;有点长):

            function drawPies(csv) {

                var radius = d3.scale.sqrt()
                    .domain([1, d3.max(csv, function(d) { 
                        return d.Total; 
                    })])
                    .range([2, 25]);

                var color = d3.scale.ordinal();
                var arc = d3.svg.arc();
                var pie = d3.layout.pie();

                var circleLayer = d3.select("svg")
                                .append("g")
                                .attr("class", "circleLayer");

                var pies = circleLayer.selectAll("g")
                    .data(csv)
                    .enter()
                    .append("g")
                    .attr("id", function(d) { return d.city; })
                    .attr("class", "capitals")
                    .on("mouseover", mouseover)
                    .on("mouseout", mouseout)
                    .attr("transform", function(d) {
                        return "translate(" + projection([d.lon, d.lat])[0] + "," + projection([d.lon, d.lat])[1] + ")";
                        });

                arc.outerRadius(function (d) { return radius(d.Total); })
                    .innerRadius(0);

                pies.append("text")
                    .text("Hi");

                pies.append("path")
                    .attr("d", arc) //this is not working...
                    .style("fill", function(d) { return color(d['X']); });
            } 

pies.append("text")工作正常;文本元素出现在右侧lat和long。我的arc变量出了点问题;而且我认为必须与我定义.outerRadius()的方式有关。 path元素已创建,但我获得NaN(因此,没有馅饼)。以下是每个饼图的示例g元素的HTML外观:

<path d="MNaN,NaNA4.859251238796309,4.859251238796309 0 1,1 NaN,NaNL0,0Z">

我怀疑这与我如何绑定数据有关,以及我如何将数据传递到arc.outerRadius()。我尝试将数据重新绑定到每个pies元素;我也试过绑定.data(d3.layout.pie())(遵循Mike Bostock的例子here),但这并不能完全生成d

我想做的是d['X']d['Non-X']用于生成每个馅饼arc.outerRadius()(我认为) - 任何指导都是非常感谢!

1 个答案:

答案 0 :(得分:2)

您需要嵌套选择:

  var arc = d3.svg.arc().innerRadius(0).outerRadius(20)
      pie = d3.layout.pie()
        .value(function(d){ return d });

  var pies = svg.selectAll('.pie') //<-- this is each row
    .data(data)
    .enter()
    .append('g')
    .attr('class', 'pie')

  ...

  pies.selectAll('.slice')
    .data(function(d){
      return pie([d.X, d.NonX]); //<-- this is each slice
    })
    .enter()
    .append('path')
    .attr('class', 'slice')
    .attr('d',  arc);

工作代码:

&#13;
&#13;
<!DOCTYPE html>
<html>

  <head>
    <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
  </head>

  <body>
    <script>
      
      var data = [{
        X: Math.random(),
        NonX: Math.random(),
        Total: Math.random() * 10
      },{
        X: Math.random(),
        NonX: Math.random(),
        Total: Math.random() * 10
      },{
        X: Math.random(),
        NonX: Math.random(),
        Total: Math.random() * 10
      },{
        X: Math.random(),
        NonX: Math.random(),
        Total: Math.random() * 10
      }];
      
      data.forEach(function(d){
        d.pieVals = [d.X, d.NonX];
      })
      
      var svg = d3.select('body')
        .append('svg')
        .attr('width', 500)
        .attr('height', 500);
        
      var arc = d3.svg.arc().innerRadius(0).outerRadius(20)
          pie = d3.layout.pie()
            .value(function(d){ return d }),
          color = d3.scale.category10();
      
      var pies = svg.selectAll('.pie')
        .data(data)
        .enter()
        .append('g')
        .attr('class', 'pie')
        .attr('transform',function(d,i){
          return 'translate(' + 20 + ',' + (i + 1) * 40 + ')';
        })
        
      pies.selectAll('.slice')
        .data(function(d){
          return pie([d.X, d.NonX]);
        })
        .enter()
        .append('path')
        .attr('d',  arc)
        .style('fill', function(d,i){
          return color(i);
        });
      
      
    </script>
  </body>

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