using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace wsControls
{
#region [ Classs ] wsPlot
public class wsPlot
{
//public static void DrawArc(Graphics g, Pen pen, PointF center, decimal radius, decimal startangle, decimal sweepangle)
//{
// decimal x = center.X - radius;
// decimal y = center.Y - radius;
// decimal w = radius + radius;
// decimal h = w;
// decimal start = (decimal)(startangle * Math.PI / 180);
// decimal sweep = (decimal)(sweepangle * Math.PI / 180);
// g.DrawArc(pen, x, y, w, h, start, sweep);
//}
public static void DrawConnection(Graphics g, Pen pen, float x1, float y1, float x2, float y2, float radius)
{
int offset = (int)pen.Width % 2 > 0 ? 0 : 1;
float xn, yn;
if (y2 > y1&&x2>x1)
{
yn = y2 - radius;
g.DrawLine(pen, x1, y1, x1, yn+offset);//|
g.DrawArc(pen, x1 - offset, yn - radius, radius + radius, radius + radius, 90, 90);//|_
xn = x1 + radius;
g.DrawLine(pen, x2, y2,xn - offset, y2);// _
}
else if (y2 < y1 && x2 > x1)
{
xn = x2 - radius;
yn = y1 - radius;
g.DrawLine(pen, x1, y1, xn, y1 + offset);//|
g.DrawArc(pen, xn-radius, y1-radius-radius, radius + radius, radius + radius, 90, -90);//|_|
g.DrawLine(pen, x2, y2, x2, yn+offset);// _
}
else if (y2 < y1 && x2 < x1)
{
xn = x1 - radius;
yn = y2 + radius;
g.DrawLine(pen, x1, yn - offset,x1, y1);//|
g.DrawArc(pen, xn - radius, y2, radius + radius, radius + radius, -90, 90);//|_|
g.DrawLine(pen, x2, y2, xn + offset, y2);// _
}
else if (y2 > y1 && x2 < x1)
{
xn = x2 + radius;
yn = y1 + radius;
g.DrawLine(pen, xn-offset, y1,x1, y1);//|
g.DrawArc(pen, x2, y1, radius + radius, radius + radius, 180, 90);//|_|
g.DrawLine(pen, x2, y2,x2, yn-offset);// _
}
}
float dx, dy;
float Pxmin, Pxmax;
float Pymin, Pymax;
public double[] Fi;
public float[] posx;
#region [ Property ] Width. Height
public int Width { get; set; }
public int Height { get; set; }
#endregion
public wsPlot(int width, int height, wsPlotProperty property)
{
ReSize(width, height, property);
}
#region [ Function ] Resize
public void ReSize(int width, int height, wsPlotProperty property)
{
Width = width;
Height = height;
Pxmin = property.LeftSpace;
Pxmax = width - property.RightSpace;
dx = (Pxmax - Pxmin) / 10f;
Pymin = property.TopSpace;
Pymax = height - property.BottomSpace;
dy = (Pymax - Pymin) / property.Ydiv;
}
#endregion
#region [ Function ] DrawBackground -- Grid & Text
public void DrawBackground(Graphics g, wsPlotProperty property)
{
DrawGrid(g, property);
UpdateText(g, property);
}
private void DrawGrid(Graphics g, wsPlotProperty property)
{
g.Clear(property.BackColor);
Pen gridpen = new Pen(property.GridColor);
float Px, Py;
for (int i = 0; i < 11; i++)
{
Px = (float)(Pxmin + i * dx);
g.DrawLine(gridpen, new PointF(Px, Pymin), new PointF(Px, Pymax));
}
for (int i = 0; i <= property.Ydiv; i++)
{
Py = Pymin + i * dy;
g.DrawLine(gridpen, new PointF(Pxmin, Py), new PointF(Pxmax, Py));
}
}
public string Format = "N2";
private void UpdateText(Graphics g, wsPlotProperty property)
{
Brush brush = new SolidBrush(property.ForeColor);
Font font = property.TitleFont;
//Title...
SizeF sf = g.MeasureString(property.Title, font);
g.DrawString(property.Title, font, brush,
new PointF((this.Width - sf.Width) / 2f, (Pymin - sf.Height) / 2F));
//Label Y...
font = property.Font;
sf = g.MeasureString(property.yLabel, font);
g.DrawString(property.yLabel, font, brush,
new PointF(Pxmin, (Pymin - 1 - sf.Height)));
//Label X...
sf = g.MeasureString(property.xLabel, font);
g.DrawString(property.xLabel, font, brush,
new PointF(Pxmin + 5*dx - sf.Width / 2f, Pymax + 1));
//X Scale...
string V = property.xMin.ToString(Format);
g.DrawString(V, font, brush, new PointF(Pxmin, Pymax + 1));
V = property.xMax.ToString(Format);
sf = g.MeasureString(V, font);
g.DrawString(V, font, brush, new PointF(Pxmax - sf.Width, Pymax + 1));
//Y Scale...
for (int i = 0; i <= property.Ydiv; i++)
{
V = (property.Refer - i * property.Scale).ToString(Format);
sf = g.MeasureString(V, font);
g.DrawString(V, font, brush,
new PointF(Pxmin - 1 - sf.Width, Pymin - sf.Height / 2 + i * dy));
}
brush.Dispose();
}
#endregion
#region [ Function ] Update Frequency & Position
public float[] GetPositionX(decimal[] f, wsPlotProperty property)
{
int ilength = f.Length;
float[] pos = new float[ilength];
decimal k =(decimal) dx * 10 / (property.xMax - property.xMin);
for (int i = 0; i < ilength; i++)
pos[i] = Pxmin + (float)((f[i] - property.xMin) * k);
return pos;
}
public float[] GetPositionX(int N, wsPlotProperty property)
{
int ilength = N;
float[] pos = new float[ilength];
decimal k = (decimal)dx * 10 / (ilength - 1);
for (int i = 0; i < ilength; i++)
pos[i] = Pxmin + (float)(i * k);
return pos;
}
#endregion
#region [ Function ] Add Trace
public PointF[] AddTrace(Graphics g, decimal[] data, Color color, string name, wsPlotProperty property)
{
PointF[] path = AddTrace(g, data, color, property);
//Trace name
SizeF sf = g.MeasureString(name, property.Font);
g.DrawString(name, property.Font, new SolidBrush(color), new PointF(Pxmax + 1, path[path.Length - 1].Y - sf.Height / 2));
return path;
}
public PointF[] AddTrace(Graphics g, decimal[] data, Color color, wsPlotProperty property)
{
decimal ymin = property.Refer - property.Ydiv * property.Scale;
int length = data.Length;
PointF[] path = new PointF[length];
for (int i = 0; i < length; i++)
{
path[i].X =(float) posx[i];
path[i].Y = Pymax - (float)((data[i] - ymin) *(decimal) dy / property.Scale);
if (path[i].Y < Pymin)
path[i].Y = Pymin;
else if (path[i].Y > Pymax)
path[i].Y = Pymax;
}
g.DrawLines(new Pen(color, 1F), path);
return path;
}
public PointF[] AddTrace(Graphics g, decimal[] data, Color color, wsPlotProperty property, int istart, int istop)
{
decimal ymin = property.Refer - property.Ydiv * property.Scale;
int length = istop - istart + 1;
PointF[] path = new PointF[length];
for (int i = 0; i < length; i++)
{
path[i].X = (float)posx[i];
path[i].Y = Pymax - (float)((data[i+istart] - ymin) * (decimal)dy / property.Scale);
if (path[i].Y < Pymin)
path[i].Y = Pymin;
else if (path[i].Y > Pymax)
path[i].Y = Pymax;
}
g.DrawLines(new Pen(color, 1F), path);
return path;
}
public PointF[] AddTrace(Graphics g, Collection<decimal>data, Color color, wsPlotProperty property)
{
decimal ymin = property.Refer - property.Ydiv * property.Scale;
int length = data.Count;
PointF[] path = new PointF[length];
for (int i = 0; i < length; i++)
{
path[i].X = (float)posx[i];
path[i].Y = Pymax - (float)((data[i] - ymin) * (decimal)dy / property.Scale);
if (path[i].Y < Pymin)
path[i].Y = Pymin;
else if (path[i].Y > Pymax)
path[i].Y = Pymax;
}
g.DrawLines(new Pen(color, 1F), path);
return path;
}
public PointF[] AddTrace(Graphics g, Collection<decimal> data, Color color, wsPlotProperty property, int istart, int istop)
{
decimal ymin = property.Refer - property.Ydiv * property.Scale;
int length = istop - istart + 1;
PointF[] path = new PointF[length];
for (int i = 0; i <length; i++)
{
path[i].X = (float)posx[i];
path[i].Y = Pymax - (float)((data[i+istart] - ymin) * (decimal)dy / property.Scale);
if (path[i].Y < Pymin)
path[i].Y = Pymin;
else if (path[i].Y > Pymax)
path[i].Y = Pymax;
}
g.DrawLines(new Pen(color, 1F), path);
return path;
}
public PointF[] AddTrace(Graphics g, decimal[] Fi, decimal[] data, Color color, wsPlotProperty property)
{
posx = GetPositionX(Fi, property);
int length = data.Length;
decimal ymin = property.Refer - property.Ydiv * property.Scale;
PointF[] path = new PointF[length];
for (int i = 0; i < length; i++)
{
path[i].X = posx[i];
path[i].Y = Pymax - (float)((data[i] - ymin) *(decimal) dy / property.Scale);
if (path[i].Y < Pymin)
path[i].Y = Pymin;
else if (path[i].Y > Pymax)
path[i].Y = Pymax;
}
g.DrawLines(new Pen(color, 1F), path);
return path;
}
#endregion
#region [ Function ] Add Marker
public void AddMarker(Graphics g, wsMarker marker, wsPlotProperty property)
{
SizeF sf = g.MeasureString(marker.Value, property.Font);
g.DrawString(marker.Value, property.Font, new SolidBrush(marker.Color),
new PointF(marker.PointF.X - sf.Width / 2F, marker.PointF.Y - dy / 3 - sf.Height));
}
public void AddMarker(Graphics g, PointF[] path, decimal[] trace, int[] indexes, wsPlotProperty property)
{
int markerysize = property.MarkerSize + property.MarkerSize;
Point[] markerpath;
GraphicsPath gpath;
Font font = new Font(property.MarkerFont.FontFamily, markerysize, FontStyle.Bold);
SizeF sf = g.MeasureString("1MHz dBm", font);
string mkrtext; string mkrtextfmt = "F" + property.MarkerDecimals.ToString();
float mpx;
float dpy = 4;
float mpy = Pymin - sf.Height - dpy / 2;
for (int i = 0; i < indexes.Length; i++)
{
if (indexes[i] >= trace.Length) continue;
markerpath = new Point[]
{
new Point((int)path[indexes[i]].X-property.MarkerSize,(int)path[indexes[i]].Y),
new Point((int)path[indexes[i]].X,(int)path[indexes[i]].Y-markerysize),
new Point((int)path[indexes[i]].X+property.MarkerSize,(int)path[indexes[i]].Y),
new Point((int)path[indexes[i]].X,(int)path[indexes[i]].Y+markerysize),
};
gpath = new GraphicsPath();
gpath.AddLines(markerpath);
gpath.CloseFigure();
if (property.MarkerFill)
g.FillPath(new SolidBrush(property.MarkerColor), gpath);
else
g.DrawPath(new Pen(property.MarkerColor, property.MarkerLineWidth), gpath);
//Marker Index
mkrtext = (i + 1).ToString();
sf = g.MeasureString(mkrtext, font);
g.DrawString(mkrtext, font, new SolidBrush(property.MarkerColor), new PointF(posx[indexes[i]] + property.MarkerSize, path[indexes[i]].Y - sf.Height));
//Marker X Text
mkrtext = "[Mkr" + mkrtext + "] " + wsArray.GetValue(property.xMin, property.xMax, posx.Length, indexes[i]).ToString() + " " + property.MarkerUnitX + ": "
+ trace[indexes[i]].ToString(mkrtextfmt) + " " + property.MarkerUnitY;
sf = g.MeasureString(mkrtext, font);
g.DrawString(mkrtext, font, new SolidBrush(property.MarkerColor), Pxmax - sf.Width, mpy); mpy += sf.Height + dpy;
}
}
public void AddMarker(Graphics g, PointF[] path, Collection<decimal> trace, int[] indexes, wsPlotProperty property)
{
int markerysize = property.MarkerSize + property.MarkerSize;
Point[] markerpath;
GraphicsPath gpath;
Font font = new Font(property.MarkerFont.FontFamily, markerysize, FontStyle.Bold);
SizeF sf = g.MeasureString("1MHz dBm", font);
string mkrtext; string mkrtextfmt = "F" + property.MarkerDecimals.ToString();
float mpx;
float dpy = 4;
float mpy = Pymin - sf.Height - dpy / 2;
for (int i = 0; i < indexes.Length; i++)
{
if (indexes[i] >= trace.Count) continue;
markerpath = new Point[]
{
new Point((int)path[indexes[i]].X-property.MarkerSize,(int)path[indexes[i]].Y),
new Point((int)path[indexes[i]].X,(int)path[indexes[i]].Y-markerysize),
new Point((int)path[indexes[i]].X+property.MarkerSize,(int)path[indexes[i]].Y),
new Point((int)path[indexes[i]].X,(int)path[indexes[i]].Y+markerysize),
};
gpath = new GraphicsPath();
gpath.AddLines(markerpath);
gpath.CloseFigure();
if (property.MarkerFill)
g.FillPath(new SolidBrush(property.MarkerColor), gpath);
else
g.DrawPath(new Pen(property.MarkerColor, property.MarkerLineWidth), gpath);
//Marker Index
mkrtext = (i + 1).ToString();
sf = g.MeasureString(mkrtext, font);
g.DrawString(mkrtext, font, new SolidBrush(property.MarkerColor), new PointF(posx[indexes[i]] + property.MarkerSize, path[indexes[i]].Y - sf.Height));
//Marker X Text
mkrtext = "[Mkr" + mkrtext + "] " + wsArray.GetValue(property.xMin, property.xMax, posx.Length, indexes[i]).ToString() + " " + property.MarkerUnitX + ": "
+ trace[indexes[i]].ToString(mkrtextfmt) + " " + property.MarkerUnitY;
sf = g.MeasureString(mkrtext, font);
g.DrawString(mkrtext, font, new SolidBrush(property.MarkerColor), Pxmax - sf.Width, mpy); mpy += sf.Height + dpy;
}
}
public void AddMarker(Graphics g, PointF[] path, int index, string mkrtext, wsPlotProperty property)
{
if (index >= path.Length) return;
int markerysize = property.MarkerSize + property.MarkerSize;
Point[] markerpath = new Point[]
{
new Point((int)path[index].X-property.MarkerSize,(int)path[index].Y),
new Point((int)path[index].X,(int)path[index].Y-markerysize),
new Point((int)path[index].X+property.MarkerSize,(int)path[index].Y),
new Point((int)path[index].X,(int)path[index].Y+markerysize),
};
GraphicsPath gpath = new GraphicsPath();
gpath.AddLines(markerpath);
gpath.CloseFigure();
if (property.MarkerFill)
g.FillPath(new SolidBrush(property.MarkerColor), gpath);
else
g.DrawPath(new Pen(property.MarkerColor), gpath);
Font font = new Font(property.MarkerFont.FontFamily, markerysize);
SizeF sf = g.MeasureString(index.ToString(), font);
g.DrawString(mkrtext, font, new SolidBrush(property.MarkerColor), new PointF(posx[index] + property.MarkerSize, path[index].Y - sf.Height));
}
public void AddMarker(Graphics g, PointF pos, string text, wsPlotProperty property)
{
int markerysize = property.MarkerSize + property.MarkerSize;
Point[] markerpath = new Point[]
{
new Point((int)pos.X-property.MarkerSize,(int)pos.Y),
new Point((int)pos.X,(int)pos.Y-markerysize),
new Point((int)pos.X+property.MarkerSize,(int)pos.Y),
new Point((int)pos.X,(int)pos.Y+markerysize),
};
GraphicsPath gpath = new GraphicsPath();
gpath.AddLines(markerpath);
gpath.CloseFigure();
if (property.MarkerFill)
g.FillPath(new SolidBrush(property.MarkerColor), gpath);
else
g.DrawPath(new Pen(property.MarkerColor), gpath);
Font font = new Font(property.MarkerFont.FontFamily, markerysize);
SizeF sf = g.MeasureString(text, font);
g.DrawString(text, font, new SolidBrush(property.MarkerColor), new PointF(pos.X + property.MarkerSize, pos.Y - sf.Height));
}
public void AddMarker(Graphics g, PointF pos, string text, Font font)
{
int markersize = 6;
int markerysize = markersize * 2;
Color markercolor = Color.Green;
bool markerfill = false;
Point[] markerpath = new Point[]
{
new Point((int)pos.X-markersize,(int)pos.Y),
new Point((int)pos.X,(int)pos.Y-markerysize),
new Point((int)pos.X+markersize,(int)pos.Y),
new Point((int)pos.X,(int)pos.Y+markerysize),
};
GraphicsPath gpath = new GraphicsPath();
gpath.AddLines(markerpath);
gpath.CloseFigure();
if (markerfill)
g.FillPath(new SolidBrush(markercolor), gpath);
else
g.DrawPath(new Pen(markercolor), gpath);
SizeF sf = g.MeasureString(text, font);
g.DrawString(text, font, new SolidBrush(markercolor), new PointF(pos.X + markersize, pos.Y - sf.Height));
}
#endregion
}
#endregion
#region [ Class ] wsPlotProperty with Type Converter
[TypeConverter(typeof(wsPlotPropertyTypeConverter)), Description("PlotProperty"), DisplayName("PlotProperty")]
public class wsPlotProperty
{
#region [ Constructor ]
public wsPlotProperty()
{
Title = "Spectrum Analyze";
TitleFont = new System.Drawing.Font("Arial", 12F, FontStyle.Bold);
Font = new System.Drawing.Font("Arial", 8F, FontStyle.Regular);
xLabel = "Frequency [ MHz ]";
yLabel = "dBm";
BackColor = Color.Black;
ForeColor = Color.Gold;
GridColor = Color.LightGray;
xMin = 0;
xMax = 100;
Refer = 0;
Ydiv = 10;
Scale = 10;
LeftSpace = 50;
RightSpace = 10;
TopSpace = 50;
BottomSpace = 30;
TraceColor = Color.Yellow;
Alpha = 192;
MarkerSize = 6;
MarkerColor = Color.Lime;
MarkerFill = false;
MarkerFont = new Font("Tahoma", 10f);
MarkerUnitX = "MHz";
MarkerUnitY = "dBm";
MarkerLineWidth = 2;
MarkerDecimals = 2;
}
#endregion
public event EventHandler BackgroundChanged;
#region [ Property ] Display: Tittle, TittleFont, Font, xLabel, yLabey, BackColor, ForeColor, GridColor
string title;
[Category("Diaplay"), DisplayName("标题")]
public string Title
{
get { return title; }
set
{
title = value;
if (BackgroundChanged != null) BackgroundChanged(this, new EventArgs());
}
}
[Category("Diaplay"), DisplayName("标题字体")]
public Font TitleFont { get; set; }
[Category("Diaplay"), DisplayName("字体")]
public Font Font { get; set; }
string xlabel;
[Category("Diaplay"), DisplayName("X坐标标示"), Description("X Axis Label Text"), Browsable(true)]
public string xLabel
{
get
{ return xlabel; }
set
{
xlabel = value;
if (BackgroundChanged != null) BackgroundChanged(this, new EventArgs());
}
}
string ylabel;
[Category("Diaplay"), DisplayName("Y坐标标示"), Description("Y Axis Label Text"), Browsable(true)]
public string yLabel
{
get
{ return ylabel; }
set
{
ylabel = value;
if (BackgroundChanged != null) BackgroundChanged(this, new EventArgs());
}
}
Color backcolor;
[Category("Diaplay"), DisplayName("背景色"), Description("Background Color")]
public Color BackColor
{
get
{
return backcolor;
}
set
{
backcolor = value;
if (BackgroundChanged != null) BackgroundChanged(this, new EventArgs());
}
}
Color forecolor;
[Category("Diaplay"), DisplayName("前景色"), Description("Foreground Color")]
public Color ForeColor
{
get
{
return forecolor;
}
set
{
forecolor = value;
if (BackgroundChanged != null) BackgroundChanged(this, new EventArgs());
}
}
Color gridcolor;
[Category("Diaplay"), DisplayName("分割线色"), Description("Grid Line Color")]
public Color GridColor
{
get
{ return gridcolor; }
set
{
gridcolor = value;
if (BackgroundChanged != null) BackgroundChanged(this, new EventArgs());
}
}
#endregion
public event EventHandler ScaleChanged;
decimal xmin;
#region [ Property ] Scale: xMin, xMax, Refer, Scale
[Category("Scale / Div"), DisplayName("X最小坐标值"), Description("Min Frequency"), Browsable(true)]
public decimal xMin
{
get
{
return xmin;
}
set
{
xmin = value;
if (ScaleChanged != null) ScaleChanged(this, new EventArgs());
}
}
decimal xmax;
[Category("Scale / Div"), DisplayName("X最大坐标值"), Description("Max Frequency"), Browsable(true)]
public decimal xMax
{
get
{
return xmax;
}
set
{
xmax = value;
if (ScaleChanged != null) ScaleChanged(this, new EventArgs());
}
}
decimal refer;
[Category("Scale / Div"), DisplayName("Y Reference")]
public decimal Refer
{
get
{
return refer;
}
set
{
refer = value;
if (ScaleChanged != null) ScaleChanged(this, new EventArgs());
}
}
int ydiv;
[Category("Scale / Div"),DisplayName("Y Div")]
public int Ydiv
{
get
{
return ydiv;
}
set
{
ydiv = value;
ydiv = ydiv < 1 ? 2 : ydiv;
if (ScaleChanged != null) ScaleChanged(this, new EventArgs());
}
}
decimal scale;
[Category("Scale / Div"), DisplayName("Y Scale/Div")]
public decimal Scale
{
get
{
return scale;
}
set
{
scale = value;
if (ScaleChanged != null) ScaleChanged(this, new EventArgs());
}
}
#endregion
#region [ Location ]
[Category("Location"), DefaultValue(75), Browsable(true),DisplayName("左侧间隙")]
public int LeftSpace { get; set; }
[Category("Location"), DefaultValue(75), Browsable(true), DisplayName("右侧间隙")]
public int RightSpace { get; set; }
[Category("Location"), DefaultValue(50), Browsable(true),DisplayName("顶部间隙")]
public int TopSpace { get; set; }
[Category("Location"), DefaultValue(50), Browsable(true), DisplayName("底部间隙")]
public int BottomSpace { get; set; }
#endregion
#region [Trace ]
[Category("Trace"), Browsable(true), DisplayName("Trace Color")]
public Color TraceColor { get; set; }
[Category("Trace"), Browsable(true), DisplayName("Alpha")]
public int Alpha { get; set; }
#endregion
#region [ Marker ]
[Category("Marker"), DefaultValue(6), Browsable(true), DisplayName("Marker Size")]
public int MarkerSize { get; set; }
[Category("Marker"), Browsable(true), DisplayName("Marker Color")]
public Color MarkerColor { get; set; }
[Category("Marker"), DefaultValue(1), Browsable(true), DisplayName("Marker Line Width")]
public float MarkerLineWidth { get; set; }
[Category("Marker"), DefaultValue(false), Browsable(true), DisplayName("Marker Fill")]
public bool MarkerFill { get; set; }
[Category("Marker"), Browsable(false)]
public Font MarkerFont { get; set; }
[Category("Marker"), DefaultValue(2), Browsable(true), DisplayName("Marker Decimal Places")]
public int MarkerDecimals { get; set; }
[Category("Marker"), DefaultValue("MHz"), Browsable(true), DisplayName("Marker Unit X ")]
public string MarkerUnitX { get; set; }
[Category("Marker"), DefaultValue("dBm"), Browsable(true), DisplayName("Marker Unit Y")]
public string MarkerUnitY { get; set; }
#endregion
public override string ToString()
{
return string.Empty;
}
#region [ Function ] From / To StringX
public StringX ToStringX()
{
string str = string.Empty;
char t = (char)220;
str += this.BackColor.ToArgb().ToString() + t;
str += this.ForeColor.ToArgb().ToString() + t;
str += this.GridColor.ToArgb().ToString() + t;
str += this.LeftSpace.ToString() + t;
str += this.RightSpace.ToString() + t;
str += this.Refer.ToString() + t;
str += this.Scale.ToString() + t;
str += this.Title + t;
str += this.TopSpace.ToString() + t;
str += this.BottomSpace.ToString() + t;
str += this.xLabel + t;
str += this.xMax.ToString() + t;
str += this.xMin.ToString() + t;
str += this.yLabel + t;
str += this.ydiv.ToString() + t;
str += this.TraceColor.ToArgb().ToString() + t;
str += this.Alpha.ToString() + t;
str += this.MarkerSize.ToString() + t;
str += this.MarkerColor.ToArgb().ToString() + t;
str += this.MarkerLineWidth.ToString() + t;
str += this.MarkerFill.ToString() + t;
str += this.MarkerDecimals.ToString() + t;
str += this.MarkerUnitX + t;
str += this.MarkerUnitY + t;
StringX sx = new StringX("Plot");
sx.String = str;
return sx;
}
public void FromStringX(StringX str)
{
string[] s = str.String.Split((char)220);
if(s.Length<17)
s = str.String.Split((char)252);
int i = 0;
this.BackColor = Color.FromArgb(Convert.ToInt32(s[i])); i++;
this.ForeColor = Color.FromArgb(Convert.ToInt32(s[i])); i++;
///////////////////
this.GridColor = Color.FromArgb(Convert.ToInt32(s[i])); i++;
this.LeftSpace = Convert.ToInt32(s[i]); i++;
this.RightSpace = Convert.ToInt32(s[i]); i++;
this.Refer = Convert.ToDecimal(s[i]); i++;
this.Scale = Convert.ToDecimal(s[i]); i++;
this.Title = s[i]; i++;
this.TopSpace = Convert.ToInt32(s[i]); i++;
this.BottomSpace = Convert.ToInt32(s[i]); i++;
this.xLabel = s[i]; i++;
this.xMax = Convert.ToDecimal(s[i]); i++;
this.xMin = Convert.ToDecimal(s[i]); i++;
this.yLabel = s[i]; i++;
this.Ydiv = Convert.ToInt32(s[i]); i++;
this.TraceColor = Color.FromArgb(Convert.ToInt32(s[i])); i++;
this.Alpha = Convert.ToInt32(s[i]); i++;
this.MarkerSize = Convert.ToInt32(s[i]); i++;
this.MarkerColor = Color.FromArgb(Convert.ToInt32(s[i])); i++;
this.MarkerLineWidth = Convert.ToSingle(s[i]); i++;
this.MarkerFill = Convert.ToBoolean(s[i]); i++;
this.MarkerDecimals = Convert.ToInt32(s[i]); i++;
this.MarkerUnitX = s[i]; i++;
this.MarkerUnitY = s[i]; i++;
}
#endregion
}
public class wsPlotPropertyTypeConverter : ExpandableObjectConverter
{
#region Can Convert
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(wsPlotProperty))
return true;
return base.CanConvertTo(context, destinationType);
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(StringX))
return true;
return base.CanConvertFrom(context, sourceType);
}
#endregion
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(StringX) && value is wsPlotProperty)
return ((wsPlotProperty)value).ToStringX();
return base.ConvertTo(context, culture, value, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is StringX)
{
try
{
wsPlotProperty p = new wsPlotProperty();
p.FromStringX((StringX)value);
return p;
}
catch (Exception ex)
{
throw new ArgumentException(ex.ToString());
}
}
return base.ConvertFrom(context, culture, value);
}
}
#endregion
#region [ Class ] wsMarker
public class wsMarker
{
public PointF PointF { get; set; }
public Color Color { get; set; }
public string Value { get; set; }
public wsMarker(PointF pf, Color cor, string val)
{
PointF = pf;
Color = cor;
Value = val;
}
}
#endregion
}
相关推荐
网络安全等保2.0与密评合规操作指南:数据中心、云平台及业务系统落地实施与迎检材料准备
内容概要:本文档是一份针对网络安全等级保护(等保2.0)与商用密码应用安全性评估(密评)的落地操作手册,旨在为数据中心、云平台运营商及业务系统提供从定级、备案、建设整改到测评评估的全流程指导。内容涵盖等保与密评的法律依据、适用范围、实施流程、技术与管理要求、材料清单、责任分工、常见问题及整改建议,并针对三类对象分别列出专项落地要点和自查清单,确保合规工作可执行、可追溯。; 适合人群:适用于数据中心运维人员、云平台安全负责人、业务系统管理员、安全合规专员及参与等保与密评工作的项目负责人和技术人员。; 使用场景及目标:①指导单位开展等保定级备案与等级测评准备工作;②推动密评在关键系统中的落地实施,确保密码应用合规、正确、有效;③支持迎检材料整理、整改措施落实与持续合规运维。; 阅读建议:建议按照手册章节顺序逐步推进,结合附录自查清单与材料模板,联动技术、管理和运维团队协同执行,并定期对照更新,确保等保与密评工作闭环管理。
政府科技管理者如何实现科技成果转化资源的精准匹配与高效调度.docx
科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。
【Web服务器运维】基于Nginx与Keepalived的高可用负载均衡系统部署:实现故障自动切换与虚拟IP管理
内容概要:本文详细介绍了如何通过Nginx与Keepalived实现高可用的负载均衡架构。首先讲解了Nginx的安装部署流程,包括依赖环境的准备、源码解压编译、启动及配置重载;接着介绍了Keepalived的安装步骤及其服务管理方式;重点在于通过配置Keepalived的主备节点(MASTER/BACKUP),结合VRRP协议和虚拟IP(VIP)实现故障自动切换,并通过自定义脚本nginx_check.sh实时检测Nginx运行状态,确保服务高可用;最后补充了在云环境中因组播限制导致心跳不稳定时,应改用单播(unicast)方式进行通信的解决方案。; 适合人群:具备Linux系统操作基础、熟悉网络基础知识,从事运维、DevOps或Web服务部署的技术人员,尤其是工作1-3年的工程师。; 使用场景及目标:①搭建高可用的Web负载均衡系统,避免单点故障;②掌握Nginx与Keepalived协同工作的原理与实战配置方法;③应用于生产环境中提升服务稳定性与容灾能力。; 阅读建议:学习时应结合实验环境动手操作,重点关注keepalived.conf配置差异与nginx_check.sh脚本逻辑,理解VRRP机制及单播替代组播的实际应用场景,注意根据实际网络环境调整IP与网卡参数。
三层交换机第一次作业.docx
三层交换机第一次作业.docx
三电平Buck直流变换器双闭环、单闭环、开环仿真【附参考文献】(Simulink仿真实现)
内容概要:本文档系统介绍了三电平Buck直流变换器在Simulink环境下的开环、单闭环与双闭环控制系统的建模仿真方法,涵盖系统建模、控制策略设计及动态性能对比分析。通过构建不同控制结构,深入探讨电压调节精度、系统响应速度、抗干扰能力及稳定性差异,重点剖析双闭环控制中电压外环与电流内环的协同作用机制,揭示其在抑制输出纹波、提升负载适应性方面的优势,帮助读者掌握多电平DC-DC变换器的核心控制原理与工程实现技术;文档还提供了详实的仿真参数设置与参考文献,便于理论验证与实践复现。; 适合人群:电力电子、自动化、电气工程及其相关专业的高校本科生、研究生、科研人员,以及从事电源系统、新能源变换器开发的工程技术人员。; 使用场景及目标:①作为高校电力电子课程的教学案例,辅助学生理解Buck变换器多层次控制策略的设计思路与性能差异;②为科研项目中高效直流变换系统的仿真研究提供可复用的技术模板;③指导工业界在高精度电源设计中优化控制器参数,提升系统动态响应与稳定性。; 阅读建议:建议结合Simulink仿真模型同步操作,对照文档逐步搭建各控制结构,重点观察不同闭环配置下输出电压的瞬态与稳态表现,深入理解PI参数整定、环路耦合影响及系统频域特性的关联性,从而全面提升对电力电子系统控制设计的综合把握能力。
国央企创新负责人如何实现科技成果的全流程数字化管理?.docx
科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。
单相boost功率因数校正 PFC电路仿真(Simulink仿真实现)
内容概要:本文档围绕“单相Boost功率因数校正(PFC)电路仿真”的Simulink实现展开,系统阐述了基于双闭环控制的单相Boost PFC电路的建模与仿真全过程。内容涵盖电路拓扑结构设计、工作原理分析、关键控制策略(如平均电流控制、PI调节、电压外环与电流内环协同控制、前馈补偿等)的实现机制,并通过Simulink平台构建完整仿真模型,验证输入电流正弦化、单位功率因数实现及输出电压稳定等性能指标。文档还详述了控制参数的设计方法、系统动态响应评估以及仿真结果的分析流程,帮助读者深入掌握PFC技术的核心理论与工程应用细节。; 适合人群:具备电力电子、自动控制理论及电路分析基础,正在从事开关电源、新能源变换系统、电能质量治理等相关方向研究的本科高年级学生、研究生及电气工程领域的研发工程师。; 使用场景及目标:① 深入理解单相Boost PFC电路的工作机理与双闭环控制架构;② 掌握在Simulink中搭建电力电子变换器控制系统的方法,提升仿真建模与调试能力;③ 为毕业课题、科研项目或工业级PFC产品开发提供可复用的技术方案与仿真基础。; 阅读建议:建议结合Simulink软件动手实践,逐步构建主电路与控制模块,重点理解电流内环的跟踪性能与电压外环的稳定性设计,关注PI控制器参数整定与系统抗扰动能力的关系,同时可延伸学习图腾柱、交错并联等先进PFC拓扑结构,以拓宽技术视野。
高校技术转移办公室人员在推介成果转化时,如何实现技术成果的精准呈现?.docx
科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。
LLC谐振变换器开环+闭环软启动仿真设计(Simulink仿真实现)
内容概要:本文档聚焦于LLC谐振变换器的开环与闭环软启动仿真设计,基于Simulink平台实现了半桥和全桥LLC拓扑结构的建模与仿真,深入探讨了软开关技术、变频控制、移相混合控制等多种先进控制策略的应用。资源包包含完整的仿真模型、详细的设计报告、参数计算书及说明文档,系统展示了LLC变换器在启动过程中电压与电流波形的动态响应特性,重点优化了系统稳定性与瞬态性能,帮助用户深入理解其闭环调节机制与工程实现方法。同时,文档整合了大量电力电子与控制系统相关的仿真资源,构建了一个涵盖PFC、DC-DC变换器、逆变器、储能系统等在内的综合性技术资料库,适用于科研、教学与产品开发多个层面。; 适合人群:具备电力电子、自动控制理论基础,从事开关电源设计、新能源变换系统研发、电力电子仿真分析等相关工作的研究生、工程师及科研人员。; 使用场景及目标:①深入掌握LLC谐振变换器的工作原理及其软启动控制策略;②学习在Simulink中构建高精度电力电子系统仿真模型的方法;③为毕业设计、科研课题或工业级电源产品的开发提供可复用的仿真架构与参数设计依据。; 阅读建议:建议结合所提供的仿真模型与技术文档同步实践,逐步调试开环启动与闭环控制参数,重点关注启动过程中的电压冲击、电流应力及谐振元件的动态行为,深入分析控制环路设计对系统稳定性和效率的影响,从而全面提升对LLC变换器系统级设计的理解与应用能力。
单相PWM整流器基于直流电流控制+虚拟dq两种闭环控制仿真【2个仿真+参考资料】
内容概要:本文系统介绍了单相PWM整流器的两种主流闭环控制策略——基于直流电流控制和虚拟dq坐标系控制,配套提供了两个完整的Simulink仿真模型及相关参考资料。资源聚焦于控制系统的设计原理与实现细节,深入剖析电压外环与电流内环构成的双闭环结构,旨在实现高功率因数运行、直流侧电压稳定以及优异的动态响应性能。通过对两种控制方法的建模、仿真与对比分析,帮助使用者全面理解其在控制精度、抗扰动能力、系统稳定性及工程实用性等方面的差异与适用场景。; 适合人群:电气工程、自动化、电力电子与电力传动等相关专业的本科生、研究生,以及从事新能源发电、电力变换系统、电能质量治理等领域研发工作的工程技术人员。; 使用场景及目标:①学习和掌握单相PWM整流器的基本工作原理、数学建模与主电路设计方法;②深入理解直流电流控制与虚拟dq控制的核心思想、实现流程及其在实际系统中的优缺点与应用场景差异;③为毕业设计、课程设计、科研课题或工业级产品开发提供可靠的仿真平台和技术参考依据。; 阅读建议:建议结合Simulink仿真模型与参考资料进行同步学习,动手调整控制器参数并观察系统动态响应变化,以深化对控制策略的理解;在掌握单相系统基础上,可进一步拓展学习三相PWM整流器、图腾柱PFC、Vienna整流器等先进拓扑及其控制技术,逐步构建完整的电力电子变换器控制知识体系。
产业园区运营负责人如何实现科技资源的高效配置与联动?.docx
科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。
一个免费的激光打标软件的配套硬件说明
激光打标软件配套硬件说明
产业园区在推动科技成果转化时,如何精准匹配企业与技术供给方?.docx
科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。
半桥LLC谐振变换器开环+闭环仿真设计资料(Simulink仿真实现)
内容概要:本文档系统地介绍了半桥LLC谐振变换器的开环与闭环仿真设计方法,基于Simulink平台实现,涵盖系统建模、仿真构建、关键参数设计与动态性能分析等内容。重点阐述了LLC谐振变换器的工作原理、软开关技术的实现机制、变频控制与双闭环控制策略的设计思路,以及系统在不同工况下的动态响应特性。资料包含完整的仿真模型、设计报告和参考文献,有助于深入理解谐振变换器在高效DC-DC变换中的应用与优化路径。; 适合人群:适用于电力电子、电气工程及其自动化等相关专业的高校本科生、研究生、科研人员,以及从事开关电源、高效率DC-DC变换器研发的工程技术人员。; 使用场景及目标:①深入掌握LLC谐振变换器的核心工作原理与数学建模方法;②学习在Simulink中搭建开环与闭环控制系统并进行稳定性、效率与动态性能仿真;③为科研课题、毕业设计、产品原型开发提供可复用的仿真基础与技术参考。; 阅读建议:建议结合文档中的仿真模型与设计说明同步实践,逐步完成建模、参数整定与仿真调试,注重理论推导与仿真结果的对比分析,以强化对控制策略与系统动态行为的理解。
高校技术转移办公室人员如何提升技术成果的转化效率与市场对接成功率?.docx
科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。
三相三电平VIENNA整流器双闭环设计与中点电压均衡控制仿真(Simulink仿真实现)
内容概要:本文详细介绍了一套针对三相三电平VIENNA整流器的Simulink仿真设计方案,重点聚焦于电压电流双闭环控制系统与中点电压均衡控制策略的实现。通过构建双闭环控制架构(外环直流电压控制与内环电流控制),确保系统在动态负载变化下仍能维持稳定的直流母线电压和单位功率因数运行;同时引入基于SVPWM的空间矢量调制技术,并结合中点电位平衡控制算法,有效抑制三电平变换器特有的中点电压漂移问题,提升系统运行的对称性与可靠性。该仿真模型具有高度工程实用性,适用于新能源发电、电动汽车充电桩、工业电机驱动等高效率、高功率密度应用场景,为相关领域的科研与产品开发提供了完整的理论依据和技术验证平台。; 适合人群:电气工程、自动化、电力电子与电力传动等相关专业的高校研究生及科研人员,以及从事高端电源、新能源并网、电能质量治理等方向的技术研发工程师,尤其适合已掌握Simulink基本操作并希望深入理解三电平整流器控制机理的学习者。; 使用场景及目标:① 深入掌握三相三电平VIENNA整流器的工作原理及其数学建模方法;② 学习并实践双闭环控制器的设计流程与PI参数整定技巧;③ 理解中点电压不平衡的成因及其对系统性能的影响,掌握基于调制策略的主动均衡控制方法;④ 构建可用于学术研究或工程项目前期验证的高保真仿真平台,支撑后续硬件原型开发与控制算法优化。; 阅读建议:建议结合仿真模型与技术文档同步学习,重点关注坐标变换(abc/dq)、SVPWM模块实现、中点电位观测与反馈控制逻辑的设计细节,推荐通过逐步调试各子系统模块的方式加深理解;有条件者可进一步开展硬件在环(HIL)测试,以验证控制策略的实际可行性与鲁棒性。
科技中介服务机构如何打造个性化服务以提升客户黏性.docx
科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。
国央企创新负责人在推动内部技术成果产业化落地时,如何实现技术资源的高效配置与精准对接?.docx
科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。



被折叠的 条评论
为什么被折叠?



