日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

告别.NET生成报表统计图的烦恼 (转)

發(fā)布時間:2024/8/23 asp.net 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 告别.NET生成报表统计图的烦恼 (转) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

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

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

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

Code
?/**/
????????
///?<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>
????????
///?統(tǒng)計圖類型(柱形,線形等)
????????
///?</summary>
????????public?SeriesType?Type
????????{
????????????
set?{?_type?=?value;?}
????????????
get?{?return?_type;?}
????????}

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

????????
///?<summary>
????????
///?對比圖形數(shù)據(jù)源
????????
///?</summary>
????????public?SeriesCollection?DataSource
????????{

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

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

?

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

一、 單一圖

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

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

?

?

???/**////?<summary>
????????
///?生成單一圖形時的數(shù)據(jù)源模型
????????
///?</summary>
????????
///?<returns></returns>

????????private?DataTable?GetDataSource()
????????
{
????????????
//如sql?=?select?month,count?from?table?where?XXX
????????????return?db.RetDataTable(sql);
????????}

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

?

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

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

????????}
?

?

/**////?<summary>
????????
///?生成單一統(tǒng)計圖片
????????
///?</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;
????????}

?

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

?

?

?生成的圖片名稱,如果不指定,系統(tǒng)會根據(jù)Tick數(shù)隨機生成圖片名稱,格式為png,這樣時間久了會很多圖片,當然可以在生成前先delete下文件下下的文件,

如果設定一個固定名稱,就只會有一個圖片,新的會覆蓋原有的,但是實際應用中這些做法都不太好,比如系統(tǒng)中有多種形式的報表,多個用戶同時在線生成統(tǒng)計圖

并且還要將該圖片導出到文檔,圖片名稱就不能重復了,要對應到用戶才行,可以這樣c.FileName = UserID+報表編號,假設系統(tǒng)中有10種類型的報表,系統(tǒng)用戶

有20個,最終的統(tǒng)計圖片文件夾下的文件隨著時間的推移最多達到200個圖片。也是可以接受的(也有的說如果是最新的統(tǒng)計圖片就不再重新生成,這樣當然好,但是

生成的圖片基本上都是按時間段動態(tài)查詢產(chǎn)生的,也不易控制),如果真的報表類型也多,用戶也多,做個定期刪除頁無妨。

?

二、對比圖

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

?

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

?

?

?


?
/**////?<summary>
????????
///?生成統(tǒng)計圖片的數(shù)據(jù)源模型(單一或對比圖都可以)
????????
///?</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數(shù)據(jù)處理成序列集合類型的數(shù)據(jù),以便保持數(shù)據(jù)源類型的統(tǒng)一
????????????//Series?s?=?new?Series();
????????????
//s.Name?=?"載客量合計";
????????????
//for?(int?b?=?1;?b?<=?12;?b++)?//X軸尺度個數(shù),如一年12個月表示有12個尺度數(shù)
????????????
//{
????????????
//????Element?e?=?new?Element();
????????????
//????e.Name?=?b.ToString();//對應于X軸個尺度的名稱
????????????
//????e.YValue?=?rd.Next(50);//與X軸對應的Y軸的數(shù)值
????????????
//????s.Elements.Add(e);
????????????
//}
????????????
//SC.Add(s);

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

????????????????SC.Add(s);
????????????}

??

????????????
//可自定義填充圖的填充色,系統(tǒng)采取默認分配各數(shù)據(jù)項的填充色
????????????
//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>
????????
///?生成統(tǒng)計圖片
????????
///?</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;?//統(tǒng)一使用默認的序列圖類型屬性
?????????????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;
????????}

?

本文最后給出的下載示例中,統(tǒng)一采用數(shù)據(jù)源為序列集合,原本定義了兩種類型的數(shù)據(jù)源SeriesCollectionDataTable,后來有想過定義一個泛型或

IDataSource接受不同的數(shù)據(jù)源,覺得還是不怎么好,就統(tǒng)一用序列數(shù)據(jù)源類型。

?

三、柱狀和折線型的疊加(其實也屬于對比圖的一類)

應用場景如,公交和地鐵某年12個月的載客量對比,同時還要反映出12個公交和地鐵的發(fā)車次數(shù)的對比, 這時就要求縱軸的左右兩邊都有尺度,左邊縱軸可以

對應載客量,右邊縱軸可以對應發(fā)車次數(shù),這種意義在于,可以看到在發(fā)車量相同的情況下,載客量對比是怎樣的,發(fā)車量不同的情況下,載客量又有什么變化,

通過這種對比可以制定方案對那些線路增加或減少發(fā)車次數(shù),有點點類似于下面這樣的圖

?

上圖不算是一個完整的圖,因為柱狀和折線都少了一個對比,而且右邊的縱軸沒有刻度,但是這也是可以做到的

dotnetcharting官方網(wǎng)上近千個樣圖中其中我看到一個類似的http://www.dotnetcharting.com/gallery/view.aspx?id=RateCharts,

做一下處理是可以滿足要求的。

補充說明(2009-4-30):補充說明下Y軸右側有尺度的情況,如下圖:

?

?

要生成上圖的情況,數(shù)據(jù)源像下面做下處理,要增加對于右側Y軸的對比數(shù)據(jù)源,如下:

?

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

????????????????SC.Add(s);
????????????}


????????????Axis?ctrAxis?
=?new?Axis("發(fā)車次數(shù)");?//只繪一次右軸

????????????
for?(int?a?=?1;?a?<=?2;?a++)?//發(fā)車此數(shù)對比
????????????{
????????????????s?
=?new?Series();
????????????????ctrAxis.Orientation?
=?dotnetCHARTING.Orientation.Right;
????????????????s.YAxis?
=?ctrAxis;
????????????????s.Type?
=?SeriesType.Line;
????????????????s.Name?
=?(a?==?1???"公交發(fā)車次數(shù)"?:?"地鐵發(fā)車次數(shù)");
????????????????
for?(int?b?=?1;?b?<=?12;?b++)
????????????????
{
????????????????????Element?e?
=?new?Element();
????????????????????e.Name?
=?b.ToString();
????????????????????e.YValue?
=?100?+?rd.Next(500);
????????????????????s.Elements.Add(e);
????????????????}

????????????????
//s.DefaultElement.Color?=?a?==?1??Color.Pink?:?Color.SpringGreen;
????????????????SC.Add(s);
????????????}

????????????SC[
0].DefaultElement.Color?=?Color.FromArgb(49,?255,?49);
????????????SC[
1].DefaultElement.Color?=?Color.FromArgb(255,?255,?0);
????????????SC[
2].DefaultElement.Color?=?Color.FromArgb(255,?99,?49);
????????????SC[
3].DefaultElement.Color?=?Color.FromArgb(0,?156,?255);

????????????
return?SC;
????????}

?

圖例在右側有點不雅,可以設置屬性和標題在一行顯示,那樣就比較好了,但是那樣的該版本不顯合計,也可以設置不顯示圖例,最新的版本的

我看了下效果很不錯,也截個圖看下

?

上圖新版本可以設置這樣的屬性 ?Chart1.TitleBox.Position = TitleBoxPosition.FullWithLegend;
??????????????????????????????????? Chart1.TitleBox.Label.Alignment = StringAlignment.Center;

本文的版本屬性是這樣的:

chart.TitleBox.Position = TitleBoxPosition.FullWithLegend;//圖例在標題行顯示,但是沒有合計信息
//chart.LegendBox.Position = LegendBoxPosition.None; 不顯示圖例,指不在右側顯示,對上面一行的屬性設置并沒有影響

另:柱形的寬度設置,也就是X軸的步長設置,這個問題一直沒解決,后來找到開發(fā)文檔看了才知道,是這樣的設置的

?chart.XAxis.StaticColumnWidth = 50; 避免X軸上坐標點少時,柱形很粗,但是要注意

一旦這樣設置了,就都是這樣的寬度,如果不設置就動態(tài)均勻分配部長。

(demo就不更新了)

PS:引用的dotnetcharting.dll有隱藏的鏈接,就是生成出來的統(tǒng)計圖的上邊和下邊的,當鼠標移上去時有導向.netcharting網(wǎng)站的鏈接,簡單

用JS腳本移除了鏈接的map標簽(網(wǎng)上給的方法是修改IL代碼后重新生成破解的dll,沒試過)。

?

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

最后該小demo下載地址給出 :demo下載

轉載于:https://www.cnblogs.com/wujy/archive/2012/10/09/2717375.html

總結

以上是生活随笔為你收集整理的告别.NET生成报表统计图的烦恼 (转)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。