Exemple #1
0
        /// <summary>
        /// Create and apply edge path using calculated ER parameters stored in edge
        /// </summary>
        /// <param name="useCurrentCoords">Use current vertices coordinates or final coorfinates (for.ex if move animation is active final coords will be its destination)</param>
        /// <param name="externalRoutingPoints">Provided custom routing points will be used instead of stored ones.</param>
        /// <param name="updateLabel">Should edge label be updated in this pass</param>
        public void PrepareEdgePath(bool useCurrentCoords = false, Point[] externalRoutingPoints = null, bool updateLabel = true)
        {
            //do not calculate invisible edges
            if ((Visibility != Visibility.Visible && !IsHiddenEdgesUpdated) && Source == null || Target == null || ManualDrawing)
            {
                return;
            }

            var template = Template;

            if (template != null)
            {
                #region Get the inputs
                //get the size of the source
                var sourceSize = new Size
                {
                    Width  = Source.ActualWidth,
                    Height = Source.ActualHeight
                };
                if (DesignerProperties.GetIsInDesignMode(this))
                {
                    sourceSize = new Size(80, 20);
                }

                //get the position center of the source
                var sourcePos = new Point
                {
                    X = (useCurrentCoords ? GraphAreaBase.GetX(Source) : GraphAreaBase.GetFinalX(Source)) + sourceSize.Width * .5,
                    Y = (useCurrentCoords ? GraphAreaBase.GetY(Source) : GraphAreaBase.GetFinalY(Source)) + sourceSize.Height * .5
                };

                //get the size of the target
                var targetSize = new Size
                {
                    Width  = Target.ActualWidth,
                    Height = Target.ActualHeight
                };
                if (DesignerProperties.GetIsInDesignMode(this))
                {
                    targetSize = new Size(80, 20);
                }

                //get the position center of the target
                var targetPos = new Point
                {
                    X = (useCurrentCoords ? GraphAreaBase.GetX(Target) : GraphAreaBase.GetFinalX(Target)) + targetSize.Width * .5,
                    Y = (useCurrentCoords ? GraphAreaBase.GetY(Target) : GraphAreaBase.GetFinalY(Target)) + targetSize.Height * .5
                };


                //get the route informations
                var routeInformation = externalRoutingPoints == null ? (Edge as IRoutingInfo).RoutingPoints : externalRoutingPoints;
                #endregion

                // Get the TopLeft position of the Source Vertex.
                var sourcePos1 = new Point
                {
                    X = (useCurrentCoords ? GraphAreaBase.GetX(Source) : GraphAreaBase.GetFinalX(Source)),
                    Y = (useCurrentCoords ? GraphAreaBase.GetY(Source) : GraphAreaBase.GetFinalY(Source))
                };
                // Get the TopLeft position of the Target Vertex.
                var targetPos1 = new Point
                {
                    X = (useCurrentCoords ? GraphAreaBase.GetX(Target) : GraphAreaBase.GetFinalX(Target)),
                    Y = (useCurrentCoords ? GraphAreaBase.GetY(Target) : GraphAreaBase.GetFinalY(Target))
                };

                //if self looped edge
                if (IsSelfLooped)
                {
                    if (!RootArea.EdgeShowSelfLooped)
                    {
                        return;
                    }
                    var          pt          = new Point(sourcePos1.X + RootArea.EdgeSelfLoopCircleOffset.X - RootArea.EdgeSelfLoopCircleRadius, sourcePos1.Y + RootArea.EdgeSelfLoopCircleOffset.X - RootArea.EdgeSelfLoopCircleRadius);
                    var          geo         = new EllipseGeometry(pt, RootArea.EdgeSelfLoopCircleRadius, RootArea.EdgeSelfLoopCircleRadius);
                    const double dArrowAngle = Math.PI / 2.0;
                    _arrowgeometry = new PathGeometry();
                    var aPoint = sourcePos1;
                    _arrowgeometry.Figures.Add(GeometryHelper.GenerateArrow(aPoint, new Point(), new Point(), dArrowAngle));
                    _linegeometry = geo;
                    GeometryHelper.TryFreeze(_arrowgeometry);
                    GeometryHelper.TryFreeze(_linegeometry);
                    return;
                }


                var hasRouteInfo = routeInformation != null && routeInformation.Length > 1;

                //calculate source and target edge attach points
                if (RootArea != null && !hasRouteInfo && RootArea.EnableParallelEdges)
                {
                    if (SourceOffset != 0)
                    {
                        sourcePos = GetParallelOffset(Source, Target, SourceOffset);
                    }
                    if (TargetOffset != 0)
                    {
                        targetPos = GetParallelOffset(Target, Source, TargetOffset);
                    }
                }

                /* Rectangular shapes implementation by bleibold */


                //Point p1 = GeometryHelper.GetEdgeEndpoint(sourcePos, new Rect(sourceSize), (hasRouteInfo ? routeInformation[1] : (targetPos)), Source.MathShape);
                //Point p2 = GeometryHelper.GetEdgeEndpoint(targetPos, new Rect(targetSize), hasRouteInfo ? routeInformation[routeInformation.Length - 2] : (sourcePos), Target.MathShape);

                var p1 = GeometryHelper.GetEdgeEndpoint(sourcePos, new Rect(sourcePos1, sourceSize), (hasRouteInfo ? routeInformation[1] : (targetPos)), Source.MathShape);
                var p2 = GeometryHelper.GetEdgeEndpoint(targetPos, new Rect(targetPos1, targetSize), hasRouteInfo ? routeInformation[routeInformation.Length - 2] : (sourcePos), Target.MathShape);

                _linegeometry  = new PathGeometry(); PathFigure lineFigure;
                _arrowgeometry = new PathGeometry(); PathFigure arrowFigure;

                //if we have route and route consist of 2 or more points
                if (RootArea != null && hasRouteInfo)
                {
                    //replace start and end points with accurate ones
                    var routePoints = routeInformation.ToList();
                    routePoints.Remove(routePoints.First());
                    routePoints.Remove(routePoints.Last());
                    routePoints.Insert(0, p1);
                    routePoints.Add(p2);

                    if (RootArea.EdgeCurvingEnabled)
                    {
                        var oPolyLineSegment = GeometryHelper.GetCurveThroughPoints(routePoints.ToArray(), 0.5, RootArea.EdgeCurvingTolerance);
                        lineFigure = GeometryHelper.GetPathFigureFromPathSegments(routePoints[0], true, true, oPolyLineSegment);
                        //get two last points of curved path to generate correct arrow
                        var cLast = oPolyLineSegment.Points.Last();
                        var cPrev = oPolyLineSegment.Points[oPolyLineSegment.Points.Count - 2];
                        arrowFigure = GeometryHelper.GenerateOldArrow(cPrev, cLast);
                        //freeze and create resulting geometry
                        GeometryHelper.TryFreeze(oPolyLineSegment);
                    }
                    else
                    {
                        lineFigure  = new PathFigure(p1, new PathSegment[] { new PolyLineSegment(routePoints, true) }, false);
                        arrowFigure = GeometryHelper.GenerateOldArrow(routePoints[routePoints.Count - 2], p2);
                    }
                }
                else // no route defined
                {
                    //!!! Here is the line calculation to not overlap an arrowhead
                    //Vector v = p1 - p2; v = v / v.Length * 5;
                    // Vector n = new Vector(-v.Y, v.X) * 0.7;
                    //segments[0] = new LineSegment(p2 + v, true);
                    lineFigure  = new PathFigure(p1, new PathSegment[] { new LineSegment(p2, true) }, false);
                    arrowFigure = GeometryHelper.GenerateOldArrow(p1, p2);
                }
                GeometryHelper.TryFreeze(lineFigure);
                (_linegeometry as PathGeometry).Figures.Add(lineFigure);
                if (arrowFigure != null)
                {
                    GeometryHelper.TryFreeze(arrowFigure);
                    _arrowgeometry.Figures.Add(arrowFigure);
                }
                GeometryHelper.TryFreeze(_linegeometry);
                GeometryHelper.TryFreeze(_arrowgeometry);

                if (ShowLabel && _edgeLabelControl != null && _updateLabelPosition && updateLabel)
                {
                    _edgeLabelControl.UpdatePosition();
                }
                //PathGeometry = (PathGeometry)_linegeometry;
            }
            else
            {
                Debug.WriteLine("PrepareEdgePath() -> Edge template not found! Can't apply path to display edge!");
            }
        }
Exemple #2
0
        /// <summary>
        /// Create and apply edge path using calculated ER parameters stored in edge
        /// </summary>
        /// <param name="useCurrentCoords">Use current vertices coordinates or final coordinates (for.ex if move animation is active final coords will be its destination)</param>
        /// <param name="externalRoutingPoints">Provided custom routing points will be used instead of stored ones.
        public void PrepareEdgePath(bool useCurrentCoords = false, Point[] externalRoutingPoints = null)
        {
            //do not calculate invisible edges
            if (Visibility != System.Windows.Visibility.Visible || Source == null || Target == null || ManualDrawing)
            {
                return;
            }

            var template = Template;

            if (template != null)
            {
                #region Get the inputs
                //get the position of the source
                var sourcePos = new Point()
                {
                    X = useCurrentCoords ? GraphAreaBase.GetX(Source) : GraphAreaBase.GetFinalX(Source),
                    Y = useCurrentCoords ? GraphAreaBase.GetY(Source) : GraphAreaBase.GetFinalY(Source)
                };
                //get the size of the source
                var sourceSize = new Size()
                {
                    Width  = Source.ActualWidth,
                    Height = Source.ActualHeight
                };
                //get the position of the target
                var targetPos = new Point()
                {
                    X = useCurrentCoords ? GraphAreaBase.GetX(Target) : GraphAreaBase.GetFinalX(Target),
                    Y = useCurrentCoords ? GraphAreaBase.GetY(Target) : GraphAreaBase.GetFinalY(Target)
                };
                //get the size of the target
                var targetSize = new Size()
                {
                    Width  = Target.ActualWidth,
                    Height = Target.ActualHeight
                };

                //get the route informations
                var routeInformation = externalRoutingPoints == null ? (Edge as IRoutingInfo).RoutingPoints : externalRoutingPoints;
                #endregion

                //if self looped edge
                if (IsSelfLooped)
                {
                    if (!RootArea.EdgeShowSelfLooped)
                    {
                        return;
                    }
                    var pt  = new Point(sourcePos.X - sourceSize.Width / 2 + RootArea.EdgeSelfLoopCircleOffset.X - RootArea.EdgeSelfLoopCircleRadius, sourcePos.Y - sourceSize.Height / 2 + RootArea.EdgeSelfLoopCircleOffset.X - RootArea.EdgeSelfLoopCircleRadius);
                    var geo = new EllipseGeometry(pt,
                                                  RootArea.EdgeSelfLoopCircleRadius, RootArea.EdgeSelfLoopCircleRadius);
                    var dArrowAngle = Math.PI / 2.0;
                    _arrowgeometry = new PathGeometry(); _arrowgeometry.Figures.Add(GeometryHelper.GenerateArrow(new Point(sourcePos.X - sourceSize.Width / 2, sourcePos.Y - sourceSize.Height / 2), new Point(), new Point(), dArrowAngle));

                    _linegeometry = geo;
                    return;
                }


                bool hasRouteInfo = routeInformation != null && routeInformation.Length > 1;

                //calculate source and target edge attach points
                if (!hasRouteInfo && RootArea.EnableParallelEdges)
                {
                    if (SourceOffset != 0)
                    {
                        sourcePos = GetOffset(Source, Target, SourceOffset);
                    }
                    if (TargetOffset != 0)
                    {
                        targetPos = GetOffset(Target, Source, TargetOffset);
                    }
                }
                Point p1 = GeometryHelper.GetEdgeEndpoint(sourcePos, new Rect(sourceSize), (hasRouteInfo ? routeInformation[1] : (targetPos)), Source.MathShape);
                Point p2 = GeometryHelper.GetEdgeEndpoint(targetPos, new Rect(targetSize), hasRouteInfo ? routeInformation[routeInformation.Length - 2] : (sourcePos), Target.MathShape);

                _linegeometry  = new PathGeometry(); PathFigure lineFigure = null;
                _arrowgeometry = new PathGeometry(); PathFigure arrowFigure = null;

                //if we have route and route consist of 2 or more points
                if (hasRouteInfo)
                {
                    //replace start and end points with accurate ones
                    var routePoints = routeInformation.ToList();
                    routePoints.Remove(routePoints.First());
                    routePoints.Remove(routePoints.Last());
                    routePoints.Insert(0, p1);
                    routePoints.Add(p2);

                    if (RootArea.EdgeCurvingEnabled)
                    {
                        var oPolyLineSegment = GeometryHelper.GetCurveThroughPoints(routePoints.ToArray(), 0.5, RootArea.EdgeCurvingTolerance);
                        lineFigure = GeometryHelper.GetPathFigureFromPathSegments(routePoints[0], true, true, oPolyLineSegment);
                        //get two last points of curved path to generate correct arrow
                        var c_last = oPolyLineSegment.Points.Last();
                        var c_prev = oPolyLineSegment.Points[oPolyLineSegment.Points.Count - 2];
                        arrowFigure = GeometryHelper.GenerateOldArrow(c_prev, c_last);
                        //freeze and create resulting geometry
                        GeometryHelper.TryFreeze(oPolyLineSegment);
                    }
                    else
                    {
                        lineFigure = new PathFigure(p1, new PathSegment[1] {
                            new PolyLineSegment(routePoints, true)
                        }, false);
                        arrowFigure = GeometryHelper.GenerateOldArrow(routePoints[routePoints.Count - 2], p2);
                    }
                }
                else // no route defined
                {
                    //!!! Here is the line calculation to not overlap an arrowhead
                    //Vector v = p1 - p2; v = v / v.Length * 5;
                    // Vector n = new Vector(-v.Y, v.X) * 0.7;
                    //segments[0] = new LineSegment(p2 + v, true);
                    lineFigure = new PathFigure(p1, new PathSegment[1] {
                        new LineSegment(p2, true)
                    }, false);
                    arrowFigure = GeometryHelper.GenerateOldArrow(p1, p2);
                }
                GeometryHelper.TryFreeze(lineFigure);
                (_linegeometry as PathGeometry).Figures.Add(lineFigure);
                if (arrowFigure != null)
                {
                    GeometryHelper.TryFreeze(arrowFigure);
                    _arrowgeometry.Figures.Add(arrowFigure);
                }
                GeometryHelper.TryFreeze(_linegeometry);
                GeometryHelper.TryFreeze(_arrowgeometry);
            }
            else
            {
                Debug.WriteLine("PrepareEdgePath() -> Edge template not found! Can't apply path to display edge!");
            }
        }