d3/d3-interpolate

Interpolating arcs can lead to error messages

rivo opened this issue · 3 comments

rivo commented

A path element's "d" attribute for an arc (such as those created with d3.arc) contain "A" commands ("elliptical arc curve commands"). They have five parameters, two of which are flags which can only be 0 or 1.

Unfortunately, some transitions can lead to these flags being linearly interpolated, leading to values such as 0.12345. At least in Chrome, this causes error messages. Here is an example:

http://codepen.io/anon/pen/qRrgLe
(You will need to open the console to see the error messages.)

Is there a chance to have these flags only assume the values 0 or 1 during a transition?

This is the expected behavior of transition.attr which uses d3.interpolateString to interpolate strings, and has no understanding of SVG path data.

If you want to use a path-aware interpolator, you should use transition.attrTween instead and supply a different interpolator. A convenient technique is to use a piecewise linear curve (a polyline) as the intermediate representation to allow smooth transitions between arbitrary shapes; see https://bl.ocks.org/mbostock/3916621 for an example.

rivo commented

Thanks for the explanation, this makes sense. What I ended up doing is use d3.interpolateString but override its result by rounding the 4th and 5th parameter in "A" (arc) commands:

transition.attrTween("d",function() {
  var basic = d3.interpolateString(d3.select(this).attr("d"),targetArc);
  return function(t) {
    return basic(t).replace(/A[^A-Z]+/g,function(match) {
      return "A" + match.substr(1).split(/[, ]+/).map(function(value,index) {
        return index == 3 || index == 4 ? String(Math.round(parseFloat(value))) : value;
      }).join(",");
    });
  };
})

This gets rid of the error messages when interpolating arcs (e.g. in pie charts).