internal void AssignLevelsToVertices() { foreach (Vertex v in vertices.Values) { v.level = Int32.MaxValue; if (v != topVertex && v != bottomVertex && v.incomingEdges.Count == 0 && v.outgoingEdges.Count != 0) { topVertex.FindOrCreateOutgoingEdge(v); } } topVertex.AssignLevel(0); int maxLevel = 0; foreach (Vertex v in vertices.Values) { if (v.level != Int32.MaxValue && maxLevel < v.level) { maxLevel = v.level; } } bottomVertex.level = maxLevel + 1; if (!this.isCallGraph) { // line up all the class names in one level foreach (Edge e in bottomVertex.incomingEdges.Values) { e.FromVertex.level = maxLevel; } // this pass optimizes the layout somewhat // so we have fewer back edges // the idea is to move vertices to the left, if doing so creates no // new back edges, but possibly removes some bool change; do { change = false; foreach (Vertex v in vertices.Values) { int minOutgoingLevel = Int32.MaxValue; foreach (Edge e in v.outgoingEdges.Values) { if (minOutgoingLevel > e.ToVertex.level) { minOutgoingLevel = e.ToVertex.level; } } if (minOutgoingLevel < Int32.MaxValue && minOutgoingLevel - 1 > v.level) { v.level = minOutgoingLevel - 1; change = true; } } }while (change); } }
internal Edge FindOrCreateEdge(Vertex fromVertex, Vertex toVertex) { Debug.Assert(fromVertex != TopVertex || toVertex != BottomVertex); return(fromVertex.FindOrCreateOutgoingEdge(toVertex)); }
internal Edge FindOrCreateEdge(Vertex fromVertex, Vertex toVertex) { Debug.Assert(fromVertex != topVertex || toVertex != bottomVertex); return fromVertex.FindOrCreateOutgoingEdge(toVertex); }