simouns
simouns

Reputation: 25

d3.js arc.centroid(d) : Error: Invalid value for <text> attribute transform="translate(NaN,NaN)"

I'm trying to center the arc labels with the centroid() function as described in D3 documentation.

arcs.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.text(function(d) { return "labels"; });

but I'm getting an error on the translate css property :

Error: Invalid value for attribute transform="translate(NaN,NaN)"

one of the console.log of the (d) objects in :

.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })

returns this:

data: 80
endAngle: 1.9112350744272506
padAngle: 0
startAngle: 0
value: 80
__proto__: Object

Here's my code:

HTML:

<div id="firstChart"></div>

JS:

var myData = [80,65,12,34,72];
var nbElement = myData.length;
var angle = (Math.PI * 2) / nbElement ;
var myColors = ["#e7d90d", "#4fe70d", "#0de7e0", "#f00000", "#00DC85"];
var width = 1500;
var height = 1500;
var radius = 200;

var canvas = d3.select("#firstChart")
              .append("svg")
              .attr("height", height)
              .attr("width", width);

var group = canvas.append("g")
                .attr("transform","translate(310, 310)");

var arc = d3.svg.arc()
                .innerRadius(0)       
                .outerRadius(function (d,i) { return (myData[i]*2); })
                .startAngle(function (d,i) { return (i*angle); })
                .endAngle(function (d,i) { return (i*angle)+(1*angle); });

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

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

arcs.append("path")
    .attr("d", arc)
    .attr("fill", function (d, i) { return ( myColors[i] ); });

arcs.append("text")
    .attr("transform", function(d) {console.log(d); return "translate(" + arc.centroid(d) + ")"; })
    .text(function(d) { return d.data; });

var outlineArc = d3.svg.arc()
        .innerRadius(0)
        .outerRadius(radius)
        .startAngle(function (d,i) { return (i*angle); })
        .endAngle(function (d,i) { return (i*angle)+(1*angle); });

var outerPath = group.selectAll(".outlineArc")
      .data(pie(myData))
    .enter().append("path")
      .attr("fill", "none")
      .attr("stroke", "black")
      .attr("stroke-width", "2")
      .attr("class", "outlineArc")
      .attr("d", outlineArc);   

Upvotes: 1

Views: 2239

Answers (1)

Luke Woodward
Luke Woodward

Reputation: 65064

You need to pass the index of the element to centroid as well as the datum:

    .attr("transform", function(d, i) { return "translate(" + arc.centroid(d, i) + ")"; })

During the call to arc.centroid, D3 calls the arc functions you have created for outerRadius, startAngle and endAngle. However, if you don't pass the index to arc.centroid, D3 has got no index to pass on to the arc functions, all of which use the index. Hence the centroid calculations end up with NaNs.

Upvotes: 5

Related Questions