/// <summary>
        /// Initializes the data of the compound vertices.
        /// </summary>
        /// <param name="vertexBorders">Dictionary of the border thicknesses.</param>
        /// <param name="vertexSizes">Dictionary of the vertex sizes.</param>
        /// <param name="layoutTypes">Dictionary of the layout types.</param>
        /// <param name="movableParentUpdateQueue">The compound vertices with fixed layout
        /// should be added to this queue.</param>
        private void InitCompoundVertices(
            IDictionary <TVertex, Thickness> vertexBorders,
            IDictionary <TVertex, Size> vertexSizes,
            IDictionary <TVertex, CompoundVertexInnerLayoutType> layoutTypes,
            Queue <TVertex> movableParentUpdateQueue)
        {
            for (int i = _levels.Count - 1; i >= 0; i--)
            {
                foreach (var vertex in _levels[i])
                {
                    if (!_compoundGraph.IsCompoundVertex(vertex))
                    {
                        continue;
                    }

                    //get the data of the vertex
                    Thickness border;
                    vertexBorders.TryGetValue(vertex, out border);

                    Size vertexSize;
                    vertexSizes.TryGetValue(vertex, out vertexSize);
                    var layoutType = CompoundVertexInnerLayoutType.Automatic;
                    layoutTypes.TryGetValue(vertex, out layoutType);

                    if (layoutType == CompoundVertexInnerLayoutType.Fixed)
                    {
                        movableParentUpdateQueue.Enqueue(vertex);
                    }

                    var position = new Point();
                    VertexPositions.TryGetValue(vertex, out position);

                    //create the information container for this compound vertex
                    var dataContainer = new CompoundVertexData(vertex, _rootCompoundVertex, false, position, vertexSize, border, layoutType);
                    if (i == 0)
                    {
                        dataContainer.Parent = _rootCompoundVertex;
                        _rootCompoundVertex.Children.Add(dataContainer);
                    }

                    _compoundVertexDatas[vertex] = dataContainer;
                    _vertexDatas[vertex]         = dataContainer;

                    //add the datas of the childrens
                    var children     = _compoundGraph.GetChildrenVertices(vertex);
                    var childrenData = children.Select(v => _vertexDatas[v]).ToList();
                    dataContainer.Children = childrenData;
                    foreach (var child in dataContainer.Children)
                    {
                        _rootCompoundVertex.Children.Remove(child);
                        child.Parent = dataContainer;
                    }
                }
            }
        }
        /// <summary>
        /// Initializes the data of the simple vertices.
        /// </summary>
        /// <param name="vertexSizes">Dictionary of the vertex sizes.</param>
        private void InitSimpleVertices(IDictionary <TVertex, Size> vertexSizes)
        {
            foreach (var vertex in _compoundGraph.SimpleVertices)
            {
                Size vertexSize;
                vertexSizes.TryGetValue(vertex, out vertexSize);

                var position = new Point();
                VertexPositions.TryGetValue(vertex, out position);

                //create the information container for this simple vertex
                var dataContainer = new SimpleVertexData(vertex, _rootCompoundVertex, false, position, vertexSize);
                dataContainer.Parent       = _rootCompoundVertex;
                _simpleVertexDatas[vertex] = dataContainer;
                _vertexDatas[vertex]       = dataContainer;
                _rootCompoundVertex.Children.Add(dataContainer);
            }
        }
Example #3
0
        private void EdgeRoutingTest(TEdge ctrl)
        {
            //bad edge data check
            if (ctrl.Source.ID == -1 || ctrl.Target.ID == -1)
            {
                throw new GX_InvalidDataException("SimpleEdgeRouting() -> You must assign unique ID for each vertex to use SimpleER algo!");
            }
            if (ctrl.Source.ID == ctrl.Target.ID)
            {
                return;
            }
            Point start_point, end_point;

            if (!VertexPositions.TryGetValue(ctrl.Source, out start_point) || !VertexPositions.TryGetValue(ctrl.Target, out end_point))
            {
                return;
            }
            //start_point= VertexPositions[ctrl.Source];// new Point(GraphAreaBase.GetX(ctrl.Source), GraphAreaBase.GetY(ctrl.Source));
            //var end_point = VertexPositions[ctrl.Target];// new Point(GraphAreaBase.GetX(ctrl.Target), GraphAreaBase.GetY(ctrl.Target));

            if (start_point == end_point)
            {
                return;
            }

            var originalSizes = getSizesCollection(ctrl, end_point);
            var CHECKLIST     = new Dictionary <TVertex, KeyValuePair <TVertex, Rect> >(originalSizes);
            var leftSIZES     = new Dictionary <TVertex, KeyValuePair <TVertex, Rect> >(originalSizes);


            var tempList = new List <Point>();

            tempList.Add(start_point);

            bool HaveIntersections = true;

            //while we have some intersections - proceed
            while (HaveIntersections)
            {
                var cur_drawback = drawback_distance;
                while (true)
                {
                    var item = CHECKLIST.Keys.FirstOrDefault();
                    //set last route point as current start point
                    start_point = tempList.Last();
                    if (item == null)
                    {
                        //checked all vertices and no intersection was found - quit
                        HaveIntersections = false;
                        break;
                    }
                    else
                    {
                        var   r = originalSizes[item].Value;
                        Point checkpoint;
                        //check for intersection point. if none found - remove vertex from checklist
                        if (MathHelper.GetIntersectionPoint(r, start_point, end_point, out checkpoint) == -1)
                        {
                            CHECKLIST.Remove(item); continue;
                        }
                        var    main_vector = new Vector(end_point.X - start_point.X, end_point.Y - start_point.Y);
                        double X = 0; double Y = 0;
                        //calculate drawback X coordinate
                        if (start_point.X == checkpoint.X || Math.Abs(start_point.X - checkpoint.X) < cur_drawback)
                        {
                            X = start_point.X;
                        }
                        else if (start_point.X < checkpoint.X)
                        {
                            X = checkpoint.X - cur_drawback;
                        }
                        else
                        {
                            X = checkpoint.X + cur_drawback;
                        }
                        //calculate drawback Y coordinate
                        if (start_point.Y == checkpoint.Y || Math.Abs(start_point.Y - checkpoint.Y) < cur_drawback)
                        {
                            Y = start_point.Y;
                        }
                        else if (start_point.Y < checkpoint.Y)
                        {
                            Y = checkpoint.Y - cur_drawback;
                        }
                        else
                        {
                            Y = checkpoint.Y + cur_drawback;
                        }
                        //set drawback checkpoint
                        checkpoint = new Point(X, Y);
                        bool isStartPoint = checkpoint == start_point;

                        bool routeFound        = false;
                        bool viceversa         = false;
                        int  counter           = 1;
                        var  joint             = new Point();
                        bool?blocked_direction = null;
                        while (!routeFound)
                        {
                            //choose opposite vector side each cycle
                            var signedDistance = viceversa ? side_distance : -side_distance;
                            //get new point coordinate
                            joint = new Point(
                                checkpoint.X + signedDistance * counter * (main_vector.Y / main_vector.Length),
                                checkpoint.Y - signedDistance * counter * (main_vector.X / main_vector.Length));

                            //now check if new point is in some other vertex
                            var iresult      = false;
                            var forced_break = false;
                            foreach (var sz in originalSizes)
                            {
                                if (sz.Value.Value.Contains(joint))
                                {
                                    iresult = true;
                                    //block this side direction
                                    if (blocked_direction == null)
                                    {
                                        blocked_direction = viceversa;
                                    }
                                    else
                                    {
                                        //both sides blocked - need to drawback
                                        forced_break = true;
                                    }
                                    break;
                                }
                            }
                            if (forced_break)
                            {
                                break;
                            }

                            //get vector intersection if its ok
                            if (!iresult)
                            {
                                iresult = MathHelper.IsIntersected(r, joint, end_point);
                            }

                            //if no vector intersection - we've found it!
                            if (!iresult)
                            {
                                routeFound        = true;
                                blocked_direction = null;
                            }
                            else
                            {
                                //still have an intersection with current vertex
                                HaveIntersections = true;
                                //skip point search if too many attempts was made (bad logic hack)
                                if (counter > 300)
                                {
                                    break;
                                }
                                counter++;
                                //switch vector search side
                                if (blocked_direction == null || (blocked_direction == viceversa))
                                {
                                    viceversa = !viceversa;
                                }
                            }
                        }

                        //if blocked and this is not start point (nowhere to drawback) - then increase drawback distance
                        if (blocked_direction != null && !isStartPoint)
                        {
                            //search has been blocked - need to drawback
                            cur_drawback += drawback_distance;
                        }
                        else
                        {
                            //add new route point if we found it
                            // if(routeFound)
                            tempList.Add(joint);
                            leftSIZES.Remove(item);
                        }
                    }
                    //remove currently evaded obstacle vertex from the checklist
                    CHECKLIST.Remove(item);
                }
                //assign possible left vertices as a new checklist if any intersections was found
                if (HaveIntersections)
                {
                    CHECKLIST = new Dictionary <TVertex, KeyValuePair <TVertex, Rect> >(leftSIZES);
                }
            }
            //finally, add an end route point

            tempList.Add(end_point);


            if (EdgeRoutes.ContainsKey(ctrl))
            {
                EdgeRoutes[ctrl] = tempList.Count > 2 ? tempList.ToArray() : null;
            }
            else
            {
                EdgeRoutes.Add(ctrl, tempList.Count > 2 ? tempList.ToArray() : null);
            }
        }