2016-11-25 1 views
0

弧のパスに沿って円を移動させる弧の開始点を提供する方法を教えてください。私はそれに表示されたいくつかのアークを持つ世界地図を持っています。 .on('click')イベントを使用してユーザーが選択した円弧上の円の動きを補間したいと思います。問題の弧の始点をどのように特定できるかを知りたい。ユーザがクリックしたときに弧上の円を補間する開始点を指定します。

具体的には、アークの開始位置から円を開始できるようにするには、円の.attr("transform", "translate(" + startPoint + ")")属性にどのパラメータを指定するのか理解できません。現在

、それは全体の経路を通過して、驚くべきことに、円形マーカーが画面に表示され、描画された第一の円弧に沿って補間しているが、私は次のエラーを

d3.v3.min.js:1 Error: attribute transform: Expected number, "translate(M1051.5549785289…".

を受け取ります。しかし、この補間をユーザーがクリックした円弧に変更したいと思います。言い換えると、ユーザーが別の円弧をクリックするたびに円マークに新しいstartPointをどのように送り、後続の円弧を補間するのでしょうか。彼らのコメントで@altocumulus状態として

enter image description here

var path3 = arcGroup.selectAll(".arc"), 
    startPoint = pathStartPoint(path3) 

var marker = arcGroup.append("circle") 
marker.attr("r", 7) 
    .attr("transform", "translate(" + startPoint + ")") 

transition(); 

function pathStartPoint(path) { 
    var d = path.attr("d") 
    console.log(path) 
    dsplitted = d.split(" "); 
    return dsplitted[0].split(","); 
} 

function transition() { 
    marker.transition() 
    .duration(7500) 
    .attrTween("transform", translateAlong(path3.node())) 
    .each("end", transition);// infinite loop 
} 

function translateAlong(path) { 
    var l = path.getTotalLength(); 
    return function(i) { 
    return function(t) { 
     var p = path.getPointAtLength(t * l); 
     return "translate(" + p.x + "," + p.y + ")";//Move marker 
    } 
    } 
} 
+0

動作します。ここでは、以下のいずれかのパスをクリックして、簡単な例です。しかし、マーカーやその座標のリストを画面に表示することは可能ですか?それらの座標を渡している間にあなたのアーク関数を呼び戻すことができるはずです。または私はここに何かを逃していますか? – Lewis

+0

あなたの返事ありがとうございますルイス。アークが現在プロットされる方法は、LineStringを使用して、アークを描画する3つの座標を指定します。これらの座標はcsvファイルから読み込まれ、linksという配列に格納されます。 links.pushとそれに続く.enter()を使用して円弧をプロットする – sjaikumar

+1

@sjaikumar明示的に開始点に設定する必要はありません。遷移が実行されると、 't = 0'の開始値を持つ' translateAlong() 'の最も内側のインターポレータ関数が呼び出され、暗黙的に開始点が計算されます。 – altocumulus

答えて

1

getPointAtLengthは出発点を必要としません。 0から始点までの距離を引数としてとります。 、私は(そのことについて、またはD3)あなたが特定のスクリプトだか全くわからないんだけど

<!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 w = 400, 
 
     h = 400; 
 

 
    var svg = d3.select('body') 
 
     .append('svg') 
 
     .attr('width', w) 
 
     .attr('height', h); 
 

 
    var data = [] 
 
    for (var i = 0; i < 5; i++) { 
 
     data.push({ 
 
     x0: Math.random() * w, 
 
     y0: Math.random() * h, 
 
     x1: Math.random() * w, 
 
     y1: Math.random() * h 
 
     }); 
 
    } 
 

 
    var marker = svg.append("circle") 
 
     .attr("r", 20) 
 
     .style("fill", "steelblue") 
 
     .style("opacity", 0); 
 

 
    svg.selectAll("path") 
 
     .data(data) 
 
     .enter() 
 
     .append("path") 
 
     .attr("d", function(d) { 
 
     var dx = d.x1 - d.x0, 
 
      dy = d.y1 - d.y0, 
 
      dr = Math.sqrt(dx * dx + dy * dy); 
 
     return "M" + d.x0 + "," + d.y0 + "A" + dr + "," + dr + 
 
      " 0 0,1 " + d.x1 + "," + d.y1; 
 
     }) 
 
     .style("stroke", function(d, i) { 
 
     return d3.schemeCategory10[i]; 
 
     }) 
 
     .style("stroke-width", "10px") 
 
     .style("fill", "none") 
 
     .on("click", function(d){ 
 
      marker 
 
      .style("opacity", 1) 
 
      .transition() 
 
      .duration(1000) 
 
      .attrTween("transform", translateAlong(this)) 
 
      .on("end", function(d) { 
 
       marker.style("opacity", 0); 
 
      }); 
 
     }); 
 

 
    function translateAlong(path) { 
 
     var l = path.getTotalLength(); 
 
     return function(i) { 
 
     return function(t) { 
 
      var p = path.getPointAtLength(t * l); 
 
      return "translate(" + p.x + "," + p.y + ")"; //Move marker 
 
     } 
 
     } 
 
    } 
 
    </script> 
 
</body> 
 

 
</html>

+0

それは魅力のように働いた。その背後にある理論を説明してくれてありがとう、そして例を通してそれを説明するためのあなたの時間をありがとう。あなたには感謝してもしきれません :) – sjaikumar

関連する問題