2017-12-01 5 views
0

こんにちは私はD3を使用して、この例のようなパスに沿ってマーカーの遷移を一時停止して再開しようとしていますD3 tween - pause and resume controlsこのようなデータポイントはD3 transition along segments of path and pause at coordinate valuesです。私はマーカーをクリックしてトランジションを開始していますが、それを停止してクリックしたときに再起動できるようにしたいと思っています。一時的に一時停止してから開始します。D3を停止してパスに沿って遷移し、ジオデータ座標をクリックスルーできるようにする

マーカーを完全に止めることができますので、ポイントを使って何かを行うことができます。つまり、jsonデータに基づいて特定のクリックされたポイントのxlink:hrefをクリックしてページを終了してからリターンしますマーカ遷移に移動し、停止した同じポイントからの遷移を再開する。

私はトランジション関数にpauseValuesを渡す必要があると思いますが、これを行う方法を理解できません。

これは私のコードです:

<!DOCTYPE html> 
<html lang="en"> 

<head> 
    <meta charset="utf-8"> 

    <script src="https://d3js.org/d3.v4.min.js"></script> 

<style type="text/css"> 
    body { 
    font-family: "Helvetica Neue", Helvetica, sans-serif; 
    color: red; 
    } 


    circle { 
    fill: steelblue; 
    stroke: steelblue; 
    stroke-width: 3px; 
    } 

    .point { 
    fill: green; 
    } 

    .line { 
    fill: none; 
    stroke: red; 
    stroke-width: 4; 
    stroke-dasharray: 4px, 8px; 
    } 

</style> 

<body> 

    <script> 
    var width = 960, 
     height = 500; 

    var data = [ 
    [610.4199794444444, 243.7191682432953], //Paris 
     [480, 200], 
     [580, 400], 
     [680, 100], 
     [780, 300], 
     [180, 300], 
     [280, 100], 
     [380, 400] 
    ]; 

    var duration = 20000/data.length, 
     pauseTime = 2000; 

    var line = d3.line() 
     .x(function(d) { 
     return (d)[0]; 
     }) 
     .y(function(d) { 
     return (d)[1]; 
     }); 

    var svg = d3.select("body") 
     .append("svg") 
     .attr("width", width) 
     .attr("height", height); 

    //path to animate - marker transitions along this path 
    var path = svg.append("path") 
     .data([data]) 
     .attr("d", line) 
     .attr('class', 'line') 
     .attr("d", function(d) { 
     return line(d) 
     }); 

    //Want to activate circles when marker paused on them - intention is to have on click to href and stop marker while href is displayed 
    svg.selectAll("circle") 
     .data(data) 
     .enter() 
     .append("circle") 
     .attr("class", "point") 
     .attr("r", 10) 

     .attr("transform", function(d) { 
      return "translate(" + d + ")"; 
     }) 

     .on('click', function(d, i) { 
      d3.select(this) 
       .style("fill", "pink") 
       //sample - data will be for each point and based on the geojson in real example 
       .append("a") 
      .attr("xlink:href", "http://collections.anmm.gov.au/en/objects/details/11429/") 

      pausePoints.push(i); 
      console.log("pausePoints_push_i: " +pausePoints.push(i)); 
      console.log("pausePoints: " + pausePoints); 
      if (pausePoints.length === 1) 
      transition();  
     }); 


    var marker = svg.append("circle") 
     .attr("r", 19) 
     .attr("transform", "translate(" + (data[0]) + ")") 
      .on('click', function(d, i) { 
      d3.select(this) 
       .style("fill", "pink") 

       pausePoints.push(i); 

       if (pausePoints.length === 1) 
       setTimeout(function() { 
       pauseValues.lastTime = pauseValues.currentTime; 
       }, 100); 
     transition();  
     }); 


    var pauseValues = { 
     lastTime: 0, 
     currentTime: 0 
    }; 

    var pausePoints = [], 
     iter = 0, 
     transData = data.slice(); 

    function transition() { 
     marker.transition() 
     .ease(d3.easeLinear) 
     .duration(duration - (duration * pauseValues.lastTime)) 
     .attrTween("transform", function(){ 
      var p0 = transData.shift(), 
       p1 = transData[0]; 
       m = (p0[1] - p1[1])/(p0[0] - p1[0]), 
       b = p0[1] - (m * p0[0]), 
       i = d3.interpolateNumber(p0[0], p1[0]); 

      return function(t){ 
      //console.log("T: " +t); 
       var x = i(t), 
        y = m*x + b; 

       return "translate(" + x + "," + y + ")"; 
      } 
     }) 
     .on("end", function(){ 
      if (transData.length <= 1) return; 
      iter++;  
      setTimeout(transition, pausePoints.indexOf(iter) !== -1 ? pauseTime : 0); 

     }); 
    }; 

    </script> 
</body> 

答えて

0

私はあなたの最後の質問であなたを助けました。私が書いたコードから、この変数pauseValuesを導入しました。これは何を目的としていますか?私が知ることから、以前の休止に基づいて期間を調整しようとします。すべてのパスで1つの長いトランジションを実行しているときにのみ必要でした。私のコードは各脚を単一のトランジションとして実行します。あなたが一時停止し、クリックで再開したい場合は、ここで簡単なリファクタリングです:

<!DOCTYPE html> 
 
<html lang="en"> 
 

 
<head> 
 
    <meta charset="utf-8"> 
 

 
    <script src="https://d3js.org/d3.v4.min.js"></script> 
 

 
    <style type="text/css"> 
 
    body { 
 
     font-family: "Helvetica Neue", Helvetica, sans-serif; 
 
     color: red; 
 
    } 
 
    
 
    circle { 
 
     fill: steelblue; 
 
     stroke: steelblue; 
 
     stroke-width: 3px; 
 
    } 
 
    
 
    .point { 
 
     fill: green; 
 
    } 
 
    
 
    .line { 
 
     fill: none; 
 
     stroke: red; 
 
     stroke-width: 4; 
 
     stroke-dasharray: 4px, 8px; 
 
    } 
 
    </style> 
 

 
    <body> 
 

 
    <script> 
 
     var width = 960, 
 
     height = 500; 
 

 
     var data = [ 
 
     [610.4199794444444, 243.7191682432953], //Paris 
 
     [480, 200], 
 
     [580, 400], 
 
     [680, 100], 
 
     [780, 300], 
 
     [180, 300], 
 
     [280, 100], 
 
     [380, 400] 
 
     ]; 
 

 
     var duration = 20000/data.length, 
 
     pauseTime = 2000; 
 

 
     var line = d3.line() 
 
     .x(function(d) { 
 
      return (d)[0]; 
 
     }) 
 
     .y(function(d) { 
 
      return (d)[1]; 
 
     }); 
 

 
     var svg = d3.select("body") 
 
     .append("svg") 
 
     .attr("width", width) 
 
     .attr("height", height); 
 

 
     //path to animate - marker transitions along this path 
 
     var path = svg.append("path") 
 
     .data([data]) 
 
     .attr("d", line) 
 
     .attr('class', 'line') 
 
     .attr("d", function(d) { 
 
      return line(d) 
 
     }); 
 

 
     //Want to activate circles when marker paused on them - intention is to have on click to href and stop marker while href is displayed 
 
     svg.selectAll("circle") 
 
     .data(data) 
 
     .enter() 
 
     .append("circle") 
 
     .attr("class", "point") 
 
     .attr("r", 10) 
 

 
     .attr("transform", function(d) { 
 
     return "translate(" + d + ")"; 
 
     }) 
 

 
     .on('click', function(d, i) { 
 
     d3.select(this) 
 
      .style("fill", "pink") 
 
      //sample - data will be for each point and based on the geojson in real example 
 
      .append("a") 
 
      .attr("xlink:href", "http://collections.anmm.gov.au/en/objects/details/11429/") 
 

 
     pausePoints.push(i); 
 

 
     if (pausePoints.length === 1) 
 
      transition(); 
 
     }); 
 

 

 
     var marker = svg.append("circle") 
 
     .attr("r", 19) 
 
     .attr("transform", "translate(" + (data[0]) + ")") 
 
     .on('click', function(d, i) { 
 
      transition(); 
 
     }); 
 

 
     var pausePoints = [], 
 
     iter = 0; 
 
     transData = data.slice(); 
 

 
     function transition() { 
 
     marker.transition() 
 
      .ease(d3.easeLinear) 
 
      .duration(duration) 
 
      .attrTween("transform", function() { 
 
      var p0 = transData.shift(), 
 
       p1 = transData[0], 
 
       m = (p0[1] - p1[1])/(p0[0] - p1[0]), 
 
       b = p0[1] - (m * p0[0]), 
 
       interp = d3.interpolateNumber(p0[0], p1[0]); 
 

 
      return function(t) { 
 

 
       var x = interp(t), 
 
       y = m * x + b; 
 

 
       return "translate(" + x + "," + y + ")"; 
 
      } 
 
      }) 
 
      .on("end", function() { 
 
      iter++; 
 
      if (
 
       transData.length <= 1 || // out of points 
 
       pausePoints.indexOf(iter) !== -1) // on a clicked point 
 
      { 
 
       return; 
 
      } 
 
      transition(); 
 
      }); 
 
     }; 
 
    </script> 
 
    </body>

+0

はいどうもありがとうございました、私は今少し良く何が起こっているかを理解し、何を書かれたことは私に多くのことができます。ポイントの遷移を開始したり停止したりできるようにしたかったのです。あなたのコードを少し変更して "pausePoints.push(i);"を追加しました。オンクリックマーカー機能と私は望んでいた結果を得る。再度、感謝します! – user3471259

関連する問題