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+相关知识

    开始

    添加一个类UCCurve 继承自UserControl

    添加一些控制属性

      1 /// <summary>
      2         /// The value count maximum
      3         /// </summary>
      4         private const int value_count_max = 4096;
      5 
      6         /// <summary>
      7         /// The value maximum left
      8         /// </summary>
      9         private float value_max_left = 100f;
     10 
     11         /// <summary>
     12         /// The value minimum left
     13         /// </summary>
     14         private float value_min_left = 0f;
     15 
     16         /// <summary>
     17         /// The value maximum right
     18         /// </summary>
     19         private float value_max_right = 100f;
     20 
     21         /// <summary>
     22         /// The value minimum right
     23         /// </summary>
     24         private float value_min_right = 0f;
     25 
     26         /// <summary>
     27         /// The value segment
     28         /// </summary>
     29         private int value_Segment = 5;
     30 
     31         /// <summary>
     32         /// The value is abscissa strech
     33         /// </summary>
     34         private bool value_IsAbscissaStrech = false;
     35 
     36         /// <summary>
     37         /// The value strech data count maximum
     38         /// </summary>
     39         private int value_StrechDataCountMax = 300;
     40 
     41         /// <summary>
     42         /// The value is render dash line
     43         /// </summary>
     44         private bool value_IsRenderDashLine = true;
     45 
     46         /// <summary>
     47         /// The text format
     48         /// </summary>
     49         private string textFormat = "HH:mm";
     50 
     51         /// <summary>
     52         /// The value interval abscissa text
     53         /// </summary>
     54         private int value_IntervalAbscissaText = 100;
     55 
     56         /// <summary>
     57         /// The random
     58         /// </summary>
     59         private Random random = null;
     60 
     61         /// <summary>
     62         /// The value title
     63         /// </summary>
     64         private string value_title = "";
     65 
     66         /// <summary>
     67         /// The left right
     68         /// </summary>
     69         private int leftRight = 50;
     70 
     71         /// <summary>
     72         /// Up dowm
     73         /// </summary>
     74         private int upDowm = 50;
     75 
     76         /// <summary>
     77         /// The data list
     78         /// </summary>
     79         private Dictionary<string, CurveItem> data_list = null;
     80 
     81         /// <summary>
     82         /// The data text
     83         /// </summary>
     84         private string[] data_text = null;
     85 
     86         /// <summary>
     87         /// The auxiliary lines
     88         /// </summary>
     89         private List<AuxiliaryLine> auxiliary_lines;
     90 
     91         /// <summary>
     92         /// The auxiliary labels
     93         /// </summary>
     94         private List<AuxiliaryLable> auxiliary_Labels;
     95 
     96         /// <summary>
     97         /// The mark texts
     98         /// </summary>
     99         private List<MarkText> MarkTexts;
    100 
    101         /// <summary>
    102         /// The font size9
    103         /// </summary>
    104         private Font font_size9 = null;
    105 
    106         /// <summary>
    107         /// The font size12
    108         /// </summary>
    109         private Font font_size12 = null;
    110 
    111         /// <summary>
    112         /// The brush deep
    113         /// </summary>
    114         private Brush brush_deep = null;
    115 
    116         /// <summary>
    117         /// The pen normal
    118         /// </summary>
    119         private Pen pen_normal = null;
    120 
    121         /// <summary>
    122         /// The pen dash
    123         /// </summary>
    124         private Pen pen_dash = null;
    125 
    126         /// <summary>
    127         /// The color normal
    128         /// </summary>
    129         private Color color_normal = Color.DeepPink;
    130 
    131         /// <summary>
    132         /// The color deep
    133         /// </summary>
    134         private Color color_deep = Color.DimGray;
    135 
    136         /// <summary>
    137         /// The color dash
    138         /// </summary>
    139         private Color color_dash = Color.FromArgb(232, 232, 232);
    140 
    141         /// <summary>
    142         /// The color mark font
    143         /// </summary>
    144         private Color color_mark_font = Color.DodgerBlue;
    145 
    146         /// <summary>
    147         /// The brush mark font
    148         /// </summary>
    149         private Brush brush_mark_font = Brushes.DodgerBlue;
    150 
    151         /// <summary>
    152         /// The format left
    153         /// </summary>
    154         private StringFormat format_left = null;
    155 
    156         /// <summary>
    157         /// The format right
    158         /// </summary>
    159         private StringFormat format_right = null;
    160 
    161         /// <summary>
    162         /// The format center
    163         /// </summary>
    164         private StringFormat format_center = null;
    165 
    166         /// <summary>
    167         /// The is render right coordinate
    168         /// </summary>
    169         private bool isRenderRightCoordinate = true;
    170 
    171         /// <summary>
    172         /// The curve name width
    173         /// </summary>
    174         private int curveNameWidth = 100;
    175 
    176         /// <summary>
    177         /// The components
    178         /// </summary>
    179         private IContainer components = null;
    180 
    181         /// <summary>
    182         /// 获取或设置控件的背景色。
    183         /// </summary>
    184         /// <value>The color of the back.</value>
    185         /// <PermissionSet>
    186         ///   <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
    187         /// </PermissionSet>
    188         [Browsable(true)]
    189         [Description("获取或设置控件的背景色")]
    190         [Category("自定义")]
    191         [DefaultValue(typeof(Color), "Transparent")]
    192         [EditorBrowsable(EditorBrowsableState.Always)]
    193         public override Color BackColor
    194         {
    195             get
    196             {
    197                 return base.BackColor;
    198             }
    199             set
    200             {
    201                 base.BackColor = value;
    202             }
    203         }
    204 
    205         /// <summary>
    206         /// Gets or sets the value maximum left.
    207         /// </summary>
    208         /// <value>The value maximum left.</value>
    209         [Category("自定义")]
    210         [Description("获取或设置图形的左纵坐标的最大值,该值必须大于最小值")]
    211         [Browsable(true)]
    212         [DefaultValue(100f)]
    213         public float ValueMaxLeft
    214         {
    215             get
    216             {
    217                 return value_max_left;
    218             }
    219             set
    220             {
    221                 value_max_left = value;
    222                 Invalidate();
    223             }
    224         }
    225 
    226         /// <summary>
    227         /// Gets or sets the value minimum left.
    228         /// </summary>
    229         /// <value>The value minimum left.</value>
    230         [Category("自定义")]
    231         [Description("获取或设置图形的左纵坐标的最小值,该值必须小于最大值")]
    232         [Browsable(true)]
    233         [DefaultValue(0f)]
    234         public float ValueMinLeft
    235         {
    236             get
    237             {
    238                 return value_min_left;
    239             }
    240             set
    241             {
    242                 value_min_left = value;
    243                 Invalidate();
    244             }
    245         }
    246 
    247         /// <summary>
    248         /// Gets or sets the value maximum right.
    249         /// </summary>
    250         /// <value>The value maximum right.</value>
    251         [Category("自定义")]
    252         [Description("获取或设置图形的右纵坐标的最大值,该值必须大于最小值")]
    253         [Browsable(true)]
    254         [DefaultValue(100f)]
    255         public float ValueMaxRight
    256         {
    257             get
    258             {
    259                 return value_max_right;
    260             }
    261             set
    262             {
    263                 value_max_right = value;
    264                 Invalidate();
    265             }
    266         }
    267 
    268         /// <summary>
    269         /// Gets or sets the value minimum right.
    270         /// </summary>
    271         /// <value>The value minimum right.</value>
    272         [Category("自定义")]
    273         [Description("获取或设置图形的右纵坐标的最小值,该值必须小于最大值")]
    274         [Browsable(true)]
    275         [DefaultValue(0f)]
    276         public float ValueMinRight
    277         {
    278             get
    279             {
    280                 return value_min_right;
    281             }
    282             set
    283             {
    284                 value_min_right = value;
    285                 Invalidate();
    286             }
    287         }
    288 
    289         /// <summary>
    290         /// Gets or sets the value segment.
    291         /// </summary>
    292         /// <value>The value segment.</value>
    293         [Category("自定义")]
    294         [Description("获取或设置图形的纵轴分段数")]
    295         [Browsable(true)]
    296         [DefaultValue(5)]
    297         public int ValueSegment
    298         {
    299             get
    300             {
    301                 return value_Segment;
    302             }
    303             set
    304             {
    305                 value_Segment = value;
    306                 Invalidate();
    307             }
    308         }
    309 
    310         /// <summary>
    311         /// Gets or sets a value indicating whether this instance is abscissa strech.
    312         /// </summary>
    313         /// <value><c>true</c> if this instance is abscissa strech; otherwise, <c>false</c>.</value>
    314         [Category("自定义")]
    315         [Description("获取或设置所有的数据是否强制在一个界面里显示")]
    316         [Browsable(true)]
    317         [DefaultValue(false)]
    318         public bool IsAbscissaStrech
    319         {
    320             get
    321             {
    322                 return value_IsAbscissaStrech;
    323             }
    324             set
    325             {
    326                 value_IsAbscissaStrech = value;
    327                 Invalidate();
    328             }
    329         }
    330 
    331         /// <summary>
    332         /// Gets or sets the strech data count maximum.
    333         /// </summary>
    334         /// <value>The strech data count maximum.</value>
    335         [Category("自定义")]
    336         [Description("获取或设置拉伸模式下的最大数据量")]
    337         [Browsable(true)]
    338         [DefaultValue(300)]
    339         public int StrechDataCountMax
    340         {
    341             get
    342             {
    343                 return value_StrechDataCountMax;
    344             }
    345             set
    346             {
    347                 value_StrechDataCountMax = value;
    348                 Invalidate();
    349             }
    350         }
    351 
    352         /// <summary>
    353         /// Gets or sets a value indicating whether this instance is render dash line.
    354         /// </summary>
    355         /// <value><c>true</c> if this instance is render dash line; otherwise, <c>false</c>.</value>
    356         [Category("自定义")]
    357         [Description("获取或设置虚线是否进行显示")]
    358         [Browsable(true)]
    359         [DefaultValue(true)]
    360         public bool IsRenderDashLine
    361         {
    362             get
    363             {
    364                 return value_IsRenderDashLine;
    365             }
    366             set
    367             {
    368                 value_IsRenderDashLine = value;
    369                 Invalidate();
    370             }
    371         }
    372 
    373         /// <summary>
    374         /// Gets or sets the color lines and text.
    375         /// </summary>
    376         /// <value>The color lines and text.</value>
    377         [Category("自定义")]
    378         [Description("获取或设置坐标轴及相关信息文本的颜色")]
    379         [Browsable(true)]
    380         [DefaultValue(typeof(Color), "DimGray")]
    381         public Color ColorLinesAndText
    382         {
    383             get
    384             {
    385                 return color_deep;
    386             }
    387             set
    388             {
    389                 color_deep = value;
    390                 InitializationColor();
    391                 Invalidate();
    392             }
    393         }
    394 
    395         /// <summary>
    396         /// Gets or sets the color dash lines.
    397         /// </summary>
    398         /// <value>The color dash lines.</value>
    399         [Category("自定义")]
    400         [Description("获取或设置虚线的颜色")]
    401         [Browsable(true)]
    402         public Color ColorDashLines
    403         {
    404             get
    405             {
    406                 return color_dash;
    407             }
    408             set
    409             {
    410                 color_dash = value;
    411                 if (pen_dash != null)
    412                     pen_dash.Dispose();
    413                 pen_dash = new Pen(color_dash);
    414                 pen_dash.DashStyle = DashStyle.Custom;
    415                 pen_dash.DashPattern = new float[2]
    416                 {
    417                     5f,
    418                     5f
    419                 };
    420                 Invalidate();
    421             }
    422         }
    423 
    424         /// <summary>
    425         /// Gets or sets the interval abscissa text.
    426         /// </summary>
    427         /// <value>The interval abscissa text.</value>
    428         [Category("自定义")]
    429         [Description("获取或设置纵向虚线的分隔情况,单位为多少个数据")]
    430         [Browsable(true)]
    431         [DefaultValue(100)]
    432         public int IntervalAbscissaText
    433         {
    434             get
    435             {
    436                 return value_IntervalAbscissaText;
    437             }
    438             set
    439             {
    440                 value_IntervalAbscissaText = value;
    441                 Invalidate();
    442             }
    443         }
    444 
    445         /// <summary>
    446         /// Gets or sets the text add format.
    447         /// </summary>
    448         /// <value>The text add format.</value>
    449         [Category("自定义")]
    450         [Description("获取或设置实时数据新增时文本相对应于时间的格式化字符串,默认HH:mm")]
    451         [Browsable(true)]
    452         [DefaultValue("HH:mm")]
    453         public string TextAddFormat
    454         {
    455             get
    456             {
    457                 return textFormat;
    458             }
    459             set
    460             {
    461                 textFormat = value;
    462                 Invalidate();
    463             }
    464         }
    465 
    466         /// <summary>
    467         /// Gets or sets the title.
    468         /// </summary>
    469         /// <value>The title.</value>
    470         [Category("自定义")]
    471         [Description("获取或设置图标的标题信息")]
    472         [Browsable(true)]
    473         [DefaultValue("")]
    474         public string Title
    475         {
    476             get
    477             {
    478                 return value_title;
    479             }
    480             set
    481             {
    482                 value_title = value;
    483                 Invalidate();
    484             }
    485         }
    486 
    487         /// <summary>
    488         /// Gets or sets a value indicating whether this instance is render right coordinate.
    489         /// </summary>
    490         /// <value><c>true</c> if this instance is render right coordinate; otherwise, <c>false</c>.</value>
    491         [Category("自定义")]
    492         [Description("获取或设置是否显示右侧的坐标系信息")]
    493         [Browsable(true)]
    494         [DefaultValue(true)]
    495         public bool IsRenderRightCoordinate
    496         {
    497             get
    498             {
    499                 return isRenderRightCoordinate;
    500             }
    501             set
    502             {
    503                 isRenderRightCoordinate = value;
    504                 Invalidate();
    505             }
    506         }
    507 
    508         /// <summary>
    509         /// Gets or sets the width of the curve name.
    510         /// </summary>
    511         /// <value>The width of the curve name.</value>
    512         [Browsable(true)]
    513         [Description("获取或设置曲线名称的布局宽度")]
    514         [Category("自定义")]
    515         [DefaultValue(100)]
    516         public int CurveNameWidth
    517         {
    518             get
    519             {
    520                 return curveNameWidth;
    521             }
    522             set
    523             {
    524                 if (value > 10)
    525                 {
    526                     curveNameWidth = value;
    527                 }
    528             }
    529         }

    构造函数做一些初始化

     1  public UCCurve()
     2         {
     3             InitializeComponent();
     4             random = new Random();
     5             data_list = new Dictionary<string, CurveItem>();
     6             auxiliary_lines = new List<AuxiliaryLine>();
     7             MarkTexts = new List<MarkText>();
     8             auxiliary_Labels = new List<AuxiliaryLable>();
     9             format_left = new StringFormat
    10             {
    11                 LineAlignment = StringAlignment.Center,
    12                 Alignment = StringAlignment.Near
    13             };
    14             format_right = new StringFormat
    15             {
    16                 LineAlignment = StringAlignment.Center,
    17                 Alignment = StringAlignment.Far
    18             };
    19             format_center = new StringFormat
    20             {
    21                 LineAlignment = StringAlignment.Center,
    22                 Alignment = StringAlignment.Center
    23             };
    24             font_size9 = new Font("微软雅黑", 9f);
    25             font_size12 = new Font("微软雅黑", 12f);
    26             InitializationColor();
    27             pen_dash = new Pen(color_deep);
    28             pen_dash.DashStyle = DashStyle.Custom;
    29             pen_dash.DashPattern = new float[2]
    30             {
    31                 5f,
    32                 5f
    33             };
    34             SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
    35             SetStyle(ControlStyles.ResizeRedraw, true);
    36             SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    37             SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    38         }

    重绘

      1   protected override void OnPaint(PaintEventArgs e)
      2         {
      3             try
      4             {
      5                 Graphics graphics = e.Graphics;
      6                 graphics.SetGDIHigh();
      7                 if (BackColor != Color.Transparent)
      8                 {
      9                     graphics.Clear(BackColor);
     10                 }
     11                 int width = base.Width;
     12                 int height = base.Height;
     13                 if (width < 120 || height < 60)
     14                 {
     15                     return;
     16                 }
     17                 Point[] array = new Point[4]
     18                 {
     19                     new Point(leftRight - 1, upDowm - 8),
     20                     new Point(leftRight - 1, height - upDowm),
     21                     new Point(width - leftRight, height - upDowm),
     22                     new Point(width - leftRight, upDowm - 8)
     23                 };
     24                 graphics.DrawLine(pen_normal, array[0], array[1]);
     25                 graphics.DrawLine(pen_normal, array[1], array[2]);
     26                 if (isRenderRightCoordinate)
     27                 {
     28                     graphics.DrawLine(pen_normal, array[2], array[3]);
     29                 }
     30 
     31                 if (!string.IsNullOrEmpty(value_title))
     32                 {
     33                     graphics.DrawString(value_title, font_size9, brush_deep, new Rectangle(0, 0, width - 1, 20), format_center);
     34                 }
     35 
     36                 if (data_list.Count > 0)
     37                 {
     38                     float num = leftRight + 10;
     39                     foreach (KeyValuePair<string, CurveItem> item in data_list)
     40                     {
     41                         if (item.Value.Visible)
     42                         {
     43                             var titleSize=graphics.MeasureString(item.Key, Font);
     44                             SolidBrush solidBrush = item.Value.LineRenderVisiable ? new SolidBrush(item.Value.LineColor) : new SolidBrush(Color.FromArgb(80, item.Value.LineColor));
     45                             graphics.FillRectangle(solidBrush, num + 8f, 24f, 20f, 14f);
     46                             graphics.DrawString(item.Key, Font, solidBrush, new PointF(num + 30f, 24f+(14 - titleSize.Height) / 2));
     47                             item.Value.TitleRegion = new RectangleF(num, 24f, 60f, 18f);
     48                             solidBrush.Dispose();
     49                             num += titleSize.Width + 30;
     50                         }
     51                     }
     52                 }
     53 
     54 
     55                 for (int i = 0; i < auxiliary_Labels.Count; i++)
     56                 {
     57                     if (!string.IsNullOrEmpty(auxiliary_Labels[i].Text))
     58                     {
     59                         int num2 = (auxiliary_Labels[i].LocationX > 1f) ? ((int)auxiliary_Labels[i].LocationX) : ((int)(auxiliary_Labels[i].LocationX * (float)width));
     60                         int num3 = (int)graphics.MeasureString(auxiliary_Labels[i].Text, Font).Width + 3;
     61                         Point[] points = new Point[6]
     62                     {
     63                         new Point(num2, 11),
     64                         new Point(num2 + 10, 20),
     65                         new Point(num2 + num3 + 10, 20),
     66                         new Point(num2 + num3 + 10, 0),
     67                         new Point(num2 + 10, 0),
     68                         new Point(num2, 11)
     69                     };
     70                         graphics.FillPolygon(auxiliary_Labels[i].TextBack, points);
     71                         graphics.DrawString(auxiliary_Labels[i].Text, Font, auxiliary_Labels[i].TextBrush, new Rectangle(num2 + 7, 0, num3 + 3, 20), format_center);
     72                     }
     73                 }
     74                 ControlHelper.PaintTriangle(graphics, brush_deep, new Point(leftRight - 1, upDowm - 8), 4, GraphDirection.Upward);
     75                 if (isRenderRightCoordinate)
     76                 {
     77                     ControlHelper.PaintTriangle(graphics, brush_deep, new Point(width - leftRight, upDowm - 8), 4, GraphDirection.Upward);
     78                 }
     79                 for (int j = 0; j < auxiliary_lines.Count; j++)
     80                 {
     81                     if (auxiliary_lines[j].IsLeftFrame)
     82                     {
     83                         auxiliary_lines[j].PaintValue = ControlHelper.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, auxiliary_lines[j].Value) + (float)upDowm;
     84                     }
     85                     else
     86                     {
     87                         auxiliary_lines[j].PaintValue = ControlHelper.ComputePaintLocationY(value_max_right, value_min_right, height - upDowm - upDowm, auxiliary_lines[j].Value) + (float)upDowm;
     88                     }
     89                 }
     90                 for (int k = 0; k <= value_Segment; k++)
     91                 {
     92                     float value = (float)((double)k * (double)(value_max_left - value_min_left) / (double)value_Segment + (double)value_min_left);
     93                     float num4 = ControlHelper.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, value) + (float)upDowm;
     94                     if (IsNeedPaintDash(num4))
     95                     {
     96                         graphics.DrawLine(pen_normal, leftRight - 4, num4, leftRight - 1, num4);
     97                         RectangleF layoutRectangle = new RectangleF(0f, num4 - 9f, leftRight - 4, 20f);
     98                         graphics.DrawString(value.ToString(), font_size9, brush_deep, layoutRectangle, format_right);
     99                         if (isRenderRightCoordinate)
    100                         {
    101                             float num5 = (float)k * (value_max_right - value_min_right) / (float)value_Segment + value_min_right;
    102                             graphics.DrawLine(pen_normal, width - leftRight + 1, num4, width - leftRight + 4, num4);
    103                             layoutRectangle.Location = new PointF(width - leftRight + 4, num4 - 9f);
    104                             graphics.DrawString(num5.ToString(), font_size9, brush_deep, layoutRectangle, format_left);
    105                         }
    106                         if (k > 0 && value_IsRenderDashLine)
    107                         {
    108                             graphics.DrawLine(pen_dash, leftRight, num4, width - leftRight, num4);
    109                         }
    110                     }
    111                 }
    112                 if (value_IsRenderDashLine)
    113                 {
    114                     if (value_IsAbscissaStrech)
    115                     {
    116                         float num6 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
    117                         int num7 = CalculateDataCountByOffect(num6);
    118                         for (int l = 0; l < value_StrechDataCountMax; l += num7)
    119                         {
    120                             if (l > 0 && l < value_StrechDataCountMax - 1)
    121                             {
    122                                 graphics.DrawLine(pen_dash, (float)l * num6 + (float)leftRight, upDowm, (float)l * num6 + (float)leftRight, height - upDowm - 1);
    123                             }
    124                             if (data_text != null && l < data_text.Length && (float)l * num6 + (float)leftRight < (float)(data_text.Length - 1) * num6 + (float)leftRight - 40f)
    125                             {
    126                                 graphics.DrawString(layoutRectangle: new Rectangle((int)((float)l * num6), height - upDowm + 1, leftRight * 2, upDowm), s: data_text[l], font: font_size9,  brush_deep, format: format_center);
    127                             }
    128                         }
    129                         string[] array2 = data_text;
    130                         if (array2 != null && array2.Length > 1)
    131                         {
    132                             if (data_text.Length < value_StrechDataCountMax)
    133                             {
    134                                 graphics.DrawLine(pen_dash, (float)(data_text.Length - 1) * num6 + (float)leftRight, upDowm, (float)(data_text.Length - 1) * num6 + (float)leftRight, height - upDowm - 1);
    135                             }
    136                             graphics.DrawString(layoutRectangle: new Rectangle((int)((float)(data_text.Length - 1) * num6 + (float)leftRight) - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[data_text.Length - 1], font: font_size9,  brush_deep, format: format_center);
    137                         }
    138                     }
    139                     else if (value_IntervalAbscissaText > 0)
    140                     {
    141                         int num8 = width - 2 * leftRight + 1;
    142                         for (int m = leftRight; m < width - leftRight; m += value_IntervalAbscissaText)
    143                         {
    144                             if (m != leftRight)
    145                             {
    146                                 graphics.DrawLine(pen_dash, m, upDowm, m, height - upDowm - 1);
    147                             }
    148                             if (data_text == null)
    149                             {
    150                                 continue;
    151                             }
    152                             int num9 = (num8 > data_text.Length) ? data_text.Length : num8;
    153                             if (m - leftRight < data_text.Length && num9 - (m - leftRight) > 40)
    154                             {
    155                                 if (data_text.Length <= num8)
    156                                 {
    157                                     graphics.DrawString(layoutRectangle: new Rectangle(m - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[m - leftRight], font: font_size9,  brush_deep, format: format_center);
    158                                 }
    159                                 else
    160                                 {
    161                                     graphics.DrawString(layoutRectangle: new Rectangle(m - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[m - leftRight + data_text.Length - num8], font: font_size9,  brush_deep, format: format_center);
    162                                 }
    163                             }
    164                         }
    165                         string[] array3 = data_text;
    166                         if (array3 != null && array3.Length > 1)
    167                         {
    168                             if (data_text.Length >= num8)
    169                             {
    170                                 graphics.DrawString(layoutRectangle: new Rectangle(width - leftRight - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[data_text.Length - 1], font: font_size9,  brush_deep, format: format_center);
    171                             }
    172                             else
    173                             {
    174                                 graphics.DrawLine(pen_dash, data_text.Length + leftRight - 1, upDowm, data_text.Length + leftRight - 1, height - upDowm - 1);
    175                                 graphics.DrawString(layoutRectangle: new Rectangle(data_text.Length + leftRight - 1 - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[data_text.Length - 1], font: font_size9,  brush_deep, format: format_center);
    176                             }
    177                         }
    178                     }
    179                 }
    180                 for (int n = 0; n < auxiliary_lines.Count; n++)
    181                 {
    182                     if (auxiliary_lines[n].IsLeftFrame)
    183                     {
    184                         graphics.DrawLine(auxiliary_lines[n].GetPen(), leftRight - 4, auxiliary_lines[n].PaintValue, leftRight - 1, auxiliary_lines[n].PaintValue);
    185                         graphics.DrawString(layoutRectangle: new RectangleF(0f, auxiliary_lines[n].PaintValue - 9f, leftRight - 4, 20f), s: auxiliary_lines[n].Value.ToString(), font: font_size9,  auxiliary_lines[n].LineTextBrush, format: format_right);
    186                     }
    187                     else
    188                     {
    189                         graphics.DrawLine(auxiliary_lines[n].GetPen(), width - leftRight + 1, auxiliary_lines[n].PaintValue, width - leftRight + 4, auxiliary_lines[n].PaintValue);
    190                         graphics.DrawString(layoutRectangle: new RectangleF(width - leftRight + 4, auxiliary_lines[n].PaintValue - 9f, leftRight - 4, 20f), s: auxiliary_lines[n].Value.ToString(), font: font_size9,  auxiliary_lines[n].LineTextBrush, format: format_left);
    191                     }
    192                     graphics.DrawLine(auxiliary_lines[n].GetPen(), leftRight, auxiliary_lines[n].PaintValue, width - leftRight, auxiliary_lines[n].PaintValue);
    193                 }
    194                 if (value_IsAbscissaStrech)
    195                 {
    196                     foreach (MarkText MarkText in MarkTexts)
    197                     {
    198                         foreach (KeyValuePair<string, CurveItem> item2 in data_list)
    199                         {
    200                             if (item2.Value.Visible && item2.Value.LineRenderVisiable && !(item2.Key != MarkText.CurveKey))
    201                             {
    202                                 float[] data = item2.Value.Data;
    203                                 if (data != null && data.Length > 1)
    204                                 {
    205                                     float num10 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
    206                                     if (MarkText.Index >= 0 && MarkText.Index < item2.Value.Data.Length)
    207                                     {
    208                                         PointF pointF = new PointF((float)leftRight + (float)MarkText.Index * num10, ControlHelper.ComputePaintLocationY(item2.Value.IsLeftFrame ? value_max_left : value_max_right, item2.Value.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, item2.Value.Data[MarkText.Index]) + (float)upDowm);
    209                                         graphics.FillEllipse(new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 3f, pointF.Y - 3f, 6f, 6f));
    210                                         switch ((MarkText.PositionStyle == MarkTextPositionStyle.Auto) ? MarkText.CalculateDirectionFromDataIndex(item2.Value.Data, MarkText.Index) : MarkText.PositionStyle)
    211                                         {
    212                                             case MarkTextPositionStyle.Left:
    213                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 100f, pointF.Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
    214                                                 break;
    215                                             case MarkTextPositionStyle.Up:
    216                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 100f, pointF.Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    217                                                 break;
    218                                             case MarkTextPositionStyle.Right:
    219                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X + (float)MarkText.MarkTextOffect, pointF.Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
    220                                                 break;
    221                                             case MarkTextPositionStyle.Down:
    222                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 100f, pointF.Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    223                                                 break;
    224                                         }
    225                                     }
    226                                 }
    227                             }
    228                         }
    229                     }
    230                     foreach (CurveItem value2 in data_list.Values)
    231                     {
    232                         if (value2.Visible && value2.LineRenderVisiable)
    233                         {
    234                             float[] data2 = value2.Data;
    235                             if (data2 != null && data2.Length > 1)
    236                             {
    237                                 float num11 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
    238                                 PointF[] array4 = new PointF[value2.Data.Length];
    239                                 for (int num12 = 0; num12 < value2.Data.Length; num12++)
    240                                 {
    241                                     array4[num12].X = (float)leftRight + (float)num12 * num11;
    242                                     array4[num12].Y = ControlHelper.ComputePaintLocationY(value2.IsLeftFrame ? value_max_left : value_max_right, value2.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value2.Data[num12]) + (float)upDowm;
    243                                     if (!string.IsNullOrEmpty(value2.MarkText[num12]))
    244                                     {
    245                                         using (Brush brush = new SolidBrush(value2.LineColor))
    246                                         {
    247                                             graphics.FillEllipse(brush, new RectangleF(array4[num12].X - 3f, array4[num12].Y - 3f, 6f, 6f));
    248                                             switch (MarkText.CalculateDirectionFromDataIndex(value2.Data, num12))
    249                                             {
    250                                                 case MarkTextPositionStyle.Left:
    251                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X - 100f, array4[num12].Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
    252                                                     break;
    253                                                 case MarkTextPositionStyle.Up:
    254                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X - 100f, array4[num12].Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    255                                                     break;
    256                                                 case MarkTextPositionStyle.Right:
    257                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X + (float)MarkText.MarkTextOffect, array4[num12].Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
    258                                                     break;
    259                                                 case MarkTextPositionStyle.Down:
    260                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X - 100f, array4[num12].Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    261                                                     break;
    262                                             }
    263                                         }
    264                                     }
    265                                 }
    266                                 using (Pen pen2 = new Pen(value2.LineColor, value2.LineThickness))
    267                                 {
    268                                     if (value2.IsSmoothCurve)
    269                                     {
    270                                         graphics.DrawCurve(pen2, array4);
    271                                     }
    272                                     else
    273                                     {
    274                                         graphics.DrawLines(pen2, array4);
    275                                     }
    276                                 }
    277                             }
    278                         }
    279                     }
    280                 }
    281                 else
    282                 {
    283                     foreach (MarkText MarkText2 in MarkTexts)
    284                     {
    285                         foreach (KeyValuePair<string, CurveItem> item3 in data_list)
    286                         {
    287                             if (item3.Value.Visible && item3.Value.LineRenderVisiable && !(item3.Key != MarkText2.CurveKey))
    288                             {
    289                                 float[] data3 = item3.Value.Data;
    290                                 if (data3 != null && data3.Length > 1 && MarkText2.Index >= 0 && MarkText2.Index < item3.Value.Data.Length)
    291                                 {
    292                                     PointF pointF2 = new PointF(leftRight + MarkText2.Index, ControlHelper.ComputePaintLocationY(item3.Value.IsLeftFrame ? value_max_left : value_max_right, item3.Value.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, item3.Value.Data[MarkText2.Index]) + (float)upDowm);
    293                                     graphics.FillEllipse(new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 3f, pointF2.Y - 3f, 6f, 6f));
    294                                     switch ((MarkText2.PositionStyle == MarkTextPositionStyle.Auto) ? MarkText.CalculateDirectionFromDataIndex(item3.Value.Data, MarkText2.Index) : MarkText2.PositionStyle)
    295                                     {
    296                                         case MarkTextPositionStyle.Left:
    297                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 100f, pointF2.Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
    298                                             break;
    299                                         case MarkTextPositionStyle.Up:
    300                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 100f, pointF2.Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    301                                             break;
    302                                         case MarkTextPositionStyle.Right:
    303                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X + (float)MarkText.MarkTextOffect, pointF2.Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
    304                                             break;
    305                                         case MarkTextPositionStyle.Down:
    306                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 100f, pointF2.Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    307                                             break;
    308                                     }
    309                                 }
    310                             }
    311                         }
    312                     }
    313                     foreach (CurveItem value3 in data_list.Values)
    314                     {
    315                         if (value3.Visible && value3.LineRenderVisiable)
    316                         {
    317                             float[] data4 = value3.Data;
    318                             if (data4 != null && data4.Length > 1)
    319                             {
    320                                 int num13 = width - 2 * leftRight + 1;
    321                                 PointF[] array5;
    322                                 if (value3.Data.Length <= num13)
    323                                 {
    324                                     array5 = new PointF[value3.Data.Length];
    325                                     for (int num14 = 0; num14 < value3.Data.Length; num14++)
    326                                     {
    327                                         array5[num14].X = leftRight + num14;
    328                                         array5[num14].Y = ControlHelper.ComputePaintLocationY(value3.IsLeftFrame ? value_max_left : value_max_right, value3.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value3.Data[num14]) + (float)upDowm;
    329                                         DrawMarkPoint(graphics, value3.MarkText[num14], array5[num14], value3.LineColor, MarkText.CalculateDirectionFromDataIndex(value3.Data, num14));
    330                                     }
    331                                 }
    332                                 else
    333                                 {
    334                                     array5 = new PointF[num13];
    335                                     for (int num15 = 0; num15 < array5.Length; num15++)
    336                                     {
    337                                         int num16 = num15 + value3.Data.Length - num13;
    338                                         array5[num15].X = leftRight + num15;
    339                                         array5[num15].Y = ControlHelper.ComputePaintLocationY(value3.IsLeftFrame ? value_max_left : value_max_right, value3.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value3.Data[num16]) + (float)upDowm;
    340                                         DrawMarkPoint(graphics, value3.MarkText[num16], array5[num15], value3.LineColor, MarkText.CalculateDirectionFromDataIndex(value3.Data, num16));
    341                                     }
    342                                 }
    343                                 using (Pen pen3 = new Pen(value3.LineColor, value3.LineThickness))
    344                                 {
    345                                     if (value3.IsSmoothCurve)
    346                                     {
    347                                         graphics.DrawCurve(pen3, array5);
    348                                     }
    349                                     else
    350                                     {
    351                                         graphics.DrawLines(pen3, array5);
    352                                     }
    353                                 }
    354                             }
    355                         }
    356                     }
    357                 }
    358                 base.OnPaint(e);
    359             }
    360             catch (Exception exc)
    361             {
    362                 e.Graphics.DrawString(exc.Message, this.Font, Brushes.Black, 10, 10);
    363             }
    364         }

    辅助函数

     1  /// <summary>
     2         /// Draws the mark point.
     3         /// </summary>
     4         /// <param name="g">The g.</param>
     5         /// <param name="markText">The mark text.</param>
     6         /// <param name="center">The center.</param>
     7         /// <param name="color">The color.</param>
     8         /// <param name="markTextPosition">The mark text position.</param>
     9         private void DrawMarkPoint(Graphics g, string markText, PointF center, Color color, MarkTextPositionStyle markTextPosition)
    10         {
    11             if (!string.IsNullOrEmpty(markText))
    12             {
    13                 using (Brush brush = new SolidBrush(color))
    14                 {
    15                     DrawMarkPoint(g, markText, center, brush, markTextPosition);
    16                 }
    17             }
    18         }
    19 
    20         /// <summary>
    21         /// Draws the mark point.
    22         /// </summary>
    23         /// <param name="g">The g.</param>
    24         /// <param name="markText">The mark text.</param>
    25         /// <param name="center">The center.</param>
    26         /// <param name="brush">The brush.</param>
    27         /// <param name="markTextPosition">The mark text position.</param>
    28         private void DrawMarkPoint(Graphics g, string markText, PointF center, Brush brush, MarkTextPositionStyle markTextPosition)
    29         {
    30             if (!string.IsNullOrEmpty(markText))
    31             {
    32                 g.FillEllipse(brush, new RectangleF(center.X - 3f, center.Y - 3f, 6f, 6f));
    33                 switch (markTextPosition)
    34                 {
    35                     case MarkTextPositionStyle.Left:
    36                         g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
    37                         break;
    38                     case MarkTextPositionStyle.Up:
    39                         g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    40                         break;
    41                     case MarkTextPositionStyle.Right:
    42                         g.DrawString(markText, Font, brush, new RectangleF(center.X + (float)MarkText.MarkTextOffect, center.Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
    43                         break;
    44                     case MarkTextPositionStyle.Down:
    45                         g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    46                         break;
    47                 }
    48             }
    49         }
    50 
    51         /// <summary>
    52         /// Determines whether [is need paint dash] [the specified paint value].
    53         /// </summary>
    54         /// <param name="paintValue">The paint value.</param>
    55         /// <returns><c>true</c> if [is need paint dash] [the specified paint value]; otherwise, <c>false</c>.</returns>
    56         private bool IsNeedPaintDash(float paintValue)
    57         {
    58             for (int i = 0; i < auxiliary_lines.Count; i++)
    59             {
    60                 if (Math.Abs(auxiliary_lines[i].PaintValue - paintValue) < (float)font_size9.Height)
    61                 {
    62                     return false;
    63                 }
    64             }
    65             return true;
    66         }
    67 
    68         /// <summary>
    69         /// Calculates the data count by offect.
    70         /// </summary>
    71         /// <param name="offect">The offect.</param>
    72         /// <returns>System.Int32.</returns>
    73         private int CalculateDataCountByOffect(float offect)
    74         {
    75             if (value_IntervalAbscissaText > 0)
    76             {
    77                 return value_IntervalAbscissaText;
    78             }
    79             if (offect > 40f)
    80             {
    81                 return 1;
    82             }
    83             offect = 40f / offect;
    84             return (int)Math.Ceiling(offect);
    85         }

    一些公开函数

      1  /// <summary>
      2         /// Sets the curve text.
      3         /// </summary>
      4         /// <param name="descriptions">The descriptions.</param>
      5         public void SetCurveText(string[] descriptions)
      6         {
      7             data_text = descriptions;
      8             Invalidate();
      9         }
     10 
     11         /// <summary>
     12         /// Sets the left curve.
     13         /// </summary>
     14         /// <param name="key">The key.</param>
     15         /// <param name="data">The data.</param>
     16         /// <param name="lineColor">Color of the line.</param>
     17         public void SetLeftCurve(string key, float[] data, Color? lineColor = null)
     18         {
     19             SetCurve(key, true, data, lineColor, 1f, false);
     20         }
     21 
     22         /// <summary>
     23         /// Sets the left curve.
     24         /// </summary>
     25         /// <param name="key">The key.</param>
     26         /// <param name="data">The data.</param>
     27         /// <param name="lineColor">Color of the line.</param>
     28         /// <param name="isSmooth">if set to <c>true</c> [is smooth].</param>
     29         public void SetLeftCurve(string key, float[] data, Color? lineColor, bool isSmooth = false)
     30         {
     31             SetCurve(key, true, data, lineColor, 1f, isSmooth);
     32         }
     33 
     34         /// <summary>
     35         /// Sets the right curve.
     36         /// </summary>
     37         /// <param name="key">The key.</param>
     38         /// <param name="data">The data.</param>
     39         /// <param name="lineColor">Color of the line.</param>
     40         public void SetRightCurve(string key, float[] data, Color? lineColor = null)
     41         {
     42             SetCurve(key, false, data, lineColor, 1f, false);
     43         }
     44 
     45         /// <summary>
     46         /// Sets the right curve.
     47         /// </summary>
     48         /// <param name="key">The key.</param>
     49         /// <param name="data">The data.</param>
     50         /// <param name="lineColor">Color of the line.</param>
     51         /// <param name="isSmooth">if set to <c>true</c> [is smooth].</param>
     52         public void SetRightCurve(string key, float[] data, Color? lineColor, bool isSmooth = false)
     53         {
     54             SetCurve(key, false, data, lineColor, 1f, isSmooth);
     55         }
     56 
     57         /// <summary>
     58         /// Sets the curve.
     59         /// </summary>
     60         /// <param name="key">The key.</param>
     61         /// <param name="isLeft">if set to <c>true</c> [is left].</param>
     62         /// <param name="data">The data.</param>
     63         /// <param name="lineColor">Color of the line.</param>
     64         /// <param name="thickness">The thickness.</param>
     65         /// <param name="isSmooth">if set to <c>true</c> [is smooth].</param>
     66         public void SetCurve(string key, bool isLeft, float[] data, Color? lineColor, float thickness, bool isSmooth)
     67         {
     68             if (data_list.ContainsKey(key))
     69             {
     70                 if (data == null)
     71                 {
     72                     data = new float[0];
     73                 }
     74                 data_list[key].Data = data;
     75             }
     76             else
     77             {
     78                 if (data == null)
     79                 {
     80                     data = new float[0];
     81                 }
     82                 data_list.Add(key, new CurveItem
     83                 {
     84                     Data = data,
     85                     MarkText = new string[data.Length],
     86                     LineThickness = thickness,
     87                     LineColor = lineColor ?? ControlHelper.Colors[data_list.Count + 13],
     88                     IsLeftFrame = isLeft,
     89                     IsSmoothCurve = isSmooth
     90                 });
     91                 if (data_text == null)
     92                 {
     93                     data_text = new string[data.Length];
     94                 }
     95             }
     96             Invalidate();
     97         }
     98 
     99         /// <summary>
    100         /// Removes the curve.
    101         /// </summary>
    102         /// <param name="key">The key.</param>
    103         public void RemoveCurve(string key)
    104         {
    105             if (data_list.ContainsKey(key))
    106             {
    107                 data_list.Remove(key);
    108             }
    109             if (data_list.Count == 0)
    110             {
    111                 data_text = new string[0];
    112             }
    113             Invalidate();
    114         }
    115 
    116         /// <summary>
    117         /// Removes all curve.
    118         /// </summary>
    119         public void RemoveAllCurve()
    120         {
    121             int count = data_list.Count;
    122             data_list.Clear();
    123             if (data_list.Count == 0)
    124             {
    125                 data_text = new string[0];
    126             }
    127             if (count > 0)
    128             {
    129                 Invalidate();
    130             }
    131         }
    132 
    133         /// <summary>
    134         /// Removes all curve data.
    135         /// </summary>
    136         public void RemoveAllCurveData()
    137         {
    138             int count = data_list.Count;
    139             foreach (KeyValuePair<string, CurveItem> item in data_list)
    140             {
    141                 item.Value.Data = new float[0];
    142                 item.Value.MarkText = new string[0];
    143             }
    144             data_text = new string[0];
    145             if (count > 0)
    146             {
    147                 Invalidate();
    148             }
    149         }
    150 
    151         /// <summary>
    152         /// Gets the curve item.
    153         /// </summary>
    154         /// <param name="key">The key.</param>
    155         /// <returns>CurveItem.</returns>
    156         public CurveItem GetCurveItem(string key)
    157         {
    158             if (data_list.ContainsKey(key))
    159             {
    160                 return data_list[key];
    161             }
    162             return null;
    163         }
    164 
    165         /// <summary>
    166         /// Saves to bitmap.
    167         /// </summary>
    168         /// <returns>Bitmap.</returns>
    169         public Bitmap SaveToBitmap()
    170         {
    171             return SaveToBitmap(base.Width, base.Height);
    172         }
    173 
    174         /// <summary>
    175         /// Saves to bitmap.
    176         /// </summary>
    177         /// <param name="width">The width.</param>
    178         /// <param name="height">The height.</param>
    179         /// <returns>Bitmap.</returns>
    180         public Bitmap SaveToBitmap(int width, int height)
    181         {
    182             Bitmap bitmap = new Bitmap(width, height);
    183             Graphics graphics = Graphics.FromImage(bitmap);
    184             OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, width, height)));
    185             return bitmap;
    186         }
    187 
    188         /// <summary>
    189         /// Adds the curve data.
    190         /// </summary>
    191         /// <param name="key">The key.</param>
    192         /// <param name="values">The values.</param>
    193         /// <param name="markTexts">The mark texts.</param>
    194         /// <param name="isUpdateUI">if set to <c>true</c> [is update UI].</param>
    195         private void AddCurveData(string key, float[] values, string[] markTexts, bool isUpdateUI)
    196         {
    197             if ((values != null && values.Length < 1) || !data_list.ContainsKey(key))
    198             {
    199                 return;
    200             }
    201             CurveItem CurveItem = data_list[key];
    202             if (CurveItem.Data != null)
    203             {
    204                 if (value_IsAbscissaStrech)
    205                 {
    206                     ControlHelper.AddArrayData(ref CurveItem.Data, values, value_StrechDataCountMax);
    207                     ControlHelper.AddArrayData(ref CurveItem.MarkText, markTexts, value_StrechDataCountMax);
    208                 }
    209                 else
    210                 {
    211                     ControlHelper.AddArrayData(ref CurveItem.Data, values, 4096);
    212                     ControlHelper.AddArrayData(ref CurveItem.MarkText, markTexts, 4096);
    213                 }
    214                 if (isUpdateUI)
    215                 {
    216                     Invalidate();
    217                 }
    218             }
    219         }
    220 
    221         /// <summary>
    222         /// Adds the curve time.
    223         /// </summary>
    224         /// <param name="count">The count.</param>
    225         private void AddCurveTime(int count)
    226         {
    227             AddCurveTime(count, DateTime.Now.ToString(textFormat));
    228         }
    229 
    230         /// <summary>
    231         /// Adds the curve time.
    232         /// </summary>
    233         /// <param name="count">The count.</param>
    234         /// <param name="text">The text.</param>
    235         private void AddCurveTime(int count, string text)
    236         {
    237             if (data_text != null)
    238             {
    239                 string[] array = new string[count];
    240                 for (int i = 0; i < array.Length; i++)
    241                 {
    242                     array[i] = text;
    243                 }
    244                 if (value_IsAbscissaStrech)
    245                 {
    246                     ControlHelper.AddArrayData(ref data_text, array, value_StrechDataCountMax);
    247                 }
    248                 else
    249                 {
    250                     ControlHelper.AddArrayData(ref data_text, array, 4096);
    251                 }
    252             }
    253         }
    254 
    255         /// <summary>
    256         /// Adds the curve data.
    257         /// </summary>
    258         /// <param name="key">The key.</param>
    259         /// <param name="value">The value.</param>
    260         public void AddCurveData(string key, float value)
    261         {
    262             AddCurveData(key, new float[1]
    263             {
    264                 value
    265             });
    266         }
    267 
    268         /// <summary>
    269         /// Adds the curve data.
    270         /// </summary>
    271         /// <param name="key">The key.</param>
    272         /// <param name="value">The value.</param>
    273         /// <param name="markText">The mark text.</param>
    274         public void AddCurveData(string key, float value, string markText)
    275         {
    276             AddCurveData(key, new float[1]
    277             {
    278                 value
    279             }, new string[1]
    280             {
    281                 markText
    282             });
    283         }
    284 
    285         /// <summary>
    286         /// Adds the curve data.
    287         /// </summary>
    288         /// <param name="key">The key.</param>
    289         /// <param name="values">The values.</param>
    290         public void AddCurveData(string key, float[] values)
    291         {
    292             AddCurveData(key, values, null);
    293         }
    294 
    295         /// <summary>
    296         /// Adds the curve data.
    297         /// </summary>
    298         /// <param name="key">The key.</param>
    299         /// <param name="values">The values.</param>
    300         /// <param name="markTexts">The mark texts.</param>
    301         public void AddCurveData(string key, float[] values, string[] markTexts)
    302         {
    303             if (markTexts == null)
    304             {
    305                 markTexts = new string[values.Length];
    306             }
    307             AddCurveData(key, values, markTexts, false);
    308             if (values != null && values.Length != 0)
    309             {
    310                 AddCurveTime(values.Length);
    311             }
    312             Invalidate();
    313         }
    314 
    315         /// <summary>
    316         /// Adds the curve data.
    317         /// </summary>
    318         /// <param name="keys">The keys.</param>
    319         /// <param name="values">The values.</param>
    320         public void AddCurveData(string[] keys, float[] values)
    321         {
    322             AddCurveData(keys, values, null);
    323         }
    324 
    325         /// <summary>
    326         /// Adds the curve data.
    327         /// </summary>
    328         /// <param name="axisText">The axis text.</param>
    329         /// <param name="keys">The keys.</param>
    330         /// <param name="values">The values.</param>
    331         public void AddCurveData(string axisText, string[] keys, float[] values)
    332         {
    333             AddCurveData(axisText, keys, values, null);
    334         }
    335 
    336         /// <summary>
    337         /// Adds the curve data.
    338         /// </summary>
    339         /// <param name="keys">The keys.</param>
    340         /// <param name="values">The values.</param>
    341         /// <param name="markTexts">The mark texts.</param>
    342         /// <exception cref="ArgumentNullException">keys
    343         /// or
    344         /// values</exception>
    345         /// <exception cref="Exception">两个参数的数组长度不一致。
    346         /// or
    347         /// 两个参数的数组长度不一致。</exception>
    348         public void AddCurveData(string[] keys, float[] values, string[] markTexts)
    349         {
    350             if (keys == null)
    351             {
    352                 throw new ArgumentNullException("keys");
    353             }
    354             if (values == null)
    355             {
    356                 throw new ArgumentNullException("values");
    357             }
    358             if (markTexts == null)
    359             {
    360                 markTexts = new string[keys.Length];
    361             }
    362             if (keys.Length != values.Length)
    363             {
    364                 throw new Exception("两个参数的数组长度不一致。");
    365             }
    366             if (keys.Length != markTexts.Length)
    367             {
    368                 throw new Exception("两个参数的数组长度不一致。");
    369             }
    370             for (int i = 0; i < keys.Length; i++)
    371             {
    372                 AddCurveData(keys[i], new float[1]
    373                 {
    374                     values[i]
    375                 }, new string[1]
    376                 {
    377                     markTexts[i]
    378                 }, false);
    379             }
    380             AddCurveTime(1);
    381             Invalidate();
    382         }
    383 
    384         /// <summary>
    385         /// Adds the curve data.
    386         /// </summary>
    387         /// <param name="axisText">The axis text.</param>
    388         /// <param name="keys">The keys.</param>
    389         /// <param name="values">The values.</param>
    390         /// <param name="markTexts">The mark texts.</param>
    391         /// <exception cref="ArgumentNullException">keys
    392         /// or
    393         /// values</exception>
    394         /// <exception cref="Exception">两个参数的数组长度不一致。
    395         /// or
    396         /// 两个参数的数组长度不一致。</exception>
    397         public void AddCurveData(string axisText, string[] keys, float[] values, string[] markTexts)
    398         {
    399             if (keys == null)
    400             {
    401                 throw new ArgumentNullException("keys");
    402             }
    403             if (values == null)
    404             {
    405                 throw new ArgumentNullException("values");
    406             }
    407             if (markTexts == null)
    408             {
    409                 markTexts = new string[keys.Length];
    410             }
    411             if (keys.Length != values.Length)
    412             {
    413                 throw new Exception("两个参数的数组长度不一致。");
    414             }
    415             if (keys.Length != markTexts.Length)
    416             {
    417                 throw new Exception("两个参数的数组长度不一致。");
    418             }
    419             for (int i = 0; i < keys.Length; i++)
    420             {
    421                 AddCurveData(keys[i], new float[1]
    422                 {
    423                     values[i]
    424                 }, new string[1]
    425                 {
    426                     markTexts[i]
    427                 }, false);
    428             }
    429             AddCurveTime(1, axisText);
    430             Invalidate();
    431         }
    432 
    433         /// <summary>
    434         /// Sets the curve visible.
    435         /// </summary>
    436         /// <param name="key">The key.</param>
    437         /// <param name="visible">if set to <c>true</c> [visible].</param>
    438         public void SetCurveVisible(string key, bool visible)
    439         {
    440             if (data_list.ContainsKey(key))
    441             {
    442                 CurveItem CurveItem = data_list[key];
    443                 CurveItem.Visible = visible;
    444                 Invalidate();
    445             }
    446         }
    447 
    448         /// <summary>
    449         /// Sets the curve visible.
    450         /// </summary>
    451         /// <param name="keys">The keys.</param>
    452         /// <param name="visible">if set to <c>true</c> [visible].</param>
    453         public void SetCurveVisible(string[] keys, bool visible)
    454         {
    455             foreach (string key in keys)
    456             {
    457                 if (data_list.ContainsKey(key))
    458                 {
    459                     CurveItem CurveItem = data_list[key];
    460                     CurveItem.Visible = visible;
    461                 }
    462             }
    463             Invalidate();
    464         }
    465 
    466         /// <summary>
    467         /// Adds the left auxiliary.
    468         /// </summary>
    469         /// <param name="value">The value.</param>
    470         public void AddLeftAuxiliary(float value)
    471         {
    472             AddLeftAuxiliary(value, ColorLinesAndText);
    473         }
    474 
    475         /// <summary>
    476         /// Adds the left auxiliary.
    477         /// </summary>
    478         /// <param name="value">The value.</param>
    479         /// <param name="lineColor">Color of the line.</param>
    480         public void AddLeftAuxiliary(float value, Color lineColor)
    481         {
    482             AddLeftAuxiliary(value, lineColor, 1f, true);
    483         }
    484 
    485         /// <summary>
    486         /// Adds the left auxiliary.
    487         /// </summary>
    488         /// <param name="value">The value.</param>
    489         /// <param name="lineColor">Color of the line.</param>
    490         /// <param name="lineThickness">The line thickness.</param>
    491         /// <param name="isDashLine">if set to <c>true</c> [is dash line].</param>
    492         public void AddLeftAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine)
    493         {
    494             AddAuxiliary(value, lineColor, lineThickness, isDashLine, true);
    495         }
    496 
    497         /// <summary>
    498         /// Adds the right auxiliary.
    499         /// </summary>
    500         /// <param name="value">The value.</param>
    501         public void AddRightAuxiliary(float value)
    502         {
    503             AddRightAuxiliary(value, ColorLinesAndText);
    504         }
    505 
    506         /// <summary>
    507         /// Adds the right auxiliary.
    508         /// </summary>
    509         /// <param name="value">The value.</param>
    510         /// <param name="lineColor">Color of the line.</param>
    511         public void AddRightAuxiliary(float value, Color lineColor)
    512         {
    513             AddRightAuxiliary(value, lineColor, 1f, true);
    514         }
    515 
    516         /// <summary>
    517         /// Adds the right auxiliary.
    518         /// </summary>
    519         /// <param name="value">The value.</param>
    520         /// <param name="lineColor">Color of the line.</param>
    521         /// <param name="lineThickness">The line thickness.</param>
    522         /// <param name="isDashLine">if set to <c>true</c> [is dash line].</param>
    523         public void AddRightAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine)
    524         {
    525             AddAuxiliary(value, lineColor, lineThickness, isDashLine, false);
    526         }
    527 
    528         /// <summary>
    529         /// Adds the auxiliary.
    530         /// </summary>
    531         /// <param name="value">The value.</param>
    532         /// <param name="lineColor">Color of the line.</param>
    533         /// <param name="lineThickness">The line thickness.</param>
    534         /// <param name="isDashLine">if set to <c>true</c> [is dash line].</param>
    535         /// <param name="isLeft">if set to <c>true</c> [is left].</param>
    536         private void AddAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine, bool isLeft)
    537         {
    538             auxiliary_lines.Add(new AuxiliaryLine
    539             {
    540                 Value = value,
    541                 LineColor = lineColor,
    542                 PenDash = new Pen(lineColor)
    543                 {
    544                     DashStyle = DashStyle.Custom,
    545                     DashPattern = new float[2]
    546                     {
    547                         5f,
    548                         5f
    549                     }
    550                 },
    551                 PenSolid = new Pen(lineColor),
    552                 IsDashStyle = isDashLine,
    553                 IsLeftFrame = isLeft,
    554                 LineThickness = lineThickness,
    555                 LineTextBrush = new SolidBrush(lineColor)
    556             });
    557             Invalidate();
    558         }
    559 
    560         /// <summary>
    561         /// Removes the auxiliary.
    562         /// </summary>
    563         /// <param name="value">The value.</param>
    564         public void RemoveAuxiliary(float value)
    565         {
    566             int num = 0;
    567             for (int num2 = auxiliary_lines.Count - 1; num2 >= 0; num2--)
    568             {
    569                 if (auxiliary_lines[num2].Value == value)
    570                 {
    571                     auxiliary_lines[num2].Dispose();
    572                     auxiliary_lines.RemoveAt(num2);
    573                     num++;
    574                 }
    575             }
    576             if (num > 0)
    577             {
    578                 Invalidate();
    579             }
    580         }
    581 
    582         /// <summary>
    583         /// Removes all auxiliary.
    584         /// </summary>
    585         public void RemoveAllAuxiliary()
    586         {
    587             int count = auxiliary_lines.Count;
    588             auxiliary_lines.Clear();
    589             if (count > 0)
    590             {
    591                 Invalidate();
    592             }
    593         }
    594 
    595         /// <summary>
    596         /// Adds the auxiliary label.
    597         /// </summary>
    598         /// <param name="auxiliaryLable">The auxiliary lable.</param>
    599         public void AddAuxiliaryLabel(AuxiliaryLable auxiliaryLable)
    600         {
    601             auxiliary_Labels.Add(auxiliaryLable);
    602         }
    603 
    604         /// <summary>
    605         /// Removes the auxiliary lable.
    606         /// </summary>
    607         /// <param name="auxiliaryLable">The auxiliary lable.</param>
    608         public void RemoveAuxiliaryLable(AuxiliaryLable auxiliaryLable)
    609         {
    610             if (auxiliary_Labels.Remove(auxiliaryLable))
    611             {
    612                 Invalidate();
    613             }
    614         }
    615 
    616         /// <summary>
    617         /// Removes all auxiliary lable.
    618         /// </summary>
    619         public void RemoveAllAuxiliaryLable()
    620         {
    621             int count = auxiliary_Labels.Count;
    622             auxiliary_Labels.Clear();
    623             if (count > 0)
    624             {
    625                 Invalidate();
    626             }
    627         }
    628 
    629         /// <summary>
    630         /// Adds the mark text.
    631         /// </summary>
    632         /// <param name="markText">The mark text.</param>
    633         public void AddMarkText(MarkText markText)
    634         {
    635             MarkTexts.Add(markText);
    636             if (data_list.Count > 0)
    637             {
    638                 Invalidate();
    639             }
    640         }
    641 
    642         /// <summary>
    643         /// Adds the mark text.
    644         /// </summary>
    645         /// <param name="strCurveKey">The string curve key.</param>
    646         /// <param name="intValueIndex">Index of the int value.</param>
    647         /// <param name="strText">The string text.</param>
    648         /// <param name="textColor">Color of the text.</param>
    649         public void AddMarkText(string strCurveKey, int intValueIndex, string strText, Color? textColor = null)
    650         {
    651             AddMarkText(new MarkText() { CurveKey = strCurveKey, PositionStyle = MarkTextPositionStyle.Auto, Text = strText, TextColor = textColor, Index = intValueIndex });
    652         }
    653 
    654         /// <summary>
    655         /// Removes the mark text.
    656         /// </summary>
    657         /// <param name="markText">The mark text.</param>
    658         public void RemoveMarkText(MarkText markText)
    659         {
    660             MarkTexts.Remove(markText);
    661             if (data_list.Count > 0)
    662             {
    663                 Invalidate();
    664             }
    665         }
    666 
    667         /// <summary>
    668         /// Removes all mark text.
    669         /// </summary>
    670         public void RemoveAllMarkText()
    671         {
    672             MarkTexts.Clear();
    673             if (data_list.Count > 0)
    674             {
    675                 Invalidate();
    676             }
    677         }

    其中

    MarkText为标注文字相关

    AuxiliaryLabel为提示信息相关

    Auxiliary为节点信息相关

    完整代码

       1 // ***********************************************************************
       2 // Assembly         : HZH_Controls
       3 // Created          : 2019-09-23
       4 //
       5 // ***********************************************************************
       6 // <copyright file="UCCurve.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.Collections.Generic;
      18 using System.ComponentModel;
      19 using System.Drawing;
      20 using System.Drawing.Drawing2D;
      21 using System.Drawing.Text;
      22 using System.Windows.Forms;
      23 
      24 namespace HZH_Controls.Controls
      25 {
      26     /// <summary>
      27     /// Class UCCurve.
      28     /// Implements the <see cref="System.Windows.Forms.UserControl" />
      29     /// </summary>
      30     /// <seealso cref="System.Windows.Forms.UserControl" />
      31     public class UCCurve : UserControl
      32     {
      33         /// <summary>
      34         /// The value count maximum
      35         /// </summary>
      36         private const int value_count_max = 4096;
      37 
      38         /// <summary>
      39         /// The value maximum left
      40         /// </summary>
      41         private float value_max_left = 100f;
      42 
      43         /// <summary>
      44         /// The value minimum left
      45         /// </summary>
      46         private float value_min_left = 0f;
      47 
      48         /// <summary>
      49         /// The value maximum right
      50         /// </summary>
      51         private float value_max_right = 100f;
      52 
      53         /// <summary>
      54         /// The value minimum right
      55         /// </summary>
      56         private float value_min_right = 0f;
      57 
      58         /// <summary>
      59         /// The value segment
      60         /// </summary>
      61         private int value_Segment = 5;
      62 
      63         /// <summary>
      64         /// The value is abscissa strech
      65         /// </summary>
      66         private bool value_IsAbscissaStrech = false;
      67 
      68         /// <summary>
      69         /// The value strech data count maximum
      70         /// </summary>
      71         private int value_StrechDataCountMax = 300;
      72 
      73         /// <summary>
      74         /// The value is render dash line
      75         /// </summary>
      76         private bool value_IsRenderDashLine = true;
      77 
      78         /// <summary>
      79         /// The text format
      80         /// </summary>
      81         private string textFormat = "HH:mm";
      82 
      83         /// <summary>
      84         /// The value interval abscissa text
      85         /// </summary>
      86         private int value_IntervalAbscissaText = 100;
      87 
      88         /// <summary>
      89         /// The random
      90         /// </summary>
      91         private Random random = null;
      92 
      93         /// <summary>
      94         /// The value title
      95         /// </summary>
      96         private string value_title = "";
      97 
      98         /// <summary>
      99         /// The left right
     100         /// </summary>
     101         private int leftRight = 50;
     102 
     103         /// <summary>
     104         /// Up dowm
     105         /// </summary>
     106         private int upDowm = 50;
     107 
     108         /// <summary>
     109         /// The data list
     110         /// </summary>
     111         private Dictionary<string, CurveItem> data_list = null;
     112 
     113         /// <summary>
     114         /// The data text
     115         /// </summary>
     116         private string[] data_text = null;
     117 
     118         /// <summary>
     119         /// The auxiliary lines
     120         /// </summary>
     121         private List<AuxiliaryLine> auxiliary_lines;
     122 
     123         /// <summary>
     124         /// The auxiliary labels
     125         /// </summary>
     126         private List<AuxiliaryLable> auxiliary_Labels;
     127 
     128         /// <summary>
     129         /// The mark texts
     130         /// </summary>
     131         private List<MarkText> MarkTexts;
     132 
     133         /// <summary>
     134         /// The font size9
     135         /// </summary>
     136         private Font font_size9 = null;
     137 
     138         /// <summary>
     139         /// The font size12
     140         /// </summary>
     141         private Font font_size12 = null;
     142 
     143         /// <summary>
     144         /// The brush deep
     145         /// </summary>
     146         private Brush brush_deep = null;
     147 
     148         /// <summary>
     149         /// The pen normal
     150         /// </summary>
     151         private Pen pen_normal = null;
     152 
     153         /// <summary>
     154         /// The pen dash
     155         /// </summary>
     156         private Pen pen_dash = null;
     157 
     158         /// <summary>
     159         /// The color normal
     160         /// </summary>
     161         private Color color_normal = Color.DeepPink;
     162 
     163         /// <summary>
     164         /// The color deep
     165         /// </summary>
     166         private Color color_deep = Color.DimGray;
     167 
     168         /// <summary>
     169         /// The color dash
     170         /// </summary>
     171         private Color color_dash = Color.FromArgb(232, 232, 232);
     172 
     173         /// <summary>
     174         /// The color mark font
     175         /// </summary>
     176         private Color color_mark_font = Color.DodgerBlue;
     177 
     178         /// <summary>
     179         /// The brush mark font
     180         /// </summary>
     181         private Brush brush_mark_font = Brushes.DodgerBlue;
     182 
     183         /// <summary>
     184         /// The format left
     185         /// </summary>
     186         private StringFormat format_left = null;
     187 
     188         /// <summary>
     189         /// The format right
     190         /// </summary>
     191         private StringFormat format_right = null;
     192 
     193         /// <summary>
     194         /// The format center
     195         /// </summary>
     196         private StringFormat format_center = null;
     197 
     198         /// <summary>
     199         /// The is render right coordinate
     200         /// </summary>
     201         private bool isRenderRightCoordinate = true;
     202 
     203         /// <summary>
     204         /// The curve name width
     205         /// </summary>
     206         private int curveNameWidth = 100;
     207 
     208         /// <summary>
     209         /// The components
     210         /// </summary>
     211         private IContainer components = null;
     212 
     213         /// <summary>
     214         /// 获取或设置控件的背景色。
     215         /// </summary>
     216         /// <value>The color of the back.</value>
     217         /// <PermissionSet>
     218         ///   <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
     219         /// </PermissionSet>
     220         [Browsable(true)]
     221         [Description("获取或设置控件的背景色")]
     222         [Category("自定义")]
     223         [DefaultValue(typeof(Color), "Transparent")]
     224         [EditorBrowsable(EditorBrowsableState.Always)]
     225         public override Color BackColor
     226         {
     227             get
     228             {
     229                 return base.BackColor;
     230             }
     231             set
     232             {
     233                 base.BackColor = value;
     234             }
     235         }
     236 
     237         /// <summary>
     238         /// Gets or sets the value maximum left.
     239         /// </summary>
     240         /// <value>The value maximum left.</value>
     241         [Category("自定义")]
     242         [Description("获取或设置图形的左纵坐标的最大值,该值必须大于最小值")]
     243         [Browsable(true)]
     244         [DefaultValue(100f)]
     245         public float ValueMaxLeft
     246         {
     247             get
     248             {
     249                 return value_max_left;
     250             }
     251             set
     252             {
     253                 value_max_left = value;
     254                 Invalidate();
     255             }
     256         }
     257 
     258         /// <summary>
     259         /// Gets or sets the value minimum left.
     260         /// </summary>
     261         /// <value>The value minimum left.</value>
     262         [Category("自定义")]
     263         [Description("获取或设置图形的左纵坐标的最小值,该值必须小于最大值")]
     264         [Browsable(true)]
     265         [DefaultValue(0f)]
     266         public float ValueMinLeft
     267         {
     268             get
     269             {
     270                 return value_min_left;
     271             }
     272             set
     273             {
     274                 value_min_left = value;
     275                 Invalidate();
     276             }
     277         }
     278 
     279         /// <summary>
     280         /// Gets or sets the value maximum right.
     281         /// </summary>
     282         /// <value>The value maximum right.</value>
     283         [Category("自定义")]
     284         [Description("获取或设置图形的右纵坐标的最大值,该值必须大于最小值")]
     285         [Browsable(true)]
     286         [DefaultValue(100f)]
     287         public float ValueMaxRight
     288         {
     289             get
     290             {
     291                 return value_max_right;
     292             }
     293             set
     294             {
     295                 value_max_right = value;
     296                 Invalidate();
     297             }
     298         }
     299 
     300         /// <summary>
     301         /// Gets or sets the value minimum right.
     302         /// </summary>
     303         /// <value>The value minimum right.</value>
     304         [Category("自定义")]
     305         [Description("获取或设置图形的右纵坐标的最小值,该值必须小于最大值")]
     306         [Browsable(true)]
     307         [DefaultValue(0f)]
     308         public float ValueMinRight
     309         {
     310             get
     311             {
     312                 return value_min_right;
     313             }
     314             set
     315             {
     316                 value_min_right = value;
     317                 Invalidate();
     318             }
     319         }
     320 
     321         /// <summary>
     322         /// Gets or sets the value segment.
     323         /// </summary>
     324         /// <value>The value segment.</value>
     325         [Category("自定义")]
     326         [Description("获取或设置图形的纵轴分段数")]
     327         [Browsable(true)]
     328         [DefaultValue(5)]
     329         public int ValueSegment
     330         {
     331             get
     332             {
     333                 return value_Segment;
     334             }
     335             set
     336             {
     337                 value_Segment = value;
     338                 Invalidate();
     339             }
     340         }
     341 
     342         /// <summary>
     343         /// Gets or sets a value indicating whether this instance is abscissa strech.
     344         /// </summary>
     345         /// <value><c>true</c> if this instance is abscissa strech; otherwise, <c>false</c>.</value>
     346         [Category("自定义")]
     347         [Description("获取或设置所有的数据是否强制在一个界面里显示")]
     348         [Browsable(true)]
     349         [DefaultValue(false)]
     350         public bool IsAbscissaStrech
     351         {
     352             get
     353             {
     354                 return value_IsAbscissaStrech;
     355             }
     356             set
     357             {
     358                 value_IsAbscissaStrech = value;
     359                 Invalidate();
     360             }
     361         }
     362 
     363         /// <summary>
     364         /// Gets or sets the strech data count maximum.
     365         /// </summary>
     366         /// <value>The strech data count maximum.</value>
     367         [Category("自定义")]
     368         [Description("获取或设置拉伸模式下的最大数据量")]
     369         [Browsable(true)]
     370         [DefaultValue(300)]
     371         public int StrechDataCountMax
     372         {
     373             get
     374             {
     375                 return value_StrechDataCountMax;
     376             }
     377             set
     378             {
     379                 value_StrechDataCountMax = value;
     380                 Invalidate();
     381             }
     382         }
     383 
     384         /// <summary>
     385         /// Gets or sets a value indicating whether this instance is render dash line.
     386         /// </summary>
     387         /// <value><c>true</c> if this instance is render dash line; otherwise, <c>false</c>.</value>
     388         [Category("自定义")]
     389         [Description("获取或设置虚线是否进行显示")]
     390         [Browsable(true)]
     391         [DefaultValue(true)]
     392         public bool IsRenderDashLine
     393         {
     394             get
     395             {
     396                 return value_IsRenderDashLine;
     397             }
     398             set
     399             {
     400                 value_IsRenderDashLine = value;
     401                 Invalidate();
     402             }
     403         }
     404 
     405         /// <summary>
     406         /// Gets or sets the color lines and text.
     407         /// </summary>
     408         /// <value>The color lines and text.</value>
     409         [Category("自定义")]
     410         [Description("获取或设置坐标轴及相关信息文本的颜色")]
     411         [Browsable(true)]
     412         [DefaultValue(typeof(Color), "DimGray")]
     413         public Color ColorLinesAndText
     414         {
     415             get
     416             {
     417                 return color_deep;
     418             }
     419             set
     420             {
     421                 color_deep = value;
     422                 InitializationColor();
     423                 Invalidate();
     424             }
     425         }
     426 
     427         /// <summary>
     428         /// Gets or sets the color dash lines.
     429         /// </summary>
     430         /// <value>The color dash lines.</value>
     431         [Category("自定义")]
     432         [Description("获取或设置虚线的颜色")]
     433         [Browsable(true)]
     434         public Color ColorDashLines
     435         {
     436             get
     437             {
     438                 return color_dash;
     439             }
     440             set
     441             {
     442                 color_dash = value;
     443                 if (pen_dash != null)
     444                     pen_dash.Dispose();
     445                 pen_dash = new Pen(color_dash);
     446                 pen_dash.DashStyle = DashStyle.Custom;
     447                 pen_dash.DashPattern = new float[2]
     448                 {
     449                     5f,
     450                     5f
     451                 };
     452                 Invalidate();
     453             }
     454         }
     455 
     456         /// <summary>
     457         /// Gets or sets the interval abscissa text.
     458         /// </summary>
     459         /// <value>The interval abscissa text.</value>
     460         [Category("自定义")]
     461         [Description("获取或设置纵向虚线的分隔情况,单位为多少个数据")]
     462         [Browsable(true)]
     463         [DefaultValue(100)]
     464         public int IntervalAbscissaText
     465         {
     466             get
     467             {
     468                 return value_IntervalAbscissaText;
     469             }
     470             set
     471             {
     472                 value_IntervalAbscissaText = value;
     473                 Invalidate();
     474             }
     475         }
     476 
     477         /// <summary>
     478         /// Gets or sets the text add format.
     479         /// </summary>
     480         /// <value>The text add format.</value>
     481         [Category("自定义")]
     482         [Description("获取或设置实时数据新增时文本相对应于时间的格式化字符串,默认HH:mm")]
     483         [Browsable(true)]
     484         [DefaultValue("HH:mm")]
     485         public string TextAddFormat
     486         {
     487             get
     488             {
     489                 return textFormat;
     490             }
     491             set
     492             {
     493                 textFormat = value;
     494                 Invalidate();
     495             }
     496         }
     497 
     498         /// <summary>
     499         /// Gets or sets the title.
     500         /// </summary>
     501         /// <value>The title.</value>
     502         [Category("自定义")]
     503         [Description("获取或设置图标的标题信息")]
     504         [Browsable(true)]
     505         [DefaultValue("")]
     506         public string Title
     507         {
     508             get
     509             {
     510                 return value_title;
     511             }
     512             set
     513             {
     514                 value_title = value;
     515                 Invalidate();
     516             }
     517         }
     518 
     519         /// <summary>
     520         /// Gets or sets a value indicating whether this instance is render right coordinate.
     521         /// </summary>
     522         /// <value><c>true</c> if this instance is render right coordinate; otherwise, <c>false</c>.</value>
     523         [Category("自定义")]
     524         [Description("获取或设置是否显示右侧的坐标系信息")]
     525         [Browsable(true)]
     526         [DefaultValue(true)]
     527         public bool IsRenderRightCoordinate
     528         {
     529             get
     530             {
     531                 return isRenderRightCoordinate;
     532             }
     533             set
     534             {
     535                 isRenderRightCoordinate = value;
     536                 Invalidate();
     537             }
     538         }
     539 
     540         /// <summary>
     541         /// Gets or sets the width of the curve name.
     542         /// </summary>
     543         /// <value>The width of the curve name.</value>
     544         [Browsable(true)]
     545         [Description("获取或设置曲线名称的布局宽度")]
     546         [Category("自定义")]
     547         [DefaultValue(100)]
     548         public int CurveNameWidth
     549         {
     550             get
     551             {
     552                 return curveNameWidth;
     553             }
     554             set
     555             {
     556                 if (value > 10)
     557                 {
     558                     curveNameWidth = value;
     559                 }
     560             }
     561         }
     562 
     563         /// <summary>
     564         /// Initializes a new instance of the <see cref="UCCurve" /> class.
     565         /// </summary>
     566         public UCCurve()
     567         {
     568             InitializeComponent();
     569             random = new Random();
     570             data_list = new Dictionary<string, CurveItem>();
     571             auxiliary_lines = new List<AuxiliaryLine>();
     572             MarkTexts = new List<MarkText>();
     573             auxiliary_Labels = new List<AuxiliaryLable>();
     574             format_left = new StringFormat
     575             {
     576                 LineAlignment = StringAlignment.Center,
     577                 Alignment = StringAlignment.Near
     578             };
     579             format_right = new StringFormat
     580             {
     581                 LineAlignment = StringAlignment.Center,
     582                 Alignment = StringAlignment.Far
     583             };
     584             format_center = new StringFormat
     585             {
     586                 LineAlignment = StringAlignment.Center,
     587                 Alignment = StringAlignment.Center
     588             };
     589             font_size9 = new Font("微软雅黑", 9f);
     590             font_size12 = new Font("微软雅黑", 12f);
     591             InitializationColor();
     592             pen_dash = new Pen(color_deep);
     593             pen_dash.DashStyle = DashStyle.Custom;
     594             pen_dash.DashPattern = new float[2]
     595             {
     596                 5f,
     597                 5f
     598             };
     599             SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
     600             SetStyle(ControlStyles.ResizeRedraw, true);
     601             SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
     602             SetStyle(ControlStyles.AllPaintingInWmPaint, true);
     603         }
     604 
     605         /// <summary>
     606         /// Initializations the color.
     607         /// </summary>
     608         private void InitializationColor()
     609         {
     610             if (pen_normal != null)
     611                 pen_normal.Dispose();
     612             if (brush_deep != null)
     613                 brush_deep.Dispose();
     614             pen_normal = new Pen(color_deep);
     615             brush_deep = new SolidBrush(color_deep);
     616         }
     617 
     618         /// <summary>
     619         /// Sets the curve text.
     620         /// </summary>
     621         /// <param name="descriptions">The descriptions.</param>
     622         public void SetCurveText(string[] descriptions)
     623         {
     624             data_text = descriptions;
     625             Invalidate();
     626         }
     627 
     628         /// <summary>
     629         /// Sets the left curve.
     630         /// </summary>
     631         /// <param name="key">The key.</param>
     632         /// <param name="data">The data.</param>
     633         /// <param name="lineColor">Color of the line.</param>
     634         public void SetLeftCurve(string key, float[] data, Color? lineColor = null)
     635         {
     636             SetCurve(key, true, data, lineColor, 1f, false);
     637         }
     638 
     639         /// <summary>
     640         /// Sets the left curve.
     641         /// </summary>
     642         /// <param name="key">The key.</param>
     643         /// <param name="data">The data.</param>
     644         /// <param name="lineColor">Color of the line.</param>
     645         /// <param name="isSmooth">if set to <c>true</c> [is smooth].</param>
     646         public void SetLeftCurve(string key, float[] data, Color? lineColor, bool isSmooth = false)
     647         {
     648             SetCurve(key, true, data, lineColor, 1f, isSmooth);
     649         }
     650 
     651         /// <summary>
     652         /// Sets the right curve.
     653         /// </summary>
     654         /// <param name="key">The key.</param>
     655         /// <param name="data">The data.</param>
     656         /// <param name="lineColor">Color of the line.</param>
     657         public void SetRightCurve(string key, float[] data, Color? lineColor = null)
     658         {
     659             SetCurve(key, false, data, lineColor, 1f, false);
     660         }
     661 
     662         /// <summary>
     663         /// Sets the right curve.
     664         /// </summary>
     665         /// <param name="key">The key.</param>
     666         /// <param name="data">The data.</param>
     667         /// <param name="lineColor">Color of the line.</param>
     668         /// <param name="isSmooth">if set to <c>true</c> [is smooth].</param>
     669         public void SetRightCurve(string key, float[] data, Color? lineColor, bool isSmooth = false)
     670         {
     671             SetCurve(key, false, data, lineColor, 1f, isSmooth);
     672         }
     673 
     674         /// <summary>
     675         /// Sets the curve.
     676         /// </summary>
     677         /// <param name="key">The key.</param>
     678         /// <param name="isLeft">if set to <c>true</c> [is left].</param>
     679         /// <param name="data">The data.</param>
     680         /// <param name="lineColor">Color of the line.</param>
     681         /// <param name="thickness">The thickness.</param>
     682         /// <param name="isSmooth">if set to <c>true</c> [is smooth].</param>
     683         public void SetCurve(string key, bool isLeft, float[] data, Color? lineColor, float thickness, bool isSmooth)
     684         {
     685             if (data_list.ContainsKey(key))
     686             {
     687                 if (data == null)
     688                 {
     689                     data = new float[0];
     690                 }
     691                 data_list[key].Data = data;
     692             }
     693             else
     694             {
     695                 if (data == null)
     696                 {
     697                     data = new float[0];
     698                 }
     699                 data_list.Add(key, new CurveItem
     700                 {
     701                     Data = data,
     702                     MarkText = new string[data.Length],
     703                     LineThickness = thickness,
     704                     LineColor = lineColor ?? ControlHelper.Colors[data_list.Count + 13],
     705                     IsLeftFrame = isLeft,
     706                     IsSmoothCurve = isSmooth
     707                 });
     708                 if (data_text == null)
     709                 {
     710                     data_text = new string[data.Length];
     711                 }
     712             }
     713             Invalidate();
     714         }
     715 
     716         /// <summary>
     717         /// Removes the curve.
     718         /// </summary>
     719         /// <param name="key">The key.</param>
     720         public void RemoveCurve(string key)
     721         {
     722             if (data_list.ContainsKey(key))
     723             {
     724                 data_list.Remove(key);
     725             }
     726             if (data_list.Count == 0)
     727             {
     728                 data_text = new string[0];
     729             }
     730             Invalidate();
     731         }
     732 
     733         /// <summary>
     734         /// Removes all curve.
     735         /// </summary>
     736         public void RemoveAllCurve()
     737         {
     738             int count = data_list.Count;
     739             data_list.Clear();
     740             if (data_list.Count == 0)
     741             {
     742                 data_text = new string[0];
     743             }
     744             if (count > 0)
     745             {
     746                 Invalidate();
     747             }
     748         }
     749 
     750         /// <summary>
     751         /// Removes all curve data.
     752         /// </summary>
     753         public void RemoveAllCurveData()
     754         {
     755             int count = data_list.Count;
     756             foreach (KeyValuePair<string, CurveItem> item in data_list)
     757             {
     758                 item.Value.Data = new float[0];
     759                 item.Value.MarkText = new string[0];
     760             }
     761             data_text = new string[0];
     762             if (count > 0)
     763             {
     764                 Invalidate();
     765             }
     766         }
     767 
     768         /// <summary>
     769         /// Gets the curve item.
     770         /// </summary>
     771         /// <param name="key">The key.</param>
     772         /// <returns>CurveItem.</returns>
     773         public CurveItem GetCurveItem(string key)
     774         {
     775             if (data_list.ContainsKey(key))
     776             {
     777                 return data_list[key];
     778             }
     779             return null;
     780         }
     781 
     782         /// <summary>
     783         /// Saves to bitmap.
     784         /// </summary>
     785         /// <returns>Bitmap.</returns>
     786         public Bitmap SaveToBitmap()
     787         {
     788             return SaveToBitmap(base.Width, base.Height);
     789         }
     790 
     791         /// <summary>
     792         /// Saves to bitmap.
     793         /// </summary>
     794         /// <param name="width">The width.</param>
     795         /// <param name="height">The height.</param>
     796         /// <returns>Bitmap.</returns>
     797         public Bitmap SaveToBitmap(int width, int height)
     798         {
     799             Bitmap bitmap = new Bitmap(width, height);
     800             Graphics graphics = Graphics.FromImage(bitmap);
     801             OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, width, height)));
     802             return bitmap;
     803         }
     804 
     805         /// <summary>
     806         /// Adds the curve data.
     807         /// </summary>
     808         /// <param name="key">The key.</param>
     809         /// <param name="values">The values.</param>
     810         /// <param name="markTexts">The mark texts.</param>
     811         /// <param name="isUpdateUI">if set to <c>true</c> [is update UI].</param>
     812         private void AddCurveData(string key, float[] values, string[] markTexts, bool isUpdateUI)
     813         {
     814             if ((values != null && values.Length < 1) || !data_list.ContainsKey(key))
     815             {
     816                 return;
     817             }
     818             CurveItem CurveItem = data_list[key];
     819             if (CurveItem.Data != null)
     820             {
     821                 if (value_IsAbscissaStrech)
     822                 {
     823                     ControlHelper.AddArrayData(ref CurveItem.Data, values, value_StrechDataCountMax);
     824                     ControlHelper.AddArrayData(ref CurveItem.MarkText, markTexts, value_StrechDataCountMax);
     825                 }
     826                 else
     827                 {
     828                     ControlHelper.AddArrayData(ref CurveItem.Data, values, 4096);
     829                     ControlHelper.AddArrayData(ref CurveItem.MarkText, markTexts, 4096);
     830                 }
     831                 if (isUpdateUI)
     832                 {
     833                     Invalidate();
     834                 }
     835             }
     836         }
     837 
     838         /// <summary>
     839         /// Adds the curve time.
     840         /// </summary>
     841         /// <param name="count">The count.</param>
     842         private void AddCurveTime(int count)
     843         {
     844             AddCurveTime(count, DateTime.Now.ToString(textFormat));
     845         }
     846 
     847         /// <summary>
     848         /// Adds the curve time.
     849         /// </summary>
     850         /// <param name="count">The count.</param>
     851         /// <param name="text">The text.</param>
     852         private void AddCurveTime(int count, string text)
     853         {
     854             if (data_text != null)
     855             {
     856                 string[] array = new string[count];
     857                 for (int i = 0; i < array.Length; i++)
     858                 {
     859                     array[i] = text;
     860                 }
     861                 if (value_IsAbscissaStrech)
     862                 {
     863                     ControlHelper.AddArrayData(ref data_text, array, value_StrechDataCountMax);
     864                 }
     865                 else
     866                 {
     867                     ControlHelper.AddArrayData(ref data_text, array, 4096);
     868                 }
     869             }
     870         }
     871 
     872         /// <summary>
     873         /// Adds the curve data.
     874         /// </summary>
     875         /// <param name="key">The key.</param>
     876         /// <param name="value">The value.</param>
     877         public void AddCurveData(string key, float value)
     878         {
     879             AddCurveData(key, new float[1]
     880             {
     881                 value
     882             });
     883         }
     884 
     885         /// <summary>
     886         /// Adds the curve data.
     887         /// </summary>
     888         /// <param name="key">The key.</param>
     889         /// <param name="value">The value.</param>
     890         /// <param name="markText">The mark text.</param>
     891         public void AddCurveData(string key, float value, string markText)
     892         {
     893             AddCurveData(key, new float[1]
     894             {
     895                 value
     896             }, new string[1]
     897             {
     898                 markText
     899             });
     900         }
     901 
     902         /// <summary>
     903         /// Adds the curve data.
     904         /// </summary>
     905         /// <param name="key">The key.</param>
     906         /// <param name="values">The values.</param>
     907         public void AddCurveData(string key, float[] values)
     908         {
     909             AddCurveData(key, values, null);
     910         }
     911 
     912         /// <summary>
     913         /// Adds the curve data.
     914         /// </summary>
     915         /// <param name="key">The key.</param>
     916         /// <param name="values">The values.</param>
     917         /// <param name="markTexts">The mark texts.</param>
     918         public void AddCurveData(string key, float[] values, string[] markTexts)
     919         {
     920             if (markTexts == null)
     921             {
     922                 markTexts = new string[values.Length];
     923             }
     924             AddCurveData(key, values, markTexts, false);
     925             if (values != null && values.Length != 0)
     926             {
     927                 AddCurveTime(values.Length);
     928             }
     929             Invalidate();
     930         }
     931 
     932         /// <summary>
     933         /// Adds the curve data.
     934         /// </summary>
     935         /// <param name="keys">The keys.</param>
     936         /// <param name="values">The values.</param>
     937         public void AddCurveData(string[] keys, float[] values)
     938         {
     939             AddCurveData(keys, values, null);
     940         }
     941 
     942         /// <summary>
     943         /// Adds the curve data.
     944         /// </summary>
     945         /// <param name="axisText">The axis text.</param>
     946         /// <param name="keys">The keys.</param>
     947         /// <param name="values">The values.</param>
     948         public void AddCurveData(string axisText, string[] keys, float[] values)
     949         {
     950             AddCurveData(axisText, keys, values, null);
     951         }
     952 
     953         /// <summary>
     954         /// Adds the curve data.
     955         /// </summary>
     956         /// <param name="keys">The keys.</param>
     957         /// <param name="values">The values.</param>
     958         /// <param name="markTexts">The mark texts.</param>
     959         /// <exception cref="ArgumentNullException">keys
     960         /// or
     961         /// values</exception>
     962         /// <exception cref="Exception">两个参数的数组长度不一致。
     963         /// or
     964         /// 两个参数的数组长度不一致。</exception>
     965         public void AddCurveData(string[] keys, float[] values, string[] markTexts)
     966         {
     967             if (keys == null)
     968             {
     969                 throw new ArgumentNullException("keys");
     970             }
     971             if (values == null)
     972             {
     973                 throw new ArgumentNullException("values");
     974             }
     975             if (markTexts == null)
     976             {
     977                 markTexts = new string[keys.Length];
     978             }
     979             if (keys.Length != values.Length)
     980             {
     981                 throw new Exception("两个参数的数组长度不一致。");
     982             }
     983             if (keys.Length != markTexts.Length)
     984             {
     985                 throw new Exception("两个参数的数组长度不一致。");
     986             }
     987             for (int i = 0; i < keys.Length; i++)
     988             {
     989                 AddCurveData(keys[i], new float[1]
     990                 {
     991                     values[i]
     992                 }, new string[1]
     993                 {
     994                     markTexts[i]
     995                 }, false);
     996             }
     997             AddCurveTime(1);
     998             Invalidate();
     999         }
    1000 
    1001         /// <summary>
    1002         /// Adds the curve data.
    1003         /// </summary>
    1004         /// <param name="axisText">The axis text.</param>
    1005         /// <param name="keys">The keys.</param>
    1006         /// <param name="values">The values.</param>
    1007         /// <param name="markTexts">The mark texts.</param>
    1008         /// <exception cref="ArgumentNullException">keys
    1009         /// or
    1010         /// values</exception>
    1011         /// <exception cref="Exception">两个参数的数组长度不一致。
    1012         /// or
    1013         /// 两个参数的数组长度不一致。</exception>
    1014         public void AddCurveData(string axisText, string[] keys, float[] values, string[] markTexts)
    1015         {
    1016             if (keys == null)
    1017             {
    1018                 throw new ArgumentNullException("keys");
    1019             }
    1020             if (values == null)
    1021             {
    1022                 throw new ArgumentNullException("values");
    1023             }
    1024             if (markTexts == null)
    1025             {
    1026                 markTexts = new string[keys.Length];
    1027             }
    1028             if (keys.Length != values.Length)
    1029             {
    1030                 throw new Exception("两个参数的数组长度不一致。");
    1031             }
    1032             if (keys.Length != markTexts.Length)
    1033             {
    1034                 throw new Exception("两个参数的数组长度不一致。");
    1035             }
    1036             for (int i = 0; i < keys.Length; i++)
    1037             {
    1038                 AddCurveData(keys[i], new float[1]
    1039                 {
    1040                     values[i]
    1041                 }, new string[1]
    1042                 {
    1043                     markTexts[i]
    1044                 }, false);
    1045             }
    1046             AddCurveTime(1, axisText);
    1047             Invalidate();
    1048         }
    1049 
    1050         /// <summary>
    1051         /// Sets the curve visible.
    1052         /// </summary>
    1053         /// <param name="key">The key.</param>
    1054         /// <param name="visible">if set to <c>true</c> [visible].</param>
    1055         public void SetCurveVisible(string key, bool visible)
    1056         {
    1057             if (data_list.ContainsKey(key))
    1058             {
    1059                 CurveItem CurveItem = data_list[key];
    1060                 CurveItem.Visible = visible;
    1061                 Invalidate();
    1062             }
    1063         }
    1064 
    1065         /// <summary>
    1066         /// Sets the curve visible.
    1067         /// </summary>
    1068         /// <param name="keys">The keys.</param>
    1069         /// <param name="visible">if set to <c>true</c> [visible].</param>
    1070         public void SetCurveVisible(string[] keys, bool visible)
    1071         {
    1072             foreach (string key in keys)
    1073             {
    1074                 if (data_list.ContainsKey(key))
    1075                 {
    1076                     CurveItem CurveItem = data_list[key];
    1077                     CurveItem.Visible = visible;
    1078                 }
    1079             }
    1080             Invalidate();
    1081         }
    1082 
    1083         /// <summary>
    1084         /// Adds the left auxiliary.
    1085         /// </summary>
    1086         /// <param name="value">The value.</param>
    1087         public void AddLeftAuxiliary(float value)
    1088         {
    1089             AddLeftAuxiliary(value, ColorLinesAndText);
    1090         }
    1091 
    1092         /// <summary>
    1093         /// Adds the left auxiliary.
    1094         /// </summary>
    1095         /// <param name="value">The value.</param>
    1096         /// <param name="lineColor">Color of the line.</param>
    1097         public void AddLeftAuxiliary(float value, Color lineColor)
    1098         {
    1099             AddLeftAuxiliary(value, lineColor, 1f, true);
    1100         }
    1101 
    1102         /// <summary>
    1103         /// Adds the left auxiliary.
    1104         /// </summary>
    1105         /// <param name="value">The value.</param>
    1106         /// <param name="lineColor">Color of the line.</param>
    1107         /// <param name="lineThickness">The line thickness.</param>
    1108         /// <param name="isDashLine">if set to <c>true</c> [is dash line].</param>
    1109         public void AddLeftAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine)
    1110         {
    1111             AddAuxiliary(value, lineColor, lineThickness, isDashLine, true);
    1112         }
    1113 
    1114         /// <summary>
    1115         /// Adds the right auxiliary.
    1116         /// </summary>
    1117         /// <param name="value">The value.</param>
    1118         public void AddRightAuxiliary(float value)
    1119         {
    1120             AddRightAuxiliary(value, ColorLinesAndText);
    1121         }
    1122 
    1123         /// <summary>
    1124         /// Adds the right auxiliary.
    1125         /// </summary>
    1126         /// <param name="value">The value.</param>
    1127         /// <param name="lineColor">Color of the line.</param>
    1128         public void AddRightAuxiliary(float value, Color lineColor)
    1129         {
    1130             AddRightAuxiliary(value, lineColor, 1f, true);
    1131         }
    1132 
    1133         /// <summary>
    1134         /// Adds the right auxiliary.
    1135         /// </summary>
    1136         /// <param name="value">The value.</param>
    1137         /// <param name="lineColor">Color of the line.</param>
    1138         /// <param name="lineThickness">The line thickness.</param>
    1139         /// <param name="isDashLine">if set to <c>true</c> [is dash line].</param>
    1140         public void AddRightAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine)
    1141         {
    1142             AddAuxiliary(value, lineColor, lineThickness, isDashLine, false);
    1143         }
    1144 
    1145         /// <summary>
    1146         /// Adds the auxiliary.
    1147         /// </summary>
    1148         /// <param name="value">The value.</param>
    1149         /// <param name="lineColor">Color of the line.</param>
    1150         /// <param name="lineThickness">The line thickness.</param>
    1151         /// <param name="isDashLine">if set to <c>true</c> [is dash line].</param>
    1152         /// <param name="isLeft">if set to <c>true</c> [is left].</param>
    1153         private void AddAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine, bool isLeft)
    1154         {
    1155             auxiliary_lines.Add(new AuxiliaryLine
    1156             {
    1157                 Value = value,
    1158                 LineColor = lineColor,
    1159                 PenDash = new Pen(lineColor)
    1160                 {
    1161                     DashStyle = DashStyle.Custom,
    1162                     DashPattern = new float[2]
    1163                     {
    1164                         5f,
    1165                         5f
    1166                     }
    1167                 },
    1168                 PenSolid = new Pen(lineColor),
    1169                 IsDashStyle = isDashLine,
    1170                 IsLeftFrame = isLeft,
    1171                 LineThickness = lineThickness,
    1172                 LineTextBrush = new SolidBrush(lineColor)
    1173             });
    1174             Invalidate();
    1175         }
    1176 
    1177         /// <summary>
    1178         /// Removes the auxiliary.
    1179         /// </summary>
    1180         /// <param name="value">The value.</param>
    1181         public void RemoveAuxiliary(float value)
    1182         {
    1183             int num = 0;
    1184             for (int num2 = auxiliary_lines.Count - 1; num2 >= 0; num2--)
    1185             {
    1186                 if (auxiliary_lines[num2].Value == value)
    1187                 {
    1188                     auxiliary_lines[num2].Dispose();
    1189                     auxiliary_lines.RemoveAt(num2);
    1190                     num++;
    1191                 }
    1192             }
    1193             if (num > 0)
    1194             {
    1195                 Invalidate();
    1196             }
    1197         }
    1198 
    1199         /// <summary>
    1200         /// Removes all auxiliary.
    1201         /// </summary>
    1202         public void RemoveAllAuxiliary()
    1203         {
    1204             int count = auxiliary_lines.Count;
    1205             auxiliary_lines.Clear();
    1206             if (count > 0)
    1207             {
    1208                 Invalidate();
    1209             }
    1210         }
    1211 
    1212         /// <summary>
    1213         /// Adds the auxiliary label.
    1214         /// </summary>
    1215         /// <param name="auxiliaryLable">The auxiliary lable.</param>
    1216         public void AddAuxiliaryLabel(AuxiliaryLable auxiliaryLable)
    1217         {
    1218             auxiliary_Labels.Add(auxiliaryLable);
    1219         }
    1220 
    1221         /// <summary>
    1222         /// Removes the auxiliary lable.
    1223         /// </summary>
    1224         /// <param name="auxiliaryLable">The auxiliary lable.</param>
    1225         public void RemoveAuxiliaryLable(AuxiliaryLable auxiliaryLable)
    1226         {
    1227             if (auxiliary_Labels.Remove(auxiliaryLable))
    1228             {
    1229                 Invalidate();
    1230             }
    1231         }
    1232 
    1233         /// <summary>
    1234         /// Removes all auxiliary lable.
    1235         /// </summary>
    1236         public void RemoveAllAuxiliaryLable()
    1237         {
    1238             int count = auxiliary_Labels.Count;
    1239             auxiliary_Labels.Clear();
    1240             if (count > 0)
    1241             {
    1242                 Invalidate();
    1243             }
    1244         }
    1245 
    1246         /// <summary>
    1247         /// Adds the mark text.
    1248         /// </summary>
    1249         /// <param name="markText">The mark text.</param>
    1250         public void AddMarkText(MarkText markText)
    1251         {
    1252             MarkTexts.Add(markText);
    1253             if (data_list.Count > 0)
    1254             {
    1255                 Invalidate();
    1256             }
    1257         }
    1258 
    1259         /// <summary>
    1260         /// Adds the mark text.
    1261         /// </summary>
    1262         /// <param name="strCurveKey">The string curve key.</param>
    1263         /// <param name="intValueIndex">Index of the int value.</param>
    1264         /// <param name="strText">The string text.</param>
    1265         /// <param name="textColor">Color of the text.</param>
    1266         public void AddMarkText(string strCurveKey, int intValueIndex, string strText, Color? textColor = null)
    1267         {
    1268             AddMarkText(new MarkText() { CurveKey = strCurveKey, PositionStyle = MarkTextPositionStyle.Auto, Text = strText, TextColor = textColor, Index = intValueIndex });
    1269         }
    1270 
    1271         /// <summary>
    1272         /// Removes the mark text.
    1273         /// </summary>
    1274         /// <param name="markText">The mark text.</param>
    1275         public void RemoveMarkText(MarkText markText)
    1276         {
    1277             MarkTexts.Remove(markText);
    1278             if (data_list.Count > 0)
    1279             {
    1280                 Invalidate();
    1281             }
    1282         }
    1283 
    1284         /// <summary>
    1285         /// Removes all mark text.
    1286         /// </summary>
    1287         public void RemoveAllMarkText()
    1288         {
    1289             MarkTexts.Clear();
    1290             if (data_list.Count > 0)
    1291             {
    1292                 Invalidate();
    1293             }
    1294         }
    1295 
    1296         /// <summary>
    1297         /// 引发 <see cref="E:System.Windows.Forms.Control.MouseMove" /> 事件。
    1298         /// </summary>
    1299         /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.MouseEventArgs" /></param>
    1300         protected override void OnMouseMove(MouseEventArgs e)
    1301         {
    1302             base.OnMouseMove(e);
    1303             bool flag = false;
    1304             foreach (KeyValuePair<string, CurveItem> item in data_list)
    1305             {
    1306                 if (item.Value.TitleRegion.Contains(e.Location))
    1307                 {
    1308                     flag = true;
    1309                     break;
    1310                 }
    1311             }
    1312             Cursor = (flag ? Cursors.Hand : Cursors.Arrow);
    1313         }
    1314 
    1315         /// <summary>
    1316         /// Handles the <see cref="E:MouseDown" /> event.
    1317         /// </summary>
    1318         /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.MouseEventArgs" /></param>
    1319         protected override void OnMouseDown(MouseEventArgs e)
    1320         {
    1321             base.OnMouseDown(e);
    1322             foreach (KeyValuePair<string, CurveItem> item in data_list)
    1323             {
    1324                 if (item.Value.TitleRegion.Contains(e.Location))
    1325                 {
    1326                     item.Value.LineRenderVisiable = !item.Value.LineRenderVisiable;
    1327                     Invalidate();
    1328                     break;
    1329                 }
    1330             }
    1331         }
    1332 
    1333         /// <summary>
    1334         /// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
    1335         /// </summary>
    1336         /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" /></param>
    1337         protected override void OnPaint(PaintEventArgs e)
    1338         {
    1339             try
    1340             {
    1341                 Graphics graphics = e.Graphics;
    1342                 graphics.SetGDIHigh();
    1343                 if (BackColor != Color.Transparent)
    1344                 {
    1345                     graphics.Clear(BackColor);
    1346                 }
    1347                 int width = base.Width;
    1348                 int height = base.Height;
    1349                 if (width < 120 || height < 60)
    1350                 {
    1351                     return;
    1352                 }
    1353                 Point[] array = new Point[4]
    1354                 {
    1355                     new Point(leftRight - 1, upDowm - 8),
    1356                     new Point(leftRight - 1, height - upDowm),
    1357                     new Point(width - leftRight, height - upDowm),
    1358                     new Point(width - leftRight, upDowm - 8)
    1359                 };
    1360                 graphics.DrawLine(pen_normal, array[0], array[1]);
    1361                 graphics.DrawLine(pen_normal, array[1], array[2]);
    1362                 if (isRenderRightCoordinate)
    1363                 {
    1364                     graphics.DrawLine(pen_normal, array[2], array[3]);
    1365                 }
    1366 
    1367                 if (!string.IsNullOrEmpty(value_title))
    1368                 {
    1369                     graphics.DrawString(value_title, font_size9, brush_deep, new Rectangle(0, 0, width - 1, 20), format_center);
    1370                 }
    1371 
    1372                 if (data_list.Count > 0)
    1373                 {
    1374                     float num = leftRight + 10;
    1375                     foreach (KeyValuePair<string, CurveItem> item in data_list)
    1376                     {
    1377                         if (item.Value.Visible)
    1378                         {
    1379                             var titleSize=graphics.MeasureString(item.Key, Font);
    1380                             SolidBrush solidBrush = item.Value.LineRenderVisiable ? new SolidBrush(item.Value.LineColor) : new SolidBrush(Color.FromArgb(80, item.Value.LineColor));
    1381                             graphics.FillRectangle(solidBrush, num + 8f, 24f, 20f, 14f);
    1382                             graphics.DrawString(item.Key, Font, solidBrush, new PointF(num + 30f, 24f+(14 - titleSize.Height) / 2));
    1383                             item.Value.TitleRegion = new RectangleF(num, 24f, 60f, 18f);
    1384                             solidBrush.Dispose();
    1385                             num += titleSize.Width + 30;
    1386                         }
    1387                     }
    1388                 }
    1389 
    1390 
    1391                 for (int i = 0; i < auxiliary_Labels.Count; i++)
    1392                 {
    1393                     if (!string.IsNullOrEmpty(auxiliary_Labels[i].Text))
    1394                     {
    1395                         int num2 = (auxiliary_Labels[i].LocationX > 1f) ? ((int)auxiliary_Labels[i].LocationX) : ((int)(auxiliary_Labels[i].LocationX * (float)width));
    1396                         int num3 = (int)graphics.MeasureString(auxiliary_Labels[i].Text, Font).Width + 3;
    1397                         Point[] points = new Point[6]
    1398                     {
    1399                         new Point(num2, 11),
    1400                         new Point(num2 + 10, 20),
    1401                         new Point(num2 + num3 + 10, 20),
    1402                         new Point(num2 + num3 + 10, 0),
    1403                         new Point(num2 + 10, 0),
    1404                         new Point(num2, 11)
    1405                     };
    1406                         graphics.FillPolygon(auxiliary_Labels[i].TextBack, points);
    1407                         graphics.DrawString(auxiliary_Labels[i].Text, Font, auxiliary_Labels[i].TextBrush, new Rectangle(num2 + 7, 0, num3 + 3, 20), format_center);
    1408                     }
    1409                 }
    1410                 ControlHelper.PaintTriangle(graphics, brush_deep, new Point(leftRight - 1, upDowm - 8), 4, GraphDirection.Upward);
    1411                 if (isRenderRightCoordinate)
    1412                 {
    1413                     ControlHelper.PaintTriangle(graphics, brush_deep, new Point(width - leftRight, upDowm - 8), 4, GraphDirection.Upward);
    1414                 }
    1415                 for (int j = 0; j < auxiliary_lines.Count; j++)
    1416                 {
    1417                     if (auxiliary_lines[j].IsLeftFrame)
    1418                     {
    1419                         auxiliary_lines[j].PaintValue = ControlHelper.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, auxiliary_lines[j].Value) + (float)upDowm;
    1420                     }
    1421                     else
    1422                     {
    1423                         auxiliary_lines[j].PaintValue = ControlHelper.ComputePaintLocationY(value_max_right, value_min_right, height - upDowm - upDowm, auxiliary_lines[j].Value) + (float)upDowm;
    1424                     }
    1425                 }
    1426                 for (int k = 0; k <= value_Segment; k++)
    1427                 {
    1428                     float value = (float)((double)k * (double)(value_max_left - value_min_left) / (double)value_Segment + (double)value_min_left);
    1429                     float num4 = ControlHelper.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, value) + (float)upDowm;
    1430                     if (IsNeedPaintDash(num4))
    1431                     {
    1432                         graphics.DrawLine(pen_normal, leftRight - 4, num4, leftRight - 1, num4);
    1433                         RectangleF layoutRectangle = new RectangleF(0f, num4 - 9f, leftRight - 4, 20f);
    1434                         graphics.DrawString(value.ToString(), font_size9, brush_deep, layoutRectangle, format_right);
    1435                         if (isRenderRightCoordinate)
    1436                         {
    1437                             float num5 = (float)k * (value_max_right - value_min_right) / (float)value_Segment + value_min_right;
    1438                             graphics.DrawLine(pen_normal, width - leftRight + 1, num4, width - leftRight + 4, num4);
    1439                             layoutRectangle.Location = new PointF(width - leftRight + 4, num4 - 9f);
    1440                             graphics.DrawString(num5.ToString(), font_size9, brush_deep, layoutRectangle, format_left);
    1441                         }
    1442                         if (k > 0 && value_IsRenderDashLine)
    1443                         {
    1444                             graphics.DrawLine(pen_dash, leftRight, num4, width - leftRight, num4);
    1445                         }
    1446                     }
    1447                 }
    1448                 if (value_IsRenderDashLine)
    1449                 {
    1450                     if (value_IsAbscissaStrech)
    1451                     {
    1452                         float num6 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
    1453                         int num7 = CalculateDataCountByOffect(num6);
    1454                         for (int l = 0; l < value_StrechDataCountMax; l += num7)
    1455                         {
    1456                             if (l > 0 && l < value_StrechDataCountMax - 1)
    1457                             {
    1458                                 graphics.DrawLine(pen_dash, (float)l * num6 + (float)leftRight, upDowm, (float)l * num6 + (float)leftRight, height - upDowm - 1);
    1459                             }
    1460                             if (data_text != null && l < data_text.Length && (float)l * num6 + (float)leftRight < (float)(data_text.Length - 1) * num6 + (float)leftRight - 40f)
    1461                             {
    1462                                 graphics.DrawString(layoutRectangle: new Rectangle((int)((float)l * num6), height - upDowm + 1, leftRight * 2, upDowm), s: data_text[l], font: font_size9,  brush_deep, format: format_center);
    1463                             }
    1464                         }
    1465                         string[] array2 = data_text;
    1466                         if (array2 != null && array2.Length > 1)
    1467                         {
    1468                             if (data_text.Length < value_StrechDataCountMax)
    1469                             {
    1470                                 graphics.DrawLine(pen_dash, (float)(data_text.Length - 1) * num6 + (float)leftRight, upDowm, (float)(data_text.Length - 1) * num6 + (float)leftRight, height - upDowm - 1);
    1471                             }
    1472                             graphics.DrawString(layoutRectangle: new Rectangle((int)((float)(data_text.Length - 1) * num6 + (float)leftRight) - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[data_text.Length - 1], font: font_size9,  brush_deep, format: format_center);
    1473                         }
    1474                     }
    1475                     else if (value_IntervalAbscissaText > 0)
    1476                     {
    1477                         int num8 = width - 2 * leftRight + 1;
    1478                         for (int m = leftRight; m < width - leftRight; m += value_IntervalAbscissaText)
    1479                         {
    1480                             if (m != leftRight)
    1481                             {
    1482                                 graphics.DrawLine(pen_dash, m, upDowm, m, height - upDowm - 1);
    1483                             }
    1484                             if (data_text == null)
    1485                             {
    1486                                 continue;
    1487                             }
    1488                             int num9 = (num8 > data_text.Length) ? data_text.Length : num8;
    1489                             if (m - leftRight < data_text.Length && num9 - (m - leftRight) > 40)
    1490                             {
    1491                                 if (data_text.Length <= num8)
    1492                                 {
    1493                                     graphics.DrawString(layoutRectangle: new Rectangle(m - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[m - leftRight], font: font_size9,  brush_deep, format: format_center);
    1494                                 }
    1495                                 else
    1496                                 {
    1497                                     graphics.DrawString(layoutRectangle: new Rectangle(m - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[m - leftRight + data_text.Length - num8], font: font_size9,  brush_deep, format: format_center);
    1498                                 }
    1499                             }
    1500                         }
    1501                         string[] array3 = data_text;
    1502                         if (array3 != null && array3.Length > 1)
    1503                         {
    1504                             if (data_text.Length >= num8)
    1505                             {
    1506                                 graphics.DrawString(layoutRectangle: new Rectangle(width - leftRight - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[data_text.Length - 1], font: font_size9,  brush_deep, format: format_center);
    1507                             }
    1508                             else
    1509                             {
    1510                                 graphics.DrawLine(pen_dash, data_text.Length + leftRight - 1, upDowm, data_text.Length + leftRight - 1, height - upDowm - 1);
    1511                                 graphics.DrawString(layoutRectangle: new Rectangle(data_text.Length + leftRight - 1 - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[data_text.Length - 1], font: font_size9,  brush_deep, format: format_center);
    1512                             }
    1513                         }
    1514                     }
    1515                 }
    1516                 for (int n = 0; n < auxiliary_lines.Count; n++)
    1517                 {
    1518                     if (auxiliary_lines[n].IsLeftFrame)
    1519                     {
    1520                         graphics.DrawLine(auxiliary_lines[n].GetPen(), leftRight - 4, auxiliary_lines[n].PaintValue, leftRight - 1, auxiliary_lines[n].PaintValue);
    1521                         graphics.DrawString(layoutRectangle: new RectangleF(0f, auxiliary_lines[n].PaintValue - 9f, leftRight - 4, 20f), s: auxiliary_lines[n].Value.ToString(), font: font_size9,  auxiliary_lines[n].LineTextBrush, format: format_right);
    1522                     }
    1523                     else
    1524                     {
    1525                         graphics.DrawLine(auxiliary_lines[n].GetPen(), width - leftRight + 1, auxiliary_lines[n].PaintValue, width - leftRight + 4, auxiliary_lines[n].PaintValue);
    1526                         graphics.DrawString(layoutRectangle: new RectangleF(width - leftRight + 4, auxiliary_lines[n].PaintValue - 9f, leftRight - 4, 20f), s: auxiliary_lines[n].Value.ToString(), font: font_size9,  auxiliary_lines[n].LineTextBrush, format: format_left);
    1527                     }
    1528                     graphics.DrawLine(auxiliary_lines[n].GetPen(), leftRight, auxiliary_lines[n].PaintValue, width - leftRight, auxiliary_lines[n].PaintValue);
    1529                 }
    1530                 if (value_IsAbscissaStrech)
    1531                 {
    1532                     foreach (MarkText MarkText in MarkTexts)
    1533                     {
    1534                         foreach (KeyValuePair<string, CurveItem> item2 in data_list)
    1535                         {
    1536                             if (item2.Value.Visible && item2.Value.LineRenderVisiable && !(item2.Key != MarkText.CurveKey))
    1537                             {
    1538                                 float[] data = item2.Value.Data;
    1539                                 if (data != null && data.Length > 1)
    1540                                 {
    1541                                     float num10 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
    1542                                     if (MarkText.Index >= 0 && MarkText.Index < item2.Value.Data.Length)
    1543                                     {
    1544                                         PointF pointF = new PointF((float)leftRight + (float)MarkText.Index * num10, ControlHelper.ComputePaintLocationY(item2.Value.IsLeftFrame ? value_max_left : value_max_right, item2.Value.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, item2.Value.Data[MarkText.Index]) + (float)upDowm);
    1545                                         graphics.FillEllipse(new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 3f, pointF.Y - 3f, 6f, 6f));
    1546                                         switch ((MarkText.PositionStyle == MarkTextPositionStyle.Auto) ? MarkText.CalculateDirectionFromDataIndex(item2.Value.Data, MarkText.Index) : MarkText.PositionStyle)
    1547                                         {
    1548                                             case MarkTextPositionStyle.Left:
    1549                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 100f, pointF.Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
    1550                                                 break;
    1551                                             case MarkTextPositionStyle.Up:
    1552                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 100f, pointF.Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    1553                                                 break;
    1554                                             case MarkTextPositionStyle.Right:
    1555                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X + (float)MarkText.MarkTextOffect, pointF.Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
    1556                                                 break;
    1557                                             case MarkTextPositionStyle.Down:
    1558                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 100f, pointF.Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    1559                                                 break;
    1560                                         }
    1561                                     }
    1562                                 }
    1563                             }
    1564                         }
    1565                     }
    1566                     foreach (CurveItem value2 in data_list.Values)
    1567                     {
    1568                         if (value2.Visible && value2.LineRenderVisiable)
    1569                         {
    1570                             float[] data2 = value2.Data;
    1571                             if (data2 != null && data2.Length > 1)
    1572                             {
    1573                                 float num11 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
    1574                                 PointF[] array4 = new PointF[value2.Data.Length];
    1575                                 for (int num12 = 0; num12 < value2.Data.Length; num12++)
    1576                                 {
    1577                                     array4[num12].X = (float)leftRight + (float)num12 * num11;
    1578                                     array4[num12].Y = ControlHelper.ComputePaintLocationY(value2.IsLeftFrame ? value_max_left : value_max_right, value2.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value2.Data[num12]) + (float)upDowm;
    1579                                     if (!string.IsNullOrEmpty(value2.MarkText[num12]))
    1580                                     {
    1581                                         using (Brush brush = new SolidBrush(value2.LineColor))
    1582                                         {
    1583                                             graphics.FillEllipse(brush, new RectangleF(array4[num12].X - 3f, array4[num12].Y - 3f, 6f, 6f));
    1584                                             switch (MarkText.CalculateDirectionFromDataIndex(value2.Data, num12))
    1585                                             {
    1586                                                 case MarkTextPositionStyle.Left:
    1587                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X - 100f, array4[num12].Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
    1588                                                     break;
    1589                                                 case MarkTextPositionStyle.Up:
    1590                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X - 100f, array4[num12].Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    1591                                                     break;
    1592                                                 case MarkTextPositionStyle.Right:
    1593                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X + (float)MarkText.MarkTextOffect, array4[num12].Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
    1594                                                     break;
    1595                                                 case MarkTextPositionStyle.Down:
    1596                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X - 100f, array4[num12].Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    1597                                                     break;
    1598                                             }
    1599                                         }
    1600                                     }
    1601                                 }
    1602                                 using (Pen pen2 = new Pen(value2.LineColor, value2.LineThickness))
    1603                                 {
    1604                                     if (value2.IsSmoothCurve)
    1605                                     {
    1606                                         graphics.DrawCurve(pen2, array4);
    1607                                     }
    1608                                     else
    1609                                     {
    1610                                         graphics.DrawLines(pen2, array4);
    1611                                     }
    1612                                 }
    1613                             }
    1614                         }
    1615                     }
    1616                 }
    1617                 else
    1618                 {
    1619                     foreach (MarkText MarkText2 in MarkTexts)
    1620                     {
    1621                         foreach (KeyValuePair<string, CurveItem> item3 in data_list)
    1622                         {
    1623                             if (item3.Value.Visible && item3.Value.LineRenderVisiable && !(item3.Key != MarkText2.CurveKey))
    1624                             {
    1625                                 float[] data3 = item3.Value.Data;
    1626                                 if (data3 != null && data3.Length > 1 && MarkText2.Index >= 0 && MarkText2.Index < item3.Value.Data.Length)
    1627                                 {
    1628                                     PointF pointF2 = new PointF(leftRight + MarkText2.Index, ControlHelper.ComputePaintLocationY(item3.Value.IsLeftFrame ? value_max_left : value_max_right, item3.Value.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, item3.Value.Data[MarkText2.Index]) + (float)upDowm);
    1629                                     graphics.FillEllipse(new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 3f, pointF2.Y - 3f, 6f, 6f));
    1630                                     switch ((MarkText2.PositionStyle == MarkTextPositionStyle.Auto) ? MarkText.CalculateDirectionFromDataIndex(item3.Value.Data, MarkText2.Index) : MarkText2.PositionStyle)
    1631                                     {
    1632                                         case MarkTextPositionStyle.Left:
    1633                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 100f, pointF2.Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
    1634                                             break;
    1635                                         case MarkTextPositionStyle.Up:
    1636                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 100f, pointF2.Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    1637                                             break;
    1638                                         case MarkTextPositionStyle.Right:
    1639                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X + (float)MarkText.MarkTextOffect, pointF2.Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
    1640                                             break;
    1641                                         case MarkTextPositionStyle.Down:
    1642                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 100f, pointF2.Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    1643                                             break;
    1644                                     }
    1645                                 }
    1646                             }
    1647                         }
    1648                     }
    1649                     foreach (CurveItem value3 in data_list.Values)
    1650                     {
    1651                         if (value3.Visible && value3.LineRenderVisiable)
    1652                         {
    1653                             float[] data4 = value3.Data;
    1654                             if (data4 != null && data4.Length > 1)
    1655                             {
    1656                                 int num13 = width - 2 * leftRight + 1;
    1657                                 PointF[] array5;
    1658                                 if (value3.Data.Length <= num13)
    1659                                 {
    1660                                     array5 = new PointF[value3.Data.Length];
    1661                                     for (int num14 = 0; num14 < value3.Data.Length; num14++)
    1662                                     {
    1663                                         array5[num14].X = leftRight + num14;
    1664                                         array5[num14].Y = ControlHelper.ComputePaintLocationY(value3.IsLeftFrame ? value_max_left : value_max_right, value3.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value3.Data[num14]) + (float)upDowm;
    1665                                         DrawMarkPoint(graphics, value3.MarkText[num14], array5[num14], value3.LineColor, MarkText.CalculateDirectionFromDataIndex(value3.Data, num14));
    1666                                     }
    1667                                 }
    1668                                 else
    1669                                 {
    1670                                     array5 = new PointF[num13];
    1671                                     for (int num15 = 0; num15 < array5.Length; num15++)
    1672                                     {
    1673                                         int num16 = num15 + value3.Data.Length - num13;
    1674                                         array5[num15].X = leftRight + num15;
    1675                                         array5[num15].Y = ControlHelper.ComputePaintLocationY(value3.IsLeftFrame ? value_max_left : value_max_right, value3.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value3.Data[num16]) + (float)upDowm;
    1676                                         DrawMarkPoint(graphics, value3.MarkText[num16], array5[num15], value3.LineColor, MarkText.CalculateDirectionFromDataIndex(value3.Data, num16));
    1677                                     }
    1678                                 }
    1679                                 using (Pen pen3 = new Pen(value3.LineColor, value3.LineThickness))
    1680                                 {
    1681                                     if (value3.IsSmoothCurve)
    1682                                     {
    1683                                         graphics.DrawCurve(pen3, array5);
    1684                                     }
    1685                                     else
    1686                                     {
    1687                                         graphics.DrawLines(pen3, array5);
    1688                                     }
    1689                                 }
    1690                             }
    1691                         }
    1692                     }
    1693                 }
    1694                 base.OnPaint(e);
    1695             }
    1696             catch (Exception exc)
    1697             {
    1698                 e.Graphics.DrawString(exc.Message, this.Font, Brushes.Black, 10, 10);
    1699             }
    1700         }
    1701 
    1702         /// <summary>
    1703         /// Draws the mark point.
    1704         /// </summary>
    1705         /// <param name="g">The g.</param>
    1706         /// <param name="markText">The mark text.</param>
    1707         /// <param name="center">The center.</param>
    1708         /// <param name="color">The color.</param>
    1709         /// <param name="markTextPosition">The mark text position.</param>
    1710         private void DrawMarkPoint(Graphics g, string markText, PointF center, Color color, MarkTextPositionStyle markTextPosition)
    1711         {
    1712             if (!string.IsNullOrEmpty(markText))
    1713             {
    1714                 using (Brush brush = new SolidBrush(color))
    1715                 {
    1716                     DrawMarkPoint(g, markText, center, brush, markTextPosition);
    1717                 }
    1718             }
    1719         }
    1720 
    1721         /// <summary>
    1722         /// Draws the mark point.
    1723         /// </summary>
    1724         /// <param name="g">The g.</param>
    1725         /// <param name="markText">The mark text.</param>
    1726         /// <param name="center">The center.</param>
    1727         /// <param name="brush">The brush.</param>
    1728         /// <param name="markTextPosition">The mark text position.</param>
    1729         private void DrawMarkPoint(Graphics g, string markText, PointF center, Brush brush, MarkTextPositionStyle markTextPosition)
    1730         {
    1731             if (!string.IsNullOrEmpty(markText))
    1732             {
    1733                 g.FillEllipse(brush, new RectangleF(center.X - 3f, center.Y - 3f, 6f, 6f));
    1734                 switch (markTextPosition)
    1735                 {
    1736                     case MarkTextPositionStyle.Left:
    1737                         g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
    1738                         break;
    1739                     case MarkTextPositionStyle.Up:
    1740                         g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    1741                         break;
    1742                     case MarkTextPositionStyle.Right:
    1743                         g.DrawString(markText, Font, brush, new RectangleF(center.X + (float)MarkText.MarkTextOffect, center.Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
    1744                         break;
    1745                     case MarkTextPositionStyle.Down:
    1746                         g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
    1747                         break;
    1748                 }
    1749             }
    1750         }
    1751 
    1752         /// <summary>
    1753         /// Determines whether [is need paint dash] [the specified paint value].
    1754         /// </summary>
    1755         /// <param name="paintValue">The paint value.</param>
    1756         /// <returns><c>true</c> if [is need paint dash] [the specified paint value]; otherwise, <c>false</c>.</returns>
    1757         private bool IsNeedPaintDash(float paintValue)
    1758         {
    1759             for (int i = 0; i < auxiliary_lines.Count; i++)
    1760             {
    1761                 if (Math.Abs(auxiliary_lines[i].PaintValue - paintValue) < (float)font_size9.Height)
    1762                 {
    1763                     return false;
    1764                 }
    1765             }
    1766             return true;
    1767         }
    1768 
    1769         /// <summary>
    1770         /// Calculates the data count by offect.
    1771         /// </summary>
    1772         /// <param name="offect">The offect.</param>
    1773         /// <returns>System.Int32.</returns>
    1774         private int CalculateDataCountByOffect(float offect)
    1775         {
    1776             if (value_IntervalAbscissaText > 0)
    1777             {
    1778                 return value_IntervalAbscissaText;
    1779             }
    1780             if (offect > 40f)
    1781             {
    1782                 return 1;
    1783             }
    1784             offect = 40f / offect;
    1785             return (int)Math.Ceiling(offect);
    1786         }
    1787 
    1788         /// <summary>
    1789         /// Releases unmanaged and - optionally - managed resources.
    1790         /// </summary>
    1791         /// <param name="disposing">为 true 则释放托管资源和非托管资源;为 false 则仅释放非托管资源。</param>
    1792         protected override void Dispose(bool disposing)
    1793         {
    1794             if (disposing && components != null)
    1795             {
    1796                 components.Dispose();
    1797             }
    1798             base.Dispose(disposing);
    1799         }
    1800 
    1801         /// <summary>
    1802         /// Initializes the component.
    1803         /// </summary>
    1804         private void InitializeComponent()
    1805         {
    1806             SuspendLayout();
    1807             base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
    1808             BackColor = System.Drawing.Color.Transparent;
    1809             base.Name = "HslCurve";
    1810             base.Size = new System.Drawing.Size(417, 205);
    1811             ResumeLayout(false);
    1812         }
    1813     }
    1814 }
    View Code

    最后的话

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

  • 相关阅读:
    扯蛋的密码规则
    【转】mysql安全基线设置
    阿里云安全基线 记录如下 不定时更新
    解决Apache的错误日志巨大的问题以及关闭Apache web日志记录
    cms如何绑定二级域名
    宝塔面板定时/同步备份网站及数据库至FTP存储空间完整教程
    宝塔部署项目报Warning: require(): open_basedir restriction in effect的解决方案
    git学习笔记(一)—— git环境搭建
    vim学习笔记(一)—— vim安装方法
    Intel Edison学习笔记(二)—— 入门环境配置
  • 原文地址:https://www.cnblogs.com/bfyx/p/11576321.html
Copyright © 2011-2022 走看看