using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Drawing.Drawing2D; namespace Mesnac.Controls.Compressor { [ToolboxBitmap(typeof(CompressorCurve), "ICONS.Curve.bmp")] public partial class CompressorCurve : Control { #region 初始化 public CompressorCurve() { InitializeComponent(); SetStyle(ControlStyles.UserPaint | ControlStyles.DoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint | ControlStyles.SupportsTransparentBackColor, true); this.Size = new Size(200, 180); } private int _xPointCount = 200; private int _xduan = 10;//x轴几等分 /// /// 中间值 /// private int Xmid { get { return _xduan / 2 - 1; } } List m_pvalues = new List(); // value array //List m_pxvalues = new List(); private string strTitle = "曲线图"; //标题 private Color clrAxisTextColor = Color.Black; //轴说明文字颜色 private Color clrSliceTextColor = Color.Black; //刻度文字颜色 private int _MaXValue = 200; private int _MaxPoint = 2000;//最大保留点数 public class pvalue { public pvalue() { time = DateTime.Now; } public float xvalue { get; set; } public float yvalue { get; set; } public DateTime time { get; set; } } #endregion #region 公共属性 #region mFont private Font _font = null; [Description("文本字体"), Category("曲线文本")] public Font mFont { get { return _font; } set { _font = value; this.Invalidate(); } } #endregion #region MaxValue [Description("Y轴最大值"), Category("曲线")] public int MaxValue { set { _MaXValue = value; this.Invalidate(); } get { return _MaXValue; } } #endregion #region _YWarnMaxLine [Description("Y轴报警上限值"), Category("曲线")] private int _YWarnMaxLine = 0; public int YWarnMaxLine { set { _YWarnMaxLine = value; this.Invalidate(); } get { return _YWarnMaxLine; } } #endregion #region _YWarnLimiLine [Description("Y轴报警下限值"), Category("曲线")] private int _YWarnLimiLine = 0; public int YWarnLimiLine { set { _YWarnLimiLine = value; this.Invalidate(); } get { return _YWarnLimiLine; } } #endregion #region _XWarnMaxLine [Description("Y轴报警上限值"), Category("曲线")] private int _XWarnMaxLine = 0; public int XWarnMaxLine { set { _XWarnMaxLine = value; this.Invalidate(); } get { return _XWarnMaxLine; } } #endregion #region _XWarnLimiLine [Description("Y轴报警下限值"), Category("曲线")] private int _XWarnLimiLine = 0; public int XWarnLimiLine { set { _XWarnLimiLine = value; this.Invalidate(); } get { return _XWarnLimiLine; } } #endregion #region xPointCount [Description("X轴最大值"), Category("曲线")] public int xPointCount { set { _xPointCount = value; this.Invalidate(); } get { return _xPointCount; } } #endregion #region CurrentValue private object[] _CurrentValue =new object[4]; public object[] CurrentValue { set { _CurrentValue = value; } get { return _CurrentValue; } } #endregion #region CurrentXYValue private pvalue _CurrentXYValue =new pvalue(); public pvalue CurrentXYValue { set { _CurrentXYValue = value; } get { return _CurrentXYValue; } } #endregion #region sName private string _sName = "CurveName"; [Description("曲线名称"), Category("曲线")] public string sName { set { _sName = value; this.Invalidate(); } get { return _sName; } } #endregion #region Title /// /// 标题 /// /// [Description("图表标题"), Category("曲线")] public string Title { set { strTitle = value; this.Invalidate(); } get { return strTitle; } } #endregion #region TextColor /// /// 文字颜色 /// /// private Color clrTextColor = Color.Green; [Description("数字和文本的颜色"), Category("曲线文本")] public Color TextColor { set { clrTextColor = value; this.Invalidate(); } get { return clrTextColor; } } #endregion #region AxisColor /// /// 轴线颜色 /// /// private Color clrAxisColor = Color.Black; [Description("坐标系的颜色"), Category("曲线")] public Color AxisColor { set { clrAxisColor = value; this.Invalidate(); } get { return clrAxisColor; } } #endregion #region CurveColor /// /// 曲线颜色 /// /// private Color clrsCurveColors = Color.Red; [Description("曲线颜色"), Category("曲线")] public Color CurveColor { set { clrsCurveColors = value; this.Invalidate(); } get { return clrsCurveColors; } } #endregion #region DashStyle private DashStyle _dashStyle = DashStyle.Solid; [Description("边框风格"), Category("边框")] public DashStyle DashStyle { get { return _dashStyle; } set { _dashStyle = value; this.Invalidate(); } } #endregion #region LineStyle private DashStyle _LineStyle = DashStyle.Solid; [Description("曲线风格"), Category("曲线")] public DashStyle LineStyle { get { return _LineStyle; } set { _LineStyle = value; this.Invalidate(); } } #endregion #region FontSize /// /// 字体大小号数 /// /// private int intFontSize = 9; [Description("数字和文本的字号"), Category("曲线文本")] public int FontSize { get { return intFontSize; } set { intFontSize = value; this.Invalidate(); } } #endregion #region CurveSize /// /// 曲线线条大小 /// /// private int intCurveSize = 1; [Description("曲线线宽"), Category("曲线")] public int CurveSize { get { return intCurveSize; } set { intCurveSize = value; this.Invalidate(); } } #endregion #region LineColor // //line style private Color _LineColor = Color.Black; [Description("边框颜色"), Category("边框")] public Color LineColor { get { return _LineColor; } set { _LineColor = value; this.Invalidate(); } } #endregion #region LineWidth private int _LineWidth = 2; [Description("边框线宽"), Category("边框")] public int LineWidth { get { return _LineWidth; } set { _LineWidth = value; this.Invalidate(); } } #endregion #region LineAlpha private int _LineAlpha = 255; [Description("边框线色透明值0~255"), Category("边框")] public int LineAlpha { get { return _LineAlpha; } set { _LineAlpha = value; this.Invalidate(); } } #endregion #region bHaveAction //action setup private bool _bHaveAction = false; public bool bHaveAction { get { return _bHaveAction; } set { _bHaveAction = value; } } #endregion #region ScaleName private string _scalename = null; public string ScaleName { get { return _scalename; } set { _scalename = value; } } #endregion #endregion #region PointValue private void AddPoint(object[] xy) { float flXvalue = 0; float flYvalue = 0; if (xy.Length > 1) { flXvalue = convertTofloat(xy); //this.Text = flvalue.ToString(); } if (xy.Length > 3) { object[] objecty=new object[2]; objecty[0] = xy[2]; objecty[1] = xy[3]; flYvalue = convertTofloat(objecty); } CurrentValue = xy; pvalue p = new pvalue(); p.xvalue = flXvalue; p.yvalue = flYvalue; CurrentXYValue = p; ICSharpCode.Core.LoggingService.Debug("添加点,x:" + p.xvalue + " Y:"+p.yvalue); m_pvalues.Add(p); if (m_pvalues.Count > _MaxPoint) { m_pvalues.RemoveAt(0); } if (flYvalue < 0) { m_pvalues.Clear(); } this.Refresh(); } private string _PointName = null; public string PointName { get { return _PointName; } set { _PointName = value; } } public object PointValue { set { object[] objectarray; try { if (!TryObject(value, out objectarray)) { ICSharpCode.Core.LoggingService.Debug("数组转换错误" +value.ToString()); return; } AddPoint(objectarray); } catch(Exception e) { ICSharpCode.Core.LoggingService.Debug("添加点失败" + e.ToString()); } } get { return CurrentValue; } } private bool TryObject(object value, out object[] arry) { arry = null; try { arry = (object[])value; return true; } catch { return false; } } #endregion protected override void OnPaint(PaintEventArgs pe) { // TODO: 在此处添加自定义绘制代码 #region 初始化基础表格 Graphics g = pe.Graphics; GraphicsPath path = new GraphicsPath(); Rectangle rect = new Rectangle(new Point(0, 0), new Size(this.ClientSize.Width, this.ClientSize.Height)); path.AddRectangle(rect); Pen pen = null; pen = new Pen(Color.FromArgb(LineAlpha, LineColor)); pen.Width = LineWidth; pen.DashStyle = DashStyle; g.DrawPath(pen, path); if (pen != null) { pen.Dispose(); } path.Dispose(); //draw cordniate if (_font == null) { _font = new Font("宋体", FontSize, FontStyle.Regular); } SolidBrush b1 = new SolidBrush(clrAxisColor); Pen b2 = new Pen(AxisColor, 1); #region Y轴网格线 for (int j = 0; j < 5; j++)//-2 3 { int i; double slice = ((double)j * MaxValue / 4); if (slice != 0) { g.DrawString(slice.ToString(), _font, b1, rect.Left, rect.Top + rect.Height - (j + 1) * rect.Height / 6); } for (i = 0; i < 60; i += 2) { float fltX1 = rect.Left + rect.Width * i / 60; float fltY1 = rect.Top + rect.Height - (j + 1) * rect.Height / 6; float fltX2 = rect.Left+ rect.Width * (i + 1) / 60; float fltY2 = rect.Top + rect.Height - (j + 1) * rect.Height / 6; g.DrawLine(b2, fltX1, fltY1, fltX2, fltY2); } } #endregion #region X轴网格线 for (int j = 0; j <9; j++) { int i; double slice = ((double)(j - Xmid) * _xPointCount / Xmid); g.DrawString(slice.ToString(), _font, b1, rect.Left + (j + 1) * rect.Width / _xduan - slice.ToString().Length*5, rect.Top + rect.Height / 6 * 5 + 2); if (j == Xmid) { for (i = 1; i < 30; i += 2) { float fltX1 = rect.Left + rect.Width / 2; float fltY1 = rect.Top + rect.Height - rect.Height / 6 - 9 * rect.Height * i / 300; float fltX2 = rect.Left + rect.Width / 2; float fltY2 = rect.Top + rect.Height - rect.Height / 6 - 9 * rect.Height * (i + 1) / 300; g.DrawLine(b2, fltX1, fltY1, fltX2, fltY2); } } else { float fltX1 = rect.Left + (j + 1) * rect.Width / _xduan; float fltY1 = rect.Top + rect.Height - rect.Height / 6 ; float fltX2 = rect.Left + (j + 1) * rect.Width / _xduan; float fltY2 = rect.Top + rect.Height - rect.Height / 6 - 9 * rect.Height / 500; g.DrawLine(b2, fltX1, fltY1, fltX2, fltY2); } } #endregion #region 报警线 //y轴 using (Pen b4 = new Pen(Color.Red, 3)) { //报警上限 float warnLine = rect.Top + rect.Height - _YWarnMaxLine * rect.Height / 6 * 4/MaxValue - rect.Height / 6; float fltX1 = rect.Left; float fltY1 = warnLine; float fltX2 = rect.Left + rect.Width; float fltY2 = warnLine; g.DrawLine(b4, fltX1, fltY1, fltX2, fltY2); //报警下限 warnLine = rect.Top + rect.Height - _YWarnLimiLine * rect.Height / 6 * 4 / MaxValue - rect.Height / 6; fltX1 = rect.Left; fltY1 = warnLine; fltX2 = rect.Left + rect.Width; fltY2 = warnLine; g.DrawLine(b4, fltX1, fltY1, fltX2, fltY2); } //x轴 #endregion SolidBrush sb = new SolidBrush(clrTextColor); //Font ft = new Font("宋体", FontSize); g.DrawString(strTitle, _font, sb, rect.Width / 2 + strTitle.Length, rect.Top + 15); g.DrawString("压力: " +CurrentXYValue.yvalue.ToString()+"Kg 位移:"+ CurrentXYValue.xvalue.ToString() + "mm" , _font, sb, rect.Left + 5, rect.Top + 15); g.DrawString("曲线名称: " + sName, _font, sb, rect.Left + 5, rect.Bottom - 20); #endregion #region 曲线值 //draw curve float maxheight = MaxValue; float widthsegment = (float)(rect.Width * 0.9) / _xPointCount; Pen b3 = new Pen(clrsCurveColors, intCurveSize); b3.DashStyle = LineStyle; #region 测试 //m_pvalues.Clear(); //pvalue canshu0 = new pvalue(); //canshu0.xvalue = 20; //canshu0.yvalue = 20; //m_pvalues.Add(canshu0); //pvalue canshu1 = new pvalue(); //canshu1.xvalue = 200; //canshu1.yvalue = Convert.ToSingle(1120.33); //m_pvalues.Add(canshu1); //pvalue canshu2 = new pvalue(); //canshu2.xvalue = Convert.ToSingle(115.33); //canshu2.yvalue = 100; //m_pvalues.Add(canshu2); //pvalue canshu3 = new pvalue(); //canshu3.xvalue = 110; //canshu3.yvalue = Convert.ToSingle(920.33); //m_pvalues.Add(canshu3); //pvalue canshu4 = new pvalue(); //canshu4.xvalue = 50; //canshu4.yvalue = Convert.ToSingle(520.33); //m_pvalues.Add(canshu4); #endregion if (m_pvalues.Count>1) { float fltX1 = Xpostion(m_pvalues[0].xvalue, rect); float fltY1 = Yposition(m_pvalues[0].yvalue, rect); for (int i = 1; i < m_pvalues.Count; i++) { float fltX2 = Xpostion(m_pvalues[i].xvalue,rect); float fltY2 = Yposition(m_pvalues[i].yvalue, rect); //ICSharpCode.Core.LoggingService.Debug("画第" + i.ToString() + "点 X:" + fltX2.ToString() + " Y:" + fltY2.ToString()); g.DrawLine(b3, fltX1, fltY1, fltX2, fltY2); fltX1 = fltX2; fltY1 = fltY2; //if ((i + 1) % 2 == 0 && i > 0) //{ // //g.DrawLine(b2, fltX2, rect.Top + 1 * rect.Height / 6, fltX2, rect.Top + 5 * rect.Height / 6); // g.DrawString(m_pvalues[i].xvalue.ToString(), _font, sb, fltX2 - 16, rect.Top + 5 * rect.Height / 6); //} } } b1.Dispose(); b2.Dispose(); b3.Dispose(); sb.Dispose(); #endregion // 调用基类 OnPaint base.OnPaint(pe); } private float Xpostion(float value, Rectangle rect) { return rect.Width / 2 + value * (rect.Width / _xduan * (_xduan - 2)) / (xPointCount * 2); } private float Yposition(float value, Rectangle rect) { return rect.Top + rect.Height - value * rect.Height / 6 * 4 / MaxValue - rect.Height / 6; } private float convertTofloat(object[] buff) { int flag = 1; int b = Convert.ToInt32(buff[0]); int a = Convert.ToInt32(buff[1]); if (a >= 32768) { a = a - 32768; flag = -1; } byte[] low = System.BitConverter.GetBytes(b); byte[] high = System.BitConverter.GetBytes(a); byte[] abc = new byte[4]; for (int i = 0; i < 2; i++) { abc[i] = low[i]; } for (int i = 0; i < 2; i++) { abc[i + 2] = high[i]; } float result = BitConverter.ToSingle(abc, 0); return result * flag; } private Object[] floatToObject(float ff) { //正负符号,默认为0 byte flag = 0; if (ff < 0) { flag = 128; ff = ff * -1; } byte[] floatByte = BitConverter.GetBytes(ff); byte[] lowhByte = new byte[4]; lowhByte[0] = floatByte[0]; lowhByte[1] = floatByte[1]; lowhByte[2] = 0; lowhByte[3] = 0; byte[] highByte = new byte[4]; highByte[0] = floatByte[2]; highByte[1] = floatByte[3]; highByte[2] = 0; highByte[3] = 0; highByte[1] = (byte)(highByte[1] + flag); UInt32 low = BitConverter.ToUInt32(lowhByte, 0); int high = BitConverter.ToInt16(highByte, 0); object[] buff = new object[2]; buff[0] = low; buff[1] = high; return buff; } } }