using System.Collections.Generic; using Microsoft.Msagl.Core.GraphAlgorithms; using Microsoft.Msagl.Core.Layout; namespace Microsoft.Msagl.Layout.Layered { /// /// Follows the idea from Gansner etc 93, creating a special graph /// for x-coordinates calculation /// internal class XLayoutGraph : BasicGraph { ProperLayeredGraph layeredGraph;//the result of layering LayerArrays layerArrays;//the result of layering int virtualVerticesStart; int virtualVerticesEnd; // we have 0,,,virtualVerticesStart-1 - usual vertices //virtualVerticesStart,...,virtualVerticesEnd -virtual vertices //and virtualVirticesEnd+1, ...NumberOfVertices - nvertices int weightMultiplierOfOriginalOriginal = 1; //weight multiplier for edges with Defaults or n end and start int weightMultOfOneVirtual = 3; //weight multiplier for edges with only one virtual node int weightMultiplierOfTwoVirtual = 8; //weight multiplier for edges with two virtual nodes internal XLayoutGraph(BasicGraph graph, //DAG of the original graph with no multiple edges ProperLayeredGraph layeredGraph, LayerArrays layerArrays, List edges, int nov) { this.SetEdges(edges, nov); this.virtualVerticesStart = graph.NodeCount; this.virtualVerticesEnd = layeredGraph.NodeCount - 1; this.layeredGraph = layeredGraph; this.layerArrays = layerArrays; } /// /// following Gansner etc 93 returning weight multplier bigger if there are virtual nodes /// /// /// internal int EdgeWeightMultiplier(IntEdge edge) { int s = edge.Source; int t = edge.Target; if (s < this.layeredGraph.NodeCount && layerArrays.Y[s] == layerArrays.Y[t] && layerArrays.X[s] == layerArrays.X[t] + 1) return 0; //this edge needed only for separation vertices in the same layer int k = 0; System.Diagnostics.Debug.Assert(s >= this.layeredGraph.NodeCount); //check the graph on correctness` // throw new InvalidOperationException();//"XLayout graph is incorrect"); //here (s0,t0) is the edge of underlying graph int s0 = -1, t0 = -1; //t0 is set to -1 to only avoid the warning //there are only two edges in graph.OutEdges(s) foreach (IntEdge intEdge in this.OutEdges(s)) { if (s0 == -1) s0 = intEdge.Target; else t0 = intEdge.Target; } if (s0 >= virtualVerticesStart && s0 <= virtualVerticesEnd) k++; if (t0 >= virtualVerticesStart && t0 <= virtualVerticesEnd) k++; int ret = k == 0 ? weightMultiplierOfOriginalOriginal : (k == 1 ? weightMultOfOneVirtual : weightMultiplierOfTwoVirtual); return ret; } /// /// caching edges weights /// internal void SetEdgeWeights() { foreach (IntEdge intEdge in this.Edges) intEdge.Weight = intEdge.Weight * EdgeWeightMultiplier(intEdge); } } }