1. 程式人生 > >(七十一)c#Winform自定義控制元件-折線圖

(七十一)c#Winform自定義控制元件-折線圖

前提

入行已經7,8年了,一直想做一套漂亮點的自定義控制元件,於是就有了本系列文章。

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

碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果覺得寫的還行,請點個 star 支援一下吧

歡迎前來交流探討: 企鵝群568015492 

麻煩部落格下方點個【推薦】,謝謝

NuGet

Install-Package HZH_Controls

目錄

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

用處及效果

準備工作

請先了解GDI+相關知識

開始

新增一個類UCCurve 繼承自UserControl

新增一些控制屬性

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

建構函式做一些初始化

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

重繪

  1   protected override void OnPaint(PaintEventArgs e)
  2         {
  3             try
  4             {
  5                 Graphics graphics = e.Graphics;
  6                 graphics.SetGDIHigh();
  7                 if (BackColor != Color.Transparent)
  8                 {
  9                     graphics.Clear(BackColor);
 10                 }
 11                 int width = base.Width;
 12                 int height = base.Height;
 13                 if (width < 120 || height < 60)
 14                 {
 15                     return;
 16                 }
 17                 Point[] array = new Point[4]
 18                 {
 19                     new Point(leftRight - 1, upDowm - 8),
 20                     new Point(leftRight - 1, height - upDowm),
 21                     new Point(width - leftRight, height - upDowm),
 22                     new Point(width - leftRight, upDowm - 8)
 23                 };
 24                 graphics.DrawLine(pen_normal, array[0], array[1]);
 25                 graphics.DrawLine(pen_normal, array[1], array[2]);
 26                 if (isRenderRightCoordinate)
 27                 {
 28                     graphics.DrawLine(pen_normal, array[2], array[3]);
 29                 }
 30 
 31                 if (!string.IsNullOrEmpty(value_title))
 32                 {
 33                     graphics.DrawString(value_title, font_size9, brush_deep, new Rectangle(0, 0, width - 1, 20), format_center);
 34                 }
 35 
 36                 if (data_list.Count > 0)
 37                 {
 38                     float num = leftRight + 10;
 39                     foreach (KeyValuePair<string, CurveItem> item in data_list)
 40                     {
 41                         if (item.Value.Visible)
 42                         {
 43                             var titleSize=graphics.MeasureString(item.Key, Font);
 44                             SolidBrush solidBrush = item.Value.LineRenderVisiable ? new SolidBrush(item.Value.LineColor) : new SolidBrush(Color.FromArgb(80, item.Value.LineColor));
 45                             graphics.FillRectangle(solidBrush, num + 8f, 24f, 20f, 14f);
 46                             graphics.DrawString(item.Key, Font, solidBrush, new PointF(num + 30f, 24f+(14 - titleSize.Height) / 2));
 47                             item.Value.TitleRegion = new RectangleF(num, 24f, 60f, 18f);
 48                             solidBrush.Dispose();
 49                             num += titleSize.Width + 30;
 50                         }
 51                     }
 52                 }
 53 
 54 
 55                 for (int i = 0; i < auxiliary_Labels.Count; i++)
 56                 {
 57                     if (!string.IsNullOrEmpty(auxiliary_Labels[i].Text))
 58                     {
 59                         int num2 = (auxiliary_Labels[i].LocationX > 1f) ? ((int)auxiliary_Labels[i].LocationX) : ((int)(auxiliary_Labels[i].LocationX * (float)width));
 60                         int num3 = (int)graphics.MeasureString(auxiliary_Labels[i].Text, Font).Width + 3;
 61                         Point[] points = new Point[6]
 62                     {
 63                         new Point(num2, 11),
 64                         new Point(num2 + 10, 20),
 65                         new Point(num2 + num3 + 10, 20),
 66                         new Point(num2 + num3 + 10, 0),
 67                         new Point(num2 + 10, 0),
 68                         new Point(num2, 11)
 69                     };
 70                         graphics.FillPolygon(auxiliary_Labels[i].TextBack, points);
 71                         graphics.DrawString(auxiliary_Labels[i].Text, Font, auxiliary_Labels[i].TextBrush, new Rectangle(num2 + 7, 0, num3 + 3, 20), format_center);
 72                     }
 73                 }
 74                 ControlHelper.PaintTriangle(graphics, brush_deep, new Point(leftRight - 1, upDowm - 8), 4, GraphDirection.Upward);
 75                 if (isRenderRightCoordinate)
 76                 {
 77                     ControlHelper.PaintTriangle(graphics, brush_deep, new Point(width - leftRight, upDowm - 8), 4, GraphDirection.Upward);
 78                 }
 79                 for (int j = 0; j < auxiliary_lines.Count; j++)
 80                 {
 81                     if (auxiliary_lines[j].IsLeftFrame)
 82                     {
 83                         auxiliary_lines[j].PaintValue = ControlHelper.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, auxiliary_lines[j].Value) + (float)upDowm;
 84                     }
 85                     else
 86                     {
 87                         auxiliary_lines[j].PaintValue = ControlHelper.ComputePaintLocationY(value_max_right, value_min_right, height - upDowm - upDowm, auxiliary_lines[j].Value) + (float)upDowm;
 88                     }
 89                 }
 90                 for (int k = 0; k <= value_Segment; k++)
 91                 {
 92                     float value = (float)((double)k * (double)(value_max_left - value_min_left) / (double)value_Segment + (double)value_min_left);
 93                     float num4 = ControlHelper.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, value) + (float)upDowm;
 94                     if (IsNeedPaintDash(num4))
 95                     {
 96                         graphics.DrawLine(pen_normal, leftRight - 4, num4, leftRight - 1, num4);
 97                         RectangleF layoutRectangle = new RectangleF(0f, num4 - 9f, leftRight - 4, 20f);
 98                         graphics.DrawString(value.ToString(), font_size9, brush_deep, layoutRectangle, format_right);
 99                         if (isRenderRightCoordinate)
100                         {
101                             float num5 = (float)k * (value_max_right - value_min_right) / (float)value_Segment + value_min_right;
102                             graphics.DrawLine(pen_normal, width - leftRight + 1, num4, width - leftRight + 4, num4);
103                             layoutRectangle.Location = new PointF(width - leftRight + 4, num4 - 9f);
104                             graphics.DrawString(num5.ToString(), font_size9, brush_deep, layoutRectangle, format_left);
105                         }
106                         if (k > 0 && value_IsRenderDashLine)
107                         {
108                             graphics.DrawLine(pen_dash, leftRight, num4, width - leftRight, num4);
109                         }
110                     }
111                 }
112                 if (value_IsRenderDashLine)
113                 {
114                     if (value_IsAbscissaStrech)
115                     {
116                         float num6 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
117                         int num7 = CalculateDataCountByOffect(num6);
118                         for (int l = 0; l < value_StrechDataCountMax; l += num7)
119                         {
120                             if (l > 0 && l < value_StrechDataCountMax - 1)
121                             {
122                                 graphics.DrawLine(pen_dash, (float)l * num6 + (float)leftRight, upDowm, (float)l * num6 + (float)leftRight, height - upDowm - 1);
123                             }
124                             if (data_text != null && l < data_text.Length && (float)l * num6 + (float)leftRight < (float)(data_text.Length - 1) * num6 + (float)leftRight - 40f)
125                             {
126                                 graphics.DrawString(layoutRectangle: new Rectangle((int)((float)l * num6), height - upDowm + 1, leftRight * 2, upDowm), s: data_text[l], font: font_size9, brush: 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>
33