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;
}
}
}