How to center (horizontal and vertical) text along an textPath inside an arc using d3.js?

Viewed 7019

After playing a while with d3.js and looking at a lot of examples, I was able to draw multiple arcs. Each one starting and ending at an specific degree and and given radius.

var dataset = {
    "2":[{"degree1":0,                 "degree2":1.5707963267949,
          "label":"Sample Text Test"},    
         {"degree1":1.5707963267949,   "degree2":3.1415926535898,
          "label":"Lorem ipsum sample text"},
         {"degree1":3.1415926535898,   "degree2":4.7123889803847,
          "label":"Sample Text Text"},
         {"degree1":4.7123889803847,   "degree2":6.2831853071796,
          "label":"Lorem ipsum"}],
    "1":[{"degree1":0,                 "degree2":3.1415926535898,
          "label":"Sample"},
         {"degree1":3.1415926535898,   "degree2":6.2831853071796,
          "label":"Text"}],
    "0":[{"degree1":0,                 "degree2":6.2831853071796,
          "label":""}]
    },
    width   = 450,
    height  = 450,
    radius  = 75;

// Helper methods
var innerRadius = function(d, i, j) {
    return 1 + radius * j;
};

var outerRadius = function(d, i, j) {
    return radius * (j + 1);
};

var startAngle = function(d, i, j) {
    return d.data.degree1;
};

var endAngle = function(d, i, j) {
    return d.data.degree2;
};

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

var arc = d3.svg.arc()
    .innerRadius(innerRadius)
    .outerRadius(outerRadius)
    .startAngle(startAngle)
    .endAngle(endAngle);

var svg = d3.select('body').append('svg')
    .attr('width', width)
    .attr('height', height)
    .append('g')
    .attr('transform', 'translate(' + (width >> 1) + ',' + (height >> 1) + ')');

var level = svg.selectAll('g')
    .data(function(d) {
        return d3.values(dataset);
    })
    .enter()
    .append('g');

var entry = level.selectAll('g')
    .data(function(d, i) {
        return pie(d);
    })
    .enter()
    .append('g');

entry.append('path')
    .attr('fill', '#aaa')
    .attr('d', arc)
    .attr('id', function(d, i, j) {
        return 'arc' + i + '-' + j;
    });

var label = entry.append('text')
    .style('font-size', '20px')
    .attr('dx', function(d, i, j) {
        return Math.round((d.data.degree2 - d.data.degree1) * 180 / Math.PI);
    })
    .attr('dy', function(d, i, j) {
        return ((radius * (j + 1)) - (1 + radius * j)) >> 1;
    });


label.append('textPath')
    .attr('xlink:href', function(d, i, j) {
        return '#arc' + i + '-' + j;
    })
    .style('fill', '#000')
    .text(function(d) {
        return d.data.label;
    });

See http://jsfiddle.net/3FP6P/2/ :

enter image description here

But some problem still exists:

  1. How to center (horizonal und vertical) an text along an textpath of an any length inside an arc described by innerRadius, outerRadius, startAngle and endAngle?
  2. The text occurs sometimes bold, sometimes not. Why?
  3. The character spacing does not appear to be the same as if it is written inside a . Some letters stick more together as other ones. Why?
  4. The letters are not located directly on the path. Some seem to have a little slip up or down. Why?
2 Answers
Related