コード例 #1
0
        /// <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);
            }
        }
コード例 #2
0
        /// <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);
        }
コード例 #4
0
        /// <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);
            }
        }
コード例 #5
0
        /// <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);
            }
        }
コード例 #6
0
        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;
                    }
                }
            }
        }