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

    用处及效果

    调用示例

     1  this.ucBarChart1.SetDataSource(new double[] { random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100) });
     2             this.ucBarChart2.SetDataSource(new double[] { random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100) }, new string[] { "张三", "李四", "王五", "赵六", "田七" });
     3             this.ucBarChart3.SetDataSource(new double[] { random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100) }, new string[] { "张三", "李四", "王五", "赵六", "田七" });
     4 
     5             this.ucBarChart4.SetDataSource(new double[] { random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100) }, new string[] { "张三", "李四", "王五", "赵六", "田七" });
     6             this.ucBarChart4.AddAuxiliaryLine(60, Color.Red, "及格线超长占位符");
     7 
     8             this.ucBarChart5.SetDataSource(new double[] { random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100) }, new string[] { "张三", "李四", "王五", "赵六", "田七" });
     9             this.ucBarChart5.AddAuxiliaryLine(50, Color.Black, "及格线");
    10 
    11            
    12             var ds = new double[5][];
    13             for (int i = 0; i < ds.Length; i++)
    14             {
    15                 ds[i] = new double[] { random.Next(50, 100), random.Next(50, 100), random.Next(50, 100) };
    16             }
    17             this.ucBarChart6.BarChartItems = new HZH_Controls.Controls.BarChartItem[] { new HZH_Controls.Controls.BarChartItem(Color.Red, "语文"), new HZH_Controls.Controls.BarChartItem(Color.Blue, "英语"), new HZH_Controls.Controls.BarChartItem(Color.Orange, "数学") };
    18             this.ucBarChart6.SetDataSource(ds, new string[] { "张三", "李四", "王五", "赵六", "田七" });
    19             this.ucBarChart6.AddAuxiliaryLine(60, Color.Black);
    20 
    21             var ds2 = new List<double[]>();
    22             for (int i = 0; i < 20; i++)
    23             {
    24                 ds2.Add(new double[] { random.Next(800, 2000), random.Next(100, 200) });
    25             }
    26             var titles = new List<string>();
    27             double dblSum = ds2.Sum(p=>p[0]);
    28             for (int i = 0; i < ds2.Count; i++)
    29             {
    30                 titles.Add("员工" + (i + 1) + "
    " + (ds2[i][0] / dblSum).ToString("0.0%"));
    31             }
    32             this.ucBarChart7.BarChartItems = new HZH_Controls.Controls.BarChartItem[] { new HZH_Controls.Controls.BarChartItem(Color.Green, "合格"), new HZH_Controls.Controls.BarChartItem(Color.Red, "次品") };
    33             this.ucBarChart7.SetDataSource(ds2.ToArray(), titles.ToArray());
    34             this.ucBarChart7.AddAuxiliaryLine(1000, Color.Black, "标准线");

    准备工作

    GDI画图,不懂可以先百度一下

    另外用到了(一)c#Winform自定义控件-基类控件 不知道的可以先前往看一下

    开始

    我们先理一下思路,

    我们需要值,x轴,y轴,辅助线,项列表,标题,以及一些颜色等

    添加一个类UCBarChart ,继承UCControlBase

    添加一些控制属性

      1 /// <summary>
      2         /// The auxiliary lines
      3         /// </summary>
      4         private List<AuxiliaryLine> auxiliary_lines;
      5 
      6         /// <summary>
      7         /// The value maximum left
      8         /// </summary>
      9         private int value_max_left = -1;
     10 
     11         /// <summary>
     12         /// The value minimum left
     13         /// </summary>
     14         private int value_min_left = 0;
     15 
     16         /// <summary>
     17         /// The value segment
     18         /// </summary>
     19         private int value_Segment = 5;
     20 
     21         /// <summary>
     22         /// The data values
     23         /// </summary>
     24         private double[][] data_values = null;
     25 
     26         /// <summary>
     27         /// The data texts
     28         /// </summary>
     29         private string[] data_texts = null;
     30 
     31         ///// <summary>
     32         ///// The data colors
     33         ///// </summary>
     34         //private Color[] data_colors = null;
     35 
     36         /// <summary>
     37         /// The brush deep
     38         /// </summary>
     39         private Brush brush_deep = null;
     40 
     41         /// <summary>
     42         /// The pen normal
     43         /// </summary>
     44         private Pen pen_normal = null;
     45 
     46         /// <summary>
     47         /// The pen dash
     48         /// </summary>
     49         private Pen pen_dash = null;
     50 
     51         /// <summary>
     52         /// The bar back color
     53         /// </summary>
     54         //private Color barBackColor = Color.FromArgb(255, 77, 59);
     55 
     56         /// <summary>
     57         /// The use gradient
     58         /// </summary>
     59         private bool useGradient = false;
     60 
     61         /// <summary>
     62         /// The color deep
     63         /// </summary>
     64         private Color color_deep = Color.FromArgb(150, 255, 77, 59);
     65 
     66         /// <summary>
     67         /// The color dash
     68         /// </summary>
     69         private Color color_dash = Color.FromArgb(50, 255, 77, 59);
     70 
     71         /// <summary>
     72         /// The format left
     73         /// </summary>
     74         private StringFormat format_left = null;
     75 
     76         /// <summary>
     77         /// The format right
     78         /// </summary>
     79         private StringFormat format_right = null;
     80 
     81         /// <summary>
     82         /// The format center
     83         /// </summary>
     84         private StringFormat format_center = null;
     85 
     86         /// <summary>
     87         /// The value is render dash line
     88         /// </summary>
     89         private bool value_IsRenderDashLine = true;
     90 
     91         /// <summary>
     92         /// The is show bar value
     93         /// </summary>
     94         private bool isShowBarValue = true;
     95 
     96         /// <summary>
     97         /// The show bar value format
     98         /// </summary>
     99         private string showBarValueFormat = "{0}";
    100 
    101         /// <summary>
    102         /// The value title
    103         /// </summary>
    104         private string value_title = "";
    105 
    106         /// <summary>
    107         /// The bar percent width
    108         /// </summary>
    109         private float barPercentWidth = 0.9f;
    110 
    111         /// <summary>
    112         /// The components
    113         /// </summary>
    114         private IContainer components = null;
    115 
    116         /// <summary>
    117         /// 获取或设置控件的背景色。
    118         /// </summary>
    119         /// <value>The color of the back.</value>
    120         /// <PermissionSet>
    121         ///   <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
    122         /// </PermissionSet>
    123         [Browsable(true)]
    124         [Description("获取或设置控件的背景色")]
    125         [Category("自定义")]
    126         [DefaultValue(typeof(Color), "Transparent")]
    127         [EditorBrowsable(EditorBrowsableState.Always)]
    128         public override Color BackColor
    129         {
    130             get
    131             {
    132                 return base.BackColor;
    133             }
    134             set
    135             {
    136                 base.BackColor = value;
    137             }
    138         }
    139 
    140         /// <summary>
    141         /// Gets or sets the text.
    142         /// </summary>
    143         /// <value>The text.</value>
    144         [Browsable(true)]
    145         [Description("获取或设置当前控件的文本")]
    146         [Category("自定义")]
    147         [EditorBrowsable(EditorBrowsableState.Always)]
    148         [Bindable(true)]
    149         [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    150         public override string Text
    151         {
    152             get
    153             {
    154                 return base.Text;
    155             }
    156             set
    157             {
    158                 base.Text = value;
    159                 Invalidate();
    160             }
    161         }
    162 
    163         /// <summary>
    164         /// 获取或设置控件的前景色。
    165         /// </summary>
    166         /// <value>The color of the fore.</value>
    167         /// <PermissionSet>
    168         ///   <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
    169         /// </PermissionSet>
    170         [Browsable(true)]
    171         [Description("获取或设置控件的前景色")]
    172         [Category("自定义")]
    173         [EditorBrowsable(EditorBrowsableState.Always)]
    174         public override Color ForeColor
    175         {
    176             get
    177             {
    178                 return base.ForeColor;
    179             }
    180             set
    181             {
    182                 base.ForeColor = value;
    183             }
    184         }
    185 
    186         /// <summary>
    187         /// Gets or sets the color lines and text.
    188         /// </summary>
    189         /// <value>The color lines and text.</value>
    190         [Category("自定义")]
    191         [Description("获取或设置坐标轴及相关信息文本的颜色")]
    192         [Browsable(true)]
    193         [DefaultValue(typeof(Color), "DimGray")]
    194         public Color ColorLinesAndText
    195         {
    196             get
    197             {
    198                 return color_deep;
    199             }
    200             set
    201             {
    202                 color_deep = value;
    203                 InitializationColor();
    204                 Invalidate();
    205             }
    206         }
    207 
    208         /// <summary>
    209         /// Gets or sets a value indicating whether [use gradient].
    210         /// </summary>
    211         /// <value><c>true</c> if [use gradient]; otherwise, <c>false</c>.</value>
    212         [Category("自定义")]
    213         [Description("获取或设置本条形图控件是否使用渐进色")]
    214         [Browsable(true)]
    215         [DefaultValue(false)]
    216         public bool UseGradient
    217         {
    218             get
    219             {
    220                 return useGradient;
    221             }
    222             set
    223             {
    224                 useGradient = value;
    225                 Invalidate();
    226             }
    227         }
    228 
    229         /// <summary>
    230         /// Gets or sets the color dash lines.
    231         /// </summary>
    232         /// <value>The color dash lines.</value>
    233         [Category("自定义")]
    234         [Description("获取或设置虚线的颜色")]
    235         [Browsable(true)]
    236         [DefaultValue(typeof(Color), "LightGray")]
    237         public Color ColorDashLines
    238         {
    239             get
    240             {
    241                 return color_dash;
    242             }
    243             set
    244             {
    245                 color_dash = value;
    246                 if (pen_dash != null)
    247                     pen_dash.Dispose();
    248                 pen_dash = new Pen(color_dash);
    249                 Invalidate();
    250             }
    251         }
    252 
    253         /// <summary>
    254         /// Gets or sets a value indicating whether this instance is render dash line.
    255         /// </summary>
    256         /// <value><c>true</c> if this instance is render dash line; otherwise, <c>false</c>.</value>
    257         [Category("自定义")]
    258         [Description("获取或设置虚线是否进行显示")]
    259         [Browsable(true)]
    260         [DefaultValue(true)]
    261         public bool IsRenderDashLine
    262         {
    263             get
    264             {
    265                 return value_IsRenderDashLine;
    266             }
    267             set
    268             {
    269                 value_IsRenderDashLine = value;
    270                 Invalidate();
    271             }
    272         }
    273 
    274         /// <summary>
    275         /// Gets or sets the value segment.
    276         /// </summary>
    277         /// <value>The value segment.</value>
    278         [Category("自定义")]
    279         [Description("获取或设置图形的纵轴分段数")]
    280         [Browsable(true)]
    281         [DefaultValue(5)]
    282         public int ValueSegment
    283         {
    284             get
    285             {
    286                 return value_Segment;
    287             }
    288             set
    289             {
    290                 value_Segment = value;
    291                 Invalidate();
    292             }
    293         }
    294 
    295         /// <summary>
    296         /// Gets or sets the value maximum left.
    297         /// </summary>
    298         /// <value>The value maximum left.</value>
    299         [Category("自定义")]
    300         [Description("获取或设置图形的左纵坐标的最大值,该值必须大于最小值,该值为负数,最大值即为自动适配。")]
    301         [Browsable(true)]
    302         [DefaultValue(-1)]
    303         public int ValueMaxLeft
    304         {
    305             get
    306             {
    307                 return value_max_left;
    308             }
    309             set
    310             {
    311                 value_max_left = value;
    312                 Invalidate();
    313             }
    314         }
    315 
    316         /// <summary>
    317         /// Gets or sets the value minimum left.
    318         /// </summary>
    319         /// <value>The value minimum left.</value>
    320         [Category("自定义")]
    321         [Description("获取或设置图形的左纵坐标的最小值,该值必须小于最大值")]
    322         [Browsable(true)]
    323         [DefaultValue(0)]
    324         public int ValueMinLeft
    325         {
    326             get
    327             {
    328                 return value_min_left;
    329             }
    330             set
    331             {
    332                 if (value < value_max_left)
    333                 {
    334                     value_min_left = value;
    335                     Invalidate();
    336                 }
    337             }
    338         }
    339 
    340         /// <summary>
    341         /// Gets or sets the title.
    342         /// </summary>
    343         /// <value>The title.</value>
    344         [Category("自定义")]
    345         [Description("获取或设置图标的标题信息")]
    346         [Browsable(true)]
    347         [DefaultValue("")]
    348         public string Title
    349         {
    350             get
    351             {
    352                 return value_title;
    353             }
    354             set
    355             {
    356                 value_title = value;
    357                 Invalidate();
    358             }
    359         }
    360 
    361         /// <summary>
    362         /// Gets or sets a value indicating whether this instance is show bar value.
    363         /// </summary>
    364         /// <value><c>true</c> if this instance is show bar value; otherwise, <c>false</c>.</value>
    365         [Category("自定义")]
    366         [Description("获取或设置是否显示柱状图的值文本")]
    367         [Browsable(true)]
    368         [DefaultValue(true)]
    369         public bool IsShowBarValue
    370         {
    371             get
    372             {
    373                 return isShowBarValue;
    374             }
    375             set
    376             {
    377                 isShowBarValue = value;
    378                 Invalidate();
    379             }
    380         }
    381 
    382         /// <summary>
    383         /// Gets or sets the show bar value format.
    384         /// </summary>
    385         /// <value>The show bar value format.</value>
    386         [Category("自定义")]
    387         [Description("获取或设置柱状图显示值的格式化信息,可以带单位")]
    388         [Browsable(true)]
    389         [DefaultValue("")]
    390         public string ShowBarValueFormat
    391         {
    392             get
    393             {
    394                 return showBarValueFormat;
    395             }
    396             set
    397             {
    398                 showBarValueFormat = value;
    399                 Invalidate();
    400             }
    401         }
    402 
    403         private BarChartItem[] barChartItems = new BarChartItem[] { new BarChartItem() };
    404         [Category("自定义")]
    405         [Description("获取或设置柱状图的项目")]
    406         [Browsable(true)]
    407         public BarChartItem[] BarChartItems
    408         {
    409             get { return barChartItems; }
    410             set { barChartItems = value; }
    411         }
    412         [Category("自定义")]
    413         [Description("获取或设置是否显示柱状图的项目名称")]
    414         [Browsable(true)]
    415         public bool ShowChartItemName { get; set; }

    做一些初始化数据

     1  public UCBarChart()
     2         {
     3             InitializeComponent();
     4             ConerRadius = 10;
     5             ForeColor = Color.FromArgb(150, 255, 77, 59);
     6             FillColor = Color.FromArgb(243, 220, 219);
     7             format_left = new StringFormat
     8             {
     9                 LineAlignment = StringAlignment.Center,
    10                 Alignment = StringAlignment.Near
    11             };
    12             format_right = new StringFormat
    13             {
    14                 LineAlignment = StringAlignment.Center,
    15                 Alignment = StringAlignment.Far
    16             };
    17             format_center = new StringFormat
    18             {
    19                 LineAlignment = StringAlignment.Center,
    20                 Alignment = StringAlignment.Center
    21             };
    22             auxiliary_lines = new List<AuxiliaryLine>();
    23             pen_dash = new Pen(color_dash);
    24             pen_dash.DashStyle = DashStyle.Custom;
    25             pen_dash.DashPattern = new float[2]
    26             {
    27                 5f,
    28                 5f
    29             };
    30             InitializationColor();
    31             SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
    32             SetStyle(ControlStyles.ResizeRedraw, true);
    33             SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    34             SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    35 
    36             if (DesignMode)
    37             {
    38                 barChartItems = new BarChartItem[] { new BarChartItem() };
    39 
    40                 data_values = new double[5][];
    41                 for (int i = 0; i < data_values.Length; i++)
    42                 {
    43                     data_values[i] = new double[] { i + 1 };
    44                 }
    45             }
    46 
    47         }

    设置数据源的函数

     1 /// <summary>
     2         /// Sets the data source.
     3         /// </summary>
     4         /// <param name="data">The data.</param>
     5         public void SetDataSource(double[] data)
     6         {
     7             SetDataSource(data, null);
     8         }
     9 
    10         public void SetDataSource(double[][] data)
    11         {
    12             SetDataSource(data, null);
    13         }
    14         /// <summary>
    15         /// Sets the data source.
    16         /// </summary>
    17         /// <param name="data">The data.</param>
    18         /// <param name="texts">X texts</param>
    19         public void SetDataSource(double[] data, string[] texts)
    20         {
    21             data_values = new double[data.Length][];
    22             for (int i = 0; i < data.Length; i++)
    23             {
    24                 data_values[i] = new double[] { data[i] };
    25             }
    26             if (barChartItems == null || barChartItems.Length <= 0)
    27                 barChartItems = new BarChartItem[] { new BarChartItem() };
    28             data_texts = texts;
    29             Invalidate();
    30         }
    31         public void SetDataSource(double[][] data, string[] texts)
    32         {
    33             data_values = data;
    34             if (barChartItems == null || barChartItems.Length <= 0)
    35                 barChartItems = new BarChartItem[] { new BarChartItem() };
    36             data_texts = texts;
    37             Invalidate();
    38         }

    重绘

      1 protected override void OnPaint(PaintEventArgs e)
      2         {
      3             base.OnPaint(e);
      4             Graphics graphics = e.Graphics;
      5             graphics.SmoothingMode = SmoothingMode.HighQuality;
      6             graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
      7             PaintMain(graphics, base.Width, base.Height);
      8         }
      9 
     10         /// <summary>
     11         /// Paints the main.
     12         /// </summary>
     13         /// <param name="g">The g.</param>
     14         /// <param name="width">The width.</param>
     15         /// <param name="height">The height.</param>
     16         private void PaintMain(Graphics g, int width, int height)
     17         {
     18             if (barChartItems == null || barChartItems.Length <= 0)
     19             {
     20                 if (DesignMode)
     21                 {
     22                     barChartItems = new BarChartItem[] { new BarChartItem() };
     23                 }
     24                 else
     25                 {
     26                     return;
     27                 }
     28             }
     29             if (data_values == null && DesignMode)
     30             {
     31                 data_values = new double[5][];
     32                 for (int i = 0; i < data_values.Length; i++)
     33                 {
     34                     data_values[i] = new double[] { i + 1 };
     35                 }
     36             }
     37 
     38             double num = (data_values != null && data_values.Length != 0) ? ChartsHelper.CalculateMaxSectionFrom(data_values) : 5;
     39             if (value_max_left > 0)
     40             {
     41                 num = value_max_left;
     42             }
     43             int intLeftX = (int)g.MeasureString(num.ToString(), Font).Width + 3;
     44             if (intLeftX < 50)
     45             {
     46                 intLeftX = 50;
     47             }
     48             //处理辅助线左侧间距
     49             if (auxiliary_lines != null && auxiliary_lines.Count > 0)
     50             {
     51                 var maxAuxiliaryWidth = auxiliary_lines.Max(p => g.MeasureString((p.Tip + "" + p.Value), Font).Width);
     52                 if (intLeftX < maxAuxiliaryWidth)
     53                 {
     54                     intLeftX = (int)maxAuxiliaryWidth + 5;
     55                 }
     56             }
     57             int intRightX = 20;
     58             //顶部距离
     59             int intTopY = 25;
     60             if (!string.IsNullOrEmpty(value_title))
     61             {
     62                 intTopY += 20;
     63             }
     64             //写标题
     65             if (!string.IsNullOrEmpty(value_title))
     66             {
     67                 g.DrawString(value_title, Font, brush_deep, new Rectangle(0, 0, width - 1, intTopY - 10), format_center);
     68             }
     69             //画项目名称颜色
     70             if (ShowChartItemName && !(barChartItems.Length == 1 && string.IsNullOrEmpty(barChartItems[0].ItemName)))
     71             {
     72                 int intItemNameRowCount = 0;
     73                 int intItemNameWidth = 0;
     74                 int intItemNameComCount = 0;
     75 
     76                 intItemNameWidth = (int)barChartItems.Max(p => g.MeasureString(p.ItemName, Font).Width) + 40;
     77                 intItemNameComCount = this.Width / intItemNameWidth;
     78                 intItemNameRowCount = barChartItems.Length / intItemNameComCount + (barChartItems.Length % intItemNameComCount != 0 ? 1 : 0);
     79                 int intItemNameHeight = (int)g.MeasureString("A", Font).Height;
     80 
     81                 for (int i = 0; i < intItemNameRowCount; i++)
     82                 {
     83                     int intLeft = (this.Width - (intItemNameWidth * ((i == intItemNameRowCount - 1) ? (barChartItems.Length % intItemNameComCount) : intItemNameComCount))) / 2;
     84                     int intTop = intTopY - 15 + intItemNameHeight * i + 10;
     85                     for (int j = i * intItemNameComCount; j < barChartItems.Length && j < (i + 1) * intItemNameComCount; j++)
     86                     {
     87                         Rectangle rectColor = new Rectangle(intLeft + (j % intItemNameComCount) * intItemNameWidth, intTop, 20, intItemNameHeight);
     88                         g.FillRectangle(new SolidBrush(barChartItems[j].BarBackColor), rectColor);
     89                         g.DrawString(barChartItems[j].ItemName, Font, new SolidBrush(ForeColor), new Point(rectColor.Right + 2, rectColor.Top));
     90                     }
     91                 }
     92                 intTopY += intItemNameRowCount * (intItemNameHeight + 20);
     93             }
     94 
     95             int intBottomY = 25;
     96             //处理x坐标文字高度
     97             if (data_texts != null && data_texts.Length > 0)
     98             {
     99                 var maxTextsHeight = data_texts.Max(p => g.MeasureString(p, Font).Height);
    100                 if (intBottomY < maxTextsHeight)
    101                     intBottomY = (int)maxTextsHeight + 5;
    102             }
    103             //画xy轴
    104             Point[] array2 = new Point[3]
    105             {
    106                 new Point(intLeftX, intTopY - 8),
    107                 new Point(intLeftX, height - intBottomY),
    108                 new Point(width - intRightX+5, height - intBottomY)
    109             };
    110             g.DrawLine(pen_normal, array2[0], array2[1]);
    111             g.DrawLine(pen_normal, array2[1], array2[2]);
    112             ChartsHelper.PaintTriangle(g, brush_deep, new Point(intLeftX, intTopY - 8), 4, GraphDirection.Upward);
    113             ChartsHelper.PaintTriangle(g, brush_deep, new Point(width - intRightX + 5, height - intBottomY), 4, GraphDirection.Rightward);
    114 
    115 
    116             //画横向分割线
    117             for (int j = 0; j <= value_Segment; j++)
    118             {
    119                 float value = (float)((double)j * (double)(num - value_min_left) / (double)value_Segment + (double)value_min_left);
    120                 float num6 = ChartsHelper.ComputePaintLocationY((float)num, value_min_left, height - intTopY - intBottomY, value) + (float)intTopY;
    121                 if (IsNeedPaintDash(num6))
    122                 {
    123                     g.DrawLine(pen_normal, intLeftX - 4, num6, intLeftX - 1, num6);
    124                     g.DrawString(layoutRectangle: new RectangleF(0f, num6 - 19f, intLeftX - 4, 40f), s: value.ToString(), font: Font,  brush_deep, format: format_right);
    125                     if (j > 0 && value_IsRenderDashLine)
    126                     {
    127                         g.DrawLine(pen_dash, intLeftX, num6, width - intRightX, num6);
    128                     }
    129                 }
    130             }
    131             //计算辅助线y坐标
    132             for (int i = 0; i < auxiliary_lines.Count; i++)
    133             {
    134                 auxiliary_lines[i].PaintValue = ChartsHelper.ComputePaintLocationY((float)num, value_min_left, height - intTopY - intBottomY, auxiliary_lines[i].Value) + (float)intTopY;
    135             }
    136 
    137             //画辅助线
    138             for (int k = 0; k < auxiliary_lines.Count; k++)
    139             {
    140                 g.DrawLine(auxiliary_lines[k].GetPen(), intLeftX - 4, auxiliary_lines[k].PaintValue, intLeftX - 1, auxiliary_lines[k].PaintValue);
    141                 g.DrawString(layoutRectangle: new RectangleF(0f, auxiliary_lines[k].PaintValue - 9f, intLeftX - 4, 20f), s: auxiliary_lines[k].Tip + "" + auxiliary_lines[k].Value.ToString(), font: Font,  auxiliary_lines[k].LineTextBrush, format: format_right);
    142                 g.DrawLine(auxiliary_lines[k].GetPen(), intLeftX, auxiliary_lines[k].PaintValue, width - intRightX, auxiliary_lines[k].PaintValue);
    143             }
    144             if (data_values == null || data_values.Length == 0 || data_values.Max(p => p.Length) <= 0)
    145             {
    146                 return;
    147             }
    148 
    149             //x轴分隔宽度
    150             float fltSplitWidth = (float)(width - intLeftX - 1 - intRightX) * 1f / (float)data_values.Length;
    151             for (int i = 0; i < data_values.Length; i++)
    152             {
    153                 int intItemSplitCount = barChartItems.Length;
    154                 float _fltSplitWidth = fltSplitWidth * barPercentWidth / intItemSplitCount;
    155                 float _fltLeft = (float)i * fltSplitWidth + (1f - barPercentWidth) / 2f * fltSplitWidth + (float)intLeftX;
    156                 for (int j = 0; j < data_values[i].Length; j++)
    157                 {
    158                     if (j >= intItemSplitCount)
    159                     {
    160                         break;
    161                     }
    162                     float fltValueY = ChartsHelper.ComputePaintLocationY((float)num, value_min_left, height - intTopY - intBottomY, (float)data_values[i][j]) + (float)intTopY;
    163 
    164 
    165                     RectangleF rect = new RectangleF(_fltLeft + _fltSplitWidth * j + (1F - barChartItems[j].BarPercentWidth) * _fltSplitWidth / 2f, fltValueY,
    166                     _fltSplitWidth * barChartItems[j].BarPercentWidth, (float)(height - intBottomY) - fltValueY);
    167 
    168                     Color color = barChartItems[j].BarBackColor;
    169 
    170                     //画柱状
    171                     if (useGradient)
    172                     {
    173                         if (rect.Height > 0f)
    174                         {
    175                             using (LinearGradientBrush brush = new LinearGradientBrush(new PointF(rect.X, rect.Y + rect.Height), new PointF(rect.X, rect.Y), ChartsHelper.GetColorLight(color), color))
    176                             {
    177                                 g.FillRectangle(brush, rect);
    178                             }
    179                         }
    180                     }
    181                     else
    182                     {
    183                         using (Brush brush2 = new SolidBrush(color))
    184                         {
    185                             g.FillRectangle(brush2, rect);
    186                         }
    187                     }
    188                     //写值文字
    189                     if (isShowBarValue)
    190                     {
    191                         using (Brush brush3 = new SolidBrush(ForeColor))
    192                         {
    193                             g.DrawString(layoutRectangle: new RectangleF(rect.Left - 50f, fltValueY - (float)Font.Height - 2f, _fltSplitWidth + 100f, Font.Height + 2), s: string.Format(showBarValueFormat, data_values[i][j]), font: Font,  brush3, format: format_center);
    194                         }
    195                     }
    196                 }
    197 
    198                 //写x轴文字
    199                 if (data_texts != null && i < data_texts.Length)
    200                 {
    201                     g.DrawString(layoutRectangle: new RectangleF((float)i * fltSplitWidth + (float)intLeftX - 50f, height - intBottomY - 1, fltSplitWidth + 100f, intBottomY + 1), s: data_texts[i], font: Font,  brush_deep, format: format_center);
    202                 }
    203             }
    204         }

    辅助线相关函数

     1 #region 辅助线    English:Guide
     2         /// <summary>
     3         /// Adds the left auxiliary.
     4         /// </summary>
     5         /// <param name="value">The value.</param>
     6         public void AddAuxiliaryLine(float value, string strTip = "")
     7         {
     8             AddAuxiliaryLine(value, ColorLinesAndText, strTip);
     9         }
    10 
    11         /// <summary>
    12         /// Adds the left auxiliary.
    13         /// </summary>
    14         /// <param name="value">The value.</param>
    15         /// <param name="lineColor">Color of the line.</param>
    16         public void AddAuxiliaryLine(float value, Color lineColor, string strTip = "")
    17         {
    18             AddAuxiliaryLine(value, lineColor, 1f, true, strTip);
    19         }
    20 
    21         /// <summary>
    22         /// Adds the left auxiliary.
    23         /// </summary>
    24         /// <param name="value">The value.</param>
    25         /// <param name="lineColor">Color of the line.</param>
    26         /// <param name="lineThickness">The line thickness.</param>
    27         /// <param name="isDashLine">if set to <c>true</c> [is dash line].</param>
    28         public void AddAuxiliaryLine(float value, Color lineColor, float lineThickness, bool isDashLine, string strTip = "")
    29         {
    30             AddAuxiliary(value, lineColor, lineThickness, isDashLine, strTip);
    31         }
    32 
    33         /// <summary>
    34         /// Adds the auxiliary.
    35         /// </summary>
    36         /// <param name="value">The value.</param>
    37         /// <param name="lineColor">Color of the line.</param>
    38         /// <param name="lineThickness">The line thickness.</param>
    39         /// <param name="isDashLine">if set to <c>true</c> [is dash line].</param>
    40         /// <param name="isLeft">if set to <c>true</c> [is left].</param>
    41         private void AddAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine, string strTip = "")
    42         {
    43             auxiliary_lines.Add(new AuxiliaryLine
    44             {
    45                 Value = value,
    46                 LineColor = lineColor,
    47                 PenDash = new Pen(lineColor)
    48                 {
    49                     DashStyle = DashStyle.Custom,
    50                     DashPattern = new float[2]
    51                     {
    52                         5f,
    53                         5f
    54                     }
    55                 },
    56                 PenSolid = new Pen(lineColor),
    57                 IsDashStyle = isDashLine,
    58                 LineThickness = lineThickness,
    59                 LineTextBrush = new SolidBrush(lineColor),
    60                 Tip = strTip
    61             });
    62             Invalidate();
    63         }
    64 
    65         /// <summary>
    66         /// Removes the auxiliary.
    67         /// </summary>
    68         /// <param name="value">The value.</param>
    69         public void RemoveAuxiliary(float value)
    70         {
    71             int num = 0;
    72             for (int num2 = auxiliary_lines.Count - 1; num2 >= 0; num2--)
    73             {
    74                 if (auxiliary_lines[num2].Value == value)
    75                 {
    76                     auxiliary_lines[num2].Dispose();
    77                     auxiliary_lines.RemoveAt(num2);
    78                     num++;
    79                 }
    80             }
    81             if (num > 0)
    82             {
    83                 Invalidate();
    84             }
    85         }
    86 
    87         /// <summary>
    88         /// Removes all auxiliary.
    89         /// </summary>
    90         public void RemoveAllAuxiliary()
    91         {
    92             int count = auxiliary_lines.Count;
    93             auxiliary_lines.Clear();
    94             if (count > 0)
    95             {
    96                 Invalidate();
    97             }
    98         }
    99         #endregion

    完整代码,请前往开源地址查看吧。

    最后的话

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

  • 相关阅读:
    Python 中的 None 与真假
    AVR第5课:蜂鸣器
    Solr使用入门指南
    EJB究竟是什么,真的那么神奇吗??
    Android 各个版本号WebView
    android SQLite 使用实例
    BackTrack5 (BT5)无线password破解教程之WPA/WPA2-PSK型无线password破解
    腾讯QQ企业邮箱POP3/SMTP设置
    【LeetCode】Substring with Concatenation of All Words
    PreferenceFragment 使用 小结
  • 原文地址:https://www.cnblogs.com/bfyx/p/11534077.html
Copyright © 2011-2022 走看看