1

I have an array that contains IDs of nodes that need to be displayed. The array looks like this list_of_people = ['1887', '1892', '1888' ...].

I am trying to make the graph look like a family tree. I have tried the Dagre layout but the node placement was not what I was looking for (it was close to the desired but does not cover some specific use-cases), so I decided to manually position the nodes.

I have created arrays of IDs for each generation. For example:grandparent_generation = ['1893', '1889' ...], parent_generation = ['1887', '1886'...] and so on.

What I would like to do is to position each generation manually (each generation will have same y value and different x values for the nodes in the generation).

My current code looks something like this:

var width = 960,
    height = 500;


var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

var force = d3.layout.force()
    .size([width, height]);    


force
   .nodes(list_of_people)
   .start();


var node = svg.selectAll(".node")
   .data(list_of_people)
   .enter().append("g")
   .attr("class", "node")


node.append("image")
  .attr("xlink:href", "https://github.com/favicon.ico")
  .attr("x", -8)
  .attr("y", -8)
  .attr("width", 16)
  .attr("height", 16);

and all the nodes are at one position.

I am not sure if the force layout is the correct one. I was thinking if it's possible to do the drawing without layout since I am going to calculate every node's position manually

Is there a way in D3 to give each node with certain ID a custom position?

In Cytoscape.js that would look like this:

for (i=0; i<grandchildren_generation.length; i++){
    x += 100;
    y = 150;
    cy.$('#' + grandchildren_generation[i]).position({x:x, y:y});
}
Porjaz
  • 771
  • 1
  • 8
  • 28
  • 1
    Maybe this example can help you : https://bl.ocks.org/mbostock/4339083. IMO the force layout is not made for this kind of tree – Tim B Aug 01 '17 at 12:30
  • Did something very similar here https://stackoverflow.com/questions/31245751/how-do-you-create-a-family-tree-in-d3-js/31367673#31367673 might be helpful. – Cyril Cherian Aug 01 '17 at 12:34
  • @Cyril The problem is that the tree layout needs nested JSON. My JSON is flat and I would like to avoid nesting it because it will end up too complicated. That is why I was thinking of not using any layout if that is possible and just give every node with certain ID a position. Since I will be giving all the position, I don't have to worry about nodes overlapping. After the nodes are placed, I can draw SVG lines that will have a zigzag like shape to connect the nodes – Porjaz Aug 01 '17 at 12:49

1 Answers1

2

If you have already the position of you node you should add it to your data

 {name: 1887, x: 40, y: 5}

Then you can simply reuse them

.attr("x", function(d) {
    return d.x;
})
.attr("y", function(d) {
    return d.y;
})

See https://jsfiddle.net/mf1hpjx1/

Tim B
  • 1,983
  • 1
  • 20
  • 21