1

d3 のパン/ズーム機能を使用して画面にボックスを描画し、ボックスをクリックすると新しいボックスが表示され、残りのボックスが右に移動して新しいボックスが中央にくるようにしようとしていますキャンバスの。パンを使用すると、描画したすべてのボックスをスクロールできます。

これが私のjsfiddleです:http://jsfiddle.net/uUTBE/1/

そして、これがズーム/パンを初期化するための私のコードです: svg.call(d3.behavior.zoom().on("zoom", redraw));

function redraw() {
    d3.select(".canvas").attr("transform",
        "translate(" + d3.event.translate + ")" 
        + " scale(" + d3.event.scale + ")");
}

そして、これがボックスを描画するための私のコードです:

function drawBox(x, y) {
    var boxGroup = canvas.append("g");
    boxGroup.append("rect")
        .attr("x", x)
        .attr("y", y)
        .attr("height", 100)
        .attr("width", 100)
        .attr("fill", function () {
            var i = Math.floor(Math.random() * 4);
            if (i === 1) return "red";
            else if (i === 2) return "blue";
           else if (i === 3) return "yellow";
           else return "green";
        })
        .on("click", function () {
            counter++;
            d3.select(".canvas")
              .transition()
              .duration(1000)
              .attr('transform', "translate(300,0)");
         drawBox(x - counter * 120, y);
        });
}

このフィドルには複数の問題がありますが、主な懸念事項の2つは次のとおりです。

1) 新しいボックスを 2 回目にクリックすると、それに応じてボックスが移動するようにするにはどうすればよいですか (つまり、最初にボックスをクリックすると、古いボックスが右に移動し、新しいボックスが表示されますが、クリックすると新しいボックス、古いボックスは右にシフトしません)。

2) 新しいボックスをクリックすると、新しいボックスの間隔が大きくなるのはなぜですか? (画面に 3 つのボックスを配置しようとした後にのみ発生します)。

ヒントをいただければ幸いです。

4

1 に答える 1

2

この辺りは混乱していると思いますtransform。このtransform属性は、1 つの要素に対して静的であり、累積的ではありません。そのため、.attr('transform', "translate(300,0)")複数回設定しても、初回以降は効果がありません。また、新しいボックスの配置ロジックがオフになっているようです。

ここで必要なポジショニング ロジックは、一歩下がった場合は非常に簡単です (あなたが何をしようとしているのかを理解していると仮定します)。

  1. 新しいボックスが追加されるたびに、すべてのボックスが含まれるフレームが右に 120 ピクセル移動するため、-translation が必要xです120 * counter

  2. 新しいボックスは、新しいフレーム位置からオフセットする必要があるため、 のx設定が必要です-120 * counter

  3. ズームは、現在のキャンバス オフセットを考慮する必要があります。

(1) 上記はクリック ハンドラーで実行できます。

canvas
  .transition()
  .duration(1000)
  .attr('transform', "translate(" + (offset * counter) + ",0)");

g(2) は、ボックスをラップしている要素に非常に簡単に適用できます。

var boxGroup = canvas.append("g")
    .attr('transform', 'translate(' + (-offset * counter)  + ',0)');

redraw(3)ハンドラーに追加できます。

function redraw() {
    var translation = d3.event.translate,
        newx = translation[0] + offset * counter,
        newy = translation[1];
    canvas.attr("transform",
        "translate(" + newx + "," + newy + ")" + " scale(" + d3.event.scale + ")");
}

ここで動作するフィドルを参照してください: http://jsfiddle.net/nrabinowitz/p3m8A/

于 2013-06-30T05:54:58.127 に答える