123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- using System.Data;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using System.Collections;
- namespace OTSPartA_STDEditor
- {
- public partial class UXrayControl : UserControl
- {
- // 画能谱图的矩形区域
- protected Rectangle m_XrayArea;
- protected PointF[] m_xraypointf = null;
- protected bool m_bShowElementLines = true;
- // 水平刻度分成20等分
- protected const int m_iHscale = 20;
- protected bool m_bMouseMove = false;
- protected Point m_curCurssorPos;
- private DataTable dt = null;
- private DataRow dr = null;
- public DataRow Dr { get => dr; set => dr = value; }
- public DataTable Dt { get => dt; set => dt = value; }
- public UXrayControl()
- {
- InitializeComponent();
-
- // 设置双缓冲
- SetDoubleBufferByIsDraw();
- }
- public void SetDoubleBufferByIsDraw()
- {
- SetStyle(ControlStyles.UserPaint, true);//没什么效果,开与关
- SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景,关了闪
- this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); // 双缓冲,关了闪
- //上面是必须有的
- SetStyle(ControlStyles.UserMouse, true);//执行自己的鼠标行为,这个打开后,在win7下鼠标操作明显改善
- }
- private void UXrayControl_Load(object sender, EventArgs e)
- {
- }
- private void UXrayControl_Resize(object sender, EventArgs e)
- {
- this.RefreshCtrl();
- }
- private void UXrayControl_Paint(object sender, PaintEventArgs e)
- {
- Graphics graphic = e.Graphics;
- DrawSpecture(ref graphic);
- if (m_bMouseMove)
- {
- ShowMouseMoveInfo(m_curCurssorPos.X, m_curCurssorPos.Y, ref m_XrayArea, ref graphic);
- }
- }
- public void RefreshCtrl()
- {
- this.Invalidate();
- Graphics graph = Graphics.FromHwnd(this.Handle);
- DrawSpecture(ref graph);
- m_bMouseMove = false;
- }
- public void DrawSpecture(ref Graphics graph)
- {
- // 设置设置能谱的区域大小
- // 首先预留出刻度的大小
- String strLabel = "9999";
- SizeF size = graph.MeasureString(strLabel, this.Font);
- // 上下左右四顶点预留2个像素空白, 扣除标签的宽高
- // Rectangle XrayArea = new Rectangle();
- m_XrayArea.X = 2 + (int)size.Width;
- m_XrayArea.Y = 2;
- m_XrayArea.Width = this.Width - 2 - m_XrayArea.X;
- m_XrayArea.Height = this.Height - 2 - m_XrayArea.Y - (int)size.Height;
- Pen pen = new Pen(Color.FromArgb(150, Color.Black), 1);
- // 画矩形框
- graph.DrawRectangle(pen, m_XrayArea);
- // 画横坐标刻度
- Point point = new Point();
- Point next = new Point();
- Point adapt = new Point(); // 微调参数
- SolidBrush brush = new SolidBrush(Color.FromArgb(255, Color.Black));
- pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
- for (int i = 0; i < m_iHscale; i++)
- {
- point.X = m_XrayArea.X + i * m_XrayArea.Width / m_iHscale;
- point.Y = m_XrayArea.Y + m_XrayArea.Height;
- // 画横坐标数字刻度
- adapt.X = (i > 9) ? 6 : 4;
- adapt.Y = 2;
- graph.DrawString(Convert.ToString(i), this.Font, brush, new Point(point.X - adapt.X, point.Y + adapt.Y));
- // 画垂直方向刻度
- next.X = point.X;
- next.Y = m_XrayArea.Y;
- pen.Color = Color.FromArgb(70, Color.Black);
- graph.DrawLine(pen, point, next);
- }
- // 画纵坐标的刻度
- int iRows = 0;
- int iMaxValue = 0;
- int iScale = GetYScale(ref iMaxValue);
- iRows = iMaxValue / iScale;
- for (int i = 1; i < iRows; i++)
- {
- point.Y = m_XrayArea.Y + m_XrayArea.Height - i * m_XrayArea.Height / iRows;
- point.X = m_XrayArea.X;
- // 画纵坐标数字刻度
- adapt.X = (i * iScale >= 100) ? 22 : 16;
- adapt.X = (i * iScale >= 1000) ? 28 : adapt.X;
- adapt.Y = 6;
- graph.DrawString(Convert.ToString(iScale * i), this.Font, brush, new Point(point.X - adapt.X, point.Y - adapt.Y));
- // 画水平方向刻度
- next.X = point.X + m_XrayArea.Width;
- next.Y = point.Y;
- graph.DrawLine(pen, point, next);
- }
- // 画能谱数据
- // ShowXray(ref m_XrayArea, iMaxValue, ref graph, m_bShowElementLines);
- ShowXrayClr(ref m_XrayArea, iMaxValue, ref graph, m_bShowElementLines);
- }
- protected void ShowXrayClr(ref Rectangle XrayArea, int iMaxValue, ref Graphics graph, bool bShowElementLines)
- {
- ShowXray( Dr, ref XrayArea, iMaxValue, ref graph);
- if (bShowElementLines)
- {
- // 元素线的高度为能谱图矩形高度一半
- ShowElementLines(Dr, XrayArea.Height / 2, ref XrayArea, ref graph);
- }
- if (null != Dr)
- {
- int iDelt = 0;
- SizeF size = graph.MeasureString("Test", this.Font);
- for (int i = 0; i < 1; i++)
- {
- //DataRow dr = Dt.Rows[i];
- ShowXray(Dr, ref XrayArea, iMaxValue, ref graph, true);
- if (bShowElementLines)
- {
- iDelt = (0 == i % 2) ? (-i - 1) * (int)size.Height : i * (int)size.Height;
- ShowElementLines(dr, iDelt + XrayArea.Height / 2, ref XrayArea, ref graph);
- }
- }
- }
- }
- protected int[] bytesToInt(byte[] src, int offset)
- {
- int[] values = new int[src.Length / 4];
- for (int i = 0; i < values.Length; i++)
- {
- values[i] = BitConverter.ToInt32(src, offset);
- offset += 4;
- }
- return values;
- }
- public void ShowXray(DataRow dr, ref Rectangle XrayArea, int iMaxValue, ref Graphics graph, bool bComp = false)
- {
- if (null != dr)
- {
- int[] SPEC= bytesToInt((byte[])dr["SPEC"], 0);
- int iXrayDataLen = SPEC.Length;
- if (null == m_xraypointf)
- {
- m_xraypointf = new PointF[iXrayDataLen];
- }
- for (int i = 0; i < iXrayDataLen; i++)
- {
- m_xraypointf[i].X = XrayArea.X + i * XrayArea.Width / iXrayDataLen;
- m_xraypointf[i].Y = XrayArea.Y + XrayArea.Height - SPEC[i] * XrayArea.Height / iMaxValue;
- }
- int ColorValue = 0;
- if (!dr["Color"].ToString().Equals(""))
- {
- ColorValue = Convert.ToInt32(dr["Color"]);
- }
- if (bComp)
- {
- Pen pen = new Pen(Color.FromArgb(150, Color.FromArgb(ColorValue % 256, (ColorValue >> 8) % 256, (ColorValue >> 16) % 256)), 1);
- graph.DrawPolygon(pen, m_xraypointf);
- }
- else
- {
- SolidBrush brush = new SolidBrush(Color.FromArgb(150, Color.FromArgb(ColorValue % 256, (ColorValue >> 8) % 256, (ColorValue >> 16) % 256)));
- graph.FillPolygon(brush, m_xraypointf);
- }
- }
- }
- protected void ShowElementLines(DataRow dr, int iLineHeight, ref Rectangle XrayArea, ref Graphics graph)
- {
- if (null == dr)
- {
- return;
- }
- //double dEnergy = 0;
- String str = "Test";
- SizeF size = graph.MeasureString(str, this.Font);
- // 判断元素线高度的合法性
- iLineHeight = (iLineHeight > size.Height) ? iLineHeight : (int)size.Height;
- iLineHeight = ((iLineHeight + (int)size.Height) > XrayArea.Height) ? (XrayArea.Height - (int)size.Height) : iLineHeight;
- //PointF point = new PointF();
- //PointF next = new PointF();
- //RectangleF rect = new RectangleF();
- Pen pen = new Pen(Color.FromArgb(255, 150, 100, 50), 1);
- int ColorValue = 0;
- if (!dr["Color"].ToString().Equals(""))
- {
- ColorValue = Convert.ToInt32(dr["Color"]);
- }
- SolidBrush brush = new SolidBrush(Color.FromArgb(255, Color.FromArgb(ColorValue % 256, (ColorValue >> 8) % 256, (ColorValue >> 16) % 256)));
- //for (int i = 0; i < 1; i++)
- //{
- // //CElementClr elementclr = stdmineralclr.GetElement(i);
- // str = "0";//elementclr.GetName();
- // size = graph.MeasureString(str, this.Font);
- // dEnergy = 2.3;//elementclr.GetEnergyValueK();
- // point.X = XrayArea.X + (float)dEnergy * XrayArea.Width / m_iHscale;
- // point.Y = XrayArea.Y + XrayArea.Height;
- // next.X = point.X;
- // next.Y = (0 == i % 2) ? (point.Y - iLineHeight) : (point.Y - iLineHeight + 2 + (int)size.Height);
- // // 画线
- // graph.DrawLine(pen, point, next);
- // // 画矩形框
- // rect.X = next.X - size.Width / 2;
- // rect.Y = next.Y - size.Height;
- // rect.Width = size.Width;
- // rect.Height = size.Height;
- // brush.Color = Color.FromArgb(255, Color.FromArgb(ColorValue % 256, (ColorValue >> 8) % 256, (ColorValue >> 16) % 256));
- // graph.FillRectangle(brush, rect);
- // // 画字符串
- // brush.Color = Color.FromArgb(255, Color.Black);
- // graph.DrawString(str, this.Font, brush, rect.X, rect.Y);
- //}
- }
- protected void ShowMouseMoveInfo(int ix, int iy, ref Rectangle XrayArea, ref Graphics graph)
- {
- // 判断坐标是否在矩形框区域内, 如果不在, 则退出
- if (ix < XrayArea.X ||
- ix > XrayArea.X + XrayArea.Width ||
- iy < XrayArea.Y ||
- iy > XrayArea.Y + XrayArea.Height)
- {
- return;
- }
- float fpos = 0;
- PointF point = new PointF();
- PointF next = new PointF();
- Pen pen = new Pen(Color.FromArgb(150, Color.Black), 1);
- SolidBrush brush = new SolidBrush(Color.FromArgb(255, Color.FromArgb(255, 0, 0)));
- fpos = (ix - XrayArea.X) * m_iHscale / (float)XrayArea.Width;
- SizeF size = graph.MeasureString(fpos.ToString(), this.Font);
- // 画竖线
- point.X = ix;
- point.Y = XrayArea.Y + XrayArea.Height;
- next.X = point.X;
- next.Y = XrayArea.Y + (int)size.Height;
- graph.DrawLine(pen, point, next);
- // 显示坐标位置
- graph.DrawString(fpos.ToString(), this.Font, brush, ix - (int)(size.Width / 2), XrayArea.Y+20);
- // 获取当前位置的元素
- // List<String> liststr = CElement.GetAllElementsEnergy(fpos, 0.1f);
- List<String> liststr = new List<string>();
- //CElementClr.GetAllElementsEnergyK(fpos, 0.1f, ref liststr);
- brush.Color = Color.FromArgb(255, Color.Blue);
- for (int i = 0; i < liststr.Count; i++)
- {
- size = graph.MeasureString(liststr[i], this.Font);
- point.X = ('-' == liststr[i][0]) ? (ix - (size.Width + 2)) : ix;
- point.Y = (XrayArea.Y + size.Height) + i * (size.Height + 2);
- graph.DrawString(liststr[i], this.Font, brush, point.X, point.Y);
- }
- }
-
- public void SetElementLines(bool bShowElementLines)
- {
- m_bShowElementLines = bShowElementLines;
- }
-
- protected override void OnMouseMove(MouseEventArgs e)
- {
- //// if (null == m_CurSelMineral &&
- //// (null == m_ListCompMineral ||
- //// 0 == m_ListCompMineral.Count()))
- //if (null == m_CurSelSTDMineralClr &&
- // (null == m_ListCompMineralClr ||
- // 0 == m_ListCompMineralClr.Count()))
- //{
- // return;
- //}
- m_bMouseMove = true;
- m_curCurssorPos.X = e.X;
- m_curCurssorPos.Y = e.Y;
- this.Invalidate();
- // this.OnPaint(new PaintEventArgs(this.CreateGraphics(), new Rectangle(new Point(0, 0), this.Size)));
- }
- // 返回值是刻度的精度, iRows表示行数
- protected int GetYScale(ref int iMaxValue)
- {
- int iMaxXray = 0;
- int iMaxXray1 = 0;
- int iMaxXray2 = 0;
- int iBaseScale = 20; // 最小基础刻度20
- int iScale = 20; // 待返回的刻度值
- int iBaseMaxValue = 100; // 基础最大值100
- int iTimes = 0;
- int iLeft = 0;
- iMaxXray1 = GetMaxXray(Dr);
- iMaxXray2 = 0;//GetMaxXrayClr();
- iMaxXray = (iMaxXray1 > iMaxXray2) ? iMaxXray1 : iMaxXray2;
- // 设计需求: 0 <= iMaxXray < 500(iScale: 50, iMaxValue: 250或者500)
- // 设计需求: 500 <= iMaxXray < 1000(iScale: 100, iMaxValue: 750或者1000)
- // 设计需求: 1000 <= iMaxXray < 1500(iScale: 150, iMaxValue: 1250或者1500)
- // 设计需求: 1500 <= iMaxXray < 2000(iScale: 200, iMaxValue: 1750或者2000)
- // 以此类推
- // iMaxXray = 9000;// 测试代码, 可以删除
- iTimes = iMaxXray / iBaseMaxValue;
- iLeft = iMaxXray % iBaseMaxValue;
- iScale = iBaseScale + iBaseScale * (iTimes / 2);
- iMaxValue = iBaseMaxValue + iBaseMaxValue * iTimes;
- // 因为iScale * (iMaxValue / iScale) <= iMaxValue, 所以如果 iMaxXray > iScale * (iMaxValue / iScale) 刻度就会不够,导致bug
- if (iScale * (iMaxValue / iScale) < iMaxXray)
- {
- iMaxValue = iMaxValue + iBaseMaxValue;
- }
- return iScale;
- }
- protected int GetMaxXray(DataRow dr)
- {
- if (null == dr)
- {
- return 0;
- }
- int iMaxXray = 0;
- int iXrayLen = 0;
- int[] SPEC = bytesToInt((byte[])dr["SPEC"], 0);
- iXrayLen = SPEC.Length;
- for (int i = 0; i < iXrayLen; i++)
- {
- if (SPEC[i] > iMaxXray)
- {
- iMaxXray = SPEC[i];
- }
- }
- return iMaxXray;
- }
- protected int GetMaxXrayClr()
- {
- if (null == Dr)
- {
- return 0;
- }
- int iMaxXray = 0;
- int iXray = 0;
- for (int i = 0; i < Dt.Rows.Count; i++)
- {
- DataRow dr = Dt.Rows[i];
- iXray = GetMaxXray(dr);
- if (iXray > iMaxXray)
- {
- iMaxXray = iXray;
- }
- }
- return iMaxXray;
- }
- }
- }
|