Click here to Skip to main content
15,891,529 members
Articles / Programming Languages / C#

Tree Circle Draw Control

Rate me:
Please Sign up or sign in to vote.
4.20/5 (15 votes)
3 Sep 2008CPOL2 min read 62.5K   1.9K   44   6
This control draws circles that include text and links them with a line
CircleTree

Introduction

This is a custom control which gives the ability to easily draw circles and edges between them.
This control is very useful for drawing binary trees.

Using the Code

The control is based on Panel class, which is derived and extended with methods for manipulation of circles and edges.
Every circle is placed in an invisible grid. The step of the grid can be specified by property GridSize. The size of circles can be changed with property CircleSize. The origin of the coordinate system can be changed by using property InvertGridYPosition, for example, the origin can be changed from upper left corner to lower right corner.
The other properties of the class can manipulate background color, border color, font of the text, color of the text in circles, color and width of the binding lines.

The methods are divided as follows:

Circle Manipulation

  • Add new circle - Add
  • caption Edit - ChangeText
  • delete circle - Remove
  • delete all edges for current circle - RemoveAllLink
  • and delete circle by its position - RemovePos
  • Check for existence of circle - Exist
  • searching by index - FindIndex

Edge Manipulation

  • Add new edge - AddLink
  • Change text of the link - ChangeTextLink
  • Check for existing edge - ExistLink
  • Searching of edge - FindLink
  • Delete edge - RemoveLink

Common Methods

  • BeginUpdate, EndUpdate - when it is needed to add many circles and edges at the same time without redrawing all elements after every addition, the methods BeginUpdate which stops redraw and EndUpdate which restores redraw mode can be used.
  • Clear - removes all circles and edges between them
  • Refresh - will redraw all elements

Description of each circle is stored in the structure CircleEntity, where are stored: coordinates, caption and List of all vertices which are direct linked to a given circle. All circles are stored in a Generic List of type CircleEntity.

The most interesting method is a derived and rewritten method OnPaint:

C#
/// <summary>
/// Override OnPaint and implement custom draw functionality
/// First draw linked lines. Next add text in link lines.
/// Second draw Circles.
/// </summary>
/// <param name="e">Paint arguments</param>
protected override void OnPaint(PaintEventArgs e)
{
    int x;
    int y;
    string s;
    float textX;
    float textY;
    SizeF sizeText;
    Graphics g = e.Graphics;
    Point pStart;
    Point pEnd;
    
    // First draw linked lines and draw text if exist
    for (int i = 0; i < _circles.Count; i++)
    {
        List<CircleLinkEntity> cl = _circles[i].Links;
        for (int j = 0; j < cl.Count; j++)
        {
            // Calculate center grid coordinates position
            pStart = CalculateGrigPosCenter(_circles[i].PosX, _circles[i].PosY);
            pEnd = CalculateGrigPosCenter(cl[j].Link.PosX, cl[j].Link.PosY);
            g.DrawLine(_linkedLinePen, pStart, pEnd);
             s = cl[j].Text;
            // if text empty not draw
            if (String.IsNullOrEmpty(s))
                continue;
             // Calculate text position
            sizeText = g.MeasureString(s, _circleFont);
            textX = Math.Min(pStart.X, pEnd.X) + 
		 (Math.Abs(pStart.X - pEnd.X) / 2) - (sizeText.Width / 2);
            textY = Math.Min(pStart.Y, pEnd.Y) + 
		 (Math.Abs(pStart.Y - pEnd.Y) / 2) - (sizeText.Height / 2);
             // Draw background rectangle
            g.FillRectangle(_circleFillSolidBrush, textX, textY, 
				sizeText.Width, sizeText.Height);
            // Draw outside rectangle
            g.DrawRectangle(new Pen(_circleOutlineColor, 1), 
			textX, textY, sizeText.Width, sizeText.Height);
            // Draw text
            e.Graphics.DrawString(s, _circleFont, 
			_circleFontColorSolidBrush, textX, textY);
        }
    }
    
    Point p;
    
    // Draw Circles and add inside text
    for (int i = 0; i < _circles.Count; i++)
    {
        p = CalculateGrigPos(_circles[i].PosX, _circles[i].PosY);
         // Centred to grid coordinates
        x = p.X + _gridCoordinateCorrection;
        y = p.Y + _gridCoordinateCorrection;
         // Draw first fill circle for background
        g.FillEllipse(_circleFillSolidBrush, x, y, _circleSize, _circleSize);
        // Draw outside circle
        g.DrawEllipse(_circlePen, x, y, _circleSize, _circleSize);
         s = _circles[i].Text;
         // Calculate text Height and Width
        sizeText = g.MeasureString(s, _circleFont);
         // Calculate text position. Justify
        textX = p.X + _cellHalfSize - (sizeText.Width / 2);
        textY = p.Y + _cellHalfSize - (sizeText.Height / 2);
         g.DrawString(s, _circleFont, _circleFontColorSolidBrush, textX, textY);
        // Rectangle over text
        //g.DrawRectangle(new Pen(Color.Red, 1.0F), textX, 
        //		textY, sizeText.Width, sizeText.Height);
    }
    
    base.OnPaint(e);
}       

In the first step, all linking edges and their captions are drawn, and meanwhile all coordinates of the grid are translated to real view coordinates.

In the second step, all circles and their captions are drawn.

When new vertices are added out of the viewable area, the control will be automatically resized and if needed, will add scroll bars.

Points of Interest

This control can be used in studying of binary and other types of trees. We used it to display results of Huffman algorithm.

History

In the first version, we made the base functionality, which contains only adding of circles and linking edges, and later we added editing, searching and deleting of elements. We have also created the ability to show captions on edges.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Bulpros AD
Bulgaria Bulgaria
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionthanks and help Pin
Member 1185614523-Dec-15 23:32
Member 1185614523-Dec-15 23:32 
Questionthanks and help Pin
Member 1185614523-Dec-15 23:29
Member 1185614523-Dec-15 23:29 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey26-Feb-12 21:52
professionalManoj Kumar Choubey26-Feb-12 21:52 
GeneralMy vote of 5 Pin
Bhavik Thakkar,Smiley IT Solution26-Nov-10 16:28
professionalBhavik Thakkar,Smiley IT Solution26-Nov-10 16:28 
GeneralGreat control Pin
FernandoUY1-Sep-10 14:09
professionalFernandoUY1-Sep-10 14:09 
Hi Plamen.

This is a great control. I'm adding some functionalities (different shapes, circles and rectangles for now), selection capabilities, etc.

With this, you can create a workflow manager, CMDB capabilities, etc.
Great work.
GeneralRe: Great control Pin
Plamen Kovandjiev2-Sep-10 6:15
professionalPlamen Kovandjiev2-Sep-10 6:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.