前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
官网:https://www.hzhcontrols.cn
GitHub:https://github.com/kwwwvagaa/NetWinformControl
如果觉得写的还行,请点个 star 支持一下吧
麻烦博客下方点个【推荐】,谢谢
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>
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为节点信息相关
完整代码
// ***********************************************************************
// Assembly : HZH_Controls
// Created : 2019-09-23
//
// ***********************************************************************
// <copyright file="UCCurve.cs">
// Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com
// </copyright>
//
// Blog: https://www.cnblogs.com/bfyx
// GitHub:https://github.com/kwwwvagaa/NetWinformControl
// gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
//
// If you use this code, please keep this note.
// ***********************************************************************
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;
namespace HZH_Controls.Controls
{
/// <summary>
/// Class UCCurve.
/// Implements the <see cref="System.Windows.Forms.UserControl" />
/// </summary>
/// <seealso cref="System.Windows.Forms.UserControl" />
public class UCCurve : UserControl
{
/// <summary>
/// The value count maximum
/// </summary>
private const int value_count_max = 4096;
/// <summary>
/// The value maximum left
/// </summary>
private float value_max_left = 100f;
/// <summary>
/// The value minimum left
/// </summary>
private float value_min_left = 0f;
/// <summary>
/// The value maximum right
/// </summary>
private float value_max_right = 100f;
/// <summary>
/// The value minimum right
/// </summary>
private float value_min_right = 0f;
/// <summary>
/// The value segment
/// </summary>
private int value_Segment = 5;
/// <summary>
/// The value is abscissa strech
/// </summary>
private bool value_IsAbscissaStrech = false;
/// <summary>
/// The value strech data count maximum
/// </summary>
private int value_StrechDataCountMax = 300;
/// <summary>
/// The value is render dash line
/// </summary>
private bool value_IsRenderDashLine = true;
/// <summary>
/// The text format
/// </summary>
private string textFormat = "HH:mm";
/// <summary>
/// The value interval abscissa text
/// </summary>
private int value_IntervalAbscissaText = 100;
/// <summary>
/// The random
/// </summary>
private Random random = null;
/// <summary>
/// The value title
/// </summary>
private string value_title = "";
/// <summary>
/// The left right
/// </summary>
private int leftRight = 50;
/// <summary>
/// Up dowm
/// </summary>
private int upDowm = 50;
/// <summary>
/// The data list
/// </summary>
private Dictionary<string, CurveItem> data_list = null;
/// <summary>
/// The data text
/// </summary>
private string[] data_text = null;
/// <summary>
/// The auxiliary lines
/// </summary>
private List<AuxiliaryLine> auxiliary_lines;
/// <summary>
/// The auxiliary labels
/// </summary>
private List<AuxiliaryLable> auxiliary_Labels;
/// <summary>
/// The mark texts
/// </summary>
private List<MarkText> MarkTexts;
/// <summary>
/// The font size9
/// </summary>
private Font font_size9 = null;
/// <summary>
/// The font size12
/// </summary>
private Font font_size12 = null;
/// <summary>
/// The brush deep
/// </summary>
private Brush brush_deep = null;
/// <summary>
/// The pen normal
/// </summary>
private Pen pen_normal = null;
/// <summary>
/// The pen dash
/// </summary>
private Pen pen_dash = null;
/// <summary>
/// The color normal
/// </summary>
private Color color_normal = Color.DeepPink;
/// <summary>
/// The color deep
/// </summary>
private Color color_deep = Color.DimGray;
/// <summary>
/// The color dash
/// </summary>
private Color color_dash = Color.FromArgb(232, 232, 232);
/// <summary>
/// The color mark font
/// </summary>
private Color color_mark_font = Color.DodgerBlue;
/// <summary>
/// The brush mark font
/// </summary>
private Brush brush_mark_font = Brushes.DodgerBlue;
/// <summary>
/// The format left
/// </summary>
private StringFormat format_left = null;
/// <summary>
/// The format right
/// </summary>
private StringFormat format_right = null;
/// <summary>
/// The format center
/// </summary>
private StringFormat format_center = null;
/// <summary>
/// The is render right coordinate
/// </summary>
private bool isRenderRightCoordinate = true;
/// <summary>
/// The curve name width
/// </summary>
private int curveNameWidth = 100;
/// <summary>
/// The components
/// </summary>
private IContainer components = null;
/// <summary>
/// 获取或设置控件的背景色。
/// </summary>
/// <value>The color of the back.</value>
/// <PermissionSet>
/// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
/// </PermissionSet>
[Browsable(true)]
[Description("获取或设置控件的背景色")]
[Category("自定义")]
[DefaultValue(typeof(Color), "Transparent")]
[EditorBrowsable(EditorBrowsableState.Always)]
public override Color BackColor
{
get
{
return base.BackColor;
}
set
{
base.BackColor = value;
}
}
/// <summary>
/// Gets or sets the value maximum left.
/// </summary>
/// <value>The value maximum left.</value>
[Category("自定义")]
[Description("获取或设置图形的左纵坐标的最大值,该值必须大于最小值")]
[Browsable(true)]
[DefaultValue(100f)]
public float ValueMaxLeft
{
get
{
return value_max_left;
}
set
{
value_max_left = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets the value minimum left.
/// </summary>
/// <value>The value minimum left.</value>
[Category("自定义")]
[Description("获取或设置图形的左纵坐标的最小值,该值必须小于最大值")]
[Browsable(true)]
[DefaultValue(0f)]
public float ValueMinLeft
{
get
{
return value_min_left;
}
set
{
value_min_left = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets the value maximum right.
/// </summary>
/// <value>The value maximum right.</value>
[Category("自定义")]
[Description("获取或设置图形的右纵坐标的最大值,该值必须大于最小值")]
[Browsable(true)]
[DefaultValue(100f)]
public float ValueMaxRight
{
get
{
return value_max_right;
}
set
{
value_max_right = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets the value minimum right.
/// </summary>
/// <value>The value minimum right.</value>
[Category("自定义")]
[Description("获取或设置图形的右纵坐标的最小值,该值必须小于最大值")]
[Browsable(true)]
[DefaultValue(0f)]
public float ValueMinRight
{
get
{
return value_min_right;
}
set
{
value_min_right = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets the value segment.
/// </summary>
/// <value>The value segment.</value>
[Category("自定义")]
[Description("获取或设置图形的纵轴分段数")]
[Browsable(true)]
[DefaultValue(5)]
public int ValueSegment
{
get
{
return value_Segment;
}
set
{
value_Segment = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets a value indicating whether this instance is abscissa strech.
/// </summary>
/// <value><c>true</c> if this instance is abscissa strech; otherwise, <c>false</c>.</value>
[Category("自定义")]
[Description("获取或设置所有的数据是否强制在一个界面里显示")]
[Browsable(true)]
[DefaultValue(false)]
public bool IsAbscissaStrech
{
get
{
return value_IsAbscissaStrech;
}
set
{
value_IsAbscissaStrech = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets the strech data count maximum.
/// </summary>
/// <value>The strech data count maximum.</value>
[Category("自定义")]
[Description("获取或设置拉伸模式下的最大数据量")]
[Browsable(true)]
[DefaultValue(300)]
public int StrechDataCountMax
{
get
{
return value_StrechDataCountMax;
}
set
{
value_StrechDataCountMax = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets a value indicating whether this instance is render dash line.
/// </summary>
/// <value><c>true</c> if this instance is render dash line; otherwise, <c>false</c>.</value>
[Category("自定义")]
[Description("获取或设置虚线是否进行显示")]
[Browsable(true)]
[DefaultValue(true)]
public bool IsRenderDashLine
{
get
{
return value_IsRenderDashLine;
}
set
{
value_IsRenderDashLine = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets the color lines and text.
/// </summary>
/// <value>The color lines and text.</value>
[Category("自定义")]
[Description("获取或设置坐标轴及相关信息文本的颜色")]
[Browsable(true)]
[DefaultValue(typeof(Color), "DimGray")]
public Color ColorLinesAndText
{
get
{
return color_deep;
}
set
{
color_deep = value;
InitializationColor();
Invalidate();
}
}
/// <summary>
/// Gets or sets the color dash lines.
/// </summary>
/// <value>The color dash lines.</value>
[Category("自定义")]
[Description("获取或设置虚线的颜色")]
[Browsable(true)]
public Color ColorDashLines
{
get
{
return color_dash;
}
set
{
color_dash = value;
if (pen_dash != null)
pen_dash.Dispose();
pen_dash = new Pen(color_dash);
pen_dash.DashStyle = DashStyle.Custom;
pen_dash.DashPattern = new float[2]
{
5f,
5f
};
Invalidate();
}
}
/// <summary>
/// Gets or sets the interval abscissa text.
/// </summary>
/// <value>The interval abscissa text.</value>
[Category("自定义")]
[Description("获取或设置纵向虚线的分隔情况,单位为多少个数据")]
[Browsable(true)]
[DefaultValue(100)]
public int IntervalAbscissaText
{
get
{
return value_IntervalAbscissaText;
}
set
{
value_IntervalAbscissaText = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets the text add format.
/// </summary>
/// <value>The text add format.</value>
[Category("自定义")]
[Description("获取或设置实时数据新增时文本相对应于时间的格式化字符串,默认HH:mm")]
[Browsable(true)]
[DefaultValue("HH:mm")]
public string TextAddFormat
{
get
{
return textFormat;
}
set
{
textFormat = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets the title.
/// </summary>
/// <value>The title.</value>
[Category("自定义")]
[Description("获取或设置图标的标题信息")]
[Browsable(true)]
[DefaultValue("")]
public string Title
{
get
{
return value_title;
}
set
{
value_title = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets a value indicating whether this instance is render right coordinate.
/// </summary>
/// <value><c>true</c> if this instance is render right coordinate; otherwise, <c>false</c>.</value>
[Category("自定义")]
[Description("获取或设置是否显示右侧的坐标系信息")]
[Browsable(true)]
[DefaultValue(true)]
public bool IsRenderRightCoordinate
{
get
{
return isRenderRightCoordinate;
}
set
{
isRenderRightCoordinate = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets the width of the curve name.
/// </summary>
/// <value>The width of the curve name.</value>
[Browsable(true)]
[Description("获取或设置曲线名称的布局宽度")]
[Category("自定义")]
[DefaultValue(100)]
public int CurveNameWidth
{
get
{
return curveNameWidth;
}
set
{
if (value > 10)
{
curveNameWidth = value;
}
}
}
/// <summary>
/// Initializes a new instance of the <see cref="UCCurve" /> class.
/// </summary>
public UCCurve()
{
InitializeComponent();
random = new Random();
data_list = new Dictionary<string, CurveItem>();
auxiliary_lines = new List<AuxiliaryLine>();
MarkTexts = new List<MarkText>();
auxiliary_Labels = new List<AuxiliaryLable>();
format_left = new StringFormat
{
LineAlignment = StringAlignment.Center,
Alignment = StringAlignment.Near
};
format_right = new StringFormat
{
LineAlignment = StringAlignment.Center,
Alignment = StringAlignment.Far
};
format_center = new StringFormat
{
LineAlignment = StringAlignment.Center,
Alignment = StringAlignment.Center
};
font_size9 = new Font("微软雅黑", 9f);
font_size12 = new Font("微软雅黑", 12f);
InitializationColor();
pen_dash = new Pen(color_deep);
pen_dash.DashStyle = DashStyle.Custom;
pen_dash.DashPattern = new float[2]
{
5f,
5f
};
SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
}
/// <summary>
/// Initializations the color.
/// </summary>
private void InitializationColor()
{
if (pen_normal != null)
pen_normal.Dispose();
if (brush_deep != null)
brush_deep.Dispose();
pen_normal = new Pen(color_deep);
brush_deep = new SolidBrush(color_deep);
}
/// <summary>
/// Sets the curve text.
/// </summary>
/// <param name="descriptions">The descriptions.</param>
public void SetCurveText(string[] descriptions)
{
data_text = descriptions;
Invalidate();
}
/// <summary>
/// Sets the left curve.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="data">The data.</param>
/// <param name="lineColor">Color of the line.</param>
public void SetLeftCurve(string key, float[] data, Color? lineColor = null)
{
SetCurve(key, true, data, lineColor, 1f, false);
}
/// <summary>
/// Sets the left curve.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="data">The data.</param>
/// <param name="lineColor">Color of the line.</param>
/// <param name="isSmooth">if set to <c>true</c> [is smooth].</param>
public void SetLeftCurve(string key, float[] data, Color? lineColor, bool isSmooth = false)
{
SetCurve(key, true, data, lineColor, 1f, isSmooth);
}
/// <summary>
/// Sets the right curve.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="data">The data.</param>
/// <param name="lineColor">Color of the line.</param>
public void SetRightCurve(string key, float[] data, Color? lineColor = null)
{
SetCurve(key, false, data, lineColor, 1f, false);
}
/// <summary>
/// Sets the right curve.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="data">The data.</param>
/// <param name="lineColor">Color of the line.</param>
/// <param name="isSmooth">if set to <c>true</c> [is smooth].</param>
public void SetRightCurve(string key, float[] data, Color? lineColor, bool isSmooth = false)
{
SetCurve(key, false, data, lineColor, 1f, isSmooth);
}
/// <summary>
/// Sets the curve.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="isLeft">if set to <c>true</c> [is left].</param>
/// <param name="data">The data.</param>
/// <param name="lineColor">Color of the line.</param>
/// <param name="thickness">The thickness.</param>
/// <param name="isSmooth">if set to <c>true</c> [is smooth].</param>
public void SetCurve(string key, bool isLeft, float[] data, Color? lineColor, float thickness, bool isSmooth)
{
if (data_list.ContainsKey(key))
{
if (data == null)
{
data = new float[0];
}
data_list[key].Data = data;
}
else
{
if (data == null)
{
data = new float[0];
}
data_list.Add(key, new CurveItem
{
Data = data,
MarkText = new string[data.Length],
LineThickness = thickness,
LineColor = lineColor ?? ControlHelper.Colors[data_list.Count + 13],
IsLeftFrame = isLeft,
IsSmoothCurve = isSmooth
});
if (data_text == null)
{
data_text = new string[data.Length];
}
}
Invalidate();
}
/// <summary>
/// Removes the curve.
/// </summary>
/// <param name="key">The key.</param>
public void RemoveCurve(string key)
{
if (data_list.ContainsKey(key))
{
data_list.Remove(key);
}
if (data_list.Count == 0)
{
data_text = new string[0];
}
Invalidate();
}
/// <summary>
/// Removes all curve.
/// </summary>
public void RemoveAllCurve()
{
int count = data_list.Count;
data_list.Clear();
if (data_list.Count == 0)
{
data_text = new string[0];
}
if (count > 0)
{
Invalidate();
}
}
/// <summary>
/// Removes all curve data.
/// </summary>
public void RemoveAllCurveData()
{
int count = data_list.Count;
foreach (KeyValuePair<string, CurveItem> item in data_list)
{
item.Value.Data = new float[0];
item.Value.MarkText = new string[0];
}
data_text = new string[0];
if (count > 0)
{
Invalidate();
}
}
/// <summary>
/// Gets the curve item.
/// </summary>
/// <param name="key">The key.</param>
/// <returns>CurveItem.</returns>
public CurveItem GetCurveItem(string key)
{
if (data_list.ContainsKey(key))
{
return data_list[key];
}
return null;
}
/// <summary>
/// Saves to bitmap.
/// </summary>
/// <returns>Bitmap.</returns>
public Bitmap SaveToBitmap()
{
return SaveToBitmap(base.Width, base.Height);
}
/// <summary>
/// Saves to bitmap.
/// </summary>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <returns>Bitmap.</returns>
public Bitmap SaveToBitmap(int width, int height)
{
Bitmap bitmap = new Bitmap(width, height);
Graphics graphics = Graphics.FromImage(bitmap);
OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, width, height)));
return bitmap;
}
/// <summary>
/// Adds the curve data.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="values">The values.</param>
/// <param name="markTexts">The mark texts.</param>
/// <param name="isUpdateUI">if set to <c>true</c> [is update UI].</param>
private void AddCurveData(string key, float[] values, string[] markTexts, bool isUpdateUI)
{
if ((values != null && values.Length < 1) || !data_list.ContainsKey(key))
{
return;
}
CurveItem CurveItem = data_list[key];
if (CurveItem.Data != null)
{
if (value_IsAbscissaStrech)
{
ControlHelper.AddArrayData(ref CurveItem.Data, values, value_StrechDataCountMax);
ControlHelper.AddArrayData(ref CurveItem.MarkText, markTexts, value_StrechDataCountMax);
}
else
{
ControlHelper.AddArrayData(ref CurveItem.Data, values, 4096);
ControlHelper.AddArrayData(ref CurveItem.MarkText, markTexts, 4096);
}
if (isUpdateUI)
{
Invalidate();
}
}
}
/// <summary>
/// Adds the curve time.
/// </summary>
/// <param name="count">The count.</param>
private void AddCurveTime(int count)
{
AddCurveTime(count, DateTime.Now.ToString(textFormat));
}
/// <summary>
/// Adds the curve time.
/// </summary>
/// <param name="count">The count.</param>
/// <param name="text">The text.</param>
private void AddCurveTime(int count, string text)
{
if (data_text != null)
{
string[] array = new string[count];
for (int i = 0; i < array.Length; i++)
{
array[i] = text;
}
if (value_IsAbscissaStrech)
{
ControlHelper.AddArrayData(ref data_text, array, value_StrechDataCountMax);
}
else
{
ControlHelper.AddArrayData(ref data_text, array, 4096);
}
}
}
/// <summary>
/// Adds the curve data.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The value.</param>
public void AddCurveData(string key, float value)
{
AddCurveData(key, new float[1]
{
value
});
}
/// <summary>
/// Adds the curve data.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The value.</param>
/// <param name="markText">The mark text.</param>
public void AddCurveData(string key, float value, string markText)
{
AddCurveData(key, new float[1]
{
value
}, new string[1]
{
markText
});
}
/// <summary>
/// Adds the curve data.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="values">The values.</param>
public void AddCurveData(string key, float[] values)
{
AddCurveData(key, values, null);
}
/// <summary>
/// Adds the curve data.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="values">The values.</param>
/// <param name="markTexts">The mark texts.</param>
public void AddCurveData(string key, float[] values, string[] markTexts)
{
if (markTexts == null)
{
markTexts = new string[values.Length];
}
AddCurveData(key, values, markTexts, false);
if (values != null && values.Length != 0)
{
AddCurveTime(values.Length);
}
Invalidate();
}
/// <summary>
/// Adds the curve data.
/// </summary>
/// <param name="keys">The keys.</param>
/// <param name="values">The values.</param>
public void AddCurveData(string[] keys, float[] values)
{
AddCurveData(keys, values, null);
}
/// <summary>
/// Adds the curve data.
/// </summary>
/// <param name="axisText">The axis text.</param>
/// <param name="keys">The keys.</param>
/// <param name="values">The values.</param>
public void AddCurveData(string axisText, string[] keys, float[] values)
{
AddCurveData(axisText, keys, values, null);
}
/// <summary>
/// Adds the curve data.
/// </summary>
/// <param name="keys">The keys.</param>
/// <param name="values">The values.</param>
/// <param name="markTexts">The mark texts.</param>
/// <exception cref="ArgumentNullException">keys
/// or
/// values</exception>
/// <exception cref="Exception">两个参数的数组长度不一致。
/// or
/// 两个参数的数组长度不一致。</exception>
public void AddCurveData(string[] keys, float[] values, string[] markTexts)
{
if (keys == null)
{
throw new ArgumentNullException("keys");
}
if (values == null)
{
throw new ArgumentNullException("values");
}
if (markTexts == null)
{
markTexts = new string[keys.Length];
}
if (keys.Length != values.Length)
{
throw new Exception("两个参数的数组长度不一致。");
}
if (keys.Length != markTexts.Length)
{
throw new Exception("两个参数的数组长度不一致。");
}
for (int i = 0; i < keys.Length; i++)
{
AddCurveData(keys[i], new float[1]
{
values[i]
}, new string[1]
{
markTexts[i]
}, false);
}
AddCurveTime(1);
Invalidate();
}
/// <summary>
/// Adds the curve data.
/// </summary>
/// <param name="axisText">The axis text.</param>
/// <param name="keys">The keys.</param>
/// <param name="values">The values.</param>
/// <param name="markTexts">The mark texts.</param>
/// <exception cref="ArgumentNullException">keys
/// or
/// values</exception>
/// <exception cref="Exception">两个参数的数组长度不一致。
/// or
/// 两个参数的数组长度不一致。</exception>
public void AddCurveData(string axisText, string[] keys, float[] values, string[] markTexts)
{
if (keys == null)
{
throw new ArgumentNullException("keys");
}
if (values == null)
{
throw new ArgumentNullException("values");
}
if (markTexts == null)
{
markTexts = new string[keys.Length];
}
if (keys.Length != values.Length)
{
throw new Exception("两个参数的数组长度不一致。");
}
if (keys.Length != markTexts.Length)
{
throw new Exception("两个参数的数组长度不一致。");
}
for (int i = 0; i < keys.Length; i++)
{
AddCurveData(keys[i], new float[1]
{
values[i]
}, new string[1]
{
markTexts[i]
}, false);
}
AddCurveTime(1, axisText);
Invalidate();
}
/// <summary>
/// Sets the curve visible.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="visible">if set to <c>true</c> [visible].</param>
public void SetCurveVisible(string key, bool visible)
{
if (data_list.ContainsKey(key))
{
CurveItem CurveItem = data_list[key];
CurveItem.Visible = visible;
Invalidate();
}
}
/// <summary>
/// Sets the curve visible.
/// </summary>
/// <param name="keys">The keys.</param>
/// <param name="visible">if set to <c>true</c> [visible].</param>
public void SetCurveVisible(string[] keys, bool visible)
{
foreach (string key in keys)
{
if (data_list.ContainsKey(key))
{
CurveItem CurveItem = data_list[key];
CurveItem.Visible = visible;
}
}
Invalidate();
}
/// <summary>
/// Adds the left auxiliary.
/// </summary>
/// <param name="value">The value.</param>
public void AddLeftAuxiliary(float value)
{
AddLeftAuxiliary(value, ColorLinesAndText);
}
/// <summary>
/// Adds the left auxiliary.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="lineColor">Color of the line.</param>
public void AddLeftAuxiliary(float value, Color lineColor)
{
AddLeftAuxiliary(value, lineColor, 1f, true);
}
/// <summary>
/// Adds the left auxiliary.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="lineColor">Color of the line.</param>
/// <param name="lineThickness">The line thickness.</param>
/// <param name="isDashLine">if set to <c>true</c> [is dash line].</param>
public void AddLeftAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine)
{
AddAuxiliary(value, lineColor, lineThickness, isDashLine, true);
}
/// <summary>
/// Adds the right auxiliary.
/// </summary>
/// <param name="value">The value.</param>
public void AddRightAuxiliary(float value)
{
AddRightAuxiliary(value, ColorLinesAndText);
}
/// <summary>
/// Adds the right auxiliary.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="lineColor">Color of the line.</param>
public void AddRightAuxiliary(float value, Color lineColor)
{
AddRightAuxiliary(value, lineColor, 1f, true);
}
/// <summary>
/// Adds the right auxiliary.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="lineColor">Color of the line.</param>
/// <param name="lineThickness">The line thickness.</param>
/// <param name="isDashLine">if set to <c>true</c> [is dash line].</param>
public void AddRightAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine)
{
AddAuxiliary(value, lineColor, lineThickness, isDashLine, false);
}
/// <summary>
/// Adds the auxiliary.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="lineColor">Color of the line.</param>
/// <param name="lineThickness">The line thickness.</param>
/// <param name="isDashLine">if set to <c>true</c> [is dash line].</param>
/// <param name="isLeft">if set to <c>true</c> [is left].</param>
private void AddAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine, bool isLeft)
{
auxiliary_lines.Add(new AuxiliaryLine
{
Value = value,
LineColor = lineColor,
PenDash = new Pen(lineColor)
{
DashStyle = DashStyle.Custom,
DashPattern = new float[2]
{
5f,
5f
}
},
PenSolid = new Pen(lineColor),
IsDashStyle = isDashLine,
IsLeftFrame = isLeft,
LineThickness = lineThickness,
LineTextBrush = new SolidBrush(lineColor)
});
Invalidate();
}
/// <summary>
/// Removes the auxiliary.
/// </summary>
/// <param name="value">The value.</param>
public void RemoveAuxiliary(float value)
{
int num = 0;
for (int num2 = auxiliary_lines.Count - 1; num2 >= 0; num2--)
{
if (auxiliary_lines[num2].Value == value)
{
auxiliary_lines[num2].Dispose();
auxiliary_lines.RemoveAt(num2);
num++;
}
}
if (num > 0)
{
Invalidate();
}
}
/// <summary>
/// Removes all auxiliary.
/// </summary>
public void RemoveAllAuxiliary()
{
int count = auxiliary_lines.Count;
auxiliary_lines.Clear();
if (count > 0)
{
Invalidate();
}
}
/// <summary>
/// Adds the auxiliary label.
/// </summary>
/// <param name="auxiliaryLable">The auxiliary lable.</param>
public void AddAuxiliaryLabel(AuxiliaryLable auxiliaryLable)
{
auxiliary_Labels.Add(auxiliaryLable);
}
/// <summary>
/// Removes the auxiliary lable.
/// </summary>
/// <param name="auxiliaryLable">The auxiliary lable.</param>
public void RemoveAuxiliaryLable(AuxiliaryLable auxiliaryLable)
{
if (auxiliary_Labels.Remove(auxiliaryLable))
{
Invalidate();
}
}
/// <summary>
/// Removes all auxiliary lable.
/// </summary>
public void RemoveAllAuxiliaryLable()
{
int count = auxiliary_Labels.Count;
auxiliary_Labels.Clear();
if (count > 0)
{
Invalidate();
}
}
/// <summary>
/// Adds the mark text.
/// </summary>
/// <param name="markText">The mark text.</param>
public void AddMarkText(MarkText markText)
{
MarkTexts.Add(markText);
if (data_list.Count > 0)
{
Invalidate();
}
}
/// <summary>
/// Adds the mark text.
/// </summary>
/// <param name="strCurveKey">The string curve key.</param>
/// <param name="intValueIndex">Index of the int value.</param>
/// <param name="strText">The string text.</param>
/// <param name="textColor">Color of the text.</param>
public void AddMarkText(string strCurveKey, int intValueIndex, string strText, Color? textColor = null)
{
AddMarkText(new MarkText() { CurveKey = strCurveKey, PositionStyle = MarkTextPositionStyle.Auto, Text = strText, TextColor = textColor, Index = intValueIndex });
}
/// <summary>
/// Removes the mark text.
/// </summary>
/// <param name="markText">The mark text.</param>
public void RemoveMarkText(MarkText markText)
{
MarkTexts.Remove(markText);
if (data_list.Count > 0)
{
Invalidate();
}
}
/// <summary>
/// Removes all mark text.
/// </summary>
public void RemoveAllMarkText()
{
MarkTexts.Clear();
if (data_list.Count > 0)
{
Invalidate();
}
}
/// <summary>
/// 引发 <see cref="E:System.Windows.Forms.Control.MouseMove" /> 事件。
/// </summary>
/// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.MouseEventArgs" />。</param>
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
bool flag = false;
foreach (KeyValuePair<string, CurveItem> item in data_list)
{
if (item.Value.TitleRegion.Contains(e.Location))
{
flag = true;
break;
}
}
Cursor = (flag ? Cursors.Hand : Cursors.Arrow);
}
/// <summary>
/// Handles the <see cref="E:MouseDown" /> event.
/// </summary>
/// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.MouseEventArgs" />。</param>
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
foreach (KeyValuePair<string, CurveItem> item in data_list)
{
if (item.Value.TitleRegion.Contains(e.Location))
{
item.Value.LineRenderVisiable = !item.Value.LineRenderVisiable;
Invalidate();
break;
}
}
}
/// <summary>
/// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
/// </summary>
/// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
protected override void OnPaint(PaintEventArgs e)
{
try
{
Graphics graphics = e.Graphics;
graphics.SetGDIHigh();
if (BackColor != Color.Transparent)
{
graphics.Clear(BackColor);
}
int width = base.Width;
int height = base.Height;
if (width < 120 || height < 60)
{
return;
}
Point[] array = new Point[4]
{
new Point(leftRight - 1, upDowm - 8),
new Point(leftRight - 1, height - upDowm),
new Point(width - leftRight, height - upDowm),
new Point(width - leftRight, upDowm - 8)
};
graphics.DrawLine(pen_normal, array[0], array[1]);
graphics.DrawLine(pen_normal, array[1], array[2]);
if (isRenderRightCoordinate)
{
graphics.DrawLine(pen_normal, array[2], array[3]);
}
if (!string.IsNullOrEmpty(value_title))
{
graphics.DrawString(value_title, font_size9, brush_deep, new Rectangle(0, 0, width - 1, 20), format_center);
}
if (data_list.Count > 0)
{
float num = leftRight + 10;
foreach (KeyValuePair<string, CurveItem> item in data_list)
{
if (item.Value.Visible)
{
var titleSize=graphics.MeasureString(item.Key, Font);
SolidBrush solidBrush = item.Value.LineRenderVisiable ? new SolidBrush(item.Value.LineColor) : new SolidBrush(Color.FromArgb(80, item.Value.LineColor));
graphics.FillRectangle(solidBrush, num + 8f, 24f, 20f, 14f);
graphics.DrawString(item.Key, Font, solidBrush, new PointF(num + 30f, 24f+(14 - titleSize.Height) / 2));
item.Value.TitleRegion = new RectangleF(num, 24f, 60f, 18f);
solidBrush.Dispose();
num += titleSize.Width + 30;
}
}
}
for (int i = 0; i < auxiliary_Labels.Count; i++)
{
if (!string.IsNullOrEmpty(auxiliary_Labels[i].Text))
{
int num2 = (auxiliary_Labels[i].LocationX > 1f) ? ((int)auxiliary_Labels[i].LocationX) : ((int)(auxiliary_Labels[i].LocationX * (float)width));
int num3 = (int)graphics.MeasureString(auxiliary_Labels[i].Text, Font).Width + 3;
Point[] points = new Point[6]
{
new Point(num2, 11),
new Point(num2 + 10, 20),
new Point(num2 + num3 + 10, 20),
new Point(num2 + num3 + 10, 0),
new Point(num2 + 10, 0),
new Point(num2, 11)
};
graphics.FillPolygon(auxiliary_Labels[i].TextBack, points);
graphics.DrawString(auxiliary_Labels[i].Text, Font, auxiliary_Labels[i].TextBrush, new Rectangle(num2 + 7, 0, num3 + 3, 20), format_center);
}
}
ControlHelper.PaintTriangle(graphics, brush_deep, new Point(leftRight - 1, upDowm - 8), 4, GraphDirection.Upward);
if (isRenderRightCoordinate)
{
ControlHelper.PaintTriangle(graphics, brush_deep, new Point(width - leftRight, upDowm - 8), 4, GraphDirection.Upward);
}
for (int j = 0; j < auxiliary_lines.Count; j++)
{
if (auxiliary_lines[j].IsLeftFrame)
{
auxiliary_lines[j].PaintValue = ControlHelper.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, auxiliary_lines[j].Value) + (float)upDowm;
}
else
{
auxiliary_lines[j].PaintValue = ControlHelper.ComputePaintLocationY(value_max_right, value_min_right, height - upDowm - upDowm, auxiliary_lines[j].Value) + (float)upDowm;
}
}
for (int k = 0; k <= value_Segment; k++)
{
float value = (float)((double)k * (double)(value_max_left - value_min_left) / (double)value_Segment + (double)value_min_left);
float num4 = ControlHelper.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, value) + (float)upDowm;
if (IsNeedPaintDash(num4))
{
graphics.DrawLine(pen_normal, leftRight - 4, num4, leftRight - 1, num4);
RectangleF layoutRectangle = new RectangleF(0f, num4 - 9f, leftRight - 4, 20f);
graphics.DrawString(value.ToString(), font_size9, brush_deep, layoutRectangle, format_right);
if (isRenderRightCoordinate)
{
float num5 = (float)k * (value_max_right - value_min_right) / (float)value_Segment + value_min_right;
graphics.DrawLine(pen_normal, width - leftRight + 1, num4, width - leftRight + 4, num4);
layoutRectangle.Location = new PointF(width - leftRight + 4, num4 - 9f);
graphics.DrawString(num5.ToString(), font_size9, brush_deep, layoutRectangle, format_left);
}
if (k > 0 && value_IsRenderDashLine)
{
graphics.DrawLine(pen_dash, leftRight, num4, width - leftRight, num4);
}
}
}
if (value_IsRenderDashLine)
{
if (value_IsAbscissaStrech)
{
float num6 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
int num7 = CalculateDataCountByOffect(num6);
for (int l = 0; l < value_StrechDataCountMax; l += num7)
{
if (l > 0 && l < value_StrechDataCountMax - 1)
{
graphics.DrawLine(pen_dash, (float)l * num6 + (float)leftRight, upDowm, (float)l * num6 + (float)leftRight, height - upDowm - 1);
}
if (data_text != null && l < data_text.Length && (float)l * num6 + (float)leftRight < (float)(data_text.Length - 1) * num6 + (float)leftRight - 40f)
{
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);
}
}
string[] array2 = data_text;
if (array2 != null && array2.Length > 1)
{
if (data_text.Length < value_StrechDataCountMax)
{
graphics.DrawLine(pen_dash, (float)(data_text.Length - 1) * num6 + (float)leftRight, upDowm, (float)(data_text.Length - 1) * num6 + (float)leftRight, height - upDowm - 1);
}
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);
}
}
else if (value_IntervalAbscissaText > 0)
{
int num8 = width - 2 * leftRight + 1;
for (int m = leftRight; m < width - leftRight; m += value_IntervalAbscissaText)
{
if (m != leftRight)
{
graphics.DrawLine(pen_dash, m, upDowm, m, height - upDowm - 1);
}
if (data_text == null)
{
continue;
}
int num9 = (num8 > data_text.Length) ? data_text.Length : num8;
if (m - leftRight < data_text.Length && num9 - (m - leftRight) > 40)
{
if (data_text.Length <= num8)
{
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);
}
else
{
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);
}
}
}
string[] array3 = data_text;
if (array3 != null && array3.Length > 1)
{
if (data_text.Length >= num8)
{
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);
}
else
{
graphics.DrawLine(pen_dash, data_text.Length + leftRight - 1, upDowm, data_text.Length + leftRight - 1, height - upDowm - 1);
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);
}
}
}
}
for (int n = 0; n < auxiliary_lines.Count; n++)
{
if (auxiliary_lines[n].IsLeftFrame)
{
graphics.DrawLine(auxiliary_lines[n].GetPen(), leftRight - 4, auxiliary_lines[n].PaintValue, leftRight - 1, auxiliary_lines[n].PaintValue);
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);
}
else
{
graphics.DrawLine(auxiliary_lines[n].GetPen(), width - leftRight + 1, auxiliary_lines[n].PaintValue, width - leftRight + 4, auxiliary_lines[n].PaintValue);
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);
}
graphics.DrawLine(auxiliary_lines[n].GetPen(), leftRight, auxiliary_lines[n].PaintValue, width - leftRight, auxiliary_lines[n].PaintValue);
}
if (value_IsAbscissaStrech)
{
foreach (MarkText MarkText in MarkTexts)
{
foreach (KeyValuePair<string, CurveItem> item2 in data_list)
{
if (item2.Value.Visible && item2.Value.LineRenderVisiable && !(item2.Key != MarkText.CurveKey))
{
float[] data = item2.Value.Data;
if (data != null && data.Length > 1)
{
float num10 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
if (MarkText.Index >= 0 && MarkText.Index < item2.Value.Data.Length)
{
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);
graphics.FillEllipse(new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 3f, pointF.Y - 3f, 6f, 6f));
switch ((MarkText.PositionStyle == MarkTextPositionStyle.Auto) ? MarkText.CalculateDirectionFromDataIndex(item2.Value.Data, MarkText.Index) : MarkText.PositionStyle)
{
case MarkTextPositionStyle.Left:
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);
break;
case MarkTextPositionStyle.Up:
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);
break;
case MarkTextPositionStyle.Right:
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);
break;
case MarkTextPositionStyle.Down:
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);
break;
}
}
}
}
}
}
foreach (CurveItem value2 in data_list.Values)
{
if (value2.Visible && value2.LineRenderVisiable)
{
float[] data2 = value2.Data;
if (data2 != null && data2.Length > 1)
{
float num11 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
PointF[] array4 = new PointF[value2.Data.Length];
for (int num12 = 0; num12 < value2.Data.Length; num12++)
{
array4[num12].X = (float)leftRight + (float)num12 * num11;
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;
if (!string.IsNullOrEmpty(value2.MarkText[num12]))
{
using (Brush brush = new SolidBrush(value2.LineColor))
{
graphics.FillEllipse(brush, new RectangleF(array4[num12].X - 3f, array4[num12].Y - 3f, 6f, 6f));
switch (MarkText.CalculateDirectionFromDataIndex(value2.Data, num12))
{
case MarkTextPositionStyle.Left:
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);
break;
case MarkTextPositionStyle.Up:
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);
break;
case MarkTextPositionStyle.Right:
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);
break;
case MarkTextPositionStyle.Down:
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);
break;
}
}
}
}
using (Pen pen2 = new Pen(value2.LineColor, value2.LineThickness))
{
if (value2.IsSmoothCurve)
{
graphics.DrawCurve(pen2, array4);
}
else
{
graphics.DrawLines(pen2, array4);
}
}
}
}
}
}
else
{
foreach (MarkText MarkText2 in MarkTexts)
{
foreach (KeyValuePair<string, CurveItem> item3 in data_list)
{
if (item3.Value.Visible && item3.Value.LineRenderVisiable && !(item3.Key != MarkText2.CurveKey))
{
float[] data3 = item3.Value.Data;
if (data3 != null && data3.Length > 1 && MarkText2.Index >= 0 && MarkText2.Index < item3.Value.Data.Length)
{
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);
graphics.FillEllipse(new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 3f, pointF2.Y - 3f, 6f, 6f));
switch ((MarkText2.PositionStyle == MarkTextPositionStyle.Auto) ? MarkText.CalculateDirectionFromDataIndex(item3.Value.Data, MarkText2.Index) : MarkText2.PositionStyle)
{
case MarkTextPositionStyle.Left:
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);
break;
case MarkTextPositionStyle.Up:
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);
break;
case MarkTextPositionStyle.Right:
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);
break;
case MarkTextPositionStyle.Down:
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);
break;
}
}
}
}
}
foreach (CurveItem value3 in data_list.Values)
{
if (value3.Visible && value3.LineRenderVisiable)
{
float[] data4 = value3.Data;
if (data4 != null && data4.Length > 1)
{
int num13 = width - 2 * leftRight + 1;
PointF[] array5;
if (value3.Data.Length <= num13)
{
array5 = new PointF[value3.Data.Length];
for (int num14 = 0; num14 < value3.Data.Length; num14++)
{
array5[num14].X = leftRight + num14;
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;
DrawMarkPoint(graphics, value3.MarkText[num14], array5[num14], value3.LineColor, MarkText.CalculateDirectionFromDataIndex(value3.Data, num14));
}
}
else
{
array5 = new PointF[num13];
for (int num15 = 0; num15 < array5.Length; num15++)
{
int num16 = num15 + value3.Data.Length - num13;
array5[num15].X = leftRight + num15;
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;
DrawMarkPoint(graphics, value3.MarkText[num16], array5[num15], value3.LineColor, MarkText.CalculateDirectionFromDataIndex(value3.Data, num16));
}
}
using (Pen pen3 = new Pen(value3.LineColor, value3.LineThickness))
{
if (value3.IsSmoothCurve)
{
graphics.DrawCurve(pen3, array5);
}
else
{
graphics.DrawLines(pen3, array5);
}
}
}
}
}
}
base.OnPaint(e);
}
catch (Exception exc)
{
e.Graphics.DrawString(exc.Message, this.Font, Brushes.Black, 10, 10);
}
}
/// <summary>
/// Draws the mark point.
/// </summary>
/// <param name="g">The g.</param>
/// <param name="markText">The mark text.</param>
/// <param name="center">The center.</param>
/// <param name="color">The color.</param>
/// <param name="markTextPosition">The mark text position.</param>
private void DrawMarkPoint(Graphics g, string markText, PointF center, Color color, MarkTextPositionStyle markTextPosition)
{
if (!string.IsNullOrEmpty(markText))
{
using (Brush brush = new SolidBrush(color))
{
DrawMarkPoint(g, markText, center, brush, markTextPosition);
}
}
}
/// <summary>
/// Draws the mark point.
/// </summary>
/// <param name="g">The g.</param>
/// <param name="markText">The mark text.</param>
/// <param name="center">The center.</param>
/// <param name="brush">The brush.</param>
/// <param name="markTextPosition">The mark text position.</param>
private void DrawMarkPoint(Graphics g, string markText, PointF center, Brush brush, MarkTextPositionStyle markTextPosition)
{
if (!string.IsNullOrEmpty(markText))
{
g.FillEllipse(brush, new RectangleF(center.X - 3f, center.Y - 3f, 6f, 6f));
switch (markTextPosition)
{
case MarkTextPositionStyle.Left:
g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
break;
case MarkTextPositionStyle.Up:
g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
break;
case MarkTextPositionStyle.Right:
g.DrawString(markText, Font, brush, new RectangleF(center.X + (float)MarkText.MarkTextOffect, center.Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
break;
case MarkTextPositionStyle.Down:
g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
break;
}
}
}
/// <summary>
/// Determines whether [is need paint dash] [the specified paint value].
/// </summary>
/// <param name="paintValue">The paint value.</param>
/// <returns><c>true</c> if [is need paint dash] [the specified paint value]; otherwise, <c>false</c>.</returns>
private bool IsNeedPaintDash(float paintValue)
{
for (int i = 0; i < auxiliary_lines.Count; i++)
{
if (Math.Abs(auxiliary_lines[i].PaintValue - paintValue) < (float)font_size9.Height)
{
return false;
}
}
return true;
}
/// <summary>
/// Calculates the data count by offect.
/// </summary>
/// <param name="offect">The offect.</param>
/// <returns>System.Int32.</returns>
private int CalculateDataCountByOffect(float offect)
{
if (value_IntervalAbscissaText > 0)
{
return value_IntervalAbscissaText;
}
if (offect > 40f)
{
return 1;
}
offect = 40f / offect;
return (int)Math.Ceiling(offect);
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="disposing">为 true 则释放托管资源和非托管资源;为 false 则仅释放非托管资源。</param>
protected override void Dispose(bool disposing)
{
if (disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}
/// <summary>
/// Initializes the component.
/// </summary>
private void InitializeComponent()
{
SuspendLayout();
base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
BackColor = System.Drawing.Color.Transparent;
base.Name = "HslCurve";
base.Size = new System.Drawing.Size(417, 205);
ResumeLayout(false);
}
}
}