2017-05-30 6 views
1

this graph of nodes and shapes created with D3.jsアニメーションに問題があります。パスの長さを変えたいのですが、そのときにpathmarker-endが消えます。D3.jsのマーカーを使用した遷移パスの長さがマーカーを消す

私はappend()とほぼ同じことを達成するためにsvg:animate要素を管理してきましたが、私はそれが実際にpath年代d属性を設定することがD3のtransition()を使用することをお勧めします考えています。誰でも、transition()でアニメーションされているときに、マーカーがパスから消える理由を教えてください。あなたはelse条件...

paths = graph.selectAll('path') 

でこれを行うと

var graph = d3.select('.graph') 
    .append('svg') 
    .attr('width', window.innerWidth) 
    .attr('height', window.innerHeight); 

var defs = graph.append('svg:defs'); 

var blueGradient = defs.append('svg:linearGradient') 
    .attr('id', 'b') 
    .attr('x1', 0) 
    .attr('y1', 0) 
    .attr('x2', 0) 
    .attr('y2', 1) 
    .attr('spreadMethod', 'pad'); 

blueGradient.append('svg:stop') 
    .attr('offset', '0%') 
    .attr('stop-color', '#e4f5fc') 
    .attr('stop-opacity', 1); 

blueGradient.append('svg:stop') 
    .attr('offset', '100%') 
    .attr('stop-color', '#2ab0ed') 
    .attr('stop-opacity', 1); 

var orangeGradient = defs.append('svg:linearGradient') 
    .attr('id', 'o') 
    .attr('x1', 0) 
    .attr('y1', 0) 
    .attr('x2', 0) 
    .attr('y2', 1) 
    .attr('spreadMethod', 'pad'); 

orangeGradient.append('svg:stop') 
    .attr('offset', 0) 
    .attr('stop-color', '#f6e6b4') 
    .attr('stop-opacity', 1); 

orangeGradient.append('svg:stop') 
    .attr('offset', '100%') 
    .attr('stop-color', '#ed9017') 
    .attr('stop-opacity', 1); 

var arrow = defs.append('svg:marker') 
    .attr('id', 'arrow') 
    .attr('orient', 'auto') 
    .attr('markerWidth', 2) 
    .attr('markerHeight', 4) 
    .attr('refX', 0.1) 
    .attr('refY', 2); 

arrow.append('path') 
    .attr('d', 'M0,0 V4 L2,2 Z') 
    .attr('fill', '#aaa'); 

var line = d3.line() 
    .x(function(d) { console.log(d); return d.x; }) 
    .y(function(d) { console.log(d); return d.y; }); 

var appended = false; 
var step = -1; 

document.addEventListener('keydown', drawGraph); 
document.addEventListener('click', drawGraph); 

drawGraph(); 

function drawGraph(event) { 
    var nodes = [ 
     { 
      x: 200, 
      y: 50, 
      c: 'b', 
     }, 
     { 
      x: 400, 
      y: 50, 
      c: 'b' 
     }, 
     { 
      x: 600, 
      y: 50, 
      c: 'b' 
     }, 
     { 
      x: 725, 
      y: 175, 
      c: 'b' 
     }, 
     { 
      x: 600, 
      y: 300, 
      c: 'o' 
     }, 
     { 
      x: 400, 
      y: 300, 
      c: 'o' 
     }, 
     { 
      x: 200, 
      y: 300, 
      c: 'o' 
     }, 
     { 
      x: 75, 
      y: 175, 
      c: 'o' 
     } 
    ]; 

    switch (step) { 
     case -1: 
      var paths; 

      if (!appended) { 
       paths = graph.selectAll('path.nodes') 
        .data(nodes) 
        .enter() 
        .append('path') 
        .attr('stroke', '#aaa') 
        .attr('stroke-width', 10) 
        .attr('fill', 'none') 
        .attr('marker-end', 'url(#arrow)'); 

       graph.selectAll('circle.nodes') 
        .data(nodes) 
        .enter() 
        .append('svg:circle') 
        .attr('cx', function(d) { 
         return d.x; 
        }) 
        .attr('cy', function(d) { 
         return d.y; 
        }) 
        .attr('r', 19) 
        .attr('fill', function(d) { 
         return 'url(#' + d.c + ')'; 
        }) 
        .attr('stroke', function(d) { 
         switch (d.c) { 
          case 'b': 
           return '#2E75B6'; 
          case 'o': 
           return '#BF9000'; 
         } 
        }); 
      } else { 
       paths = graph.selectAll('path') 
        .transition(); 
      } 

      paths.attr('d', function(currentNode, i) { 
       if (!currentNode) { 
        return; 
       } 

       if (appended) { 
        // For some reason, the index is base 0 when the elements 
        // are appended, then 1 based afterwards. 
        i--; 
       } 

       currentNode = nodes[i]; 

       var nextNode = i < nodes.length - 1 ? 
        nodes[i + 1] : 
        nodes[0]; 

       startPath = { 
        x: currentNode.x, 
        y: currentNode.y, 
        c: currentNode.c 
       }; 

       endPath = { 
        x: nextNode.x, 
        y: nextNode.y, 
        c: nextNode.c 
       }; 

       return line([startPath, endPath]); 
      }); 

      appended = true; 
      step++; 
      break; 

     case 0: 
      graph.selectAll('path') 
       .transition() 
       .attr('d', function(currentNode, i) { 
        if (!currentNode) { 
         return; 
        } 

        // For some reason, the index is suddenly base 1, not 0. 
        i--; 

        var nextNode = i < nodes.length - 1 ? 
         nodes[i + 1] : 
         nodes[0]; 

        startPath = { 
         x: currentNode.x, 
         y: currentNode.y, 
         c: currentNode.c 
        }; 

        endPath = { 
         x: nextNode.x, 
         y: nextNode.y, 
         c: nextNode.c 
        }; 
        var diff = { 
         x: nextNode.x - currentNode.x, 
         y: nextNode.y - currentNode.y 
        }; 

        var margins = { 
         current: { 
          x: 0, 
          y: 0 
         }, 
         next: { 
          x: 0, 
          y: 0 
         } 
        }; 

        if (diff.x > 0 && diff.y === 0) { 
         margins.current.x = 30; 
        } else if (diff.x < 0 && diff.y === 0) { 
         margins.current.x = -30; 
        } else if (diff.x > 0) { 
         margins.current.x = 20; 
        } else if (diff.x < 0) { 
         margins.current.x = -20; 
        } 

        if (diff.y > 0 && diff.x === 0) { 
         margins.current.y = 30; 
        } else if (diff.y < 0 && diff.x === 0) { 
         margins.current.y = -30; 
        } else if (diff.y > 0) { 
         margins.current.y = 20; 
        } else if (diff.y < 0) { 
         margins.current.y = -20; 
        } 

        if (margins.current.x != 0) { 
         margins.next.x = margins.current.x < 0 ? 
          Math.abs(margins.current.x * 1.5) : 
          margins.current.x * -1.5; 
        } 

        if (margins.current.y != 0) { 
         margins.next.y = margins.current.y < 0 ? 
          Math.abs(margins.current.y * 1.5) : 
          margins.current.y * -1.5; 
        } 

        startPath.x += margins.current.x; 
        startPath.y += margins.current.y; 
        endPath.x += margins.next.x; 
        endPath.y += margins.next.y; 

        return line([startPath, endPath]); 
       }); 

      step--; 
      break; 
    } 
} 

答えて

1

...あなたにもマーカーを選択している、そしてそれはあなたが望むものではありません。

ソリューション:あなたのパスクラスを与える...

.attr("class", "nodes") 

...と、そのクラスによって選択:見て(適切な "更新" 選択を作成、また

paths = graph.selectAll('.nodes') 

Post Scriptum)。 https://jsfiddle.net/khukeh13/

PS:ここ

が更新フィドルがある私は、あなたが、マーカーが移動していることを確認するだけのために遅い移行しました。しかし、現在の質問とは関係なく、そのコードにはまだ多くの問題があります(コンソールのエラーを見てください)。それは新しい質問の価値があるかもしれません。エラーは、switchifという奇妙なミックスに関連しています。これは取り除くことをお勧めします。基本的な「入力」、「更新」、「終了」の選択肢を作成するだけです。それはその慣用的なD3方法です。

+0

私はコードが理想的ではないことを理解していますが、私が 'switch'を持っている理由は、コードがReveal.jsプレゼンテーションから取られ、スライド内の各「断片化ステップ」がグラフ。 また、 '.selectAll( 'path')'が 'path'という名前のない要素をどのように選択できるのかよくわかりません。説明していただけますか? 最後に、移行によってパスが無くなりました。それはクラス名を追加する前に起こりませんでした。なぜ説明できますか? –

+1

しかし、矢印**は**パスです。 attr( 'd'、 'M0,0 V4 L2,2 Z')。attr( 'fill'、 '#aaa'); 'あなたのコードでこれを見てください:' arrow.append( 'path' 。 –

+0

'selectAll(" path ")'選択内のすべての 'path'要素を選択します。移行に関しては、私がPSであなたに言ったように、スイッチで使用しているカウンターにいくつか問題があるためです。 –

関連する問題