D3 Tree Layout Séparation entre les nœuds utilisant NodeSize

En ce moment, j'essaie de séparer mes noeuds rectangulaires car ils se chevauchent comme indiqué dans l'image ci-dessous:

Entrez la description de l'image ici

J'ai jeté un coup d'oeil et j'ai découvert que D3 offre une méthode de notation et de séparation , mais pour une raison quelconque, cela ne fonctionnait pas.

J'ai trouvé cette publication sur le sujet, mais il dit

La propriété taille n'existe pas dans les noeuds, de sorte que ce sera la propriété que vous souhaitez contrôler la taille de ceux-ci.

Mais il est clair qu'il y a une méthode nodeSize, alors j'ai l'impression que j'utilise simplement la méthode de manière incorrecte et que la publication du blog n'est pas à jour. Je veux former mes noeuds pour être la taille du rectangle et les répartir uniformément afin qu'ils ne se chevauchent pas. Est-ce que quelqu'un sait comment utiliser correctement les méthodes? La documentation sur ces méthodes n'est pas très bien expliquée et elle ne donne aucune différence. Je ne trouvais pas non plus de nombreux exemples où les gens ont changé le nombre d'arbres ou la séparation nécessaire pour les objets rectangulaires (il y avait quelques exemples concernant les circulaires, mais je me sens trop différent …)

Voici le code pertinent. Je vais essayer de préparer un 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 dx, dy 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 + ")"); 

Mise à jour de cette réponse. J'ai parlé avec mon ami et nous avons examiné la source pour la size et la 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; }; 

Lorsque vous définissez une size pour l'arborescence, vous définissez une taille fixe afin que l'arbre soit conforme à cette largeur et cette hauteur. Lorsque vous définissez un nodeSize , l'arbre doit être dynamique afin qu'il réinitialise la taille de l'arborescence.

Quand j'ai spécifié la size après nodeSize , j'étais à peu près prioritaire à ce que je voulais, haha ​​…

Bottom line : Si vous souhaitez que nodeSize fonctionne, vous ne pouvez pas avoir une taille d'arbre fixe. Il rendra la taille null . Ne déclarez pas une size si vous nodeSize un nombre de nodeSize .

EDIT: D3.js a effectivement mis à jour la documentation . Merci à qui que ce soit parce que c'est bien plus clair maintenant!

La propriété nodeSize est exclusive avec tree.size; Définir tree.nodeSize définit tree.size sur null.

C'est ce que mon arbre ressemble maintenant. J'ai également ajouté des fonctionnalités de zoom ainsi que la façon de centrer le texte dans le rectangle.

Image où nodeSize est réglé à une largeur de 100 et une hauteur de 30

Voici un jsFiddle: http://jsfiddle.net/augburto/YMa2y/

EDIT: mis à jour et passe l'exemple à Codepen. L'exemple existe encore sur jsFiddle, mais Codepen semble avoir un meilleur éditeur et vous permet de facilement démarrer. J'essaierai également d'ajouter l'exemple directement à cette réponse une fois que j'ai réduit la quantité de contenu.

http://codepen.io/augbog/pen/LEXZKK

Je n'ai pas bien compris la réponse acceptée jusqu'à ce que je fasse du creux, alors j'ai pensé que je partagerais ce que j'ai trouvé aussi …

Si vous utilisez .size() et que vos nœuds se chevauchent, utilisez .nodeSize() place

Comme expliqué dans la réponse acceptée, .size() définit la taille disponible de l'arborescence, et donc en fonction de l'espacement entre les nœuds cousins, les cousins ​​secondaires, etc., ils peuvent se calinquer ensemble et se chevaucher. L'utilisation de .nodeSize() indique simplement que chaque nœud devrait avoir beaucoup d'espace, de sorte qu'ils ne se chevauchent jamais!

Le code qui a fini par travailler pour moi était

 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; }); 

Sans horizontalSeparationBetweenNodes et verticalSeparationBetweenNodes les bords des nœuds se touchent. J'ai également ajouté cette .separation() pour diminuer la quantité d'espace entre les noeuds de cousin, car mes noeuds sont assez larges et beaucoup d'espace a été gaspillé.

Remarque: Ceci est pour d3 v3, pas v4