score:4

Accepted answer

The problem here is just this inside the inner function, which will no longer work as it worked in v3.

Let's prove it. Have a look at the console here, using D3 v3, this is the DOM element:

d3.select("p").transition()
  .tween("foo", function(d) {
    var i = d3.interpolate(0, 1);
    return function(t) {
      console.log(this)
    };
  });
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
<script src="https://d3js.org/d3.v3.min.js"></script>
<p></p>

Now the same snippet, using D3 v4... this is now the window object:

d3.select("p").transition()
  .tween("foo", function(d) {
    var i = d3.interpolate(0, 1);
    return function(t) {
      console.log(this)
    };
  });
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<p></p>

Solution: keep the reference to this in the outer function as a variable (traditionally named self, but here I'll name it node):

d3.selectAll(".pieLabel").transition()
    .delay(500)
    .duration(1000)
    .tween("text", function(d) {
        var node = this;
        //keep a reference to 'this'
        var i = d3.interpolate(node.textContent, d.value);
        return function(t) {
            node.textContent = form(i(t));
            //use that reference in the inner function
        };
    });

Here is your code with that change only:

var widthpie = 250,
  heightpie = 300,
  radius = Math.min(widthpie, heightpie) / 2;

var data = [{
  antwort: "A",
  value: 0.5
}, {
  antwort: "B",
  value: 0.4
}];

var form = d3.format(",%");

var body4 = d3.select("#chart1");

var svg4 = body4.selectAll("svg.Pie")
  .data(data)
  .enter()
  .append("svg")
  .attr("width", widthpie)
  .attr("height", heightpie)
  .append("g")
  .attr("transform", "translate(" + widthpie / 2 + "," + heightpie / 2 + ")");

var pieText = svg4.append("text")
  .attr("class", "pieLabel")
  .attr("x", 0)
  .attr("y", 0)
  .text(0)
  .attr("dy", "0.2em")
  .style("font-size", 19)
  .style("fill", "#46596b")
  .attr("text-anchor", "middle");

d3.selectAll(".pieLabel").transition()
  .delay(500)
  .duration(1000)
  .tween("text", function(d) {
    var node = this;
    var i = d3.interpolate(node.textContent, d.value);
    return function(t) {
      node.textContent = form(i(t));
    };
  });
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="chart1"></div>

PS: I'm using Firebug in the snippets because S.O. snippet don't log the window object correctly.

score:-2

i thing i copy this code i dont know where, if any one knew just give referance. i use this to add transition to path, i hope this give you an idea

Use this to append the transition

.transition()
              .duration(2000)
              .attrTween("stroke-dasharray", tweenDash)

this the function

function tweenDash() {
    return function(t) {
        var l = path.node().getTotalLength();
        interpolate = d3.interpolateString("0," + l, l + "," + l);

        //t is fraction of time 0-1 since transition began

        var p = path.node().getPointAtLength(t * l);

        return interpolate(t);
    }
}

score:2

The problem is caused by a change which is not documented in the changelog. D3 v3 calls the inner function returned by the callback passed to transition.tween() on every tick passing the current node as the this context:

tweens[--n].call(node, e);

As of v4, however, this is no longer the case when the inner function is called:

tween[i].call(null, t);

Passing null to that function will be replaced with the global object. In this case this in your function no longer points to current element as was true for v3. The remedy was already been laid out by Gerardo in his answer and is even suggested by the documentation on v4:

transition.tween("attr.fill", function() {
  var node = this, i = d3.interpolateRgb(node.getAttribute("fill"), "blue");
  return function(t) {
    node.setAttribute("fill", i(t));
  };
});

Hence, you need a closure to keep a reference to the current element as it is referenced as this in the callback provided to transition.tween().


More Query from same tag