Hi,
I think the best result you can get with built-in layouts is via LayeredLayout with custom layers enabled to map generation to layer. Also add a fictional node for each couple with children and connect parent and child nodes to it to keep them close together. With that, you should get nice node positions without link crossings, and could do some post-processing to set link shapes, align nodes, etc. For example the code below creates a subset of the diagram shown at
http://www.genopro.com/genogram/, and produces the layout shown in the image.
void TestGenogram()
{
GenerateGenogram();
ArrangeGenogram();
}
void GenerateGenogram()
{
diagram.ClearAll();
var n1 = AddNode("Grand Papa", 0);
var n2 = AddNode("Grand Maman", 0);
var c1 = SetCouple(n1, n2);
var n3 = AddNode("Pierre", 0);
var n4 = AddNode("Yolande", 0);
var c2 = SetCouple(n3, n4);
var n5 = AddNode("Lisa", 0);
var n6 = AddNode("Lisa's first hsb.", 0);
var c3 = SetCouple(n5, n6);
var n7 = AddNode("Andre", 1);
var n8 = AddNode("Helene", 1);
var n9 = AddNode("???", 1);
var c4 = SetCouple(n7, n8);
var c5 = SetCouple(n7, n9);
SetChild(n7, c1);
SetChild(n8, c2);
SetChild(n9, c3);
var n10 = AddNode("Daniel", 2);
var n11 = AddNode("Anne", 2);
var n12 = AddNode("Benoit", 2);
var n13 = AddNode("Raphael", 2);
var n14 = AddNode("Estelle", 2);
var n15 = AddNode("Jean claude", 2);
var n16 = AddNode("Mike", 2);
SetChild(n10, c4);
SetChild(n11, c4);
SetChild(n12, c4);
SetChild(n14, c4);
SetChild(n15, c4);
SetChild(n16, c5);
SetCouple(n13, n14);
}
DiagramNode AddNode(string name, int generation)
{
var node = diagram.Factory.CreateShapeNode(0, 0, 15, 8);
node.Text = name;
node.LayoutTraits[LayeredLayoutTraits.Layer] = generation * 2;
node.Font = new Font("Arial", 7);
return node;
}
void SetChild(DiagramNode node, DiagramNode couple)
{
diagram.Factory.CreateDiagramLink(couple, node);
}
DiagramNode SetCouple(DiagramNode n1, DiagramNode n2)
{
var node = diagram.Factory.CreateShapeNode(0, 0, 1, 1);
node.Transparent = true;
node.LayoutTraits[LayeredLayoutTraits.Layer] =
(int)n1.LayoutTraits[LayeredLayoutTraits.Layer] + 1;
var l1 = diagram.Factory.CreateDiagramLink(n1, node);
l1.HeadShape = ArrowHeads.None;
var l2 = diagram.Factory.CreateDiagramLink(n2, node);
l2.HeadShape = ArrowHeads.None;
return node;
}
void ArrangeGenogram()
{
var ll = new LayeredLayout();
ll.EnableCustomLayers = true;
ll.LayerDistance = 10;
ll.StraightenLongLinks = true;
ll.Arrange(diagram);
foreach (var link in diagram.Links)
{
link.Shape = LinkShape.Cascading;
var or = link.Origin.Bounds;
var dr = link.Destination.Bounds;
SetLinkPoints(link,
new PointF(or.X + or.Width / 2, or.Bottom),
new PointF(or.X + or.Width / 2, (or.Bottom + dr.Top) / 2),
new PointF(dr.X + dr.Width / 2, (or.Bottom + dr.Top) / 2),
new PointF(dr.X + dr.Width / 2, dr.Top));
}
}
void SetLinkPoints(DiagramLink link, params PointF[] points)
{
link.AutoRoute = false;
link.Shape = LinkShape.Cascading;
link.ControlPoints.Clear();
link.ControlPoints.AddRange(points);
link.UpdateFromPoints(false, true);
}
Some further post-processing you could do is to align parent nodes to the leftmost and rightmost coordinates of their children, and draw couple-to-child links as parallel lines starting from the parent-to-couple links.
I hope that helps,
Stoyan