Mike Bostock の Node-link Tree に基づいて、D3.js で Tree を作成しました。私が抱えていて、マイクのツリーでも見られる問題は、リンクを拡張してスペースを残すのではなく、十分なスペースがない場合に、テキストラベルが円ノードにオーバーラップ/アンダーラップすることです。
新しいユーザーとして画像をアップロードすることは許可されていません。そのため、 Mike のツリーへのリンクを次に示します。ここでは、前のノードのラベルが次のノードと重なっているのを確認できます。
テキストのピクセル長を検出することで、問題を解決するためにさまざまなことを試しました。
d3.select('.nodeText').node().getComputedTextLength();
ただし、これは、レンダリングする前に最も長いテキスト項目の長さが必要な場合に、ページをレンダリングした後にのみ機能します。
レンダリングする前に最長のテキスト項目を取得する:
nodes = tree.nodes(root).reverse();
var longest = nodes.reduce(function (a, b) {
return a.label.length > b.label.length ? a : b;
});
node = vis.selectAll('g.node').data(nodes, function(d, i){
return d.id || (d.id = ++i);
});
nodes.forEach(function(d) {
d.y = (longest.label.length + 200);
});
を使用している間、文字列の長さのみを返します
d.y = (d.depth * 200);
すべてのリンクを静的な長さにし、新しいノードが開いたり閉じたりしたときに美しくサイズ変更しません。
この重複を避ける方法はありますか?もしそうなら、これを行い、ツリーの動的構造を維持するための最良の方法は何でしょうか?
私が思いつくことができる解決策は 3 つありますが、それほど単純ではありません。
- ラベルの長さを検出し、子ノードをオーバーランする省略記号を使用します。(これにより、ラベルが読みにくくなります)
- ラベルの長さを検出し、それに応じてリンクを調整するように指示することで、レイアウトを動的にスケーリングします。(これが一番いいのですが、本当に難しいようです
- svg 要素を拡大縮小し、ラベルがはみ出し始めたらスクロール バーを使用します。(SVGには高さと幅を設定する必要があるという前提で作業しているため、これが可能かどうかはわかりません)。