/// <summary> /// it is a special recovery constructor to recreate the engine from the recovery engine /// </summary> internal LayeredLayoutEngine(LayerArrays engineLayerArrays, GeometryGraph originalGraph, ProperLayeredGraph properLayeredGraph, SugiyamaLayoutSettings sugiyamaSettings, Database database, BasicGraph<Node, IntEdge> intGraph, Dictionary<Node, int> nodeIdToIndex, BasicGraph<Node, IntEdge> gluedDagSkeletonForLayering, bool layersAreDoubled, ConstrainedOrdering constrainedOrdering, bool brandes, XLayoutGraph xLayoutGraph) { this.engineLayerArrays = engineLayerArrays; this.originalGraph = originalGraph; this.properLayeredGraph = properLayeredGraph; this.sugiyamaSettings = sugiyamaSettings; this.database = database; IntGraph = intGraph; this.nodeIdToIndex = nodeIdToIndex; GluedDagSkeletonForLayering = gluedDagSkeletonForLayering; LayersAreDoubled = layersAreDoubled; this.constrainedOrdering = constrainedOrdering; Brandes = brandes; anchors = database.anchors; this.xLayoutGraph = xLayoutGraph; }
/// <summary> /// The function calculates y-layers and x-layers, /// thus, in fact, defining node, including dummy nodes, locations. /// </summary> /// <param name="layerArrays"></param> void CalculateXLayersByGansnerNorth(LayerArrays layerArrays) { xLayoutGraph = CreateXLayoutGraph(layerArrays); CalculateXLayersByGansnerNorthOnProperLayeredGraph(); }
///// <summary> ///// A quote from Gansner93. ///// The method involves constructing an auxiliary graph as illustrated in figure 4-2. ///// This transformation is the graphical analogue of the algebraic ///// transformation mentioned above for removing the absolute values ///// from the optimization problem. The nodes of the auxiliary graph Gў are the nodes of ///// the original graph G plus, for every edge e in G, there is a new node ne. ///// There are two kinds of edges in Gў. One edge class encodes the ///// cost of the original edges. Every edge e = (u,v) in G is replaced by two edges (ne ,u) ///// and (ne, v) with d = 0 and w = w(e)W(e). The other class of edges separates nodes in the same layer. ///// If v is the left neighbor of w, then Gў has an edge f = e(v,w) with d( f ) = r(v,w) and ///// w( f ) = 0. This edge forces the nodes to be sufficiently ///// separated but does not affect the cost of the layout. XLayoutGraph CreateXLayoutGraph(LayerArrays layerArrays) { int nOfVerts = properLayeredGraph.NodeCount; //create edges of XLayoutGraph var edges = new List<IntEdge>(); foreach (LayerEdge e in properLayeredGraph.Edges) { var n1 = new IntEdge(nOfVerts, e.Source); var n2 = new IntEdge(nOfVerts, e.Target); n1.Weight = n2.Weight = e.Weight; n1.Separation = 0; //these edge have 0 separation n2.Separation = 0; nOfVerts++; edges.Add(n1); edges.Add(n2); } foreach (var layer in layerArrays.Layers) for (int i = layer.Length - 1; i > 0; i--) { int source = layer[i]; int target = layer[i - 1]; var ie = new IntEdge(source, target); Anchor sourceAnchor = database.Anchors[source]; Anchor targetAnchor = database.Anchors[target]; double sep = sourceAnchor.LeftAnchor + targetAnchor.RightAnchor + sugiyamaSettings.NodeSeparation; ie.Separation = (int) (sep + 1); edges.Add(ie); } var ret = new XLayoutGraph(IntGraph, properLayeredGraph, layerArrays, edges, nOfVerts); ret.SetEdgeWeights(); return ret; }