2014-01-13 4 views
0

버튼을 클릭하면 도넛 형 차트에 새 데이터 세트를 추가하고 새 데이터 세트를 전환하려고합니다. 내가 작성한 코드는 그 일을하지만, 데이터 세트 내의 개별 데이터 수가 이전의 [1,2]에서 [1,2,3,4]로 바뀌면 문제가된다.d3, js로 도넛 형 차트의 데이터 세트 변경

새로운 데이터 세트에 더 많은 데이터가있을 때마다 새 경로를 만들어야하고 더 적은 데이터가있을 때마다 경로를 제거해야한다고 생각합니다. 그러나 클릭 기능에서 데이터를 추가하려고하면 이전 경로를 제거하지 않고 추가하고 차트에서 중복됩니다. http://jsfiddle.net/njrPF/1/

다음
var pieW = 500; 
var pieH = 500; 
var innerRadius = 100; 
var outerRadius = 200; 

var results_pie = d3.layout.pie() 
    .sort(null); 
var pie_arc = d3.svg.arc() 
    .innerRadius(innerRadius) 
    .outerRadius(outerRadius); 

var svg_pie = d3.select("#pieTotal") 
    .attr("width", pieW) 
    .attr("height", pieH) 
    .append("g") 
    .attr("transform", "translate(" + pieW/2 + "," + pieH/2 + ")") 
    .attr("class", "piechart"); 

var pie_path = svg_pie.selectAll("path").data(results_pie([1, 2])) 
    .enter().append("path") 
    .attr("d", pie_arc) 
    .each(function (d) { 
    this._current = d; 
}) // store the initial values 
.attr("class", "vote_arc") 
    .attr("value", function (d, i) { 
    return (i - 1); 
}); 


var pie_votes = [1, 2]; 
var pie_colors = ["#0f0", "#f00"]; 
$(svg_pie).bind("monitor", worker); 
$(svg_pie).trigger("monitor"); 

function worker(event) { 
    pie_path = pie_path.data(results_pie(pie_votes)) 
     .attr("fill", function (d, i) { 
     return pie_colors[i]; 
    }); 

    pie_path.transition().duration(500).attrTween("d", arcTween).each('end', function (d) { 
     if (d.value <= 0) { 
      this.remove(); 
     } 
    }); 
    setTimeout(function() { 
     $(svg_pie).trigger("monitor"); 
    }, 500); 
} 

function arcTween(a) { 
    var i = d3.interpolate(this._current, a); 
    this._current = i(0); 
    return function (t) { 
     return pie_arc(i(t)); 
    }; 
} 

$('button').click(function() { 
    pie_votes = []; 
    pie_colors = []; 
    for (var i = 0; i < Math.floor(Math.random() * 6); i++) { 
     //sets new values on pie arcs 
     pie_votes.push(Math.floor(Math.random() * 10)); 
     pie_colors.push("#" + (Math.floor(Math.random() * 16777215)).toString(16)); 
    } 
    pie_path = pie_path.data(results_pie(pie_votes)) 
     .attr("fill", function (d, i) { 
     return pie_colors[i] 
    }); 

    pie_path.transition().duration(500).attrTween("d", arcTween).each('end', function (d) { 
     if (d.value <= 0) { 
      this.remove(); 
     } 
    }); 
}); 

가 있습니다 : 여기

내가 경로를 추가하지 않기 때문에 arctween이 (arctween 반 시간 작동) 빈 파이 호를 작동하지만이있을 곳, 추가가없는 버전입니다 버전 나는 새로운 경로를 추가하려고하지만 그들은 중복 여기서 사전에 http://jsfiddle.net/njrPF/3/

var pieW = 500; 
var pieH = 500; 
var innerRadius = 100; 
var outerRadius = 200; 

var results_pie = d3.layout.pie() 
    .sort(null); 
var pie_arc = d3.svg.arc() 
    .innerRadius(innerRadius) 
    .outerRadius(outerRadius); 

var svg_pie = d3.select("#pieTotal") 
    .attr("width", pieW) 
    .attr("height", pieH) 
    .append("g") 
    .attr("transform", "translate(" + pieW/2 + "," + pieH/2 + ")") 
    .attr("class", "piechart"); 

var pie_path = svg_pie.selectAll("path").data(results_pie([1, 2])) 
    .enter().append("path") 
    .attr("d", pie_arc) 
    .each(function (d) { 
    this._current = d; 
}) // store the initial values 
.attr("class", "vote_arc") 
    .attr("value", function (d, i) { 
    return (i - 1); 
}); 

function arcTween(a) { 
    var i = d3.interpolate(this._current, a); 
    this._current = i(0); 
    return function (t) { 
     return pie_arc(i(t)); 
    }; 
} 

$('button').click(function() { 
    pie_votes = []; 
    pie_colors = []; 
    for (var i = 0; i < Math.floor(Math.random() * 10); i++) { 
     //sets new values on pie arcs 
     pie_votes.push(Math.floor(Math.random() * 10)); 
     pie_colors.push("#" + (Math.floor(Math.random() * 16777215)).toString(16)); 
    } 
    pie_path = pie_path.data(results_pie(pie_votes)) 
     .enter().append("path") 
     .attr("d", pie_arc) 
     .each(function (d) { 
     this._current = d; }) // store the initial values 
    .attr("class", "vote_arc") 
     .attr("value", function (d, i) { 
     return (i - 1); 
    }); 
    pie_path.attr("fill", function (d, i) { 
     return pie_colors[i] 
    }); 

    pie_path.transition().duration(500).attrTween("d", arcTween).each('end', function (d) { 
     if (d.value <= 0) { 
      this.remove(); 
     } 
    }); 
}); 

감사합니다.

답변

1

입력 선택 및 종료 선택과 업데이트 선택을 처리해야합니다. 예를 들어 this tutorial을 참조하십시오. 귀하의 경우 관련 코드는

pie_path = pie_path.data(results_pie(pie_votes)); 

pie_path.enter().append("path") 
    .attr("d", pie_arc) 
    .each(function (d) { 
     this._current = d; 
    }) // store the initial values 
    .attr("class", "vote_arc") 
     .attr("value", function (d, i) { 
     return (i - 1); 
    }); 

pie_path.exit().remove(); 

예 : here입니다.

+0

감사합니다. remove() 후에 콜백을 수행 할 수 있습니까? 제거 (콜백)와 같은 것이겠습니까? – PGT

+1

콜백에서 무엇을하고 싶습니까? '.remove()'가 마지막 일 것입니다. –

+0

기본적으로 파이 데이터 변경 기능을 넣고 데이터와 색을 전달합니다. 완전히 새로운 세트의 데이터 (데이터 배열의 길이가 다른)를 삽입하는 경우 모든 것을 0으로 설정하여 처리합니다 (arctween과 같을 것입니다). '비우기'), 데이터 제거, 새 데이터 세트 초기화 및 새 데이터 애니 메이팅. 따라서 기본적으로 원형 차트의 이동을 조작하기 위해 위 코드의 변경된 버전을 4 번 호출합니다. – PGT

관련 문제