2016-12-10 5 views
3

d3.arcを使って生成された弧を別の弧の中に完全に入れようとしています。私は、 "自分で" 描くことでこれを行うことができますd3.arcを別のものにネストする方法は?

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
</head> 
 

 
<body> 
 
    <script> 
 
    function arc_position(x, y, radius, angle) { 
 
     return { 
 
     x: x + (radius * Math.cos(angle)), 
 
     y: y + (radius * Math.sin(angle)) 
 
     }; 
 
    } 
 

 
    function describe_arc(x, y, radius, startAngle, endAngle) { 
 

 
     var s = arc_position(x, y, radius, endAngle); 
 
     var e = arc_position(x, y, radius, startAngle); 
 

 
     var sweep = e - s <= 180 ? '0' : '1'; 
 

 
     var d = [ 
 
     'M', s.x, s.y, 
 
     'A', radius, radius, 0, sweep, 0, e.x, e.y 
 
     ].join(' '); 
 

 
     return d; 
 
    } 
 

 
    var svg = d3.select("body") 
 
     .append("svg") 
 
     .attr("width", 500) 
 
     .attr("height", 500) 
 
     .append("g"); 
 
     
 
    var s = arc_position(250, 250, 200, Math.PI/2); 
 
    var e = arc_position(250, 250, 200, (Math.PI * 3)/2); 
 
     
 
    svg.append("path") 
 
     .style("fill", "none") 
 
     .style("stroke", "orange") 
 
     .style("stroke-width", "20px") 
 
     .attr("d", describe_arc(250,250,180,(Math.PI * 3)/2, Math.PI/2)); 
 
     
 
    svg.append("path") 
 
     .style("fill", "none") 
 
     .style("stroke", "orange") 
 
     .style("stroke-width", "20px") 
 
     .attr("d", "M" + (s.x + 30) + "," + s.y + "L" + (e.x + 30) + "," + e.y); 
 

 
    svg.append("path") 
 
     .style("fill", "none") 
 
     .style("stroke", "steelblue") 
 
     .style("stroke-width", "20px") 
 
     .attr("d", describe_arc(250,250,200,(Math.PI * 3)/2, Math.PI/2)); 
 
    
 
    svg.append("path") 
 
     .style("fill", "none") 
 
     .style("stroke", "steelblue") 
 
     .style("stroke-width", "20px") 
 
     .attr("d", "M" + (s.x + 10) + "," + s.y + "L" + (e.x + 10) + "," + e.y); 
 
    
 
    </script> 
 
</body> 
 

 
</html>

しかし、私はd3.arcを使用しての方法論を理解することはできません。

<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
    </head> 
 

 
    <body> 
 
    <script> 
 
     
 
     var svg = d3.select("body") 
 
     .append("svg") 
 
     .attr("width", 500) 
 
     .attr("height", 500) 
 
     .append("g") 
 
     .attr("transform","translate(250,250)"); 
 
     
 
     var arc = d3.arc() 
 
     .innerRadius(0) 
 
     .outerRadius(200) 
 
     .startAngle(0) 
 
     .endAngle(Math.PI); 
 

 
     svg.append("path") 
 
     .style("fill", "none") 
 
     .style("stroke", "steelblue") 
 
     .style("stroke-width", "20px") 
 
     .attr("d", arc()); 
 
     
 
     arc.outerRadius(200 - 40); 
 
     
 
     svg.append("path") 
 
     .style("fill", "none") 
 
     .style("stroke", "orange") 
 
     .style("stroke-width", "20px") 
 
     .attr("d", arc()) 
 
     .attr("transform", "translate(20,0)") 
 
     
 
    </script> 
 
    </body> 
 

 
</html>

アイデア?

+2

@gerardofurtado、任意のアイデア? – Mark

+1

メイト、私は賞賛されますが、あなたに比べて私はまだ学習者です! –

答えて

4

として同じ中心を持つべきであることは、のセクションを描画するためのものですので、私はちょうどd3.arcを使用して、これを行うには良い方法はないと思いますあなたは部分的な楕円を描こうとしています。

ストローク幅と内側円弧の半径をoffsetAngle = sin(stroke width/inner radius)として角度オフセットを生成することで、近づけることができます。弧のstartAngleoffsetAngleで、endAngleMath.PI - offsetAngleです。

残念ながら、それは円の中心点を含むパスを生成します。あなたは生成されたパス(innerArc().replace("L0,0",""))からL0,0を削除するだけで動作するものを一緒にハックすることができます。これは醜い方法ではあるが、あなたが望むものを与えるでしょう。

これはかなり単純なパスなので、代わりに独自のパスジェネレータを使用することをお勧めします。

<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
    </head> 
 

 
    <body> 
 
    <script> 
 
     
 
     var svg = d3.select("body") 
 
     .append("svg") 
 
     .attr("width", 500) 
 
     .attr("height", 500) 
 
     .append("g") 
 
     .attr("transform","translate(250,250)"); 
 
     
 
     var outerRadius = 200; 
 
     var stroke = 20; 
 
     var innerRadius = outerRadius - stroke; 
 
     var innerAngle = Math.sin(stroke/innerRadius); 
 

 
     var outerArc = d3.arc() 
 
     .innerRadius(0) 
 
     .outerRadius(outerRadius) 
 
     .startAngle(0) 
 
     .endAngle(Math.PI); 
 

 
     var innerArc = d3.arc() 
 
     .innerRadius(0) 
 
     .outerRadius(innerRadius) 
 
     .startAngle(innerAngle) 
 
     .endAngle(Math.PI - innerAngle); 
 

 
     svg.append("path") 
 
     .style("fill", "none") 
 
     .style("stroke", "steelblue") 
 
     .style("stroke-width", stroke) 
 
     .attr("d", outerArc()); 
 
     
 
     svg.append("path") 
 
     .style("fill", "none") 
 
     .style("stroke", "orange") 
 
     .style("stroke-width", stroke) 
 
     .attr("d", innerArc().replace("L0,0","")); 
 
     
 
    </script> 
 
    </body> 
 

 
</html>

+0

Upvoted、これは正しい説明だと思います。 –

+0

すばらしい答え... – Mark

0

外側の半径をR - 2 * strokewidth、中心をstrokewidthだけシフトした2番目の円弧を描画します。

しかし、小さなアークが大きい方と外半径R - strokewidth

2

(これは答えが、私はSOスニペットを必要とするので、私は答えとして偽装することを選んだだけのコメントではない)

私はPaul Sと信じていますそれは大きな賞の緑のダニの価値がある:内側(オレンジ色)のパスにペイントしようとしているのはではない円の弧代わりに楕円があります。そして、ドキュメントが言うように、

アーク発生器は、楕円セ​​クタを作成するために動作しません、円形または環状のセクタ

を生成します。

次のデモでは、forループを使用して、外半径を小さくしてアークを描画しています。

<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
    </head> 
 

 
    <body> 
 
    <script> 
 
     
 
     var svg = d3.select("body") 
 
     .append("svg") 
 
     .attr("width", 500) 
 
     .attr("height", 500) 
 
     .append("g") 
 
     .attr("transform","translate(250,250)"); 
 
     
 
     var arc = d3.arc() 
 
     .innerRadius(0) 
 
     .outerRadius(200) 
 
     .startAngle(0) 
 
     .endAngle(Math.PI); 
 
     
 
     var color = d3.scaleOrdinal(d3.schemeCategory10); 
 
     
 
     for(var i = 0; i<11; i++){ 
 

 
     svg.append("path") 
 
     .style("stroke", color(i)) 
 
     .style("fill", "none") 
 
     .style("stroke-width", "20px") 
 
     .attr("d", arc()); 
 
     
 
     arc.outerRadius(200 - 20*i); 
 
     
 
     }; 
 
     
 
    </script> 
 
    </body> 
 

 
</html>

でも簡単にあります:次の、小さなアーチが同じ中心前例の、大きなものを持っている場合は完全に各アークの内部空間を埋めるための唯一の方法ですそれを視覚化する方法。のは、巨大なストロークで、単一の円弧を作成してみましょう:

<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="d[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
    </head> 
 

 
    <body> 
 
    <script> 
 
     
 
     var svg = d3.select("body") 
 
     .append("svg") 
 
     .attr("width", 500) 
 
     .attr("height", 500) 
 
     .append("g") 
 
     .attr("transform","translate(250,250)"); 
 
     
 
     var arc = d3.arc() 
 
     .innerRadius(0) 
 
     .outerRadius(150) 
 
     .startAngle(0) 
 
     .endAngle(Math.PI); 
 

 
     svg.append("path") 
 
     .style("fill", "none") 
 
     .style("stroke", "steelblue") 
 
     .style("stroke-width", "100px") 
 
     .attr("d", arc()); 
 
     
 
     
 
    </script> 
 
    </body> 
 

 
</html>

はブルーアークを見て:それは半円です。それでは、内部の空白を見てください:それは明らかにではなく、半円です。青い物は半円ですが、その中の空間は半円ではありません。

だから、d3.arc()として今(あなたが行ったように)、オプションは独自の関数を作成しているか(ポール・Sが行ったように)パスをハッキング二つの異なる焦点を設定するオプションはありません。

関連する問題