日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

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

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

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

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

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

Code
?/**/
????????
///?<summary>
????????
///?圖片存放路徑
????????
///?</summary>
????????public?string?PhaysicalImagePath
????????{
????????????
set?{?_phaysicalimagepath?=?value;?}
????????????
get?{?return?_phaysicalimagepath;?}
????????}
????????
/**/
????????
///?<summary>
????????
///?圖片標(biāo)題
????????
///?</summary>
????????public?string?Title
????????{
????????????
set?{?_title?=?value;?}
????????????
get?{?return?_title;?}
????????}
????????
/**/
????????
///?<summary>
????????
///?圖片x座標(biāo)名稱
????????
///?</summary>
????????public?string?XTitle
????????{
????????????
set?{?_xtitle?=?value;?}
????????????
get?{?return?_xtitle;?}
????????}
????????
/**/
????????
///?<summary>
????????
///?圖片y座標(biāo)名稱
????????
///?</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)計(jì)圖類型(柱形,線形等)
????????
///?</summary>
????????public?SeriesType?Type
????????{
????????????
set?{?_type?=?value;?}
????????????
get?{?return?_type;?}
????????}

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

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

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

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

?

不用解釋,上面的屬性一看就應(yīng)該能明白

一、 單一圖

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

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

?

?

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

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

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

?

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

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

????????}
?

?

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

?

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

?

?

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

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

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

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

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

?

二、對(duì)比圖

對(duì)比圖的應(yīng)用,比如某年12個(gè)中公交和地鐵的載客量對(duì)比趨勢(shì)圖,如下(折線和柱狀圖)

?

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

?

?

?


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

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

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

??

????????????
//可自定義填充圖的填充色,系統(tǒng)采取默認(rèn)分配各數(shù)據(jù)項(xiàng)的填充色
????????????
//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)計(jì)圖片
????????
///?</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;//生成對(duì)比的線型圖時(shí)不適用
?????????????chart.DefaultSeries.Type?=?this.Type;?//統(tǒng)一使用默認(rèn)的序列圖類型屬性
?????????????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,后來有想過定義一個(gè)泛型或

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

?

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

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

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

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

?

上圖不算是一個(gè)完整的圖,因?yàn)橹鶢詈驼劬€都少了一個(gè)對(duì)比,而且右邊的縱軸沒有刻度,但是這也是可以做到的

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

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

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

?

?

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

?

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

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


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

????????????
for?(int?a?=?1;?a?<=?2;?a++)?//發(fā)車此數(shù)對(duì)比
????????????{
????????????????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;
????????}

?

圖例在右側(cè)有點(diǎn)不雅,可以設(shè)置屬性和標(biāo)題在一行顯示,那樣就比較好了,但是那樣的該版本不顯合計(jì),也可以設(shè)置不顯示圖例,最新的版本的

我看了下效果很不錯(cuò),也截個(gè)圖看下

?

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

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

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

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

?chart.XAxis.StaticColumnWidth = 50; 避免X軸上坐標(biāo)點(diǎn)少時(shí),柱形很粗,但是要注意

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

(demo就不更新了)

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

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

?

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

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

轉(zhuǎn)載于:https://www.cnblogs.com/wujy/archive/2012/10/09/2717375.html

總結(jié)

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

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