Chart实时段分析控件----------WinForm控件开发系列

Posted tlmbem

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Chart实时段分析控件----------WinForm控件开发系列相关的知识,希望对你有一定的参考价值。

技术图片

  /// <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

以上是关于Chart实时段分析控件----------WinForm控件开发系列的主要内容,如果未能解决你的问题,请参考以下文章

使用Chart控件进行实时监控

C#使用chart绘制实时折线图,波形图叠加

VS2010 Chart控件报错

VS控件Chart的使用

winform Chart控件动态曲线图数据多了会卡,怎么解决

C#中ZedGraph控件怎么没有myPane.chart.Fill?