简体   繁体   English

D3 饼图初始渲染问题

[英]D3 Pie chart initial render issue

Looking at implementing a d3 pie chart, and the initial draw of the pie chart is not rendering properly.查看实现 d3 饼图,并且饼图的初始绘制未正确呈现。 Once I call a redraw (randomize top left) however, it falls into place as expected, and then future ones transition as expected.然而,一旦我调用重绘(随机化左上角),它就会按预期落到位,然后未来的按预期过渡。

Am I doing something wrong here when initializing the chart for the first time?第一次初始化图表时,我在这里做错了什么吗?

https://codepen.io/MattN96/pen/xxdVjRN https://codepen.io/MattN96/pen/xxdVjRN

<!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="//cdnjs.cloudflare.com/ajax/libs/d3/5.9.2/d3.min.js" data-semver="5.9.2" data-require="d3@*"></script>
<script>
  
 var arc, outerArc, width, height, radius;
  
 var pie = d3.pie()
    .sort(null)
    .value(function(d) {
        return d.value;
    });
  
  var key = function(d){ return d.data.label; };

  var color = d3.scaleOrdinal()
    .domain(["Lorem ipsum", "dolor sit", "amet"])
    .range(["#98abc5", "#6b486b", "#d0743c", "#ff8c00"]);


function randomData (){
    var labels = ["Lorem ipsum", "dolor sit", "amet"];
    return labels.map(function(label){
        return { label: label, value: Math.random() }
    });
}

initialRender(randomData());  
  
redraw(randomData());
 
d3.select(".randomize")
    .on("click", function(){
        redraw(randomData()); 
    });
 
 
function initialRender(data){
  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");

 
width = 960;
    height = 450;
    radius = Math.min(width, height) / 2;
 
var pie = d3.pie()
    .sort(null)
    .value(function(d) {
        return d.value;
    });

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

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

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

}
function redraw(data) { 

  var pieData = pie(data);
  
  var svg = d3.select("body")
  
  
    var text = svg.select(".labels").selectAll("text")
        .data(pieData, 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(pieData, 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();
  
    /* ------- PIE SLICES -------*/
  
    var slice = svg.select(".slices").selectAll("path.slice")
        .data(pieData, 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 -------*/

};

</script>
</body>


 

You are very close.你很亲近。 Your problem is here:你的问题在这里:

text.transition().duration(1000)

Likewise for the polyline and slice transitions.对于折线和切片过渡也是如此。 On the first render there is no actual text on the dom selected in the variable text .在第一次渲染时,变量text选择的 dom 上没有实际text You subsequently append the text, but appending does not alter your original selection variable.您随后附加了文本,但附加不会改变您的原始选择变量。 You need to reselect each after the enter, append.您需要在输入后重新选择每个,追加。 Selecting the enter append didn't work later because future enter append selections would be empty (you never add any new slices, etc)选择 enter append 以后不起作用,因为以后的 enter append selections 将为空(您永远不会添加任何新切片等)

 var arc, outerArc, width, height, radius;
  
 var pie = d3.pie()
    .sort(null)
    .value(function(d) {
        return d.value;
    });
  
  var key = function(d){ return d.data.label; };

  var color = d3.scaleOrdinal()
    .domain(["Lorem ipsum", "dolor sit", "amet"])
    .range(["#98abc5", "#6b486b", "#d0743c", "#ff8c00"]);


function randomData (){
    var labels = ["Lorem ipsum", "dolor sit", "amet"];
    return labels.map(function(label){
        return { label: label, value: Math.random() }
    });
}

initialRender(randomData());  
  
redraw(randomData());
 
d3.select(".randomize")
    .on("click", function(){
        redraw(randomData()); 
    });
 
 
function initialRender(data){
  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");

 
width = 960;
    height = 450;
    radius = Math.min(width, height) / 2;
 
var pie = d3.pie()
    .sort(null)
    .value(function(d) {
        return d.value;
    });

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

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

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

}
function redraw(data) { 

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

    text.enter()
        .append("text")
        .attr("dy", ".35em")
        .text(function(d) {
            return d.data.label;
        });
    
  var textPath= svg.selectAll('text')
  
    function midAngle(d){ 
        return d.startAngle + (d.endAngle - d.startAngle)/2;
    }

    textPath.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(pieData, key);
    
    polyline.enter()
        .append("polyline");
  
  var polyPath= svg.selectAll('polyline')
  
    polyPath.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];
            };          
        }); 
    
    polyPath.exit()
        .remove();
  
    /* ------- PIE SLICES -------*/
  
    var slice = svg.select(".slices").selectAll("path.slice")
        .data(pieData, key);

    slice.enter()
        .insert("path")
        .style("fill", function(d) { return color(d.data.label); })
        .attr("class", "slice");
  
  
  var slicePath = svg.selectAll('.slice')
  
 
    slicePath       
        .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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM