MyDraw.cs 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Drawing.Drawing2D;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Windows.Forms;
  9. namespace OTSIncAReportGraph
  10. {
  11. #region 基类,抽像类
  12. /// <summary>
  13. /// 绘制的基本类,下面的画布,多边形,线都要从这里派生
  14. /// </summary>
  15. public abstract class BaseObject : ICloneable
  16. {
  17. //自动生成的ID
  18. public abstract string ID { get; set; }
  19. //画布的坐标
  20. public abstract RectangleF Rect { get; set; }
  21. //OTS的坐标
  22. public abstract PointF OTSPointF { get; set; }
  23. //画布是否被选择
  24. public abstract bool IsSelect { get; set; }
  25. //画布是否被拖动
  26. public abstract bool IsDragging { get; set; }
  27. //画布被拖动到的位置
  28. public abstract PointF DraggingPoint { get; set; }
  29. //线的颜色
  30. public abstract Color Color { get; set; }
  31. //画布的背景色
  32. public abstract Color BackColor { get; set; }
  33. //绘制函数
  34. public abstract void OnPaint(PaintEventArgs e);
  35. //多边形路径
  36. public abstract GraphicsPath GPath { get; set; }
  37. //克隆
  38. public virtual object Clone()
  39. {
  40. return null;
  41. }
  42. }
  43. #endregion
  44. #region 历史操作记录类
  45. ///历史操作记录类,记录颗粒被操作的记录
  46. public class HistoryApolygon
  47. {
  48. //自增长,操作id,增长在程序中自己写代码控制
  49. private int m_id;
  50. //所操作的颗粒的id
  51. private string m_apolygonid;
  52. //操作类型
  53. private ParticleOperator m_operator;
  54. //原先的操作状态类型
  55. private ParticleOperator m_oldoperator;
  56. /// <summary>
  57. /// 操作类ID
  58. /// </summary>
  59. public int ID
  60. {
  61. get { return m_id; }
  62. set { m_id = value; }
  63. }
  64. /// <summary>
  65. /// 颗粒类ID
  66. /// </summary>
  67. public string APolygonID
  68. {
  69. get { return m_apolygonid; }
  70. set { m_apolygonid = value; }
  71. }
  72. /// <summary>
  73. /// 操作类型
  74. /// </summary>
  75. public ParticleOperator Operator
  76. {
  77. get { return m_operator; }
  78. set { m_operator = value; }
  79. }
  80. /// <summary>
  81. /// 原先的操作类型
  82. /// </summary>
  83. public ParticleOperator OldOperator
  84. {
  85. get { return m_oldoperator; }
  86. set { m_oldoperator = value; }
  87. }
  88. }
  89. #endregion
  90. #region 颗粒分布图,排序图统一使用类
  91. /// <summary>
  92. /// 颗粒排序,能对颗粒进行分栏的类
  93. /// </summary>
  94. public class SortParticleDistribution : ICloneable
  95. {
  96. private List<DParticle> list_dparticle = new List<DParticle>();
  97. private RectangleF m_rectf;
  98. private string m_showstr = "";
  99. private float m_size_min = 0;
  100. private float m_size_max = 0;
  101. public SortParticleDistribution()
  102. { }
  103. //构造函数
  104. SortParticleDistribution(List<DParticle> inlist_dparticle, SortParticleDistribution in_spd)
  105. {
  106. m_rectf = in_spd.m_rectf;
  107. m_showstr = in_spd.m_showstr;
  108. m_size_min = in_spd.m_size_min;
  109. m_size_max = in_spd.m_size_max;
  110. foreach (DParticle e in inlist_dparticle)
  111. {
  112. list_dparticle.Add(e.Clone() as DParticle);
  113. }
  114. }
  115. /// <summary>
  116. /// 克隆方法
  117. /// </summary>
  118. /// <returns></returns>
  119. public object Clone()
  120. {
  121. return new SortParticleDistribution(this.list_dparticle, this);
  122. }
  123. /// <summary>
  124. /// 多边形图数组
  125. /// </summary>
  126. public List<DParticle> List_DParticle
  127. {
  128. get { return list_dparticle; }
  129. set { list_dparticle = value; }
  130. }
  131. /// <summary>
  132. /// 整个分类Grid的位置
  133. /// </summary>
  134. public RectangleF RectF
  135. {
  136. get { return m_rectf; }
  137. set { m_rectf = value; }
  138. }
  139. /// <summary>
  140. /// 该分类Grid显示的文字
  141. /// </summary>
  142. public string ShowStr
  143. {
  144. get { return m_showstr; }
  145. set { m_showstr = value; }
  146. }
  147. /// <summary>
  148. /// 该Grid保存多边形范围的最小值
  149. /// </summary>
  150. public float Size_Min
  151. {
  152. get { return m_size_min; }
  153. set { m_size_min = value; }
  154. }
  155. /// <summary>
  156. /// 该Grid保存多边形范围的最大值
  157. /// </summary>
  158. public float Size_Max
  159. {
  160. get { return m_size_max; }
  161. set { m_size_max = value; }
  162. }
  163. /// <summary>
  164. /// 获取多边形Grid内,所有多边形所占有的行数,用于其它计算使用
  165. /// </summary>
  166. /// <returns></returns>
  167. public int GetDParticleRowNumber()
  168. {
  169. int RowsNumber = 0;
  170. //首先获取所有多边形的宽度之和
  171. float f_all_dparticle_widthsum = 0;
  172. foreach (DParticle dp in this.list_dparticle)
  173. {
  174. f_all_dparticle_widthsum = f_all_dparticle_widthsum + dp.Rect.Width;
  175. }
  176. //然后除以自身的宽度+1,就是所有的行数了
  177. float f_rowsnumber = f_all_dparticle_widthsum / this.RectF.Width + 1;
  178. RowsNumber = Convert.ToInt32(f_rowsnumber);
  179. return RowsNumber;
  180. }
  181. /// <summary>
  182. /// 获取多边形分栏,分栏的高度
  183. /// </summary>
  184. /// <returns></returns>
  185. public float GetSortGridHeight()
  186. {
  187. float i_SortGridHeight = 0;
  188. int i_RowNumber = GetDParticleRowNumber();
  189. //再获取所有的颗粒中,最长的
  190. float i_heightmax = 0;
  191. float i_ls_height = 0;
  192. foreach (DParticle dp in this.list_dparticle)
  193. {
  194. float ls_y = 0;//用来判断y坐标是否有变化,好用来计算长度
  195. foreach (DSegment ds in dp.DSegments)
  196. {
  197. if (ds.Rect.Y != ls_y)
  198. {
  199. //i_ls_height++;
  200. ls_y = ds.Rect.Y;
  201. //如果需要考虑笔宽缩放的话,目前这样写,效果还没有出现问题
  202. i_ls_height = i_ls_height + ds.Rect.Height * ds.PenWidthAndHeight;
  203. }
  204. if (i_heightmax < i_ls_height)
  205. {
  206. i_heightmax = i_ls_height;
  207. }
  208. }
  209. i_ls_height = 0;
  210. }
  211. //用最高的颗粒*行数,来计算整个grid的高度
  212. i_SortGridHeight = i_RowNumber * (i_heightmax + 10) + 20;//因为每行都额外增加了10点的高度
  213. //应该当grid最小大于=50
  214. if (i_SortGridHeight < 50)
  215. {
  216. i_SortGridHeight = 50;
  217. }
  218. return i_SortGridHeight;
  219. }
  220. /// <summary>
  221. /// 根据传入的2个多边形list,从大到小进行排序,两个多边形list通过guid保持一致
  222. /// 主要用于计算list与old_list能进行相同顺序的排序
  223. /// </summary>
  224. /// <param name="list_dparticle"></param>
  225. /// <param name="old_list_dparticle"></param>
  226. public void SortDParticleBySizeFromBigToSmall(List<DParticle> list_dparticle, List<DParticle> old_list_dparticle)
  227. {
  228. //首先分别将两个多边形list保存起来
  229. List<DParticle> list_dp1 = new List<DParticle>();
  230. List<DParticle> list_dp2 = new List<DParticle>();
  231. foreach (DParticle ls_dp in list_dparticle)
  232. {
  233. DParticle dp1 = ls_dp.Clone() as DParticle;
  234. list_dp1.Add(dp1);
  235. }
  236. foreach (DParticle ls_dp in old_list_dparticle)
  237. {
  238. DParticle dp2 = ls_dp.Clone() as DParticle;
  239. list_dp2.Add(dp2);
  240. }
  241. //清除原先的两个多边形list
  242. list_dparticle.Clear();
  243. old_list_dparticle.Clear();
  244. //嵌套2次循环
  245. int icount = list_dp1.Count();
  246. for (int i = 0; i < icount; i++)
  247. {
  248. //找出最大的
  249. float f_max_size = 0;
  250. string str_jlguid = "";
  251. DParticle ls_dp = new DParticle();
  252. foreach (DParticle ls_del_dp in list_dp1)
  253. {
  254. //通过包含的线,获取多边形的尺寸大小
  255. ls_del_dp.FSize = ls_del_dp.GetSizeFormSegmentsAllWidth();
  256. if (f_max_size < ls_del_dp.FSize)
  257. {
  258. f_max_size = ls_del_dp.FSize;
  259. str_jlguid = ls_del_dp.ID;
  260. ls_dp = ls_del_dp;
  261. }
  262. }
  263. //然后分别将两个该guid的多边形从list1,2中删除
  264. list_dp1.Remove(ls_dp);
  265. //再分别插入到原先的list,和old_list中
  266. ls_dp.Rect = ls_dp.GetRectFromDSegment();
  267. list_dparticle.Add(ls_dp);
  268. }
  269. //换种方法,按Guid将list2中对应的再添加到old_list中
  270. foreach (DParticle ls_dp in list_dparticle)
  271. {
  272. foreach (DParticle ls_dp2 in list_dp2)
  273. {
  274. if (ls_dp2.ID == ls_dp.ID)
  275. {
  276. ls_dp2.Rect = ls_dp2.GetRectFromDSegment();
  277. old_list_dparticle.Add(ls_dp2);
  278. }
  279. }
  280. }
  281. }
  282. /// <summary>
  283. /// 根据传入的2个多边形list,从小到大进行排序,两个多边形list通过guid保持一致
  284. /// 主要用于计算list与old_list能进行相同顺序的排序
  285. /// </summary>
  286. /// <param name="list_dparticle"></param>
  287. /// <param name="old_list_dparticle"></param>
  288. public void SortDParticlesBySizeFromSmallToBig(List<DParticle> list_dparticle, List<DParticle> old_list_dparticles)
  289. {
  290. //首先分别将两个多边形list保存起来
  291. List<DParticle> list_dp1 = new List<DParticle>();
  292. List<DParticle> list_dp2 = new List<DParticle>();
  293. foreach (DParticle ls_dp in list_dparticle)
  294. {
  295. DParticle dp1 = ls_dp.Clone() as DParticle;
  296. list_dp1.Add(dp1);
  297. }
  298. foreach (DParticle ls_dp in old_list_dparticles)
  299. {
  300. DParticle dp2 = ls_dp.Clone() as DParticle;
  301. list_dp2.Add(dp2);
  302. }
  303. //清除原先的两个多边形list
  304. list_dparticle.Clear();
  305. old_list_dparticles.Clear();
  306. //嵌套2次循环
  307. int icount = list_dparticle.Count();
  308. for (int i = 0; i < icount; i++)
  309. {
  310. //找出最小的
  311. float f_min_size = 10000000;
  312. string str_jlguid = "";
  313. DParticle ls_dp = new DParticle();
  314. foreach (DParticle ls_del_dp in list_dp1)
  315. {
  316. //通过包含的线,获取多边形的尺寸大小
  317. ls_del_dp.FSize = ls_del_dp.GetSizeFormSegmentsAllWidth();
  318. if (f_min_size > ls_del_dp.FSize)
  319. {
  320. f_min_size = ls_del_dp.FSize;
  321. str_jlguid = ls_del_dp.ID;
  322. ls_dp = ls_del_dp;
  323. }
  324. }
  325. //然后分别将两个该guid的多边形从list1,2中删除
  326. list_dp1.Remove(ls_dp);
  327. //再分别插入到原先的list,和old_list中
  328. list_dparticle.Add(ls_dp);
  329. }
  330. //换种方法,按Guid将list2中对应的再添加到old_list中
  331. foreach (DParticle ls_dp in list_dparticle)
  332. {
  333. foreach (DParticle ls_dp2 in list_dp2)
  334. {
  335. if (ls_dp2.ID == ls_dp.ID)
  336. {
  337. old_list_dparticles.Add(ls_dp2);
  338. }
  339. }
  340. }
  341. }
  342. /// <summary>
  343. /// 颗粒排序方法2
  344. /// </summary>
  345. /// <param name="in_f_zoom_record"></param>
  346. public void SortParticle222(float in_f_zoom_record)
  347. {
  348. float f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record;
  349. float f_ls_y = this.m_rectf.Y + 3 * in_f_zoom_record;
  350. foreach (DParticle dp in this.list_dparticle)
  351. {
  352. dp.Rect = dp.GetRectFromDSegment();
  353. if ((f_ls_x + dp.Rect.Width + 6) > this.m_rectf.Width + this.m_rectf.X)
  354. {
  355. f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record;
  356. f_ls_y = f_ls_y + this.GetSortGridHeight() / this.GetDParticleRowNumber() - 5;
  357. }
  358. float f_cz_x = f_ls_x - dp.Rect.X;
  359. float f_cz_y = f_ls_y - dp.Rect.Y;
  360. foreach (DSegment ds in dp.DSegments)
  361. {
  362. ds.Rect = new RectangleF(ds.Rect.X + f_cz_x, ds.Rect.Y + f_cz_y, ds.Rect.Width, ds.Rect.Height);
  363. }
  364. f_ls_x = f_ls_x + dp.Rect.Width + 3 * in_f_zoom_record;
  365. dp.Rect = dp.GetRectFromDSegment();
  366. dp.GPath = dp.GetRegionFromDSegments();
  367. dp.SmallRect = dp.GetSmallRectangleFromRect();
  368. }
  369. }
  370. /// <summary>
  371. /// 对已经存入的颗粒信息,按定位好的rect位置,重新给line和各参数,重新进行计算
  372. /// 就是在分栏的Grid中对多边形进行摆放
  373. /// </summary>
  374. public void SortDParticle(float in_f_zoom_record)
  375. {
  376. //设置增长的x,y轴值,+3是跳过边框的位置, 可能有个别情况,会在右侧突出占到边框的位置上
  377. float f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record;
  378. float f_ls_y = this.m_rectf.Y + 3 * in_f_zoom_record;
  379. foreach (DParticle dp in this.list_dparticle)
  380. {
  381. //这里要对不显示的颗粒进行屏蔽,也就是进行不计算位置,不知道会不会有其它的影响
  382. if (dp.Operator !=ParticleOperator.NODISPLAY)
  383. {
  384. //首先确定各多边形的矩形位置
  385. dp.Rect = dp.GetRectFromDSegment();
  386. //判断是否已经达到了x的边缘,是的话,那么y轴进行增长,判断x轴+颗粒的宽度+6的相当于边框宽度的差值补值,大于grid宽度时
  387. //在增长前就判断宽度,防止部份多边形突出到分栏外
  388. if ((f_ls_x + dp.Rect.Width + 6) > this.m_rectf.Width + this.m_rectf.X)
  389. {
  390. //还原x到该分栏Grid的左边框+3的位置,并且将y轴定位到下一高度的y轴位置
  391. f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record;
  392. f_ls_y = f_ls_y + this.GetSortGridHeight() / this.GetDParticleRowNumber() - 5;//在获取高度时,已经+10,所以这里再-5,颗粒近一些
  393. }
  394. //计算出与定位的Grid的差值,然后重新排序线,用分栏Grid-颗粒的外Rect,取到x,y的差值
  395. float f_cz_x = f_ls_x - dp.Rect.X;
  396. float f_cz_y = f_ls_y - dp.Rect.Y;
  397. //获取到差值后,再对该多边形下面的所有线进行调整
  398. foreach (DSegment ds in dp.DSegments)
  399. {
  400. ds.Rect = new RectangleF(ds.Rect.X + f_cz_x, ds.Rect.Y + f_cz_y, ds.Rect.Width, ds.Rect.Height);
  401. }
  402. //定位好该多边形后,对x轴进行增长,为下一个多边形定位好位置
  403. f_ls_x = f_ls_x + dp.Rect.Width + 3 * in_f_zoom_record;
  404. //重新计算sort_ap的
  405. dp.Rect = dp.GetRectFromDSegment();
  406. //通过line获取路径边缘
  407. dp.GPath = dp.GetRegionFromDSegments();
  408. //重新计算小矩形边框
  409. dp.SmallRect = dp.GetSmallRectangleFromRect();
  410. }
  411. }
  412. }
  413. }
  414. /// <summary>
  415. /// 包含DParticle类的field类,目前只用于绘制背景色,按理说应该有更多的作用,比如做多线程分式运算
  416. /// </summary>
  417. public class DField:BaseObject
  418. {
  419. string m_id;
  420. string m_tagid;
  421. string m_fieldid;
  422. bool m_IsDragging;
  423. Color m_backcolor;
  424. List<DParticle> m_list_dparticle;
  425. RectangleF m_ots_rect; //按底层设计结构,底层返回的物理坐标位置及大小,OTS坐标大小
  426. RectangleF m_pix_rect; //与底层返回物理坐标及位置大小对应转换成,pixel像素分率下的坐标位置大小
  427. RectangleF m_show_rect;//最后换算到在显示器上显示的坐标位置大小
  428. RectangleF m_current_rect;//当前field在显示器上显示的坐标位置大小
  429. PointF m_dragingpoint;//鼠标拖动的位置
  430. private string m_GBContent;
  431. private PointF m_OTSPointF;
  432. private bool m_IsSelect;
  433. private Color m_color;
  434. private GraphicsPath m_GPath;
  435. /// <summary>
  436. /// 构造函数
  437. /// </summary>
  438. public DField()
  439. {
  440. m_id = System.Guid.NewGuid().ToString();
  441. }
  442. public DField(List<DParticle> in_list_dparticle)
  443. {
  444. m_list_dparticle = in_list_dparticle;
  445. }
  446. /// <summary>
  447. /// ID
  448. /// </summary>
  449. //public string ID
  450. //{
  451. // get { return m_id; }
  452. // set { m_id = value; }
  453. //}
  454. public override string ID { get => m_id; set => m_id=value; }
  455. /// <summary>
  456. /// 记录与底层对应的TagID
  457. /// </summary>
  458. public string TagID
  459. {
  460. get { return m_tagid; }
  461. set { m_tagid = value; }
  462. }
  463. /// <summary>
  464. /// 是否被拖动标识
  465. /// </summary>
  466. //public bool IsDragging
  467. //{
  468. // get { return m_IsDragging; }
  469. // set { m_IsDragging = value; }
  470. //}
  471. public override bool IsDragging { get => m_IsDragging; set => m_IsDragging=value; }
  472. /// <summary>
  473. /// 被拖动到的位置坐标
  474. /// </summary>
  475. //public PointF DraggingPoint
  476. //{
  477. // get { return m_dragingpoint; }
  478. // set { m_dragingpoint = value; }
  479. //}
  480. public override PointF DraggingPoint { get => m_dragingpoint; set => m_dragingpoint=value; }
  481. /// <summary>
  482. /// 与底层对应的ID,这里叫成FieldID
  483. /// </summary>
  484. public string FieldID
  485. {
  486. get { return m_fieldid; }
  487. set { m_fieldid = value; }
  488. }
  489. public override Color BackColor { get => m_backcolor; set => m_backcolor=value; }
  490. /// <summary>
  491. /// 包含的Particle列表
  492. /// </summary>
  493. public List<DParticle> List_DParticle
  494. {
  495. get { return m_list_dparticle; }
  496. set { m_list_dparticle = value; }
  497. }
  498. /// <summary>
  499. /// 该Field的OTS坐标及大小
  500. /// </summary>
  501. public RectangleF OTS_RECT
  502. {
  503. get { return m_ots_rect; }
  504. set { m_ots_rect = value; }
  505. }
  506. /// <summary>
  507. /// 该Field物理坐标大小转换出,对应的像素坐标及大小
  508. /// </summary>
  509. public RectangleF Pix_Rect
  510. {
  511. get { return m_pix_rect; }
  512. set { m_pix_rect = value; }
  513. }
  514. /// <summary>
  515. /// 该Field最后在屏幕上显示的坐标及大小
  516. /// </summary>
  517. public RectangleF Show_Rect
  518. {
  519. get { return m_show_rect; }
  520. set { m_show_rect = value; }
  521. }
  522. /// <summary>
  523. /// Field当前在屏幕上显示的坐标及大小
  524. /// </summary>
  525. public RectangleF Current_Rect
  526. {
  527. get { return m_current_rect; }
  528. set { m_current_rect = value; }
  529. }
  530. public override RectangleF Rect { get => m_ots_rect; set => m_ots_rect=value; }
  531. public override PointF OTSPointF { get => m_OTSPointF; set => m_OTSPointF=value; }
  532. public override bool IsSelect { get => m_IsSelect; set => m_IsSelect=value; }
  533. public override Color Color { get => m_color; set => m_color=value; }
  534. public override GraphicsPath GPath { get => m_GPath; set =>m_GPath=value; }
  535. public override void OnPaint(PaintEventArgs e)
  536. {
  537. throw new NotImplementedException();
  538. }
  539. }
  540. /// <summary>
  541. /// Particle对象上操作状态的枚举,显示,不显示,已删除,已选择
  542. /// </summary>
  543. public enum ParticleOperator
  544. {
  545. DISPLAY = 0,
  546. NODISPLAY = 1,
  547. DELETED = 2,
  548. SELECTED =3,
  549. }
  550. /// <summary>
  551. /// Particle对象上操作xray的枚举状态,显示xray数据,不显示
  552. /// </summary>
  553. public enum ParticleOperatorShowXray
  554. {
  555. SELECTANDDISPLAYXRAY = 0,
  556. NODISPLAY = 1,
  557. }
  558. /// <summary>
  559. /// Segment对象绘制的枚举,以点绘制,还是以线绘制
  560. /// </summary>
  561. public enum SegmentShowMode
  562. {
  563. DRAWPOINT = 0,
  564. DRAWLINE = 1,
  565. }
  566. /// <summary>
  567. /// 颗粒类
  568. /// </summary>
  569. public class DParticle : BaseObject, ICloneable, IComparable<DParticle>
  570. {
  571. private string m_id;
  572. private RectangleF m_rect;
  573. private PointF m_OTSPointF;
  574. private RectangleF m_small_rect;
  575. private bool m_isselected_smallrect;
  576. private bool m_showsmallx;
  577. private bool m_isselect;
  578. private ParticleOperator m_operator = ParticleOperator.DISPLAY;//显示,不显示,删除,选择,默认应为(不显示)
  579. private ParticleOperatorShowXray m_operator_showxray = ParticleOperatorShowXray.NODISPLAY;//选定显示XRAY,不显示XRAY,默认应为(不显示XRAY)
  580. private bool m_isdragging;
  581. private PointF m_dragingpoint;
  582. private Color m_color;
  583. private Color m_backcolor;
  584. private GraphicsPath m_gpath;
  585. private List<DSegment> m_listdsegment = new List<DSegment>();
  586. private bool m_IsMouseMove;
  587. private float m_zoom_displaymultiplier = 1;
  588. private bool m_zoom_display;
  589. private string m_sort_type = "从大到小";
  590. private float m_f_size = 0;
  591. private string m_str_lj = "颗粒粒级";
  592. private string m_str_klzl = "颗粒种类";
  593. private string m_str_klfl = "颗粒分类";
  594. private int m_clrfieldid = 0;
  595. private int m_clrtagid = 0;
  596. private int m_stdtypeid = 0;//表示这个颗粒分析出来后的类型
  597. //TypeId
  598. public int TypeId { set; get; }
  599. //TypeName
  600. public string TypeName { set; get; }
  601. //XRayId
  602. public int XRayId { set; get; }
  603. public int SEMPosX { set; get; }
  604. public int SEMPosY { set; get; }
  605. //国标内容
  606. private string m_GBContent = "";
  607. public DParticle()
  608. {
  609. m_id = System.Guid.NewGuid().ToString();
  610. }
  611. public DParticle(List<DSegment> in_list_segment, DParticle in_particle)
  612. {
  613. // m_id = System.Guid.NewGuid().ToString();
  614. m_id = in_particle.m_id;
  615. m_zoom_display = in_particle.m_zoom_display;
  616. m_zoom_displaymultiplier = in_particle.m_zoom_displaymultiplier;
  617. m_clrfieldid = in_particle.m_clrfieldid;
  618. m_clrtagid = in_particle.m_clrtagid;
  619. m_operator = in_particle.m_operator;
  620. m_operator_showxray = in_particle.m_operator_showxray;
  621. m_stdtypeid = in_particle.m_stdtypeid;
  622. SEMPosX = in_particle.SEMPosX;
  623. SEMPosY = in_particle.SEMPosY;
  624. foreach (DSegment e in in_list_segment)
  625. {
  626. m_listdsegment.Add(e.Clone() as DSegment);
  627. }
  628. }
  629. /// <summary>
  630. /// [目前也不使用该方法了,因为该方法每次排序都有不同的结果]多边形排序,按传入的sort_type的排序类型行排序,但需要两个list做一致性排序
  631. /// </summary>
  632. /// <param name="in_ap"></param>
  633. /// <returns></returns>
  634. public int CompareTo(DParticle in_particle)
  635. {
  636. int r_b = 0;//排序返回值
  637. switch (m_sort_type)
  638. {
  639. case "从大到小":
  640. r_b = in_particle.m_f_size.CompareTo(this.m_f_size);
  641. break;
  642. case "从小到大":
  643. //与上面的从大到小正好相反即可
  644. r_b = in_particle.m_f_size.CompareTo(this.m_f_size);
  645. if (r_b == 1)
  646. r_b = -1;
  647. else
  648. r_b = 1;
  649. break;
  650. default:
  651. break;
  652. }
  653. return r_b;
  654. }
  655. /// <summary>
  656. /// 克隆方法
  657. /// </summary>
  658. /// <returns></returns>
  659. public override object Clone()
  660. {
  661. return new DParticle(this.m_listdsegment, this);
  662. }
  663. /// <summary>
  664. /// ID
  665. /// </summary>
  666. public override string ID
  667. {
  668. get { return m_id; }
  669. set { m_id = value; }
  670. }
  671. /// <summary>
  672. /// 颗粒的外边框大小
  673. /// </summary>
  674. public override RectangleF Rect
  675. {
  676. get { return m_rect; }
  677. set { m_rect = value; }
  678. }
  679. /// <summary>
  680. /// OTSPointF
  681. /// </summary>
  682. public override PointF OTSPointF
  683. {
  684. get { return m_OTSPointF; }
  685. set { m_OTSPointF = value; }
  686. }
  687. /// <summary>
  688. /// 颗粒里+号位置的外边框大小
  689. /// </summary>
  690. public RectangleF SmallRect
  691. {
  692. get { return m_small_rect; }
  693. set { m_small_rect = value; }
  694. }
  695. /// <summary>
  696. /// 颗粒是否被选择
  697. /// </summary>
  698. public override bool IsSelect
  699. {
  700. get { return m_isselect; }
  701. set { m_isselect = value; }
  702. }
  703. /// <summary>
  704. /// 该颗粒是否被设置成,选中状态
  705. /// </summary>
  706. public ParticleOperator Operator
  707. {
  708. get { return m_operator; }
  709. set { m_operator = value; }
  710. }
  711. /// <summary>
  712. /// 是否对该颗粒选定显示X-Ray能谱图
  713. /// </summary>
  714. public ParticleOperatorShowXray Operator_ShowXRay
  715. {
  716. get { return m_operator_showxray; }
  717. set { m_operator_showxray = value; }
  718. }
  719. /// <summary>
  720. /// 鼠标是否在该矩形上
  721. /// </summary>
  722. public bool IsMouseMove
  723. {
  724. get { return m_IsMouseMove; }
  725. set { m_IsMouseMove = value; }
  726. }
  727. /// <summary>
  728. /// 是否显示x号
  729. /// </summary>
  730. public bool IsShowSmallX
  731. {
  732. get { return m_showsmallx; }
  733. set { m_showsmallx = value; }
  734. }
  735. /// <summary>
  736. /// 颗粒的x-ray的点,是否被选择上了
  737. /// </summary>
  738. public bool IsSelectedSmallRect
  739. {
  740. get { return m_isselected_smallrect; }
  741. set { m_isselected_smallrect = value; }
  742. }
  743. /// <summary>
  744. /// 是否在被拖动
  745. /// </summary>
  746. public override bool IsDragging
  747. {
  748. get { return m_isdragging; }
  749. set { m_isdragging = value; }
  750. }
  751. /// <summary>
  752. /// 被拖动到的位置坐标
  753. /// </summary>
  754. public override PointF DraggingPoint
  755. {
  756. get { return m_dragingpoint; }
  757. set { m_dragingpoint = value; }
  758. }
  759. /// <summary>
  760. /// 线的颜色
  761. /// </summary>
  762. public override Color Color
  763. {
  764. get { return m_color; }
  765. set { m_color = value; }
  766. }
  767. /// <summary>
  768. /// 背景色
  769. /// </summary>
  770. public override Color BackColor
  771. {
  772. get { return m_backcolor; }
  773. set { m_backcolor = value; }
  774. }
  775. /// <summary>
  776. /// 多边形的图形路径边缘
  777. /// </summary>
  778. public override GraphicsPath GPath
  779. {
  780. get { return m_gpath; }
  781. set { m_gpath = value; }
  782. }
  783. /// <summary>
  784. /// 里面包含的多个线的集合
  785. /// </summary>
  786. public List<DSegment> DSegments
  787. {
  788. get { return m_listdsegment; }
  789. set { m_listdsegment = value; }
  790. }
  791. /// <summary>
  792. /// 控制多边形在进行缩放到多少倍时进行显示
  793. /// </summary>
  794. public float Zoom_DisPlayMultiplier
  795. {
  796. get { return m_zoom_displaymultiplier; }
  797. set { m_zoom_displaymultiplier = value; }
  798. }
  799. /// <summary>
  800. /// 临时的变量,控制进行缩放时,是显示+号,还是显示多边形
  801. /// </summary>
  802. public bool Zoom_DisPlay
  803. {
  804. get { return m_zoom_display; }
  805. set { m_zoom_display = value; }
  806. }
  807. /// <summary>
  808. /// 设置排序的类型
  809. /// </summary>
  810. public string SortType
  811. {
  812. get { return m_sort_type; }
  813. set { m_sort_type = value; }
  814. }
  815. /// <summary>
  816. /// 设置该多边形的尺寸大小
  817. /// </summary>
  818. public float FSize
  819. {
  820. get { return m_f_size; }
  821. set { m_f_size = value; }
  822. }
  823. /// <summary>
  824. /// 设置粒级
  825. /// </summary>
  826. public string ParticleLJ
  827. {
  828. get { return m_str_lj; }
  829. set { m_str_lj = value; }
  830. }
  831. /// <summary>
  832. /// 设置种类
  833. /// </summary>
  834. public string ParticleZL
  835. {
  836. get { return m_str_klzl; }
  837. set { m_str_klzl = value; }
  838. }
  839. /// <summary>
  840. /// 设置分类
  841. /// </summary>
  842. public string ParticleFL
  843. {
  844. get { return m_str_klfl; }
  845. set { m_str_klfl = value; }
  846. }
  847. /// <summary>
  848. /// 获取或设置该Particle对应底层的FieldID值
  849. /// </summary>
  850. public int CLRFieldID
  851. {
  852. get { return m_clrfieldid; }
  853. set { m_clrfieldid = value; }
  854. }
  855. /// <summary>
  856. /// 获取或设置该Particle对应底层的ParticleID值
  857. /// </summary>
  858. public int CLRTagID
  859. {
  860. get { return m_clrtagid; }
  861. set { m_clrtagid = value; }
  862. }
  863. /// <summary>
  864. /// 获取或设置STD分析物的ID
  865. /// </summary>
  866. public int STDTypeID
  867. {
  868. get { return m_stdtypeid; }
  869. set { m_stdtypeid = value; }
  870. }
  871. /// <summary>
  872. /// 绘制函数
  873. /// </summary>
  874. /// <param name="e"></param>
  875. public override void OnPaint(PaintEventArgs e)
  876. {
  877. Graphics g = e.Graphics;
  878. //绘制鼠标移动到颗粒上时的边框,需要判断当前鼠标在颗粒上,及颗粒的操作为正常显示
  879. if (true == m_IsMouseMove && m_operator == ParticleOperator.DISPLAY)
  880. {
  881. //如果有鼠标在该矩形上,那么进行描边
  882. ControlPaint.DrawBorder(g,
  883. Rectangle.Round(this.Rect),
  884. Color.Lime,
  885. 1,
  886. ButtonBorderStyle.Solid,
  887. Color.Lime,
  888. 1,
  889. ButtonBorderStyle.Solid,
  890. Color.Lime,
  891. 1,
  892. ButtonBorderStyle.Solid,
  893. Color.Lime,
  894. 1,
  895. ButtonBorderStyle.Solid);
  896. }
  897. else
  898. {
  899. //应该是什么都不做就可以了,就刷新掉了
  900. }
  901. if (ParticleOperator.SELECTED == m_operator)
  902. {
  903. //如果説该矩形被选择上了的话,那么也显示边框
  904. ControlPaint.DrawBorder(g,
  905. Rectangle.Round(this.Rect),
  906. Color.Blue,
  907. 1,
  908. ButtonBorderStyle.Solid,
  909. Color.Blue,
  910. 1,
  911. ButtonBorderStyle.Solid,
  912. Color.Blue,
  913. 1,
  914. ButtonBorderStyle.Solid,
  915. Color.Blue,
  916. 1,
  917. ButtonBorderStyle.Solid);
  918. }
  919. if (ParticleOperatorShowXray.SELECTANDDISPLAYXRAY == m_operator_showxray && ParticleOperator.NODISPLAY != m_operator)
  920. {
  921. //当鼠标在该颗粒上进行点击,则对颗粒状态更改为选定状态,用来显示X-ray能谱表
  922. ControlPaint.DrawBorder(g,
  923. Rectangle.Round(this.Rect),
  924. Color.DeepSkyBlue,
  925. 1,
  926. ButtonBorderStyle.Solid,
  927. Color.DeepSkyBlue,
  928. 1,
  929. ButtonBorderStyle.Solid,
  930. Color.DeepSkyBlue,
  931. 1,
  932. ButtonBorderStyle.Solid,
  933. Color.DeepSkyBlue,
  934. 1,
  935. ButtonBorderStyle.Solid);
  936. }
  937. //只有正常和选择中的颗粒才进行绘制显示
  938. if (m_operator == ParticleOperator.DISPLAY || m_operator == ParticleOperator.SELECTED)
  939. {
  940. if (m_zoom_display == true)
  941. {
  942. //调用绘制基本线
  943. foreach (DSegment item in m_listdsegment)
  944. {
  945. item.OnPaint(e);
  946. }
  947. }
  948. else
  949. {
  950. g.DrawString("+", new Font("黑体", 6), new SolidBrush(Color.DarkSlateBlue), new PointF(m_small_rect.X, m_small_rect.Y));
  951. }
  952. }
  953. }
  954. /// <summary>
  955. /// 从Line中获取矩形的边缘闭合路径
  956. /// </summary>
  957. /// <returns></returns>
  958. public GraphicsPath GetRegionFromDSegments()
  959. {
  960. GraphicsPath gpath = new GraphicsPath();
  961. List<PointF> list_leftpointf = new List<PointF>();
  962. List<PointF> list_rightpointf = new List<PointF>();
  963. //从y循环,这里假设y轴会按lines集合来计算,然后将所有的左x,和右x取出排成两个队列
  964. foreach (DSegment ds in this.m_listdsegment)
  965. {
  966. list_leftpointf.Add(new PointF(ds.Rect.X, ds.Rect.Y));
  967. list_rightpointf.Add(new PointF(ds.Rect.X + ds.Rect.Width, ds.Rect.Y));
  968. }
  969. PointF[] lsp = new PointF[list_leftpointf.Count + list_rightpointf.Count];
  970. //再将两个x,y点依次添加到闭合路径中
  971. for (int i = 0; i < list_leftpointf.Count(); i++)
  972. {
  973. lsp[i] = list_leftpointf[i];
  974. }
  975. //右节点
  976. for (int i = 0; i < list_rightpointf.Count(); i++)
  977. {
  978. //这边倒着存入
  979. lsp[list_rightpointf.Count() + i] = list_rightpointf[list_rightpointf.Count() - i - 1];
  980. }
  981. //防止从低层拿到无数据的外边路径,在我的程序里却需要计算,而防止程序报死,这里做一下特殊处理。
  982. if (lsp.Count() >= 3)
  983. {
  984. gpath.AddPolygon(lsp);
  985. }
  986. else
  987. {
  988. //有时居然有颗粒,有没有segment的时候,防止报错
  989. if (this.DSegments.Count == 0)
  990. {
  991. lsp = new PointF[3] { new PointF(0, 0), new PointF(0, 0), new PointF(0, 0) };
  992. gpath.AddPolygon(lsp);
  993. return gpath;
  994. }
  995. //有2条数据
  996. if (lsp[1].X != 0 && lsp[1].Y != 0)
  997. {
  998. lsp = new PointF[3] { new PointF(lsp[0].X, lsp[0].Y), new PointF(lsp[1].X, lsp[1].Y), new PointF(lsp[1].X, lsp[1].Y) };
  999. }
  1000. //有1条数据
  1001. else if (lsp[0].X != 0 && lsp[0].Y != 0)
  1002. {
  1003. lsp = new PointF[3] { new PointF(lsp[0].X, lsp[0].Y), new PointF(lsp[0].X, lsp[0].Y), new PointF(lsp[0].X, lsp[0].Y) };
  1004. }
  1005. //剩下的情况
  1006. else
  1007. {
  1008. lsp = new PointF[3] { new PointF(0, 0), new PointF(0, 0), new PointF(0,0) };
  1009. }
  1010. gpath.AddPolygon(lsp);
  1011. }
  1012. return gpath;
  1013. }
  1014. /// <summary>
  1015. /// 从已经确定的外边框来计算出里面的+号小框位置
  1016. /// </summary>
  1017. /// <returns></returns>
  1018. public RectangleF GetSmallRectangleFromRect()
  1019. {
  1020. RectangleF rect = new RectangleF();
  1021. //用外边框的坐标,除2获得中心点,然后再分别+,- 4
  1022. float x = 0, y = 0;
  1023. x = m_rect.X + (m_rect.Width / 2);
  1024. y = m_rect.Y + (m_rect.Height / 2);
  1025. rect.X = x - 4;
  1026. rect.Y = y - 4;
  1027. rect.Width = 8;
  1028. rect.Height = 4;
  1029. return rect;
  1030. }
  1031. /// <summary>
  1032. /// 根据该多边形所有包含的线长度,计算出,该多边形的面积大小
  1033. /// </summary>
  1034. /// <returns></returns>
  1035. public float GetSizeFormSegmentsAllWidth()
  1036. {
  1037. float f_size_sum = 0;
  1038. foreach (DSegment ls_ds in this.m_listdsegment)
  1039. {
  1040. f_size_sum = f_size_sum + ls_ds.Rect.Width;
  1041. }
  1042. return f_size_sum;
  1043. }
  1044. /// <summary>
  1045. /// 从基本线中获取整个矩形的Rectangle
  1046. /// </summary>
  1047. /// <returns></returns>
  1048. public RectangleF GetRectFromDSegment()
  1049. {
  1050. RectangleF rect = new RectangleF();
  1051. float x1 = 0, y1 = 0;
  1052. float i_width = 0, i_height = 0;
  1053. //先从自身中初始化x,y,和宽,高
  1054. if (this.m_listdsegment.Count > 0)
  1055. {
  1056. x1 = this.m_listdsegment[0].Rect.X;
  1057. y1 = this.m_listdsegment[0].Rect.Y;
  1058. i_width = x1 + this.m_listdsegment[0].Rect.Width;
  1059. i_height = this.m_listdsegment[0].Rect.Y;
  1060. }
  1061. foreach (DSegment ds in this.m_listdsegment)
  1062. {
  1063. //分别取出,最小的x,y,
  1064. if (ds.Rect.X < x1)
  1065. {
  1066. x1 = ds.Rect.X;
  1067. }
  1068. if (ds.Rect.Y < y1)
  1069. {
  1070. y1 = ds.Rect.Y;
  1071. }
  1072. //最大的x,y
  1073. if (ds.Rect.X + ds.Rect.Width > i_width)
  1074. {
  1075. i_width = ds.Rect.X + ds.Rect.Width;
  1076. }
  1077. if (ds.Rect.Y > i_height)
  1078. {
  1079. i_height = ds.Rect.Y;
  1080. }
  1081. }
  1082. //对矩形Rect大小位置进行修补,因为画线是内边框,并且计算出来的位置也是向内占用一像素的,
  1083. //正常应该是 +2,但实际效果,+3也才勉强够用,因为放大缩小画笔宽度影响的
  1084. rect.X = x1 - 2;
  1085. rect.Y = y1 - 3;
  1086. rect.Width = i_width - rect.X + 2;
  1087. rect.Height = i_height - rect.Y + 3;
  1088. //判断如果太小,就给个最小值吧
  1089. if (rect.Width < 8)
  1090. rect.Width = 8;
  1091. if (rect.Height < 8)
  1092. rect.Height = 8;
  1093. return rect;
  1094. }
  1095. }
  1096. /// <summary>
  1097. /// 基本线类
  1098. /// </summary>
  1099. public class DSegment : BaseObject, ICloneable
  1100. {
  1101. private string m_id;
  1102. private RectangleF m_region;
  1103. private PointF m_OTSPointF;
  1104. private bool m_isselect;
  1105. private bool m_isdragging;
  1106. private PointF m_dragingpoint;
  1107. private Color m_color;
  1108. private Color m_backcolor;
  1109. private GraphicsPath m_gpath;
  1110. private float m_PenWidthAndHeight = 1;
  1111. private SegmentShowMode show_mode = SegmentShowMode.DRAWPOINT;//绘线,绘点,默认绘点,意思为默认显示BSE原图像
  1112. private List<Color> m_list_colors;
  1113. /// <summary>
  1114. /// 克隆基本线
  1115. /// </summary>
  1116. /// <returns></returns>
  1117. public override object Clone()
  1118. {
  1119. return MemberwiseClone();
  1120. }
  1121. public DSegment()
  1122. {
  1123. m_id = System.Guid.NewGuid().ToString();
  1124. }
  1125. /// <summary>
  1126. /// ID
  1127. /// </summary>
  1128. public override string ID
  1129. {
  1130. get { return m_id; }
  1131. set { m_id = value; }
  1132. }
  1133. /// <summary>
  1134. /// 画面的大小
  1135. /// </summary>
  1136. public override RectangleF Rect
  1137. {
  1138. get { return m_region; }
  1139. set { m_region = value; }
  1140. }
  1141. /// <summary>
  1142. /// OTSField
  1143. /// </summary>
  1144. public override PointF OTSPointF
  1145. {
  1146. get { return m_OTSPointF; }
  1147. set { m_OTSPointF = value; }
  1148. }
  1149. /// <summary>
  1150. /// 画布是否被选择
  1151. /// </summary>
  1152. public override bool IsSelect
  1153. {
  1154. get { return m_isselect; }
  1155. set { m_isselect = value; }
  1156. }
  1157. /// <summary>
  1158. /// 是否在被拖动
  1159. /// </summary>
  1160. public override bool IsDragging
  1161. {
  1162. get { return m_isdragging; }
  1163. set { m_isdragging = value; }
  1164. }
  1165. /// <summary>
  1166. /// 被拖动到的位置坐标
  1167. /// </summary>
  1168. public override PointF DraggingPoint
  1169. {
  1170. get { return m_dragingpoint; }
  1171. set { m_dragingpoint = value; }
  1172. }
  1173. /// <summary>
  1174. /// 线的颜色
  1175. /// </summary>
  1176. public override Color Color
  1177. {
  1178. get { return m_color; }
  1179. set { m_color = value; }
  1180. }
  1181. /// <summary>
  1182. /// 背景色
  1183. /// </summary>
  1184. public override Color BackColor
  1185. {
  1186. get { return m_backcolor; }
  1187. set { m_backcolor = value; }
  1188. }
  1189. /// <summary>
  1190. /// 多边形的图形路径边缘
  1191. /// </summary>
  1192. public override GraphicsPath GPath
  1193. {
  1194. get { return m_gpath; }
  1195. set { m_gpath = value; }
  1196. }
  1197. /// <summary>
  1198. /// 设置画笔的笔宽度
  1199. /// </summary>
  1200. public float PenWidthAndHeight
  1201. {
  1202. get { return m_PenWidthAndHeight; }
  1203. set { m_PenWidthAndHeight = value; }
  1204. }
  1205. /// <summary>
  1206. /// 设置显示的方式,可以用,绘线显示查看标准库颜色的,也可以用绘点,查看BSE原图颗粒图色的
  1207. /// </summary>
  1208. public SegmentShowMode ShowMode
  1209. {
  1210. get { return show_mode; }
  1211. set { show_mode = value; }
  1212. }
  1213. /// <summary>
  1214. /// 保存BSE标准库文件的颗粒点的颜色信息
  1215. /// </summary>
  1216. public List<Color> List_Colors
  1217. {
  1218. get { return m_list_colors; }
  1219. set { m_list_colors = value; }
  1220. }
  1221. /// <summary>
  1222. /// 绘制函数
  1223. /// </summary>
  1224. /// <param name="e"></param>
  1225. public override void OnPaint(PaintEventArgs e)
  1226. {
  1227. //两种绘制模式的选择,绘线还是缓点
  1228. if (show_mode == SegmentShowMode.DRAWLINE)
  1229. {
  1230. //表示显示的是带有标准库的图像
  1231. Pen p = new Pen(m_color, m_PenWidthAndHeight + 1f);//这里加1f的宽度后,用线组成多边形不会分散,效果正常,原因不知,但目前没有遇到问题
  1232. e.Graphics.DrawLine(p, Rect.X, Rect.Y, Rect.X + Rect.Width, Rect.Y);
  1233. }
  1234. else if (show_mode == SegmentShowMode.DRAWPOINT)
  1235. {
  1236. //根据color的序列,显示绘制的原像素的图像。
  1237. for (int i = 0; i < m_list_colors.Count(); i++)
  1238. {
  1239. e.Graphics.FillRectangle(new SolidBrush(m_list_colors[i]),
  1240. this.Rect.X + (i * m_PenWidthAndHeight) + 1f,
  1241. this.Rect.Y,
  1242. m_PenWidthAndHeight,
  1243. m_PenWidthAndHeight);
  1244. }
  1245. }
  1246. }
  1247. }
  1248. #endregion
  1249. }