状态波形图控件

时间:2022-07-02 10:23:32

文件来自:Nobi's StatusChart - 野比的状态波形图控件

http://bbs.bccn.net/viewthread.php?tid=210440&page=1#pid1254128

用途提供形象的可视化数据流动记录功能,如 FlashGet 及其衍生软件的悬浮窗网速监视图,Windows 任务管理器的 CPU、内存使用图等。
控件被改为三条曲线输出

状态波形图控件

第一步:添加DLL控件

状态波形图控件






状态波形图控件



第二步:添加控件带窗体


状态波形图控件

三:设置

状态波形图控件

只能选择Waveform。 

状态波形图控件状态波形图控件



(4)引用

初始化颜色,在控件上改也可以

状态波形图控件



添加一个定时器,用于装在数值 。

这个定时器不同于器件自己的刷新时间,这个定时器用来定时跟新数值,

使用串口则定时的向设备询问数据状态。



状态波形图控件



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
#endregion


//DLL 内容
namespace UI
{
    public partial class StatusChart : UserControl
    {
        /****************************
         * Nobi's StatusChart
         * 野比的状态波形图
         * --------------------------
         * 设计:野比
         * 制作:野比
         * 首发:bbs.bccn.net
         * For evaluations ONLY, NOT for commercial!
         * 仅供评测、交流、学习,请勿用于商业用途!
         * 作者拒绝承担因私自发布、使用所带来的任何法律或社会责任!
         * 
         * 转发请保留以上信息
         * *************************/

        #region ** 私有成员 **
        //私有成员:属性
        private int range = 100;    //波形所容纳的最大值
        private int interval = 2000; //定时器间隔

        //定义三条曲线的缓存数组
        private int[] val1;//Chart 值数组
        private int[] val2;//Chart 值数组
        private int[] val3;//Chart 值数组
        //外部复制时调用的暂存数值
        private int currentValue1 = 0;//当前值
        private int currentValue2 = 0;//当前值
        private int currentValue3 = 0;//当前值



        private int w, h;//画布大小
        private Timer tmrRefresh;//定时器

        //私有成员:绘图
        private ChartMode chartMode = ChartMode.Histogram;    //绘图方式
        private int iOffset = 0;//平移偏移量
        private bool gridShiftting = true;//网格是否平移
        private int gridShifttingIncrement = 1;//网格平移间距
        private int gridWidth = 10;//网格宽度
        private int gridHeight = 10;//网格高度

        private Pen penChart1 = new Pen(Color.Lime);
        private Pen penChart2 = new Pen(Color.Lime);
        private Pen penChart3 = new Pen(Color.Lime);


        private Pen penGrid = new Pen(Color.Green);
        private Graphics graph;

        #endregion

        #region ** 私有方法 **
        //私有方法:绘制网格
        private void DrawGrids(ref Graphics g, int offset)
        {
            //网格数(不计边缘)
            float div;
            float pos = 0F;
            //先画 垂直 方向
            //可以少画一根线
            div = (float)w / (float)gridWidth + 1;
            for (int i = 0; i < (int)div; i++)
            {
                pos += gridWidth;
                g.DrawLine(penGrid, pos - offset, 0, pos - offset, h);
            }
            //画 水平 方向
            div = (float)h / (float)gridHeight;
            pos = 0F;
            for (int i = 0; i < (int)div; i++)
            {
                pos += gridHeight;
                g.DrawLine(penGrid, 0, pos, w, pos);
            }
        }

        //私有方法:绘制图形
        //p:Pen 类 封装了画出线的颜色和粗细
        //第一个x,y:线条起点X,Y的坐标 
        //第二个x,y: 线条终点X,Y的坐标
        private void DrawChart(ref Graphics g, Pen p, ref int[] val)
        {
            //从 0 到 w 绘制
            int len = w;
            //根据绘制方式
            if (chartMode == StatusChart.ChartMode.Histogram)
            {
                for (int i = 0; i < len; i++)
                {
                    g.DrawLine(p, i, h - val[i], i, h);          
                }
                g.DrawLine(p, len, h - val[len - 1], len, h);
            }
            else
            {
                len--;
                for (int i = 0; i < len; i++)
                {
                    g.DrawLine(p, i, h - val[i], i + 1, h - val[i + 1]);
                }
                len++;
                g.DrawLine(p, len - 1, h - val[len - 2], len, h - val[len - 1]);
            }
        }


        //私有方法:重载方法 
        //onload 事件会在页面或图像加载完成后立即发生。
        protected override void OnLoad(EventArgs e)
        {
            //base.OnLoad(e);
            //打开双缓冲,防止闪烁
            DoubleBuffered = true;
            h = base.ClientSize.Height - 1;
            w = base.ClientSize.Width - 1;
            val1 = new int[w];
            val2 = new int[w];
            val3 = new int[w];
            //设置 Timer
            tmrRefresh = new Timer();
            tmrRefresh.Interval = interval;
            tmrRefresh.Enabled = true;
            tmrRefresh.Tick += new EventHandler(tmrRefresh_Tick);
        }
        //重设大小
        //onresize 事件会在窗口或框架被调整大小时发生。
        protected override void OnResize(EventArgs e)
        {
            h = base.ClientSize.Height;
            w = base.ClientSize.Width;
            Array.Resize(ref val1, w);
            Array.Resize(ref val2, w);
            Array.Resize(ref val3, w);
            Invalidate();
        }
        //绘图 
        //在视图改变后,会产生无效区域这个无效区域需要重新画,一般windows系统发送两条消息WM_Paint(通知客户区域有变化)
        //VM_NCPAINT (通知非客户区有变化)。非客户区域的重画系统自己搞定,客户区域需要调用OnPaint()重画
        protected override void OnPaint(PaintEventArgs e)
        {
            //base.OnPaint(e);
            graph = e.Graphics;
            DrawGrids(ref graph, iOffset);
            DrawChart(ref graph, penChart1, ref  val1);
            DrawChart(ref graph, penChart2, ref  val2);
            DrawChart(ref graph, penChart3, ref  val3);
        }

        //定时器更新
        //移动数据这里决定了数据的移动方向
        private void tmrRefresh_Tick(object sender, EventArgs e)
        {
            //更新网格偏移
            //只有启用了网格移动才处理
            if (gridShiftting)
            {
                iOffset += gridShifttingIncrement;
                iOffset %= gridWidth;
            }
            //更新图形(整体左移)
            //必须在这里而不能在画图的同时移动,
            //若在画图中移动,则当画面被遮挡(OnPaint)事件不发生时无法更新
            int len = w;
            for (int i = 0; i < len; i++)
            {
                //判断数组越界
                if (i < len - 1)
                {
                    val1[i] = val1[i + 1];
                    val2[i] = val2[i + 1];
                    val3[i] = val3[i + 1];
                }
                else
                {
                    val1[len - 1] = currentValue1;
                    val2[len - 1] = currentValue2;
                    val3[len - 1] = currentValue3;
                    //break;
                }
            }
            //val[len] = currentValue;
            Invalidate();//使控件重绘自身
        }

        #endregion

        #region ** 公共成员 **
        /// <summary>
        /// 波形图显示方式枚举。
        /// </summary>
        public enum ChartMode
        {
            /// <summary>
            /// 直方图
            /// </summary>
            Histogram = 0,    //直方图
            /// <summary>
            /// 波形图
            /// </summary>
            Waveform        //波形图
        }
        #endregion

        #region ** 公共属性 **
        //公共成员:属性
        [Browsable(true)]
        /// <summary>
        /// 数据值范围。绘图时将根据此值缩放 Value 值。
        /// </summary>
        [Category("内容"), Description("数据值范围。绘图时将根据此值缩放 Value 值。"), DefaultValue(100)]
        public int Range
        {
            get
            {
                return range;
            }
            set
            {
                range = value;
            }
        }
        /// <summary>
        /// 当前值。
        /// </summary>
        ///外部调用时使用此参数复制
   
        [Category("内容"), Description("当前值。"), DefaultValue(0)]
        public int Value1
        {
            get
            {
                return currentValue1;
            }
            set
            {
                //约束 value
                if (value > range)
                {
                    value = range;
                }
                if (value < 0)
                {
                    value = 0;
                }
                //根据 Range 属性修正 value
                //尽量减小误差
                value = (int)((float)value / (float)range * (float)h);
                currentValue1 = value;
            }
        }

        /// <summary>
        /// 当前值。
        /// </summary>
        [Category("内容"), Description("当前值。"), DefaultValue(0)]
        public int Value2
        {
            get
            {
                return currentValue2;
            }
            set
            {
                //约束 value
                if (value > range)
                {
                    value = range;
                }
                if (value < 0)
                {
                    value = 0;
                }
                //根据 Range 属性修正 value
                //尽量减小误差
                value = (int)((float)value / (float)range * (float)h);
                currentValue2 = value;
            }
        }
        public int Value3
        {
            get
            {
                return currentValue3;
            }
            set
            {
                //约束 value
                if (value > range)
                {
                    value = range;
                }
                if (value < 0)
                {
                    value = 0;
                }
                //根据 Range 属性修正 value
                //尽量减小误差
                value = (int)((float)value / (float)range * (float)h);
                currentValue3 = value;
            }
        }














        /// <summary>
        /// 波形图刷新间隔。
        /// </summary>
        [Category("内容"), Description("波形图刷新间隔。"), DefaultValue(500)]
        public int Interval
        {
            get
            {
                return interval;
            }
            set
            {
                interval = value;
                if (tmrRefresh != null)
                {
                    tmrRefresh.Interval = interval;
                }
            }
        }
        /// <summary>
        /// 指示波形是否继续更新。
        /// </summary>
        [Category("内容"), Description("指示波形是否继续更新。"), DefaultValue(true)]
        public new bool Enabled
        {
            get
            {
                if (tmrRefresh != null)
                {
                    return tmrRefresh.Enabled;
                }
                else
                {
                    return false;
                }
            }
            set
            {
                if (tmrRefresh != null)
                {
                    tmrRefresh.Enabled = value;
                }
            }
        }
        /// <summary>
        /// 显示方式。
        /// </summary>
        [Category("外观"), Description("波形显示方式。"), DefaultValue(typeof(StatusChart.ChartMode), "Histogram")]
        public ChartMode Mode
        {
            get
            {
                return chartMode;
            }
            set
            {
                chartMode = value;
            }
        }
        /// <summary>
        /// 网格每次更新时向左平移的距离。
        /// </summary>
        [Category("外观"), Description("网格每次更新时向左平移的距离。"), DefaultValue(1)]
        public int ShifttingIncrement
        {
            get
            {
                return gridShifttingIncrement;
            }
            set
            {
                gridShifttingIncrement = value;
                if (gridShifttingIncrement < 0)
                {
                    gridShifttingIncrement = 0;
                }
            }
        }
        /// <summary>
        /// 指示网格是否每次更新时向左平移。
        /// </summary>
        [Category("外观"), Description("指示网格是否每次更新时向左平移。"), DefaultValue(true)]
        public bool GridShiftting
        {
            get
            {
                return gridShiftting;
            }
            set
            {
                gridShiftting = value;
            }
        }
        /// <summary>
        /// 网格宽度。
        /// </summary>
        [Category("外观"), Description("网格宽度。"), DefaultValue(10)]
        public int GridWidth
        {
            get
            {
                return gridWidth;
            }
            set
            {
                gridWidth = value;
                Invalidate();
            }
        }
        /// <summary>
        /// 网格高度。
        /// </summary>
        [Category("外观"), Description("网格高度。"), DefaultValue(10)]
        public int GridHeight
        {
            get
            {
                return gridHeight;
            }
            set
            {
                gridHeight = value;
                Invalidate();
            }
        }
        /// <summary>
        /// 网格颜色。
        /// </summary>
        [Category("外观"), Description("网格颜色。"), DefaultValue(typeof(Color), "Green")]
        public Color GridColor
        {
            get
            {
                return penGrid.Color;
            }
            set
            {
                penGrid.Color = value;
            }
        }
        /// <summary>
        /// 波形颜色。
        /// </summary>
        [Category("外观"), Description("波形颜色。"), DefaultValue(typeof(Color), "Lime")]
        //public override Color ForeColor
        public  Color ForeColor1
        {
            get
            {
                return penChart1.Color;
            }
            set
            {
                penChart1.Color = value;
            }
        }


        public Color ForeColor2
        {
            get
            {
                return penChart2.Color;
            }
            set
            {
                penChart2.Color = value;
            }
        }

        public Color ForeColor3
        {
            get
            {
                return penChart3.Color;
            }
            set
            {
                penChart3.Color = value;
            }
        }



















        #endregion

        #region ** 公共方法 **
        /// <summary>
        /// 启动计时器更新。返回执行情况。
        /// </summary>
        /// <returns>执行情况。true 成功;false 失败。</returns>
        public bool Start()
        {
            try
            {
                if (tmrRefresh != null)
                {
                    tmrRefresh.Enabled = true;
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// 停止计时器更新。返回执行情况。
        /// </summary>
        /// <returns>执行情况。true 成功;false 失败。</returns>
        public bool Stop()
        {
            try
            {
                if (tmrRefresh != null)
                {
                    tmrRefresh.Enabled = false;
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }

        private void StatusChart_Load(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// 清除历史状态记录。
        /// </summary>
        public void Clear()
        {
            if (val1 != null)
            {
                //没用
                //val.Initialize();
                Array.Resize(ref val1, 0);
                Array.Resize(ref val1, w);
                currentValue1 = 0;
            }

            if (val2 != null)
            {
                //没用
                //val.Initialize();
                Array.Resize(ref val2, 0);
                Array.Resize(ref val2, w);
                currentValue2 = 0;
            }

            if (val3 != null)
            {
                //没用
                //val.Initialize();
                Array.Resize(ref val3, 0);
                Array.Resize(ref val3, w);
                currentValue3 = 0;
            }


        }
        #endregion
    }
}


DLL文件 : 链接:http://pan.baidu.com/s/1o8qUyka 密码:776f

三曲线源文件:链接:http://pan.baidu.com/s/1hrX3M2w 密码:kbzf

作者的源文件:链接:http://pan.baidu.com/s/1skJEt8T 密码:j10w