/// <summary> /// 实时段进度控件 /// </summary> [ToolboxItem(true)] [Description("实时段进度控件")] public partial class ChartExt : Control { #region private Timer interval; /// <summary> /// 定时刷新 /// </summary> [Browsable(false)] [Description("定时刷新")] public Timer Interval { get { return this.interval; } set { if (this.interval == value) return; this.interval = value; } } private int gridsWidthIntervalPixel = 15; /// <summary> /// 网格宽度间隔像素 /// </summary> [DefaultValue(15)] [Description("网格宽度间隔像素")] public int GridsWidthIntervalPixel { get { return this.gridsWidthIntervalPixel; } set { if (this.gridsWidthIntervalPixel == value) return; this.gridsWidthIntervalPixel = value; this.Invalidate(); } } private Color gridsColor = Color.Gainsboro; /// <summary> /// 网格颜色 /// </summary> [DefaultValue(typeof(Color), "Gainsboro")] [Description("网格颜色")] public Color GridsColor { get { return this.gridsColor; } set { if (this.gridsColor == value) return; this.gridsColor = value; this.Invalidate(); } } private int gridsHeightIntervalPixel = 15; /// <summary> /// 网格高度间隔像素 /// </summary> [DefaultValue(15)] [Description("网格高度间隔像素")] public int GridsHeightIntervalPixel { get { return this.gridsHeightIntervalPixel; } set { if (this.gridsHeightIntervalPixel == value) return; this.gridsHeightIntervalPixel = value; this.Invalidate(); } } private bool hLineShow = true; /// <summary> /// 是否显示横向鼠标线 /// </summary> [DefaultValue(true)] [Description("是否显示横向鼠标线")] public bool HLineShow { get { return this.hLineShow; } set { if (this.hLineShow == value) return; this.hLineShow = value; this.Invalidate(); } } private Color hLineColor = Color.FromArgb(200, 147, 112, 219); /// <summary> /// 横向鼠标线颜色 /// </summary> [DefaultValue(typeof(Color), "200, 147, 112, 219")] [Description("横向鼠标线颜色")] [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))] public Color HLineColor { get { return this.hLineColor; } set { if (this.hLineColor == value) return; this.hLineColor = value; this.Invalidate(); } } private bool vLineShow = true; /// <summary> /// 是否显示纵向鼠标线 /// </summary> [DefaultValue(true)] [Description("是否显示纵向鼠标线")] public bool VLineShow { get { return this.vLineShow; } set { if (this.vLineShow == value) return; this.vLineShow = value; this.Invalidate(); } } private Color vLineColor = Color.FromArgb(200, 147, 112, 219); /// <summary> /// 横鼠标向线颜色 /// </summary> [DefaultValue(typeof(Color), "200, 147, 112, 219")] [Description("渐变结束颜色")] [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))] public Color VLineColor { get { return this.vLineColor; } set { if (this.vLineColor == value) return; this.vLineColor = value; this.Invalidate(); } } private int chartColorGroupItemsOpacity = 200; /// <summary> /// 线区域背景颜色级别透明度 /// </summary> [DefaultValue(200)] [Description("线区域背景颜色级别透明度")] public int ChartColorGroupItemsOpacity { get { return this.chartColorGroupItemsOpacity; } set { if (this.chartColorGroupItemsOpacity == value || value < 0 || value > 255) return; this.chartColorGroupItemsOpacity = value; this.Invalidate(); } } private Color lineBackColor = Color.FromArgb(151, 147, 112, 219); /// <summary> /// 线区域背景颜色 /// </summary> [DefaultValue(typeof(Color), "151, 147, 112, 219")] [Description("线区域背景颜色")] [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))] public Color LineBackColor { get { return this.lineBackColor; } set { if (this.lineBackColor == value) return; this.lineBackColor = value; this.Invalidate(); } } private int lineThickness = 2; /// <summary> /// 线区边界厚度 /// </summary> [DefaultValue(2)] [Description("线区边界厚度")] public int LineThickness { get { return this.lineThickness; } set { if (this.lineThickness == value) return; this.lineThickness = value; this.Invalidate(); } } private Color lineColor = Color.FromArgb(147, 112, 219); /// <summary> /// 线区边界颜色 /// </summary> [DefaultValue(typeof(Color), "147, 112, 219")] [Description("线区边界颜色")] [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))] public Color LineColor { get { return this.lineColor; } set { if (this.lineColor == value) return; this.lineColor = value; this.Invalidate(); } } private bool lineDotShow = false; /// <summary> /// 是否显示线上圆点 /// </summary> [DefaultValue(false)] [Description("是否显示线上圆点")] public bool LineDotShow { get { return this.lineDotShow; } set { if (this.lineDotShow == value) return; this.lineDotShow = value; this.Invalidate(); } } private int lineDotRadius = 3; /// <summary> /// 线上圆点半径 /// </summary> [DefaultValue(3)] [Description("线上圆点半径")] public int LineDotRadius { get { return this.lineDotRadius; } set { if (this.lineDotRadius == value) return; this.lineDotRadius = value; this.Invalidate(); } } private Color lineDotColor = Color.FromArgb(147, 112, 219); /// <summary> /// 是否显示线上圆点颜色 /// </summary> [DefaultValue(typeof(Color), "147, 112, 219")] [Description("是否显示线上圆点颜色")] [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))] public Color LineDotColor { get { return this.lineDotColor; } set { if (this.lineDotColor == value) return; this.lineDotColor = value; this.Invalidate(); } } private Color tipBackColor = Color.FromArgb(151, 147, 112, 219); /// <summary> /// 提示背景颜色 /// </summary> [DefaultValue(typeof(Color), "151, 147, 112, 219")] [Description("提示背景颜色")] [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))] public Color TipBackColor { get { return this.tipBackColor; } set { if (this.tipBackColor == value) return; this.tipBackColor = value; this.Invalidate(); } } private Font tipFont = new Font("宋体", 11); /// <summary> /// 提示字体 /// </summary> [DefaultValue(typeof(Font), "宋体, 11pt")] [Description("提示字体")] public Font TipFont { get { return this.tipFont; } set { if (this.tipFont == value) return; this.tipFont = value; this.Invalidate(); } } private Color tipColor = Color.FromArgb(0, 0, 0); /// <summary> /// 提示字体颜色 /// </summary> [DefaultValue(typeof(Color), "0, 0, 0")] [Description("提示字体颜色")] [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))] public Color TipColor { get { return this.tipColor; } set { if (this.tipColor == value) return; this.tipColor = value; this.Invalidate(); } } private ChartColorType colorType = ChartColorType.Normal; /// <summary> /// 线区域背景颜色类型 /// </summary> [DefaultValue(ChartColorType.Normal)] [Description("线区域背景颜色类型")] public ChartColorType ColorType { get { return this.colorType; } set { if (this.colorType == value) return; this.colorType = value; this.Invalidate(); } } private ChartColorGroupCollection chartColorGroupCollection; /// <summary> /// 颜色级别配置集合 /// </summary> [Description("颜色级别配置集合")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public ChartColorGroupCollection ChartColorGroupItems { get { if (this.chartColorGroupCollection == null) this.chartColorGroupCollection = new ChartColorGroupCollection(this); return this.chartColorGroupCollection; } } [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))] public override Color BackColor { get { return base.BackColor; } set { base.BackColor = value; } } protected override Size DefaultSize { get { return new Size(300, 150); ; } } private ArrayList pathpoints; 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.Interval = 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, e.ClipRectangle.Width - 1, e.ClipRectangle.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) { float max = -1; float sum = 0; Point[] points = new Point[this.pathpoints.Count]; for (int i = 0; i < this.pathpoints.Count; i++) { if ((float)this.pathpoints[i] > max) max = (float)this.pathpoints[i]; sum += (float)this.pathpoints[i]; points[i] = new Point((int)(rectf.Width - i * this.GridsWidthIntervalPixel), (int)(rectf.Height - rectf.Height * (float)this.pathpoints[i])); } if (this.pathpoints.Count > 1) { GraphicsPath line_gp = new GraphicsPath(); GraphicsPath lineback_gp = new GraphicsPath(); line_gp.AddCurve(points, 0.5f); lineback_gp.AddCurve(points, 0.5f); lineback_gp.AddLine(points[this.pathpoints.Count - 1].X, e.ClipRectangle.Height, points[0].X, e.ClipRectangle.Height); Pen line_pen = new Pen(this.LineColor, this.LineThickness); Brush lineback_sb = null; LinearGradientBrush lineback_lgb = null; if (this.ColorType == ChartColorType.Normal) { lineback_sb = new SolidBrush(this.LineBackColor); } else { Color[] colors = new Color[this.ChartColorGroupItems.Count]; float[] interval = new float[this.ChartColorGroupItems.Count]; for (int i = 0; i < this.ChartColorGroupItems.Count; i++) { colors[i] = Color.FromArgb(this.ChartColorGroupItemsOpacity, this.ChartColorGroupItems[i].Color); interval[i] = this.ChartColorGroupItems[i].Interval; } //Positions开始值必须为0,结束值必须为1 interval[0] = 0.0f; interval[this.ChartColorGroupItems.Count - 1] = 1.0f; lineback_lgb = new LinearGradientBrush(e.ClipRectangle, Color.Transparent, Color.Transparent, 270); lineback_lgb.InterpolationColors = new ColorBlend() { Colors = colors, Positions = interval }; } g.FillPath(this.ColorType == ChartColorType.Normal ? lineback_sb : lineback_lgb, lineback_gp); g.DrawPath(line_pen, line_gp); line_gp.Dispose(); lineback_gp.Dispose(); line_pen.Dispose(); if (lineback_sb != null) lineback_sb.Dispose(); if (lineback_lgb != null) lineback_lgb.Dispose(); if (this.LineDotShow) { SolidBrush linedot_sb = new SolidBrush(this.LineDotColor); for (int i = 0; i < points.Count(); i++) { g.FillEllipse(linedot_sb, new Rectangle(points[i].X - this.LineDotRadius, points[i].Y - this.LineDotRadius, this.LineDotRadius * 2, this.LineDotRadius * 2)); } } } 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(this.TipBackColor); g.FillRectangle(maxback_sb, max_rect); g.DrawString(max_str, this.tipFont, max_sb, max_rect); string avg_str = String.Format("当前平均峰值:{0}%", (int)((sum / this.pathpoints.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(); } #endregion #region 鼠标线、鼠标值 if (this.enterLeave && this.movepoint != null) { #region 鼠标线 if (this.HLineShow) { Pen h_pen = new Pen(this.HLineColor); g.DrawLine(h_pen, 0, this.movepoint.Y, this.ClientRectangle.Width, this.movepoint.Y); h_pen.Dispose(); } if (this.vLineShow) { 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.ClientRectangle.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(this.TipBackColor); 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.ClientRectangle.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.interval != null) { this.interval.Dispose(); } } base.Dispose(disposing); } /// <summary> /// 颜色级别配置集合 /// </summary> [Description("颜色级别配置集合")] [Editor(typeof(CollectionEditorExt), typeof(UITypeEditor))] public sealed class ChartColorGroupCollection : IList, ICollection, IEnumerable { private ArrayList chartColorGroupList = new ArrayList(); private ChartExt owner; public ChartColorGroupCollection(ChartExt owner) { this.owner = owner; } #region IEnumerable public IEnumerator GetEnumerator() { ChartColorGroup[] listArray = new ChartColorGroup[this.chartColorGroupList.Count]; for (int index = 0; index < listArray.Length; ++index) listArray[index] = (ChartColorGroup)this.chartColorGroupList[index]; return listArray.GetEnumerator(); } #endregion #region ICollection public void CopyTo(Array array, int index) { for (int i = 0; i < this.Count; i++) array.SetValue(this.chartColorGroupList[i], i + index); } public int Count { get { return this.chartColorGroupList.Count; } } public bool IsSynchronized { get { return false; } } public object SyncRoot { get { return (object)this; } } #endregion #region IList public int Add(object value) { ChartColorGroup chartColorGroup = (ChartColorGroup)value; this.chartColorGroupList.Add(chartColorGroup); this.owner.Invalidate(); return this.Count - 1; } public void Clear() { this.chartColorGroupList.Clear(); this.owner.Invalidate(); } public bool Contains(object value) { return this.IndexOf(value) != -1; } public int IndexOf(object value) { return this.chartColorGroupList.IndexOf(value); } public void Insert(int index, object value) { throw new NotImplementedException(); } public bool IsFixedSize { get { return false; } } public bool IsReadOnly { get { return false; } } public void Remove(object value) { if (!(value is ChartColorGroup)) return; this.chartColorGroupList.Remove((ChartColorGroup)value); this.owner.Invalidate(); } public void RemoveAt(int index) { this.chartColorGroupList.RemoveAt(index); this.owner.Invalidate(); } public ChartColorGroup this[int index] { get { return (ChartColorGroup)this.chartColorGroupList[index]; } set { this.chartColorGroupList[index] = (ChartColorGroup)value; this.owner.Invalidate(); } } object IList.this[int index] { get { return (object)this.chartColorGroupList[index]; } set { this.chartColorGroupList[index] = (ChartColorGroup)value; this.owner.Invalidate(); } } #endregion } } /// <summary> /// 线区域背景颜色级别配置 /// </summary> [Description("线区域背景颜色级别配置")] public class ChartColorGroup { private float interval = 0f; /// <summary> ///颜色从该值开始渐变(0-1) /// </summary> [DefaultValue(0f)] [Description("颜色从该值开始渐变(0-1)")] public float Interval { get { return this.interval; } set { if (this.interval == value || value < 0 || value > 1) return; this.interval = value; } } private Color color = Color.Empty; /// <summary> /// 颜色 /// </summary> [DefaultValue(typeof(Color), "Empty")] [Description("颜色")] public Color Color { get { return this.color; } set { if (this.color == value) return; this.color = value; } } } /// <summary> /// 线区域背景颜色类型 /// </summary> [Description("线区域背景颜色类型")] public enum ChartColorType { /// <summary> /// 渐变 /// </summary> Gradient, /// <summary> /// 正常 /// </summary> Normal }
源码下载:实时段分析控件.zip