程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 告別.NET生成報表統計圖的煩惱

告別.NET生成報表統計圖的煩惱

編輯:關於.NET

信息系統大多會涉及到數據的統計,如數據的導出及生成統計對比圖等,記得之前有一次要生成一個 統計圖在WEB頁面上顯示,那時也是在網上找了段Code,完全是一點點畫橫縱軸坐標上面的畫出來的,而 且出來的效果也一般。最近項目的需要又有類似的要求,當然也知道隨VS08一起免費發布的繪圖組件功能 很強大,那繪圖組件要下載安裝,說是只支持.NET3.5(沒試驗過),不過園子裡我看到了飛雪飄寒 的一 篇博客(http://www.cnblogs.com/dreamof/archive/2008/07/18/1245887.html),只需引用一個 dotnetCHARTING.dll,而且對於.NET1.1到.NET3.5都適用,在此非常感謝飛雪飄寒,這裡我在他的基礎上 作了一些補充說明。當然dreamof也提到了參考的來源網站http://www.dotnetcharting.com/,上面有近上 千種圖樣,同時給出的調用方式,幾乎涵蓋了應用系統報表圖的所有方面。

OK,開始正題,統計圖一般分柱狀圖,折線圖,扁圖,扁圖稍微用的少點,常見的一般是折線和柱狀 圖,特殊概念的統計還是少不了扁圖的,我下面主要以柱狀和折線圖作說明。

柱狀和折線的又分單一圖和對比圖,對比圖也就是柱形的疊加,折線的疊加,當然柱形和折線也可以 混合疊加。首先說下生成統計圖的相關屬性

 /**/
        /// <summary>
        /// 圖片存放路徑
        /// </summary>
        public string PhaysicalImagePath
        {
            set { _phaysicalimagepath = value; }
            get { return _phaysicalimagepath; }
        }
        /**/
        /// <summary>
        /// 圖片標題
        /// </summary>
        public string Title
        {
            set { _title = value; }
            get { return _title; }
        }
        /**/
        /// <summary>
        /// 圖片x座標名稱
        /// </summary>
        public string XTitle
        {
            set { _xtitle = value; }
            get { return _xtitle; }
        }
        /**/
        /// <summary>
        /// 圖片y座標名稱
        /// </summary>
        public string YTitle
        {
            set { _ytitle = value; }
            get { return _ytitle; }
        }

        /**/
        /// <summary>
        /// 圖例名稱
        /// </summary>
        public string SeriesName
        {
            set { _seriesname = value; }
            get { return _seriesname; }
        }
        /**/
        /// <summary>
        /// 圖片寬度
        /// </summary>
        public int PicWidth
        {
            set { _picwidth = value; }
            get { return _picwidth; }
        }
        /**/
        /// <summary>
        /// 圖片高度
        /// </summary>
        public int PicHight
        {
            set { _pichight = value; }
            get { return _pichight; }
        }

        /// <summary>
        /// 統計圖類型(柱形,線形等)
        /// </summary>
        public SeriesType Type
        {
            set { _type = value; }
            get { return _type; }
        }

        /// <summary>
        /// 是否將輸出的圖片顯示成三維
        /// </summary>
        public bool Use3D
        {
            set { _use3d = value; }
            get { return _use3d; }
        }

        /// <summary>
        /// 對比圖形數據源
        /// </summary>
        public SeriesCollection DataSource
        {

            set { _dt = value; }
            get { return _dt; }
        }

        /// <summary>
        /// 生成統計圖片的名稱
        /// </summary>
        public string FileName
        {
            set { _filename = value; }
            get { return _filename; }
        }

不用解釋,上面的屬性一看就應該能明白

一、 單一圖

單一圖的應用,比如某條公交線一年12個月中每月的載客量趨勢圖,如下(折線和柱狀圖):

通過dotnetCHARTING繪制上面的單一統計圖是非常方便的,只需給定一個DataTable類型的數據源,數 據源的段包括橫軸的數值和縱軸的數值,即兩個字段

   /**//// <summary>
        /// 生成單一圖形時的數據源模型
        /// </summary>
        /// <returns></returns>
        private DataTable GetDataSource()
        {
            //如sql = select month,count from table where XXX
            return db.RetDataTable(sql);
        }

在生成統計圖時只需要合理組織數據源就可以了,dotnetcharting會根據數據庫的數值自動合理的分 配縱軸的尺度,這點比較方便。調用也很簡單,如下面

private void Drawing()
        {
            Charting c = new Charting();

            c.Title = "2008年各月載客量";
            c.XTitle = "月份";
            c.YTitle = "載客量(萬人)";
            c.PicHight = 350;
            c.PicWidth = 650;
            c.SeriesName = "合計";//僅對於DataTable類型做數據源時,此屬性有效
            c.PhaysicalImagePath = "ChartImages";//統計圖片存放的文件夾名稱,缺少 對應的文件夾生成不了統計圖片
            c.FileName = "Statistics";
            c.Type = SeriesType.Line;//折線型
            c.Use3D = false;
            c.DataSource = GetDataSource();
            c.CreateStatisticPic(this.Chart1);

        }

/**//// <summary>
        /// 生成單一統計圖片
        /// </summary>
        /// <param name="chart"></param>
        /// <param name="type">圖形類別,如柱狀,折線型</param>
        public void CreateStatisticPic(dotnetCHARTING.Chart chart)
        {
            chart.Title = this.Title;
            chart.XAxis.Label.Text = this.XTitle;
            chart.YAxis.Label.Text = this.YTitle;
            chart.TempDirectory = this.PhaysicalImagePath;
            chart.FileManager.FileName = this.FileName;
            chart.Width = this.PicWidth;
            chart.Height = this.PicHight;
            chart.Type = ChartType.Combo;
            chart.Series.Type = this.Type;
              chart.Series.Name = this.SeriesName;
            chart.Series.Data = this.DataSource;
            chart.SeriesCollection.Add();
            chart.DefaultSeries.DefaultElement.ShowValue = true;
            chart.ShadingEffect = true;
            chart.Use3D = this.Use3D;
            chart.Series.DefaultElement.ShowValue = true;
        }

個人覺得生成平面圖還好看些,三維的圖反而看起來別扭,下面也貼一張三維的單一圖效果看下

生成的圖片名稱,如果不指定,系統會根據Tick數隨機生成圖片名稱,格式為png,這樣時間久了會很 多圖片,當然可以在生成前先delete下文件下下的文件,如果設定一個固定名稱,就只會有一個圖片,新 的會覆蓋原有的,但是實際應用中這些做法都不太好,比如系統中有多種形式的報表,多個用戶同時在線 生成統計圖並且還要將該圖片導出到文檔,圖片名稱就不能重復了,要對應到用戶才行,可以這樣 c.FileName = UserID+報表編號,假設系統中有10種類型的報表,系統用戶有20個,最終的統計圖片文件 夾下的文件隨著時間的推移最多達到200個圖片。也是可以接受的(也有的說如果是最新的統計圖片就不 再重新生成,這樣當然好,但是生成的圖片基本上都是按時間段動態查詢產生的,也不易控制),如果真 的報表類型也多,用戶也多,做個定期刪除頁無妨。

二、對比圖

對比圖的應用,比如某年12個中公交和地鐵的載客量對比趨勢圖,如下(折線和柱狀圖)

與單一圖不一樣的是,生成對比圖的數據源必須是序列集合的類型SeriesCollection類型,也就是從 數據庫取出的數據要處理成序列集合的形式,如下

 /**//// <summary>
        /// 生成統計圖片的數據源模型(單一或對比圖都可以)
        /// </summary>
        /// <returns></returns>
        private SeriesCollection GetDataSource()
        {
            SeriesCollection SC = new SeriesCollection();
            Random rd = new Random();

            //DataTable newTable = new DataTable();
            //newTable.Columns.Add("Month", typeof(int));//月份
            //newTable.Columns.Add("Count", typeof(float));//載客量
            //for (int i = 1; i <= 12; i++)
            //{
            //    newTable.Rows.Add(new object[] { i, rd.Next(50) });
            //}
            /**/////生成單一圖,將返回的DataTable數據處理成序列集合類型的數據, 以便保持數據源類型的統一
            //Series s = new Series();
            //s.Name = "載客量合計";
            //for (int b = 1; b <= 12; b++) //X軸尺度個數,如一年12個月表示 有12個尺度數
            //{
            //    Element e = new Element();
            //    e.Name = b.ToString();//對應於X軸個尺度的名稱
            //    e.YValue = rd.Next(50);//與X軸對應的Y軸的數值
            //    s.Elements.Add(e);
            //}
            //SC.Add(s);

            // 生成對比圖
            for (int a = 1; a <= 2; a++) //對比的項數,如2008年各月的公交和 地鐵載客量數據對比就相當於有兩個數據項
            {
                Series s = new Series();
                s.Name = (a == 1 ? "公交載客量合計" : "地鐵載客量合計");// 各個數據項代表的名稱,如公交和地鐵12個月載客量走勢圖,則一條表示公交,一條表示地鐵
                for (int b = 1; b <= 12; b++) //X軸尺度個數,如12個月表 示有12個尺度數
                {
                    Element e = new Element();
                    e.Name = b.ToString();//對應於X軸個尺度的名稱
                    e.YValue = rd.Next(50);//與X軸對應的Y軸的數值
                    s.Elements.Add(e);
                }
                SC.Add(s);
            }

            //可自定義填充圖的填充色,系統采取默認分配各數據項的填充色
            //SC[0].DefaultElement.Color = Color.Blue;
            //SC[1].DefaultElement.Color = Color.Red;
            //SC[2].DefaultElement.Color = Color.FromArgb(255, 99, 49);
            //SC[3].DefaultElement.Color = Color.FromArgb(0, 156, 255);
            return SC;
        }

/**//// <summary>
        /// 生成統計圖片
        /// </summary>
        /// <param name="chart"></param>
        /// <param name="type">圖形類別,如柱狀,折線型</param>
        public void CreateStatisticPic(dotnetCHARTING.Chart chart)
        {
            chart.Title = this.Title;
            chart.XAxis.Label.Text = this.XTitle;
            chart.YAxis.Label.Text = this.YTitle;
            chart.TempDirectory = this.PhaysicalImagePath;
            chart.FileManager.FileName = this.FileName;
            chart.Width = this.PicWidth;
            chart.Height = this.PicHight;
            chart.Type = ChartType.Combo;
            //chart.Series.Type = this.Type;//生成對比的線型圖時不適用
             chart.DefaultSeries.Type = this.Type; //統一使用默認的序列圖類型 屬性
             chart.Series.Name = this.SeriesName;
            chart.SeriesCollection.Add(this.DataSource);
            chart.DefaultSeries.DefaultElement.ShowValue = true;
            chart.ShadingEffect = true;
            chart.Use3D = this.Use3D;
            chart.Series.DefaultElement.ShowValue = true;
        }

本文最後給出的下載示例中,統一采用數據源為序列集合,原本定義了兩種類型的數據源 SeriesCollection和DataTable,後來有想過定義一個泛型或IDataSource接受不同的數據源,覺得還是不 怎麼好,就統一用序列數據源類型。

三、柱狀和折線型的疊加(其實也屬於對比圖的一類)應用場景如,公交和地鐵某年12個月的載客量對 比,同時還要反映出12個公交和地鐵的發車次數的對比, 這時就要求縱軸的左右兩邊都有尺度,左邊縱 軸可以對應載客量,右邊縱軸可以對應發車次數,這種意義在於,可以看到在發車量相同的情況下,載客 量對比是怎樣的,發車量不同的情況下,載客量又有什麼變化,通過這種對比可以制定方案對那些線路增 加或減少發車次數,有點點類似於下面這樣的圖

上圖不算是一個完整的圖,因為柱狀和折線都少了一個對比,而且右邊的縱軸沒有刻度,但是這也是 可以做到的dotnetcharting官方網上近千個樣圖中其中我看到一個類似的 http://www.dotnetcharting.com/gallery/view.aspx?id=RateCharts,做一下處理是可以滿足要求的。

PS:引用的dotnetcharting.dll有隱藏的鏈接,就是生成出來的統計圖的上邊和下邊的,當鼠標移上去 時有導向.netcharting網站的鏈接,簡單用JS腳本移除了鏈接的map標簽(網上給的方法是修改IL代碼後 重新生成破解的dll,沒試過)。

總之,應用這個組件繪統計圖確實帶來了很大的方便和靈活性。

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved