2017-09-29 12 views
2

D3.js 버전 4를 사용하여 도넛 형 차트를 작성 중입니다.이 차트를 이동하고 작게 만들려고합니다. 나는 그것을 움직일 수는 있지만 그것을 더 작게 만들 수는 없다.d3 : arcTween을 사용하여 도넛 형 차트를 부드럽게 트위닝하려면?

JSFiddle 여기를 클릭하십시오 : https://jsfiddle.net/5sar7yp9/ - 크기를 갑자기 큰 것으로부터 작은 것으로 어떻게 이동하는지 보려면 텍스트를 클릭하십시오.

나는 그것이 내 정의 인 arcTween과 관련이 있다고 의심하지만, 나는 정확히 무엇을 확신하지 못합니다. 어쩌면 인라인해야할까요?

전체 코드 :

function updateDataPoints(series, scales) { 
    var padAngle = 0.015, 
     cornerRadius = 3, 
     floatFormat = d3.format('.4r'), 
     radius = Math.min(scales.w, scales.h)/2; 
    var outerRadius = radius * 0.8, innerRadius = radius * 0.6; 
    var tPie = d3.pie() 
     .value(function(d) { return floatFormat(d.y); }) 
     .sort(null); 
    var tArc = d3.arc() 
     .outerRadius(outerRadius) 
     .innerRadius(innerRadius) 
     .cornerRadius(cornerRadius) 
     .padAngle(padAngle); 
    function arcTween(d) { 
     var i = d3.interpolate(this._current, d); 
     this._current = i(0); 
     return function(t) { return tArc(i(t)); }; 
    } 
    var points = series.select(".data-points") 
     .selectAll("path.data-point") 
     .data(function(d) { return tPie(d.data_points); }); 
    var points_enter = points.enter() 
     .append("path") 
     .each(function(d, i) { this._current = d; }) 
     .attr("class", "data-point arc") 
     .attr("opacity", 0) 
     .attr("d", tArc) 
     .attr("transform", 'translate(' + scales.w/2 + ',' + scales.h/2 + ")") 
     .transition().duration(1000) 
     .attr("fill", function(d) { return 'red'; }); 
    var points_update = points.merge(points_enter); 
    points_update 
     .attr("fill", function(d) { return 'red'; }) 
     .transition().duration(1000) 
     .attr("transform", 'translate(' + scales.w/2 + ',' + scales.h/2 + ")") 
     .attr("opacity", 0.8) 
     .transition().duration(1000) 
     .attrTween('d', arcTween); 
    points.exit().transition() 
     .duration(1000) 
     .attrTween("d", arcTween) 
     .remove(); 
} 

function updateSeries(chart_data, plot, scales) { 
    var series_data = [chart_data.series[0]]; 
    var series = plot.selectAll(".series").data(series_data); 
    var series_enter = series.enter().append("g").attr("class", "series"); 
    series_enter.append("g").attr("class", "data-points"); 
    var series_update = series.merge(series_enter); 
    series.exit().remove(); 
    updateDataPoints(series_update, scales); 
} 

var svg = d3.select("#chart").append("svg") 
    .attr("width", 300) 
    .attr("height", 300) 
    .append("g") 
    .attr("transform", "translate(100,100)"); 
var scales = { w: 100, h: 100}, 
    chart_data = { 
     'series': [{ 
      'data_points': [ 
       { x: 1999, y: 20000}, 
       { x: 2000, y: 12000}, 
       { x: 2001, y: 14000} 
      ] 
     }] 
    }, 
    plot = svg.append('g').attr('class', 'plot'); 
updateSeries(chart_data, plot, scales); 

d3.select('#update').on('click', function() { 
    scales.w = 50; 
    scales.h = 50; 
    updateSeries(chart_data, plot, scales); 

}); 
+0

오 사랑을! 왜 downvote? – Richard

+0

우연히, 전화를 걸었고 나는 아무 것도 클릭하지 않고 재편성하지 않았다. 질문을 편집하지 않으면 15 분이 지나면 수정하지 않겠습니다. 어색한 손가락, 죄송합니다, 지금은 수정되었습니다. –

답변

2

당신이 그것을 복잡 이상 생각합니다. 트위닝 함수는 축소하기 위해 도넛의 개별 세그먼트를 동적으로 늘리거나 줄이는 것과 같습니다. 그냥 부드럽게 크기를 조정하려면, 당신은 단지 경로의 d 속성 자체를 전환 할 수 있습니다

points_update 
    .attr("fill", function(d) { return 'red'; }) 
    .transition().duration(1000) 
    .attr("transform", 'translate(' + scales.w/2 + ',' + scales.h/2 + ")") 
    .attr("opacity", 0.8) 
    .transition().duration(1000) 
    .attr('d', function(d){ 
    return tArc(d); 
    }); 

를 코드를 실행 :

function updateDataPoints(series, scales) { 
 
\t var padAngle = 0.015, 
 
\t \t cornerRadius = 3, 
 
\t \t floatFormat = d3.format('.4r'), 
 
\t \t radius = Math.min(scales.w, scales.h)/2; 
 
\t var outerRadius = radius * 0.8, innerRadius = radius * 0.6; 
 
\t var tPie = d3.pie() 
 
\t \t .value(function(d) { return floatFormat(d.y); }) 
 
\t \t .sort(null); 
 
    
 
\t var tArc = d3.arc() 
 
\t \t .outerRadius(outerRadius) 
 
\t \t .innerRadius(innerRadius) 
 
\t \t .cornerRadius(cornerRadius) 
 
\t \t .padAngle(padAngle); 
 
    
 
\t var points = series.select(".data-points") 
 
\t \t .selectAll("path.data-point") 
 
\t \t .data(function(d) { return tPie(d.data_points); }); 
 
\t var points_enter = points.enter() 
 
\t \t .append("path") 
 
     .each(function(d, i) { this._current = d; }) 
 
\t \t .attr("class", "data-point arc") 
 
\t \t .attr("opacity", 0) 
 
\t \t .attr("d", tArc) 
 
\t \t .attr("transform", 'translate(' + scales.w/2 + ',' + scales.h/2 + ")") 
 
\t \t .transition().duration(1000) 
 
\t \t .attr("fill", function(d) { return 'red'; }); 
 
\t var points_update = points.merge(points_enter); 
 
\t points_update 
 
\t \t .attr("fill", function(d) { return 'red'; }) 
 
\t \t .transition().duration(1000) 
 
\t \t .attr("transform", 'translate(' + scales.w/2 + ',' + scales.h/2 + ")") 
 
\t \t .attr("opacity", 0.8) 
 
\t \t .transition().duration(1000) 
 
\t \t .attr('d', function(d){ 
 
    \t return tArc(d); 
 
    }); 
 
\t points.exit().transition() 
 
\t \t .duration(1000) 
 
\t \t .attr("d", "") 
 
\t \t .remove(); 
 
} 
 

 
function updateSeries(chart_data, plot, scales) { 
 
\t var series_data = [chart_data.series[0]]; 
 
\t console.log('series', series_data); 
 
\t var series = plot.selectAll(".series").data(series_data); 
 
\t var series_enter = series.enter().append("g").attr("class", "series"); 
 
\t console.log('updateSeries series_enter', series_enter.size()); 
 
\t series_enter.append("g").attr("class", "data-points"); 
 
\t var series_update = series.merge(series_enter); 
 
\t series.exit().remove(); 
 
\t console.log('updateSeries series_update', series_update.size()); 
 
\t updateDataPoints(series_update, scales); 
 
} 
 

 
var svg = d3.select("#chart").append("svg") 
 
    .attr("width", 300) 
 
    .attr("height", 300) 
 
    .append("g") 
 
    .attr("transform", "translate(100,100)"); 
 

 
var scales = { w: 100, h: 100}, 
 
\t chart_data = { 
 
\t \t 'series': [{ 
 
\t \t \t 'data_points': [ 
 
\t \t \t \t { x: 1999, y: 20000}, 
 
\t \t \t \t { x: 2000, y: 12000}, 
 
\t \t \t \t { x: 2001, y: 14000} 
 
\t \t \t ] 
 
\t \t }] 
 
\t }, 
 
\t plot = svg.append('g').attr('class', 'plot'); 
 

 
updateSeries(chart_data, plot, scales); 
 

 
d3.select('#update').on('click', function() { 
 
\t scales.w = 50; 
 
\t scales.h = 50; 
 
\t updateSeries(chart_data, plot, scales); 
 

 
});
<script src="https://d3js.org/d3.v4.min.js"></script> 
 
<div id="update">click text to tween...</div> 
 
\t <div id="chart"></div>