(七十)c#Winform自定义控件-饼状图

Posted bfyx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(七十)c#Winform自定义控件-饼状图相关的知识,希望对你有一定的参考价值。

前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 技术图片

麻烦博客下方点个【推荐】,谢谢

NuGet

Install-Package HZH_Controls

目录

https://www.cnblogs.com/bfyx/p/11364884.html

用处及效果

技术图片

准备工作

使用GDI+画的控件,不了解可以先百度下

开始

添加一个类UCPieChart ,继承UserControl

添加一些属性

  1  /// <summary>
  2         /// The pie items
  3         /// </summary>
  4         private PieItem[] pieItems = new PieItem[0];
  5 
  6         /// <summary>
  7         /// The random
  8         /// </summary>
  9         private Random random = null;
 10 
 11         /// <summary>
 12         /// The format center
 13         /// </summary>
 14         private StringFormat formatCenter = null;
 15 
 16         /// <summary>
 17         /// The margin
 18         /// </summary>
 19         private int margin = 50;
 20 
 21         /// <summary>
 22         /// The m is render percent
 23         /// </summary>
 24         private bool m_IsRenderPercent = false;
 25 
 26         /// <summary>
 27         /// The percen format
 28         /// </summary>
 29         private string percenFormat = "0:F2%";
 30 
 31         /// <summary>
 32         /// The components
 33         /// </summary>
 34         private IContainer components = null;
 35 
 36         /// <summary>
 37         /// Gets or sets a value indicating whether this instance is render percent.
 38         /// </summary>
 39         /// <value><c>true</c> if this instance is render percent; otherwise, <c>false</c>.</value>
 40         [Browsable(true)]
 41         [Category("自定义")]
 42         [DefaultValue(false)]
 43         [Description("获取或设置是否显示百分比占用")]
 44         public bool IsRenderPercent
 45         
 46             get
 47             
 48                 return m_IsRenderPercent;
 49             
 50             set
 51             
 52                 m_IsRenderPercent = value;
 53                 Invalidate();
 54             
 55         
 56 
 57 
 58         /// <summary>
 59         /// Gets or sets the text margin.
 60         /// </summary>
 61         /// <value>The text margin.</value>
 62         [Browsable(true)]
 63         [Category("自定义")]
 64         [Description("获取或设置文本距离,单位为像素,默认50")]
 65         [DefaultValue(50)]
 66         public int TextMargin
 67         
 68             get
 69             
 70                 return margin;
 71             
 72             set
 73             
 74                 margin = value;
 75                 Invalidate();
 76             
 77         
 78 
 79 
 80         /// <summary>
 81         /// Gets or sets the percent format.
 82         /// </summary>
 83         /// <value>The percent format.</value>
 84         [Browsable(true)]
 85         [Category("自定义")]
 86         [Description("获取或设置文百分比文字的格式化信息")]
 87         [DefaultValue("0:F2%")]
 88         public string PercentFormat
 89         
 90             get
 91             
 92                 return percenFormat;
 93             
 94             set
 95             
 96                 percenFormat = value;
 97                 Invalidate();
 98             
 99         
100 
101         /// <summary>
102         /// The center of circle color
103         /// </summary>
104         private Color centerOfCircleColor = Color.White;
105         /// <summary>
106         /// Gets or sets the color of the center of circle.
107         /// </summary>
108         /// <value>The color of the center of circle.</value>
109         [Browsable(true)]
110         [Category("自定义")]
111         [Description("获取或设置圆心颜色")]
112         public Color CenterOfCircleColor
113         
114             get  return centerOfCircleColor; 
115             set
116             
117                 centerOfCircleColor = value;
118                 Invalidate();
119             
120         
121 
122         /// <summary>
123         /// The center of circle width
124         /// </summary>
125         private int centerOfCircleWidth = 0;
126         /// <summary>
127         /// Gets or sets the width of the center of circle.
128         /// </summary>
129         /// <value>The width of the center of circle.</value>
130         [Browsable(true)]
131         [Category("自定义")]
132         [Description("获取或设置圆心宽度")]
133         public int CenterOfCircleWidth
134         
135             get  return centerOfCircleWidth; 
136             set
137             
138                 if (value < 0)
139                     return;
140                 centerOfCircleWidth = value;
141                 Invalidate();
142             
143         
144 
145         /// <summary>
146         /// The title
147         /// </summary>
148         private string title;
149         /// <summary>
150         /// Gets or sets the ti tle.
151         /// </summary>
152         /// <value>The ti tle.</value>
153         [Browsable(true)]
154         [Category("自定义")]
155         [Description("获取或设置标题")]
156         public string TiTle
157         
158             get  return title; 
159             set
160             
161                 title = value;
162                 ResetTitleHeight();
163                 Invalidate();
164             
165         
166         /// <summary>
167         /// The title font
168         /// </summary>
169         private Font titleFont = new Font("微软雅黑", 12);
170         /// <summary>
171         /// Gets or sets the title font.
172         /// </summary>
173         /// <value>The title font.</value>
174         [Browsable(true)]
175         [Category("自定义")]
176         [Description("获取或设置标题字体")]
177         public Font TitleFont
178         
179             get  return titleFont; 
180             set
181             
182                 titleFont = value;
183                 ResetTitleHeight();
184                 Invalidate();
185             
186         
187 
188         /// <summary>
189         /// The title froe color
190         /// </summary>
191         private Color titleFroeColor = Color.Black;
192         /// <summary>
193         /// Gets or sets the color of the title froe.
194         /// </summary>
195         /// <value>The color of the title froe.</value>
196         [Browsable(true)]
197         [Category("自定义")]
198         [Description("获取或设置标题颜色")]
199         public Color TitleFroeColor
200         
201             get  return titleFroeColor; 
202             set
203             
204                 titleFroeColor = value;
205                 Invalidate();
206             
207         
208 
209         /// <summary>
210         /// The title size
211         /// </summary>
212         private SizeF titleSize = SizeF.Empty;
213         /// <summary>
214         /// Resets the height of the title.
215         /// </summary>
216         private void ResetTitleHeight()
217         
218             if (string.IsNullOrEmpty(title))
219                 titleSize = SizeF.Empty;
220             else
221             
222                 using (var g = this.CreateGraphics())
223                 
224                     titleSize = g.MeasureString(title, titleFont);
225                 
226             
227         
228 
229         /// <summary>
230         /// Gets or sets the data source.
231         /// </summary>
232         /// <value>The data source.</value>
233         [Browsable(true)]
234         [Category("自定义")]
235         [Description("获取或设置标题颜色")]
236         [Localizable(true)]
237         public PieItem[] DataSource
238         
239             get  return pieItems; 
240             set
241             
242                 pieItems = value;
243                 Invalidate();
244             
245         

重绘

  1  protected override void OnPaint(PaintEventArgs e)
  2         
  3             e.Graphics.SetGDIHigh();
  4 
  5             int width;
  6             Point centerPoint = GetCenterPoint(out width);
  7             Rectangle rectangle = new Rectangle(centerPoint.X - width, centerPoint.Y - width, width * 2, width * 2);
  8             if (width > 0 && pieItems.Length != 0)
  9             
 10                 if (!string.IsNullOrEmpty(title))
 11                     e.Graphics.DrawString(title, titleFont, new SolidBrush(titleFroeColor), new PointF((this.Width - titleSize.Width) / 2, 5));               
 12                 Rectangle rect = new Rectangle(rectangle.X - centerPoint.X, rectangle.Y - centerPoint.Y, rectangle.Width, rectangle.Height);
 13                 e.Graphics.TranslateTransform(centerPoint.X, centerPoint.Y);
 14                 e.Graphics.RotateTransform(90f);
 15                 int num = pieItems.Sum((PieItem item) => item.Value);
 16                 float num2 = 0f;
 17                 float num3 = -90f;
 18                 for (int i = 0; i < pieItems.Length; i++)
 19                 
 20                     Color cItem = pieItems[i].PieColor ?? ControlHelper.Colors[i];
 21                     Pen pen = new Pen(cItem, 1f);
 22                     SolidBrush solidBrush = new SolidBrush(cItem);
 23                     SolidBrush solidBrush2 = new SolidBrush(cItem);
 24                     Brush percentBrush = new SolidBrush(cItem);
 25                     float num4 = e.Graphics.MeasureString(pieItems[i].Name, Font).Width + 3f;
 26                     float num5 = (num != 0) ? Convert.ToSingle((double)pieItems[i].Value * 1.0 / (double)num * 360.0) : ((float)(360 / pieItems.Length));
 27                     e.Graphics.FillPie(solidBrush, rect, 0f, 0f - num5);
 28                     e.Graphics.DrawPie(new Pen(solidBrush), rect, 0f, 0f - num5);
 29                     e.Graphics.RotateTransform(0f - num5 / 2f);
 30                     if (num5 < 2f)
 31                     
 32                         num2 += num5;
 33                     
 34                     else
 35                     
 36                         num2 += num5 / 2f;
 37                         int num6 = 15;
 38                         if (num2 < 45f || num2 > 315f)
 39                         
 40                             num6 = 20;
 41                         
 42                         if (num2 > 135f && num2 < 225f)
 43                         
 44                             num6 = 20;
 45                         
 46                         e.Graphics.DrawLine(pen, width * 2 / 3, 0, width + num6, 0);
 47                         e.Graphics.TranslateTransform(width + num6, 0f);
 48                         if (num2 - num3 < 5f)
 49                         
 50                         
 51                         num3 = num2;
 52                         if (num2 < 180f)
 53                         
 54                             e.Graphics.RotateTransform(num2 - 90f);
 55                             e.Graphics.DrawLine(pen, 0f, 0f, num4, 0f);
 56                             e.Graphics.DrawString(pieItems[i].Name, Font, solidBrush2, new Point(0, -Font.Height));
 57                             if (IsRenderPercent)
 58                             
 59                                 e.Graphics.DrawString(string.Format(percenFormat, num5 * 100f / 360f), Font, percentBrush, new Point(0, 1));
 60                             
 61                             e.Graphics.RotateTransform(90f - num2);
 62                         
 63                         else
 64                         
 65                             e.Graphics.RotateTransform(num2 - 270f);
 66                             e.Graphics.DrawLine(pen, 0f, 0f, num4, 0f);
 67                             e.Graphics.TranslateTransform(num4 - 3f, 0f);
 68                             e.Graphics.RotateTransform(180f);
 69                             e.Graphics.DrawString(pieItems[i].Name, Font, solidBrush2, new Point(0, -Font.Height));
 70                             if (IsRenderPercent)
 71                             
 72                                 e.Graphics.DrawString(string.Format(percenFormat, num5 * 100f / 360f), Font, percentBrush, new Point(0, 1));
 73                             
 74                             e.Graphics.RotateTransform(-180f);
 75                             e.Graphics.TranslateTransform(0f - num4 + 3f, 0f);
 76                             e.Graphics.RotateTransform(270f - num2);
 77                         
 78                         e.Graphics.TranslateTransform(-width - num6, 0f);
 79                         e.Graphics.RotateTransform(0f - num5 / 2f);
 80                         num2 += num5 / 2f;
 81                     
 82                     solidBrush.Dispose();
 83                     pen.Dispose();
 84                     solidBrush2.Dispose();
 85                     percentBrush.Dispose();
 86                 
 87                 e.Graphics.ResetTransform();
 88 
 89                 if (centerOfCircleWidth > 0)
 90                 
 91                     Rectangle rectCenter = new Rectangle(rect.Left + rect.Width / 2 - centerOfCircleWidth / 2, rect.Top + rect.Height / 2 - centerOfCircleWidth / 2, centerOfCircleWidth, centerOfCircleWidth);
 92                     e.Graphics.FillEllipse(new SolidBrush(centerOfCircleColor), rectCenter);
 93                 
 94             
 95             else
 96             
 97                 e.Graphics.FillEllipse(Brushes.AliceBlue, rectangle);
 98                 e.Graphics.DrawEllipse(Pens.DodgerBlue, rectangle);
 99                 e.Graphics.DrawString("无数据", Font, Brushes.DimGray, rectangle, formatCenter);
100             
101             base.OnPaint(e);
102         

一些辅助函数

 1  /// <summary>
 2         /// Sets the data source.
 3         /// </summary>
 4         /// <param name="source">The source.</param>
 5         public void SetDataSource(PieItem[] source)
 6         
 7             if (source != null)
 8             
 9                 DataSource = source;
10             
11         
12         /// <summary>
13         /// Sets the data source.
14         /// </summary>
15         /// <param name="names">The names.</param>
16         /// <param name="values">The values.</param>
17         /// <exception cref="System.ArgumentNullException">
18         /// names
19         /// or
20         /// values
21         /// </exception>
22         /// <exception cref="System.Exception">两个数组的长度不一致!</exception>
23         public void SetDataSource(string[] names, int[] values)
24         
25             if (names == null)
26             
27                 throw new ArgumentNullException("names");
28             
29             if (values == null)
30             
31                 throw new ArgumentNullException("values");
32             
33             if (names.Length != values.Length)
34             
35                 throw new Exception("两个数组的长度不一致!");
36             
37             pieItems = new PieItem[names.Length];
38             for (int i = 0; i < names.Length; i++)
39             
40                 pieItems[i] = new PieItem
41                 
42                     Name = names[i],
43                     Value = values[i]
44                 ;
45             
46             Invalidate();
47         

完整代码

技术图片
  1 // ***********************************************************************
  2 // Assembly         : HZH_Controls
  3 // Created          : 2019-09-23
  4 //
  5 // ***********************************************************************
  6 // <copyright file="UCPieChart.cs">
  7 //     Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com
  8 // </copyright>
  9 //
 10 // Blog: https://www.cnblogs.com/bfyx
 11 // GitHub:https://github.com/kwwwvagaa/NetWinformControl
 12 // gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
 13 //
 14 // If you use this code, please keep this note.
 15 // ***********************************************************************
 16 using System;
 17 using System.ComponentModel;
 18 using System.ComponentModel.Design;
 19 using System.Drawing;
 20 using System.Drawing.Drawing2D;
 21 using System.Drawing.Text;
 22 using System.Linq;
 23 using System.Windows.Forms;
 24 
 25 namespace HZH_Controls.Controls
 26 
 27     /// <summary>
 28     /// Class UCPieChart.
 29     /// Implements the <see cref="System.Windows.Forms.UserControl" />
 30     /// </summary>
 31     /// <seealso cref="System.Windows.Forms.UserControl" />
 32     public class UCPieChart : UserControl
 33     
 34         /// <summary>
 35         /// The pie items
 36         /// </summary>
 37         private PieItem[] pieItems = new PieItem[0];
 38 
 39         /// <summary>
 40         /// The random
 41         /// </summary>
 42         private Random random = null;
 43 
 44         /// <summary>
 45         /// The format center
 46         /// </summary>
 47         private StringFormat formatCenter = null;
 48 
 49         /// <summary>
 50         /// The margin
 51         /// </summary>
 52         private int margin = 50;
 53 
 54         /// <summary>
 55         /// The m is render percent
 56         /// </summary>
 57         private bool m_IsRenderPercent = false;
 58 
 59         /// <summary>
 60         /// The percen format
 61         /// </summary>
 62         private string percenFormat = "0:F2%";
 63 
 64         /// <summary>
 65         /// The components
 66         /// </summary>
 67         private IContainer components = null;
 68 
 69         /// <summary>
 70         /// Gets or sets a value indicating whether this instance is render percent.
 71         /// </summary>
 72         /// <value><c>true</c> if this instance is render percent; otherwise, <c>false</c>.</value>
 73         [Browsable(true)]
 74         [Category("自定义")]
 75         [DefaultValue(false)]
 76         [Description("获取或设置是否显示百分比占用")]
 77         public bool IsRenderPercent
 78         
 79             get
 80             
 81                 return m_IsRenderPercent;
 82             
 83             set
 84             
 85                 m_IsRenderPercent = value;
 86                 Invalidate();
 87             
 88         
 89 
 90 
 91         /// <summary>
 92         /// Gets or sets the text margin.
 93         /// </summary>
 94         /// <value>The text margin.</value>
 95         [Browsable(true)]
 96         [Category("自定义")]
 97         [Description("获取或设置文本距离,单位为像素,默认50")]
 98         [DefaultValue(50)]
 99         public int TextMargin
100         
101             get
102             
103                 return margin;
104             
105             set
106             
107                 margin = value;
108                 Invalidate();
109             
110         
111 
112 
113         /// <summary>
114         /// Gets or sets the percent format.
115         /// </summary>
116         /// <value>The percent format.</value>
117         [Browsable(true)]
118         [Category("自定义")]
119         [Description("获取或设置文百分比文字的格式化信息")]
120         [DefaultValue("0:F2%")]
121         public string PercentFormat
122         
123             get
124             
125                 return percenFormat;
126             
127             set
128             
129                 percenFormat = value;
130                 Invalidate();
131             
132         
133 
134         /// <summary>
135         /// The center of circle color
136         /// </summary>
137         private Color centerOfCircleColor = Color.White;
138         /// <summary>
139         /// Gets or sets the color of the center of circle.
140         /// </summary>
141         /// <value>The color of the center of circle.</value>
142         [Browsable(true)]
143         [Category("自定义")]
144         [Description("获取或设置圆心颜色")]
145         public Color CenterOfCircleColor
146         
147             get  return centerOfCircleColor; 
148             set
149             
150                 centerOfCircleColor = value;
151                 Invalidate();
152             
153         
154 
155         /// <summary>
156         /// The center of circle width
157         /// </summary>
158         private int centerOfCircleWidth = 0;
159         /// <summary>
160         /// Gets or sets the width of the center of circle.
161         /// </summary>
162         /// <value>The width of the center of circle.</value>
163         [Browsable(true)]
164         [Category("自定义")]
165         [Description("获取或设置圆心宽度")]
166         public int CenterOfCircleWidth
167         
168             get  return centerOfCircleWidth; 
169             set
170             
171                 if (value < 0)
172                     return;
173                 centerOfCircleWidth = value;
174                 Invalidate();
175             
176         
177 
178         /// <summary>
179         /// The title
180         /// </summary>
181         private string title;
182         /// <summary>
183         /// Gets or sets the ti tle.
184         /// </summary>
185         /// <value>The ti tle.</value>
186         [Browsable(true)]
187         [Category("自定义")]
188         [Description("获取或设置标题")]
189         public string TiTle
190         
191             get  return title; 
192             set
193             
194                 title = value;
195                 ResetTitleHeight();
196                 Invalidate();
197             
198         
199         /// <summary>
200         /// The title font
201         /// </summary>
202         private Font titleFont = new Font("微软雅黑", 12);
203         /// <summary>
204         /// Gets or sets the title font.
205         /// </summary>
206         /// <value>The title font.</value>
207         [Browsable(true)]
208         [Category("自定义")]
209         [Description("获取或设置标题字体")]
210         public Font TitleFont
211         
212             get  return titleFont; 
213             set
214             
215                 titleFont = value;
216                 ResetTitleHeight();
217                 Invalidate();
218             
219         
220 
221         /// <summary>
222         /// The title froe color
223         /// </summary>
224         private Color titleFroeColor = Color.Black;
225         /// <summary>
226         /// Gets or sets the color of the title froe.
227         /// </summary>
228         /// <value>The color of the title froe.</value>
229         [Browsable(true)]
230         [Category("自定义")]
231         [Description("获取或设置标题颜色")]
232         public Color TitleFroeColor
233         
234             get  return titleFroeColor; 
235             set
236             
237                 titleFroeColor = value;
238                 Invalidate();
239             
240         
241 
242         /// <summary>
243         /// The title size
244         /// </summary>
245         private SizeF titleSize = SizeF.Empty;
246         /// <summary>
247         /// Resets the height of the title.
248         /// </summary>
249         private void ResetTitleHeight()
250         
251             if (string.IsNullOrEmpty(title))
252                 titleSize = SizeF.Empty;
253             else
254             
255                 using (var g = this.CreateGraphics())
256                 
257                     titleSize = g.MeasureString(title, titleFont);
258                 
259             
260         
261 
262         /// <summary>
263         /// Gets or sets the data source.
264         /// </summary>
265         /// <value>The data source.</value>
266         [Browsable(true)]
267         [Category("自定义")]
268         [Description("获取或设置标题颜色")]
269         [Localizable(true)]
270         public PieItem[] DataSource
271         
272             get  return pieItems; 
273             set
274             
275                 pieItems = value;
276                 Invalidate();
277             
278         
279 
280         /// <summary>
281         /// Initializes a new instance of the <see cref="UCPieChart"/> class.
282         /// </summary>
283         public UCPieChart()
284         
285             InitializeComponent();
286             random = new Random();
287             formatCenter = new StringFormat();
288             formatCenter.Alignment = StringAlignment.Center;
289             formatCenter.LineAlignment = StringAlignment.Center;
290             SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
291             SetStyle(ControlStyles.ResizeRedraw, true);
292             SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
293             SetStyle(ControlStyles.AllPaintingInWmPaint, true);
294             pieItems = new PieItem[0];
295             if (GetService(typeof(IDesignerHost)) != null || LicenseManager.UsageMode == LicenseUsageMode.Designtime)
296             
297                 pieItems = new PieItem[5];
298 
299                 for (int i = 0; i < 5; i++)
300                 
301                     pieItems[i] = new PieItem
302                     
303                         Name = "Source" + (i + 1),
304                         Value = random.Next(10, 100)
305                     ;
306                 
307             
308         
309 
310    
311 
312         /// <summary>
313         /// Gets the center point.
314         /// </summary>
315         /// <param name="width">The width.</param>
316         /// <returns>Point.</returns>
317         private Point GetCenterPoint(out int width)
318         
319             width = Math.Min(base.Width, base.Height - (titleSize != SizeF.Empty ? ((int)titleSize.Height) : 0)) / 2 - margin - 8;
320             return new Point(base.Width / 2 - 1, base.Height / 2 + (titleSize != SizeF.Empty ? ((int)titleSize.Height) : 0) - 1);
321         
322 
323 
324         /// <summary>
325         /// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
326         /// </summary>
327         /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" /></param>
328         protected override void OnPaint(PaintEventArgs e)
329         
330             e.Graphics.SetGDIHigh();
331 
332             int width;
333             Point centerPoint = GetCenterPoint(out width);
334             Rectangle rectangle = new Rectangle(centerPoint.X - width, centerPoint.Y - width, width * 2, width * 2);
335             if (width > 0 && pieItems.Length != 0)
336             
337                 if (!string.IsNullOrEmpty(title))
338                     e.Graphics.DrawString(title, titleFont, new SolidBrush(titleFroeColor), new PointF((this.Width - titleSize.Width) / 2, 5));               
339                 Rectangle rect = new Rectangle(rectangle.X - centerPoint.X, rectangle.Y - centerPoint.Y, rectangle.Width, rectangle.Height);
340                 e.Graphics.TranslateTransform(centerPoint.X, centerPoint.Y);
341                 e.Graphics.RotateTransform(90f);
342                 int num = pieItems.Sum((PieItem item) => item.Value);
343                 float num2 = 0f;
344                 float num3 = -90f;
345                 for (int i = 0; i < pieItems.Length; i++)
346                 
347                     Color cItem = pieItems[i].PieColor ?? ControlHelper.Colors[i];
348                     Pen pen = new Pen(cItem, 1f);
349                     SolidBrush solidBrush = new SolidBrush(cItem);
350                     SolidBrush solidBrush2 = new SolidBrush(cItem);
351                     Brush percentBrush = new SolidBrush(cItem);
352                     float num4 = e.Graphics.MeasureString(pieItems[i].Name, Font).Width + 3f;
353                     float num5 = (num != 0) ? Convert.ToSingle((double)pieItems[i].Value * 1.0 / (double)num * 360.0) : ((float)(360 / pieItems.Length));
354                     e.Graphics.FillPie(solidBrush, rect, 0f, 0f - num5);
355                     e.Graphics.DrawPie(new Pen(solidBrush), rect, 0f, 0f - num5);
356                     e.Graphics.RotateTransform(0f - num5 / 2f);
357                     if (num5 < 2f)
358                     
359                         num2 += num5;
360                     
361                     else
362                     
363                         num2 += num5 / 2f;
364                         int num6 = 15;
365                         if (num2 < 45f || num2 > 315f)
366                         
367                             num6 = 20;
368                         
369                         if (num2 > 135f && num2 < 225f)
370                         
371                             num6 = 20;
372                         
373                         e.Graphics.DrawLine(pen, width * 2 / 3, 0, width + num6, 0);
374                         e.Graphics.TranslateTransform(width + num6, 0f);
375                         if (num2 - num3 < 5f)
376                         
377                         
378                         num3 = num2;
379                         if (num2 < 180f)
380                         
381                             e.Graphics.RotateTransform(num2 - 90f);
382                             e.Graphics.DrawLine(pen, 0f, 0f, num4, 0f);
383                             e.Graphics.DrawString(pieItems[i].Name, Font, solidBrush2, new Point(0, -Font.Height));
384                             if (IsRenderPercent)
385                             
386                                 e.Graphics.DrawString(string.Format(percenFormat, num5 * 100f / 360f), Font, percentBrush, new Point(0, 1));
387                             
388                             e.Graphics.RotateTransform(90f - num2);
389                         
390                         else
391                         
392                             e.Graphics.RotateTransform(num2 - 270f);
393                             e.Graphics.DrawLine(pen, 0f, 0f, num4, 0f);
394                             e.Graphics.TranslateTransform(num4 - 3f, 0f);
395                             e.Graphics.RotateTransform(180f);
396                             e.Graphics.DrawString(pieItems[i].Name, Font, solidBrush2, new Point(0, -Font.Height));
397                             if (IsRenderPercent)
398                             
399                                 e.Graphics.DrawString(string.Format(percenFormat, num5 * 100f / 360f), Font, percentBrush, new Point(0, 1));
400                             
401                             e.Graphics.RotateTransform(-180f);
402                             e.Graphics.TranslateTransform(0f - num4 + 3f, 0f);
403                             e.Graphics.RotateTransform(270f - num2);
404                         
405                         e.Graphics.TranslateTransform(-width - num6, 0f);
406                         e.Graphics.RotateTransform(0f - num5 / 2f);
407                         num2 += num5 / 2f;
408                     
409                     solidBrush.Dispose();
410                     pen.Dispose();
411                     solidBrush2.Dispose();
412                     percentBrush.Dispose();
413                 
414                 e.Graphics.ResetTransform();
415 
416                 if (centerOfCircleWidth > 0)
417                 
418                     Rectangle rectCenter = new Rectangle(rect.Left + rect.Width / 2 - centerOfCircleWidth / 2, rect.Top + rect.Height / 2 - centerOfCircleWidth / 2, centerOfCircleWidth, centerOfCircleWidth);
419                     e.Graphics.FillEllipse(new SolidBrush(centerOfCircleColor), rectCenter);
420                 
421             
422             else
423             
424                 e.Graphics.FillEllipse(Brushes.AliceBlue, rectangle);
425                 e.Graphics.DrawEllipse(Pens.DodgerBlue, rectangle);
426                 e.Graphics.DrawString("无数据", Font, Brushes.DimGray, rectangle, formatCenter);
427             
428             base.OnPaint(e);
429         
430         /// <summary>
431         /// Sets the data source.
432         /// </summary>
433         /// <param name="source">The source.</param>
434         public void SetDataSource(PieItem[] source)
435         
436             if (source != null)
437             
438                 DataSource = source;
439             
440         
441         /// <summary>
442         /// Sets the data source.
443         /// </summary>
444         /// <param name="names">The names.</param>
445         /// <param name="values">The values.</param>
446         /// <exception cref="System.ArgumentNullException">
447         /// names
448         /// or
449         /// values
450         /// </exception>
451         /// <exception cref="System.Exception">两个数组的长度不一致!</exception>
452         public void SetDataSource(string[] names, int[] values)
453         
454             if (names == null)
455             
456                 throw new ArgumentNullException("names");
457             
458             if (values == null)
459             
460                 throw new ArgumentNullException("values");
461             
462             if (names.Length != values.Length)
463             
464                 throw new Exception("两个数组的长度不一致!");
465             
466             pieItems = new PieItem[names.Length];
467             for (int i = 0; i < names.Length; i++)
468             
469                 pieItems[i] = new PieItem
470                 
471                     Name = names[i],
472                     Value = values[i]
473                 ;
474             
475             Invalidate();
476         
477 
478         /// <summary>
479         /// Releases unmanaged and - optionally - managed resources.
480         /// </summary>
481         /// <param name="disposing">为 true 则释放托管资源和非托管资源;为 false 则仅释放非托管资源。</param>
482         protected override void Dispose(bool disposing)
483         
484             if (disposing && components != null)
485             
486                 components.Dispose();
487             
488             base.Dispose(disposing);
489         
490 
491         /// <summary>
492         /// Initializes the component.
493         /// </summary>
494         private void InitializeComponent()
495         
496             SuspendLayout();
497             base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
498             BackColor = System.Drawing.Color.Transparent;
499             base.Name = "UCPieChart";
500             ResumeLayout(false);
501         
502     
503 
View Code

 

最后的话

如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧

以上是关于(七十)c#Winform自定义控件-饼状图的主要内容,如果未能解决你的问题,请参考以下文章

自定义控件练习:饼状图

(七十二)c#Winform自定义控件-雷达图

Android之自定义控件实现天气温度折线图和饼状图

在winform中如何生成饼状图和柱状图?

如何在C#的WinForm中制作饼状图和柱状图

Qt编写自定义控件41-自定义环形图