2017-03-21 27 views
3

このトピックは初めてのことですが、D3.js v4のハーフ・パイ/ハーフ・ドーナツ・チャートを作成しようとしています。結果は、次の例のグラフのようになります。http://bl.ocks.org/dbuezas/9306799D3 - ハーフ・パイ/ハーフ・ドーナツ・チャートにラベルとラインを配置する

私の問題は、これらのラベルと行の配置です。ここで

は私の現在のコードです:

<!DOCTYPE html> 
<meta charset="utf-8"> 
<body> 
<script src="http://d3js.org/d3.v4.min.js"></script> 
<script> 

var data = [ 
    {name: "ABC", val: 11975}, 
    {name: "DEF", val: 5871}, 
    {name: "GEH", val: 8916} 
]; 

var margin = { 
    top: 40, 
    right: 40, 
    bottom: 40, 
    left: 40 
}; 

var width = 800 - margin.right - margin.left; 
var height = 400 - margin.top - margin.bottom; 
var radius = 300; 

var svg = d3.select('body') 
    .append('svg') 
    .attr('width', width) 
    .attr('height', height) 
    .append('g') 
    .attr('transform', 'translate(' + width/2 + ',' + height + ')'); 

svg.append('g') 
    .attr('class', 'slices'); 
svg.append('g') 
    .attr('class', 'labels'); 
svg.append('g') 
    .attr('class', 'lines'); 

var color = d3.scaleOrdinal(d3.schemeCategory20); 

var pie = d3.pie() 
    .sort(null) 
    .value(function (d) { 
     return d.val; 
    }) 
    .startAngle(-90 * (Math.PI/180)) 
    .endAngle(90 * (Math.PI/180)); 

// donut chart arc 
var arc = d3.arc() 
    .innerRadius(radius - 100) 
    .outerRadius(radius - 50); 

var slice = svg.select('.slices') 
    .selectAll('path.slice') 
    .data(pie(data)); 

slice.enter() 
    .append('path') 
    .attr('d', arc) 
    .attr('fill', function (d) { 
     return color(d.data.name); 
    }) 
    .attr('class', 'slice'); 

var sliceDots = svg.select('.slices') 
    .selectAll('circle') 
    .data(pie(data)); 

sliceDots.enter() 
    .append('circle') 
    .attr('class', 'dot') 
    .attr('cx', function (d) { 
     return arc.centroid(d)[0]; 
    }) 
    .attr('cy', function (d) { 
     return arc.centroid(d)[1]; 
    }) 
    .attr('r', 2) 
    .attr('fill', 'black'); 

// label arc 
var labelArc = d3.arc() 
    .innerRadius(radius * 0.9) 
    .outerRadius(radius * 0.9); 

var labels = svg.select('.labels') 
    .selectAll('text') 
    .data(pie(data)); 

labels.enter() 
    .append('text') 
    .attr('dy', '.35em') 
    .attr('text-anchor', 'middle') 
    .attr('class', 'labels') 
    .text(function (d) { 
     return d.data.name; 
    }) 
    .attr('transform', function (d) { 
     return 'translate(' + labelArc.centroid(d)[0] + ',' + labelArc.centroid(d)[1] + ')'; 
    }); 

// lines 
var polyline = svg.select('.lines') 
    .selectAll('polyline') 
    .data(pie(data)); 

polyline.enter() 
    .append('polyline') 
    .attr('stroke-width', '2px') 
    .attr('stroke', 'black') 
    .attr('opacity', '0.4') 
    .attr('points', function (d) { 
     return [arc.centroid(d), labelArc.centroid(d)]; 
    }); 
</script> 
</body> 

は、このための簡単な解決策はありますか?

+0

。 –

+0

ラベルをどこに配置しようとしていますか?パス上かパス外か?また、それらを回転させたいですか? – stijena

+0

パス上にラベルを配置しようとしていて、ラベルを回転しないでください。おそらく、より広い半径を持つ第2の円弧オブジェクトで作業する方が簡単でしょう。 –

答えて

1

重心を使うのは良いアプローチだと思うので、ちょうどgetTextWidth(ここから:Calculate text width with JavaScript)メソッドを追加して、値ラベルの長さを決定し、それを左に移動します。ここで

.attr("transform", function (d) { 
    var textWidth = getTextWidth(d.data.val.toString(), "Arial"); 
    return "translate(" + (arc.centroid(d)[0] - textWidth) + "," + arc.centroid(d)[1] + ")"; 
}) 

はJSFiddleです:私はあなたがラベルを表示するための**変換属性を変更すべきだと思うhttps://jsfiddle.net/w6d4hcb9/2/

+1

ありがとうございますが、ドーナツの外側にラベルが必要です。私は以前のソリューションを変更し、ラベルの2番目の弧を追加しました。あなたは常に左に位置を移動しているが、私はそれが角度に依存しなければならないと思う:左の左と右の右のラベル。 私の現在のバージョンのJSFiddleがあります:https://jsfiddle.net/Lnj00so0/ –

関連する問題