15

d3 グラフィックス ライブラリを使用すると、パスがゆっくりと描画されるので、パスが成長しているように見えません。

このサイトの「Line Chart (Unrolling)」セクションには完璧な例がありますが、そのセクションのコードはありません。誰かがそれを実現できる D3 コードの行を手伝ってくれませんか?

次のコード スニペットのように delay() または duration() を追加しようとすると、パスはすぐに描画され、このセグメントの後のすべての SVG コードはレンダリングに失敗します。

    var mpath = svg.append ('path');
        mpath.attr ('d', 'M35 48 L22 48 L22 35 L22 22 L35 22 L35 35 L48 35 L48 48')
             .attr ('fill', 'none')
             .attr ('stroke', 'blue')
             .duration (1000);
4

3 に答える 3

49

svgで行をアニメーション化するときの一般的なパターンstroke-dasharrayは、パスの長さを設定してからアニメーション化することstroke-dashoffsetです。

var totalLength = path.node().getTotalLength();

path
  .attr("stroke-dasharray", totalLength + " " + totalLength)
  .attr("stroke-dashoffset", totalLength)
  .transition()
    .duration(2000)
    .ease("linear")
    .attr("stroke-dashoffset", 0);

ここでデモを見ることができます:http: //bl.ocks.org/4063326

于 2012-11-13T01:42:29.773 に答える
18

これを行う「D3の方法」は、カスタムトゥイーン関数を使用することだと思います。ここで実際の実装を見ることができます: http://jsfiddle.net/nrabinowitz/XytnD/

これは、パスを計算するためのlineセットアップと呼ばれるジェネレーターがあることを前提としています。d3.svg.line

// add element and transition in
var path = svg.append('path')
    .attr('class', 'line')
    .attr('d', line(data[0]))
  .transition()
    .duration(1000)
    .attrTween('d', pathTween);

function pathTween() {
    var interpolate = d3.scale.quantile()
            .domain([0,1])
            .range(d3.range(1, data.length + 1));
    return function(t) {
        return line(data.slice(0, interpolate(t)));
    };
}​

ここでのpathTween関数は、トランジションの進行状況によって定義されるラインの特定のスライスを取得し、それに応じてパスを更新するインターポレーターを返します。

ただし、簡単な方法をとることで、パフォーマンスが向上し、アニメーションがよりスムーズになると思われることに注意してください。白い四角形 (背景が単純な場合) またはclipPath(背景が複雑な場合) を線の上に置き、それを右に移動して、下の線を表示します。

于 2012-11-13T01:35:40.867 に答える
1

リンク先の投稿に基づいて、次の例を思いつきました。

var i = 0,
    svg = d3.select("#main");

String.prototype.repeat = function(times) {
   return (new Array(times + 1)).join(this);
}

segments = [{x:35, y: 48}, {x: 22, y: 48}, {x: 22, y: 35}, {x: 34, y:35}, {x: 34, y:60}];
line = "M"+segments[0].x + " " + segments[0].y

new_line = line + (" L" + segments[0].x + " " + segments[0].y).repeat(segments.length);
 var mpath = svg.append ('path').attr ('d',new_line )
             .attr ('fill', 'none')
             .attr ('stroke', 'blue')

for (i=0; i<segments.length; i++)
    {
    new_segment = " " + "L"+segments[i].x + " " + segments[i].y
    new_line = line + new_segment.repeat(segments.length-i)
    mpath.transition().attr('d',new_line).duration(1000).delay(i*1000);
    line = line + new_segment

    }

少し醜いですが、機能します。jsFiddleで見ることができます

于 2012-11-13T01:11:16.617 に答える