Genogram: enforce ordering of male/female

I’m trying to create a Genogram based off of the example. In traditional genetic pedigrees, the Paternal side should be on the left side, and the Maternal on the right. In other words, the parents of the proband should be top priority in following the direction of the link. I tried to enforce that the links are always from the husband to the wife. However, when drawn, sometimes it is not drawn correctly.

if (link === null) {
    // add a label node for the marriage link
    var mlab = { s: "LinkLabel" };
    model.addNodeData(mlab);

    // add the marriage link itself, also referring to the label node
    var mdata = { from: key, to: wife, labelKeys: [mlab.key], category: "Marriage" };
    model.addLinkData(mdata);
}})

Any advice on how to achieve this?

What happens when a person has two spouses?

The GenogramLayout is based on LayeredDigraphLayout, which explicitly re-orders nodes to reduce link cross-overs. So there’s no built in way to do what you want. But I can look into it.

The canonical way of drawing pedigree has the Paternal Lineage (of the Proband) on the left, and Maternal on the right. So in terms of ordering nodes, the top priority would be in the Proband’s parents.

If, say, the father had multiple spouses, ordering would not be as important so long that the proband’s father was still to the left of the proband’s mother.

The problem I’m having is that the ordering method is following the correct pattern (Male: left, Female:right) for all of my nodes except for the Father/Mother, which results in the whole sides being on the wrong side.

Thanks for the help.

Well, it’s easy enough to have the GenogramLayout prefer having the father be on the left and and mother on the right, by changing commitNodes as follows:

        var spouseA = lablink.fromNode;
        var spouseB = lablink.toNode;
        // prefer fathers on the left, mothers on the right
        if (spouseA.data.s === "F") {
          var temp = spouseA;
          spouseA = spouseB;
          spouseB = temp;
        }
        // see if the parents are on the desired sides, to avoid a link crossing
        var aParentsNode = layout.findParentsMarriageLabelNode(spouseA);
        var bParentsNode = layout.findParentsMarriageLabelNode(spouseB);
        if (aParentsNode !== null && bParentsNode !== null &&
            aParentsNode.position.x > bParentsNode.position.x) {
          // swap the spouses
          var temp = spouseA;
          spouseA = spouseB;
          spouseB = temp;
        }
        spouseA.position = new go.Point(v.x, v.y);
        spouseB.position = new go.Point(v.x + spouseA.actualBounds.width + 30, v.y);

However this doesn’t help with the big-picture problem that you noticed – sometimes the mother ends up being on the left side. One could live with the parent links for those two being crossed, with their respective families being on the wrong side, or one could live with the mother being on the left and the father on the right, but with fewer crossings.

I can look into this some more, as I find time.

If in the model data you always add the father node before the mother node, then the following initialization in the constructor seems to do what you want:

    function GenogramLayout() {
      go.LayeredDigraphLayout.call(this);
      this.initializeOption = go.LayeredDigraphLayout.InitDepthFirstIn;
    }

Hi @walter, sorry for the long response. I tried this out at it seems to be working how I’d like. Thanks@