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

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控件开发系列

上一篇:C#中string.Join的用法


下一篇:C#中int[] 转 string[] 的代码