javascript - d3.js collapsible force layout with images won't start with nodes collapsed -
i'm new d3 , js
i'm using d3.js collapsible force layout images based off example: http://bl.ocks.org/eesur/be2abfb3155a38be4de4
however wish start nodes collapsed. i've tried solutions thread aren't working correctly.
the second solution has no effect @ all.
when use first solution , change children _children functionality of nodes changes , instead of expanding start split apart. screenshot: https://dl.dropboxusercontent.com/u/38140937/memory%20site/screenshot/solution2.png
any appreciated
you should update json data before inital call of update
function.
$(function () { --------------------- --------------------- --------------------- var nodes = flatten(g.data); nodes.foreach(function(d) { d._children = d.children; d.children = null; }); update(); });
here working code snippet.
//notes: // src: http://bl.ocks.org/mbostock/1093130 //notes: // * each dom element using // children store refs expanded children // _children store refs collapsed children //* it's using both tree , graph layout. //root var g = { data: null, force: null }; $(function() { //use global var data: g.data = data; var width = 960, height = 500; //create sized svg surface within viz: var svg = d3.select("#viz") .append("svg") .attr("width", width) .attr("height", height); g.link = svg.selectall(".link"), g.node = svg.selectall(".node"); //create graph layout engine: g.force = d3.layout.force() .linkdistance(80) .charge(-120) .gravity(0.05) .size([width, height]) //that invokes tick method draw elements in new location: .on("tick", tick); var nodes = flatten(g.data); nodes.foreach(function(d) { d._children = d.children; d.children = null; }); //draw graph: //note method invoked again //when clicking nodes: update(); }); //invoked once @ start, //and again when 'click' method //which expands , collapses node. function update() { //iterate through original nested data, , 1 dimension array of nodes. var nodes = flatten(g.data); //each node extracted above has children attribute. //from them, can use tree() layout function in order //to build links selection. var links = d3.layout.tree().links(nodes); // pass both of sets graph layout engine, , restart g.force.nodes(nodes) .links(links) .start(); //------------------- // create subselection, wiring data, using function define //how it's suppossed know appended/updated/exited g.link = g.link.data(links, function(d) { return d.target.id; }); //get rid of old links: g.link.exit().remove(); //build new links adding new svg lines: g.link .enter() .insert("line", ".node") .attr("class", "link"); // create subselection, wiring data, using function define //how it's suppossed know appended/updated/exited g.node = g.node.data(nodes, function(d) { return d.id; }); //get rid of old nodes: g.node.exit().remove(); //------------------- //create new nodes making groupd elements, contain circls , text: var nodeenter = g.node.enter() .append("g") .attr("class", "node") .on("click", click) .call(g.force.drag); //circle within single node group: nodeenter.append("circle") .attr("r", function(d) { return math.sqrt(d.size) / 10 || 4.5; }); //text within single node group: nodeenter.append("text") .attr("dy", ".35em") .text(function(d) { return d.name; }); //all nodes, following: g.node.select("circle") .style("fill", color); //calls delegate //------------------- } // invoked 'update'. // original source data not usual nodes + edge list, // that's what's needed force layout engine. // returns list of nodes under root. function flatten(data) { var nodes = [], = 0; //count children (not _children) //note doesn't count descendents of collapsed _children //rather elegant? function recurse(node) { if (node.children) node.children.foreach(recurse); if (!node.id) node.id = ++i; nodes.push(node); } recurse(data); //done: return nodes; } //invoked 'update' //return color of node //based on children value of //source data item: {name=..., children: {...}} function color(d) { return d._children ? "#3182bd" // collapsed package : d.children ? "#c6dbef" // expanded package : "#fd8d3c"; // leaf node } // toggle children on click switching around values on _children , children. function click(d) { if (d3.event.defaultprevented) return; // ignore drag if (d.children) { d._children = d.children; d.children = null; } else { d.children = d._children; d._children = null; } // update(); } //event handler every time force layout engine //says redraw everthing: function tick() { //redraw position of every link within link set: g.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; }); //same nodes, using functor: g.node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); } var data = { name: "flare", children: [{ name: "analytics", children: [{ name: "cluster", children: [{ name: "agglomerativecluster", size: 3938 }, { name: "communitystructure", size: 3812 }, { name: "hierarchicalcluster", size: 6714 }, { name: "mergeedge", size: 743 }] }, { name: "graph", children: [{ name: "betweennesscentrality", size: 3534 }, { name: "linkdistance", size: 5731 }, { name: "maxflowmincut", size: 7840 }, { name: "shortestpaths", size: 5914 }, { name: "spanningtree", size: 3416 }] }, { name: "optimization", children: [{ name: "aspectratiobanker", size: 7074 }] }] }] };
.node circle { cursor: pointer; stroke: #3182bd; stroke-width: 1.5px; } .node text { font: 10px sans-serif; pointer-events: none; text-anchor: middle; } line.link { fill: none; stroke: #9ecae1; stroke-width: 1.5px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <div id="viz" />
Comments
Post a Comment