public ColumnNodes[] computeNodeLayers()
    {
        int max = 0;

        for (int i = 0; i < NodesStructures.Length; i++)
        {
            if (NodesStructures[i].depth > max)
            {
                max = NodesStructures[i].depth;
            }
        }
        int    x  = NodesStructures.Max(c => c.depth) + 1;
        double kx = (x1 - x0 - nodeWidth) / (x - 1);

        ColumnNodes[] columns = new ColumnNodes[x];

        foreach (NodesStructure a in NodesStructures)
        {
            double temp = 0;
            switch (align)
            {
            case aligns.justify:
                temp = justify(a, x);
                break;

            case aligns.center:
                temp = center(a);
                break;

            case aligns.right:
                temp = right(a, x);
                break;

            case aligns.left:
                temp = left(a);
                break;

            default:
                Debug.Log("ERROR Align");
                break;
            }
            int i = Math.Max(0, Math.Min(x - 1, (int)Math.Floor(temp)));
            a.layer = i;
            a.x0    = (x0 + i * kx);
            a.x1    = a.x0 + nodeWidth;
            push(a, i, columns);

            /*            if (sort) for (const column of columns) {
             *              column.sort(sort);
             *          }*/
        }
        if (sort != null)
        {
            foreach (var column in columns)
            {
                column.Columnnode.Sort((IComparer <NodesStructure>)sort);
            }
        }
        return(columns);
    }
    public void relaxRightToLeft(ColumnNodes[] columns, double alpha, double beta)
    {
        for (int n = columns.Length, i = n - 2; i >= 0; --i)
        {
            ColumnNodes column = columns[i];
            foreach (NodesStructure source in column.Columnnode)
            {
                double y = 0;
                double w = 0;

                foreach (LinksStructure a in source.SourceLinks)
                {
                    var v = a.value * (a.TargetNode.layer - source.layer);
                    y += sourceTop(source, a.TargetNode) * v;
                    w += v;
                }

                if (!(w > 0))
                {
                    continue;
                }
                var dy = (y / w - source.y0) * alpha;

                source.y0 += dy;
                source.y1 += dy;
                reorderNodeLinks(source);
            }
            if (sort == null)
            {
                column.Columnnode.Sort(ascendingBreadth);
            }
            resolveCollisions(column, beta);
        }
    }
    private void resolveCollisions(ColumnNodes nodes, double alpha)
    {
        var i       = nodes.Columnnode.Count >> 1;
        var subject = nodes.Columnnode[i];

        resolveCollisionsBottomToTop(nodes, subject.y0 - py, i - 1, alpha);
        resolveCollisionsTopToBottom(nodes, subject.y1 + py, i + 1, alpha);
        resolveCollisionsBottomToTop(nodes, y1, nodes.Columnnode.Count - 1, alpha);
        resolveCollisionsTopToBottom(nodes, y0, 0, alpha);
    }
 public void push(NodesStructure a, int i, ColumnNodes[] b)
 {
     if (b[i] == null)
     {
         b[i]            = new ColumnNodes();
         b[i].Columnnode = new List <NodesStructure>();
         b[i].Columnnode.Add(a);
     }
     else
     {
         b[i].Columnnode.Add(a);
     }
 }
 private void resolveCollisionsBottomToTop(ColumnNodes nodes, double y, int i, double alpha)
 {
     for (; i >= 0; --i)
     {
         var node = nodes.Columnnode[i];
         var dy   = (node.y1 - y) * alpha;
         if (dy > 1e-6)
         {
             node.y0 -= dy;
             node.y1 -= dy;
         }
         y = node.y0 - py;
     }
 }
 private void resolveCollisionsTopToBottom(ColumnNodes nodes, double y, int i, double alpha)
 {
     for (; i < nodes.Columnnode.Count; ++i)
     {
         var node = nodes.Columnnode[i];
         var dy   = (y - node.y0) * alpha;
         if (dy > 1e-6)
         {
             node.y0 += dy;
             node.y1 += dy;
         }
         y = node.y1 + py;
     }
 }