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 themRefresh
- 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
:
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;
for (int i = 0; i < _circles.Count; i++)
{
List<CircleLinkEntity> cl = _circles[i].Links;
for (int j = 0; j < cl.Count; j++)
{
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 (String.IsNullOrEmpty(s))
continue;
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);
g.FillRectangle(_circleFillSolidBrush, textX, textY,
sizeText.Width, sizeText.Height);
g.DrawRectangle(new Pen(_circleOutlineColor, 1),
textX, textY, sizeText.Width, sizeText.Height);
e.Graphics.DrawString(s, _circleFont,
_circleFontColorSolidBrush, textX, textY);
}
}
Point p;
for (int i = 0; i < _circles.Count; i++)
{
p = CalculateGrigPos(_circles[i].PosX, _circles[i].PosY);
x = p.X + _gridCoordinateCorrection;
y = p.Y + _gridCoordinateCorrection;
g.FillEllipse(_circleFillSolidBrush, x, y, _circleSize, _circleSize);
g.DrawEllipse(_circlePen, x, y, _circleSize, _circleSize);
s = _circles[i].Text;
sizeText = g.MeasureString(s, _circleFont);
textX = p.X + _cellHalfSize - (sizeText.Width / 2);
textY = p.Y + _cellHalfSize - (sizeText.Height / 2);
g.DrawString(s, _circleFont, _circleFontColorSolidBrush, textX, textY);
}
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.