您的位置:首页 > 编程语言 > C#

Generic Chart Control in C# 一个通用的图表控件

2008-07-01 21:04 363 查看
这个control 是把原来 mfc 下的图形显示class 移植到 c# 下,做成一个更通用的 usercontrol.坐标变换 class:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Text;using System.Drawing; namespace Utility{       public class CAxis       {              protected float m_Scale;              protected float m_Offset;              public CAxis()              {                     m_ShowLabel = true;              }               protected float m_LogicMax;              public float LogicMax              {                     get { return m_LogicMax; }                     set { m_LogicMax = value; }              }               protected bool m_ShowLabel = true;              [DefaultValue(true)]              public bool ShowLabel              {                     get { return m_ShowLabel; }                     set { m_ShowLabel = value; }              }               protected string m_AxisUnit;              [DefaultValue(null)]              public string AxisUnit              {                     get { return m_AxisUnit; }                     set { m_AxisUnit = value; }              }               protected string m_FormatString = "F1";              [DefaultValue("F1")]              public string FormatString              {                     get { return m_FormatString; }                     set { m_FormatString = value; }              }                protected float m_LogicMin;              public float LogicMin              {                     get { return m_LogicMin; }                     set { m_LogicMin = value; }              }               protected bool m_Vertical;              public bool Vertical              {                     get { return m_Vertical; }                     set { m_Vertical = value; }              }                            protected Point m_Location;              public Point Location              {                     get { return m_Location; }                     set { m_Location = value; }              }               protected int m_Length;              public int Length              {                     get { return m_Length; }                     set { m_Length = value; }              }               protected int m_Step = 30;              [DefaultValue(30)]              public int Step              {                     get { return m_Step; }                     set { m_Step = value; }              }               protected float m_MinimumLogicStep = 0.0f;              public float MinimumLogicStep              {                     get { return m_MinimumLogicStep; }                     set { m_MinimumLogicStep = value; }              }               public float LogicScale              {                     get { return m_Scale; }              }               public int ToPhycical(float size)              {                     return (int) (m_Scale *size + m_Offset);              }               public float GetLogicStep()              {                     float logicSize = m_LogicMax - m_LogicMin;                     m_Scale = m_Length / logicSize;                     m_Offset = -m_Length * m_LogicMin / logicSize;                      double x = Math.Log10(logicSize * m_Step / m_Length);                      int           int_part = (x >= 0) ? (int)(x+0.1f) : (int)(x-0.1f) - 1;                     double       x2 = Math.Pow(10, (double) x - int_part);                     double       x3 = Math.Pow(10, (double) int_part);                     int x4 = (int)(x2+0.1f);                     int y1 = 20;                     if (x4 < 10) y1 = 10;                     if (x4 < 5) y1 = 5;                     if (x4 < 2) y1 = 2;                     if (x4 < 1) y1 = 1;                     float dy = (float) (y1 * x3);                     return dy < m_MinimumLogicStep ? m_MinimumLogicStep : dy;              }               public void DrawGrid(Graphics g, Pen pen, Font font, int length, bool showLabel)              {                     int p;                     string s;                     float logicSize = m_LogicMax - m_LogicMin;                     float dy = GetLogicStep();                     if (m_Vertical) {                            for (double y = m_LogicMin; y <= m_LogicMax; y += dy) {                                   y = (float) ((int) (y / dy + (y >= 0 ? 0.01f : -0.01f)) * dy);                                   if (y >= m_LogicMin) {                                          p = m_Location.Y - (int) (m_Scale * y + m_Offset);                                          if (y == 0.0f) {                                                 g.DrawLine(Pens.Silver, m_Location.X, p, m_Location.X + length, p);                                                 s = "0";                                          }                                          else {                                                 g.DrawLine(pen, m_Location.X, p, m_Location.X + length, p);                                                 s = y.ToString(m_FormatString);                                          }                                          if (m_ShowLabel && showLabel) {                                                 SizeF sf = g.MeasureString(s, font);                                                 g.DrawString(s, font, Brushes.Black, m_Location.X - sf.Width - 4, p - sf.Height / 2);                                          }                                   }                            }                            if (m_AxisUnit != null && m_AxisUnit.Length > 0) {                                   g.DrawString(m_AxisUnit, font, Brushes.Black, m_Location.X + 1, m_Location.Y - m_Length + 1);                            }                     }                     else {                            for (float y = m_LogicMin; y <= m_LogicMax; y += dy) {                                   y = (float) ((int) (y / dy + (y >= 0 ? 0.01f : -0.01f)) * dy);                                   if (y >= m_LogicMin) {                                          p = m_Location.X + (int) (m_Scale * y + m_Offset);                                          if (y == 0.0f) {                                                 g.DrawLine(Pens.Silver, p, m_Location.Y, p, m_Location.Y - length);                                                 s = "0";                                          }                                          else {                                                 g.DrawLine(pen, p, m_Location.Y, p, m_Location.Y - length);                                                 s = y.ToString(m_FormatString);                                          }                                          if (m_ShowLabel && showLabel) {                                                 SizeF sf = g.MeasureString(s, font);                                                 g.DrawString(s, font, Brushes.Black, p - sf.Width / 2, m_Location.Y + sf.Height / 2 - 2);                                          }                                   }                            }                            if (m_AxisUnit != null && m_AxisUnit.Length > 0) {                                   SizeF sf = g.MeasureString(m_AxisUnit, font);                                   g.DrawString(m_AxisUnit, font, Brushes.Black, m_Location.X + m_Length - sf.Width - 1, m_Location.Y - sf.Height - 1);                            }                     }              }        }}
Chart Control:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing;using System.Data;using System.Text;using System.Windows.Forms;namespace Utility{public partial class ChartControl : UserControl{protected bool m_bRebuilt = false;protected bool m_bSizeChanged = true;protected CMemoryGraph m_Graph;protected CMemoryGraph m_ChartGraph;protected Point m_StartPoint;protected Pen m_AxisPen;protected Point m_DragPoint;protected bool m_bBeginDrag = false;protected SolidBrush m_PlotBackgroundBrush;public PaintEventHandler OnDrawChart;public PaintEventHandler OnBeforeDrawChart;public PaintEventHandler OnAfterDrawChart;public ChartControl(){InitializeComponent();m_Graph = new CMemoryGraph();m_XAxis = new CAxis();m_YAxis = new CAxis();m_PlotRectangle = new Rectangle();m_StartPoint = new Point();m_XAxis.Vertical = false;m_YAxis.Vertical = true;m_LeftTopMargin = new Point(56, 10);m_RightBottomMargin = new Point(16, 40);m_Graph.Location = new Point(0, 0);m_AxisPen = new Pen(Color.LightGray);m_AxisPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;m_PlotBackgroundBrush = new SolidBrush(Color.White);// m_BackgroundColor = this.BackColor;}#region Propertiesprotected bool m_bYAxisFollowXAxis = false;[DefaultValue(false)]public bool YAxisFollowXAxis{get { return m_bYAxisFollowXAxis; }set { m_bYAxisFollowXAxis = value; }}public CMemoryGraph MemoryGraph{get { return m_Graph; }}protected CAxis m_XAxis;public CAxis XAxis{get { return m_XAxis; }set { m_XAxis = value; }}protected CAxis m_YAxis;public CAxis YAxis{get { return m_YAxis; }set { m_YAxis = value; }}protected Point m_LeftTopMargin;[DefaultValue(typeof(System.Drawing.Point), "56,10")]public Point LeftTopMargin{get { return m_LeftTopMargin; }set { m_LeftTopMargin = value; }}protected Point m_RightBottomMargin;[DefaultValue(typeof(System.Drawing.Point), "16,40")]public Point RightBottomMargin{get { return m_RightBottomMargin; }set { m_RightBottomMargin = value; }}protected float m_XLogicMax;public float XLogicMax{get { return m_XLogicMax; }set { m_XLogicMax = value; }}protected float m_XLogicMin;[DefaultValue(0f)]public float XLogicMin{get { return m_XLogicMin; }set { m_XLogicMin = value; }}protected float m_YLogicMax;public float YLogicMax{get { return m_YLogicMax; }set { m_YLogicMax = value; }}protected float m_YLogicMin;[DefaultValue(0f)]public float YLogicMin{get { return m_YLogicMin; }set { m_YLogicMin = value; }}protected string m_YTitle;[DefaultValue(null)]public string YTitle{get { return m_YTitle; }set { m_YTitle = value; }}protected string m_XTitle;[DefaultValue(null)]public string XTitle{get { return m_XTitle; }set { m_XTitle = value; }}protected int m_YTitleLeftMargin = 8;[DefaultValue(8)]public int YTitleLeftMargin{get { return m_YTitleLeftMargin; }set { m_YTitleLeftMargin = value; }}protected int m_XTitleBottomMargin = 6;[DefaultValue(6)]public int XTitleBottomMargin{get { return m_XTitleBottomMargin; }set { m_XTitleBottomMargin = value; }}protected PointF[] m_PlotPoints = null;[DefaultValue(null)]public PointF[] PlotPoints{get { return m_PlotPoints; }set { m_PlotPoints = value; }}protected Color m_PlotColor = Color.Blue;[DefaultValue(typeof(Color), "Blue")]public Color PlotColor{get { return m_PlotPen.Color; }set { m_PlotPen.Color = value; }}[DefaultValue(typeof(Color), "White")]public Color PlotBackgroundColor{get { return m_PlotBackgroundBrush.Color; }set { m_PlotBackgroundBrush.Color = value; }}[DefaultValue(1)]public int PlotPenWidth{get { return (int) m_PlotPen.Width; }set { m_PlotPen.Width = value; }}protected bool m_PlotTypeIsBar;[DefaultValue(false)]public bool PlotTypeIsBar{get { return m_PlotTypeIsBar; }set { m_PlotTypeIsBar = value; }}protected Pen m_PlotPen = new Pen(Color.Blue, 1);public Pen PlotPen{get { return m_PlotPen; }}protected Rectangle m_PlotRectangle;public Rectangle PlotRectangle{get { return m_PlotRectangle; }}public int LogicToX(float x){return m_XAxis.ToPhycical(x);}protected PointF m_MaxLogicLimit;public PointF MaxLogicLimit{// get { return m_MaxLogicLimit; }set { m_MaxLogicLimit = value; }}protected PointF m_MinLogicLimit;public PointF MinLogicLimit{// get { return m_MinLogicLimit; }set { m_MinLogicLimit = value; }}#endregionprotected SolidBrush m_FontBrush;protected override void OnLoad(EventArgs e){base.OnLoad(e);m_FontBrush = new SolidBrush(this.ForeColor);}protected override void OnPaint(PaintEventArgs e){if (m_bRebuilt) {Graphics g;if (m_bSizeChanged) {m_PlotRectangle = new Rectangle(m_LeftTopMargin.X, m_LeftTopMargin.Y,this.Size.Width - m_LeftTopMargin.X - m_RightBottomMargin.X,this.Size.Height - m_LeftTopMargin.Y - m_RightBottomMargin.Y);g = m_Graph.CreateMemoryGraphics(this.ClientSize);m_bSizeChanged = false;}else {g = m_Graph.MemoryGraphics;g.ResetClip();g.ResetTransform();}m_Graph.EraseBackground(this.BackColor);if (m_PlotBackgroundBrush.Color != this.BackColor) {g.FillRectangle(m_PlotBackgroundBrush, m_PlotRectangle);}m_XAxis.Location = new Point(m_LeftTopMargin.X, this.Size.Height - m_RightBottomMargin.Y);m_XAxis.Length = m_PlotRectangle.Size.Width;m_XAxis.LogicMax = m_XLogicMax;m_XAxis.LogicMin = m_XLogicMin;m_XAxis.DrawGrid(g, m_AxisPen, this.Font, m_PlotRectangle.Size.Height, true);m_YAxis.Location = new Point(m_LeftTopMargin.X, this.Size.Height - m_RightBottomMargin.Y);m_YAxis.Length = m_PlotRectangle.Size.Height;if (m_bYAxisFollowXAxis) {m_YLogicMax = m_YLogicMin + (m_XLogicMax - m_XLogicMin) * m_YAxis.Length / m_XAxis.Length;}m_YAxis.LogicMin = m_YLogicMin;m_YAxis.LogicMax = m_YLogicMax;m_YAxis.DrawGrid(g, m_AxisPen, this.Font, m_PlotRectangle.Size.Width, true);if (m_XTitle != null && m_XTitle.Length > 0) {SizeF sf = g.MeasureString(m_XTitle, SystemFonts.DefaultFont);g.DrawString(m_XTitle, SystemFonts.DefaultFont, m_FontBrush, (this.Size.Width - sf.Width) / 2, this.Size.Height - sf.Height - m_XTitleBottomMargin);}if (m_YTitle != null && m_YTitle.Length > 0) {SizeF sf = g.MeasureString(m_YTitle, SystemFonts.DefaultFont);g.TranslateTransform(m_YTitleLeftMargin, m_YAxis.Location.Y - (m_YAxis.Length - sf.Width) / 2);g.RotateTransform(270.0f);g.DrawString(m_YTitle, SystemFonts.DefaultFont, m_FontBrush, 0, 0);g.ResetTransform();}g.DrawRectangle(Pens.Black, m_LeftTopMargin.X-1, m_LeftTopMargin.Y-1, m_XAxis.Length+2, m_YAxis.Length+2);if (OnBeforeDrawChart != null)OnBeforeDrawChart(this, e);g.SetClip(m_PlotRectangle);g.TranslateTransform(m_LeftTopMargin.X, m_LeftTopMargin.Y);if (OnDrawChart != null)OnDrawChart(this, e);m_bRebuilt = false;}m_Graph.PaintToScreen(e.Graphics);e.Graphics.SetClip(m_PlotRectangle);if (OnAfterDrawChart != null) {e.Graphics.TranslateTransform(m_LeftTopMargin.X, m_LeftTopMargin.Y);OnAfterDrawChart(this, e);}}public void UpdateChart(){Graphics g = m_Graph.MemoryGraphics;g.ResetTransform();g.FillRectangle(Brushes.White, m_PlotRectangle);m_XAxis.DrawGrid(g, m_AxisPen, this.Font, m_PlotRectangle.Size.Height, false);m_YAxis.DrawGrid(g, m_AxisPen, this.Font, m_PlotRectangle.Size.Width, false);g.DrawRectangle(Pens.Black, m_LeftTopMargin.X - 1, m_LeftTopMargin.Y - 1, m_XAxis.Length + 2, m_YAxis.Length + 2);if (OnBeforeDrawChart != null)OnBeforeDrawChart(this, null);g.SetClip(m_PlotRectangle);g.TranslateTransform(m_LeftTopMargin.X, m_LeftTopMargin.Y);if (OnDrawChart != null)OnDrawChart(this, null);this.Invalidate();}public void PlotLines(Graphics g){if (m_PlotPoints != null && m_PlotPoints.Length > 0) {if (m_PlotTypeIsBar) {for (int i = 0; i < m_PlotPoints.Length; i++) {DrawLine(m_PlotPen, m_PlotPoints[i].X, 0, m_PlotPoints[i].X, m_PlotPoints[i].Y);}}else {SetLogicStartPoint(m_PlotPoints[0]);for (int i = 1; i < m_PlotPoints.Length; i++) {DrawLineTo(m_PlotPen, m_PlotPoints[i]);}}}}public int LogicToY(float y){return m_YAxis.Length - m_YAxis.ToPhycical(y);}public void SetLogicStartPoint(float x, float y){m_StartPoint.X = m_XAxis.ToPhycical(x);m_StartPoint.Y = m_YAxis.Length - m_YAxis.ToPhycical(y);}public void SetLogicStartPoint(PointF point){m_StartPoint.X = m_XAxis.ToPhycical(point.X);m_StartPoint.Y = m_YAxis.Length - m_YAxis.ToPhycical(point.Y);}public void DrawLine(Pen pen, float x1, float y1, float x2, float y2){m_Graph.MemoryGraphics.DrawLine(pen, LogicToX(x1), LogicToY(y1), LogicToX(x2), LogicToY(y2));}public void DrawLine(Pen pen, PointF point1, PointF point2){m_Graph.MemoryGraphics.DrawLine(pen, LogicToX(point1.X), LogicToY(point1.Y), LogicToX(point2.X), LogicToY(point2.Y));}public void DrawLineTo(Pen pen, float x, float y){int x1 = LogicToX(x);int y1 = LogicToY(y);m_Graph.MemoryGraphics.DrawLine(pen, m_StartPoint.X, m_StartPoint.Y, x1, y1);m_StartPoint.X = x1;m_StartPoint.Y = y1;}public void DrawLineTo(Pen pen, PointF point){int x1 = LogicToX(point.X);int y1 = LogicToY(point.Y);m_Graph.MemoryGraphics.DrawLine(pen, m_StartPoint.X, m_StartPoint.Y, x1, y1);m_StartPoint.X = x1;m_StartPoint.Y = y1;}public void DrawCircle(Pen pen, float originX, float originY, float radius){int x1 = LogicToX(originX - radius);int y1 = LogicToY(originY + radius);int x2 = LogicToX(originX + radius);int y2 = LogicToY(originY - radius);m_Graph.MemoryGraphics.DrawEllipse(pen, x1, y2, x2 - x1, y1 - y2);}//*********************************************************************************//public void DrawLine(Graphics g, Pen pen, float x1, float y1, float x2, float y2){g.DrawLine(pen, LogicToX(x1), LogicToY(y1), LogicToX(x2), LogicToY(y2));}public void DrawLine(Graphics g, Pen pen, PointF point1, PointF point2){g.DrawLine(pen, LogicToX(point1.X), LogicToY(point1.Y), LogicToX(point2.X), LogicToY(point2.Y));}public void DrawLineTo(Graphics g, Pen pen, float x, float y){int x1 = LogicToX(x);int y1 = LogicToY(y);g.DrawLine(pen, m_StartPoint.X, m_StartPoint.Y, x1, y1);m_StartPoint.X = x1;m_StartPoint.Y = y1;}public void DrawLineTo(Graphics g, Pen pen, PointF point){int x1 = LogicToX(point.X);int y1 = LogicToY(point.Y);g.DrawLine(pen, m_StartPoint.X, m_StartPoint.Y, x1, y1);m_StartPoint.X = x1;m_StartPoint.Y = y1;}public void DrawCircle(Graphics g, Pen pen, float originX, float originY, float radius){int x1 = LogicToX(originX - radius);int y1 = LogicToY(originY + radius);int x2 = LogicToX(originX + radius);int y2 = LogicToY(originY - radius);g.DrawEllipse(pen, x1, y2, x2 - x1, y1 - y2);}//*********************************************************************************//protected override void OnResize(EventArgs e){m_bSizeChanged = true;base.OnResize(e);Refresh();}public override void Refresh(){m_bRebuilt = true;base.Refresh();}protected override void OnPaintBackground(PaintEventArgs e){}//*********************************************************************************//public void MoveUpDown(float ratio){float fx = (XLogicMax - XLogicMin) * ratio;if (fx > 0 && m_XLogicMax < m_MaxLogicLimit.X) {if ((m_XLogicMax + fx) > m_MaxLogicLimit.X)fx = m_MaxLogicLimit.X - m_XLogicMax;m_XLogicMax += fx;m_XLogicMin += fx;Refresh();}else if (fx < 0 && m_XLogicMin > m_MinLogicLimit.X) {if ((m_XLogicMin + fx) < m_MinLogicLimit.X)fx = m_MinLogicLimit.X - m_XLogicMin;m_XLogicMax += fx;m_XLogicMin += fx;Refresh();}}public void MoveLeftRigh(float ratio){float fy = (YLogicMax - YLogicMin) * ratio;if (fy > 0 && m_YLogicMax < m_MaxLogicLimit.Y) {if ((m_YLogicMax + fy) > m_MaxLogicLimit.Y)fy = m_MaxLogicLimit.Y - m_YLogicMax;m_YLogicMax += fy;m_YLogicMin += fy;Refresh();}else if (fy < 0 && m_YLogicMin > m_MinLogicLimit.Y) {if ((m_YLogicMin + fy) < m_MinLogicLimit.Y)fy = m_MinLogicLimit.Y - m_YLogicMin;m_YLogicMax += fy;m_YLogicMin += fy;Refresh();}}public void ZoomIn(float ratio, float limitX, float limitY){float dx = XLogicMax - XLogicMin;float dy = YLogicMax - YLogicMin;float rx = dx * ratio;float ry = dy * ratio;if (dx > limitX && dy > limitY) {XLogicMax -= rx;XLogicMin += rx;YLogicMax -= ry;YLogicMin += ry;this.Refresh();}}public void ZoomOut(float ratio){float dx = XLogicMax - XLogicMin;float dy = YLogicMax - YLogicMin;float rx = dx * ratio;float ry = dy * ratio;float x1 = XLogicMax + rx;float x2 = XLogicMin - rx;float y1 = YLogicMax + ry;float y2 = YLogicMin - ry;if ( dx < (m_MaxLogicLimit.X - m_MinLogicLimit.X) ||dy < (m_MaxLogicLimit.Y - m_MinLogicLimit.Y)) {XLogicMax = x1;XLogicMin = x2;YLogicMax = y1;YLogicMin = y2;this.Refresh();}}//*********************************************************************************//protected override void OnMouseDown(MouseEventArgs e){if (!AllowDrop) return;if (e.Button == MouseButtons.Left) {m_DragPoint = new Point(e.X, e.Y);if (m_PlotRectangle.Contains(m_DragPoint)) {m_bBeginDrag = true;this.Cursor = Cursors.Hand;base.OnMouseDown(e);}}}protected override void OnMouseUp(MouseEventArgs e){if (!AllowDrop) return;if (e.Button == MouseButtons.Left && m_bBeginDrag) {if (m_PlotRectangle.Contains(e.X, e.Y)) {int x = -e.X + m_DragPoint.X;int y = e.Y - m_DragPoint.Y;float fx = x / m_XAxis.LogicScale;float fy = y / m_YAxis.LogicScale;if (fx > 0 && m_XLogicMax < m_MaxLogicLimit.X) {if ((m_XLogicMax + fx) > m_MaxLogicLimit.X)fx = m_MaxLogicLimit.X -m_XLogicMax;m_XLogicMax += fx;m_XLogicMin += fx;m_bRebuilt = true;}else if (fx < 0 && m_XLogicMin > m_MinLogicLimit.X) {if ((m_XLogicMin + fx) < m_MinLogicLimit.X)fx = m_MinLogicLimit.X - m_XLogicMin;m_XLogicMax += fx;m_XLogicMin += fx;m_bRebuilt = true;}if (fy > 0 && m_YLogicMax < m_MaxLogicLimit.Y) {if ((m_YLogicMax + fy) > m_MaxLogicLimit.Y)fy = m_MaxLogicLimit.Y - m_YLogicMax;m_YLogicMax += fy;m_YLogicMin += fy;m_bRebuilt = true;}else if (fy < 0 && m_YLogicMin > m_MinLogicLimit.Y) {if ((m_YLogicMin + fy) < m_MinLogicLimit.Y)fy = m_MinLogicLimit.Y - m_YLogicMin;m_YLogicMax += fy;m_YLogicMin += fy;m_bRebuilt = true;}this.Cursor = Cursors.Default;base.OnMouseUp(e);base.Refresh();}}m_bBeginDrag = false;}}}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐