Accepted answer

Here's an updated codepen

Changes made:

1) As part of initialization, create element valueText

valueText = chart.append("text")
                .attr('id', "Value")
                .style("fill", '#000000');

2) Also at initialization, create formatValue, to format percent

formatValue = d3.format('1%');

3) At each frame of the transition, compute the position of the text. It adds an offset of 45 units to self.len (the needle's length) to move the text outwards.

var thetaRad = percToRad(progress / 2);
var textX = - (self.len + 45) * Math.cos(thetaRad);
var textY = - (self.len + 45) * Math.sin(thetaRad);

4) Translate valueText based on the computed position and update its text from current progress

  .attr('transform', "translate("+textX+","+textY+")")


Well, I found out something waiting for a better solution.

I'm using this :

var trX = 180 - 210 * Math.cos(percToRad(percent / 2)); 
var trY = 195 - 210 * Math.sin(percToRad(percent / 2));
// (180, 195) are the coordinates of the center of the gauge.

displayValue = function() {
                        return dataset[0].value;
                    .attr('id', "Value")
                    .attr('transform', "translate(" + trX + ", " + trY+ ")")
                    .style("fill", '#FB0006');

[...] then calling this :

setTimeout(displayValue, 1350);

So that it doesn't appear right away, but when the needle has stopped at its position.

It works, in the way that the value appears on the top of the needle, but I still have two problems. I'd really like it to follow the needle all the way long during the needle animation when it goes to its value, and I'd like something more general than using the coordinates I found out by calculating, is there a function which can give me the center of the gauge for example ?

I edited the pen given above to that version of the gauge. (

Anyway, this solution doesn't really fit my expectations, but I'll use it till I can find something better.

Related Query

More Query from same tag