d3.js:在地图上生成饼图,出现意外的NaN [英] d3.js: Generating pie charts over map, unexpected NaN

查看:81
本文介绍了d3.js:在地图上生成饼图,出现意外的NaN的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

数据

我有一个.csv,它具有以下格式的数据:

I've got a .csv which has data of the following format:

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

city, industry, X, Non-X, latitude, longitude, Total

目标

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

I've made a map of the country, and have created some g elements over each capital (using the latitude and longitude data). Within each g element, I'd like to create a pie chart, showing the proportions of X and Non-X. I'd like the radius of each pie to be a function of Total.

代码

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

Skipping over creating the map, etc, here's my function to create the pie charts (scroll down; a bit long):

            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")工作正常;文本元素出现在正确的纬度和经度处.我的arc变量出了点问题;我认为这与我定义.outerRadius()的方式有关. path元素已创建,但是我正在获取NaN(因此没有派).这是每个饼形图的g元素示例中的HTML外观:

pies.append("text") works fine; the text elements appear at the right lat and long. Something's wrong with my arc variable; and I think it must be to do with how I've defined .outerRadius(). The path elements are created, but I'm getting NaN (and, hence, no pies). Here's what the HTML looks like from an example g element for each pie chart:

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

我怀疑这与我如何绑定数据以及如何将数据传递到arc.outerRadius()有关.我尝试将数据重新绑定到每个pies元素;我还尝试了绑定.data(d3.layout.pie())(按照Mike Bostock的示例此处),但这只是没有完全不会生成d.

I suspect it's something with how I'm binding the data, and how I'm passing the data into arc.outerRadius(). I've tried re-binding the data to each pies element; I've also tried binding .data(d3.layout.pie()) (following Mike Bostock's example here), but that just doesn't generate d altogether.

我想做的是使用d['X']d['Non-X']来生成每个饼图的arc.outerRadius()(我认为)-任何指导将不胜感激!

What I'd like to do, is have d['X'] and d['Non-X'] be used to generate each pie's arc.outerRadius() (I think) - any guidance would be much appreciated!

推荐答案

您需要嵌套选择:

  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);


工作代码:


Working code:

<!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>

这篇关于d3.js:在地图上生成饼图,出现意外的NaN的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆