Нарисуйте отмеченную круговую диаграмму в 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 от радиуса круга.