/// <summary> /// Converts the VisitedGraph to the inner type (which is a mutable graph representation). /// Wraps the vertices, converts the edges. /// </summary> protected void ConvertGraph(IDictionary <TVertex, Size> vertexSizes) { //creating the graph with the new type _graph = new SoftMutableHierarchicalGraph <SugiVertex, SugiEdge>(true); var vertexDict = new Dictionary <TVertex, SugiVertex>(); //wrapping the vertices foreach (TVertex v in VisitedGraph.Vertices) { var size = vertexSizes[v]; size.Height += Parameters.VerticalGap; size.Width += Parameters.HorizontalGap; var wrapped = new SugiVertex(v, size); _graph.AddVertex(wrapped); vertexDict[v] = wrapped; } //creating the new edges foreach (TEdge e in VisitedGraph.Edges) { var wrapped = new SugiEdge(e, vertexDict[e.Source], vertexDict[e.Target], _edgePredicate(e)); _graph.AddEdge(wrapped); } }
/// <summary> /// Initializes the private _graph field which stores the graph that /// we operate on. /// </summary> private void InitTheGraph() { //make a copy of the original graph _graph = new BidirectionalGraph <SugiVertex, SugiEdge>(); //copy the vertices foreach (var vertex in VisitedGraph.Vertices) { Size size = new Size(); if (_vertexSizes != null) { _vertexSizes.TryGetValue(vertex, out size); } var vertexWrapper = new SugiVertex(vertex, size); _graph.AddVertex(vertexWrapper); _vertexMap[vertex] = vertexWrapper; } //copy the edges foreach (var edge in VisitedGraph.Edges) { var edgeWrapper = new SugiEdge(edge, _vertexMap[edge.Source], _vertexMap[edge.Target]); _graph.AddEdge(edgeWrapper); } }
/// <summary> /// Adds a new segment to the sparse compaction graph. /// </summary> /// <param name="pVertex">The source vertex of the segment.</param> /// <param name="qVertex">The target vertex of the segment.</param> /// <param name="edge">The edge which has been replaced by the /// dummy vertices and this segment.</param> /// <returns>The newly created segment.</returns> private Segment AddSegment(SugiVertex pVertex, SugiVertex qVertex, SugiEdge edge) { var segment = new Segment() { PVertex = pVertex, QVertex = qVertex }; pVertex.Segment = segment; qVertex.Segment = segment; return(segment); }
/// <summary> /// Removes the cycles from the given graph. /// It reverts some edges, so the cycles disappeares. /// </summary> private void FilterCycles() { var cycleEdges = new List <SugiEdge>(); var dfsAlgo = new DepthFirstSearchAlgorithm <SugiVertex, SugiEdge>(_graph); dfsAlgo.BackEdge += cycleEdges.Add; //non-tree edges selected dfsAlgo.Compute(); //put back the reverted ones foreach (var edge in cycleEdges) { _graph.RemoveEdge(edge); var revertEdge = new SugiEdge(edge.Original, edge.Target, edge.Source, edge.Type); _graph.AddEdge(revertEdge); } }
/// <summary> /// Initializes the <see cref="_graph"/> field which stores the graph that we operate on. /// </summary> private void CopyToWorkingGraph() { // Make a copy of the original graph _graph = new BidirectionalGraph <SugiVertex, SugiEdge>(); // Copy the vertices foreach (TVertex vertex in VisitedGraph.Vertices) { var size = default(Size); _verticesSizes?.TryGetValue(vertex, out size); var vertexWrapper = new SugiVertex(vertex, size); _graph.AddVertex(vertexWrapper); _verticesMap[vertex] = vertexWrapper; } // Copy the edges foreach (TEdge edge in VisitedGraph.Edges) { var edgeWrapper = new SugiEdge(edge, _verticesMap[edge.Source], _verticesMap[edge.Target]); _graph.AddEdge(edgeWrapper); } }
private void DoAlignment(int modeIndex, LeftRightMode leftRightMode, UpperLowerEdges upperLowerEdges) { int layerStart, layerEnd, layerStep; if (upperLowerEdges == UpperLowerEdges.Upper) { layerStart = 0; layerEnd = _layers.Count; layerStep = 1; } else { layerStart = _layers.Count - 1; layerEnd = -1; layerStep = -1; } for (int i = layerStart; i != layerEnd; i += layerStep) { int r = leftRightMode == LeftRightMode.Left ? int.MinValue : int.MaxValue; IList <SugiVertex> layer = _layers[i]; int vertexStart, vertexEnd, vertexStep; if (leftRightMode == LeftRightMode.Left) { vertexStart = 0; vertexEnd = layer.Count; vertexStep = 1; } else { vertexStart = layer.Count - 1; vertexEnd = -1; vertexStep = -1; } for (int j = vertexStart; j != vertexEnd; j += vertexStep) { SugiVertex vertex = layer[j]; switch (vertex.Type) { case VertexTypes.Original: case VertexTypes.RVertex: case VertexTypes.PVertex when upperLowerEdges == UpperLowerEdges.Upper: case VertexTypes.QVertex when upperLowerEdges == UpperLowerEdges.Lower: { SugiEdge[] neighborEdges = upperLowerEdges == UpperLowerEdges.Upper ? _graph.InEdges(vertex).OrderBy(e => e.Source.Position).ToArray() : _graph.OutEdges(vertex).OrderBy(e => e.Target.Position).ToArray(); if (neighborEdges.Length <= 0) { continue; } int c1 = (int)Math.Floor((neighborEdges.Length + 1) / 2.0) - 1; int c2 = (int)Math.Ceiling((neighborEdges.Length + 1) / 2.0) - 1; int[] medians; if (c1 == c2) { medians = new[] { c1 }; } else { medians = leftRightMode == LeftRightMode.Left ? new[] { c1, c2 } : new[] { c2, c1 }; } foreach (int median in medians) { if (vertex.Aligns[modeIndex] != vertex) { continue; } SugiEdge edge = neighborEdges[median]; SugiVertex neighbor = edge.GetOtherVertex(vertex); if (!edge.Marked && (leftRightMode == LeftRightMode.Left && r < neighbor.Position || leftRightMode == LeftRightMode.Right && r > neighbor.Position)) { neighbor.Aligns[modeIndex] = vertex; neighbor.BlockWidths[modeIndex] = Math.Max(neighbor.BlockWidths[modeIndex], vertex.Size.Width); vertex.Roots[modeIndex] = neighbor.Roots[modeIndex]; vertex.Aligns[modeIndex] = vertex.Roots[modeIndex]; r = neighbor.Position; } } break; } case VertexTypes.PVertex: // Align the segment of the PVertex vertex.Roots[modeIndex] = vertex.Segment.QVertex.Roots[modeIndex]; vertex.Aligns[modeIndex] = vertex.Roots[modeIndex]; r = vertex.Segment.Position; break; case VertexTypes.QVertex: // Align the segment of the QVertex vertex.Roots[modeIndex] = vertex.Segment.PVertex.Roots[modeIndex]; vertex.Aligns[modeIndex] = vertex.Roots[modeIndex]; r = vertex.Segment.Position; break; } } } }