using OTSIncAReportGraph; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; namespace OTSIncAReportGraph { #region 颗粒分布图,排序图统一使用类 /// /// 颗粒排序,能对颗粒进行分栏的类 /// public class SortParticleDistribution : ICloneable { private List list_dparticle = new List(); private RectangleF m_rectf; private string m_showstr = ""; private float m_size_min = 0; private float m_size_max = 0; public SortParticleDistribution() { } //构造函数 SortParticleDistribution(List inlist_dparticle, SortParticleDistribution in_spd) { m_rectf = in_spd.m_rectf; m_showstr = in_spd.m_showstr; m_size_min = in_spd.m_size_min; m_size_max = in_spd.m_size_max; foreach (DisplayParticle e in inlist_dparticle) { list_dparticle.Add(e.Clone() as DisplayParticle); } } /// /// 克隆方法 /// /// public object Clone() { return new SortParticleDistribution(this.list_dparticle, this); } /// /// 多边形图数组 /// public List List_DParticle { get { return list_dparticle; } set { list_dparticle = value; } } /// /// 整个分类Grid的位置 /// public RectangleF RectF { get { return m_rectf; } set { m_rectf = value; } } /// /// 该分类Grid显示的文字 /// public string ShowStr { get { return m_showstr; } set { m_showstr = value; } } /// /// 该Grid保存多边形范围的最小值 /// public float Size_Min { get { return m_size_min; } set { m_size_min = value; } } /// /// 该Grid保存多边形范围的最大值 /// public float Size_Max { get { return m_size_max; } set { m_size_max = value; } } /// /// 获取多边形Grid内,所有多边形所占有的行数,用于其它计算使用 /// /// public int GetDParticleRowNumber() { int RowsNumber = 0; //首先获取所有多边形的宽度之和 float f_all_dparticle_widthsum = 0; foreach (DisplayParticle dp in this.list_dparticle) { f_all_dparticle_widthsum = f_all_dparticle_widthsum + dp.Rect.Width; } //然后除以自身的宽度+1,就是所有的行数了 float f_rowsnumber = f_all_dparticle_widthsum / this.RectF.Width + 1; RowsNumber = Convert.ToInt32(f_rowsnumber); return RowsNumber; } /// /// 获取多边形分栏,分栏的高度 /// /// public float GetSortGridHeight() { float i_SortGridHeight = 0; int i_RowNumber = GetDParticleRowNumber(); //再获取所有的颗粒中,最长的 float i_heightmax = 0; float i_ls_height = 0; foreach (DisplayParticle dp in this.list_dparticle) { float ls_y = 0;//用来判断y坐标是否有变化,好用来计算长度 foreach (DisplaySegment ds in dp.DSegments) { if (ds.Rect.Y != ls_y) { //i_ls_height++; ls_y = ds.Rect.Y; //如果需要考虑笔宽缩放的话,目前这样写,效果还没有出现问题 i_ls_height = i_ls_height + ds.Rect.Height * ds.PenWidthAndHeight; } if (i_heightmax < i_ls_height) { i_heightmax = i_ls_height; } } i_ls_height = 0; } //用最高的颗粒*行数,来计算整个grid的高度 i_SortGridHeight = i_RowNumber * (i_heightmax + 10) + 20;//因为每行都额外增加了10点的高度 //应该当grid最小大于=50 if (i_SortGridHeight < 50) { i_SortGridHeight = 50; } return i_SortGridHeight; } /// /// 根据传入的2个多边形list,从大到小进行排序,两个多边形list通过guid保持一致 /// 主要用于计算list与old_list能进行相同顺序的排序 /// /// /// public void SortDParticleBySizeFromBigToSmall(List list_dparticle, List old_list_dparticle) { //首先分别将两个多边形list保存起来 List list_dp1 = new List(); List list_dp2 = new List(); foreach (DisplayParticle ls_dp in list_dparticle) { DisplayParticle dp1 = ls_dp.Clone() as DisplayParticle; list_dp1.Add(dp1); } foreach (DisplayParticle ls_dp in old_list_dparticle) { DisplayParticle dp2 = ls_dp.Clone() as DisplayParticle; list_dp2.Add(dp2); } //清除原先的两个多边形list list_dparticle.Clear(); old_list_dparticle.Clear(); //嵌套2次循环 int icount = list_dp1.Count(); for (int i = 0; i < icount; i++) { //找出最大的 float f_max_size = 0; Guid str_jlguid ; DisplayParticle ls_dp = new DisplayParticle(); foreach (DisplayParticle ls_del_dp in list_dp1) { //通过包含的线,获取多边形的尺寸大小 ls_del_dp.FSize = ls_del_dp.GetSizeFormSegmentsAllWidth(); if (f_max_size < ls_del_dp.FSize) { f_max_size = ls_del_dp.FSize; str_jlguid = ls_del_dp.guid; ls_dp = ls_del_dp; } } //然后分别将两个该guid的多边形从list1,2中删除 list_dp1.Remove(ls_dp); //再分别插入到原先的list,和old_list中 ls_dp.Rect = ls_dp.GetRectFromDSegment(); list_dparticle.Add(ls_dp); } //换种方法,按Guid将list2中对应的再添加到old_list中 foreach (DisplayParticle ls_dp in list_dparticle) { foreach (DisplayParticle ls_dp2 in list_dp2) { if (ls_dp2.guid == ls_dp.guid) { ls_dp2.Rect = ls_dp2.GetRectFromDSegment(); old_list_dparticle.Add(ls_dp2); } } } } /// /// 根据传入的2个多边形list,从小到大进行排序,两个多边形list通过guid保持一致 /// 主要用于计算list与old_list能进行相同顺序的排序 /// /// /// public void SortDParticlesBySizeFromSmallToBig(List list_dparticle, List old_list_dparticles) { //首先分别将两个多边形list保存起来 List list_dp1 = new List(); List list_dp2 = new List(); foreach (DisplayParticle ls_dp in list_dparticle) { DisplayParticle dp1 = ls_dp.Clone() as DisplayParticle; list_dp1.Add(dp1); } foreach (DisplayParticle ls_dp in old_list_dparticles) { DisplayParticle dp2 = ls_dp.Clone() as DisplayParticle; list_dp2.Add(dp2); } //清除原先的两个多边形list list_dparticle.Clear(); old_list_dparticles.Clear(); //嵌套2次循环 int icount = list_dparticle.Count(); for (int i = 0; i < icount; i++) { //找出最小的 float f_min_size = 10000000; Guid str_jlguid ; DisplayParticle ls_dp = new DisplayParticle(); foreach (DisplayParticle ls_del_dp in list_dp1) { //通过包含的线,获取多边形的尺寸大小 ls_del_dp.FSize = ls_del_dp.GetSizeFormSegmentsAllWidth(); if (f_min_size > ls_del_dp.FSize) { f_min_size = ls_del_dp.FSize; str_jlguid = ls_del_dp.guid; ls_dp = ls_del_dp; } } //然后分别将两个该guid的多边形从list1,2中删除 list_dp1.Remove(ls_dp); //再分别插入到原先的list,和old_list中 list_dparticle.Add(ls_dp); } //换种方法,按Guid将list2中对应的再添加到old_list中 foreach (DisplayParticle ls_dp in list_dparticle) { foreach (DisplayParticle ls_dp2 in list_dp2) { if (ls_dp2.guid == ls_dp.guid) { old_list_dparticles.Add(ls_dp2); } } } } /// /// 颗粒排序方法2 /// /// public void SortParticle222(float in_f_zoom_record) { float f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record; float f_ls_y = this.m_rectf.Y + 3 * in_f_zoom_record; foreach (DisplayParticle dp in this.list_dparticle) { dp.Rect = dp.GetRectFromDSegment(); if ((f_ls_x + dp.Rect.Width + 6) > this.m_rectf.Width + this.m_rectf.X) { f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record; f_ls_y = f_ls_y + this.GetSortGridHeight() / this.GetDParticleRowNumber() - 5; } float f_cz_x = f_ls_x - dp.Rect.X; float f_cz_y = f_ls_y - dp.Rect.Y; foreach (DisplaySegment ds in dp.DSegments) { ds.Rect = new RectangleF(ds.Rect.X + f_cz_x, ds.Rect.Y + f_cz_y, ds.Rect.Width, ds.Rect.Height); } f_ls_x = f_ls_x + dp.Rect.Width + 3 * in_f_zoom_record; dp.Rect = dp.GetRectFromDSegment(); dp.GPath = dp.GetRegionFromDSegments(); dp.SmallRect = dp.GetSmallRectangleFromRect(); } } /// /// 对已经存入的颗粒信息,按定位好的rect位置,重新给line和各参数,重新进行计算 /// 就是在分栏的Grid中对多边形进行摆放 /// public void SortDParticle(float in_f_zoom_record) { //设置增长的x,y轴值,+3是跳过边框的位置, 可能有个别情况,会在右侧突出占到边框的位置上 float f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record; float f_ls_y = this.m_rectf.Y + 3 * in_f_zoom_record; foreach (DisplayParticle dp in this.list_dparticle) { //这里要对不显示的颗粒进行屏蔽,也就是进行不计算位置,不知道会不会有其它的影响 if (dp.displayState != DisplayState.NODISPLAY) { //首先确定各多边形的矩形位置 dp.Rect = dp.GetRectFromDSegment(); //判断是否已经达到了x的边缘,是的话,那么y轴进行增长,判断x轴+颗粒的宽度+6的相当于边框宽度的差值补值,大于grid宽度时 //在增长前就判断宽度,防止部份多边形突出到分栏外 if ((f_ls_x + dp.Rect.Width + 6) > this.m_rectf.Width + this.m_rectf.X) { //还原x到该分栏Grid的左边框+3的位置,并且将y轴定位到下一高度的y轴位置 f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record; f_ls_y = f_ls_y + this.GetSortGridHeight() / this.GetDParticleRowNumber() - 5;//在获取高度时,已经+10,所以这里再-5,颗粒近一些 } //计算出与定位的Grid的差值,然后重新排序线,用分栏Grid-颗粒的外Rect,取到x,y的差值 float f_cz_x = f_ls_x - dp.Rect.X; float f_cz_y = f_ls_y - dp.Rect.Y; //获取到差值后,再对该多边形下面的所有线进行调整 foreach (DisplaySegment ds in dp.DSegments) { ds.Rect = new RectangleF(ds.Rect.X + f_cz_x, ds.Rect.Y + f_cz_y, ds.Rect.Width, ds.Rect.Height); } //定位好该多边形后,对x轴进行增长,为下一个多边形定位好位置 f_ls_x = f_ls_x + dp.Rect.Width + 3 * in_f_zoom_record; //重新计算sort_ap的 dp.Rect = dp.GetRectFromDSegment(); //通过line获取路径边缘 dp.GPath = dp.GetRegionFromDSegments(); //重新计算小矩形边框 dp.SmallRect = dp.GetSmallRectangleFromRect(); } } } } } #endregion