Title: Make a sunburst chart in C#, Part 2
The post Make a sunburst chart in C#, Part 1 explained how to build a simple sunburst chart. Unfortunately the node labels used by that chart didn't fit their wedges very well because the text was all drawn horizontally. This post modifies the chart so it displays the text rotated to fit the node wedges better.
This change actually isn't all that hard. The program simply uses the following new version of the DrawCenteredText method.
// Draw text centered at the position.
private void DrawCenteredText(Graphics gr, Font font, Color color,
string text, PointF center, float angle)
{
// Rotate.
gr.RotateTransform(angle);
// Translate.
gr.TranslateTransform(center.X, center.Y, MatrixOrder.Append);
// Draw the text.
using (StringFormat sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
using (Brush brush = new SolidBrush(color))
{
gr.DrawString(text, font, brush, 0, 0, sf);
}
}
// Reset the transformation.
gr.ResetTransform();
}
This version of the method takes a new angle parameter that gives the angle at which the text should be drawn.
The method starts by adding a rotation transformation to the Graphics object that will draw the text. Now if the Graphics object draws text (or anything else), it will be rotated by the indicated angle.
Next the code appends a transformation to translate the drawing so the origin (0, 0) is moved to the text's desired point center. The MatrixOrder.Append parameter is important because the default makes the Graphics object prepend the new transformation so it comes before the rotation. (I have never understood why Microsoft did it this way. It seems very nonintuitive to me.)
Now when you use the Graphics object to draw something, it is rotated and then translated.
The code then creates a StringFormat object and sets it up to center text. It creates a brush of the correct color and draws the text centered at the origin. The Graphics object's transformations automatically rotate the text and translate it so it appears where it needs to be drawn.
The method finishes by resetting the Graphics object's transformation. This is important. If you don't do this, then the transformations for every piece of text pile on top of each other. The first piece of text is drawn where it should be, but later piece of text use stranger and stranger transformations so they don't appear where they should. In fact, they probably will be mapped off of the image so they won't appear at all.
The only other large change to the program is in the DrawSunburstChild method. When it is drawing text for a wedge with center angle mid_theta in radians, the method uses the following statement to calculate the text's angle of rotation.
float text_angle = (float)(90 + mid_theta / Math.PI * 180);
This code converts mid_theta into degrees and then adds 90°. (If you don't add 90°, then the text is oriented radially away from the center of the chart.)
After performing this calculation, the code passes the text's angle into the DrawCenteredText method.
The final change to the program is that it uses a bold Arial font instead of Times New Roman. At the font size used here (10 point) and when rotated, Arial bold looks better than Times New Roman.
In my next post I'll show how you can make the text curve to fit inside the wedges even better.
Download the example to experiment with it and to see additional details.
|