I am trying to create a graph using d3 and formatting. To get started, I used the following example http://bl.ocks.org/mbostock/1062288 :

I also need images and labels, so I looked at this http://bl.ocks.org/mbostock/950642 example to understand how I can add them.
My graph will also increase depending on user interaction with nodes, so if a user clicks on a node that has no children, the ajax request is sent to the server service to request more nodes. The graph is intended to be used as a relationship discovery application. I created the following jsfiddle http://jsfiddle.net/R2JGa/7/ to get an idea of what I'm trying to achieve.
It works relatively well, but I have one unpleasant problem: when adding new nodes to the graph, the old nodes are somehow lost. For example, I start with 3 nodes, the root node is a torch. The remaining 2 nodes are "animation" and "analytics". In my example, children will always be "x", "y", "z", "t" anytime you click on a node that currently has no children. After expanding several nodes, you will see that the "animation" or "analytics" are not associated with the root node "flash", but with some other nodes (x, y, z, t). Or sometimes, if you extend x or y or z or t, the child nodes have a duplicate of x or y or z or t. If you press the “flash” to hide the entire graph and then open the “torch” again, you will see that the nodes are correctly connected and named.
I don't seem to understand why this is happening. Can anyone shed some light here? I'm still new to d3 and find it really interesting, but these problems are so annoying ...
Here is the code:
var w = 960, h = 800, node, link, root; var force = d3.layout.force() .charge(-1000) .size([w, h]); var vis = d3.select("#chart").append("svg:svg") .attr("width", w) .attr("height", h); d3.json("data.json", function (json) { root = json; update(); }); function update() { var nodes = flatten(root); nodes.reverse(); nodes = nodes.sort(function (a, b) { return a.index - b.index; }); var links = d3.layout.tree().links(nodes); console.log(nodes); // Restart the force layout. force .nodes(nodes) .links(links) .linkDistance(55) .start(); var link = vis.selectAll(".link") .data(links); link.enter().append("line") .attr("class", "link"); link.exit().remove(); var node = vis.selectAll("g.node") .data(nodes) var groups = node.enter().append("g") .attr("class", "node") .attr("id", function (d) { return d.id }) .on('click', click) .call(force.drag); groups.append("image") .attr("xlink:href", "https://github.com/favicon.ico") .attr("x", -8) .attr("y", -8) .attr("width", 16) .attr("height", 16); groups.append("text") .attr("dx", 12) .attr("dy", "0.35em") .style("font-size", "10px") .text(function (d) { console.log(d); return d.name }); node.exit().remove(); force.on("tick", function () { link.attr("x1", function (d) { return d.source.x; }) .attr("y1", function (d) { return d.source.y; }) .attr("x2", function (d) { return d.target.x; }) .attr("y2", function (d) { return d.target.y; }); node.attr("transform", function (d) { return "translate(" + dx + "," + dy + ")"; }); }); } // Color leaf nodes orange, and packages white or blue. function color(d) { return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c"; } // Toggle children on click. function click(d) { console.log(d); if (d.children) { d._children = d.children; d.children = null; update(); } else if (d._children) { d.children = d._children; d._children = null; update(); } else { d3.json("expand.json", function (json) { d.children = json.children; update(); }) } } // Returns a list of all nodes under the root. function flatten(root) { var nodes = [], i = 0; function recurse(node) { if (node.children) node.children.forEach(recurse); if (!node.id) node.id = ++i; nodes.push(node); } recurse(root); return nodes; }
And here are 2 json files that I request:
data.json
{ "name": "flare", "id" : "flare", "children": [ { "name": "analytics", "id": "analytics" }, { "name": "animate", "id": "animate" } ] }
And expand.json
{"children": [ { "name": "x", "id": "x", "size": 1983 }, { "name": "y", "id": "y", "size": 2047 }, { "name": "z", "id": "z", "size": 1375 }, { "name": "t", "id": "t", "size": 1375 } ]}
PS: I had to sort the array of nodes, otherwise bad things happened to the chart, I can’t understand why.