Example #1
0
        //*************************************************************************
        //  Method: TryDrawVertex()
        //
        /// <summary>
        /// Draws a vertex after moving it if necessary.
        /// </summary>
        ///
        /// <param name="vertex">
        /// The vertex to draw.
        /// </param>
        ///
        /// <param name="graphDrawingContext">
        /// Provides access to objects needed for graph-drawing operations.
        /// </param>
        ///
        /// <param name="vertexDrawingHistory">
        /// Where a <see cref="VertexDrawingHistory" /> object that retains
        /// information about how the vertex was drawn gets stored if true is
        /// returned.
        /// </param>
        ///
        /// <returns>
        /// true if the vertex was drawn, false if the vertex is hidden.
        /// </returns>
        ///
        /// <remarks>
        /// This method should be called repeatedly while a graph is being drawn,
        /// once for each of the graph's vertices.  The <see
        /// cref="IVertex.Location" /> property on all of the graph's vertices must
        /// be set by ILayout.LayOutGraph before this method is called.
        ///
        /// <para>
        /// If the vertex falls outside the graph rectangle, it gets moved before
        /// being drawn.
        /// </para>
        ///
        /// </remarks>
        //*************************************************************************
        public Boolean TryDrawVertex(
            IVertex vertex,
            GraphDrawingContext graphDrawingContext,
            out VertexDrawingHistory vertexDrawingHistory
            )
        {
            AssertValid();

            vertexDrawingHistory = null;

            CheckDrawVertexArguments(vertex, graphDrawingContext);

            // If the vertex is hidden, do nothing.

            VisibilityKeyValue eVisibility = GetVisibility(vertex);

            if (eVisibility == VisibilityKeyValue.Hidden)
            {
            return (false);
            }

            // Check for a per-vertex label.

            Object oLabelAsObject;
            String sLabel = null;

            if ( vertex.TryGetValue(ReservedMetadataKeys.PerVertexLabel,
            typeof(String), out oLabelAsObject) )
            {
            sLabel = (String)oLabelAsObject;

            if ( String.IsNullOrEmpty(sLabel) )
            {
                sLabel = null;
            }
            else
            {
                sLabel = TruncateLabel(sLabel);
            }
            }

            Boolean bDrawAsSelected = GetDrawAsSelected(vertex);
            Point oLocation = WpfGraphicsUtil.PointFToWpfPoint(vertex.Location);
            DrawingVisual oDrawingVisual = new DrawingVisual();
            VertexShape eShape = GetShape(vertex);

            VertexLabelDrawer oVertexLabelDrawer =
            new VertexLabelDrawer(m_eLabelPosition);

            using ( DrawingContext oDrawingContext = oDrawingVisual.RenderOpen() )
            {
            if (eShape == VertexShape.Label)
            {
                if (sLabel != null)
                {
                    // Draw the vertex as a label.

                    vertexDrawingHistory = DrawLabelShape(vertex,
                        graphDrawingContext, oDrawingContext, oDrawingVisual,
                        eVisibility, bDrawAsSelected, sLabel);

                    return (true);
                }

                // Default to something usable.

                eShape = VertexShape.Disk;
            }
            else if (eShape == VertexShape.Image)
            {
                Object oImageSourceAsObject;

                if (vertex.TryGetValue(ReservedMetadataKeys.PerVertexImage,
                    typeof(ImageSource), out oImageSourceAsObject)
                    )
                {
                    // Draw the vertex as an image.

                    vertexDrawingHistory = DrawImageShape(vertex,
                        graphDrawingContext, oDrawingContext, oDrawingVisual,
                        eVisibility, bDrawAsSelected, sLabel,
                        (ImageSource)oImageSourceAsObject, oVertexLabelDrawer);

                    return (true);
                }

                // Default to something usable.

                eShape = VertexShape.Disk;
            }

            // Draw the vertex as a simple shape.

            vertexDrawingHistory = DrawSimpleShape(vertex, eShape,
                graphDrawingContext, oDrawingContext, oDrawingVisual,
                eVisibility, bDrawAsSelected, sLabel, oVertexLabelDrawer);
            }

            return (true);
        }
Example #2
0
        //*************************************************************************
        //  Method: DrawPlusSign()
        //
        /// <summary>
        /// Draws a plus sign on top of the vertex.
        /// </summary>
        ///
        /// <param name="eShape">
        /// The simple vertex shape.
        /// </param>
        ///
        /// <param name="oGraphDrawingContext">
        /// Provides access to objects needed for graph-drawing operations.
        /// </param>
        ///
        /// <param name="oVertexLocation">
        /// The location of the vertex.
        /// </param>
        ///
        /// <param name="oDrawingContext">
        /// The DrawingContext to use.
        /// </param>
        ///
        /// <param name="oVertexColor">
        /// The color of the vertex.
        /// </param>
        ///
        /// <param name="oVertexLabelDrawer">
        /// Object that draws a vertex label as an annotation.
        /// </param>
        ///
        /// <param name="oVertexDrawingHistory">
        /// A <see cref="VertexDrawingHistory" /> object that retains information
        /// about how the vertex was drawn.
        /// </param>
        ///
        /// <param name="oVertexBounds">
        /// The rectangle defining the bounds of the vertex.
        /// </param>
        //*************************************************************************
        protected void DrawPlusSign(
            VertexShape eShape,
            Point oVertexLocation,
            Rect oVertexBounds,
            Color oVertexColor,
            GraphDrawingContext oGraphDrawingContext,
            DrawingContext oDrawingContext,
            VertexLabelDrawer oVertexLabelDrawer,
            VertexDrawingHistory oVertexDrawingHistory
            )
        {
            Debug.Assert(oGraphDrawingContext != null);
            Debug.Assert(oDrawingContext != null);
            Debug.Assert(oVertexLabelDrawer != null);
            Debug.Assert(oVertexDrawingHistory != null);
            AssertValid();

            Color oFillColor;

            switch (eShape)
            {
            case VertexShape.Circle:
            case VertexShape.Square:
            case VertexShape.Diamond:
            case VertexShape.Triangle:

                // The fill color is the color of the background.  Adjust the
                // fill color for the opacity of the vertex.

                oFillColor = WpfGraphicsUtil.SetWpfColorAlpha(
                    oGraphDrawingContext.BackColor, oVertexColor.A);

                break;

            default:

                oFillColor = oVertexColor;
                break;
            }

            Color oContrastingColor =
            WpfGraphicsUtil.GetContrastingColor(oFillColor);

            // The font size used below was chosen so that it is large enough to be
            // easily readable, but small enough to fit within the smallest
            // collapsed group vertex created by the NodeXLControl.

            oVertexLabelDrawer.DrawLabel( oDrawingContext, oGraphDrawingContext,
            oVertexDrawingHistory, oVertexBounds,
            VertexLabelPosition.MiddleCenter,
            CreateFormattedText("+", oContrastingColor, 15.0) );
        }
        //*************************************************************************
        //  Method: GetEdgeEndpoint()
        //
        /// <summary>
        /// Gets the endpoint of an edge that is connected to <see
        /// cref="Vertex" />.
        /// </summary>
        ///
        /// <param name="otherVertexDrawingHistory">
        /// The <paramref name="VertexDrawingHistory" /> object that retains
        /// information about how the edge's other vertex was drawn.
        /// </param>
        ///
        /// <param name="edgeEndpoint">
        /// Where the edge endpoint gets stored.  The endpoint is somewhere on <see
        /// cref="Vertex" />.
        /// </param>
        //*************************************************************************
        public override void GetEdgeEndpoint(
            VertexDrawingHistory otherVertexDrawingHistory,
            out Point edgeEndpoint
            )
        {
            AssertValid();

            GetEdgeEndpointOnRectangle(this.VertexLocation, this.Rectangle,
            otherVertexDrawingHistory.VertexLocation, out edgeEndpoint);
        }
        //*************************************************************************
        //  Method: GetEdgeEndpoint()
        //
        /// <summary>
        /// Gets the endpoint of an edge that is connected to <see
        /// cref="Vertex" />.
        /// </summary>
        ///
        /// <param name="otherVertexDrawingHistory">
        /// The <paramref name="VertexDrawingHistory" /> object that retains
        /// information about how the edge's other vertex was drawn.
        /// </param>
        ///
        /// <param name="edgeEndpoint">
        /// Where the edge endpoint gets stored.  The endpoint is somewhere on <see
        /// cref="Vertex" />.
        /// </param>
        //*************************************************************************
        public override void GetEdgeEndpoint(
            VertexDrawingHistory otherVertexDrawingHistory,
            out Point edgeEndpoint
            )
        {
            AssertValid();

            Point oVertexLocation = this.VertexLocation;
            Point oOtherVertexLocation = otherVertexDrawingHistory.VertexLocation;

            // Instead of doing geometry calculations similar to what is done in
            // VertexDrawingHistory.GetEdgePointOnRectangle(), make use of that
            // method by making the triangle look like a rectangle.  First, figure
            // out how to rotate the triangle about the vertex location so that the
            // side containing the endpoint is vertical and to the right of the
            // vertex location.

            Double dEdgeAngle = WpfGraphicsUtil.GetAngleBetweenPoints(
            oVertexLocation, oOtherVertexLocation);

            Double dEdgeAngleDegrees = MathUtil.RadiansToDegrees(dEdgeAngle);

            Double dAngleToRotateDegrees;

            if (dEdgeAngleDegrees >= -30.0 && dEdgeAngleDegrees < 90.0)
            {
            dAngleToRotateDegrees = 30.0;
            }
            else if (dEdgeAngleDegrees >= -150.0 && dEdgeAngleDegrees < -30.0)
            {
            dAngleToRotateDegrees = 270.0;
            }
            else
            {
            dAngleToRotateDegrees = 150.0;
            }

            // Now create a rotated rectangle that is centered on the vertex
            // location and that has the vertical, endpoint-containing triangle
            // side as the rectangle's right edge.

            Double dWidth = 2.0 * m_dHalfWidth;

            Rect oRotatedRectangle = new Rect(
            oVertexLocation.X,
            oVertexLocation.Y - m_dHalfWidth,
            dWidth * WpfGraphicsUtil.Tangent30Degrees,
            dWidth
            );

            Matrix oMatrix = WpfGraphicsUtil.GetRotatedMatrix(oVertexLocation,
            dAngleToRotateDegrees);

            // Rotate the other vertex location.

            Point oRotatedOtherVertexLocation =
            oMatrix.Transform(oOtherVertexLocation);

            // GetEdgeEndpointOnRectangle will compute an endpoint on the
            // rectangle's right edge.

            Point oRotatedEdgeEndpoint;

            GetEdgeEndpointOnRectangle(oVertexLocation, oRotatedRectangle,
            oRotatedOtherVertexLocation, out oRotatedEdgeEndpoint);

            // Now rotate the edge endpoint in the other direction.

            oMatrix = WpfGraphicsUtil.GetRotatedMatrix(oVertexLocation,
            -dAngleToRotateDegrees);

            edgeEndpoint = oMatrix.Transform(oRotatedEdgeEndpoint);
        }
Example #5
0
        //*************************************************************************
        //  Method: DrawLabel()
        //
        /// <summary>
        /// Draws a vertex label as an annotation at a specified position.
        /// </summary>
        ///
        /// <param name="drawingContext">
        /// The DrawingContext to use.
        /// </param>
        ///
        /// <param name="graphDrawingContext">
        /// Provides access to objects needed for graph-drawing operations.
        /// </param>
        ///
        /// <param name="vertexDrawingHistory">
        /// Describes how the vertex was drawn.
        /// </param>
        ///
        /// <param name="vertexBounds">
        /// The vertex's bounding rectangle.
        /// </param>
        ///
        /// <param name="labelPosition">
        /// The label's position.
        /// </param>
        ///
        /// <param name="formattedText">
        /// The FormattedText object to use.  Several properties get changed by
        /// this method.
        /// </param>
        //*************************************************************************
        public void DrawLabel(
            DrawingContext drawingContext,
            GraphDrawingContext graphDrawingContext,
            VertexDrawingHistory vertexDrawingHistory,
            Rect vertexBounds,
            VertexLabelPosition labelPosition,
            FormattedText formattedText
            )
        {
            Debug.Assert(drawingContext != null);
            Debug.Assert(graphDrawingContext != null);
            Debug.Assert(vertexDrawingHistory != null);
            Debug.Assert(formattedText != null);
            AssertValid();

            Double dHalfVertexBoundsWidth = vertexBounds.Width / 2.0;
            Double dHalfVertexBoundsHeight = vertexBounds.Height / 2.0;
            Double dLabelHeight = formattedText.Height;
            Double dHalfLabelHeight = dLabelHeight / 2.0;
            Double dLabelWidth = formattedText.Width;
            Double dHalfLabelWidth = dLabelWidth / 2.0;
            TextAlignment eTextAlignment = TextAlignment.Left;

            formattedText.MaxLineCount = 1;

            // This is the point where the label will be drawn.  It initially
            // assumes a text height of zero with no margin, but that will be
            // adjusted within the switch statement below.

            Point oDraw = vertexDrawingHistory.GetLabelLocation(labelPosition);
            Double dDrawX = oDraw.X;
            Double dDrawY = oDraw.Y;

            // These are the bounds of the label text.

            Double dLabelBoundsLeft = 0;
            Double dLabelBoundsRight = 0;

            switch (labelPosition)
            {
            case VertexLabelPosition.TopLeft:

                eTextAlignment = TextAlignment.Right;

                dDrawY -= (dLabelHeight + VerticalMargin);
                dLabelBoundsLeft = dDrawX - dLabelWidth;
                dLabelBoundsRight = dDrawX;

                break;

            case VertexLabelPosition.TopCenter:

                eTextAlignment = TextAlignment.Center;

                dDrawY -= (dLabelHeight + VerticalMargin);
                dLabelBoundsLeft = dDrawX - dHalfLabelWidth;
                dLabelBoundsRight = dDrawX + dHalfLabelWidth;

                break;

            case VertexLabelPosition.TopRight:

                // eTextAlignment = TextAlignment.Left;

                dDrawY -= (dLabelHeight + VerticalMargin);
                dLabelBoundsLeft = dDrawX;
                dLabelBoundsRight = dDrawX + dLabelWidth;

                break;

            case VertexLabelPosition.MiddleLeft:

                eTextAlignment = TextAlignment.Right;

                dDrawX -= HorizontalMargin;
                dDrawY -= dHalfLabelHeight;
                dLabelBoundsLeft = dDrawX - dLabelWidth;
                dLabelBoundsRight = dDrawX;

                break;

            case VertexLabelPosition.MiddleCenter:

                eTextAlignment = TextAlignment.Center;

                dDrawY -= dHalfLabelHeight;
                dLabelBoundsLeft = dDrawX - dHalfLabelWidth;
                dLabelBoundsRight = dDrawX + dHalfLabelWidth;

                break;

            case VertexLabelPosition.MiddleRight:

                // eTextAlignment = TextAlignment.Left;

                dDrawX += HorizontalMargin;
                dDrawY -= dHalfLabelHeight;
                dLabelBoundsLeft = dDrawX;
                dLabelBoundsRight = dDrawX + dLabelWidth;

                break;

            case VertexLabelPosition.BottomLeft:

                eTextAlignment = TextAlignment.Right;

                dDrawY += VerticalMargin;
                dLabelBoundsLeft = dDrawX - dLabelWidth;
                dLabelBoundsRight = dDrawX;

                break;

            case VertexLabelPosition.BottomCenter:

                eTextAlignment = TextAlignment.Center;

                dDrawY += VerticalMargin;
                dLabelBoundsLeft = dDrawX - dHalfLabelWidth;
                dLabelBoundsRight = dDrawX + dHalfLabelWidth;

                break;

            case VertexLabelPosition.BottomRight:

                // eTextAlignment = TextAlignment.Left;

                dDrawY += VerticalMargin;
                dLabelBoundsLeft = dDrawX;
                dLabelBoundsRight = dDrawX + dLabelWidth;

                break;

            default:

                Debug.Assert(false);
                break;
            }

            // Don't let the text exceed the bounds of the graph rectangle.

            Double dLabelBoundsTop = dDrawY;
            Double dLabelBoundsBottom = dDrawY + dLabelHeight;

            Rect oGraphRectangleMinusMargin =
            graphDrawingContext.GraphRectangleMinusMargin;

            dDrawX += Math.Max(0,
            oGraphRectangleMinusMargin.Left - dLabelBoundsLeft);

            dDrawX -= Math.Max(0,
            dLabelBoundsRight - oGraphRectangleMinusMargin.Right);

            dDrawY += Math.Max(0,
            oGraphRectangleMinusMargin.Top - dLabelBoundsTop);

            dDrawY -= Math.Max(0,
            dLabelBoundsBottom - oGraphRectangleMinusMargin.Bottom);

            formattedText.TextAlignment = eTextAlignment;

            drawingContext.DrawText( formattedText, new Point(dDrawX, dDrawY) );
        }
Example #6
0
        //*************************************************************************
        //  Method: DrawLabel()
        //
        /// <summary>
        /// Draws a vertex label as an annotation.
        /// </summary>
        ///
        /// <summary>
        /// Draws a vertex label as an annotation at a position determined by the
        /// vertex's metadata.
        /// </summary>
        ///
        /// <param name="drawingContext">
        /// The DrawingContext to use.
        /// </param>
        ///
        /// <param name="graphDrawingContext">
        /// Provides access to objects needed for graph-drawing operations.
        /// </param>
        ///
        /// <param name="vertexDrawingHistory">
        /// Describes how the vertex was drawn.
        /// </param>
        ///
        /// <param name="vertexBounds">
        /// The vertex's bounding rectangle.
        /// </param>
        ///
        /// <param name="formattedText">
        /// The FormattedText object to use.  Several properties get changed by
        /// this method.
        /// </param>
        //*************************************************************************
        public void DrawLabel(
            DrawingContext drawingContext,
            GraphDrawingContext graphDrawingContext,
            VertexDrawingHistory vertexDrawingHistory,
            Rect vertexBounds,
            FormattedText formattedText
            )
        {
            Debug.Assert(drawingContext != null);
            Debug.Assert(graphDrawingContext != null);
            Debug.Assert(vertexDrawingHistory != null);
            Debug.Assert(formattedText != null);
            AssertValid();

            DrawLabel(drawingContext, graphDrawingContext, vertexDrawingHistory,
            vertexBounds, GetLabelPosition(vertexDrawingHistory.Vertex),
            formattedText);
        }