0

ここにある D3.js の SVG セマンティック ズームとパンの例のバージョンを実装しようとしています。Mike Bostock (こちら) が推奨するように、デンドログラム/ツリー (例はこちら) でこれを実行しようとしています。目標は、奇妙なノード/パスのリンク解除動作がないことを除いて、他のスレッドの1つが言及したこのjsFiddleのようなものです。私の個人的な試みはここにあります

Firebug で Mike のコードで「cannot translate(NaN,NaN)」というエラーが発生していたので、ズーム機能のコードを以下のように変更しました。ただし、挙動がおかしい。現在、1) パスがズーム/移動しません。2) ノードを右下から左上にしかパンできません (左下から右上にパンしようとすると、ノードは引き続き LR-UL に沿って移動します)。方向)。

var vis = d3.select("#tree").append("svg:svg")
              .attr("viewBox", "0 0 600 600")
              .attr("width", w + m[1] + m[3])
              .attr("height", h + m[0] + m[2])
              .append("svg:g")
              .attr("transform", "translate(" + m[3] + "," + m[0] + ")")
              .call(d3.behavior.zoom().x(x).y(y).scaleExtent([1,8]).on("zoom",zoom));

// zoom in / out
function zoom() {
    var nodes = vis.selectAll("g.node");
    nodes.attr("transform", transform);
}

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

上記の Google Groups スレッドとjsFiddleに記載されている他の解決策に従ってみましたが、あまり進歩していません。コードに jsFiddle からのパス リンクを含め、translate() 関数を使用すると、パスをスケーリングできます。ただし、1) 垂直方向に反転します (どこかで x と y の転置が正しく機能しません)。2) パスはノード (おそらく #1 に関連) と同じ速度でズームしないため、「リンク解除」されます。3) パンすると、パスはすべての方向にパンしますが、ノードは移動しません。ノードをクリックしてツリーを展開すると、パスが再調整されて修正されるため、更新コードがうまく機能しているように見えます (ただし、その作業部分を特定/コピーする方法がわかりません)。ここで私のコードを参照してください。

function zoom(d) {
    var nodes = vis.selectAll("g.node");
    nodes.attr("transform", transform);

    // Update the links...
    var link = vis.selectAll("path.link");
    link.attr("d", translate);
}

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

function translate(d) {
    var sourceX = x(d.target.parent.y);
    var sourceY = y(d.target.parent.x);
    var targetX = x(d.target.y);
    var targetY = (sourceX + targetX)/2;
    var linkTargetY = y(d.target.x0);
    var result = "M"+sourceX+","+sourceY+" C"+targetX+","+sourceY+" "+targetY+","+y(d.target.x0)+" "+targetX+","+linkTargetY+"";
    //console.log(result);

   return result;

私の質問は次のとおりです。

  • 私が見ることができるデンドログラム/ツリーのズーム/パンの実例はありますか?
  • 上記のコードを使用して、パスがどこで/どのように反転されているかを誰でも特定できますか? SVG Cubic Bezier 曲線を描画する translate() 関数内でさまざまな順列を試しましたが、何も正しく機能していないようです。繰り返しますが、私の jsFiddle はhereです。
  • パンニングが部分的にしか機能しない場合のトラブルシューティングのヒントやアイデアはありますか?

助けてくれてありがとう!

4

1 に答える 1

2

1 つの重大なタイプミスによって脱線した、非常に優れた実装がありました。

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

になるはずだった

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

パスが反転しないようにするには、おそらく y 軸を反転していないはずです。

y = d3.scale.linear().domain([0, h]).range([h, 0])

に変更

y = d3.scale.linear().domain([0, h]).range([0, h])

修正はこちら: http://jsfiddle.net/6kEpp/2/ . しかし、将来の参考のために、おそらく x 軸を x 値で操作し、y 軸を y 値で操作する必要があります。そうしないと、本当に混乱するだけです。

実装に磨きをかけるための最後のコメント:

  1. デフォルトのレンダリング (またはノードを開いたり閉じたりした直後) からズームの実装に至るまで、ベジエの描画には多少のジャンプがあります。それらを同じベジエ関数にするだけで、それを使って遊んだときの感触がずっと良くなります。
  2. 既存のノードの相対的な動きに基づいて、グラフ自体が再描画された後、ズーム ベクトルを更新する必要があります。そうしないと、ノードを開いたり閉じたりした後に再度ズームしようとすると、突然ジャンプします。
于 2013-02-25T18:52:37.400 に答える