(七十一)c#Winform自定义控件-折线图
程序员文章站
2022-06-05 20:52:06
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:https://gitee.com/kwwwvagaa/net_winform_custom_contr ......
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
github:https://github.com/kwwwvagaa/netwinformcontrol
码云:
如果觉得写的还行,请点个 star 支持一下吧
欢迎前来交流探讨: 企鹅群568015492
麻烦博客下方点个【推荐】,谢谢
nuget
install-package hzh_controls
目录
用处及效果
准备工作
请先了解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为节点信息相关
完整代码
1 // *********************************************************************** 2 // assembly : hzh_controls 3 // created : 2019-09-23 4 // 5 // *********************************************************************** 6 // <copyright file="uccurve.cs"> 7 // copyright by huang zhenghui(黄正辉) all, qq group:568015492 qq:623128629 email:623128629@qq.com 8 // </copyright> 9 // 10 // blog: https://www.cnblogs.com/bfyx 11 // github:https://github.com/kwwwvagaa/netwinformcontrol 12 // gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git 13 // 14 // if you use this code, please keep this note. 15 // *********************************************************************** 16 using system; 17 using system.collections.generic; 18 using system.componentmodel; 19 using system.drawing; 20 using system.drawing.drawing2d; 21 using system.drawing.text; 22 using system.windows.forms; 23 24 namespace hzh_controls.controls 25 { 26 /// <summary> 27 /// class uccurve. 28 /// implements the <see cref="system.windows.forms.usercontrol" /> 29 /// </summary> 30 /// <seealso cref="system.windows.forms.usercontrol" /> 31 public class uccurve : usercontrol 32 { 33 /// <summary> 34 /// the value count maximum 35 /// </summary> 36 private const int value_count_max = 4096; 37 38 /// <summary> 39 /// the value maximum left 40 /// </summary> 41 private float value_max_left = 100f; 42 43 /// <summary> 44 /// the value minimum left 45 /// </summary> 46 private float value_min_left = 0f; 47 48 /// <summary> 49 /// the value maximum right 50 /// </summary> 51 private float value_max_right = 100f; 52 53 /// <summary> 54 /// the value minimum right 55 /// </summary> 56 private float value_min_right = 0f; 57 58 /// <summary> 59 /// the value segment 60 /// </summary> 61 private int value_segment = 5; 62 63 /// <summary> 64 /// the value is abscissa strech 65 /// </summary> 66 private bool value_isabscissastrech = false; 67 68 /// <summary> 69 /// the value strech data count maximum 70 /// </summary> 71 private int value_strechdatacountmax = 300; 72 73 /// <summary> 74 /// the value is render dash line 75 /// </summary> 76 private bool value_isrenderdashline = true; 77 78 /// <summary> 79 /// the text format 80 /// </summary> 81 private string textformat = "hh:mm"; 82 83 /// <summary> 84 /// the value interval abscissa text 85 /// </summary> 86 private int value_intervalabscissatext = 100; 87 88 /// <summary> 89 /// the random 90 /// </summary> 91 private random random = null; 92 93 /// <summary> 94 /// the value title 95 /// </summary> 96 private string value_title = ""; 97 98 /// <summary> 99 /// the left right 100 /// </summary> 101 private int leftright = 50; 102 103 /// <summary> 104 /// up dowm 105 /// </summary> 106 private int updowm = 50; 107 108 /// <summary> 109 /// the data list 110 /// </summary> 111 private dictionary<string, curveitem> data_list = null; 112 113 /// <summary> 114 /// the data text 115 /// </summary> 116 private string[] data_text = null; 117 118 /// <summary> 119 /// the auxiliary lines 120 /// </summary> 121 private list<auxiliaryline> auxiliary_lines; 122 123 /// <summary> 124 /// the auxiliary labels 125 /// </summary> 126 private list<auxiliarylable> auxiliary_labels; 127 128 /// <summary> 129 /// the mark texts 130 /// </summary> 131 private list<marktext> marktexts; 132 133 /// <summary> 134 /// the font size9 135 /// </summary> 136 private font font_size9 = null; 137 138 /// <summary> 139 /// the font size12 140 /// </summary> 141 private font font_size12 = null; 142 143 /// <summary> 144 /// the brush deep 145 /// </summary> 146 private brush brush_deep = null; 147 148 /// <summary> 149 /// the pen normal 150 /// </summary> 151 private pen pen_normal = null; 152 153 /// <summary> 154 /// the pen dash 155 /// </summary> 156 private pen pen_dash = null; 157 158 /// <summary> 159 /// the color normal 160 /// </summary> 161 private color color_normal = color.deeppink; 162 163 /// <summary> 164 /// the color deep 165 /// </summary> 166 private color color_deep = color.dimgray; 167 168 /// <summary> 169 /// the color dash 170 /// </summary> 171 private color color_dash = color.fromargb(232, 232, 232); 172 173 /// <summary> 174 /// the color mark font 175 /// </summary> 176 private color color_mark_font = color.dodgerblue; 177 178 /// <summary> 179 /// the brush mark font 180 /// </summary> 181 private brush brush_mark_font = brushes.dodgerblue; 182 183 /// <summary> 184 /// the format left 185 /// </summary> 186 private stringformat format_left = null; 187 188 /// <summary> 189 /// the format right 190 /// </summary> 191 private stringformat format_right = null; 192 193 /// <summary> 194 /// the format center 195 /// </summary> 196 private stringformat format_center = null; 197 198 /// <summary> 199 /// the is render right coordinate 200 /// </summary> 201 private bool isrenderrightcoordinate = true; 202 203 /// <summary> 204 /// the curve name width 205 /// </summary> 206 private int curvenamewidth = 100; 207 208 /// <summary> 209 /// the components 210 /// </summary> 211 private icontainer components = null; 212 213 /// <summary> 214 /// 获取或设置控件的背景色。 215 /// </summary> 216 /// <value>the color of the back.</value> 217 /// <permissionset> 218 /// <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" /> 219 /// </permissionset> 220 [browsable(true)] 221 [description("获取或设置控件的背景色")] 222 [category("自定义")] 223 [defaultvalue(typeof(color), "transparent")] 224 [editorbrowsable(editorbrowsablestate.always)] 225 public override color backcolor 226 { 227 get 228 { 229 return base.backcolor; 230 } 231 set 232 { 233 base.backcolor = value; 234 } 235 } 236 237 /// <summary> 238 /// gets or sets the value maximum left. 239 /// </summary> 240 /// <value>the value maximum left.</value> 241 [category("自定义")] 242 [description("获取或设置图形的左纵坐标的最大值,该值必须大于最小值")] 243 [browsable(true)] 244 [defaultvalue(100f)] 245 public float valuemaxleft 246 { 247 get 248 { 249 return value_max_left; 250 } 251 set 252 { 253 value_max_left = value; 254 invalidate(); 255 } 256 } 257 258 /// <summary> 259 /// gets or sets the value minimum left. 260 /// </summary> 261 /// <value>the value minimum left.</value> 262 [category("自定义")] 263 [description("获取或设置图形的左纵坐标的最小值,该值必须小于最大值")] 264 [browsable(true)] 265 [defaultvalue(0f)] 266 public float valueminleft 267 { 268 get 269 { 270 return value_min_left; 271 } 272 set 273 { 274 value_min_left = value; 275 invalidate(); 276 } 277 } 278 279 /// <summary> 280 /// gets or sets the value maximum right. 281 /// </summary> 282 /// <value>the value maximum right.</value> 283 [category("自定义")] 284 [description("获取或设置图形的右纵坐标的最大值,该值必须大于最小值")] 285 [browsable(true)] 286 [defaultvalue(100f)] 287 public float valuemaxright 288 { 289 get 290 { 291 return value_max_right; 292 } 293 set 294 { 295 value_max_right = value; 296 invalidate(); 297 } 298 } 299 300 /// <summary> 301 /// gets or sets the value minimum right. 302 /// </summary> 303 /// <value>the value minimum right.</value> 304 [category("自定义")] 305 [description("获取或设置图形的右纵坐标的最小值,该值必须小于最大值")] 306 [browsable(true)] 307 [defaultvalue(0f)] 308 public float valueminright 309 { 310 get 311 { 312 return value_min_right; 313 } 314 set 315 { 316 value_min_right = value; 317 invalidate(); 318 } 319 } 320 321 /// <summary> 322 /// gets or sets the value segment. 323 /// </summary> 324 /// <value>the value segment.</value> 325 [category("自定义")] 326 [description("获取或设置图形的纵轴分段数")] 327 [browsable(true)] 328 [defaultvalue(5)] 329 public int valuesegment 330 { 331 get 332 { 333 return value_segment; 334 } 335 set 336 { 337 value_segment = value; 338 invalidate(); 339 } 340 } 341 342 /// <summary> 343 /// gets or sets a value indicating whether this instance is abscissa strech. 344 /// </summary> 345 /// <value><c>true</c> if this instance is abscissa strech; otherwise, <c>false</c>.</value> 346 [category("自定义")] 347 [description("获取或设置所有的数据是否强制在一个界面里显示")] 348 [browsable(true)] 349 [defaultvalue(false)] 350 public bool isabscissastrech 351 { 352 get 353 { 354 return value_isabscissastrech; 355 } 356 set 357 { 358 value_isabscissastrech = value; 359 invalidate(); 360 } 361 } 362 363 /// <summary> 364 /// gets or sets the strech data count maximum. 365 /// </summary> 366 /// <value>the strech data count maximum.</value> 367 [category("自定义")] 368 [description("获取或设置拉伸模式下的最大数据量")] 369 [browsable(true)] 370 [defaultvalue(300)] 371 public int strechdatacountmax 372 { 373 get 374 { 375 return value_strechdatacountmax; 376 } 377 set 378 { 379 value_strechdatacountmax = value; 380 invalidate(); 381 } 382 } 383 384 /// <summary> 385 /// gets or sets a value indicating whether this instance is render dash line. 386 /// </summary> 387 /// <value><c>true</c> if this instance is render dash line; otherwise, <c>false</c>.</value> 388 [category("自定义")] 389 [description("获取或设置虚线是否进行显示")] 390 [browsable(true)] 391 [defaultvalue(true)] 392 public bool isrenderdashline 393 { 394 get 395 { 396 return value_isrenderdashline; 397 } 398 set 399 { 400 value_isrenderdashline = value; 401 invalidate(); 402 } 403 } 404 405 /// <summary> 406 /// gets or sets the color lines and text. 407 /// </summary> 408 /// <value>the color lines and text.</value> 409 [category("自定义")] 410 [description("获取或设置坐标轴及相关信息文本的颜色")] 411 [browsable(true)] 412 [defaultvalue(typeof(color), "dimgray")] 413 public color colorlinesandtext 414 { 415 get 416 { 417 return color_deep; 418 } 419 set 420 { 421 color_deep = value; 422 initializationcolor(); 423 invalidate(); 424 } 425 } 426 427 /// <summary> 428 /// gets or sets the color dash lines. 429 /// </summary> 430 /// <value>the color dash lines.</value> 431 [category("自定义")] 432 [description("获取或设置虚线的颜色")] 433 [browsable(true)] 434 public color colordashlines 435 { 436 get 437 { 438 return color_dash; 439 } 440 set 441 { 442 color_dash = value; 443 if (pen_dash != null) 444 pen_dash.dispose(); 445 pen_dash = new pen(color_dash); 446 pen_dash.dashstyle = dashstyle.custom; 447 pen_dash.dashpattern = new float[2] 448 { 449 5f, 450 5f 451 }; 452 invalidate(); 453 } 454 } 455 456 /// <summary> 457 /// gets or sets the interval abscissa text. 458 /// </summary> 459 /// <value>the interval abscissa text.</value> 460 [category("自定义")] 461 [description("获取或设置纵向虚线的分隔情况,单位为多少个数据")] 462 [browsable(true)] 463 [defaultvalue(100)] 464 public int intervalabscissatext 465 { 466 get 467 { 468 return value_intervalabscissatext; 469 } 470 set 471 { 472 value_intervalabscissatext = value; 473 invalidate(); 474 } 475 } 476 477 /// <summary> 478 /// gets or sets the text add format. 479 /// </summary> 480 /// <value>the text add format.</value> 481 [category("自定义")] 482 [description("获取或设置实时数据新增时文本相对应于时间的格式化字符串,默认hh:mm")] 483 [browsable(true)] 484 [defaultvalue("hh:mm")] 485 public string textaddformat 486 { 487 get 488 { 489 return textformat; 490 } 491 set 492 { 493 textformat = value; 494 invalidate(); 495 } 496 } 497 498 /// <summary> 499 /// gets or sets the title. 500 /// </summary> 501 /// <value>the title.</value> 502 [category("自定义")] 503 [description("获取或设置图标的标题信息")] 504 [browsable(true)] 505 [defaultvalue("")] 506 public string title 507 { 508 get 509 { 510 return value_title; 511 } 512 set 513 { 514 value_title = value; 515 invalidate(); 516 } 517 } 518 519 /// <summary> 520 /// gets or sets a value indicating whether this instance is render right coordinate. 521 /// </summary> 522 /// <value><c>true</c> if this instance is render right coordinate; otherwise, <c>false</c>.</value> 523 [category("自定义")] 524 [description("获取或设置是否显示右侧的坐标系信息")] 525 [browsable(true)] 526 [defaultvalue(true)] 527 public bool isrenderrightcoordinate 528 { 529 get 530 { 531 return isrenderrightcoordinate; 532 } 533 set 534 { 535 isrenderrightcoordinate = value; 536 invalidate(); 537 } 538 } 539 540 /// <summary> 541 /// gets or sets the width of the curve name. 542 /// </summary> 543 /// <value>the width of the curve name.</value> 544 [browsable(true)] 545 [description("获取或设置曲线名称的布局宽度")] 546 [category("自定义")] 547 [defaultvalue(100)] 548 public int curvenamewidth 549 { 550 get 551 { 552 return curvenamewidth; 553 } 554 set 555 { 556 if (value > 10) 557 { 558 curvenamewidth = value; 559 } 560 } 561 } 562 563 /// <summary> 564 /// initializes a new instance of the <see cref="uccurve" /> class. 565 /// </summary> 566 public uccurve() 567 { 568 initializecomponent(); 569 random = new random(); 570 data_list = new dictionary<string, curveitem>(); 571 auxiliary_lines = new list<auxiliaryline>(); 572 marktexts = new list<marktext>(); 573 auxiliary_labels = new list<auxiliarylable>(); 574 format_left = new stringformat 575 { 576 linealignment = stringalignment.center, 577 alignment = stringalignment.near 578 }; 579 format_right = new stringformat 580 { 581 linealignment = stringalignment.center, 582 alignment = stringalignment.far 583 }; 584 format_center = new stringformat 585 { 586 linealignment = stringalignment.center, 587 alignment = stringalignment.center 588 }; 589 font_size9 = new font("微软雅黑", 9f); 590 font_size12 = new font("微软雅黑", 12f); 591 initializationcolor(); 592 pen_dash = new pen(color_deep); 593 pen_dash.dashstyle = dashstyle.custom; 594 pen_dash.dashpattern = new float[2] 595 { 596 5f, 597 5f 598 }; 599 setstyle(controlstyles.userpaint | controlstyles.supportstransparentbackcolor, true); 600 setstyle(controlstyles.resizeredraw, true); 601 setstyle(controlstyles.optimizeddoublebuffer, true); 602 setstyle(controlstyles.allpaintinginwmpaint, true); 603 } 604 605 /// <summary> 606 /// initializations the color. 607 /// </summary> 608 private void initializationcolor() 609 { 610 if (pen_normal != null) 611 pen_normal.dispose(); 612 if (brush_deep != null) 613 brush_deep.dispose(); 614 pen_normal = new pen(color_deep); 615 brush_deep = new solidbrush(color_deep); 616 } 617 618 /// <summary> 619 /// sets the curve text. 620 /// </summary> 621 /// <param name="descriptions">the descriptions.</param> 622 public void setcurvetext(string[] descriptions) 623 { 624 data_text = descriptions; 625 invalidate(); 626 } 627 628 /// <summary> 629 /// sets the left curve. 630 /// </summary> 631 /// <param name="key">the key.</param> 632 /// <param name="data">the data.</param> 633 /// <param name="linecolor">color of the line.</param> 634 public void setleftcurve(string key, float[] data, color? linecolor = null) 635 { 636 setcurve(key, true, data, linecolor, 1f, false); 637 } 638 639 /// <summary> 640 /// sets the left curve. 641 /// </summary> 642 /// <param name="key">the key.</param> 643 /// <param name="data">the data.</param> 644 /// <param name="linecolor">color of the line.</param> 645 /// <param name="issmooth">if set to <c>true</c> [is smooth].</param> 646 public void setleftcurve(string key, float[] data, color? linecolor, bool issmooth = false) 647 { 648 setcurve(key, true, data, linecolor, 1f, issmooth); 649 } 650 651 /// <summary> 652 /// sets the right curve. 653 /// </summary> 654 /// <param name="key">the key.</param> 655 /// <param name="data">the data.</param> 656 /// <param name="linecolor">color of the line.</param> 657 public void setrightcurve(string key, float[] data, color? linecolor = null) 658 { 659 setcurve(key, false, data, linecolor, 1f, false); 660 } 661 662 /// <summary> 663 /// sets the right curve. 664 /// </summary> 665 /// <param name="key">the key.</param> 666 /// <param name="data">the data.</param> 667 /// <param name="linecolor">color of the line.</param> 668 /// <param name="issmooth">if set to <c>true</c> [is smooth].</param> 669 public void setrightcurve(string key, float[] data, color? linecolor, bool issmooth = false) 670 { 671 setcurve(key, false, data, linecolor, 1f, issmooth); 672 } 673 674 /// <summary> 675 /// sets the curve. 676 /// </summary> 677 /// <param name="key">the key.</param> 678 /// <param name="isleft">if set to <c>true</c> [is left].</param> 679 /// <param name="data">the data.</param> 680 /// <param name="linecolor">color of the line.</param> 681 /// <param name="thickness">the thickness.</param> 682 /// <param name="issmooth">if set to <c>true</c> [is smooth].</param> 683 public void setcurve(string key, bool isleft, float[] data, color? linecolor, float thickness, bool issmooth) 684 { 685 if (data_list.containskey(key)) 686 { 687 if (data == null) 688 { 689 data = new float[0]; 690 } 691 data_list[key].data = data; 692 } 693 else 694 { 695 if (data == null) 696 { 697 data = new float[0]; 698 } 699 data_list.add(key, new curveitem 700 { 701 data = data, 702 marktext = new string[data.length], 703 linethickness = thickness, 704 linecolor = linecolor ?? controlhelper.colors[data_list.count + 13], 705 isleftframe = isleft, 706 issmoothcurve = issmooth 707 }); 708 if (data_text == null) 709 { 710 data_text = new string[data.length]; 711 } 712 } 713 invalidate(); 714 } 715 716 /// <summary> 717 /// removes the curve. 718 /// </summary> 719 /// <param name="key">the key.</param> 720 public void removecurve(string key) 721 { 722 if (data_list.containskey(key)) 723 { 724 data_list.remove(key); 725 } 726 if (data_list.count == 0) 727 { 728 data_text = new string[0]; 729 } 730 invalidate(); 731 } 732 733 /// <summary> 734 /// removes all curve. 735 /// </summary> 736 public void removeallcurve() 737 { 738 int count = data_list.count; 739 data_list.clear(); 740 if (data_list.count == 0) 741 { 742 data_text = new string[0]; 743 } 744 if (count > 0) 745 { 746 invalidate(); 747 } 748 } 749 750 /// <summary> 751 /// removes all curve data. 752 /// </summary> 753 public void removeallcurvedata() 754 { 755 int count = data_list.count; 756 foreach (keyvaluepair<string, curveitem> item in data_list) 757 { 758 item.value.data = new float[0]; 759 item.value.marktext = new string[0]; 760 } 761 data_text = new string[0]; 762 if (count > 0) 763 { 764 invalidate(); 765 } 766 } 767 768 /// <summary> 769 /// gets the curve item. 770 /// </summary> 771 /// <param name="key">the key.</param> 772 /// <returns>curveitem.</returns> 773 public curveitem getcurveitem(string key) 774 { 775 if (data_list.containskey(key)) 776 { 777 return data_list[key]; 778 } 779 return null; 780 } 781 782 /// <summary> 783 /// saves to bitmap. 784 /// </summary> 785 /// <returns>bitmap.</returns> 786 public bitmap savetobitmap() 787 { 788 return savetobitmap(base.width, base.height); 789 } 790 791 /// <summary> 792 /// saves to bitmap. 793 /// </summary> 794 /// <param name="width">the width.</param> 795 /// <param name="height">the height.</param> 796 /// <returns>bitmap.</returns> 797 public bitmap savetobitmap(int width, int height) 798 { 799 bitmap bitmap = new bitmap(width, height); 800 graphics graphics = graphics.fromimage(bitmap); 801 onpaint(new painteventargs(graphics, new rectangle(0, 0, width, height))); 802 return bitmap; 803 } 804 805 /// <summary> 806 /// adds the curve data. 807 /// </summary> 808 /// <param name="key">the key.</param> 809 /// <param name="values">the values.</param> 810 /// <param name="marktexts">the mark texts.</param> 811 /// <param name="isupdateui">if set to <c>true</c> [is update ui].</param> 812 private void addcurvedata(string key, float[] values, string[] marktexts, bool isupdateui) 813 { 814 if ((values != null && values.length < 1) || !data_list.containskey(key)) 815 { 816 return; 817 } 818 curveitem curveitem = data_list[key]; 819 if (curveitem.data != null) 820 { 821 if (value_isabscissastrech) 822 { 823 controlhelper.addarraydata(ref curveitem.data, values, value_strechdatacountmax); 824 controlhelper.addarraydata(ref curveitem.marktext, marktexts, value_strechdatacountmax); 825 } 826 else 827 { 828 controlhelper.addarraydata(ref curveitem.data, values, 4096); 829 controlhelper.addarraydata(ref curveitem.marktext, marktexts, 4096); 830 } 831 if (isupdateui) 832 { 833 invalidate(); 834 } 835 } 836 } 837 838 /// <summary> 839 /// adds the curve time. 840 /// </summary> 841 /// <param name="count">the count.</param> 842 private void addcurvetime(int count) 843 { 844 addcurvetime(count, datetime.now.tostring(textformat)); 845 } 846 847 /// <summary> 848 /// adds the curve time. 849 /// </summary> 850 /// <param name="count">the count.</param> 851 /// <param name="text">the text.</param> 852 private void addcurvetime(int count, string text) 853 { 854 if (data_text != null) 855 { 856 string[] array = new string[count]; 857 for (int i = 0; i < array.length; i++) 858 { 859 array[i] = text; 860 } 861 if (value_isabscissastrech) 862 { 863 controlhelper.addarraydata(ref data_text, array, value_strechdatacountmax); 864 } 865 else 866 { 867 controlhelper.addarraydata(ref data_text, array, 4096); 868 } 869 } 870 } 871 872 /// <summary> 873 /// adds the curve data. 874 /// </summary> 875 /// <param name="key">the key.</param> 876 /// <param name="value">the value.</param> 877 public void addcurvedata(string key, float value) 878 { 879 addcurvedata(key, new float[1] 880 { 881 value 882 }); 883 } 884 885 /// <summary> 886 /// adds the curve data. 887 /// </summary> 888 /// <param name="key">the key.</param> 889 /// <param name="value">the value.</param> 890 /// <param name="marktext">the mark text.</param> 891 public void addcurvedata(string key, float value, string marktext) 892 { 893 addcurvedata(key, new float[1] 894 { 895 value 896 }, new string[1] 897 { 898 marktext 899 }); 900 } 901 902 /// <summary> 903 /// adds the curve data. 904 /// </summary> 905 /// <param name="key">the key.</param> 906 /// <param name="values">the values.</param> 907 public void addcurvedata(string key, float[] values) 908 { 909 addcurvedata(key, values, null); 910 } 911 912 /// <summary> 913 /// adds the curve data. 914 /// </summary> 915 /// <param name="key">the key.</param> 916 /// <param name="values">the values.</param> 917 /// <param name="marktexts">the mark texts.</param> 918 public void addcurvedata(string key, float[] values, string[] marktexts) 919 { 920 if (marktexts == null) 921 { 922 marktexts = new string[values.length]; 923 } 924 addcurvedata(key, values, marktexts, false); 925 if (values != null && values.length != 0) 926 { 927 addcurvetime(values.length); 928 } 929 invalidate(); 930 } 931 932 /// <summary> 933 /// adds the curve data. 934 /// </summary> 935 /// <param name="keys">the keys.</param> 936 /// <param name="values">the values.</param> 937 public void addcurvedata(string[] keys, float[] values) 938 { 939 addcurvedata(keys, values, null); 940 } 941 942 /// <summary> 943 /// adds the curve data. 944 /// </summary> 945 /// <param name="axistext">the axis text.</param> 946 /// <param name="keys">the keys.</param> 947 /// <param name="values">the values.</param> 948 public void addcurvedata(string axistext, string[] keys, float[] values) 949 { 950 addcurvedata(axistext, keys, values, null); 951 } 952 953 /// <summary> 954 /// adds the curve data. 955 /// </summary> 956 /// <param name="keys">the keys.</param> 957 /// <param name="values">the values.</param> 958 /// <param name="marktexts">the mark texts.</param> 959 /// <exception cref="argumentnullexception">keys 960 /// or 961 /// values</exception> 962 /// <exception cref="exception">两个参数的数组长度不一致。 963 /// or 964 /// 两个参数的数组长度不一致。</exception> 965 public void addcurvedata(string[] keys, float[] values, string[] marktexts) 966 { 967 if (keys == null) 968 { 969 throw new argumentnullexception("keys"); 970 } 971 if (values == null) 972 { 973 throw new argumentnullexception("values"); 974 } 975 if (marktexts == null) 976 { 977 marktexts = new string[keys.length]; 978 } 979 if (keys.length != values.length) 980 { 981 throw new exception("两个参数的数组长度不一致。"); 982 } 983 if (keys.length != marktexts.length) 984 { 985 throw new exception("两个参数的数组长度不一致。"); 986 } 987 for (int i = 0; i < keys.length; i++) 988 { 989 addcurvedata(keys[i], new float[1] 990 { 991 values[i] 992 }, new string[1] 993 { 994 marktexts[i] 995 }, false); 996 } 997 addcurvetime(1); 998 invalidate(); 999 } 1000 1001 /// <summary> 1002 /// adds the curve data. 1003 /// </summary> 1004 /// <param name="axistext">the axis text.</param> 1005 /// <param name="keys">the keys.</param> 1006 /// <param name="values">the values.</param> 1007 /// <param name="marktexts">the mark texts.</param> 1008 /// <exception cref="argumentnullexception">keys 1009 /// or 1010 /// values</exception> 1011 /// <exception cref="exception">两个参数的数组长度不一致。 1012 /// or 1013 /// 两个参数的数组长度不一致。</exception> 1014 public void addcurvedata(string axistext, string[] keys, float[] values, string[] marktexts) 1015 { 1016 if (keys == null) 1017 { 1018 throw new argumentnullexception("keys"); 1019 } 1020 if (values == null) 1021 { 1022 throw new argumentnullexception("values"); 1023 } 1024 if (marktexts == null) 1025 { 1026 marktexts = new string[keys.length]; 1027 } 1028 if (keys.length != values.length) 1029 { 1030 throw new exception("两个参数的数组长度不一致。"); 1031 } 1032 if (keys.length != marktexts.length) 1033 { 1034 throw new exception("两个参数的数组长度不一致。"); 1035 } 1036 for (int i = 0; i < keys.length; i++) 1037 { 1038 addcurvedata(keys[i], new float[1] 1039 { 1040 values[i] 1041 }, new string[1] 1042 { 1043 marktexts[i] 1044 }, false); 1045 } 1046 addcurvetime(1, axistext); 1047 invalidate(); 1048 } 1049 1050 /// <summary> 1051 /// sets the curve visible. 1052 /// </summary> 1053 /// <param name="key">the key.</param> 1054 /// <param name="visible">if set to <c>true</c> [visible].</param> 1055 public void setcurvevisible(string key, bool visible) 1056 { 1057 if (data_list.containskey(key)) 1058 { 1059 curveitem curveitem = data_list[key]; 1060 curveitem.visible = visible; 1061 invalidate(); 1062 } 1063 } 1064 1065 /// <summary> 1066 /// sets the curve visible. 1067 /// </summary> 1068 /// <param name="keys">the keys.</param> 1069 /// <param name="visible">if set to <c>true</c> [visible].</param> 1070 public void setcurvevisible(string[] keys, bool visible) 1071 { 1072 foreach (string key in keys) 1073 { 1074 if (data_list.containskey(key)) 1075 { 1076 curveitem curveitem = data_list[key]; 1077 curveitem.visible = visible; 1078 } 1079 } 1080 invalidate(); 1081 } 1082 1083 /// <summary> 1084 /// adds the left auxiliary. 1085 /// </summary> 1086 /// <param name="value">the value.</param> 1087 public void addleftauxiliary(float value) 1088 { 1089 addleftauxiliary(value, colorlinesandtext); 1090 } 1091 1092 /// <summary> 1093 /// adds the left auxiliary. 1094 /// </summary> 1095 /// <param name="value">the value.</param> 1096 /// <param name="linecolor">color of the line.</param> 1097 public void addleftauxiliary(float value, color linecolor) 1098 { 1099 addleftauxiliary(value, linecolor, 1f, true); 1100 } 1101 1102 /// <summary> 1103 /// adds the left auxiliary. 1104 /// </summary> 1105 /// <param name="value">the value.</param> 1106 /// <param name="linecolor">color of the line.</param> 1107 /// <param name="linethickness">the line thickness.</param> 1108 /// <param name="isdashline">if set to <c>true</c> [is dash line].</param> 1109 public void addleftauxiliary(float value, color linecolor, float linethickness, bool isdashline) 1110 { 1111 addauxiliary(value, linecolor, linethickness, isdashline, true); 1112 } 1113 1114 /// <summary> 1115 /// adds the right auxiliary. 1116 /// </summary> 1117 /// <param name="value">the value.</param> 1118 public void addrightauxiliary(float value) 1119 { 1120 addrightauxiliary(value, colorlinesandtext); 1121 } 1122 1123 /// <summary> 1124 /// adds the right auxiliary. 1125 /// </summary> 1126 /// <param name="value">the value.</param> 1127 /// <param name="linecolor">color of the line.</param> 1128 public void addrightauxiliary(float value, color linecolor) 1129 { 1130 addrightauxiliary(value, linecolor, 1f, true); 1131 } 1132 1133 /// <summary> 1134 /// adds the right auxiliary. 1135 /// </summary> 1136 /// <param name="value">the value.</param> 1137 /// <param name="linecolor">color of the line.</param> 1138 /// <param name="linethickness">the line thickness.</param> 1139 /// <param name="isdashline">if set to <c>true</c> [is dash line].</param> 1140 public void addrightauxiliary(float value, color linecolor, float linethickness, bool isdashline) 1141 { 1142 addauxiliary(value, linecolor, linethickness, isdashline, false); 1143 } 1144 1145 /// <summary> 1146 /// adds the auxiliary. 1147 /// </summary> 1148 /// <param name="value">the value.</param> 1149 /// <param name="linecolor">color of the line.</param> 1150 /// <param name="linethickness">the line thickness.</param> 1151 /// <param name="isdashline">if set to <c>true</c> [is dash line].</param> 1152 /// <param name="isleft">if set to <c>true</c> [is left].</param> 1153 private void addauxiliary(float value, color linecolor, float linethickness, bool isdashline, bool isleft) 1154 { 1155 auxiliary_lines.add(new auxiliaryline 1156 { 1157 value = value, 1158 linecolor = linecolor, 1159 pendash = new pen(linecolor) 1160 { 1161 dashstyle = dashstyle.custom, 1162 dashpattern = new float[2] 1163 { 1164 5f, 1165 5f 1166 } 1167 }, 1168 pensolid = new pen(linecolor), 1169 isdashstyle = isdashline, 1170 isleftframe = isleft, 1171 linethickness = linethickness, 1172 linetextbrush = new solidbrush(linecolor) 1173 }); 1174 invalidate(); 1175 } 1176 1177 /// <summary> 1178 /// removes the auxiliary. 1179 /// </summary> 1180 /// <param name="value">the value.</param> 1181 public void removeauxiliary(float value) 1182 { 1183 int num = 0; 1184 for (int num2 = auxiliary_lines.count - 1; num2 >= 0; num2--) 1185 { 1186 if (auxiliary_lines[num2].value == value) 1187 { 1188 auxiliary_lines[num2].dispose(); 1189 auxiliary_lines.removeat(num2); 1190 num++; 1191 } 1192 } 1193 if (num > 0) 1194 { 1195 invalidate(); 1196 } 1197 } 1198 1199 /// <summary> 1200 /// removes all auxiliary. 1201 /// </summary> 1202 public void removeallauxiliary() 1203 { 1204 int count = auxiliary_lines.count; 1205 auxiliary_lines.clear(); 1206 if (count > 0) 1207 { 1208 invalidate(); 1209 } 1210 } 1211 1212 /// <summary> 1213 /// adds the auxiliary label. 1214 /// </summary> 1215 /// <param name="auxiliarylable">the auxiliary lable.</param> 1216 public void addauxiliarylabel(auxiliarylable auxiliarylable) 1217 { 1218 auxiliary_labels.add(auxiliarylable); 1219 } 1220 1221 /// <summary> 1222 /// removes the auxiliary lable. 1223 /// </summary> 1224 /// <param name="auxiliarylable">the auxiliary lable.</param> 1225 public void removeauxiliarylable(auxiliarylable auxiliarylable) 1226 { 1227 if (auxiliary_labels.remove(auxiliarylable)) 1228 { 1229 invalidate(); 1230 } 1231 } 1232 1233 /// <summary> 1234 /// removes all auxiliary lable. 1235 /// </summary> 1236 public void removeallauxiliarylable() 1237 { 1238 int count = auxiliary_labels.count; 1239 auxiliary_labels.clear(); 1240 if (count > 0) 1241 { 1242 invalidate(); 1243 } 1244 } 1245 1246 /// <summary> 1247 /// adds the mark text. 1248 /// </summary> 1249 /// <param name="marktext">the mark text.</param> 1250 public void addmarktext(marktext marktext) 1251 { 1252 marktexts.add(marktext); 1253 if (data_list.count > 0) 1254 { 1255 invalidate(); 1256 } 1257 } 1258 1259 /// <summary> 1260 /// adds the mark text. 1261 /// </summary> 1262 /// <param name="strcurvekey">the string curve key.</param> 1263 /// <param name="intvalueindex">index of the int value.</param> 1264 /// <param name="strtext">the string text.</param> 1265 /// <param name="textcolor">color of the text.</param> 1266 public void addmarktext(string strcurvekey, int intvalueindex, string strtext, color? textcolor = null) 1267 { 1268 addmarktext(new marktext() { curvekey = strcurvekey, positionstyle = marktextpositionstyle.auto, text = strtext, textcolor = textcolor, index = intvalueindex }); 1269 } 1270 1271 /// <summary> 1272 /// removes the mark text. 1273 /// </summary> 1274 /// <param name="marktext">the mark text.</param> 1275 public void removemarktext(marktext marktext) 1276 { 1277 marktexts.remove(marktext); 1278 if (data_list.count > 0) 1279 { 1280 invalidate(); 1281 } 1282 } 1283 1284 /// <summary> 1285 /// removes all mark text. 1286 /// </summary> 1287 public void removeallmarktext() 1288 { 1289 marktexts.clear(); 1290 if (data_list.count > 0) 1291 { 1292 invalidate(); 1293 } 1294 } 1295 1296 /// <summary> 1297 /// 引发 <see cref="e:system.windows.forms.control.mousemove" /> 事件。 1298 /// </summary> 1299 /// <param name="e">包含事件数据的 <see cref="t:system.windows.forms.mouseeventargs" />。</param> 1300 protected override void onmousemove(mouseeventargs e) 1301 { 1302 base.onmousemove(e); 1303 bool flag = false; 1304 foreach (keyvaluepair<string, curveitem> item in data_list) 1305 { 1306 if (item.value.titleregion.contains(e.location)) 1307 { 1308 flag = true; 1309 break; 1310 } 1311 } 1312 cursor = (flag ? cursors.hand : cursors.arrow); 1313 } 1314 1315 /// <summary> 1316 /// handles the <see cref="e:mousedown" /> event. 1317 /// </summary> 1318 /// <param name="e">包含事件数据的 <see cref="t:system.windows.forms.mouseeventargs" />。</param> 1319 protected override void onmousedown(mouseeventargs e) 1320 { 1321 base.onmousedown(e); 1322 foreach (keyvaluepair<string, curveitem> item in data_list) 1323 { 1324 if (item.value.titleregion.contains(e.location)) 1325 { 1326 item.value.linerendervisiable = !item.value.linerendervisiable; 1327 invalidate(); 1328 break; 1329 } 1330 } 1331 } 1332 1333 /// <summary> 1334 /// 引发 <see cref="e:system.windows.forms.control.paint" /> 事件。 1335 /// </summary> 1336 /// <param name="e">包含事件数据的 <see cref="t:system.windows.forms.painteventargs" />。</param> 1337 protected override void onpaint(painteventargs e) 1338 { 1339 try 1340 { 1341 graphics graphics = e.graphics; 1342 graphics.setgdihigh(); 1343 if (backcolor != color.transparent) 1344 { 1345 graphics.clear(backcolor); 1346 } 1347 int width = base.width; 1348 int height = base.height; 1349 if (width < 120 || height < 60) 1350 { 1351 return; 1352 } 1353 point[] array = new point[4] 1354 { 1355 new point(leftright - 1, updowm - 8), 1356 new point(leftright - 1, height - updowm), 1357 new point(width - leftright, height - updowm), 1358 new point(width - leftright, updowm - 8) 1359 }; 1360 graphics.drawline(pen_normal, array[0], array[1]); 1361 graphics.drawline(pen_normal, array[1], array[2]); 1362 if (isrenderrightcoordinate) 1363 { 1364 graphics.drawline(pen_normal, array[2], array[3]); 1365 } 1366 1367 if (!string.isnullorempty(value_title)) 1368 { 1369 graphics.drawstring(value_title, font_size9, brush_deep, new rectangle(0, 0, width - 1, 20), format_center); 1370 } 1371 1372 if (data_list.count > 0) 1373 { 1374 float num = leftright + 10; 1375 foreach (keyvaluepair<string, curveitem> item in data_list) 1376 { 1377 if (item.value.visible) 1378 { 1379 var titlesize=graphics.measurestring(item.key, font); 1380 solidbrush solidbrush = item.value.linerendervisiable ? new solidbrush(item.value.linecolor) : new solidbrush(color.fromargb(80, item.value.linecolor)); 1381 graphics.fillrectangle(solidbrush, num + 8f, 24f, 20f, 14f); 1382 graphics.drawstring(item.key, font, solidbrush, new pointf(num + 30f, 24f+(14 - titlesize.height) / 2)); 1383 item.value.titleregion = new rectanglef(num, 24f, 60f, 18f); 1384 solidbrush.dispose(); 1385 num += titlesize.width + 30; 1386 } 1387 } 1388 } 1389 1390 1391 for (int i = 0; i < auxiliary_labels.count; i++) 1392 { 1393 if (!string.isnullorempty(auxiliary_labels[i].text)) 1394 { 1395 int num2 = (auxiliary_labels[i].locationx > 1f) ? ((int)auxiliary_labels[i].locationx) : ((int)(auxiliary_labels[i].locationx * (float)width)); 1396 int num3 = (int)graphics.measurestring(auxiliary_labels[i].text, font).width + 3; 1397 point[] points = new point[6] 1398 { 1399 new point(num2, 11), 1400 new point(num2 + 10, 20), 1401 new point(num2 + num3 + 10, 20), 1402 new point(num2 + num3 + 10, 0), 1403 new point(num2 + 10, 0), 1404 new point(num2, 11) 1405 }; 1406 graphics.fillpolygon(auxiliary_labels[i].textback, points); 1407 graphics.drawstring(auxiliary_labels[i].text, font, auxiliary_labels[i].textbrush, new rectangle(num2 + 7, 0, num3 + 3, 20), format_center); 1408 } 1409 } 1410 controlhelper.painttriangle(graphics, brush_deep, new point(leftright - 1, updowm - 8), 4, graphdirection.upward); 1411 if (isrenderrightcoordinate) 1412 { 1413 controlhelper.painttriangle(graphics, brush_deep, new point(width - leftright, updowm - 8), 4, graphdirection.upward); 1414 } 1415 for (int j = 0; j < auxiliary_lines.count; j++) 1416 { 1417 if (auxiliary_lines[j].isleftframe) 1418 { 1419 auxiliary_lines[j].paintvalue = controlhelper.computepaintlocationy(value_max_left, value_min_left, height - updowm - updowm, auxiliary_lines[j].value) + (float)updowm; 1420 } 1421 else 1422 { 1423 auxiliary_lines[j].paintvalue = controlhelper.computepaintlocationy(value_max_right, value_min_right, height - updowm - updowm, auxiliary_lines[j].value) + (float)updowm; 1424 } 1425 } 1426 for (int k = 0; k <= value_segment; k++) 1427 { 1428 float value = (float)((double)k * (double)(value_max_left - value_min_left) / (double)value_segment + (double)value_min_left); 1429 float num4 = controlhelper.computepaintlocationy(value_max_left, value_min_left, height - updowm - updowm, value) + (float)updowm; 1430 if (isneedpaintdash(num4)) 1431 { 1432 graphics.drawline(pen_normal, leftright - 4, num4, leftright - 1, num4); 1433 rectanglef layoutrectangle = new rectanglef(0f, num4 - 9f, leftright - 4, 20f); 1434 graphics.drawstring(value.tostring(), font_size9, brush_deep, layoutrectangle, format_right); 1435 if (isrenderrightcoordinate) 1436 { 1437 float num5 = (float)k * (value_max_right - value_min_right) / (float)value_segment + value_min_right; 1438 graphics.drawline(pen_normal, width - leftright + 1, num4, width - leftright + 4, num4); 1439 layoutrectangle.location = new pointf(width - leftright + 4, num4 - 9f); 1440 graphics.drawstring(num5.tostring(), font_size9, brush_deep, layoutrectangle, format_left); 1441 } 1442 if (k > 0 && value_isrenderdashline) 1443 { 1444 graphics.drawline(pen_dash, leftright, num4, width - leftright, num4); 1445 } 1446 } 1447 } 1448 if (value_isrenderdashline) 1449 { 1450 if (value_isabscissastrech) 1451 { 1452 float num6 = (float)(width - leftright * 2) * 1f / (float)(value_strechdatacountmax - 1); 1453 int num7 = calculatedatacountbyoffect(num6); 1454 for (int l = 0; l < value_strechdatacountmax; l += num7) 1455 { 1456 if (l > 0 && l < value_strechdatacountmax - 1) 1457 { 1458 graphics.drawline(pen_dash, (float)l * num6 + (float)leftright, updowm, (float)l * num6 + (float)leftright, height - updowm - 1); 1459 } 1460 if (data_text != null && l < data_text.length && (float)l * num6 + (float)leftright < (float)(data_text.length - 1) * num6 + (float)leftright - 40f) 1461 { 1462 graphics.drawstring(layoutrectangle: new rectangle((int)((float)l * num6), height - updowm + 1, leftright * 2, updowm), s: data_text[l], font: font_size9, brush: brush_deep, format: format_center); 1463 } 1464 } 1465 string[] array2 = data_text; 1466 if (array2 != null && array2.length > 1) 1467 { 1468 if (data_text.length < value_strechdatacountmax) 1469 { 1470 graphics.drawline(pen_dash, (float)(data_text.length - 1) * num6 + (float)leftright, updowm, (float)(data_text.length - 1) * num6 + (float)leftright, height - updowm - 1); 1471 } 1472 graphics.drawstring(layoutrectangle: new rectangle((int)((float)(data_text.length - 1) * num6 + (float)leftright) - leftright, height - updowm + 1, leftright * 2, updowm), s: data_text[data_text.length - 1], font: font_size9, brush: brush_deep, format: format_center); 1473 } 1474 } 1475 else if (value_intervalabscissatext > 0) 1476 { 1477 int num8 = width - 2 * leftright + 1; 1478 for (int m = leftright; m < width - leftright; m += value_intervalabscissatext) 1479 { 1480 if (m != leftright) 1481 { 1482 graphics.drawline(pen_dash, m, updowm, m, height - updowm - 1); 1483 } 1484 if (data_text == null) 1485 { 1486 continue; 1487 } 1488 int num9 = (num8 > data_text.length) ? data_text.length : num8; 1489 if (m - leftright < data_text.length && num9 - (m - leftright) > 40) 1490 { 1491 if (data_text.length <= num8) 1492 { 1493 graphics.drawstring(layoutrectangle: new rectangle(m - leftright, height - updowm + 1, leftright * 2, updowm), s: data_text[m - leftright], font: font_size9, brush: brush_deep, format: format_center); 1494 } 1495 else 1496 { 1497 graphics.drawstring(layoutrectangle: new rectangle(m - leftright, height - updowm + 1, leftright * 2, updowm), s: data_text[m - leftright + data_text.length - num8], font: font_size9, brush: brush_deep, format: format_center); 1498 } 1499 } 1500 } 1501 string[] array3 = data_text; 1502 if (array3 != null && array3.length > 1) 1503 { 1504 if (data_text.length >= num8) 1505 { 1506 graphics.drawstring(layoutrectangle: new rectangle(width - leftright - leftright, height - updowm + 1, leftright * 2, updowm), s: data_text[data_text.length - 1], font: font_size9, brush: brush_deep, format: format_center); 1507 } 1508 else 1509 { 1510 graphics.drawline(pen_dash, data_text.length + leftright - 1, updowm, data_text.length + leftright - 1, height - updowm - 1); 1511 graphics.drawstring(layoutrectangle: new rectangle(data_text.length + leftright - 1 - leftright, height - updowm + 1, leftright * 2, updowm), s: data_text[data_text.length - 1], font: font_size9, brush: brush_deep, format: format_center); 1512 } 1513 } 1514 } 1515 } 1516 for (int n = 0; n < auxiliary_lines.count; n++) 1517 { 1518 if (auxiliary_lines[n].isleftframe) 1519 { 1520 graphics.drawline(auxiliary_lines[n].getpen(), leftright - 4, auxiliary_lines[n].paintvalue, leftright - 1, auxiliary_lines[n].paintvalue); 1521 graphics.drawstring(layoutrectangle: new rectanglef(0f, auxiliary_lines[n].paintvalue - 9f, leftright - 4, 20f), s: auxiliary_lines[n].value.tostring(), font: font_size9, brush: auxiliary_lines[n].linetextbrush, format: format_right); 1522 } 1523 else 1524 { 1525 graphics.drawline(auxiliary_lines[n].getpen(), width - leftright + 1, auxiliary_lines[n].paintvalue, width - leftright + 4, auxiliary_lines[n].paintvalue); 1526 graphics.drawstring(layoutrectangle: new rectanglef(width - leftright + 4, auxiliary_lines[n].paintvalue - 9f, leftright - 4, 20f), s: auxiliary_lines[n].value.tostring(), font: font_size9, brush: auxiliary_lines[n].linetextbrush, format: format_left); 1527 } 1528 graphics.drawline(auxiliary_lines[n].getpen(), leftright, auxiliary_lines[n].paintvalue, width - leftright, auxiliary_lines[n].paintvalue); 1529 } 1530 if (value_isabscissastrech) 1531 { 1532 foreach (marktext marktext in marktexts) 1533 { 1534 foreach (keyvaluepair<string, curveitem> item2 in data_list) 1535 { 1536 if (item2.value.visible && item2.value.linerendervisiable && !(item2.key != marktext.curvekey)) 1537 { 1538 float[] data = item2.value.data; 1539 if (data != null && data.length > 1) 1540 { 1541 float num10 = (float)(width - leftright * 2) * 1f / (float)(value_strechdatacountmax - 1); 1542 if (marktext.index >= 0 && marktext.index < item2.value.data.length) 1543 { 1544 pointf pointf = new pointf((float)leftright + (float)marktext.index * num10, controlhelper.computepaintlocationy(item2.value.isleftframe ? value_max_left : value_max_right, item2.value.isleftframe ? value_min_left : value_min_right, height - updowm - updowm, item2.value.data[marktext.index]) + (float)updowm); 1545 graphics.fillellipse(new solidbrush(marktext.textcolor ?? item2.value.linecolor), new rectanglef(pointf.x - 3f, pointf.y - 3f, 6f, 6f)); 1546 switch ((marktext.positionstyle == marktextpositionstyle.auto) ? marktext.calculatedirectionfromdataindex(item2.value.data, marktext.index) : marktext.positionstyle) 1547 { 1548 case marktextpositionstyle.left: 1549 graphics.drawstring(marktext.text, font, new solidbrush(marktext.textcolor ?? item2.value.linecolor), new rectanglef(pointf.x - 100f, pointf.y - (float)font.height, 100 - marktext.marktextoffect, font.height * 2), format_right); 1550 break; 1551 case marktextpositionstyle.up: 1552 graphics.drawstring(marktext.text, font, new solidbrush(marktext.textcolor ?? item2.value.linecolor), new rectanglef(pointf.x - 100f, pointf.y - (float)font.height - (float)marktext.marktextoffect, 200f, font.height + 2), format_center); 1553 break; 1554 case marktextpositionstyle.right: 1555 graphics.drawstring(marktext.text, font, new solidbrush(marktext.textcolor ?? item2.value.linecolor), new rectanglef(pointf.x + (float)marktext.marktextoffect, pointf.y - (float)font.height, 100f, font.height * 2), format_left); 1556 break; 1557 case marktextpositionstyle.down: 1558 graphics.drawstring(marktext.text, font, new solidbrush(marktext.textcolor ?? item2.value.linecolor), new rectanglef(pointf.x - 100f, pointf.y + (float)marktext.marktextoffect, 200f, font.height + 2), format_center); 1559 break; 1560 } 1561 } 1562 } 1563 } 1564 } 1565 } 1566 foreach (curveitem value2 in data_list.values) 1567 { 1568 if (value2.visible && value2.linerendervisiable) 1569 { 1570 float[] data2 = value2.data; 1571 if (data2 != null && data2.length > 1) 1572 { 1573 float num11 = (float)(width - leftright * 2) * 1f / (float)(value_strechdatacountmax - 1); 1574 pointf[] array4 = new pointf[value2.data.length]; 1575 for (int num12 = 0; num12 < value2.data.length; num12++) 1576 { 1577 array4[num12].x = (float)leftright + (float)num12 * num11; 1578 array4[num12].y = controlhelper.computepaintlocationy(value2.isleftframe ? value_max_left : value_max_right, value2.isleftframe ? value_min_left : value_min_right, height - updowm - updowm, value2.data[num12]) + (float)updowm; 1579 if (!string.isnullorempty(value2.marktext[num12])) 1580 { 1581 using (brush brush = new solidbrush(value2.linecolor)) 1582 { 1583 graphics.fillellipse(brush, new rectanglef(array4[num12].x - 3f, array4[num12].y - 3f, 6f, 6f)); 1584 switch (marktext.calculatedirectionfromdataindex(value2.data, num12)) 1585 { 1586 case marktextpositionstyle.left: 1587 graphics.drawstring(value2.marktext[num12], font, brush, new rectanglef(array4[num12].x - 100f, array4[num12].y - (float)font.height, 100 - marktext.marktextoffect, font.height * 2), format_right); 1588 break; 1589 case marktextpositionstyle.up: 1590 graphics.drawstring(value2.marktext[num12], font, brush, new rectanglef(array4[num12].x - 100f, array4[num12].y - (float)font.height - (float)marktext.marktextoffect, 200f, font.height + 2), format_center); 1591 break; 1592 case marktextpositionstyle.right: 1593 graphics.drawstring(value2.marktext[num12], font, brush, new rectanglef(array4[num12].x + (float)marktext.marktextoffect, array4[num12].y - (float)font.height, 100f, font.height * 2), format_left); 1594 break; 1595 case marktextpositionstyle.down: 1596 graphics.drawstring(value2.marktext[num12], font, brush, new rectanglef(array4[num12].x - 100f, array4[num12].y + (float)marktext.marktextoffect, 200f, font.height + 2), format_center); 1597 break; 1598 } 1599 } 1600 } 1601 } 1602 using (pen pen2 = new pen(value2.linecolor, value2.linethickness)) 1603 { 1604 if (value2.issmoothcurve) 1605 { 1606 graphics.drawcurve(pen2, array4); 1607 } 1608 else 1609 { 1610 graphics.drawlines(pen2, array4); 1611 } 1612 } 1613 } 1614 } 1615 } 1616 } 1617 else 1618 { 1619 foreach (marktext marktext2 in marktexts) 1620 { 1621 foreach (keyvaluepair<string, curveitem> item3 in data_list) 1622 { 1623 if (item3.value.visible && item3.value.linerendervisiable && !(item3.key != marktext2.curvekey)) 1624 { 1625 float[] data3 = item3.value.data; 1626 if (data3 != null && data3.length > 1 && marktext2.index >= 0 && marktext2.index < item3.value.data.length) 1627 { 1628 pointf pointf2 = new pointf(leftright + marktext2.index, controlhelper.computepaintlocationy(item3.value.isleftframe ? value_max_left : value_max_right, item3.value.isleftframe ? value_min_left : value_min_right, height - updowm - updowm, item3.value.data[marktext2.index]) + (float)updowm); 1629 graphics.fillellipse(new solidbrush(marktext2.textcolor ?? item3.value.linecolor), new rectanglef(pointf2.x - 3f, pointf2.y - 3f, 6f, 6f)); 1630 switch ((marktext2.positionstyle == marktextpositionstyle.auto) ? marktext.calculatedirectionfromdataindex(item3.value.data, marktext2.index) : marktext2.positionstyle) 1631 { 1632 case marktextpositionstyle.left: 1633 graphics.drawstring(marktext2.text, font, new solidbrush(marktext2.textcolor ?? item3.value.linecolor), new rectanglef(pointf2.x - 100f, pointf2.y - (float)font.height, 100 - marktext.marktextoffect, font.height * 2), format_right); 1634 break; 1635 case marktextpositionstyle.up: 1636 graphics.drawstring(marktext2.text, font, new solidbrush(marktext2.textcolor ?? item3.value.linecolor), new rectanglef(pointf2.x - 100f, pointf2.y - (float)font.height - (float)marktext.marktextoffect, 200f, font.height + 2), format_center); 1637 break; 1638 case marktextpositionstyle.right: 1639 graphics.drawstring(marktext2.text, font, new solidbrush(marktext2.textcolor ?? item3.value.linecolor), new rectanglef(pointf2.x + (float)marktext.marktextoffect, pointf2.y - (float)font.height, 100f, font.height * 2), format_left); 1640 break; 1641 case marktextpositionstyle.down: 1642 graphics.drawstring(marktext2.text, font, new solidbrush(marktext2.textcolor ?? item3.value.linecolor), new rectanglef(pointf2.x - 100f, pointf2.y + (float)marktext.marktextoffect, 200f, font.height + 2), format_center); 1643 break; 1644 } 1645 } 1646 } 1647 } 1648 } 1649 foreach (curveitem value3 in data_list.values) 1650 { 1651 if (value3.visible && value3.linerendervisiable) 1652 { 1653 float[] data4 = value3.data; 1654 if (data4 != null && data4.length > 1) 1655 { 1656 int num13 = width - 2 * leftright + 1; 1657 pointf[] array5; 1658 if (value3.data.length <= num13) 1659 { 1660 array5 = new pointf[value3.data.length]; 1661 for (int num14 = 0; num14 < value3.data.length; num14++) 1662 { 1663 array5[num14].x = leftright + num14; 1664 array5[num14].y = controlhelper.computepaintlocationy(value3.isleftframe ? value_max_left : value_max_right, value3.isleftframe ? value_min_left : value_min_right, height - updowm - updowm, value3.data[num14]) + (float)updowm; 1665 drawmarkpoint(graphics, value3.marktext[num14], array5[num14], value3.linecolor, marktext.calculatedirectionfromdataindex(value3.data, num14)); 1666 } 1667 } 1668 else 1669 { 1670 array5 = new pointf[num13]; 1671 for (int num15 = 0; num15 < array5.length; num15++) 1672 { 1673 int num16 = num15 + value3.data.length - num13; 1674 array5[num15].x = leftright + num15; 1675 array5[num15].y = controlhelper.computepaintlocationy(value3.isleftframe ? value_max_left : value_max_right, value3.isleftframe ? value_min_left : value_min_right, height - updowm - updowm, value3.data[num16]) + (float)updowm; 1676 drawmarkpoint(graphics, value3.marktext[num16], array5[num15], value3.linecolor, marktext.calculatedirectionfromdataindex(value3.data, num16)); 1677 } 1678 } 1679 using (pen pen3 = new pen(value3.linecolor, value3.linethickness)) 1680 { 1681 if (value3.issmoothcurve) 1682 { 1683 graphics.drawcurve(pen3, array5); 1684 } 1685 else 1686 { 1687 graphics.drawlines(pen3, array5); 1688 } 1689 } 1690 } 1691 } 1692 } 1693 } 1694 base.onpaint(e); 1695 } 1696 catch (exception exc) 1697 { 1698 e.graphics.drawstring(exc.message, this.font, brushes.black, 10, 10); 1699 } 1700 } 1701 1702 /// <summary> 1703 /// draws the mark point. 1704 /// </summary> 1705 /// <param name="g">the g.</param> 1706 /// <param name="marktext">the mark text.</param> 1707 /// <param name="center">the center.</param> 1708 /// <param name="color">the color.</param> 1709 /// <param name="marktextposition">the mark text position.</param> 1710 private void drawmarkpoint(graphics g, string marktext, pointf center, color color, marktextpositionstyle marktextposition) 1711 { 1712 if (!string.isnullorempty(marktext)) 1713 { 1714 using (brush brush = new solidbrush(color)) 1715 { 1716 drawmarkpoint(g, marktext, center, brush, marktextposition); 1717 } 1718 } 1719 } 1720 1721 /// <summary> 1722 /// draws the mark point. 1723 /// </summary> 1724 /// <param name="g">the g.</param> 1725 /// <param name="marktext">the mark text.</param> 1726 /// <param name="center">the center.</param> 1727 /// <param name="brush">the brush.</param> 1728 /// <param name="marktextposition">the mark text position.</param> 1729 private void drawmarkpoint(graphics g, string marktext, pointf center, brush brush, marktextpositionstyle marktextposition) 1730 { 1731 if (!string.isnullorempty(marktext)) 1732 { 1733 g.fillellipse(brush, new rectanglef(center.x - 3f, center.y - 3f, 6f, 6f)); 1734 switch (marktextposition) 1735 { 1736 case marktextpositionstyle.left: 1737 g.drawstring(marktext, font, brush, new rectanglef(center.x - 100f, center.y - (float)font.height, 100 - marktext.marktextoffect, font.height * 2), format_right); 1738 break; 1739 case marktextpositionstyle.up: 1740 g.drawstring(marktext, font, brush, new rectanglef(center.x - 100f, center.y - (float)font.height - (float)marktext.marktextoffect, 200f, font.height + 2), format_center); 1741 break; 1742 case marktextpositionstyle.right: 1743 g.drawstring(marktext, font, brush, new rectanglef(center.x + (float)marktext.marktextoffect, center.y - (float)font.height, 100f, font.height * 2), format_left); 1744 break; 1745 case marktextpositionstyle.down: 1746 g.drawstring(marktext, font, brush, new rectanglef(center.x - 100f, center.y + (float)marktext.marktextoffect, 200f, font.height + 2), format_center); 1747 break; 1748 } 1749 } 1750 } 1751 1752 /// <summary> 1753 /// determines whether [is need paint dash] [the specified paint value]. 1754 /// </summary> 1755 /// <param name="paintvalue">the paint value.</param> 1756 /// <returns><c>true</c> if [is need paint dash] [the specified paint value]; otherwise, <c>false</c>.</returns> 1757 private bool isneedpaintdash(float paintvalue) 1758 { 1759 for (int i = 0; i < auxiliary_lines.count; i++) 1760 { 1761 if (math.abs(auxiliary_lines[i].paintvalue - paintvalue) < (float)font_size9.height) 1762 { 1763 return false; 1764 } 1765 } 1766 return true; 1767 } 1768 1769 /// <summary> 1770 /// calculates the data count by offect. 1771 /// </summary> 1772 /// <param name="offect">the offect.</param> 1773 /// <returns>system.int32.</returns> 1774 private int calculatedatacountbyoffect(float offect) 1775 { 1776 if (value_intervalabscissatext > 0) 1777 { 1778 return value_intervalabscissatext; 1779 } 1780 if (offect > 40f) 1781 { 1782 return 1; 1783 } 1784 offect = 40f / offect; 1785 return (int)math.ceiling(offect); 1786 } 1787 1788 /// <summary> 1789 /// releases unmanaged and - optionally - managed resources. 1790 /// </summary> 1791 /// <param name="disposing">为 true 则释放托管资源和非托管资源;为 false 则仅释放非托管资源。</param> 1792 protected override void dispose(bool disposing) 1793 { 1794 if (disposing && components != null) 1795 { 1796 components.dispose(); 1797 } 1798 base.dispose(disposing); 1799 } 1800 1801 /// <summary> 1802 /// initializes the component. 1803 /// </summary> 1804 private void initializecomponent() 1805 { 1806 suspendlayout(); 1807 base.autoscalemode = system.windows.forms.autoscalemode.none; 1808 backcolor = system.drawing.color.transparent; 1809 base.name = "hslcurve"; 1810 base.size = new system.drawing.size(417, 205); 1811 resumelayout(false); 1812 } 1813 } 1814 }
最后的话
如果你喜欢的话,请到 点个星星吧
上一篇: 一篇文章告诉你所不知道的椰子油的吃法
下一篇: Thinkphp中的curd应用实用要点