SortParticleDistribution.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. using OTSIncAReportGraph;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Drawing;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace OTSIncAReportGraph
  9. {
  10. #region 颗粒分布图,排序图统一使用类
  11. /// <summary>
  12. /// 颗粒排序,能对颗粒进行分栏的类
  13. /// </summary>
  14. public class SortParticleDistribution : ICloneable
  15. {
  16. private List<DisplayParticle> list_dparticle = new List<DisplayParticle>();
  17. private RectangleF m_rectf;
  18. private string m_showstr = "";
  19. private float m_size_min = 0;
  20. private float m_size_max = 0;
  21. public SortParticleDistribution()
  22. { }
  23. //构造函数
  24. SortParticleDistribution(List<DisplayParticle> inlist_dparticle, SortParticleDistribution in_spd)
  25. {
  26. m_rectf = in_spd.m_rectf;
  27. m_showstr = in_spd.m_showstr;
  28. m_size_min = in_spd.m_size_min;
  29. m_size_max = in_spd.m_size_max;
  30. foreach (DisplayParticle e in inlist_dparticle)
  31. {
  32. list_dparticle.Add(e.Clone() as DisplayParticle);
  33. }
  34. }
  35. /// <summary>
  36. /// 克隆方法
  37. /// </summary>
  38. /// <returns></returns>
  39. public object Clone()
  40. {
  41. return new SortParticleDistribution(this.list_dparticle, this);
  42. }
  43. /// <summary>
  44. /// 多边形图数组
  45. /// </summary>
  46. public List<DisplayParticle> List_DParticle
  47. {
  48. get { return list_dparticle; }
  49. set { list_dparticle = value; }
  50. }
  51. /// <summary>
  52. /// 整个分类Grid的位置
  53. /// </summary>
  54. public RectangleF RectF
  55. {
  56. get { return m_rectf; }
  57. set { m_rectf = value; }
  58. }
  59. /// <summary>
  60. /// 该分类Grid显示的文字
  61. /// </summary>
  62. public string ShowStr
  63. {
  64. get { return m_showstr; }
  65. set { m_showstr = value; }
  66. }
  67. /// <summary>
  68. /// 该Grid保存多边形范围的最小值
  69. /// </summary>
  70. public float Size_Min
  71. {
  72. get { return m_size_min; }
  73. set { m_size_min = value; }
  74. }
  75. /// <summary>
  76. /// 该Grid保存多边形范围的最大值
  77. /// </summary>
  78. public float Size_Max
  79. {
  80. get { return m_size_max; }
  81. set { m_size_max = value; }
  82. }
  83. /// <summary>
  84. /// 获取多边形Grid内,所有多边形所占有的行数,用于其它计算使用
  85. /// </summary>
  86. /// <returns></returns>
  87. public int GetDParticleRowNumber()
  88. {
  89. int RowsNumber = 0;
  90. //首先获取所有多边形的宽度之和
  91. float f_all_dparticle_widthsum = 0;
  92. foreach (DisplayParticle dp in this.list_dparticle)
  93. {
  94. f_all_dparticle_widthsum = f_all_dparticle_widthsum + dp.Rect.Width;
  95. }
  96. //然后除以自身的宽度+1,就是所有的行数了
  97. float f_rowsnumber = f_all_dparticle_widthsum / this.RectF.Width + 1;
  98. RowsNumber = Convert.ToInt32(f_rowsnumber);
  99. return RowsNumber;
  100. }
  101. /// <summary>
  102. /// 获取多边形分栏,分栏的高度
  103. /// </summary>
  104. /// <returns></returns>
  105. public float GetSortGridHeight()
  106. {
  107. float i_SortGridHeight = 0;
  108. int i_RowNumber = GetDParticleRowNumber();
  109. //再获取所有的颗粒中,最长的
  110. float i_heightmax = 0;
  111. float i_ls_height = 0;
  112. foreach (DisplayParticle dp in this.list_dparticle)
  113. {
  114. float ls_y = 0;//用来判断y坐标是否有变化,好用来计算长度
  115. foreach (DisplaySegment ds in dp.DSegments)
  116. {
  117. if (ds.Rect.Y != ls_y)
  118. {
  119. //i_ls_height++;
  120. ls_y = ds.Rect.Y;
  121. //如果需要考虑笔宽缩放的话,目前这样写,效果还没有出现问题
  122. i_ls_height = i_ls_height + ds.Rect.Height * ds.PenWidthAndHeight;
  123. }
  124. if (i_heightmax < i_ls_height)
  125. {
  126. i_heightmax = i_ls_height;
  127. }
  128. }
  129. i_ls_height = 0;
  130. }
  131. //用最高的颗粒*行数,来计算整个grid的高度
  132. i_SortGridHeight = i_RowNumber * (i_heightmax + 10) + 20;//因为每行都额外增加了10点的高度
  133. //应该当grid最小大于=50
  134. if (i_SortGridHeight < 50)
  135. {
  136. i_SortGridHeight = 50;
  137. }
  138. return i_SortGridHeight;
  139. }
  140. /// <summary>
  141. /// 根据传入的2个多边形list,从大到小进行排序,两个多边形list通过guid保持一致
  142. /// 主要用于计算list与old_list能进行相同顺序的排序
  143. /// </summary>
  144. /// <param name="list_dparticle"></param>
  145. /// <param name="old_list_dparticle"></param>
  146. public void SortDParticleBySizeFromBigToSmall(List<DisplayParticle> list_dparticle, List<DisplayParticle> old_list_dparticle)
  147. {
  148. //首先分别将两个多边形list保存起来
  149. List<DisplayParticle> list_dp1 = new List<DisplayParticle>();
  150. List<DisplayParticle> list_dp2 = new List<DisplayParticle>();
  151. foreach (DisplayParticle ls_dp in list_dparticle)
  152. {
  153. DisplayParticle dp1 = ls_dp.Clone() as DisplayParticle;
  154. list_dp1.Add(dp1);
  155. }
  156. foreach (DisplayParticle ls_dp in old_list_dparticle)
  157. {
  158. DisplayParticle dp2 = ls_dp.Clone() as DisplayParticle;
  159. list_dp2.Add(dp2);
  160. }
  161. //清除原先的两个多边形list
  162. list_dparticle.Clear();
  163. old_list_dparticle.Clear();
  164. //嵌套2次循环
  165. int icount = list_dp1.Count();
  166. for (int i = 0; i < icount; i++)
  167. {
  168. //找出最大的
  169. float f_max_size = 0;
  170. Guid str_jlguid ;
  171. DisplayParticle ls_dp = new DisplayParticle();
  172. foreach (DisplayParticle ls_del_dp in list_dp1)
  173. {
  174. //通过包含的线,获取多边形的尺寸大小
  175. ls_del_dp.FSize = ls_del_dp.GetSizeFormSegmentsAllWidth();
  176. if (f_max_size < ls_del_dp.FSize)
  177. {
  178. f_max_size = ls_del_dp.FSize;
  179. str_jlguid = ls_del_dp.guid;
  180. ls_dp = ls_del_dp;
  181. }
  182. }
  183. //然后分别将两个该guid的多边形从list1,2中删除
  184. list_dp1.Remove(ls_dp);
  185. //再分别插入到原先的list,和old_list中
  186. ls_dp.Rect = ls_dp.GetRectFromDSegment();
  187. list_dparticle.Add(ls_dp);
  188. }
  189. //换种方法,按Guid将list2中对应的再添加到old_list中
  190. foreach (DisplayParticle ls_dp in list_dparticle)
  191. {
  192. foreach (DisplayParticle ls_dp2 in list_dp2)
  193. {
  194. if (ls_dp2.guid == ls_dp.guid)
  195. {
  196. ls_dp2.Rect = ls_dp2.GetRectFromDSegment();
  197. old_list_dparticle.Add(ls_dp2);
  198. }
  199. }
  200. }
  201. }
  202. /// <summary>
  203. /// 根据传入的2个多边形list,从小到大进行排序,两个多边形list通过guid保持一致
  204. /// 主要用于计算list与old_list能进行相同顺序的排序
  205. /// </summary>
  206. /// <param name="list_dparticle"></param>
  207. /// <param name="old_list_dparticle"></param>
  208. public void SortDParticlesBySizeFromSmallToBig(List<DisplayParticle> list_dparticle, List<DisplayParticle> old_list_dparticles)
  209. {
  210. //首先分别将两个多边形list保存起来
  211. List<DisplayParticle> list_dp1 = new List<DisplayParticle>();
  212. List<DisplayParticle> list_dp2 = new List<DisplayParticle>();
  213. foreach (DisplayParticle ls_dp in list_dparticle)
  214. {
  215. DisplayParticle dp1 = ls_dp.Clone() as DisplayParticle;
  216. list_dp1.Add(dp1);
  217. }
  218. foreach (DisplayParticle ls_dp in old_list_dparticles)
  219. {
  220. DisplayParticle dp2 = ls_dp.Clone() as DisplayParticle;
  221. list_dp2.Add(dp2);
  222. }
  223. //清除原先的两个多边形list
  224. list_dparticle.Clear();
  225. old_list_dparticles.Clear();
  226. //嵌套2次循环
  227. int icount = list_dparticle.Count();
  228. for (int i = 0; i < icount; i++)
  229. {
  230. //找出最小的
  231. float f_min_size = 10000000;
  232. Guid str_jlguid ;
  233. DisplayParticle ls_dp = new DisplayParticle();
  234. foreach (DisplayParticle ls_del_dp in list_dp1)
  235. {
  236. //通过包含的线,获取多边形的尺寸大小
  237. ls_del_dp.FSize = ls_del_dp.GetSizeFormSegmentsAllWidth();
  238. if (f_min_size > ls_del_dp.FSize)
  239. {
  240. f_min_size = ls_del_dp.FSize;
  241. str_jlguid = ls_del_dp.guid;
  242. ls_dp = ls_del_dp;
  243. }
  244. }
  245. //然后分别将两个该guid的多边形从list1,2中删除
  246. list_dp1.Remove(ls_dp);
  247. //再分别插入到原先的list,和old_list中
  248. list_dparticle.Add(ls_dp);
  249. }
  250. //换种方法,按Guid将list2中对应的再添加到old_list中
  251. foreach (DisplayParticle ls_dp in list_dparticle)
  252. {
  253. foreach (DisplayParticle ls_dp2 in list_dp2)
  254. {
  255. if (ls_dp2.guid == ls_dp.guid)
  256. {
  257. old_list_dparticles.Add(ls_dp2);
  258. }
  259. }
  260. }
  261. }
  262. /// <summary>
  263. /// 颗粒排序方法2
  264. /// </summary>
  265. /// <param name="in_f_zoom_record"></param>
  266. public void SortParticle222(float in_f_zoom_record)
  267. {
  268. float f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record;
  269. float f_ls_y = this.m_rectf.Y + 3 * in_f_zoom_record;
  270. foreach (DisplayParticle dp in this.list_dparticle)
  271. {
  272. dp.Rect = dp.GetRectFromDSegment();
  273. if ((f_ls_x + dp.Rect.Width + 6) > this.m_rectf.Width + this.m_rectf.X)
  274. {
  275. f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record;
  276. f_ls_y = f_ls_y + this.GetSortGridHeight() / this.GetDParticleRowNumber() - 5;
  277. }
  278. float f_cz_x = f_ls_x - dp.Rect.X;
  279. float f_cz_y = f_ls_y - dp.Rect.Y;
  280. foreach (DisplaySegment ds in dp.DSegments)
  281. {
  282. ds.Rect = new RectangleF(ds.Rect.X + f_cz_x, ds.Rect.Y + f_cz_y, ds.Rect.Width, ds.Rect.Height);
  283. }
  284. f_ls_x = f_ls_x + dp.Rect.Width + 3 * in_f_zoom_record;
  285. dp.Rect = dp.GetRectFromDSegment();
  286. dp.GPath = dp.GetRegionFromDSegments();
  287. dp.SmallRect = dp.GetSmallRectangleFromRect();
  288. }
  289. }
  290. /// <summary>
  291. /// 对已经存入的颗粒信息,按定位好的rect位置,重新给line和各参数,重新进行计算
  292. /// 就是在分栏的Grid中对多边形进行摆放
  293. /// </summary>
  294. public void SortDParticle(float in_f_zoom_record)
  295. {
  296. //设置增长的x,y轴值,+3是跳过边框的位置, 可能有个别情况,会在右侧突出占到边框的位置上
  297. float f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record;
  298. float f_ls_y = this.m_rectf.Y + 3 * in_f_zoom_record;
  299. foreach (DisplayParticle dp in this.list_dparticle)
  300. {
  301. //这里要对不显示的颗粒进行屏蔽,也就是进行不计算位置,不知道会不会有其它的影响
  302. if (dp.displayState != DisplayState.NODISPLAY)
  303. {
  304. //首先确定各多边形的矩形位置
  305. dp.Rect = dp.GetRectFromDSegment();
  306. //判断是否已经达到了x的边缘,是的话,那么y轴进行增长,判断x轴+颗粒的宽度+6的相当于边框宽度的差值补值,大于grid宽度时
  307. //在增长前就判断宽度,防止部份多边形突出到分栏外
  308. if ((f_ls_x + dp.Rect.Width + 6) > this.m_rectf.Width + this.m_rectf.X)
  309. {
  310. //还原x到该分栏Grid的左边框+3的位置,并且将y轴定位到下一高度的y轴位置
  311. f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record;
  312. f_ls_y = f_ls_y + this.GetSortGridHeight() / this.GetDParticleRowNumber() - 5;//在获取高度时,已经+10,所以这里再-5,颗粒近一些
  313. }
  314. //计算出与定位的Grid的差值,然后重新排序线,用分栏Grid-颗粒的外Rect,取到x,y的差值
  315. float f_cz_x = f_ls_x - dp.Rect.X;
  316. float f_cz_y = f_ls_y - dp.Rect.Y;
  317. //获取到差值后,再对该多边形下面的所有线进行调整
  318. foreach (DisplaySegment ds in dp.DSegments)
  319. {
  320. ds.Rect = new RectangleF(ds.Rect.X + f_cz_x, ds.Rect.Y + f_cz_y, ds.Rect.Width, ds.Rect.Height);
  321. }
  322. //定位好该多边形后,对x轴进行增长,为下一个多边形定位好位置
  323. f_ls_x = f_ls_x + dp.Rect.Width + 3 * in_f_zoom_record;
  324. //重新计算sort_ap的
  325. dp.Rect = dp.GetRectFromDSegment();
  326. //通过line获取路径边缘
  327. dp.GPath = dp.GetRegionFromDSegments();
  328. //重新计算小矩形边框
  329. dp.SmallRect = dp.GetSmallRectangleFromRect();
  330. }
  331. }
  332. }
  333. }
  334. }
  335. #endregion