Example #1
0
        GetLabelPosition
        (
            IVertex oVertex
        )
        {
            Debug.Assert(oVertex != null);
            AssertValid();

            // Start with the default position.

            VertexLabelPosition eLabelPosition = m_eLabelPosition;

            // Check for a per-vertex label position.

            Object oPerVertexLabelPositionAsObject;

            if (oVertex.TryGetValue(ReservedMetadataKeys.PerVertexLabelPosition,
                                    typeof(VertexLabelPosition), out oPerVertexLabelPositionAsObject))
            {
                eLabelPosition =
                    (VertexLabelPosition)oPerVertexLabelPositionAsObject;
            }

            return(eLabelPosition);
        }
Example #2
0
        GetLabelLocation
        (
            VertexLabelPosition labelPosition
        )
        {
            AssertValid();

            Rect oVertexBounds =
                WpfGraphicsUtil.TriangleBoundsFromCenterAndHalfWidth(
                    this.VertexLocation, m_dHalfWidth);

            Double dCenterX = oVertexBounds.Left + oVertexBounds.Width / 2.0;

            // These were determined experimentally to avoid trigonometry method
            // calls and to make the labels look good.

            Double dCenterY = oVertexBounds.Top +
                              1.2 * (oVertexBounds.Height / 2.0);

            Double dOffsetX = m_dHalfWidth * 1.0;

            switch (labelPosition)
            {
            case VertexLabelPosition.TopLeft:
            case VertexLabelPosition.TopCenter:
            case VertexLabelPosition.TopRight:

                return(new Point(dCenterX, oVertexBounds.Top));

            case VertexLabelPosition.MiddleLeft:

                return(new Point(dCenterX - dOffsetX, dCenterY));

            case VertexLabelPosition.MiddleCenter:

                return(new Point(dCenterX, dCenterY));

            case VertexLabelPosition.MiddleRight:

                return(new Point(dCenterX + dOffsetX, dCenterY));

            case VertexLabelPosition.BottomLeft:

                return(oVertexBounds.BottomLeft);

            case VertexLabelPosition.BottomCenter:

                return(new Point(dCenterX, oVertexBounds.Bottom));

            case VertexLabelPosition.BottomRight:

                return(oVertexBounds.BottomRight);

            default:

                Debug.Assert(false);
                return(this.VertexLocation);
            }
        }
Example #3
0
        //*************************************************************************
        //  Constructor: VertexLabelDrawer()
        //
        /// <summary>
        /// Initializes a new instance of the <see cref="VertexLabelDrawer" />
        /// class.
        /// </summary>
        ///
        /// <param name="labelPosition">
        /// The default position to use for vertex labels.
        /// </param>
        //*************************************************************************
        public VertexLabelDrawer(
            VertexLabelPosition labelPosition
            )
        {
            m_eLabelPosition = labelPosition;

            AssertValid();
        }
Example #4
0
        GetLabelLocation
        (
            VertexLabelPosition labelPosition
        )
        {
            AssertValid();

            return(GetLabelLocationOnDiamond(labelPosition, m_dHalfWidth));
        }
Example #5
0
        //*************************************************************************
        //  Constructor: VertexLabelDrawer()
        //
        /// <summary>
        /// Initializes a new instance of the <see cref="VertexLabelDrawer" />
        /// class.
        /// </summary>
        ///
        /// <param name="labelPosition">
        /// The default position to use for vertex labels.
        /// </param>
        //*************************************************************************

        public VertexLabelDrawer
        (
            VertexLabelPosition labelPosition
        )
        {
            m_eLabelPosition = labelPosition;

            AssertValid();
        }
        GetLabelLocation
        (
            VertexLabelPosition labelPosition
        )
        {
            AssertValid();

            // The diamond pattern for label locations is appropriate for circles.

            return(GetLabelLocationOnDiamond(labelPosition, m_dRadius));
        }
Example #7
0
        GetLabelLocation
        (
            VertexLabelPosition labelPosition
        )
        {
            AssertValid();

            Double dCenterX = m_oRectangle.Left + m_oRectangle.Width / 2.0;
            Double dMiddleY = m_oRectangle.Top + m_oRectangle.Height / 2.0;

            switch (labelPosition)
            {
            case VertexLabelPosition.TopLeft:

                return(m_oRectangle.TopLeft);

            case VertexLabelPosition.TopCenter:

                return(new Point(dCenterX, m_oRectangle.Top));

            case VertexLabelPosition.TopRight:

                return(m_oRectangle.TopRight);

            case VertexLabelPosition.MiddleLeft:

                return(new Point(m_oRectangle.Left, dMiddleY));

            case VertexLabelPosition.MiddleCenter:

                return(new Point(dCenterX, dMiddleY));

            case VertexLabelPosition.MiddleRight:

                return(new Point(m_oRectangle.Right, dMiddleY));

            case VertexLabelPosition.BottomLeft:

                return(m_oRectangle.BottomLeft);

            case VertexLabelPosition.BottomCenter:

                return(new Point(dCenterX, m_oRectangle.Bottom));

            case VertexLabelPosition.BottomRight:

                return(m_oRectangle.BottomRight);

            default:

                Debug.Assert(false);
                return(new Point());
            }
        }
Example #8
0
        //*************************************************************************
        //  Constructor: VertexLabelDrawer()
        //
        /// <summary>
        /// Initializes a new instance of the <see cref="VertexLabelDrawer" />
        /// class.
        /// </summary>
        ///
        /// <param name="labelPosition">
        /// The default position to use for vertex labels.
        /// </param>
        ///
        /// <param name="backgroundAlpha">
        /// The alpha of the label's background rectangle, as a Byte.
        /// </param>
        //*************************************************************************

        public VertexLabelDrawer
        (
            VertexLabelPosition labelPosition,
            Byte backgroundAlpha
        )
        {
            m_eLabelPosition    = labelPosition;
            m_btBackgroundAlpha = backgroundAlpha;

            AssertValid();
        }
    //*************************************************************************
    //  Constructor: VertexLabelDrawer()
    //
    /// <summary>
    /// Initializes a new instance of the <see cref="VertexLabelDrawer" />
    /// class.
    /// </summary>
    ///
    /// <param name="labelPosition">
    /// The default position to use for vertex labels.
    /// </param>
    ///
    /// <param name="backgroundAlpha">
    /// The alpha of the label's background rectangle, as a Byte.
    /// </param>
    //*************************************************************************

    public VertexLabelDrawer
    (
        VertexLabelPosition labelPosition,
        Byte backgroundAlpha
    )
    {
        m_eLabelPosition = labelPosition;
        m_btBackgroundAlpha = backgroundAlpha;

        AssertValid();
    }
        GetLabelLocationOnDiamond
        (
            VertexLabelPosition eLabelPosition,
            Double dHalfWidth
        )
        {
            Debug.Assert(dHalfWidth >= 0);
            AssertValid();

            Point  oVertexLocation = this.VertexLocation;
            Double dVertexX        = oVertexLocation.X;
            Double dVertexY        = oVertexLocation.Y;

            switch (eLabelPosition)
            {
            case VertexLabelPosition.TopLeft:
            case VertexLabelPosition.TopCenter:
            case VertexLabelPosition.TopRight:

                return(new Point(dVertexX, dVertexY - dHalfWidth));

            case VertexLabelPosition.MiddleLeft:

                return(new Point(dVertexX - dHalfWidth, dVertexY));

            case VertexLabelPosition.MiddleCenter:

                return(oVertexLocation);

            case VertexLabelPosition.MiddleRight:

                return(new Point(dVertexX + dHalfWidth, dVertexY));

            case VertexLabelPosition.BottomLeft:
            case VertexLabelPosition.BottomCenter:
            case VertexLabelPosition.BottomRight:

                return(new Point(dVertexX, dVertexY + dHalfWidth));

            default:

                Debug.Assert(false);
                return(oVertexLocation);
            }
        }
Example #11
0
        SetTextAlignment
        (
            FormattedText oFormattedText,
            VertexLabelPosition eLabelPosition
        )
        {
            Debug.Assert(oFormattedText != null);
            Debug.Assert(eLabelPosition != VertexLabelPosition.Nowhere);
            AssertValid();

            TextAlignment eTextAlignment = TextAlignment.Left;

            switch (eLabelPosition)
            {
            case VertexLabelPosition.TopLeft:
            case VertexLabelPosition.MiddleLeft:
            case VertexLabelPosition.BottomLeft:

                eTextAlignment = TextAlignment.Right;
                break;

            case VertexLabelPosition.TopCenter:
            case VertexLabelPosition.MiddleCenter:
            case VertexLabelPosition.BottomCenter:

                eTextAlignment = TextAlignment.Center;
                break;

            case VertexLabelPosition.TopRight:
            case VertexLabelPosition.MiddleRight:
            case VertexLabelPosition.BottomRight:

                // eTextAlignment = TextAlignment.Left;
                break;

            case VertexLabelPosition.Nowhere:
            default:

                Debug.Assert(false);
                break;
            }

            oFormattedText.TextAlignment = eTextAlignment;
        }
Example #12
0
        //*************************************************************************
        //  Constructor: VertexDrawer()
        //
        /// <summary>
        /// Initializes a new instance of the <see cref="VertexDrawer" /> class.
        /// </summary>
        //*************************************************************************
        public VertexDrawer()
        {
            m_eShape = VertexShape.Disk;
            m_dRadius = 3.0;
            m_oLabelFillColor = SystemColors.WindowColor;
            m_eLabelPosition = VertexLabelPosition.TopRight;
            m_bLimitVerticesToBounds = true;

            AssertValid();
        }
Example #13
0
        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));
        }
    GetLabelLocationOnDiamond
    (
        VertexLabelPosition eLabelPosition,
        Double dHalfWidth
    )
    {
        Debug.Assert(dHalfWidth >= 0);
        AssertValid();

        Point oVertexLocation = this.VertexLocation;
        Double dVertexX = oVertexLocation.X;
        Double dVertexY = oVertexLocation.Y;

        switch (eLabelPosition)
        {
            case VertexLabelPosition.TopLeft:
            case VertexLabelPosition.TopCenter:
            case VertexLabelPosition.TopRight:

                return ( new Point(dVertexX, dVertexY - dHalfWidth) );

            case VertexLabelPosition.MiddleLeft:

                return ( new Point(dVertexX - dHalfWidth, dVertexY) );

            case VertexLabelPosition.MiddleCenter:

                return (oVertexLocation);

            case VertexLabelPosition.MiddleRight:

                return ( new Point(dVertexX + dHalfWidth, dVertexY) );

            case VertexLabelPosition.BottomLeft:
            case VertexLabelPosition.BottomCenter:
            case VertexLabelPosition.BottomRight:

                return ( new Point(dVertexX, dVertexY + dHalfWidth) );

            default:

                Debug.Assert(false);
                return (oVertexLocation);
        }
    }
 GetLabelLocation
 (
     VertexLabelPosition labelPosition
 );
    SetTextAlignment
    (
        FormattedText oFormattedText,
        VertexLabelPosition eLabelPosition
    )
    {
        Debug.Assert(oFormattedText != null);
        Debug.Assert(eLabelPosition != VertexLabelPosition.Nowhere);
        AssertValid();

        TextAlignment eTextAlignment = TextAlignment.Left;

        switch (eLabelPosition)
        {
            case VertexLabelPosition.TopLeft:
            case VertexLabelPosition.MiddleLeft:
            case VertexLabelPosition.BottomLeft:

                // eTextAlignment = TextAlignment.Left;
                break;

            case VertexLabelPosition.TopCenter:
            case VertexLabelPosition.MiddleCenter:
            case VertexLabelPosition.BottomCenter:

                eTextAlignment = TextAlignment.Center;
                break;

            case VertexLabelPosition.TopRight:
            case VertexLabelPosition.MiddleRight:
            case VertexLabelPosition.BottomRight:

                eTextAlignment = TextAlignment.Right;
                break;

            default:

                Debug.Assert(false);
                break;
        }

        oFormattedText.TextAlignment = eTextAlignment;
    }
        //*************************************************************************
        //  Method: GetLabelLocation()
        //
        /// <summary>
        /// Gets the location at which an annotation label should be drawn.
        /// </summary>
        ///
        /// <param name="labelPosition">
        /// The position of the annotation label.
        /// </param>
        ///
        /// <returns>
        /// The point at which an annotation label should be drawn.
        /// </returns>
        ///
        /// <remarks>
        /// The returned point assumes that the label text height is zero and that
        /// there is zero margin between the vertex and the label.  The caller must
        /// adjust the point for the actual text height and any margin.
        /// </remarks>
        //*************************************************************************
        public override Point GetLabelLocation(
            VertexLabelPosition labelPosition
            )
        {
            AssertValid();

            Rect oVertexBounds =
            WpfGraphicsUtil.TriangleBoundsFromCenterAndHalfWidth(
                this.VertexLocation, m_dHalfWidth);

            Double dCenterX = oVertexBounds.Left + oVertexBounds.Width / 2.0;

            // These were determined experimentally to avoid trigonometry method
            // calls and to make the labels look good.

            Double dCenterY = oVertexBounds.Top +
            1.2 * (oVertexBounds.Height / 2.0);

            Double dOffsetX = m_dHalfWidth * 0.7;

            switch (labelPosition)
            {
            case VertexLabelPosition.TopLeft:
            case VertexLabelPosition.TopCenter:
            case VertexLabelPosition.TopRight:

                return ( new Point(dCenterX, oVertexBounds.Top) );

            case VertexLabelPosition.MiddleLeft:

                return ( new Point(dCenterX - dOffsetX, dCenterY) );

            case VertexLabelPosition.MiddleCenter:

                return ( new Point(dCenterX, dCenterY) );

            case VertexLabelPosition.MiddleRight:

                return ( new Point(dCenterX + dOffsetX, dCenterY) );

            case VertexLabelPosition.BottomLeft:

                return (oVertexBounds.BottomLeft);

            case VertexLabelPosition.BottomCenter:

                return ( new Point(dCenterX, oVertexBounds.Bottom) );

            case VertexLabelPosition.BottomRight:

                return (oVertexBounds.BottomRight);

            default:

                Debug.Assert(false);
                return (this.VertexLocation);
            }
        }
Example #18
0
        DrawLabel
        (
            DrawingContext drawingContext,
            GraphDrawingContext graphDrawingContext,
            VertexDrawingHistory vertexDrawingHistory,
            VertexLabelPosition labelPosition,
            FormattedText formattedText,
            Color formattedTextColor,
            Boolean drawBackground
        )
        {
            Debug.Assert(drawingContext != null);
            Debug.Assert(graphDrawingContext != null);
            Debug.Assert(vertexDrawingHistory != null);
            Debug.Assert(formattedText != null);
            AssertValid();

            if (labelPosition == VertexLabelPosition.Nowhere)
            {
                return;
            }

            // The alignment needs to be set before the width and height of the
            // FormattedText are obtained.

            SetTextAlignment(formattedText, labelPosition);

            // You can't use FormattedText.Width to get the width of the actual
            // text when text wrapping is enabled (FormattedText.MaxTextWidth > 0).
            // Instead, use a method that takes wrapping into account.

            Double dLabelWidth = WpfGraphicsUtil.GetFormattedTextSize(
                formattedText).Width;

            Double dLabelHeight = formattedText.Height;

            // This is the point where the label will be drawn using
            // DrawingContext.Draw().  It initially assumes a text height of zero,
            // a margin of zero, and no adjustment for alignment (see
            // dAdjustmentForTextAlignmentX below), but this will be modified
            // appropriately within the switch statement below.

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

            // These are the left and right bounds of the rectangle where the text
            // will actually appear.

            Double dLabelBoundsLeft  = 0;
            Double dLabelBoundsRight = 0;

            AdjustForTextAlignment(dLabelWidth, dLabelHeight, labelPosition,
                                   formattedText, ref dDrawX, ref dDrawY, ref dLabelBoundsLeft,
                                   ref dLabelBoundsRight);

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

            dDrawX = StayWithinHorizontalBounds(
                dDrawX, graphDrawingContext, dLabelBoundsLeft, dLabelBoundsRight);

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

            dDrawY = StayWithinVerticalBounds(
                dDrawY, graphDrawingContext, dLabelBoundsTop, dLabelBoundsBottom);

            if (drawBackground)
            {
                dLabelBoundsLeft = StayWithinHorizontalBounds(
                    dLabelBoundsLeft, graphDrawingContext,
                    dLabelBoundsLeft, dLabelBoundsRight);

                DrawLabelBackground(drawingContext, graphDrawingContext,
                                    formattedText, formattedTextColor, m_btBackgroundAlpha,
                                    new Point(dLabelBoundsLeft, dDrawY));
            }

            drawingContext.DrawText(formattedText, new Point(dDrawX, dDrawY));
        }
Example #19
0
        AdjustForTextAlignment
        (
            Double dLabelWidth,
            Double dLabelHeight,
            VertexLabelPosition eLabelPosition,
            FormattedText oFormattedText,
            ref Double dDrawX,
            ref Double dDrawY,
            ref Double dLabelBoundsLeft,
            ref Double dLabelBoundsRight
        )
        {
            Debug.Assert(dLabelWidth >= 0);
            Debug.Assert(dLabelHeight >= 0);
            Debug.Assert(oFormattedText != null);
            AssertValid();

            Double dHalfLabelHeight  = dLabelHeight / 2.0;
            Double dHalfLabelWidth   = dLabelWidth / 2.0;
            Double dMaxTextWidth     = oFormattedText.MaxTextWidth;
            Double dHalfMaxTextWidth = dMaxTextWidth / 2.0;

            // This is the adjustment that needs to be made to the x-coordinate
            // passed to DrawingContext.DrawText() to compensate for the way
            // centered and right-justified text is positioned.
            //
            // When wrapping is turned off (FormattedText.MaxTextWidth = 0) and
            // FormattedText.TextAlignment = TextAlignment.Center, for example,
            // the text gets centered horizontally at the specified drawing point.
            // When wrapping is turned on, however (FormattedText.MaxTextWidth
            // > 0), the text gets centered horizontally at the point halfway
            // between the specified drawing point and the MaxTextWidth value.

            Double dAdjustmentForTextAlignmentX = 0;

            switch (eLabelPosition)
            {
            case VertexLabelPosition.TopLeft:

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

                break;

            case VertexLabelPosition.TopCenter:

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

                break;

            case VertexLabelPosition.TopRight:

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

                break;

            case VertexLabelPosition.MiddleLeft:

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

                break;

            case VertexLabelPosition.MiddleCenter:

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

                break;

            case VertexLabelPosition.MiddleRight:

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

                break;

            case VertexLabelPosition.BottomLeft:

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

                break;

            case VertexLabelPosition.BottomCenter:

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

                break;

            case VertexLabelPosition.BottomRight:

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

                break;

            case VertexLabelPosition.Nowhere:

            // (This was handled at the top of the method.)

            default:

                Debug.Assert(false);
                break;
            }

            dDrawX += dAdjustmentForTextAlignmentX;
        }
    GetLabelLocation
    (
        VertexLabelPosition labelPosition
    )
    {
        AssertValid();

        return ( GetLabelLocationOnDiamond(labelPosition, m_dHalfWidth) );
    }
    DrawLabel
    (
        DrawingContext drawingContext,
        GraphDrawingContext graphDrawingContext,
        VertexDrawingHistory vertexDrawingHistory,
        VertexLabelPosition labelPosition,
        FormattedText formattedText,
        Color formattedTextColor,
        Boolean drawBackground
    )
    {
        Debug.Assert(drawingContext != null);
        Debug.Assert(graphDrawingContext != null);
        Debug.Assert(vertexDrawingHistory != null);
        Debug.Assert(formattedText != null);
        AssertValid();

        if (labelPosition == VertexLabelPosition.Nowhere)
        {
            return;
        }

        // The alignment needs to be set before the width and height of the
        // FormattedText are obtained.

        SetTextAlignment(formattedText, labelPosition);

        // You can't use FormattedText.Width to get the width of the actual
        // text when text wrapping is enabled (FormattedText.MaxTextWidth > 0).
        // Instead, use a method that takes wrapping into account.

        Double dLabelWidth = WpfGraphicsUtil.GetFormattedTextSize(
            formattedText).Width;

        Double dLabelHeight = formattedText.Height;

        // This is the point where the label will be drawn using
        // DrawingContext.Draw().  It initially assumes a text height of zero,
        // a margin of zero, and no adjustment for alignment (see
        // dAdjustmentForTextAlignmentX below), but this will be modified
        // appropriately within the switch statement below.

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

        // These are the left and right bounds of the rectangle where the text
        // will actually appear.

        Double dLabelBoundsLeft = 0;
        Double dLabelBoundsRight = 0;

        AdjustForTextAlignment(dLabelWidth, dLabelHeight, labelPosition,
            formattedText, ref dDrawX, ref dDrawY, ref dLabelBoundsLeft,
            ref dLabelBoundsRight);

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

        dDrawX = StayWithinHorizontalBounds(
            dDrawX, graphDrawingContext, dLabelBoundsLeft, dLabelBoundsRight);

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

        dDrawY = StayWithinVerticalBounds(
            dDrawY, graphDrawingContext, dLabelBoundsTop, dLabelBoundsBottom);

        if (drawBackground)
        {
            dLabelBoundsLeft = StayWithinHorizontalBounds(
                dLabelBoundsLeft, graphDrawingContext,
                dLabelBoundsLeft, dLabelBoundsRight);

            DrawLabelBackground( drawingContext, graphDrawingContext,
                formattedText, formattedTextColor, m_btBackgroundAlpha,
                new Point(dLabelBoundsLeft, dDrawY) );
        }

        drawingContext.DrawText( formattedText, new Point(dDrawX, dDrawY) );
    }
    GetLabelLocation
    (
        VertexLabelPosition labelPosition
    )
    {
        AssertValid();

        // The diamond pattern for label locations is appropriate for circles.

        return ( GetLabelLocationOnDiamond(labelPosition, m_dRadius) );
    }
 GetLabelLocation
 (
     VertexLabelPosition labelPosition
 );
    AdjustForTextAlignment
    (
        Double dLabelWidth,
        Double dLabelHeight,
        VertexLabelPosition eLabelPosition,
        FormattedText oFormattedText,
        ref Double dDrawX,
        ref Double dDrawY,
        ref Double dLabelBoundsLeft,
        ref Double dLabelBoundsRight
    )
    {
        Debug.Assert(dLabelWidth >= 0);
        Debug.Assert(dLabelHeight >= 0);
        Debug.Assert(oFormattedText != null);
        AssertValid();

        Double dHalfLabelHeight = dLabelHeight / 2.0;
        Double dHalfLabelWidth = dLabelWidth / 2.0;
        Double dMaxTextWidth = oFormattedText.MaxTextWidth;
        Double dHalfMaxTextWidth = dMaxTextWidth / 2.0;

        // This is the adjustment that needs to be made to the x-coordinate
        // passed to DrawingContext.DrawText() to compensate for the way
        // centered and right-justified text is positioned.
        //
        // When wrapping is turned off (FormattedText.MaxTextWidth = 0) and
        // FormattedText.TextAlignment = TextAlignment.Center, for example,
        // the text gets centered horizontally at the specified drawing point.
        // When wrapping is turned on, however (FormattedText.MaxTextWidth
        // > 0), the text gets centered horizontally at the point halfway
        // between the specified drawing point and the MaxTextWidth value.

        Double dAdjustmentForTextAlignmentX = 0;

        switch (eLabelPosition)
        {
            case VertexLabelPosition.TopLeft:

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

                break;

            case VertexLabelPosition.TopCenter:

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

                break;

            case VertexLabelPosition.TopRight:

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

                break;

            case VertexLabelPosition.MiddleLeft:

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

                break;

            case VertexLabelPosition.MiddleCenter:

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

                break;

            case VertexLabelPosition.MiddleRight:

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

                break;

            case VertexLabelPosition.BottomLeft:

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

                break;

            case VertexLabelPosition.BottomCenter:

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

                break;

            case VertexLabelPosition.BottomRight:

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

                break;

            case VertexLabelPosition.Nowhere:

                // (This was handled at the top of the method.)

            default:

                Debug.Assert(false);
                break;
        }

        dDrawX += dAdjustmentForTextAlignmentX;
    }
        //*************************************************************************
        //  Method: GetLabelLocation()
        //
        /// <summary>
        /// Gets the location at which an annotation label should be drawn.
        /// </summary>
        ///
        /// <param name="labelPosition">
        /// The position of the annotation label.
        /// </param>
        ///
        /// <returns>
        /// The point at which an annotation label should be drawn.
        /// </returns>
        ///
        /// <remarks>
        /// The returned point assumes that the label text height is zero and that
        /// there is zero margin between the vertex and the label.  The caller must
        /// adjust the point for the actual text height and any margin.
        /// </remarks>
        //*************************************************************************
        public override Point GetLabelLocation(
            VertexLabelPosition labelPosition
            )
        {
            AssertValid();

            Double dCenterX = m_oRectangle.Left + m_oRectangle.Width / 2.0;
            Double dMiddleY = m_oRectangle.Top + m_oRectangle.Height / 2.0;

            switch (labelPosition)
            {
            case VertexLabelPosition.TopLeft:

                return (m_oRectangle.TopLeft);

            case VertexLabelPosition.TopCenter:

                return ( new Point(dCenterX, m_oRectangle.Top) );

            case VertexLabelPosition.TopRight:

                return (m_oRectangle.TopRight);

            case VertexLabelPosition.MiddleLeft:

                return ( new Point(m_oRectangle.Left, dMiddleY) );

            case VertexLabelPosition.MiddleCenter:

                return ( new Point(dCenterX, dMiddleY) );

            case VertexLabelPosition.MiddleRight:

                return ( new Point(m_oRectangle.Right, dMiddleY) );

            case VertexLabelPosition.BottomLeft:

                return (m_oRectangle.BottomLeft);

            case VertexLabelPosition.BottomCenter:

                return ( new Point(dCenterX, m_oRectangle.Bottom) );

            case VertexLabelPosition.BottomRight:

                return (m_oRectangle.BottomRight);

            default:

                Debug.Assert(false);
                return ( new Point() );
            }
        }
Example #26
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) );
        }