Comment modifier l'orientation de l'arborescence D3 de 90 degrés

Je viens de commencer à m'impliquer dans les visualisations Web, donc je suis totalement novice. Mon objectif est d'afficher un arbre familial où un noeud racine aurait à la fois des parents et des enfants multiples. En recherchant une solution, j'ai trouvé cet exemple: http://bl.ocks.org/jdarling/2503502 C'est génial car il semble avoir la fonctionnalité dont j'ai besoin. Cependant, j'aimerais modifier l'orientation (top-to-bottom). J'ai essayé de le faire en utilisant cet exemple: http://bl.ocks.org/mbostock/3184089 mais échoué.

Mon code:

var tree = d3.layout.tree() .size([height, width]); var diagonal = d3.svg.diagonal() .projection(function(d) { return [dx, dy]; }); var elbow = function (d, i){ var source = calcTop(d.source); var target = calcTop(d.target); var hx = (target.x-source.x)/2; if(d.isRight) hx = -hx; return "M" + source.x + "," + source.y + "H" + (source.x+hx) + "V" + target.y + "H" + target.x; }; var connector = elbow; var calcTop = function(d){ var top = dx; if(!d.isRight){ top = dx-halfHeight; top = halfHeight - top; } return {x : top, y : dy}; }; var vis = d3.select("#chart") .append("svg") .attr("height", height + margin.top + margin.bottom) .attr("width", width + margin.right + margin.left) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); d3.json("tree.json", function(json) { root = json; root.x0 = height / 2; root.y0 = width / 2; var t1 = d3.layout.tree() .size([halfHeight, width]) .children(function(d){ return d.winners; }); var t2 = d3.layout.tree() .size([halfHeight, width]) .children(function(d){ return d.challengers; }); t1.nodes(root); t2.nodes(root); var rebuildChildren = function(node){ node.children = getChildren(node); if(node.children) node.children.forEach(rebuildChildren); } rebuildChildren(root); root.isRight = false; update(root); }); var toArray = function(item, arr){ arr = arr || []; var i = 0, l = item.children?item.children.length:0; arr.push(item); for(; i < l; i++){ toArray(item.children[i], arr); } return arr; }; function update(source) { // Compute the new tree layout. var nodes = toArray(source); // Normalize for fixed-depth. nodes.forEach(function(d) { dx = d.depth * 180 + halfHeight; }); // Update the nodes… var node = vis.selectAll("g.node") .data(nodes, function(d) { return d.id || (d.id = ++i); }); // Enter any new nodes at the parent's previous position. var nodeEnter = node.enter().append("g") .attr("class", "node") .attr("transform", function(d) { return "translate(" + source.x0 + "," + source.y0 + ")"; }) .on("click", click); nodeEnter.append("circle") .attr("r", 1e-6) .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }); nodeEnter.append("text") .attr("dy", function(d) { return d.isRight?14:-8;}) .attr("text-anchor", "middle") .text(function(d) { return d.name; }) .style("fill-opacity", 1e-6); // Transition nodes to their new position. var nodeUpdate = node.transition() .duration(duration) .attr("transform", function(d) { p = calcTop(d); return "translate(" + px + "," + py + ")"; }); nodeUpdate.select("circle") .attr("r", 4.5) .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }); nodeUpdate.select("text") .style("fill-opacity", 1); // Transition exiting nodes to the parent's new position. var nodeExit = node.exit().transition() .duration(duration) .attr("transform", function(d) { p = calcTop(d.parent||source); return "translate(" + px + "," + py + ")"; }) .remove(); nodeExit.select("circle") .attr("r", 1e-6); nodeExit.select("text") .style("fill-opacity", 1e-6); // Update the links... var link = vis.selectAll("path.link") .data(tree.links(nodes), function(d) { return d.target.id; }); // Enter any new links at the parent's previous position. link.enter().insert("path", "g") .attr("class", "link") .attr("d", function(d) { var o = {x: source.x0, y: source.y0}; return connector({source: o, target: o}); }); // Transition links to their new position. link.transition() .duration(duration) .attr("d", connector); // Transition exiting nodes to the parent's new position. link.exit() .transition() .duration(duration) .attr("d", function(d) { var o = calcTop(d.source||source); if(d.source.isRight) ox -= halfHeight - (d.target.x - d.source.x); else ox += halfHeight - (d.target.x - d.source.x); return connector({source: o, target: o}); }) .remove(); // Stash the old positions for transition. nodes.forEach(function(d) { var p = calcTop(d); d.x0 = px; d.y0 = py; }); // Toggle children on click. function click(d) { if (d.children) { d._children = d.children; d.children = null; } else { d.children = d._children; d._children = null; } update(source); 

}}

J'apprécierais vraiment l'aide!

L'exemple que vous regardez est en fait déjà retourné – cela pourrait vous causer une certaine confusion. Les arbres en D3 sont naturellement des arbres descendants, et le code fait beaucoup de xy flip pour faire l'arbre de côté.

En changeant

  var nodeUpdate = node.transition() .duration(duration) .attr("transform", function(d) { p = calcLeft(d); return "translate(" + py + "," + px + ")"; }) ; 

à

  var nodeUpdate = node.transition() .duration(duration) .attr("transform", function(d) { p = calcLeft(d); return "translate(" + px + "," + py + ")"; }) ; 

Obtiendra les nœuds affichés dans la bonne position. Effectuer un changement similaire avec n'importe quelle instance de coordonnées xy échangées dans la mise à jour () corrige la plupart des problèmes de positionnement. Une dernière chose est la fonction de coude / variable / quoi que vous vouliez appeler, où

  return "M" + source.y + "," + source.x + "H" + (source.y+hy) + "V" + target.x + "H" + target.y; 

Devrait être changé en

  return "M" + source.x + "," + source.y + "V" + (source.y+hy) + "H" + target.x + "V" + target.y; 

Cela modifie la forme du connecteur de l'horizontale horizontale horizontale à la vertical verticale verticale. Notez qu'il s'agit d'une ligne SVG brute, pas d3 du tout. Les changements que j'ai effectués (plus la largeur et la hauteur de l'échange, et la modification de la requête JAA AJAX pour coder les données – AJAX est difficile à travailler dans le violon) sont tous sur http://jsfiddle.net/Zj3th/2/ .

Si vous n'avez aucune expérience avec d3 et SVG, je vais certainement regarder et comprendre un exemple simple comme http://blog.pixelingene.com/2011/07/building-a-tree-diagram-in-d3-js / Avant d'aller plus loin dans la modification du code.

Voici un exemple de diagramme en bas de page que j'ai créé. Je crois que cela pourrait vous être utile, peut-être que vous constaterez une idée, etc.

Entrez la description de l'image ici

Lien vers le code sur codepen . N'hésitez pas à poser une question.

 its very easy to make rotation in d3 collapsible tree TOP-DOWN.. step 1: specify top,bottom,left,right part of our drawing pan and also the width and height. Step 2: Make the orientation as top to bottom step 3: Reading the json and make the orientation step 4: Appending the link and circle to the body <script> var jdata='${data}' var margin = {top: 20, right: 120, bottom: 20, left: 120}, width = 980 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var orientations = { "top-to-bottom": { size: [width, height], x: function(d) { return dx; }, y: function(d) { return dy; } } }; var svg = d3.select("body").selectAll("svg") .data(d3.entries(orientations)) .enter().append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); d3.json("resources/grap.json", function(json) { root = JSON.parse(jdata); svg.each(function(orientation) { var svg = d3.select(this), o = orientation.value; // Compute the layout. var tree = d3.layout.tree().size(o.size), nodes = tree.nodes(root), links = tree.links(nodes); // Create the link lines. svg.selectAll(".link") .data(links) .enter().append("path") .attr("class", "link") .attr("d", d3.svg.diagonal().projection(function(d) { return [ox(d), oy(d)]; })); // Create the node circles. svg.selectAll(".node") .data(nodes) .enter().append("circle") .attr("r",1.5) .attr("x", ox) .attr("y", oy) }); }); </script>