wsPlot

本文详细介绍了如何使用特定的编程技术与库,实现高效且专业的图表绘制与数据可视化功能,包括绘制曲线、标记关键点、添加网格、设置坐标轴标签等。通过实例演示,帮助开发者快速掌握图表绘制的核心技巧。
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
}

液体化学品实例分割数据集 一、基础信息 数据集名称:液体化学品实例分割数据集 图片数量: - 训练集:2550张图片 - 验证集:233张图片 - 测试集:82张图片 - 总计:2865张实际场景图片 分类类别: - 电池酸:常见的腐蚀性液体,用于电池等设备。 - 漂白剂:强氧化性液体,常用于清洁和消毒。 - 冷却剂:用于发动机或工业设备的散热液体。 - 燃料:如汽油、柴油等易燃液体。 - 液压燃料:用于液压系统的专用液体。 - 机油:润滑油,用于机械维护。 标注格式: YOLO格式,包含实例分割多边形标注,适用于实例分割任务。 数据格式:来源于真实环境图像,格式为JPEG/PNG,覆盖多种场景。 二、适用场景 工业安全与检查: 数据集支持实例分割任务,帮助构建能够自动识别和分割液体区域的AI模型,用于检测泄漏、溢出或不当存储,提升工作场所安全。 环境监测与风险评估: 集成至环境监控系统,实时识别污染物液体,支持环境保护和风险预警。 制造业与自动化: 在制造过程中监控液体使用和状态,实现质量控制和自动化管理。 学术研究与创新: 支持计算机视觉和人工智能在工业应用中的研究,促进算法开发和论文发表。 教育与培训: 可用于工程或安全培训课程,作为学习液体识别和处理的视觉资料。 三、数据集优势 精准标注与高质量: 每个实例分割多边形经过严格验证,确保标注准确性和一致性,覆盖液体区域的细节。 类别丰富多样: 包含六种关键工业液体,涵盖不同性质和风险,增强模型在多样场景下的识别能力。 真实场景数据: 图片来源于实际工业和环境设置,提供真实世界的挑战,提升模型的实用性和鲁棒性。 任务适配性强: 标注兼容YOLO等主流框架,便于快速集成和训练,支持实例分割及相关任务。 应用价值突出: 专注于工业安全和环境健康,为自动检测系统提供可靠数据,助力智能监控解决方案。
源码来自:https://pan.quark.cn/s/a7cc5c1f6849 简介 GitFlowPlus4Idea插件是一款基于mrtf-git-flow分支管理流程的Idea插件,它最主要的作用是用来简化分支管理流程,最大限度的防止误操作。 mrrtf.png 在初始化插件之前必须先保证仓库中具有分支。 主要功能如下: 插件配置文件可以加入GIT版本管理,在团队内部共享; 基于新建开发分支和修复分支; 基于重建测试分支和发布分支; 开发完成后将开发分支合并到测试分支; 测试完成后将开发分支合并到发布分支,并锁定发布分支; 发布完成后将发布分支合并到分支; 发布失败将解除发布分支的锁定; 只有锁定发布分支的人才能点[发布完成]和[发布失败] 所有执行的git命令都可以在"Event Log"查看 主要解决的问题 新建特性分支操作过程复杂,且容易出错; 提测等环节合并代码出错,老是将测试分支代码带上线; 解决多人同时发布,将未完成预发布测试的代码带上线; 解决发布完成后忘记将代码同步到分支; 发布完成后忘记打Tag; Switch To English switchtoenglish.gif 安装 在线安装 local_install.gif 离线安装 下载地址: https://.com/xiaolyuh/mrtf-git-flow-4idea/releases local_install.gif 插件入口 插件入口.png 插件入口有2个: 在Toolbar栏,这个需要显示Toolbar(View->Toolbar) 在Statusbar中 配置管理 每个仓库都需要进行插件初始化,配置完成后会生成一个配置文件,该文件可以添加到git版本管理中进行组内...
紫葡萄关键点检测数据集 一、基础信息 数据集名称:紫葡萄关键点检测数据集 图片数量: 训练集:1,250张图片 验证集:357张图片 测试集:179张图片 分类类别: 紫葡萄(purple_grape):常见的葡萄品种,用于农业检测和分析。 标注格式: YOLO格式,包含关键点坐标和类别标签,适用于关键点检测任务。 数据格式:图像文件,细节清晰。 二、适用场景 农业AI监测系统开发: 数据集支持关键点检测任务,帮助构建能够自动识别葡萄关键点并分析其生长状态的AI模型,辅助农民监控作物健康。 智能农业应用研发: 集成至农业机器人或无人机系统,提供实时葡萄检测功能,为精准农业提供数据支持。 学术研究与创新: 支持农业与计算机视觉交叉领域的研究,助力发表高水平农业AI论文。 教育训练: 数据集可用于农业院校或培训机构,作为学习关键点检测技术和农业应用的重要资源。 三、数据集优势 精准关键点标注: 每个关键点均由坐标精确标注,确保模型能学习细粒度特征,适用于葡萄形态分析。 数据多样性高: 包含多种场景下的紫葡萄图像,提升模型在实际农业环境中的泛化能力。 任务适配性强: 标注兼容主流深度学习框架(如YOLO等),可直接加载使用,支持关键点检测任务。 农业应用价值突出: 专注于紫葡萄关键点检测,为农业自动化监测和作物管理提供重要数据支撑,提高生产效率。
内容概要:本文系统讲解了ASP(Active Server Pages)动态网页开发技术,从其历史背景、核心优势到与现代Web技术的关联,全面介绍了ASP的基础知识与实际应用。文章详细阐述了ASP开发环境的搭建(IIS、SQL Server、Visual Studio),ASP页面结构与语法,VBScript与JavaScript脚本语言的选择,并深入探讨了服务器端脚本的工作机制、动态内容生成方法及ASP内置对象(Request、Response、Session、Application)的实际运用。通过ADO技术实现数据库连接与操作,并结合在线学习平台的实战项目,完整展示了从前端界面设计到后端功能实现的全过程,涵盖用户注册、登录、留言、课程管理等核心功能,最后提出了网站测试、性能优化与安全防护策略,并对ASP在当前技术环境下的角色与发展前景进行了客观分析。 适合人群:具备一定HTML、数据库基础,对Web开发感兴趣的初级开发者或在校学生,尤其是希望了解传统服务器端脚本技术及其演进过程的学习者。 使用场景及目标:①掌握ASP动态网页开发的核心原理与技术实现;②学会搭建ASP开发环境并完成数据库连接与CRUD操作;③通过完整项目实践理解Web应用的前后端协同开发流程;④为学习ASP.NET或其他现代Web框架奠定基础。 阅读建议:此资源以理论结合实战的方式展开,建议读者在本地环境中同步搭建IIS与数据库,边学习边动手实现文中示例代码,尤其应重视数据库操作的安全性(如参数化查询)与代码规范性,从而深入理解ASP技术的本质及其在现代Web开发中的定位。
人体肢体与躯干关键点检测数据集 一、基础信息 数据集名称:人体肢体与躯干关键点检测数据集 图片数量: 训练集:6,215张图片 验证集:604张图片 测试集:302张图片 总计:7,121张图片 分类类别: limbs(肢体):人体四肢部位的关键点标注,适用于姿态分析和运动追踪。 torso(躯干):人体躯干部位的关键点标注,支持身体核心区域的定位与识别。 标注格式:YOLO格式,包含关键点坐标信息,适用于关键点检测任务。 数据格式:图片来源于实际场景,标注精确,适用于模型训练。 二、适用场景 人体姿态估计与运动分析: 数据集支持关键点检测任务,帮助构建AI模型以实时追踪人体肢体和躯干的关键点位置,适用于健身指导、运动表现分析和康复训练监测。 安防与监控应用: 集成至智能监控系统,实现对人体姿态的自动识别,用于行为分析、异常检测和公共安全管理。 医疗康复与健康管理: 应用于医疗AI系统,辅助医生或康复师评估患者身体姿态和运动功能,提升诊断效率和个性化治疗计划。 虚拟试衣与娱乐交互: 支持虚拟现实或增强现实应用,用于人体姿态模拟和交互体验开发,增强用户参与感。 三、数据集优势 精准标注与多样性: 关键点坐标由专业标注团队完成,确保定位准确,覆盖多种人体姿态和场景。 包含肢体和躯干两个核心类别,数据样本丰富,提升模型对不同身体部位的泛化能力。 任务适配性强: 标注兼容主流深度学习框架(如YOLO),可直接用于关键点检测模型的训练与验证。 支持从关键点检测扩展到姿态估计、行为识别等多种计算机视觉任务。 实用价值突出: 专注于人体关键点检测,为运动科学、医疗健康和智能安防等领域提供高质量数据支撑,助力AI应用落地。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值