20

d3.js のd3.behavior.drag() dragイベントを使用してデータ モデルを更新し (要素の位置をすぐに設定せずに)、「描画」関数を実行して、更新されたモデルに基づいてすべての要素を更新しようとしています。transformさらに、ドラッグされたオブジェクトに関連付けられているすべての要素を移動するために、含まれているグループ要素で翻訳を使用しています (以下にリンクされている例から余分な要素を削除しました)。これにより、ドラッグされた要素がドラッグされるにつれてスタッタリングし、ドラッグが速くなるほど悪化します。

jsFiddle のこの簡素化された例を参照してください。

例のコードは次のとおりです。

blocks = [
  { x: 0, y: 0 }
];

drag = d3.behavior.drag()
  .origin(Object)
  .on("drag", function(d) {
    d.x = d3.event.x;
    d.y = d3.event.y;
    draw();
  });

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

function draw() {
  g = svg.selectAll("g")
    .data(blocks);

  gEnter = g.enter().append("g");

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

  gEnter.append("rect")
    .attr("height", 100)
    .attr("width", 100)
    .call(drag);
}

draw()​;
4

3 に答える 3

41

要素を呼び出しdragrectいますが、その親であるg要素を変換しています。

問題は、ドラッグ コンポーネントが親に対するマウスの位置を使用して新しいd3.event.xとを決定することd3.event.yです。transformそのため、ユーザーがドラッグしているときに親を移動 (つまり) すると、問題が発生します。

drag解決策は、移動している同じ要素を呼び出すことです。この場合、g要素:

function draw() {
  g = svg.selectAll("g")
    .data(blocks);

  gEnter = g.enter().append("g")
    .call(drag);

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

  gEnter.append("rect")
    .attr("height", 100)
    .attr("width", 100);
}

修正されたフィドルを参照してください: http://jsfiddle.net/EMNGq/14/

于 2012-10-26T01:47:41.640 に答える
7

私はダーウィンと同じ問題を抱えていました。ドラッグ ハンドラーは、D3 データがアタッチされている子オブジェクトにありますが、変換を親グループ (d3 ではなく) に適用する必要があります。

x:0、y:0 を返すように origin 関数を設定し、dx ではなくイベントで x 値を使用することで解決しました。

例えば

var drag = d3.behavior.drag()
    .origin(function(d,i) { return {x:0, y:0}; })
    .on("drag", function (d) {  movePosition(d3.event.x);   });
于 2013-05-24T23:11:57.127 に答える
3

Nautat はあなたのケースに適したソリューションを提供しました。

私の場合はもう少し複雑です。私のデータは、変換したい g ノードの下にバインドされています。この場合、単に .call(drag) を g レベルに移動することはできません。

ベース座標空間をカスタマイズ可能にするプル リクエストを送信しました: https://github.com/mbostock/d3/pull/1055

于 2013-02-05T20:16:40.903 に答える