0

is there a way to have this diagram collapsed in the beginning? http://bl.ocks.org/mbostock/1093130

It seems mission impossible for my purpose as I'm using identical names in my .json file.

here is my example: http://plnkr.co/edit/vg18Z5APuK1HhxZu3IXj?p=preview

code:

var width = 600,
    height = 600,
    node,
    link,
    root;

var leafColor = d3.scale.category20();

var force = d3.layout.force()
    .linkDistance(function(d) { return d.target._children ? 80 : 30; })
    .charge(function(d) { return d._children ? -d.size / 100 : -150; })
    .gravity(0.1)
    .size([width, height -160])
    .on("tick", tick);

var vis = d3.select("#chart").append("svg:svg")
.attr("width", width)
.attr("height", height);

function moveChildren(node) {
  if(node.children) {
    node.children.forEach(function(c) { moveChildren(c); });
    node._children = node.children;
    node.children = null;

  }
}

var link = vis.selectAll(".link"),
    node = vis.selectAll(".node");

d3.json("graph.json", function(error, json) {
  root = json;
  root.x = width / 2;
  root.y = height / 2 - 80;
  moveChildren(json);
  update();
});

function update(d) {

  var nodes = flatten(root),
      links = d3.layout.tree().links(nodes);

  // Restart the force layout.
  force
      .nodes(nodes) //.nodes([nodes[0]])
      .links(links)
      .start();

  // Update links.
  link = vis.selectAll("line.link")
  .data(links, function(d) { return d.target.id; });

  // Enter any new links.
  link.enter().insert("line", ".node")
      .attr("class", "link");

  // Exit any old links.
  link.exit().remove();

  // Update nodes.
  node = node.data(nodes, function(d) { return d.id; });

  // ??
  node.transition()
  .attr("r", function(d) { return d.children ? 4.5 : Math.sqrt(d.size) / 10; });

  // Enter any new nodes.
  var nodeEnter = node.enter().append("g")
      .attr("class", "node")
      .on("click", click)
      .call(force.drag)
      .attr("href", function(d) { return d.link; });

  // Exit any old nodes.
  node.exit().remove();

  nodeEnter.append("svg:a")
  .attr("xlink:href", function(d){return d.link;})
  .append("circle")
      .attr("r", function(d) { return Math.sqrt(d.size) / 15 || 2.5; });

  nodeEnter.append("text")
      .attr("dy", "0.35em")
      .text(function(d) { return d.name; });

  node.select("circle")
      .style("fill", color);
}

function tick(d) {
  // sets the bounding box
  node.attr("cx", function(d) { return d.x = Math.max(15, Math.min(width - 15, d.x)); })
  .attr("cy", function(d) { return d.y = Math.max(15, Math.min(height - 15, d.y)); });

  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(" + d.x + "," + d.y + ")"; });
}

function color(d) {
   console.log(d)
   return leafColor(d.parentName)
}

function neighboring(a, b) {
  return a.index == b.index || linkedByIndex[a.index + "," + b.index];
}

// Toggle children on click.
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();

  // marks the clicked node
  d3.selectAll(".link").transition().duration(500)
  .style("stroke-width", function(o) {
    return o.target === d || o.target === d ? 3 : 1;
  }).style("stroke", function(o) {
    return o.target === d || o.target === d ? "red" : "grey";
  });

  d3.selectAll(".node").transition().duration(500)
    .style("stroke-width", function(o) {
       return neighboring(d, o) ? 1 : 0;
    }).style("stroke", function(o) {
       return neighboring(d, o) ? "red" : "white";
    });
}

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

json:

    {
 "name": "AR1", "size": 100000,
 "parentName": "none",
 "link": "ar1.html",
 "children": [
  {
    "name": "LA", 
    "size": 50000, 
    "parentName": "A", 
    "link": "la.html",
    "children": [
      {"name": "AR", "parentName": "A", "size": 50000,
      "children": [
      {"name": "RE", "parentName": "A", "size": 50000,
        "children": [
          {"name": "ME", "parentName": "A", "size": 50000}
        ]
      },
      {"name": "ME", "parentName": "A", "size": 50000,
        "children": [
          {"name": "RE", "parentName": "A", "size": 50000}
        ]
      }
     ]
      },
      {"name": "RE", "parentName": "A", "size": 50000,
      "children": [
      {"name": "AR", "parentName": "A", "size": 50000,
        "children": [
          {"name": "ME", "parentName": "A", "size": 50000}
        ]
      },
      {"name": "ME", "parentName": "A", "size": 50000,
        "children": [
          {"name": "AR", "parentName": "A", "size": 50000}
        ]
      }
     ]
      },
      {"name": "ME", "parentName": "A", "size": 50000,
      "children": [
      {"name": "AR", "parentName": "A", "size": 50000,
        "children": [
          {"name": "RE", "parentName": "A", "size": 50000}
        ]
      },
      {"name": "RE", "parentName": "A", "size": 50000,
        "children": [
          {"name": "AR", "parentName": "A", "size": 50000}
        ]
      }
     ]
      }
     ]
  },
  {
    "name": "AR", 
    "size": 50000, 
    "parentName": "B", 
    "link": "ar.html",
    "children": [
      {"name": "LA", "parentName": "B", "size":50000,
      "children": [
      {"name": "RE", "parentName": "B", "size": 50000,
        "children": [
          {"name": "ME", "parentName": "B", "size": 50000}
        ]
      },
      {"name": "ME", "parentName": "B", "size": 50000,
        "children": [
          {"name": "RE", "parentName": "B", "size": 50000}
        ]
      }
     ]
      },
      {"name": "RE", "parentName": "B", "size": 50000,
      "children": [
      {"name": "LA", "parentName": "B", "size": 50000,
        "children": [
          {"name": "ME", "parentName": "B", "size": 50000}
        ]
      },
      {"name": "ME", "parentName": "B", "size": 50000,
        "children": [
          {"name": "LA", "parentName": "B", "size": 50000}
        ]
      }
     ]
      },
      {"name": "ME", "parentName": "B", "size": 50000,
      "children": [
      {"name": "LA", "parentName": "B", "size": 50000,
        "children": [
          {"name": "RE", "parentName": "B", "size": 50000}
        ]
      },
      {"name": "RE", "parentName": "B", "size": 50000,
        "children": [
          {"name": "LA", "parentName": "B", "size": 50000}
        ]
      }
     ]
      }
     ]
  },
  {
    "name": "RE", 
    "size": 50000, 
    "parentName": "C", 
    "link": "re.html",
    "children": [
      {"name": "LA", "parentName": "C", "size": 50000,
      "children": [
      {"name": "AR", "parentName": "C", "size": 50000,
        "children": [
          {"name": "ME", "parentName": "C", "size": 50000}
        ]
      },
      {"name": "ME", "parentName": "C", "size": 50000,
        "children": [
          {"name": "AR", "parentName": "C", "size": 50000}
        ]
      }
     ]
      },
      {"name": "AR", "parentName": "C", "size": 50000,
      "children": [
      {"name": "LA", "parentName": "C", "size": 50000,
        "children": [
          {"name": "ME", "parentName": "C", "size": 50000}
        ]
      },
      {"name": "ME", "parentName": "C", "size": 50000,
        "children": [
          {"name": "LA", "parentName": "C", "size": 50000}
        ]
      }
     ]
      },
      {"name": "ME", "parentName": "C", "size": 50000,
      "children": [
      {"name": "LA", "parentName": "C", "size": 50000,
        "children": [
          {"name": "AR", "parentName": "C", "size": 50000}
        ]
      },
      {"name": "AR", "parentName": "C", "size": 50000,
        "children": [
          {"name": "LA", "parentName": "C", "size": 50000}
        ]
      }
     ]
      }
     ]
  },
  {
    "name": "ME", 
    "size": 50000, 
    "parentName": "D", 
    "link": "me.html",
    "children": [
      {"name": "LA", "parentName": "D", "size": 50000,
      "children": [
      {"name": "AR", "parentName": "D", "size": 50000,
        "children": [
          {"name": "RE", "parentName": "D", "size": 50000}
        ]
      },
      {"name": "RE", "parentName": "D", "size": 50000,
        "children": [
          {"name": "AR", "parentName": "D", "size": 50000}
        ]
      }
     ]
      },
      {"name": "AR", "parentName": "D", "size": 50000,
      "children": [
      {"name": "LA", "parentName": "D", "size": 50000,
        "children": [
          {"name": "RE", "parentName": "D", "size": 50000}
        ]
      },
      {"name": "RE", "parentName": "D", "size": 50000,
        "children": [
          {"name": "LA", "parentName": "D", "size": 50000}
        ]
      }
     ]
      },
      {"name": "RE", "parentName": "D", "size": 50000,
      "children": [
      {"name": "LA", "parentName": "D", "size": 50000,
        "children": [
          {"name": "AR", "parentName": "D", "size": 50000}
        ]
      },
      {"name": "AR", "parentName": "D", "size": 50000,
        "children": [
          {"name": "LA", "parentName": "D", "size": 50000}
        ]
      }
     ]
      }
     ]
  }
 ]
}

i got partial help already here: D3.js Collapsible Force Layout, collapsed by default

However, it seems quite complex and does not work when having identical names of the nodes.

i used this piece of code:

function moveChildren(node) {
if(node.children) {
    node.children.forEach(function(c) { moveChildren(c); });
    node._children = node.children;
    node.children = null;
}
}

moveChildren(json);

as suggested here: d3.js How to make all the nodes collapsed in Collapsible indented Tree

The diagram gets corrupted. I went through many other solution on this forim that did not work, eg: d3.js collapsible force layout with all the nodes collapsed

How can I start with all the nodes collapsed in d3js?

http://bl.ocks.org/david4096/6168323

None of it helped. Any suggestion appreciated. Thank you!

Community
  • 1
  • 1
matus
  • 53
  • 8
  • I would make the names unique. Having duplicate names may cause further trouble later. – Lars Kotthoff Jan 27 '16 at 17:55
  • Thank you for answering @LarsKotthoff. Unfortunately we are using identical names, as we're making a diagram of possible combinations of 5 elements that have the same name. Is it possible to have unique name but the label of the node is different? Let's say the names of two nodes in .json go "uniqueA" "uniqueB" but their labels (that would be shown) are "sameA" "sameA"? – matus Jan 27 '16 at 18:05
  • Yes, that would be possible, but it seems to me that the problems you're having are caused by the duplicate identifiers and not labels. – Lars Kotthoff Jan 27 '16 at 20:28
  • I started with unique names and still had the same problem. Would you be willing to be more specific? – matus Jan 27 '16 at 21:10
  • Well you've found the answer for how to do this in general already. Could you post the code and data that you're having trouble with (with unique IDs)? – Lars Kotthoff Jan 27 '16 at 21:12
  • In this example: http://plnkr.co/edit/QtFXa53Q7p65NQpO4z5f?p=preview with the help of @thisOneGuy I managed to get it work with unique names. he even suggested that using `node.each(function(d,i){ d.uniqueID = uniqueNode + i; }` i could get the unique ID's. But I was unable to solve that. So I went back and tried what you suggested: `function moveChildren(node)` as seen above which gives corrupted results. – matus Jan 28 '16 at 10:34
  • The plnkr you've linked to seems to work fine? – Lars Kotthoff Jan 28 '16 at 17:22
  • i cracked it now with identical names. working example here: http://plnkr.co/edit/rqh8SD?p=preview i think i can delete this thread and move the answer to my previous question. thank you for helping and commenting! – matus Jan 29 '16 at 09:05

0 Answers0