我有一个输入控件应该在控件上的key up事件中根据是否按下左或右箭头键从饼图中添加或减去切片。它并没有像预期的那样真正起作用,因为似乎新的饼图切片有时会从现有的饼图切片中取出,并且整个图表不会被重新计算。我不确定我是否搞砸了enter
或exit
选项。感谢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);
答案 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,$);
答案 2 :(得分:0)
与使用此代码的方式相同:
svg.selectAll('path').append('g')
.data(pie(data))
.enter()
.append('path')
您可以使用:
svg.selectAll('path').append('g')
.data(pie(data))
.exit()
.remove()
这应该删除不再有与之关联的数据的饼图元素。