| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824 | using OTSCommon.Model;using OTSIncAReportGraph.Class;using System;using System.Collections.Generic;using System.Drawing;using System.Drawing.Drawing2D;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace OTSIncAReportGraph{        /// <summary>    /// Particle对象上操作状态的枚举,显示,不显示,已删除,已选择    /// </summary>    public enum PaintState    {        PAINT = 0,        NOPAINT = 1,        CONCISEPAINT=2,// display as a "+"            }    public enum DisplayState    {        DISPLAY = 0,        NODISPLAY = 1,           }    /// <summary>    /// Particle对象上操作xray的枚举状态,显示xray数据,不显示    /// </summary>    public enum ParticleShowXray    {        SELECTANDDISPLAYXRAY = 0,        NODISPLAY = 1,    }    /// <summary>    /// Segment对象绘制的枚举,以点绘制,还是以线绘制    /// </summary>    public enum SegmentShowMode    {        DRAWPOINT = 0,        DRAWLINE = 1,    }    /// <summary>    /// 颗粒类    /// </summary>    public class DisplayParticle : BaseObject, ICloneable, IComparable<DisplayParticle>    {        private const float m_zoom_displaymultiplier = 0.5f;        public Particle objParticleData;        private Guid m_id;        private RectangleF m_rect;        private PointF m_OTSPointF;        private RectangleF m_small_rect;        private bool m_isSelected_smallrect;        private bool m_showSmallx;        private bool m_isSelected;        private bool m_isDeleted;        private bool m_isMouseOver;        private PaintState m_paintState = PaintState.PAINT;        private ParticleShowXray m_operator_showxray = ParticleShowXray.NODISPLAY;//选定显示XRAY,不显示XRAY,默认应为(不显示XRAY)        private bool m_isdragging;        private PointF m_dragingpoint;        private Color m_color;        private Color m_backcolor;        private GraphicsPath m_gpath;        private List<DisplaySegment> m_listdsegment = new List<DisplaySegment>();        private DisplayState m_displayState;        private Image m_image;        private string m_sort_type = "从大到小";        private float m_f_size = 0;        private string m_str_lj = "颗粒粒级";        private string m_str_klzl = "颗粒种类";        private string m_str_klfl = "颗粒分类";         public int TypeId         {            get            {               return objParticleData.TypeId;            }        }        //TypeName        public string TypeName         {            get            {                return objParticleData.TypeName;            }        }        //XRayId        public int XRayId         {            get            {                return objParticleData.XrayId;            }        }        public int SEMPosX         {            get            {                return objParticleData.SEMPosX;            }        }        public int SEMPosY         {            get            {                return objParticleData.SEMPosY;            }        }        public DisplayParticle()        {            m_id = System.Guid.NewGuid();        }        public DisplayParticle(Particle part)        {            m_id = System.Guid.NewGuid();            objParticleData = part;            this.Color = GetColorBySTDTypeIDForBSEAndSorImage(part.TypeColor, part.TypeId);                   }        public DisplayParticle(List<DisplaySegment> in_list_segment, DisplayParticle in_particle)        {                       objParticleData = in_particle.objParticleData;            m_id = in_particle.m_id;                                            m_paintState = in_particle.m_paintState;            m_operator_showxray = in_particle.m_operator_showxray;                                 foreach (DisplaySegment e in in_list_segment)            {                m_listdsegment.Add(e.Clone() as DisplaySegment);            }        }        /// <summary>        /// [目前也不使用该方法了,因为该方法每次排序都有不同的结果]多边形排序,按传入的sort_type的排序类型行排序,但需要两个list做一致性排序        /// </summary>        /// <param name="in_ap"></param>        /// <returns></returns>        public int CompareTo(DisplayParticle in_particle)        {            int r_b = 0;//排序返回值            switch (m_sort_type)            {                case "从大到小":                    r_b = in_particle.m_f_size.CompareTo(this.m_f_size);                    break;                case "从小到大":                    //与上面的从大到小正好相反即可                    r_b = in_particle.m_f_size.CompareTo(this.m_f_size);                    if (r_b == 1)                        r_b = -1;                    else                        r_b = 1;                    break;                default:                    break;            }            return r_b;        }        public Color GetColorBySTDTypeIDForBSEAndSorImage(string in_partcolor, int in_stdtypeid)        {            Color ret_c = new Color();            if (in_stdtypeid < 1000)            {                   ret_c = GetColorByEnum(in_stdtypeid);            }            else if (in_stdtypeid >= 1000)            {                //大于等于1000,并且小于10000时,使用用户标准库来分析夹杂物名称                if (!in_partcolor.Contains("#"))                {                    ret_c = DrawFunction.colorHx16toRGB("#" + in_partcolor);//接收必须是#000000的格式                }                else                {                    ret_c = DrawFunction.colorHx16toRGB(in_partcolor);//接收必须是#000000的格式                }            }            return ret_c;        }        public Color GetColorByEnum(int STDID)        {            Color ret_c = new Color();            switch (STDID)            {                case -1:                    //INVALID = -1,                    //stdName = "无效颗粒";                    ret_c = Color.Black;                    break;                case 0:                    //small = 0;                    //stdName = "过小颗粒";                    ret_c = Color.Black;                    break;                case 1:                    //OVERSIZE = 1,                    //stdName = "过大颗粒";                    ret_c = Color.Black;                    break;                case 2:                    //AVE_GRAY_NOT_INRANRE = 2,                     //stdName = "亮度不在分析范围内的颗粒";                    ret_c = Color.Black;                    break;                case 3:                    //SEARCH_X_RAY = 3,                    //stdName = "不进行搜索x-ray分析的颗粒";                    ret_c = Color.Black;                    break;                case 4:                    //LOW_COUNT = 4,                     //stdName = "低x-ray计数颗粒";                    ret_c = Color.Black;                    break;                case 5:                    //NO_INTEREST_ELEMENTS = 5,                    //stdName = "不含分析元素的颗粒";                    ret_c = Color.Black;                    break;                case 6:                    //ALAYSIS_X_RAY = 6,                    //stdName = "不进行x-ray分析的颗粒";                    ret_c = Color.Black;                    break;                case 7:                    //NOT_IDENTIFIED = 7,                    //stdName = "未识别颗粒";                    ret_c = Color.Black;                    break;                case 8:                    //NOT_IDENTIFIED = 8,                    //stdName = "未识别颗粒";                    ret_c = Color.Black;                    break;                case 9:                    //NOT_IDENTIFIED = 9,                    //stdName = "未识别颗粒";                    ret_c = Color.Black;                    break;                default:                    ret_c = Color.Black;                    break;            }            return ret_c;        }        /// <summary>        /// 克隆方法        /// </summary>        /// <returns></returns>        public override object Clone()        {            var dp= new DisplayParticle(this.m_listdsegment, this);            dp.m_image = this.m_image;            return dp;        }        public PointF GetCenterPoint()        {            return new PointF(m_rect.X + m_rect.Width / 2, m_rect.Y + m_rect.Height / 2);                }        /// <summary>        /// ID        /// </summary>        public override Guid guid        {            get { return m_id; }            set { m_id = value; }        }        /// <summary>        /// 颗粒的外边框大小        /// </summary>        public override RectangleF Rect        {            get { return m_rect; }            set { m_rect = value; }        }        /// <summary>        /// OTSPointF        /// </summary>        public override PointF OTSPointF        {            get { return m_OTSPointF; }            set { m_OTSPointF = value; }        }        /// <summary>        /// 颗粒里+号位置的外边框大小        /// </summary>        public RectangleF SmallRect        {            get { return m_small_rect; }            set { m_small_rect = value; }        }        /// <summary>        /// 颗粒是否被选择        /// </summary>        public override bool IsSelect        {            get { return m_isSelected; }            set { m_isSelected = value; }        }        /// <summary>        /// 该颗粒是否被设置成,选中状态        /// </summary>        public PaintState GetPaintState()        {            if (GetDisplayState() == DisplayState.NODISPLAY)            {                m_paintState = PaintState.NOPAINT;            }            return m_paintState;        }        /// <summary>        /// 该颗粒是否被设置成,选中状态        /// </summary>        public void SetPaintState(PaintState value)        { m_paintState = value; }        /// <summary>        /// 是否对该颗粒选定显示X-Ray能谱图        /// </summary>        public ParticleShowXray Operator_ShowXRay        {            get { return m_operator_showxray; }            set { m_operator_showxray = value; }        }           /// <summary>        /// 是否显示x号        /// </summary>        public bool IsShowSmallX        {            get { return m_showSmallx; }            set { m_showSmallx = value; }        }        /// <summary>        /// 颗粒的x-ray的点,是否被选择上了        /// </summary>        public bool IsSelectedSmallRect        {            get { return m_isSelected_smallrect; }            set { m_isSelected_smallrect = value; }        }        /// <summary>        /// 是否在被拖动        /// </summary>        public override bool IsDragging        {            get { return m_isdragging; }            set { m_isdragging = value; }        }        /// <summary>        /// 被拖动到的位置坐标        /// </summary>        public override PointF DraggingPoint        {            get { return m_dragingpoint; }            set { m_dragingpoint = value; }        }        /// <summary>        /// 线的颜色        /// </summary>        public override Color Color        {            get { return m_color; }            set { m_color = value; }        }        /// <summary>        /// 背景色        /// </summary>        public override Color BackColor        {            get { return m_backcolor; }            set { m_backcolor = value; }        }        /// <summary>        /// 多边形的图形路径边缘        /// </summary>        public override GraphicsPath GPath        {            get { return m_gpath; }            set { m_gpath = value; }        }        /// <summary>        /// 里面包含的多个线的集合        /// </summary>        public List<DisplaySegment> DSegments        {            get { return m_listdsegment; }            set { m_listdsegment = value; }        }        /// <summary>        /// 控制多边形在进行缩放到多少倍时进行显示        /// </summary>        public float Zoom_DisPlayThreshold        {            get { return m_zoom_displaymultiplier; }                   }        /// <summary>        /// 设置排序的类型        /// </summary>        public string SortType        {            get { return m_sort_type; }            set { m_sort_type = value; }        }        /// <summary>        /// 设置该多边形的尺寸大小        /// </summary>        public float FSize        {            get { return m_f_size; }            set { m_f_size = value; }        }        /// <summary>        /// 设置粒级        /// </summary>        public string ParticleLJ        {            get { return m_str_lj; }            set { m_str_lj = value; }        }        /// <summary>        /// 设置种类        /// </summary>        public string ParticleZL        {            get { return m_str_klzl; }            set { m_str_klzl = value; }        }        /// <summary>        /// 设置分类        /// </summary>        public string ParticleFL        {            get { return m_str_klfl; }            set { m_str_klfl = value; }        }        /// <summary>        /// 获取或设置该Particle对应底层的FieldID值        /// </summary>        public int FieldId        {            get { return objParticleData.FieldId; }                   }        /// <summary>        /// 获取或设置该Particle对应底层的ParticleID值        /// </summary>        public int ParticleId        {            get { return objParticleData.ParticleId; }                   }        public bool IsDeleted { get => m_isDeleted; set => m_isDeleted = value; }        public bool IsMouseOver { get => m_isMouseOver; set => m_isMouseOver = value; }        public Image GetImage()        {            return m_image;        }        public void SetImage(Image value)        {            m_image = value;        }        public DisplayState GetDisplayState()        {            if (m_isDeleted)            {                m_displayState = DisplayState.NODISPLAY;            }            return m_displayState;        }        public void SetDisplayState(DisplayState value)        {            m_displayState = value;        }        /// <summary>        /// 绘制函数        /// </summary>        /// <param name="e"></param>        public override void OnPaint(PaintEventArgs e)        {            Graphics g = e.Graphics;            //绘制鼠标移动到颗粒上时的边框,需要判断当前鼠标在颗粒上,及颗粒的操作为正常显示            if (m_isMouseOver == true)            {                //如果有鼠标在该矩形上,那么进行描边                ControlPaint.DrawBorder(g,                                    Rectangle.Round(this.Rect),                                    Color.Lime,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.Lime,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.Lime,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.Lime,                                    1,                                    ButtonBorderStyle.Solid);            }                       if (GetPaintState() == PaintState.PAINT)            {                if (m_listdsegment.Count > 0)                {                    DisplaySegment ds = m_listdsegment[0];                    if (ds.ShowMode == SegmentShowMode.DRAWPOINT)                    {                        try                        {                            e.Graphics.DrawImage(m_image, m_rect);                        }                        catch (Exception ex)                        {                            NLog.LogManager.GetCurrentClassLogger().Error(ex.ToString());                        }                    }                    else                    {                        //调用绘制基本线                        foreach (DisplaySegment item in m_listdsegment)                        {                            item.OnPaint(e);                        }                    }                }            }            if (GetPaintState() == PaintState.CONCISEPAINT)            {                g.DrawString("+", new Font("黑体", 6), new SolidBrush(Color.DarkSlateBlue), new PointF(m_small_rect.X, m_small_rect.Y));            }            if (m_isSelected)            {                //如果説该矩形被选择上了的话,那么也显示边框                ControlPaint.DrawBorder(g,                                    Rectangle.Round(this.Rect),                                    Color.Blue,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.Blue,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.Blue,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.Blue,                                    1,                                    ButtonBorderStyle.Solid);            }                        if (ParticleShowXray.SELECTANDDISPLAYXRAY == m_operator_showxray && PaintState.NOPAINT != GetPaintState())            {                //当鼠标在该颗粒上进行点击,则对颗粒状态更改为选定状态,用来显示X-ray能谱表                ControlPaint.DrawBorder(g,                                    Rectangle.Round(this.Rect),                                    Color.DeepSkyBlue,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.DeepSkyBlue,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.DeepSkyBlue,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.DeepSkyBlue,                                    1,                                    ButtonBorderStyle.Solid);            }                  }        /// <summary>        /// 从Line中获取矩形的边缘闭合路径        /// </summary>        /// <returns></returns>        public GraphicsPath GetRegionFromDSegments()        {            GraphicsPath gpath = new GraphicsPath();            List<PointF> list_leftpointf = new List<PointF>();            List<PointF> list_rightpointf = new List<PointF>();            //从y循环,这里假设y轴会按lines集合来计算,然后将所有的左x,和右x取出排成两个队列            foreach (DisplaySegment ds in this.m_listdsegment)            {                list_leftpointf.Add(new PointF(ds.Rect.X, ds.Rect.Y));                list_rightpointf.Add(new PointF(ds.Rect.X + ds.Rect.Width, ds.Rect.Y));            }            PointF[] lsp = new PointF[list_leftpointf.Count + list_rightpointf.Count];            //再将两个x,y点依次添加到闭合路径中            for (int i = 0; i < list_leftpointf.Count(); i++)            {                lsp[i] = list_leftpointf[i];            }            //右节点            for (int i = 0; i < list_rightpointf.Count(); i++)            {                //这边倒着存入                lsp[list_rightpointf.Count() + i] = list_rightpointf[list_rightpointf.Count() - i - 1];            }            //防止从低层拿到无数据的外边路径,在我的程序里却需要计算,而防止程序报死,这里做一下特殊处理。            if (lsp.Count() >= 3)            {                gpath.AddPolygon(lsp);            }            else            {                //有时居然有颗粒,有没有segment的时候,防止报错                if (this.DSegments.Count == 0)                {                    lsp = new PointF[3] { new PointF(0, 0), new PointF(0, 0), new PointF(0, 0) };                    gpath.AddPolygon(lsp);                    return gpath;                }                //有2条数据                if (lsp[1].X != 0 && lsp[1].Y != 0)                {                    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) };                }                //有1条数据                else if (lsp[0].X != 0 && lsp[0].Y != 0)                {                    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) };                }                //剩下的情况                 else                {                    lsp = new PointF[3] { new PointF(0, 0), new PointF(0, 0), new PointF(0,0) };                }                gpath.AddPolygon(lsp);            }            return gpath;        }        /// <summary>        /// 从已经确定的外边框来计算出里面的+号小框位置        /// </summary>        /// <returns></returns>        public RectangleF GetSmallRectangleFromRect()        {            RectangleF rect = new RectangleF();            //用外边框的坐标,除2获得中心点,然后再分别+,- 4            float x = 0, y = 0;            x = m_rect.X + (m_rect.Width / 2);            y = m_rect.Y + (m_rect.Height / 2);            rect.X = x - 4;            rect.Y = y - 4;            rect.Width = 8;            rect.Height = 4;            return rect;        }        /// <summary>        /// 根据该多边形所有包含的线长度,计算出,该多边形的面积大小        /// </summary>        /// <returns></returns>        public float GetAreaFormSegments()        {            float f_size_sum = 0;            foreach (DisplaySegment ls_ds in this.m_listdsegment)            {                f_size_sum = f_size_sum + ls_ds.Rect.Width;            }            return f_size_sum;        }        /// <summary>        /// 从基本线中获取整个矩形的Rectangle        /// </summary>        /// <returns></returns>        public RectangleF GetRectFromDSegment()        {            RectangleF rect = new RectangleF();            float x1 = 0, y1 = 0;            float i_width = 0, i_height = 0;            //先从自身中初始化x,y,和宽,高            if (this.m_listdsegment.Count > 0)            {                x1 = this.m_listdsegment[0].Rect.X;                y1 = this.m_listdsegment[0].Rect.Y;                i_width = x1 + this.m_listdsegment[0].Rect.Width;                i_height = this.m_listdsegment[0].Rect.Y;            }            foreach (DisplaySegment ds in this.m_listdsegment)            {                //分别取出,最小的x,y,                if (ds.Rect.X < x1)                {                    x1 = ds.Rect.X;                }                if (ds.Rect.Y < y1)                {                    y1 = ds.Rect.Y;                }                //最大的x,y                if (ds.Rect.X + ds.Rect.Width > i_width)                {                    i_width = ds.Rect.X + ds.Rect.Width;                }                if (ds.Rect.Y > i_height)                {                    i_height = ds.Rect.Y;                }            }              rect.X = x1 ;            rect.Y = y1 ;            rect.Width = i_width - rect.X ;            rect.Height = i_height - rect.Y ;                    return rect;        }    }   }
 |