.net chart(圖表)控件的使用-System.Windows.Forms.DataVisualization.dll


這個案例指在介紹微軟這套免費又功能強大的圖表控件Microsoft Chart Controls for Microsoft .NET Framework 3.5,通過它,可讓您的項目及報表,輕松套用各種功能強大的 2D、3D、實時變化的動態圖表;且透過 AJAX,可讓圖表及里面的數據,每秒鍾都持續更新;使用者透過瀏覽器,可和圖表做各種互動設定

 

下面結合BBVS項目中溫度功能模塊中溫度曲線的繪制 做了如下Demo,供大家學習微軟的這款功能強大的圖標控件,這里只是起一個拋磚引玉的作用,更多更好玩的功能還等大家不斷進一步去挖掘!

 

首先,讓大家瞧瞧Chart控件的廬山真面目和組成吧,不然有些對不住大家,呵呵

 

 

一、需引用的DLL


要想利用這個功能強大的控件,首先必須引用以下DLL和相關文件:


1. WinForm應用程序中要想使用該圖表控件,需引用如下DLL:


System.Windows.Forms.DataVisualization.Design.dll


System.Windows.Forms.DataVisualization.dll


System.Windows.Forms.DataVisualization.xml


2. Web應用程序中要想使用該圖表控件,需引用如下DLL:


System.Web.DataVisualization.dll


System.Web.DataVisualization.Design.dll


System.Web.DataVisualization.xml


 二、采用WinForm程序使用該圖表控件

1. 創建一個WinForm工程: DemoCollection

2. 添加一個Form窗體: FrmChartDemo

3. 添加所需的DLL引用

4. 在該窗體的Load事件函數中動態創建好Chart對象實例

5. 添加一個Timer控件,在Timer控件的Tick事件函數中向Chart中添加坐標值(X值和Y值),然后在窗體中繪制出來.

6. FrmChartDemo的后台代碼如下:

FrmChartDemo.cs:

 

View Code
復制代碼
using System.Windows.Forms.DataVisualization.Charting;

namespace DemoCollection
{
    public partial class FrmChartDemo : Form
    {
        #region the variable definiton

        private Chart chart1;
        private Random random = new Random();
        private int maxYValue = 20;
        private int minYValue = 0;

        #endregion

        #region Ctor

        public FrmChartDemo()
        {
            InitializeComponent();

            this.Load += new EventHandler(FrmChartDemo_Load);
            this.timer1.Tick += new EventHandler(timer1_Tick);
        }

        #endregion

        #region the event handler

        void FrmChartDemo_Load(object sender, EventArgs e)
        {
            #region from BBVS porject

            // Create a Chart
            chart1 = new Chart();

            // Create Chart Area
            ChartArea chartArea1 = new ChartArea();

            // Add Chart Area to the Chart
            chart1.ChartAreas.Add(chartArea1);

            #region Set the Chart

            // Set the chart style
            chart1.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.TopBottom;
            chart1.BackSecondaryColor = System.Drawing.Color.White;
            chart1.BorderlineColor = System.Drawing.Color.FromArgb(((int)(((byte)(26)))), ((int)(((byte)(59)))), ((int)(((byte)(105)))));
            chart1.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
            chart1.BorderlineWidth = 2;
            chart1.BorderSkin.SkinStyle = System.Windows.Forms.DataVisualization.Charting.BorderSkinStyle.Emboss;
            chart1.BackColor = Color.SteelBlue;
            chart1.Dock = DockStyle.Fill;

            chartArea1.Area3DStyle.Inclination = 15;
            chartArea1.Area3DStyle.IsClustered = true;
            chartArea1.Area3DStyle.IsRightAngleAxes = false;
            chartArea1.Area3DStyle.Perspective = 10;
            chartArea1.Area3DStyle.Rotation = 10;
            chartArea1.Area3DStyle.WallWidth = 0;

            // 設置是否啟用 3D 效果
            //chartArea1.Area3DStyle.Enable3D = true;

            chartArea1.AxisX.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS"8.25F, System.Drawing.FontStyle.Bold);
            chartArea1.AxisX.LabelStyle.Format = "hh:mm:ss";
            chartArea1.AxisX.LabelStyle.Interval = 5D; // 10D;
            chartArea1.AxisX.LabelStyle.IntervalType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Seconds;

            chartArea1.AxisX.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));             chartArea1.AxisX.MajorGrid.Interval = 5D; // 10D;             chartArea1.AxisX.MajorGrid.IntervalType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Seconds;             chartArea1.AxisX.MajorGrid.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));             chartArea1.AxisX.MajorTickMark.Interval = 5D; // 10D;             chartArea1.AxisX.MajorTickMark.IntervalType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Seconds;             chartArea1.AxisY.IsLabelAutoFit = false;             chartArea1.AxisY.IsStartedFromZero = false;             chartArea1.AxisY.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold);             chartArea1.AxisY.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));             chartArea1.AxisY.MajorGrid.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));             #region 設置 Y 軸的 最大值和 最小值             chartArea1.AxisY.Maximum = this.maxYValue + 6;              chartArea1.AxisY.Minimum = this.minYValue - 6;             #endregion             chartArea1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(165)))), ((int)(((byte)(191)))), ((int)(((byte)(228)))));             chartArea1.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.TopBottom;             chartArea1.BackSecondaryColor = System.Drawing.Color.White;             chartArea1.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));             chartArea1.BorderDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;             chartArea1.InnerPlotPosition.Auto = false;             chartArea1.InnerPlotPosition.Height = 85F;             chartArea1.InnerPlotPosition.Width = 86F;             chartArea1.InnerPlotPosition.X = 8.3969F;             chartArea1.InnerPlotPosition.Y = 3.63068F;             chartArea1.Name = "Default";             chartArea1.Position.Auto = false;             chartArea1.Position.Height = 86.76062F;             chartArea1.Position.Width = 88F;             chartArea1.Position.X = 5.089137F;             chartArea1.Position.Y = 5.895753F;             chartArea1.ShadowColor = System.Drawing.Color.Transparent;             #endregion             #region Create a Legend             Legend legend1 = new Legend();             legend1.Alignment = System.Drawing.StringAlignment.Far;             legend1.BackColor = System.Drawing.Color.Transparent;             legend1.DockedToChartArea = "Default";             legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;             legend1.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold);             legend1.IsTextAutoFit = false;             legend1.LegendStyle = System.Windows.Forms.DataVisualization.Charting.LegendStyle.Row;             legend1.Name = "Default";             chart1.Legends.Add(legend1);             #endregion             #region Create a Series             Series series1 = new Series();             series1.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(180)))), ((int)(((byte)(26)))), ((int)(((byte)(59)))), ((int)(((byte)(105)))));             series1.ChartArea = "Default";             series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine;//Line;             series1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(64)))), ((int)(((byte)(10)))));             series1.Legend = "Default";             series1.Name = "Series1";             series1.ShadowOffset = 1;             series1.YValuesPerPoint = 2;             chart1.Series.Add(series1);             // 設置是否在 Chart 中顯示 坐標點值             series1.IsValueShownAsLabel = true;             #endregion             // Set chart control location             chart1.Location = new System.Drawing.Point(0, 0);             // Add chart control to the form             this.Controls.AddRange(new System.Windows.Forms.Control[] { this.chart1 });             #endregion         }         void timer1_Tick(object sender, EventArgs e)         {             double tempValue = 0.0;             // 隨機產生 溫度值             tempValue = random.Next(this.minYValue, this.maxYValue);             DateTime timeStamp = DateTime.Now;             double xValue = DateTime.Now.ToOADate();             // 向 Chart中 添加 X軸 和 Y軸的 值             chart1.Series["Series1"].Points.AddXY(xValue, tempValue);             // remove all points from the source series older than 20 seconds.             double removeBefore = timeStamp.AddSeconds((double)(20) * (-1)).ToOADate();             //remove oldest values to maintain a constant number of data points             if (chart1.Series[0].Points.Count > 0)             {                 while (chart1.Series[0].Points[0].XValue < removeBefore)                 {                     chart1.Series[0].Points.RemoveAt(0);                 }                 chart1.ChartAreas[0].AxisX.Minimum = chart1.Series[0].Points[0].XValue;                 chart1.ChartAreas[0].AxisX.Maximum = DateTime.FromOADate(chart1.Series[0].Points[0].XValue).AddSeconds(20).ToOADate();             }             else             {                 //chart1.ChartAreas[0].AxisX.Minimum = (double)minTempThreshold;                 //chart1.ChartAreas[0].AxisX.Maximum = (double)maxTempThreshold;             }             chart1.Invalidate();         }         #endregion     } }
控件:.NET Framework 3.5 的 Microsoft 圖表控件(Microsoft Chart Controls for Microsoft 語言包:Microsoft Chart Controls for Microsoft .NET Framework 3.5 的Microsoft 圖表控件 的語言包,包含23中語言。

 下了它的示例程序后,運行了一下,非常的強大,可以支持各種各樣的圖形顯示,常見的:點狀圖、餅圖、柱狀圖、曲線圖、面積圖、排列圖等等,同時也支持3D樣式的圖表顯示,不過我覺得最有用的功能還是支持圖形上各個點的屬性操作,它可以定義圖形上各個點、標簽、圖形的提示信息(Tooltip)以及超級鏈接、Javascript動作等,而不是像其它圖形類庫僅生成一幅圖片而已,通過這些,加上微軟自己的Ajax框架,可以建立一個可以互動的圖形統計報表了。
一。安裝
     控件的安裝相對比較簡單,下載完后,先執行“MSChart.exe”程序,它會自動檢測你的環境,安裝到系統目錄中去,如果要在VS 2008環境中直接使用,那么需要安裝For Vs2008的插件,MSChart_VisualStudioAddOn.exe,還有一個中文語言包MSChartLP_chs.exe。安裝完后, 打開Vs2008,在建立項目的時候,你就能在工具欄中看到有一個.NET3.5的Web項目,像使用普通控件一樣拖放到要使用的Web界面即可。初步研究了一下,整個圖形控件主要由以下幾個部份組成:
1.Annotations --圖形注解集合
2.ChartAreas  --圖表區域集合
3.Legends      --圖例集合
4.Series    --圖表序列集合(即圖表數據對象集合)
5.Titles    --圖標的標題集合
Annotations注解集合
     Annotations是一個對圖形的一些注解對象的集合,所謂注解對象,類似於對某個點的詳細或者批注的說明,比如,在圖片上實現各個節點的關鍵信息,如下圖方框和黃色的小方框:

  一個圖形上可以擁有多個注解對象,可以添加十多種圖形樣式的注解對象,包括常見的箭頭、雲朵、矩行、圖片等等注解符號,通過各個注解對象的屬性,可以方便的設置注解對象的放置位置、呈現的顏色、大小、文字內容樣式等常見的屬性。
ChartAreas圖表區域集合
    ChartAreas可以理解為是一個圖表的繪圖區,例如,你想在一幅圖上呈現兩個不同屬性的內容,一個是用戶流量,另一個則是系統資源占用情況,那么你 要在一個圖形上繪制這兩種情況,明顯是不合理的,對於這種情況,可以建立兩個ChartArea,一個用於呈現用戶流量,另一個則用於呈現系統資源的占用 情況。
    當然了,圖表控件並不限制你添加多少個繪圖區域,你可以根據你的需要進行添加。對於每一個繪圖區域,你可以需要注意的是,繪圖區域只是一個可以作圖的區域范圍,它本身並不包含要作圖形的各種屬性數據。

    多繪圖區效果圖如下,分為上下兩個繪圖區域,分別表示不同的繪圖數據:

   Legends圖例集合
    Legends是一個圖例的集合,即標注圖形中各個線條或顏色的含義,同樣,一個圖片也可以包含多個圖例說明,比如像上面說的多個圖表區域的方式,則可以 建立多個圖例,每別說明各個繪圖區域的信息,具體的圖例配置說明此處就不詳細說明了,可以參考一下官網的例子,寫得豐富的詳細了:)也上一張圖例的效果圖 吧~

Series圖表序列
     圖表序列,應該是整個繪圖中最關鍵的內容了,通俗點說,即是實際的繪圖數據區域,實際呈現的圖形形狀,就是由此集合中的每一個圖表來構成的,可以往集合里面添加多個圖表,每一個圖表可以有自己的繪制形狀、樣式、獨立的數據等。
    需要注意的是,每一個圖表,你可以指定它的繪制區域(見ChartAreas的說明),讓此圖表呈現在某個繪圖區域,也可以讓幾個圖表在同一個繪圖區域疊加,如下圖:


上面兩幅圖,分別表示了把圖表放在不同的繪制區域和放在同一個繪制區域的情況。
     繼續回到ChartAreas章節舉的例子,同時要顯示用戶的流量還要顯示系統的占用情況,對於這種時候,應該建立兩個Series,一個用於呈現用戶的流量,另一個則用於呈現系統的占用情況。它們分別屬於各自的繪圖區域。
Titles標題合集
    根據字面含義即可以理解,是圖表的標題配置,同樣可以添加多個標題,以及設置標題的樣式及文字、位置等屬性。多看一下它的屬性即能明白各自的含義。
三。其它屬性
    相對來說,我覺得比較有用的屬性有三個,分別是:Label、Tooltip以及Url鏈接。
    Label即標簽的含義,可以在圖片的關鍵位置進行一些關鍵數字或文字的描述,如下圖:

像上圖:X軸和Y軸的文字便是標簽,以及圖表曲線中的紅點上的文字,也是標簽,添加了標簽,可以讓人更容易的對內容進行理解。
    Tooltip即提示的含義,用於在各個關鍵點,如:標簽、圖形關鍵點、標題等當鼠標移動上去的時候,提示用戶一些相關的詳細或說明信息,例如上圖,可以 給曲線中的每一個點增加Tooltip的屬性,寫上需要詳細說明的內容,比如:詳細的銷售明細,那么,在鼠標移動到這個點的時候,會自動彈出提示信息。
    Tooltip可以支持簡單方式以及自定義的方式,簡單方式即像平時Html頁面設置此屬性,在鼠標點擊的時候,代到其它相應的頁面去。
   建議大家看看官方例子中的Interactivity and AJAX部份,很精彩:)
例子:建立一個Cpu信息和內存使用的實時統計表
    下面寫一個小例子,建立一個系統的內存實時統計圖表,使用到了Ajax的方法,以及Windows Api取得系統內存的方法。
    首先,建立一個Aspx頁面,拖動一個圖表控件到頁面,設置圖表控件的EnableViewState屬性為True,否則無法記錄狀態。

Code

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><asp:Chart ID="ChartMemory" runat="server" BackColor="LightSteelBlue"
BackGradientStyle="TopBottom" BackSecondaryColor="White" EnableTheming="False"
EnableViewState="True" Height="363px" Width="415px">
<Legends>
<asp:Legend Alignment="Center" Docking="Bottom" Name="Legend1" Title="圖例">
</asp:Legend>
</Legends>
<Titles>
<asp:Title Font="微軟雅黑, 16pt" Name="Title1" Text="系統內存監控圖表">
</asp:Title>
</Titles>
<Series>
<asp:Series BorderColor="White" BorderWidth="3" ChartArea="ChartArea1"
ChartType="Spline" Legend="Legend1" Name="已使用物理內存" XValueType="Double"
YValueType="Double">
</asp:Series>
<asp:Series BorderWidth="3" ChartArea="ChartArea1" ChartType="Spline"
Legend="Legend1" Name="全部占用內存">
</asp:Series>
<asp:Series ChartArea="ChartArea2" ChartType="StackedArea" Legend="Legend1"
Name="CPU">
</asp:Series>
</Series>
<ChartAreas>
<asp:ChartArea BackColor="224, 224, 224" BackGradientStyle="LeftRight"
Name="ChartArea1">
</asp:ChartArea>
<asp:ChartArea Name="ChartArea2">
</asp:ChartArea>
</ChartAreas>
</asp:Chart>

 
 
一共建立了兩個繪圖區,一個用於呈現內存使用情況的在ChartArea1區域,另一個則是呈現Cpu使用情況的,放置在ChartArea2區域了。一共有三個圖表,分別表示已使用的物理內存、全部占用的物理內存,以及Cpu使用顯示的情況。 添加一個Ajax的計時器以及Ajax的ScriptManager,UpdatePanel,把計時器和圖表控件都拖進UpdatePanel里面。設置計時器的間隔時間為一秒鍾(1000),雙擊計時器,寫如下代碼:

 

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

static PerformanceCounter pc = new PerformanceCounter("Processor", "% Processor Time", "_Total");
protected void Timer1_Tick(object sender, EventArgs e)
{
MEMORY_INFO MemInfo = new MEMORY_INFO();
ComputerInfo.GlobalMemoryStatus(ref MemInfo);
//UseMemory
Series series = ChartMemory.Series[0];
int xCount = series.Points.Count == 0 ? 0 : series.Points.Count - 1;
double lastXValue = series.Points.Count == 0 ? 1 : series.Points[xCount].XValue + 1;
double lastYValue = (double)(MemInfo.dwTotalPhys-MemInfo.dwAvailPhys)/1024/1024;
series.Points.AddXY(lastXValue, lastYValue);
//Total Memory
series = ChartMemory.Series[1];
lastYValue = (double)(MemInfo.dwTotalVirtual+MemInfo.dwTotalPhys-MemInfo.dwAvailPhys - MemInfo.dwAvailVirtual)/1024/1024;
series.Points.AddXY(lastXValue, lastYValue);

//CPU
series = ChartMemory.Series[2];
lastYValue = (double)pc.NextValue();
series.Points.AddXY(lastXValue, lastYValue);

// Remove points from the left chart side if number of points exceeds 100.
while (this.ChartMemory.Series[0].Points.Count > 80)
{
// Remove series points
foreach (Series s in this.ChartMemory.Series)
{
s.Points.RemoveAt(0);
}
}
// Adjust categorical scale
double axisMinimum = this.ChartMemory.Series[0].Points[0].XValue;
this.ChartMemory.ChartAreas[0].AxisX.Minimum = axisMinimum;
this.ChartMemory.ChartAreas[0].AxisX.Maximum = axisMinimum + 99;
}

 
 
 
   附上取得內存信息的類代碼:
 
Code

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
/// <summary>
///取得計算機的系統信息
/// </summary>
public class ComputerInfo
{
/// <summary>
/// 取得Windows的目錄
/// </summary>
/// <param name="WinDir"></param>

/// <param name="count"></param>
[DllImport("kernel32")]
public static extern void GetWindowsDirectory(StringBuilder WinDir, int count);
/// <summary>
/// 獲取系統路徑
/// </summary>
/// <param name="SysDir"></param>
/// <param name="count"></param>
[DllImport("kernel32")]
public static extern void GetSystemDirectory(StringBuilder SysDir, int count);
/// <summary>
/// 取得CPU信息
/// </summary>
/// <param name="cpuinfo"></param>
[DllImport("kernel32")]
public static extern void GetSystemInfo(ref CPU_INFO cpuinfo);
/// <summary>
/// 取得內存狀態
/// </summary>
/// <param name="meminfo"></param>
[DllImport("kernel32")]
public static extern void GlobalMemoryStatus(ref MEMORY_INFO meminfo);
/// <summary>
/// 取得系統時間
/// </summary>
/// <param name="stinfo"></param>
[DllImport("kernel32")]
public static extern void GetSystemTime(ref SYSTEMTIME_INFO stinfo);

public ComputerInfo()
{
}
}

//定義CPU的信息結構
[StructLayout(LayoutKind.Sequential)]
public struct CPU_INFO
{
public uint dwOemId;
public uint dwPageSize;
public uint lpMinimumApplicationAddress;
public uint lpMaximumApplicationAddress;
public uint dwActiveProcessorMask;
public uint dwNumberOfProcessors;
public uint dwProcessorType;
public uint dwAllocationGranularity;
public uint dwProcessorLevel;
public uint dwProcessorRevision;
}
//定義內存的信息結構
[StructLayout(LayoutKind.Sequential)]

 public struct MEMORY_INFO
{
public uint dwLength;
public uint dwMemoryLoad;
public uint dwTotalPhys;
public uint dwAvailPhys;
public uint dwTotalPageFile;
public uint dwAvailPageFile;
public uint dwTotalVirtual;
public uint dwAvailVirtual;
}
//定義系統時間的信息結構
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME_INFO
{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}

 


    運行的效果圖如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM