Microsoft Chart Controls(簡稱MSChart)控件,給圖形統計和報表圖形顯示提供了很好的解決辦法,同時支持Web和WinForm兩種方式。
MSChart 在.NET 4.0自帶的有,.NET 3.5 需要下載相應的插件(如果用的是VS2010做開發但是選擇的版本是3.5的而不是默認的4.0話,請按本文介紹的.NET 3.5 進行插件安裝),
官方例子(web和winform):http://archive.msdn.microsoft.com/mschart/Release/ProjectReleases.aspx?ReleaseId=4418
插件下載地址:http://archive.msdn.microsoft.com/mschart,把下面四個下載完成后把前三個按順序安裝
- Chart Controls for .NET Framework 3.5 (Beginning in .NET Framework 4, the Chart controls are part of the .NET Framework.)
- Chart Controls for .NET Framework 3.5 Language Pack
- Chart Controls Add-on for Visual Studio 2008
- Chart Controls for .NET Framework Documentation
安裝完成之后,在C:\Program Files\Microsoft Chart Controls\Assemblies可以獲取到web和winform的DLL。對於.NET 3.5 只需要把 System.Windows.Forms.DataVisualization.dll 添加到工具箱即可獲得圖表控件。前台只需要從工具箱拖一個Chart控件即可,如下圖所示:

本文用MSChart實現Winform曲線圖的繪制,本文結合自己的實際項目,每個點需要顯示到秒(這也是本文需要解決的關鍵點),剛開始照着網上的例子實現了一下,樣子是出來了,但是當數據一多並且顯示到秒時用鼠標進行拖動放大頁面會直接卡死,后來經過自己的一番探索和研究,終於把這個問題給解決了,故把整個實現過程記錄下來,和大家分享一下。
在文章的后面附上了源碼,源碼有詳細的代碼注釋,一些需要注意的屬性設置都有說明,可以實現刻度到秒的拖動放大,兩條紅色分別我定義是Min和Max值基准,是為了表達一個區間的概念。頁面上繪制了一千個點,每個點上有相應的ToolTip提示。代碼沒有做拆分,只是把整個創建及設置的流程給描述下來,是為了讓需要的朋友更好的理解和使用,第一次寫博文,希望大家給予指正與支持,謝謝。
附上效果圖:



附上后台源碼:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; using Hyet.Dal; using Hxj.Model; using Hxj.Data; using System.Collections; using Hyet.BLL; namespace DigitalFactory.ReportForms { public partial class ChartInfo : Form { public ChartInfo() { InitializeComponent(); InitializeChart(); this.myChart.GetToolTipText += new EventHandler<ToolTipEventArgs>(myChart_GetToolTipText); } private void InitializeChart() { myChart.ChartAreas.Clear(); myChart.Series.Clear(); #region 設置圖表的屬性 //圖表的背景色 myChart.BackColor = Color.FromArgb(211, 223, 240); //圖表背景色的漸變方式 myChart.BackGradientStyle = GradientStyle.TopBottom; //圖表的邊框顏色、 myChart.BorderlineColor = Color.FromArgb(26, 59, 105); //圖表的邊框線條樣式 myChart.BorderlineDashStyle = ChartDashStyle.Solid; //圖表邊框線條的寬度 myChart.BorderlineWidth = 2; //圖表邊框的皮膚 myChart.BorderSkin.SkinStyle = BorderSkinStyle.Emboss; #endregion #region 設置圖表的標題 Title title = new Title(); //標題內容 title.Text = "曲線圖"; //標題的字體 title.Font = new System.Drawing.Font("Microsoft Sans Serif", 12, FontStyle.Bold); //標題字體顏色 title.ForeColor = Color.FromArgb(26, 59, 105); //標題陰影顏色 title.ShadowColor = Color.FromArgb(32, 0, 0, 0); //標題陰影偏移量 title.ShadowOffset = 3; myChart.Titles.Add(title); #endregion #region 設置圖例的屬性 //注意,需要把原來控件自帶的圖例刪除掉 this.myChart.Legends.Clear(); Legend legend = new Legend("Default"); legend.Alignment = StringAlignment.Center; legend.Docking = Docking.Bottom; legend.LegendStyle = LegendStyle.Column; this.myChart.Legends.Add(legend); // Add header separator of type line legend.HeaderSeparator = LegendSeparatorStyle.Line; legend.HeaderSeparatorColor = Color.Gray; LegendCellColumn firstColumn = new LegendCellColumn(); firstColumn.ColumnType = LegendCellColumnType.SeriesSymbol; firstColumn.HeaderText = "Color"; firstColumn.HeaderBackColor = Color.WhiteSmoke; myChart.Legends["Default"].CellColumns.Add(firstColumn); // Add Legend Text column LegendCellColumn secondColumn = new LegendCellColumn(); secondColumn.ColumnType = LegendCellColumnType.Text; secondColumn.HeaderText = "Name"; secondColumn.Text = "#LEGENDTEXT"; secondColumn.HeaderBackColor = Color.WhiteSmoke; myChart.Legends["Default"].CellColumns.Add(secondColumn); // Add AVG cell column LegendCellColumn avgColumn = new LegendCellColumn(); avgColumn.Text = "#AVG{N2}"; avgColumn.HeaderText = "Avg"; avgColumn.Name = "AvgColumn"; avgColumn.HeaderBackColor = Color.WhiteSmoke; myChart.Legends["Default"].CellColumns.Add(avgColumn); // Add Total cell column LegendCellColumn totalColumn = new LegendCellColumn(); totalColumn.Text = "#TOTAL{N1}"; totalColumn.HeaderText = "Total"; totalColumn.Name = "TotalColumn"; totalColumn.HeaderBackColor = Color.WhiteSmoke; myChart.Legends["Default"].CellColumns.Add(totalColumn); // Set Min cell column attributes LegendCellColumn minColumn = new LegendCellColumn(); minColumn.Text = "#MIN{N1}"; minColumn.HeaderText = "Min"; minColumn.Name = "MinColumn"; minColumn.HeaderBackColor = Color.WhiteSmoke; myChart.Legends["Default"].CellColumns.Add(minColumn); // Set Max cell column attributes LegendCellColumn maxColumn = new LegendCellColumn(); maxColumn.Text = "#MAX{N1}"; maxColumn.HeaderText = "Max"; maxColumn.Name = "MaxColumn"; maxColumn.HeaderBackColor = Color.WhiteSmoke; myChart.Legends["Default"].CellColumns.Add(maxColumn); #endregion #region 設置圖表區屬性 ChartArea chartArea = new ChartArea("Default"); //設置Y軸刻度間隔大小 chartArea.AxisY.Interval = 5; //設置Y軸的數據類型格式 //chartArea.AxisY.LabelStyle.Format = "C"; //設置背景色 chartArea.BackColor = Color.FromArgb(64, 165, 191, 228); //設置背景漸變方式 chartArea.BackGradientStyle = GradientStyle.TopBottom; //設置漸變和陰影的輔助背景色 chartArea.BackSecondaryColor = Color.White; //設置邊框顏色 chartArea.BorderColor = Color.FromArgb(64, 64, 64, 64); //設置陰影顏色 chartArea.ShadowColor = Color.Transparent; //設置X軸和Y軸線條的顏色 chartArea.AxisX.LineColor = Color.FromArgb(64, 64, 64, 64); chartArea.AxisY.LineColor = Color.FromArgb(64, 64, 64, 64); //設置X軸和Y軸線條的寬度 chartArea.AxisX.LineWidth = 1; chartArea.AxisY.LineWidth = 1; //設置X軸和Y軸的標題 chartArea.AxisX.Title = "時間"; chartArea.AxisY.Title = "數值"; //設置圖表區網格橫縱線條的顏色 chartArea.AxisX.MajorGrid.LineColor = Color.FromArgb(64, 64, 64, 64); chartArea.AxisY.MajorGrid.LineColor = Color.FromArgb(64, 64, 64, 64); //設置圖表區網格橫縱線條的寬度 chartArea.AxisX.MajorGrid.LineWidth = 1; chartArea.AxisY.MajorGrid.LineWidth = 1; //設置坐標軸刻度線不延長出來 chartArea.AxisX.MajorTickMark.Enabled = false; chartArea.AxisY.MajorTickMark.Enabled = false; //開啟下面兩句能夠隱藏網格線條 //chartArea.AxisX.MajorGrid.Enabled = false; //chartArea.AxisY.MajorGrid.Enabled = false; //設置X軸的顯示類型及顯示方式 chartArea.AxisX.Interval = 0; //設置為0表示由控件自動分配 chartArea.AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount; chartArea.AxisX.IntervalType = DateTimeIntervalType.Minutes; chartArea.AxisX.LabelStyle.IsStaggered = true; //chartArea.AxisX.MajorGrid.IntervalType = DateTimeIntervalType.Minutes; //chartArea.AxisX.LabelStyle.IntervalType = DateTimeIntervalType.Minutes; chartArea.AxisX.LabelStyle.Format = "yyyy-MM-dd HH:mm:ss"; //設置文本角度 //chartArea.AxisX.LabelStyle.Angle = 45; //設置文本自適應 chartArea.AxisX.IsLabelAutoFit = true; //設置X軸允許拖動放大 chartArea.CursorX.IsUserEnabled = true; chartArea.CursorX.IsUserSelectionEnabled = true; chartArea.CursorX.Interval = 0; chartArea.CursorX.IntervalOffset = 0; chartArea.CursorX.IntervalType = DateTimeIntervalType.Minutes; chartArea.AxisX.ScaleView.Zoomable = true; chartArea.AxisX.ScrollBar.IsPositionedInside = false; //設置中短線(還沒看到效果) //chartArea.AxisY.ScaleBreakStyle.Enabled = true; //chartArea.AxisY.ScaleBreakStyle.CollapsibleSpaceThreshold = 47; //chartArea.AxisY.ScaleBreakStyle.BreakLineStyle = BreakLineStyle.Wave; //chartArea.AxisY.ScaleBreakStyle.Spacing = 2; //chartArea.AxisY.ScaleBreakStyle.LineColor = Color.Red; //chartArea.AxisY.ScaleBreakStyle.LineWidth = 10; myChart.ChartAreas.Add(chartArea); #endregion //線條2:主要曲線 Series series = new Series("Default"); //設置線條類型 series.ChartType = SeriesChartType.Line; //線條寬度 series.BorderWidth = 1; //陰影寬度 series.ShadowOffset = 0; //是否顯示在圖例集合Legends series.IsVisibleInLegend = true; //線條上數據點上是否有數據顯示 series.IsValueShownAsLabel = true; //線條顏色 series.Color = Color.MediumPurple; //設置曲線X軸的顯示類型 series.XValueType = ChartValueType.DateTime; //設置數據點的類型 series.MarkerStyle = MarkerStyle.Circle; //線條數據點的大小 series.MarkerSize = 5; myChart.Series.Add(series); //手動構造橫坐標數據 DataTable dataTable = new DataTable(); dataTable.Columns.Add("TheTime",typeof(DateTime)); //注意typeof dataTable.Columns.Add("TheValue", typeof(double)); //注意typeof Random random = new Random(); //隨機數 DateTime dateTime = System.DateTime.Now; for (int n = 0; n < 3; n++) { dateTime = dateTime.AddSeconds(10); DataRow dr = dataTable.NewRow(); dr["TheTime"] = dateTime; dr["TheValue"] = random.Next(0, 101); dataTable.Rows.Add(dr); } for (int n = 3; n < 1000; n++) { dateTime = dateTime.AddSeconds(30); DataRow dr = dataTable.NewRow(); dr["TheTime"] = dateTime; dr["TheValue"] = random.Next(0, 101); dataTable.Rows.Add(dr); } //線條1:下限橫線 Series seriesMin = new Series("Min"); seriesMin.ChartType = SeriesChartType.Line; seriesMin.BorderWidth = 1; seriesMin.ShadowOffset = 0; seriesMin.IsVisibleInLegend = true; seriesMin.IsValueShownAsLabel = false; seriesMin.Color = Color.Red; seriesMin.XValueType = ChartValueType.DateTime; seriesMin.MarkerStyle = MarkerStyle.None; myChart.Series.Add(seriesMin); //線條3:上限橫線 Series seriesMax = new Series("Max"); seriesMax.ChartType = SeriesChartType.Line; seriesMax.BorderWidth = 1; seriesMax.ShadowOffset = 0; seriesMax.IsVisibleInLegend = true; seriesMax.IsValueShownAsLabel = false; seriesMax.Color = Color.Red; seriesMax.XValueType = ChartValueType.DateTime; seriesMax.MarkerStyle = MarkerStyle.None; myChart.Series.Add(seriesMax); //設置X軸的最小值為第一個點的X坐標值 chartArea.AxisX.Minimum = Convert.ToDateTime(dataTable.Rows[0]["TheTime"]).ToOADate(); //開始畫線 foreach (DataRow dr in dataTable.Rows) { series.Points.AddXY(dr["TheTime"], dr["TheValue"]); seriesMin.Points.AddXY(dr["TheTime"], 15); //設置下線為15 seriesMax.Points.AddXY(dr["TheTime"], 30); //設置上限為30 } } private void myChart_GetToolTipText(object sender, ToolTipEventArgs e) { if (e.HitTestResult.ChartElementType == ChartElementType.DataPoint) { int i = e.HitTestResult.PointIndex; DataPoint dp = e.HitTestResult.Series.Points[i]; e.Text = string.Format("時間:{0},數值:{1:F1} ", DateTime.FromOADate(dp.XValue), dp.YValues[0]); } } } }
