Нарисуйте отмеченную круговую диаграмму в C#
Пример показывает, как для рисования простой круговой диаграммы. Этот пример добавляет метки в срезы пирога.
В этом примере используется следующий код для рисования его круговой диаграммы.
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(BackColor);
if ((ClientSize.Width < 20) || (ClientSize.Height < 20))
return;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
Rectangle rect = new Rectangle(
10, 10, ClientSize.Width - 20, ClientSize.Height - 20);
DrawLabeledPieChart(e.Graphics, rect, -90, SliceBrushes,
SlicePens, Values, "0.0", Font, Brushes.Black);
}
private static void DrawLabeledPieChart(Graphics gr,
Rectangle rect, float initial_angle, Brush[] brushes,
Pen[] pens, float[] values, string label_format,
Font label_font, Brush label_brush)
{
float total = values.Sum();
float start_angle = initial_angle;
for (int i = 0; i < values.Length; i++)
{
float sweep_angle = values[i] * 360f / total;
gr.FillPie(brushes[i % brushes.Length],
rect, start_angle, sweep_angle);
gr.DrawPie(pens[i % pens.Length],
rect, start_angle, sweep_angle);
start_angle += sweep_angle;
}
using (StringFormat string_format = new StringFormat())
{
string_format.Alignment = StringAlignment.Center;
string_format.LineAlignment = StringAlignment.Center;
float cx = (rect.Left + rect.Right) / 2f;
float cy = (rect.Top + rect.Bottom) / 2f;
float radius = (rect.Width + rect.Height) / 2f * 0.33f;
start_angle = initial_angle;
for (int i = 0; i < values.Length; i++)
{
float sweep_angle = values[i] * 360f / total;
double label_angle =
Math.PI * (start_angle + sweep_angle / 2f) / 180f;
float x = cx + (float)(radius * Math.Cos(label_angle));
float y = cy + (float)(radius * Math.Sin(label_angle));
gr.DrawString(values[i].ToString(label_format),
label_font, label_brush, x, y, string_format);
start_angle += sweep_angle;
}
}
}
Первая часть кода похожа на предыдущий пример. Вторая часть рисует метки на срезах. Код называет срезы после рисования всех них, в отличие от маркировки каждого среза по мере его рисования, поэтому срез не будет закрывать ярлык ранее нарисованного очень тонкого среза.
Код маркировки создает объект StringFormat и подготавливает его к центру текста. Затем он находит центр прямоугольника, содержащий круговую диаграмму.
Далее код вычисляет радиус, по которому нужно рисовать метки среза. Чтобы получить этот радиус, код усредняет ширину и высоту диаграммы и умножает на 0,33. Это делает радиус около 2/3 полуширины / высоты прямоугольника. Если прямоугольник квадратный, круговая диаграмма круглая, и этот радиус действительно равен 2/3 от радиуса круга.
