以下の図に示すように、長方形ノードは重なっているため、現在、長方形ノードを分離しようとしています。
私は見てみると、D3は nodeSize および separation メソッドを提供していることがわかりましたが、何らかの理由で機能しませんでした。
私はこれを見つけました ブログ投稿 問題について話していますが、彼は言います
サイズプロパティはノードには存在しないため、ノードのサイズを制御するプロパティになります。
ただし、nodeSizeメソッドがあることは明らかです。そのため、このメソッドを間違って使用しているだけで、ブログの投稿が古くなっているように感じます。ノードを長方形のサイズに整形し、ノードが互いに重ならないように均等に配置します。誰もがメソッドを適切に使用する方法を知っていますか?これらのメソッドに関するドキュメントはあまり説明されておらず、違いはありません。また、人々が木のノードサイズを変更したり、長方形のオブジェクトの分離が必要だったりする多くの例を見つけることができませんでした(円形のものに関するいくつかの例がありましたが、私はそれがあまりにも違うと感じています...)
関連するコードは次のとおりです。 JSFiddleの準備を試みます。
var margin = {top: 20, right: 120, bottom: 20, left: 120},
height = 960 - margin.right - margin.left,
width = 800 - margin.top - margin.bottom,
rectW = 70;
rectH = 30;
//bbox = NaN,
maxTextLength = 0;
var i = 0,
duration = 750,
root;
//paths from each node drawn initially here
//changed to d.x, d.y
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.x+rectW/2, d.y+rectH/2];
//.projection(function(d) { return [d.x+bbox.getBBox().width/2, d.y+bbox.getBBox().height/2];
});
var tree = d3.layout.tree()
.nodeSize([30,70])
.separation(function(a, b) { return (a.parent == b.parent ? 1 : 2); })
.size([width, height]);
var svg = d3.select("body")
.append("svg")
.attr("height","100%").attr("width","100%")
.call(d3.behavior.zoom().on("zoom", redraw))
.append("g")
.attr("transform", "translate(" + margin.top + "," + margin.left + ")");
UPDATE 05/04/2018:私の理解では、d3はより良くモジュール化するために(より良いために)大きく変化しました。この答えを探している人のために、これははるかに古いバージョンのd3(特にv3)を使用していました。
多くの調査結果は、 _d3-hierarchy
_cluster.size()
and cluster.nodeSize()
の下のパッケージに関連しています。それを使用するように私の例を潜在的に更新します。ただし、歴史的な参考のために、私は下の部分をそのままにしておきます。
ここにjsFiddleがあります: http://jsfiddle.net/augburto/YMa2y/
編集:例を更新してCodepenに移動します。この例はjsFiddleにまだ存在しますが、Codepenはより優れたエディターを備えているようで、簡単に分岐できます。また、コンテンツの量を減らしたら、この回答にサンプルを直接追加しようとします。
http://codepen.io/augbog/pen/LEXZKK
この回答を更新しています。友達と話をして、size
とnodeSize
のソースを見ました
_ tree.size = function(x) {
if (!arguments.length) return nodeSize ? null : size;
nodeSize = (size = x) == null;
return tree;
};
tree.nodeSize = function(x) {
if (!arguments.length) return nodeSize ? size : null;
nodeSize = (size = x) != null;
return tree;
};
_
ツリーにsize
を設定すると、ツリーがその幅と高さに適合しなければならないように、固定サイズが設定されます。 nodeSize
を設定すると、ツリーは動的である必要があるため、ツリーのサイズがリセットされます。
size
の後にnodeSize
を指定したとき、望んでいたものをほとんどオーバーライドしていました。
一番下の行:nodeSize
を機能させたい場合は、ツリーのサイズを固定することはできません。サイズをnull
に設定します。 size
を宣言している場合は、nodeSize
を宣言しないでください。
編集:D3.jsは実際に ドキュメントを更新 。それが今よりずっと明確になったので、だれでもありがとう!
NodeSizeプロパティはtree.size専用です。 tree.nodeSizeを設定すると、tree.sizeがnullに設定されます。
これが私のツリーの外観です。また、ズーム機能と、テキストを長方形の中央に配置する方法も追加しました。
私は自分で掘り下げるまで受け入れられた答えを十分に理解していなかったので、私も見つけたものを共有すると思った...
.size()
を使用していて、ノードが重複している場合は、代わりに.nodeSize()
を使用します
受け入れられた答えで説明されているように、.size()
はツリーの利用可能なサイズを設定します。 .nodeSize()
を使用すると、各ノードがこれだけのスペースを確保する必要があるため、オーバーラップすることはありません。
最終的に私のために働いたコードは
_var nodeWidth = 300;
var nodeHeight = 75;
var horizontalSeparationBetweenNodes = 16;
var verticalSeparationBetweenNodes = 128;
var tree = d3.layout.tree()
.nodeSize([nodeWidth + horizontalSeparationBetweenNodes, nodeHeight + verticalSeparationBetweenNodes])
.separation(function(a, b) {
return a.parent == b.parent ? 1 : 1.25;
});
_
horizontalSeparationBetweenNodes
とverticalSeparationBetweenNodes
がなければ、ノードのエッジは互いに接触していました。また、この.separation()
を追加して、いとこノード間のスペースを減らしました。これは、ノードがかなり広く、多くのスペースが無駄になっていたためです。
注:これは、v4ではなくd3 v3用です
D3はObservableを介して処理を行うようになりました。
ObservableでnodeSizeを設定し、
lineを探します:
main.variable(observer("tree")).define("tree", ["d3","dx","dy"],
function(d3,dx,dy){return(
d3.tree()
そして、追加された定数でノードサイズを設定:
main.variable(observer("tree")).define("tree", ["d3","dx","dy"],
function(d3,dx,dy){return(
d3.tree().nodeSize([dx + 10, dy + 10])
または、古いD3アプローチを使用した他の回答で説明されているように、関数を使用してチャートサイズに値を設定します。
まず、以前に投稿したすべての人に感謝します、純金。水平に描画されたツリーに関連するオフセットの問題に苦しんでいる可能性のある人のために、この投稿に追加したかった。
重要なのは、水平ツリーで.size()から.nodeSize()に切り替えると、ルートノードが(0,0)に位置するようにジャンプ/方向転換しているように見えることです。 d3.jsのドキュメントによれば、これは実際に当てはまります( https://github.com/d3/d3-hierarchy/blob/master/README.md#tree_nodeSize を参照)
ただし、調整するには、viewBox
の向きを変更する必要があります。つまり、.append
your svg
viewBox
を明示的に設定する必要があります。これが私の役に立つハックな小さなラインです...
svg = d3.select("#tree").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + 0 + 0)
.attr("viewBox", "0 "+(-1*(height-margin.top-margin.bottom)/2)+" "+width+" "+height)
.append("g")
.attr("transform", "translate("
+ margin.left + "," + 0 + ")");