d3:为什么输入选择不显示任何转换的甜甜圈图

d3: Why is enter selection not showing any transition for a donut chart?

本文关键字:转换 任何 甜甜圈 显示 为什么 输入 选择 d3      更新时间:2023-09-26

我是d3库的新手。我试图在进入,更新和退出选择上创建一个过渡的甜甜圈图。我的代码灵感来自于这个小提琴。但与此不同的是,我的代码中没有发生转换。下面是代码-

crm = [
    {name: 'SMR', value: 3097},
    {name: 'PSF', value: 3374},
    {name: 'Insurance', value: 1225}
]
 pieTween = function(d, i) {
      var s0;
      var e0;
      if(oldPieData[i]){
        s0 = oldPieData[i].startAngle;
        e0 = oldPieData[i].endAngle;
      } else if (!(oldPieData[i]) && oldPieData[i-1]) {
        s0 = oldPieData[i-1].endAngle;
        e0 = oldPieData[i-1].endAngle;
      } else if(!(oldPieData[i-1]) && oldPieData.length > 0){
        s0 = oldPieData[oldPieData.length-1].endAngle;
        e0 = oldPieData[oldPieData.length-1].endAngle;
      } else {
        s0 = 0;
        e0 = 0;
      }
      var i = d3.interpolate({startAngle: s0, endAngle: e0}, {startAngle: d.startAngle, endAngle: d.endAngle});
      return function(t) {
        var b = i(t);
        return arc(b);
      };
}
var pie = Math.PI * 2;
var w = 500,
    h = 500;
var ir = 45;
var duration = 250;
var chart = d3.select('.chart')
                .attr('width', w)
                .attr('height',h)
createPieChart = function(data){
    var radius = 200;
    var total = 0;
    angular.forEach(data, function(item){
        total+=item.value;
    })
    color = d3.scale.ordinal()
            .range(['#469AB2', '#F0AD4E', '#5CB85C', '#D9534F']);

    groups = chart.append('g')
                .attr('transform', 'translate('+w/2+','+ h/2 + ')');
    // group at the center of donut
    center_group = chart.append('g')
                        .attr("class", "center_group")
                        .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");
    // displaying total calls at the center
    center_group.append('text')
                .attr('text-anchor', 'middle')
                .text(total);
    arc = d3.svg.arc()
            .innerRadius(radius-60)
            .outerRadius(radius)
    pieChart = d3.layout.pie()
                .value(function(d){ return d.value; });
    oldPieData = pieChart(data);
    arcs = groups.selectAll('path')
            .data(pieChart(data))
    arcsEnter = arcs.enter().append('path')
                .each(function(d) { this._current = d; });
    arcsEnter.attr('class', 'arc')
            .attr('fill', function(d){ return color(d.data.value)})
            .transition().duration(duration).attrTween("d", pieTween)
}
createPieChart(crm);

谁能帮我一下,告诉我为什么没有过渡?

这是我的代码

问题是oldPieData数组的初始值,在转换开始时它已经有了新数据的值。

crm = [
        {name: 'SMR', value: 3097},
        {name: 'PSF', value: 3374},
        {name: 'Insurance', value: 1225}
    ]
    pieTween = function(d, i) {
        var s0;
        var e0;
        if(oldPieData[i]){
            s0 = oldPieData[i].startAngle;
            e0 = oldPieData[i].endAngle;
        } else if (!(oldPieData[i]) && oldPieData[i-1]) {
            s0 = oldPieData[i-1].endAngle;
            e0 = oldPieData[i-1].endAngle;
        } else if(!(oldPieData[i-1]) && oldPieData.length > 0){
            s0 = oldPieData[oldPieData.length-1].endAngle;
            e0 = oldPieData[oldPieData.length-1].endAngle;
        } else {
            s0 = 0;
            e0 = 0;
        }
        var i = d3.interpolate({startAngle: s0, endAngle: e0}, {startAngle: d.startAngle, endAngle: d.endAngle});
        return function(t) {
            var b = i(t);
            return arc(b);
        };
    }
    var pie = Math.PI * 2;
    var w = 200,
        h = 180;
    var ir = 45;
    var duration = 250;
    var chart = d3.select('.chart')
        .attr('width', w)
        .attr('height',h);
    var pieChart = d3.layout.pie()
            .value(function(d){ return d.value; }),
        oldPieData = [];
    createPieChart = function(data){
        var radius = h/2;
        var total = 0;
        data.forEach(function(item){
            total+=item.value;
        }),
        color = d3.scale.ordinal()
            .range(['#469AB2', '#F0AD4E', '#5CB85C', '#D9534F']);
        groups = chart.append('g')
            .attr('transform', 'translate('+w/2+','+ h/2 + ')');
        // group at the center of donut
        var center_group = chart.append('g')
            .attr("class", "center_group")
            .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");
        // displaying total calls at the center
        center_group.append('text')
            .attr('text-anchor', 'middle')
            .text(total);
        arc = d3.svg.arc()
            .innerRadius(radius-h/4)
            .outerRadius(radius)
        var arcs = groups.selectAll('path')
            .data((pieChart(data))),
            arcsEnter = arcs.enter().append('path');
        arcs.attr('class', 'arc')
            .attr('fill', function(d){ return color(d.data.value)})
            .transition().duration(duration).attrTween("d", pieTween);
        return data;
    };
    createPieChart(crm);
.shady-background {
            background-color: #f5f5f5;
            border: 1px solid #e3e3e3;
            border-radius: 4px;
            box-shadow: 0 2px 2px rgba(0,0,0,.05);
        }
        div.shady-background{
            padding: 0.5%;
        }
        div.shady-background>span{
            margin-left: 30px;
        }
        #main-container {
            top:6.8em;
            position: relative;
        }
        .chart rect {
            fill: steelblue;
        }
        .chart text {
            /*  fill: white;*/
            font: 10px sans-serif;
        }
        #pie-chart-div {
            position: relative;
            top: 6em;
        }
        .chart {
            position: relative;
            /*	top: 2em;*/
            left: 5em;
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<svg class="chart"></svg>


这是一个干净的版本…

var crm = (function() {
        var prevData = [];
        return function crm(f) {
            var max = 10000;
            oldPieData = JSON.parse(JSON.stringify(prevData));
            prevData = f([
                {name: 'SMR', value: Math.random() * max},
                {name: 'PSF', value: Math.random() * max},
                {name: 'Insurance', value: Math.random() * max},
                {name: 'Other', value: Math.random() * max}
            ])
        }
    })();
    pieTween = function(d, i) {
        var s0;
        var e0;
        if(oldPieData[i]){
            s0 = oldPieData[i].startAngle;
            e0 = oldPieData[i].endAngle;
        } else if (!(oldPieData[i]) && oldPieData[i-1]) {
            s0 = oldPieData[i-1].endAngle;
            e0 = oldPieData[i-1].endAngle;
        } else if(!(oldPieData[i-1]) && oldPieData.length > 0){
            s0 = oldPieData[oldPieData.length-1].endAngle;
            e0 = oldPieData[oldPieData.length-1].endAngle;
        } else {
            s0 = 0;
            e0 = 0;
        }
        var i = d3.interpolate({startAngle: s0, endAngle: e0}, {startAngle: d.startAngle, endAngle: d.endAngle});
        return function(t) {
            var b = i(t);
            return arc(b);
        };
    };
    var pie = Math.PI * 2;
    var w = 200,
        h = 190;
    var ir = 45;
    var duration = 500;
    var chart = d3.select('.chart')
            .attr('width', w)
            .attr('height',h)
            .append('g')
            .attr('transform', 'translate('+w/2+','+ h/2 + ')'),
        pieChart = d3.layout.pie()
            .value(function(d){ return d.value; })
            .sort(null),
        oldPieData = [],
        groups = chart.append ("g")
            .attr("class", "groups"),
    // group at the center of donut
        center_group = chart.append('g')
            .attr("class", "center_group")
            .append('text')
            .attr({'text-anchor': 'middle', dy: "0.35em"});
    createPieChart = function(data){
        var radius = 92;
        var pieData,
            color = d3.scale.ordinal()
                .range(['#469AB2', '#F0AD4E', '#5CB85C', '#D9534F'])
                .domain(data.map(function(d){return d.name}));
        // displaying total calls at the center
        center_group.text(d3.format(",.1f")(d3.sum(data, function(d){return d.value})));
        arc = d3.svg.arc()
            .innerRadius(radius-50)
            .outerRadius(radius);
        var arcs = groups.selectAll('path')
            .data((pieData = pieChart(data)), function(d){return d.data.name});
        arcs.enter().append('path')
            .attr('class', 'arc');
        arcs.attr('fill', function(d){ return color(d.data.name)})
            .transition()
            .duration(duration)
            .attrTween("d", pieTween)
            .ease("bounce");
        return pieData;
    };
    crm(createPieChart);
    window.setInterval(function(){crm(createPieChart)}, 3000)
.shady-background {
            background-color: #f5f5f5;
            border: 1px solid #e3e3e3;
            border-radius: 4px;
            box-shadow: 0 2px 2px rgba(0,0,0,.05);
        }
        div.shady-background{
            padding: 0.5%;
        }
        div.shady-background>span{
            margin-left: 30px;
        }
        #main-container {
            top:6.8em;
            position: relative;
        }
        .chart rect {
            fill: steelblue;
        }
        .chart text {
            /*  fill: white;*/
            font: 10px sans-serif;
        }
        #pie-chart-div {
            position: relative;
            top: 6em;
        }
        .chart {
            position: relative;
            /*	top: 2em;*/
            left: 5em;
        }
<svg class="chart"></svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>