/// <summary>
 /// Creates a smoothed polyline
 /// </summary>
 internal SmoothedPolylineCalculator(IntEdge edgePathPar, Anchor[] anchorsP, GeometryGraph origGraph, SugiyamaLayoutSettings settings, LayerArrays la, ProperLayeredGraph layerGraph, Database databaseP) {
     this.database = databaseP;
     edgePath = edgePathPar;
     anchors = anchorsP;
     this.layerArrays = la;
     this.originalGraph = origGraph;
     this.settings = settings;
     this.layeredGraph = layerGraph;
     rightHierarchy = BuildRightHierarchy();
     leftHierarchy = BuildLeftHierarchy();
 }
 internal static void Refine(
     int topNodeP,
     int bottomNode,
     Site topSiteP,
     Anchor[] anchors,
     LayerArrays layerArraysP,
     ProperLayeredGraph layeredGraph,
     GeometryGraph originalGraph,
     double layerSeparation) {
     RefinerBetweenTwoLayers refiner = new RefinerBetweenTwoLayers(topNodeP,
                                                                   bottomNode, topSiteP, layerArraysP,
                                                                   layeredGraph, originalGraph, anchors,
                                                                   layerSeparation);
     refiner.Refine();
 }
 RefinerBetweenTwoLayers(
         int topNodeP,
         int bottomNodeP,
         Site topSiteP,
         LayerArrays layerArraysP,
         ProperLayeredGraph layeredGraphP, GeometryGraph originalGraphP, Anchor[] anchorsP, double layerSeparation) {
     this.topNode = topNodeP;
     this.bottomNode = bottomNodeP;
     this.topSite = topSiteP;
     this.bottomSite = topSiteP.Next;
     this.currentTopSite = topSiteP;
     this.currentBottomSite = topSiteP.Next;
     this.layerArrays = layerArraysP;
     this.layeredGraph = layeredGraphP;
     this.originalGraph = originalGraphP;
     this.anchors = anchorsP;
     this.layerSeparation = layerSeparation;
 }
        void GetSuccessorAndPredecessor(int i, out Anchor p, out Anchor s) {
            int predecessor = 10; //the value does not matter, just to silence the compiler
            foreach (LayerEdge ie in properLayeredGraph.InEdges(i))
                predecessor = ie.Source; // there will be only one

            int successor = 10; // the value does not matter, just to silence the compiler
            foreach (LayerEdge ie in properLayeredGraph.OutEdges(i))
                successor = ie.Target; //there will be only one

            //we compare the sum of length of projections of edges (predecessor,i), (i,successor) to x in cases when the label is to the right and to the left
            p = anchors[predecessor];

            s = anchors[successor];
        }
        static void PutLabelToTheLeft(Anchor a) {
            double r = a.Right;
            double t = a.LeftAnchor;
            a.LeftAnchor = a.RightAnchor;
            a.RightAnchor = t;
            a.X = r - a.RightAnchor;

            a.LabelToTheLeftOfAnchorCenter = true;
            a.LabelToTheRightOfAnchorCenter = false;
        }
        static bool TryToPutLabelOutsideOfAngle(Anchor a, Anchor predecessor, Anchor successor) {
            if (a.LabelToTheRightOfAnchorCenter) {
                if (Point.GetTriangleOrientation(predecessor.Origin, a.Origin, successor.Origin) ==
                    TriangleOrientation.Clockwise)
                    return true;

                double la = a.LeftAnchor;
                double ra = a.RightAnchor;
                double x = a.X;
                PutLabelToTheLeft(a);
                if (Point.GetTriangleOrientation(predecessor.Origin, a.Origin, successor.Origin) ==
                    TriangleOrientation.Counterclockwise)
                    return true;
                a.X = x;
                a.LeftAnchor = la;
                a.RightAnchor = ra;
                a.LabelToTheRightOfAnchorCenter = true;
                a.LabelToTheLeftOfAnchorCenter = false;
                return false;
            }
            return false;
        }
        static void CalcAnchorsForOriginalNode(int i, BasicGraph<Node, IntEdge> intGraph, Anchor[] anchors,
                                               Database database, SugiyamaLayoutSettings settings) {
            double leftAnchor = 0;
            double rightAnchor = leftAnchor;
            double topAnchor = 0;
            double bottomAnchor = topAnchor;

            //that's what we would have without the label and multiedges 

            if (intGraph.Nodes != null) {
                Node node = intGraph.Nodes[i];
                ExtendStandardAnchors(ref leftAnchor, ref rightAnchor, ref topAnchor, ref bottomAnchor, node, settings);
            }

            RightAnchorMultiSelfEdges(i, ref rightAnchor, ref topAnchor, ref bottomAnchor, database, settings);

            double hw = settings.MinNodeWidth/2;
            if (leftAnchor < hw)
                leftAnchor = hw;
            if (rightAnchor < hw)
                rightAnchor = hw;
            double hh = settings.MinNodeHeight/2;

            if (topAnchor < hh)
                topAnchor = hh;
            if (bottomAnchor < hh)
                bottomAnchor = hh;

            anchors[i] = new Anchor(leftAnchor, rightAnchor, topAnchor, bottomAnchor, intGraph.Nodes[i],
                                    settings.LabelCornersPreserveCoefficient) {Padding = intGraph.Nodes[i].Padding};
#if TEST_MSAGL
            anchors[i].UserData = intGraph.Nodes[i].UserData;
#endif
        }
 static void MakeVirtualNodesTall(int[] yLayer, double bottomAnchorMax, double topAnchorMax,
                                  int originalNodeCount, Anchor[] anchors) {
     if (LayerIsOriginal(yLayer, originalNodeCount))
         foreach (int j in yLayer)
             if (j >= originalNodeCount) {
                 Anchor p = anchors[j];
                 p.BottomAnchor = bottomAnchorMax;
                 p.TopAnchor = topAnchorMax;
             }
 }
        internal static void CalculateAnchorSizes(Database database, out Anchor[] anchors,
                                                  ProperLayeredGraph properLayeredGraph, GeometryGraph originalGraph,
                                                  BasicGraph<Node, IntEdge> intGraph, SugiyamaLayoutSettings settings) {
            database.Anchors = anchors = new Anchor[properLayeredGraph.NodeCount];

            for (int i = 0; i < anchors.Length; i++)
                anchors[i] = new Anchor(settings.LabelCornersPreserveCoefficient);

            //go over the old vertices
            for (int i = 0; i < originalGraph.Nodes.Count; i++)
                CalcAnchorsForOriginalNode(i, intGraph, anchors, database, settings);

            //go over virtual vertices
            foreach (IntEdge intEdge in database.AllIntEdges)
                if (intEdge.LayerEdges != null) {
                    foreach (LayerEdge layerEdge in intEdge.LayerEdges) {
                        int v = layerEdge.Target;
                        if (v != intEdge.Target) {
                            Anchor anchor = anchors[v];
                            if (!database.MultipleMiddles.Contains(v)) {
                                anchor.LeftAnchor = anchor.RightAnchor = VirtualNodeWidth/2.0f;
                                anchor.TopAnchor = anchor.BottomAnchor = VirtualNodeHeight(settings)/2.0f;
                            } else {
                                anchor.LeftAnchor = anchor.RightAnchor = VirtualNodeWidth*4;
                                anchor.TopAnchor = anchor.BottomAnchor = VirtualNodeHeight(settings)/2.0f;
                            }
                        }
                    }
                    //fix label vertices      
                    if (intEdge.HasLabel) {
                        int lj = intEdge.LayerEdges[intEdge.LayerEdges.Count/2].Source;
                        Anchor a = anchors[lj];
                        double w = intEdge.LabelWidth, h = intEdge.LabelHeight;
                        a.RightAnchor = w;
                        a.LeftAnchor = VirtualNodeWidth*8;

                        if (a.TopAnchor < h/2.0)
                            a.TopAnchor = a.BottomAnchor = h/2.0;

                        a.LabelToTheRightOfAnchorCenter = true;
                    }
                }
        }
        void CalcAnchorsForOriginalNode(int i) {

            double leftAnchor = 0;
            double rightAnchor = leftAnchor;
            double topAnchor = 0;
            double bottomAnchor = topAnchor;

            //that's what we would have without the label and multiedges 

            if (intGraph.Nodes != null) {
                Node node = intGraph.Nodes[i];
                ExtendStandardAnchors(ref leftAnchor, ref rightAnchor, ref topAnchor, ref bottomAnchor, node);
            }

            RightAnchorMultiSelfEdges(i, ref rightAnchor, ref topAnchor, ref bottomAnchor);

            double hw = LayoutSettings.MinNodeWidth / 2;
            if (leftAnchor < hw)
                leftAnchor = hw;
            if (rightAnchor < hw)
                rightAnchor = hw;
            double hh = LayoutSettings.MinNodeHeight / 2;

            if (topAnchor < hh)
                topAnchor = hh;
            if (bottomAnchor < hh)
                bottomAnchor = hh;

            anchors[i] = new Anchor(leftAnchor, rightAnchor, topAnchor, bottomAnchor, this.intGraph.Nodes[i], LayoutSettings.LabelCornersPreserveCoefficient)
                         {Padding = this.intGraph.Nodes[i].Padding};
#if TEST_MSAGL
            //anchors[i].Id = this.intGraph.Nodes[i].Id;
#endif
        }
        private void SizeAnchors() {
            dataBase.Anchors = anchors = new Anchor[properLayeredGraph.NodeCount];

            for (int i = 0; i < anchors.Length; i++)
                anchors[i] = new Anchor(LayoutSettings.LabelCornersPreserveCoefficient);

            //go over the old vertices
            for (int i = 0; i < intGraph.NodeCount; i++)
                CalcAnchorsForOriginalNode(i);

            //go over virtual vertices
            foreach (IntEdge intEdge in dataBase.AllIntEdges) {
                if (intEdge.LayerEdges != null) {
                    foreach (LayerEdge layerEdge in intEdge.LayerEdges) {
                        int v = layerEdge.Target;
                        if (v != intEdge.Target) {
                            Anchor anchor = anchors[v];
                            if (!dataBase.MultipleMiddles.Contains(v)) {
                                anchor.LeftAnchor = anchor.RightAnchor = VirtualNodeWidth / 2.0f;
                                anchor.TopAnchor = anchor.BottomAnchor = VirtualNodeHeight / 2.0f;
                            } else {
                                anchor.LeftAnchor = anchor.RightAnchor = VirtualNodeWidth * 4;
                                anchor.TopAnchor = anchor.BottomAnchor = VirtualNodeHeight / 2.0f;
                            }
                        }
                    }
                    //fix label vertices      

                    if (intEdge.Edge.Label!=null) {
                        int lj = intEdge.LayerEdges[intEdge.LayerEdges.Count / 2].Source;
                        Anchor a = anchors[lj];
                        double w = intEdge.LabelWidth, h = intEdge.LabelHeight;
                        a.RightAnchor = w;
                        a.LeftAnchor = LayoutSettings.NodeSeparation;

                        if (a.TopAnchor < h / 2.0)
                            a.TopAnchor = a.BottomAnchor = h / 2.0;

                        a.LabelToTheRightOfAnchorCenter = true;
                    }
                }
            }

        }
 /// <summary>
 /// 
 /// </summary>
 static internal void CalculateXCoordinates(LayerArrays layerArrays, ProperLayeredGraph layeredGraph, int nOfOriginalVs, Anchor[] anchors, double nodeSeparation) {
     XCoordsWithAlignment x = new XCoordsWithAlignment(layerArrays, layeredGraph, nOfOriginalVs, anchors, nodeSeparation);
     x.Calculate();
 }
 ///// <summary>
 ///// private constructor
 ///// </summary>
 ///// <param name="layerArrays"></param>
 ///// <param name="anchs"></param>
 ///// <param name="layeredGraph"></param>
 ///// <param name="nOfOriginalVs"></param>
 XCoordsWithAlignment(LayerArrays layerArrays, ProperLayeredGraph layeredGraph, 
     int nOfOriginalVs, Anchor[] anchorsP, double ns) {
     this.la = layerArrays;
     this.graph = layeredGraph;
     this.nOfOriginalVertices = nOfOriginalVs;
     this.nOfVertices = graph.NodeCount;
     this.h = la.Layers.Length;
     this.root = new int[nOfVertices];
     this.align = new int[nOfVertices];
     // this.sink = new int[nOfVertices];
     // this.shift = new double[nOfVertices];
     this.anchors = anchorsP;
     this.nodeSep = ns;
 }
        //void UpdateEdgeLabelPosition(LayerEdge[][] list, int i) {
        //    IntEdge e;
        //    int labelNodeIndex;
        //    if (Engine.GetLabelEdgeAndVirtualNode(list, i, out e, out labelNodeIndex)) {
        //        UpdateLabel(e, labelNodeIndex, db.Anchors);
        //    }
        //}

        internal static void UpdateLabel(Edge e, Anchor anchor){
            LineSegment labelSide = null;
            if (anchor.LabelToTheRightOfAnchorCenter){
                e.Label.Center = new Point(anchor.X + anchor.RightAnchor/2, anchor.Y);
                labelSide = new LineSegment(e.LabelBBox.LeftTop, e.LabelBBox.LeftBottom);
            }
            else if (anchor.LabelToTheLeftOfAnchorCenter){
                e.Label.Center = new Point(anchor.X - anchor.LeftAnchor/2, anchor.Y);
                labelSide = new LineSegment(e.LabelBBox.RightTop, e.LabelBBox.RightBottom);
            }
            ICurve segmentInFrontOfLabel = GetSegmentInFrontOfLabel(e.Curve, e.Label.Center.Y);
            if (segmentInFrontOfLabel == null)
                return;
            if (Curve.GetAllIntersections(e.Curve, Curve.PolyFromBox(e.LabelBBox), false).Count == 0){
                Point curveClosestPoint;
                Point labelSideClosest;
                if (FindClosestPoints(out curveClosestPoint, out labelSideClosest, segmentInFrontOfLabel, labelSide)){
                    //shift the label if needed
                    ShiftLabel(e, ref curveClosestPoint, ref labelSideClosest);
                }
                else{
                    //assume that the distance is reached at the ends of labelSideClosest
                    double u = segmentInFrontOfLabel.ClosestParameter(labelSide.Start);
                    double v = segmentInFrontOfLabel.ClosestParameter(labelSide.End);
                    if ((segmentInFrontOfLabel[u] - labelSide.Start).Length <
                        (segmentInFrontOfLabel[v] - labelSide.End).Length){
                        curveClosestPoint = segmentInFrontOfLabel[u];
                        labelSideClosest = labelSide.Start;
                    }
                    else{
                        curveClosestPoint = segmentInFrontOfLabel[v];
                        labelSideClosest = labelSide.End;
                    }
                    ShiftLabel(e, ref curveClosestPoint, ref labelSideClosest);
                }
            }
        }
Exemplo n.º 15
0
        static int DrawAnchor(Graphics g, int i, Anchor p){
            string stringToShow = i + (p.UserData != null ? (" " + p.UserData) : String.Empty);

            DrawStringInRectCenter(g, Brushes.Blue, new Font(FontFamily.GenericSerif, 10), stringToShow,
                                   new RectangleF((float) p.Left, (float) p.Bottom,
                                                  (float) p.RightAnchor + (float) p.LeftAnchor,
                                                  (float) p.TopAnchor + (float) p.BottomAnchor));
            i++;
            return i;
        }