如何解决错误:arc.centroid(d)上<text>属性transform =“translate(NaN,NaN)”的值无效?

时间:2015-11-05 12:27:38

标签: d3.js

我正试图在我的多线甜甜圈图表上附加文字。但它在“translate”行返回无效值错误。

gs
    .append("text") 
    .attr("class", "pieNum")    
    .attr("transform", function(d, i, j){
        console.log(d, i, j);
        return "translate(" + arc.centroid(d[i]) + ")"  
    })
    .text(function(d, i){
        console.log(d);
        return d.value 
    })

我发现它发生是因为在function(d, i, j)上,d获取数组数据,而不是字符串或浮点数。

因为我的数据看起来像

nextYear    thisYear    preYear
11118       10683       10892
28201       27358       28537
1473        1398        1399
0           0           1

因此["11118", "28201", "1473", "0"]之类的数据位于d,我正在尝试使用数组中的数字,但仍然失败。

这是我的代码:

JS

  d3.csv(filename, function(error,data){


  var dataOuter = [], dataMid = [], dataInner = [];
  var dataset = {
            dataOuter,
            dataMid,
            dataInner,

        };
        var svgEle = document.getElementById("chart")
        var width = window.getComputedStyle(svgEle, null).getPropertyValue("width")
            height = window.getComputedStyle(svgEle, null).getPropertyValue("height")
            cwidth = 50;

        width = parseFloat(width) // remove px
        height = parseFloat(height) // remove px    

for (var i = 0; i < data.length; i++){
dataset.dataOuter.push(data[i].nextYear)
dataset.dataMid.push(data[i].thisYear)
dataset.dataInner.push(data[i].preYear)
  }

        var color = d3.scale.category10();

        var pie = d3.layout.pie()
            .sort(null);

        var arc = d3.svg.arc();

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

        var gs = svg.selectAll("g").data(d3.values(dataset)).enter().append("g");
        var path = gs.selectAll("path")
            .data(function (d) { return pie(d); })
            .enter().append("path")
            .attr("fill", function (d, i) { return color(i); })
            .attr("d", function (d, i, j) { return arc.innerRadius(10 + cwidth * j).outerRadius(cwidth * (j + 1))(d); });

    gs
        .append("text") 
        .attr("class", "pieNum")    
        .attr("transform", function(d, i, j){
        console.log(d, i, j);
        return "translate(" + arc.centroid(d[i]) + ")" 
            })
        .text(function(d, i){
    console.log(d);
            return d.value
            })

    })

1 个答案:

答案 0 :(得分:0)

从代码中看起来你正在将3个饼图嵌套在一起。对于每个,您需要保持对它正在使用的弧函数的引用。以下是我重新构建代码的方法:

&#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>
  <div id="chart" style="width: 600px; height: 600px"></div>
  <script>
      // input data
      var data = [{"nextYear":"11118","thisYear":"10683","preYear":"10892"},{"nextYear":"28201","thisYear":"27358","preYear":"28537"},{"nextYear":"1473","thisYear":"1398","preYear":"1399"},{"nextYear":"0","thisYear":"0","preYear":"1"}];

      var dataOuter = [],
        dataMid = [],
        dataInner = [];
      
      // make this array of arrays
      var dataset = [
        dataOuter,
        dataMid,
        dataInner,
      ];

      var svgEle = document.getElementById("chart")
      var width = window.getComputedStyle(svgEle, null).getPropertyValue("width")
      height = window.getComputedStyle(svgEle, null).getPropertyValue("height")
      cwidth = 50;

      width = parseFloat(width) // remove px
      height = parseFloat(height) // remove px    
 
      // again, array of arrays for data-binding
      for (var i = 0; i < data.length; i++) {
        dataset[0].push(+data[i].nextYear);
        dataset[1].push(+data[i].thisYear);
        dataset[2].push(+data[i].preYear);
      }

      var color = d3.scale.category10();

      var pie = d3.layout.pie()
        .sort(null);
 
      // pre-make all the arcs you'll need
      var arcs = [
        d3.svg.arc()
          .innerRadius(0)
          .outerRadius(50),
        d3.svg.arc()
          .innerRadius(60)
          .outerRadius(110),
        d3.svg.arc()
          .innerRadius(120)
          .outerRadius(170)];

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

      // g for each pie
      var pies = svg.selectAll(".pie")
        .data(dataset)
        .enter().append("g")
        .attr("class", "pie");

      // pie up the data, add a g for each slice (arc + text)
      var slices = pies.selectAll(".slice")
        .data(function(d) {
          return pie(d);
        })
        .enter()
        .append("g")
        .attr("class","slice");
      
      // add our paths with our arcs
      slices
        .append("path")
        .attr("fill", function(d, i, j) {
          return color(i);
        })
        .attr("d", function(d, i, j) {
          return arcs[j](d);
        });
  
      // add our text
      slices
        .append("text")
        .attr("class", "pieNum")
        .attr("transform", function(d, i, j) {
          return "translate(" + arcs[j].centroid(d) + ")"
        })
        .text(function(d, i) {
          return d.value
        })

   // })
  </script>
</body>

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