zoukankan      html  css  js  c++  java
  • (七十)c#Winform自定义控件-饼状图-HZHControls

    官网

    http://www.hzhcontrols.com

    前提

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

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

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

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

    欢迎前来交流探讨: 企鹅群568015492 企鹅群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 点个星星吧

  • 相关阅读:
    Java实现 LeetCode 132 分割回文串 II(二)
    Java实现 蓝桥杯 算法提高 宰羊
    Java实现 蓝桥杯 算法提高 宰羊
    Java实现 蓝桥杯 算法提高 宰羊
    Java实现 蓝桥杯 算法提高 秘密行动
    Java实现 蓝桥杯 算法提高 秘密行动
    在VC下显示JPEG、GIF格式图像的一种简便方法
    vc 基于对话框多线程编程实例——线程之间的通信
    VC/MFC 编程技巧大总结
    VC 获取指定文件夹路径的方法小结
  • 原文地址:https://www.cnblogs.com/bfyx/p/11572058.html
Copyright © 2011-2022 走看看