/// <summary> /// 实时段进度控件 /// </summary> [ToolboxItem(true)] [Description("实时段进度控件")] public partial class ChartExt : Control { #region private Timer timeInterval; /// <summary> /// 定时刷新 /// </summary> [Description("定时刷新")] public Timer TimeInterval { get { return this.timeInterval; } set { this.timeInterval = value; } } private Color gridsColor = Color.Gainsboro; /// <summary> /// 网格默认颜色 /// </summary> [DefaultValue(typeof(Color), "Gainsboro")] [Description("网格默认颜色")] public Color GridsColor { get { return this.gridsColor; } set { this.gridsColor = value; this.Invalidate(); } } private int gridsWidthIntervalPixel = 10; /// <summary> /// 网格宽度间隔像素 /// </summary> [DefaultValue(10)] [Description("网格宽度间隔像素")] public int GridsWidthIntervalPixel { get { return this.gridsWidthIntervalPixel; } set { this.gridsWidthIntervalPixel = value; this.Invalidate(); } } private int gridsHeightIntervalPixel = 10; /// <summary> /// 网格高度间隔像素 /// </summary> [DefaultValue(10)] [Description("网格高度间隔像素")] public int GridsHeighIntervalPixel { get { return this.gridsHeightIntervalPixel; } set { this.gridsHeightIntervalPixel = value; this.Invalidate(); } } private bool showHLine = true; /// <summary> /// 是否显示横向鼠标线 /// </summary> [DefaultValue(true)] [Description("是否显示横向鼠标线")] public bool ShowHLine { get { return this.showHLine; } set { if (this.showHLine == value) return; this.showHLine = value; this.Invalidate(); } } private Color hLineColor = Color.DeepSkyBlue; /// <summary> /// 横向鼠标线颜色 /// </summary> [DefaultValue(typeof(Color), "DeepSkyBlue")] [Description("横向鼠标线颜色")] public Color HLineColor { get { return this.hLineColor; } set { this.hLineColor = value; this.Invalidate(); } } private bool showVLine = true; /// <summary> /// 是否显示纵向鼠标线 /// </summary> [DefaultValue(true)] [Description("是否显示纵向鼠标线")] public bool ShowVLine { get { return this.showVLine; } set { if (this.showVLine == value) return; this.showVLine = value; this.Invalidate(); } } private Color vLineColor = Color.DeepSkyBlue; /// <summary> /// 横鼠标向线颜色 /// </summary> [DefaultValue(typeof(Color), "DeepSkyBlue")] [Description("渐变结束颜色")] public Color VLineColor { get { return this.vLineColor; } set { this.vLineColor = value; this.Invalidate(); } } private Color lineColor = Color.YellowGreen; /// <summary> /// 线颜色 /// </summary> [DefaultValue(typeof(Color), "YellowGreen")] [Description("线颜色")] public Color LineColor { get { return this.lineColor; } set { this.lineColor = value; this.Invalidate(); } } private int lineWidth = 2; /// <summary> /// 线宽度 /// </summary> [DefaultValue(2)] [Description("线宽度")] public int LineWidth { get { return this.lineWidth; } set { this.lineWidth = value; this.Invalidate(); } } private Font tipFont = new Font("宋体", 11); /// <summary> /// 提示字体 /// </summary> [DefaultValue(typeof(Color), "宋体, 11")] [Description("提示字体")] public Font TipFont { get { return this.tipFont; } set { this.tipFont = value; this.Invalidate(); } } private Color tipColor = Color.Black; /// <summary> /// 提示字体颜色 /// </summary> [DefaultValue(typeof(Color), "Black")] [Description("提示字体颜色")] public Color TipColor { get { return this.tipColor; } set { this.tipColor = value; this.Invalidate(); } } private Color tipBackColor = Color.SlateBlue; /// <summary> /// 提示背景颜色 /// </summary> [DefaultValue(typeof(Color), "SlateBlue")] [Description("提示背景颜色")] public Color TipBackColor { get { return this.tipBackColor; } set { this.tipBackColor = value; this.Invalidate(); } } private ArrayList pathpoints; protected override Size DefaultSize { get { return new Size(300, 150); ; } } private Point movepoint = new Point(0, 0);//鼠标坐标 private bool enterLeave = false;//鼠标状态 #endregion public ChartExt() { SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.OptimizedDoubleBuffer, true); SetStyle(ControlStyles.ResizeRedraw, true); SetStyle(ControlStyles.SupportsTransparentBackColor, true); InitializeComponent(); this.pathpoints = new ArrayList(); this.pathpoints.Add(0.0f); this.timeInterval = new Timer(); } protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; g.CompositingQuality = CompositingQuality.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBilinear; g.SmoothingMode = SmoothingMode.AntiAlias; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; RectangleF rectf = new RectangleF(0, 0, this.Width - 1, this.Height - 1); #region 网格 Pen grids_pen = new Pen(this.gridsColor); g.DrawRectangle(grids_pen, rectf.X, rectf.Y, rectf.Width, rectf.Height);//外边框 int r_count = (int)Math.Ceiling(rectf.Height / (float)this.gridsHeightIntervalPixel);//行线 for (int i = r_count - 1; i > -1; i--) { float y = rectf.Height - this.gridsHeightIntervalPixel * i; g.DrawLine(grids_pen, 0, y, rectf.Width, y); } int c_count = (int)Math.Ceiling(rectf.Width / (float)this.gridsWidthIntervalPixel);//列线 c_count++; for (int i = 0; i < c_count; i++) { float x = this.gridsWidthIntervalPixel * i; g.DrawLine(grids_pen, x, 0, x, rectf.Height); } grids_pen.Dispose(); #endregion #region 线 if (this.pathpoints != null) { Pen line_sb = new Pen(this.lineColor, this.lineWidth); float max = -1; int count = this.pathpoints.Count; float sum = 0; for (int i = 0; i < this.pathpoints.Count - 1; i++) { if ((float)this.pathpoints[i] > max) max = (float)this.pathpoints[i]; sum += (float)this.pathpoints[i]; Point start_point = new Point((int)(rectf.Width - (i + 1) * this.gridsWidthIntervalPixel), (int)(rectf.Height - rectf.Height * (float)this.pathpoints[i + 1])); Point end_point = new Point((int)(rectf.Width - i * this.gridsWidthIntervalPixel), (int)(rectf.Height - rectf.Height * (float)this.pathpoints[i])); g.DrawLine(line_sb, start_point, end_point); } string max_str = String.Format("当前最大峰值:{0}%", (int)(max * rectf.Height)); SizeF max_size = g.MeasureString("当前最大峰值:100%", this.tipFont); Rectangle max_rect = new Rectangle(10, 10, (int)max_size.Width + 1, (int)max_size.Height); SolidBrush max_sb = new SolidBrush(this.tipColor); SolidBrush maxback_sb = new SolidBrush(Color.FromArgb(150, this.TipBackColor.R, this.TipBackColor.G, this.TipBackColor.B)); g.FillRectangle(maxback_sb, max_rect); g.DrawString(max_str, this.tipFont, max_sb, max_rect); string avg_str = String.Format("当前平均峰值:{0}%", (int)((sum / count) * 100)); Rectangle avg_rect = new Rectangle(10, 10 + (int)max_size.Height + 10, (int)max_size.Width + 1, (int)max_size.Height); g.FillRectangle(maxback_sb, avg_rect); g.DrawString(avg_str, this.tipFont, max_sb, avg_rect); max_sb.Dispose(); maxback_sb.Dispose(); line_sb.Dispose(); } #endregion #region 鼠标线、鼠标值 if (this.enterLeave && this.movepoint != null) { #region 鼠标线 if (this.showHLine) { Pen h_pen = new Pen(this.hLineColor); g.DrawLine(h_pen, 0, this.movepoint.Y, this.Width, this.movepoint.Y); h_pen.Dispose(); } if (this.showVLine) { Pen v_pen = new Pen(this.vLineColor); g.DrawLine(v_pen, this.movepoint.X, 0, this.movepoint.X, this.Height); v_pen.Dispose(); } #endregion #region 鼠标值 string str = String.Format("{0}%", (int)(((rectf.Height - this.movepoint.Y) / rectf.Height) * 100)); SolidBrush str_sb = new SolidBrush(this.tipColor); SizeF s = g.MeasureString(str, this.tipFont); Rectangle str_rect = new Rectangle(this.movepoint.X + 5, this.movepoint.Y - (int)s.Height - 5, (int)s.Width, (int)s.Height); if (str_rect.Right > this.Width) { str_rect.X = this.movepoint.X - str_rect.Width - 5; } if (str_rect.Y < 0) { str_rect.Y = this.movepoint.Y + 20 + 5; } SolidBrush back_sb = new SolidBrush(Color.FromArgb(150, this.TipBackColor.R, this.TipBackColor.G, this.TipBackColor.B)); g.FillRectangle(back_sb, str_rect); g.DrawString(str, this.tipFont, str_sb, str_rect.X, str_rect.Y); back_sb.Dispose(); str_sb.Dispose(); #endregion } #endregion } protected override void OnMouseEnter(EventArgs e) { base.OnMouseEnter(e); this.enterLeave = true; this.Invalidate(); } protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); this.enterLeave = false; this.Invalidate(); } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (e.Location != this.movepoint) { this.movepoint = e.Location; this.Invalidate(); } } public void AddPathPoint(float value) { ArrayList al = new ArrayList(); al.Add(value); for (int i = 0; i < this.pathpoints.Count; i++) { if (this.Width - i * this.gridsWidthIntervalPixel >= 0) { al.Add(this.pathpoints[i]); } else { break; } } this.pathpoints = al; this.Invalidate(); } protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); if (this.timeInterval != null) { this.timeInterval.Dispose(); } } base.Dispose(disposing); } }