2016-10-13 1 views
3

Ich versuche, das folgende Donut-Diagramm von d3.js v3 zu d3.js v4 zu aktualisieren.d3-Übergang attrTween, styleTween Methoden werden nicht in d3 Version 4 ausgelöst

http://bl.ocks.org/dbuezas/9306799

Ich habe alle alten Version Methodennamen mit den equivalant Methoden in eine neue Version ersetzt.

d3.scale.ordinal() zu d3.scaleOrdinal()

d3.layout.pie() zu d3.pie()

d3.svg .arc() zu d3.arc()

Die "d" Attribut des Pfad-Tags wird nicht generiert.

Und die Methoden "attrTween und styleTween" nicht einmal in v4 ausgelöst zu werden.

Ich habe dafür eine plunker erstellt.

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style> 

body { 
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 
    width: 960px; 
    height: 500px; 
    position: relative; 
} 

svg { 
    width: 100%; 
    height: 100%; 
} 

path.slice{ 
    stroke-width:2px; 
} 

polyline{ 
    opacity: .3; 
    stroke: black; 
    stroke-width: 2px; 
    fill: none; 
} 

</style> 
<body> 
<button class="randomize">randomize</button> 

<script src="http://d3js.org/d3.v4.min.js"></script> 
<script> 

var svg = d3.select("body") 
    .append("svg") 
    .append("g") 

svg.append("g") 
    .attr("class", "slices"); 
svg.append("g") 
    .attr("class", "labels"); 
svg.append("g") 
    .attr("class", "lines"); 

var width = 960, 
    height = 450, 
    radius = Math.min(width, height)/2; 

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

var arc = d3.arc() 
    .outerRadius(radius * 0.8) 
    .innerRadius(radius * 0.4); 

var outerArc = d3.arc() 
    .innerRadius(radius * 0.9) 
    .outerRadius(radius * 0.9); 

svg.attr("transform", "translate(" + width/2 + "," + height/2 + ")"); 

var key = function(d){ return d.data.label; }; 

var color = d3.scaleOrdinal() 
    .domain(["Lorem ipsum", "dolor sit", "amet", "consectetur", "adipisicing", "elit", "sed", "do", "eiusmod", "tempor", "incididunt"]) 
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]); 

function randomData(){ 
    var labels = color.domain(); 
    return labels.map(function(label){ 
     return { label: label, value: Math.random() } 
    }); 
} 

change(randomData()); 

d3.select(".randomize") 
    .on("click", function(){ 
     change(randomData()); 
    }); 


function change(data) { 

    /* ------- PIE SLICES -------*/ 
    var slice = svg.select(".slices").selectAll("path.slice") 
     .data(pie(data), key); 

    slice.enter() 
     .insert("path") 
     .style("fill", function(d) { return color(d.data.label); }) 
     .attr("class", "slice"); 

    slice  
     .transition().duration(1000) 
     .attrTween("d", function(d) { 
      this._current = this._current || d; 
      var interpolate = d3.interpolate(this._current, d); 
      this._current = interpolate(0); 
      return function(t) { 
       return arc(interpolate(t)); 
      }; 
     }) 

    slice.exit() 
     .remove(); 

    /* ------- TEXT LABELS -------*/ 

    var text = svg.select(".labels").selectAll("text") 
     .data(pie(data), key); 

    text.enter() 
     .append("text") 
     .attr("dy", ".35em") 
     .text(function(d) { 
      return d.data.label; 
     }); 

    function midAngle(d){ 
     return d.startAngle + (d.endAngle - d.startAngle)/2; 
    } 

    text.transition().duration(1000) 
     .attrTween("transform", function(d) { 
      this._current = this._current || d; 
      var interpolate = d3.interpolate(this._current, d); 
      this._current = interpolate(0); 
      return function(t) { 
       var d2 = interpolate(t); 
       var pos = outerArc.centroid(d2); 
       pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1); 
       return "translate("+ pos +")"; 
      }; 
     }) 
     .styleTween("text-anchor", function(d){ 
      this._current = this._current || d; 
      var interpolate = d3.interpolate(this._current, d); 
      this._current = interpolate(0); 
      return function(t) { 
       var d2 = interpolate(t); 
       return midAngle(d2) < Math.PI ? "start":"end"; 
      }; 
     }); 

    text.exit() 
     .remove(); 

    /* ------- SLICE TO TEXT POLYLINES -------*/ 

    var polyline = svg.select(".lines").selectAll("polyline") 
     .data(pie(data), key); 

    polyline.enter() 
     .append("polyline"); 

    polyline.transition().duration(1000) 
     .attrTween("points", function(d){ 
      this._current = this._current || d; 
      var interpolate = d3.interpolate(this._current, d); 
      this._current = interpolate(0); 
      return function(t) { 
       var d2 = interpolate(t); 
       var pos = outerArc.centroid(d2); 
       pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1); 
       return [arc.centroid(d2), outerArc.centroid(d2), pos]; 
      };   
     }); 

    polyline.exit() 
     .remove(); 
}; 

</script> 
</body> 

Vielen Dank im Voraus.

Antwort

3

Die Muster enter, update und exit wurden geringfügig in v4 geändert. Sie müssen jetzt die .merge statement integrieren.

var slice = svg.select(".slices").selectAll("path.slice") 
    .data(pie(data), key); 

slice.enter() 
    .insert("path") 
    .style("fill", function(d) { return color(d.data.label); }) 
    .attr("class", "slice") //<-- enter selection 
    .merge(slice) //<-- merge back in update selection 
    .transition().duration(1000) 
    .attrTween("d", function(d) { 
     this._current = this._current || d; 
     var interpolate = d3.interpolate(this._current, d); 
     this._current = interpolate(0); 
     return function(t) { 
      return arc(interpolate(t)); 
     }; 
    }); 

Aktualisiert plunker.

Verwandte Themen