You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

641 lines
20 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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轴几等分
/// <summary>
/// 中间值
/// </summary>
private int Xmid
{
get
{
return _xduan / 2 - 1;
}
}
List<pvalue> m_pvalues = new List<pvalue>(); // value array
//List<pvalue> m_pxvalues = new List<pvalue>();
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
/// <summary>
/// 标题
/// </summary>
///
[Description("图表标题"), Category("曲线")]
public string Title
{
set { strTitle = value; this.Invalidate(); }
get { return strTitle; }
}
#endregion
#region TextColor
/// <summary>
/// 文字颜色
/// </summary>
///
private Color clrTextColor = Color.Green;
[Description("数字和文本的颜色"), Category("曲线文本")]
public Color TextColor
{
set { clrTextColor = value; this.Invalidate(); }
get { return clrTextColor; }
}
#endregion
#region AxisColor
/// <summary>
/// 轴线颜色
/// </summary>
///
private Color clrAxisColor = Color.Black;
[Description("坐标系的颜色"), Category("曲线")]
public Color AxisColor
{
set { clrAxisColor = value; this.Invalidate(); }
get { return clrAxisColor; }
}
#endregion
#region CurveColor
/// <summary>
/// 曲线颜色
/// </summary>
///
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
/// <summary>
/// 字体大小号数
/// </summary>
///
private int intFontSize = 9;
[Description("数字和文本的字号"), Category("曲线文本")]
public int FontSize
{
get { return intFontSize; }
set { intFontSize = value; this.Invalidate(); }
}
#endregion
#region CurveSize
/// <summary>
/// 曲线线条大小
/// </summary>
///
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;
}
}
}