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 点个星星吧

  • 相关阅读:
    LOJ 6089 小Y的背包计数问题 —— 前缀和优化DP
    洛谷 P1969 积木大赛 —— 水题
    洛谷 P1965 转圈游戏 —— 快速幂
    洛谷 P1970 花匠 —— DP
    洛谷 P1966 火柴排队 —— 思路
    51Nod 1450 闯关游戏 —— 期望DP
    洛谷 P2312 & bzoj 3751 解方程 —— 取模
    洛谷 P1351 联合权值 —— 树形DP
    NOIP2007 树网的核
    平面最近点对(加强版)
  • 原文地址:https://www.cnblogs.com/bfyx/p/11534077.html
Copyright © 2011-2022 走看看