D3.js添加/删除数据饼图切片

时间:2015-05-21 21:20:17

标签: javascript d3.js

我有一个输入控件应该在控件上的key up事件中根据是否按下左或右箭头键从饼图中添加或减去切片。它并没有像预期的那样真正起作用,因为似乎新的饼图切片有时会从现有的饼图切片中取出,并且整个图表不会被重新计算。我不确定我是否搞砸了enterexit选项。感谢TIA。

小提琴http://jsfiddle.net/jaqj3usb/

相关代码

function removeSlices(n){
        var i = -1;
        while(++i < n){
            data.pop();
        }

        paths.data(pie(data)).exit().remove();
        paths.data(pie(data)).attr('d',arc).attr('transform','translate(100,200)')

    }

    function changeSlices(){
        console.log('woot');
        var shouldAddSlice = d3.event.target.valueAsNumber > data.length,
            numDifference = Math.abs(data.length - d3.event.target.valueAsNumber);
        if(shouldAddSlice){
            addSlices(numDifference);
        }
        else{
            removeSlices(numDifference);
        }
    }
    sliceSlider.on('keyup',changeSlices);

3 个答案:

答案 0 :(得分:1)

这是第一个变体(我认为这是正确的),基于此请添加注释,因为从开始svg添加到页面后你没有正确计算。

你可以删除这样的单个饼图切片,但这不会更新你的盘子:

svg.selectAll('path')[0][pos].remove();

其中pos 0&lt; data.length(原始代码不正确)

以这种方式添加您重叠未移动的切片:

paths
            .data(pie(data))
            .enter()
            .append('path')
            .attr('d',arc)
            .attr('transform','translate(100,200)')
            .attr('fill',function(d,i){
                return colors[i]
            }); 

总之:

<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>Eat my pie</title>
  <script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.js"></script>
    <script type='text/javascript'>
    window.onload=function(){
    /**
     * Created by cecild on 5/21/2015.
     * Updated by SilentTremor 5/25/2015.
     */
    (function(d3){
        svg = d3.select('body').append('svg').attr({
            height: 800,
            width: 900,
            id: 'mySvg'
        });
        var data = [10];
        var sliceSlider = d3.select('body').append('input').attr({
            type: 'range',
            max: 10,
            min: 1,
            value : data.length
        });

        var colors=['orange','blue','steelblue','green','red','yellow','purple','pink','indigo'];
        var pie = d3.layout.pie();
        pie.value(function(d){ return d});

        var arc = d3.svg.arc().innerRadius(10).outerRadius(100);

        var paths = svg.selectAll('path').append('g')
            .data(pie(data))
            .enter()
            .append('path')
            .attr('d',arc)
            .attr('transform','translate(100,200)')
            .attr('fill',function(d,i){
                return colors[i]
            });

        function addSlices(n){
            var i = -1;
            function randomBetween(min,max){
                return Math.floor(Math.random()*(max-min+1)+min);
            }
            while(++i <n){
                data.push(randomBetween(10,50));
            }
            svg.selectAll("path").remove();

            paths = svg.selectAll('path').append('g')
                .data(pie(data))
                .enter()
                .append('path')
                .attr('d',arc)
                .attr('transform','translate(100,200)')
                .attr('fill',function(d,i){
                    return colors[i]
                });
        }
        function removeSlices(n){
            var i = -1;
            while(++i < n){
                data.pop();
            }

            svg.selectAll("path").remove()

            paths = svg.selectAll('path').append('g')
                .data(pie(data))
                .enter()
                .append('path')
                .attr('d',arc)
                .attr('transform','translate(100,200)')
                .attr('fill',function(d,i){
                    return colors[i]
                });
        }

        function changeSlices(){
            var shouldAddSlice = d3.event.target.valueAsNumber > data.length,
                numDifference = Math.abs(data.length - d3.event.target.valueAsNumber);
            if(shouldAddSlice){
                addSlices(numDifference);
            }
            else{
                removeSlices(numDifference);
            }
        }
        sliceSlider.on('keyup',changeSlices);
    })(window.d3);

    }

</script>
</head>
<body>
</body>
</html>

答案 1 :(得分:1)

我也是D3js的新手,正在努力学习。我使用jQuery来处理keyup事件。我做了一些更改,所以左箭头添加,右箭头减去切片。

将jquery作为参数传递给自执行函数

(function(d3, $) {
})(window.d3, $);

在addSlices()中更改了

 paths
        .data(pie(data))
        .enter()
        .append('path')
        .attr('d',arc)
        .attr('transform','translate(100,200)')
        .attr('fill',function(d,i){
            return colors[i]
        });

paths.data(pie([])).exit().remove();

    paths = svg.selectAll('path').append('g')
    .data(pie(data))
    .enter()
    .append('path')
    .attr('d',arc)
    .attr('transform','translate(100,200)')
    .attr('fill',function(d,i){
        return colors[i];
    });

上面的代码删除并重绘了饼图。

完整代码:

(function(d3,$){
var svg = d3.select('body').append('svg').attr({
    height: 500,
    width: 500,
    id: 'mySvg'
});
var data = [10,20,30];
var sliceSlider = d3.select('body').append('input').attr({
    type: 'range',
    max: 10,
    min: 1,
    value : data.length
});

var colors=['orange','blue','steelblue','green','red','yellow','purple','pink','indigo'];
var pie = d3.layout.pie();
pie.value(function(d){ return d});

var arc = d3.svg.arc().innerRadius(10).outerRadius(100);

var paths = svg.selectAll('path').append('g')
    .data(pie(data))
    .enter()
    .append('path')
    .attr('d',arc)
    .attr('transform','translate(100,200)')
    .attr('fill',function(d,i){
        return colors[i]
    });

function addSlices(n){
    var i = -1;
    function randomBetween(min,max){
        return Math.floor(Math.random()*(max-min+1)+min);
    }
    while(++i <n){
        data.push(randomBetween(10,50));
    }
    paths.data(pie([])).exit().remove();

    paths = svg.selectAll('path').append('g')
    .data(pie(data))
    .enter()
    .append('path')
    .attr('d',arc)
    .attr('transform','translate(100,200)')
    .attr('fill',function(d,i){
        return colors[i];
    });
}
function removeSlices(n){
    var i = -1;
    while(++i < n){
        data.pop();
    }

     paths.data(pie(data)).exit().remove();
    paths.data(pie(data)).attr('d',arc).attr('transform','translate(100,200)');

}

function changeSlices(){
    console.log('woot');
    var max=$("input[type='range']").attr("max")-data.length;
    var shouldAddSlice = max > data.length;
    if(shouldAddSlice){
        addSlices(1);
    }
}

$(document).keyup(function(e) {
    switch(e.which) {
        case 37: // left
            changeSlices();
        break;

        case 39: // right
            removeSlices(1);
        break;  

        default: return; // exit this handler for other keys
    }
    e.preventDefault(); // prevent the default action (scroll / move caret)
});
})(window.d3,$);

示例:http://jsfiddle.net/jaqj3usb/2/

答案 2 :(得分:0)

与使用此代码的方式相同:

svg.selectAll('path').append('g')
    .data(pie(data))
    .enter()
    .append('path')

您可以使用:

svg.selectAll('path').append('g')
    .data(pie(data))
    .exit()
    .remove()

这应该删除不再有与之关联的数据的饼图元素。