(七十一)c#Winform自定义控件-折线图

前提

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

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

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

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

欢迎前来交流探讨: 企鹅群568015492 (七十一)c#Winform自定义控件-折线图

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

NuGet

Install-Package HZH_Controls

目录

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

用处及效果

(七十一)c#Winform自定义控件-折线图

(七十一)c#Winform自定义控件-折线图

(七十一)c#Winform自定义控件-折线图

准备工作

请先了解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: 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: 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: 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: 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: 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: 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, brush: 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, brush: 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为节点信息相关

 

完整代码

(七十一)c#Winform自定义控件-折线图
   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: 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: 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: 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: 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: 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: 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, brush: 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, brush: 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 点个星星吧

(七十一)c#Winform自定义控件-折线图

上一篇:AB包


下一篇:Unity3D AssetBundle的打包与加载