Пример #1
0
        /// <summary>
        /// Calculates the slice positions based on the selected modes.
        /// </summary>
        /// <param name="leftRightMode">Mode of the vertical alignment.</param>
        /// <param name="upperLowerEdges">Alignment based on which edges (upper or lower ones).</param>
        private void CalculateSlicePositions(LeftRightMode leftRightMode, UpperLowerEdges upperLowerEdges)
        {
            int modeIndex = (byte)upperLowerEdges * 2 + (byte)leftRightMode;

            InitializeRootsAndAligns(modeIndex);
            DoAlignment(modeIndex, leftRightMode, upperLowerEdges);
            InitializeSinksAndShifts(modeIndex);
            DoSliceCompaction(modeIndex, leftRightMode, upperLowerEdges);
        }
Пример #2
0
 /// <summary>
 /// Calculates the horizontal positions based on the selected modes.
 /// </summary>
 /// <param name="leftRightMode">Mode of the vertical alignment.</param>
 /// <param name="upperLowerEdges">Alignment based on which edges (upper or lower ones).</param>
 private void CalculateHorizontalPositions(LeftRightMode leftRightMode, UpperLowerEdges upperLowerEdges)
 {
     if (_graph.Vertices.Count() == 1)
     {
         _graph.Vertices.First().HorizontalPosition = 0;
     }
     else
     {
         int modeIndex = (byte)upperLowerEdges * 2 + (byte)leftRightMode;
         InitializeRootsAndAligns(modeIndex);
         DoAlignment(modeIndex, leftRightMode, upperLowerEdges);
         WriteOutAlignment(modeIndex);
         InitializeSinksAndShifts(modeIndex);
         DoHorizontalCompaction(modeIndex, leftRightMode, upperLowerEdges);
     }
 }
Пример #3
0
        private void DoHorizontalCompaction(int modeIndex, LeftRightMode leftRightMode, UpperLowerEdges upperLowerEdges)
        {
            foreach (var vertex in _graph.Vertices)
            {
                if (vertex.Roots[modeIndex] == vertex)
                {
                    PlaceBlock(modeIndex, leftRightMode, upperLowerEdges, vertex);
                }
            }

            foreach (var vertex in _graph.Vertices)
            {
                vertex.HorizontalPositions[modeIndex] = vertex.Roots[modeIndex].HorizontalPositions[modeIndex];
                if (vertex.Roots[modeIndex].Sinks[modeIndex].Shifts[modeIndex] < double.PositiveInfinity &&
                    vertex.Roots[modeIndex] == vertex)
                {
                    vertex.HorizontalPositions[modeIndex] += vertex.Roots[modeIndex].Sinks[modeIndex].Shifts[modeIndex];
                }
            }
        }
Пример #4
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;
                var 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)
                {
                    var vertex = layer[j];
                    if (vertex.Type == VertexTypes.Original ||
                        vertex.Type == VertexTypes.RVertex ||
                        (vertex.Type == VertexTypes.PVertex && upperLowerEdges == UpperLowerEdges.Upper) ||
                        (vertex.Type == VertexTypes.QVertex && upperLowerEdges == UpperLowerEdges.Lower))
                    {
                        List <SugiEdge> neighbourEdges = null;
                        neighbourEdges = upperLowerEdges == UpperLowerEdges.Upper
                            ? _graph.InEdges(vertex).OrderBy(e => e.Source.Position).ToList()
                            : _graph.OutEdges(vertex).OrderBy(e => e.Target.Position).ToList();
                        if (neighbourEdges.Count <= 0)
                        {
                            continue;
                        }

                        int   c1      = (int)Math.Floor((neighbourEdges.Count + 1) / 2.0) - 1;
                        int   c2      = (int)Math.Ceiling((neighbourEdges.Count + 1) / 2.0) - 1;
                        int[] medians = null;
                        if (c1 == c2)
                        {
                            medians = new int[1] {
                                c1
                            };
                        }
                        else
                        {
                            medians = leftRightMode == LeftRightMode.Left
                                ? new int[2] {
                                c1, c2
                            }
                                : new int[2] {
                                c2, c1
                            };
                        }
                        for (int m = 0; m < medians.Length; m++)
                        {
                            if (vertex.Aligns[modeIndex] != vertex)
                            {
                                continue;
                            }
                            var edge = neighbourEdges[medians[m]];
                            if (edge.Marked)
                            {
                                Debug.WriteLine("Edge marked: " + edge.Source.OriginalVertex + ", " + edge.Target.OriginalVertex);
                            }
                            var neighbour = edge.OtherVertex(vertex);
                            if (!edge.Marked &&
                                ((leftRightMode == LeftRightMode.Left && r < neighbour.Position) ||
                                 (leftRightMode == LeftRightMode.Right && r > neighbour.Position)))
                            {
                                neighbour.Aligns[modeIndex]      = vertex;
                                neighbour.BlockWidths[modeIndex] = Math.Max(neighbour.BlockWidths[modeIndex], vertex.Size.Width);
                                vertex.Roots[modeIndex]          = neighbour.Roots[modeIndex];
                                vertex.Aligns[modeIndex]         = vertex.Roots[modeIndex];
                                r = neighbour.Position;
                            }
                        }
                    }
                    else if (vertex.Type == VertexTypes.PVertex /*&& upperLowerEdges == UpperLowerEdges.Lower*/)
                    {
                        //align the segment of the PVertex
                        vertex.Roots[modeIndex]  = vertex.Segment.QVertex.Roots[modeIndex];
                        vertex.Aligns[modeIndex] = vertex.Roots[modeIndex];
                        r = vertex.Segment.Position;
                    }
                    else if (vertex.Type == VertexTypes.QVertex /*&& upperLowerEdges == UpperLowerEdges.Upper*/)
                    {
                        //align the segment of the QVertex
                        vertex.Roots[modeIndex]  = vertex.Segment.PVertex.Roots[modeIndex];
                        vertex.Aligns[modeIndex] = vertex.Roots[modeIndex];
                        r = vertex.Segment.Position;
                    }
                }
            }
        }
Пример #5
0
        private void PlaceBlock(int modeIndex, LeftRightMode leftRightMode, UpperLowerEdges upperLowerEdges, SugiVertex v)
        {
            if (!double.IsNaN(v.HorizontalPositions[modeIndex]))
            {
                return;
            }

            double delta = Parameters.VertexDistance;

            v.HorizontalPositions[modeIndex] = 0;
            Data w = v;

            do
            {
                SugiVertex wVertex  = w as SugiVertex;
                Segment    wSegment = w as Segment;
                if (_sparseCompactionGraph.ContainsVertex(w) &&
                    ((leftRightMode == LeftRightMode.Left && _sparseCompactionGraph.InDegree(w) > 0) ||
                     (leftRightMode == LeftRightMode.Right && _sparseCompactionGraph.OutDegree(w) > 0)))
                {
                    var edges = leftRightMode == LeftRightMode.Left
                        ? _sparseCompactionGraph.InEdges(w)
                        : _sparseCompactionGraph.OutEdges(w);
                    foreach (var edge in edges)
                    {
                        SugiVertex u    = null;
                        Data       pred = leftRightMode == LeftRightMode.Left ? edge.Source : edge.Target;
                        if (pred is SugiVertex)
                        {
                            u = ((SugiVertex)pred).Roots[modeIndex];
                        }
                        else
                        {
                            var segment = (Segment)pred;
                            u = upperLowerEdges == UpperLowerEdges.Upper ? segment.PVertex.Roots[modeIndex] : segment.QVertex.Roots[modeIndex];
                        }
                        PlaceBlock(modeIndex, leftRightMode, upperLowerEdges, u);
                        if (v.Sinks[modeIndex] == v)
                        {
                            v.Sinks[modeIndex] = u.Sinks[modeIndex];
                        }
                        //var xDelta = delta + (v.Roots[modeIndex].BlockWidths[modeIndex] + u.BlockWidths[modeIndex]) / 2.0;
                        var xDelta = delta + ((wVertex != null ? wVertex.Size.Width : 0.0) + ((pred is SugiVertex) ? ((SugiVertex)pred).Size.Width : u.BlockWidths[modeIndex])) / 2.0;
                        if (v.Sinks[modeIndex] != u.Sinks[modeIndex])
                        {
                            var s = leftRightMode == LeftRightMode.Left
                                ? v.HorizontalPositions[modeIndex] - u.HorizontalPositions[modeIndex] - xDelta
                                : u.HorizontalPositions[modeIndex] - v.HorizontalPositions[modeIndex] - xDelta;

                            u.Sinks[modeIndex].Shifts[modeIndex] = leftRightMode == LeftRightMode.Left
                                ? Math.Min(u.Sinks[modeIndex].Shifts[modeIndex], s)
                                : Math.Max(u.Sinks[modeIndex].Shifts[modeIndex], s);
                        }
                        else
                        {
                            v.HorizontalPositions[modeIndex] =
                                leftRightMode == LeftRightMode.Left
                                    ? Math.Max(v.HorizontalPositions[modeIndex], u.HorizontalPositions[modeIndex] + xDelta)
                                    : Math.Min(v.HorizontalPositions[modeIndex], u.HorizontalPositions[modeIndex] - xDelta);
                        }
                    }
                }
                if (wSegment != null)
                {
                    w = (upperLowerEdges == UpperLowerEdges.Upper) ? wSegment.QVertex : wSegment.PVertex;
                }
                else if (wVertex.Type == VertexTypes.PVertex && upperLowerEdges == UpperLowerEdges.Upper)
                {
                    w = wVertex.Segment;
                }
                else if (wVertex.Type == VertexTypes.QVertex && upperLowerEdges == UpperLowerEdges.Lower)
                {
                    w = wVertex.Segment;
                }
                else
                {
                    w = wVertex.Aligns[modeIndex];
                }
            } while (w != v);
        }
Пример #6
0
        private void PlaceBlock(
            int modeIndex,
            LeftRightMode leftRightMode,
            UpperLowerEdges upperLowerEdges,
            [NotNull] SugiVertex v)
        {
            if (!double.IsNaN(v.SlicePositions[modeIndex]))
            {
                return;
            }

            double delta = Parameters.SliceGap;

            v.SlicePositions[modeIndex] = 0;
            Data w = v;

            do
            {
                var wVertex  = w as SugiVertex;
                var wSegment = w as Segment;
                if (_sparseCompactionGraph.ContainsVertex(w) &&
                    (leftRightMode == LeftRightMode.Left && _sparseCompactionGraph.InDegree(w) > 0 ||
                     leftRightMode == LeftRightMode.Right && _sparseCompactionGraph.OutDegree(w) > 0))
                {
                    IEnumerable <IEdge <Data> > edges = leftRightMode == LeftRightMode.Left
                        ? _sparseCompactionGraph.InEdges(w)
                        : _sparseCompactionGraph.OutEdges(w);

                    foreach (IEdge <Data> edge in edges)
                    {
                        SugiVertex u;
                        Data       predecessor = leftRightMode == LeftRightMode.Left ? edge.Source : edge.Target;
                        if (predecessor is SugiVertex vertex)
                        {
                            u = vertex.Roots[modeIndex];
                        }
                        else
                        {
                            var segment = (Segment)predecessor;
                            u = upperLowerEdges == UpperLowerEdges.Upper ? segment.PVertex.Roots[modeIndex] : segment.QVertex.Roots[modeIndex];
                        }

                        PlaceBlock(modeIndex, leftRightMode, upperLowerEdges, u);

                        if (v.Sinks[modeIndex] == v)
                        {
                            v.Sinks[modeIndex] = u.Sinks[modeIndex];
                        }

                        double xDelta = delta
                                        + (
                            (wVertex?.Size.Width ?? 0.0)
                            + (predecessor is SugiVertex sugiVertex
                                                ? sugiVertex.Size.Width
                                                : u.BlockWidths[modeIndex])
                            ) / 2.0;

                        if (v.Sinks[modeIndex] != u.Sinks[modeIndex])
                        {
                            double s = leftRightMode == LeftRightMode.Left
                                ? v.SlicePositions[modeIndex] - u.SlicePositions[modeIndex] - xDelta
                                : u.SlicePositions[modeIndex] - v.SlicePositions[modeIndex] - xDelta;

                            u.Sinks[modeIndex].Shifts[modeIndex] = leftRightMode == LeftRightMode.Left
                                ? Math.Min(u.Sinks[modeIndex].Shifts[modeIndex], s)
                                : Math.Max(u.Sinks[modeIndex].Shifts[modeIndex], s);
                        }
                        else
                        {
                            v.SlicePositions[modeIndex] = leftRightMode == LeftRightMode.Left
                                ? Math.Max(v.SlicePositions[modeIndex], u.SlicePositions[modeIndex] + xDelta)
                                : Math.Min(v.SlicePositions[modeIndex], u.SlicePositions[modeIndex] - xDelta);
                        }
                    }
                }

                if (wSegment != null)
                {
                    w = upperLowerEdges == UpperLowerEdges.Upper ? wSegment.QVertex : wSegment.PVertex;
                }
                // ReSharper disable once PossibleNullReferenceException
                // Justification: If not a segment then it's a vertex
                else if (wVertex.Type == VertexTypes.PVertex && upperLowerEdges == UpperLowerEdges.Upper)
                {
                    w = wVertex.Segment;
                }
                else if (wVertex.Type == VertexTypes.QVertex && upperLowerEdges == UpperLowerEdges.Lower)
                {
                    w = wVertex.Segment;
                }
                else
                {
                    w = wVertex.Aligns[modeIndex];
                }
            } while (w != v);
        }
Пример #7
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;
                    }
                }
            }
        }