C# 報表設計器 (winform 設計端)開發與實現生成網頁的HTML報表

    記得2010年以前,公司的項目基本上都要用到報表,之前咱們經常使用的方法就是針對客戶的需求來定製化開發(基本上是死寫代碼)來實現,常常致使項目常常性的延期,由於客戶的需求常常會變化,隨着用戶的使用認知度的提升,對報表的要求愈來愈高,致使程序員不停的修改代碼來實現,效率不高、結束遙遙無期。。。很是的痛苦;固然市面上有不少報表開發工具能夠實現,可是針對小公司來講採購一套這樣的系統的成本也很是的高,因此咱們決定本身來開發一套像目前的潤乾、FineReport 這樣的報表設計器,來實現快速的報表設計製做。c++

   當初爲了開發這樣的系統,花費的了很長的時間學習查閱各類資料,其痛苦只有程序員才能體會,由於沒有任何現成的實例代碼可供參考,只有看別人的思路來一步步的摸索,本文將咱們當初設計製做的報表設計器的功能分享出來,讓有須要的或想開發報表設計的朋友們提供一個參考,儘可能少走很動彎路,設計端能夠直接使用,可是計算引擎和網頁的計算的源碼就不能分享出來了(請不要介意,由於涉及到公司的保密緣由)程序員

   記得當初爲了製做報表設計器,在網上查找有沒有相關的實例資料,找了好久,也是沒有找到合適的,後來發現 SourceGrid 能夠實現單元格的合併拆分功能,因此決定修改實現winform端的報表設計。下面我將製做的E_Report 報表控件抽取出來創建一個簡易的Winform的可運行的實例提供給大夥下載,但願能給你的開發提供一點幫助和借鑑;固然你能夠直接使用也能夠,裏面的設計功能基本所有能。數組

   抽取出來的源碼包含:E_Report 報表設計自定義控件DLL源碼;  EReportDemo 創建的簡易Winform 端設計器使用DLL的實例源碼;app

  1、運行效果ide

    實例中,只作了一個簡單的效果,工具欄的按鈕在單元格右擊屬性中都有,只是放了幾個經常使用的在工具導航欄中(右擊單元格屬性能夠看到設計導航)函數

    能夠進行單元格的合併、拆分、字體、顏色、背景、邊框等的設置,朋友們能夠本身編寫保存發佈等功能,實現報表的真實功能;工具

  

      例如單元格屬性(其餘還有不少的屬性,本身下載源碼後運行起來就能看到了)學習

    

       對錶格的斜線、斜線文字有很好的支持;能夠設置表頭、表位、標題等 實際效果圖以下開發工具

    

 

2、使用介紹測試

一、頁面初始化的時候,經過 ReportDoc 類 初始報表的行列及單元格屬性

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Text;
  4 using System.Drawing;
  5 using System.Windows.Forms;
  6 using System.Drawing.Drawing2D;
  7 using System.Xml;
  8 using System.Collections;
  9 using E_Report;
 10 
 11 namespace EReportDemo
 12 {
 13     /// <summary>
 14     /// 報表表格對象
 15     /// </summary>
 16     public class ReportDoc
 17     {
 18         #region 變量參數定義
 19 
 20         /// <summary>
 21         /// 表格對象
 22         /// </summary>
 23         private EReport _nowReport;
 24 
 25         /// <summary>
 26         /// 報表配置編碼
 27         /// </summary>
 28         private string _reportCode = "";
 29 
 30         /// <summary>
 31         /// 表報設計狀態
 32         /// </summary>
 33         private string _reportState = "";
 34 
 35         #endregion
 36 
 37         #region 函數構造方法
 38 
 39         /// <summary>
 40         /// 構造函數
 41         /// </summary>
 42         public ReportDoc()
 43         {
 44             this._nowReport = null;
 45             this._reportCode = "";
 46             this._reportState = "";
 47 
 48         }
 49 
 50 
 51         /// <summary>
 52         /// 獲取--設置--表格對象
 53         /// </summary>
 54         public EReport NowReport
 55         {
 56             get { return this._nowReport; }
 57             set { this._nowReport = value; }
 58         }
 59 
 60         /// <summary>
 61         /// 報表配置編碼
 62         /// </summary>
 63         public string ReportCode
 64         {
 65             get { return this._reportCode; }
 66             set { this._reportCode = value; }
 67         }
 68 
 69         /// <summary>
 70         /// 報表設計狀態
 71         /// 新增、修改 兩種狀態
 72         /// </summary>
 73         public string ReportState
 74         {
 75             get { return this._reportState; }
 76             set { this._reportState = value; }
 77         }
 78 
 79         /// <summary>
 80         /// 資源釋放
 81         /// </summary>
 82         ~ReportDoc()
 83         {
 84             this._nowReport = null;
 85             this._reportState = "";
 86 
 87         }
 88 
 89         #endregion
 90 
 91         #region 加載報表表格
 92 
 93         /// <summary>
 94         /// 初始化--報表表格
 95         /// </summary>
 96         public void InitReport()
 97         {
 98 
 99             int rCount = 41;  // 41行
100             int cCount = 20;  // 20列
101 
102             _nowReport.Redim(rCount, cCount);
103             _nowReport.FixedRows = 1;
104             _nowReport.FixedColumns = 1;
105 
106             InitCells();
107 
108         }
109 
110         /// <summary>
111         /// 初始化--單元格
112         /// </summary>
113         public void InitCells()
114         {
115             // 第一行 第一列
116             _nowReport.Rows[0].Height = 23;
117             _nowReport.Columns[0].Width = 50;
118 
119             // 設置00格
120             _nowReport[0, 0] = new E_Report.Cells.HeaderColumn("");
121 
122             //  設置行
123             for (int rr = 1; rr < _nowReport.RowsCount; rr++)
124             {
125                 string tmRowT = rr.ToString();
126                 _nowReport[rr, 0] = new E_Report.Cells.HeaderRow(tmRowT);
127             }
128 
129             //  設置列
130             for (int cc = 1; cc < _nowReport.ColumnsCount; cc++)
131             {
132                 _nowReport[0, cc] = new E_Report.Cells.HeaderColumn(_nowReport.GetColumnHeadTileChar(cc));
133             }
134 
135             // 設置單元格
136             for (int iRow = 1; iRow < _nowReport.RowsCount; iRow++)
137             {
138                 for (int iCol = 1; iCol < _nowReport.ColumnsCount; iCol++)
139                 {
140                     _nowReport[iRow, iCol] = new E_Report.Cells.Cell("", typeof(string));
141                 }
142             }
143 
144         }
145 
146 
147         #endregion
148 
149     }
150 }
View Code

二、工具導航欄 設置單元格相關屬性

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Text;
  7 using System.Windows.Forms;
  8 using System.Collections;
  9 using E_Report;
 10 
 11 namespace EReportDemo
 12 {
 13     /// <summary>
 14     /// 本程序只是Winform端的報表設計功能
 15     /// 至於其餘的功能,本實例沒有提供
 16     /// 報表設計的設計效果:能夠查看  www.sdpsoft.com  SDP軟件快速開發平臺 報表設計篇
 17     /// </summary>
 18 
 19     public partial class EReportMain : Form
 20     {
 21         private ReportDoc report;
 22         private E_Report.Cells.Controllers.PopupMenu myPopupMenu;
 23 
 24         public EReportMain()
 25         {
 26             InitializeComponent();
 27         }
 28 
 29         private void EReportMain_Load(object sender, EventArgs e)
 30         {
 31             Cursor.Current = Cursors.WaitCursor;
 32             gridMain.Rows.Clear();
 33             myPopupMenu = new E_Report.Cells.Controllers.PopupMenu(gridMain);
 34 
 35             report = new ReportDoc();
 36             report.NowReport = gridMain;
 37             report.InitReport();
 38             Cursor.Current = Cursors.Default;
 39         }
 40 
 41         private void gridMain_MouseMove(object sender, MouseEventArgs e)
 42         {
 43             this.lbl_X.Text = e.X.ToString();
 44             this.lbl_Y.Text = e.Y.ToString();
 45         }
 46 
 47         /// <summary>
 48         /// 工具欄報表單元格事件
 49         /// </summary>
 50         /// <param name="sender"></param>
 51         /// <param name="e"></param>
 52         private void btn_GridTools_Click(object sender, EventArgs e)
 53         {
 54             string sType = ((Button)sender).Tag.ToString().Trim().ToLower();
 55             switch (sType)
 56             {
 57 
 58                 case "cellproperty":  // 單元格屬性設置
 59                     myPopupMenu.CellProperty_Click(sender, e);
 60                     break;
 61                 case "fontset":       // 單元格字體設置
 62                     myPopupMenu.CellFont_Click(sender, e);
 63                     break;
 64                 case "fontcolor":     // 文本字體顏色
 65                     myPopupMenu.CellForColor_Click(sender, e);
 66                     break;
 67                 case "backcolor":     // 單元格背景色
 68                     myPopupMenu.CellBackColor_Click(sender, e);
 69                     break;
 70                 case "cellborder":   // 單元格邊框設置
 71                     myPopupMenu.CellBorder_Click(sender, e);
 72                     break;
 73                 case "lock":         // 設置表格只讀
 74                     myPopupMenu.LockReport_Click(sender, e);
 75                     break;
 76                 case "unlock":       // 設置表格編輯
 77                     myPopupMenu.UnLockReport_Click(sender, e);
 78                     break;
 79                 case "alignleft":    // 水平居左對齊
 80                     myPopupMenu.AlignLeft_Click(sender, e);
 81                     break;
 82                 case "aligncenter":  // 水平居中對齊
 83                     myPopupMenu.AlignCenter_Click(sender, e);
 84                     break;
 85                 case "alignright":   // 水平居右對齊
 86                     myPopupMenu.AlignRight_Click(sender, e);
 87                     break;
 88                 case "aligntop":     // 垂直居上對齊
 89                     myPopupMenu.AlignTop_Click(sender, e);
 90                     break;
 91                 case "alignmiddle":  // 垂直居中對齊
 92                     myPopupMenu.AlignMiddle_Click(sender, e);
 93                     break;
 94                 case "alignbottom":  // 垂直居下對齊
 95                     myPopupMenu.AlignBottom_Click(sender, e);
 96                     break;
 97                 case "addindent":    // 增長文本縮進
 98                     myPopupMenu.AddIndent_Click(sender, e);
 99                     break;
100                 case "delindent":    // 清除文本縮進
101                     myPopupMenu.RemoveIndent_Click(sender, e);
102                     break;
103                 case "insertrow":    // 插入後一行
104                     myPopupMenu.InsertRow_Click(sender, e);
105                     break;
106                 case "appendrow":    // 表格追加行
107                     myPopupMenu.AddRow_Click(sender, e);
108                     break;
109                 case "delrow":       // 刪除選中行
110                     myPopupMenu.DeleteRows_Click(sender, e);
111                     break;
112                 case "hiderow":      // 隱藏選中行
113                     myPopupMenu.HideSelectRows_Click(sender, e);
114                     break;
115                 case "showrow":      // 顯示選中行
116                     myPopupMenu.ShowSelectRows_Click(sender, e);
117                     break;
118                 case "showallrow":   // 顯示全部行
119                     myPopupMenu.ShowAllRows_Click(sender, e);
120                     break;
121                 case "insertcol":    // 插入左側列
122                     myPopupMenu.InsertColumn_Click(sender, e);
123                     break;
124                 case "addcol":       // 插入右側列
125                     myPopupMenu.AddColumn_Click(sender, e);
126                     break;
127                 case "delcol":       // 刪除選中列
128                     myPopupMenu.DeleteColumns_Click(sender, e);
129                     break;
130                 case "hidecol":      // 隱藏選中列
131                     myPopupMenu.HideSelectColumns_Click(sender, e);
132                     break;
133                 case "showcol":      // 顯示選中列
134                     myPopupMenu.ShowSelectColumns_Click(sender, e);
135                     break;
136                 case "showallcol":   // 顯示全部列
137                     myPopupMenu.ShowAllColumns_Click(sender, e);
138                     break;
139                 case "mergecell":    // 合併單元格
140                     myPopupMenu.MergeCell_Click(sender, e);
141                     break;
142                 case "splitcell":    // 拆分單元格
143                     myPopupMenu.SplitCell_Click(sender, e);
144                     break;
145             }
146         }
147     }
148 }
View Code

三、報表控件DLL類庫部分

    裏面有咱們自定義的 條碼控件、圖片控件、圖表控件

  表格內自定義圖表控件(曲線、柱狀、餅狀)源碼

   1 using System;
   2 using System.Collections.Generic;
   3 using System.Text;
   4 using System.Drawing;
   5 using System.Drawing.Drawing2D;
   6 using System.Drawing.Text;
   7 
   8 namespace E_Report
   9 {
  10     /// <summary>
  11     /// 圖表屬性
  12     /// </summary>
  13     /// <summary>
  14     /// 報表圖表類庫
  15     /// </summary>
  16     public class EChart
  17     {
  18         #region 屬性方法
  19 
  20         #region 臨時變量
  21 
  22         /// <summary>
  23         /// 臨時變量--關聯單元格行號
  24         /// </summary>
  25         private int _row = 0;
  26 
  27         /// <summary>
  28         /// 獲取--設置--關聯單元格行號
  29         /// </summary>
  30         public int Row
  31         {
  32             get { return _row; }
  33             set { _row = value; }
  34         }
  35 
  36         /// <summary>
  37         /// 臨時變量--關聯單元格列號
  38         /// </summary>
  39         private int _col = 0;
  40 
  41         /// <summary>
  42         /// 獲取--設置--關聯單元格列號
  43         /// </summary>
  44         public int Col
  45         {
  46             get { return _col; }
  47             set { _col = value; }
  48         }
  49 
  50         /// <summary>
  51         /// 數據來源
  52         /// </summary>
  53         private string _t_DataFrom = "數據源";
  54 
  55         /// <summary>
  56         /// 獲取--設置--數據來源
  57         /// </summary>
  58         public string T_DataFrom
  59         {
  60             get { return _t_DataFrom; }
  61             set { _t_DataFrom = value; }
  62         }
  63 
  64         /// <summary>
  65         /// 數據源名稱
  66         /// </summary>
  67         private string _t_DsName = "";
  68 
  69         /// <summary>
  70         /// 獲取--設置--數據源名稱
  71         /// </summary>
  72         public string T_DsName
  73         {
  74             get { return _t_DsName; }
  75             set { _t_DsName = value; }
  76         }
  77 
  78         /// <summary>
  79         /// 項目名稱
  80         /// </summary>
  81         private string _t_ItemName = "";
  82 
  83         /// <summary>
  84         /// 獲取--設置--項目名稱
  85         /// </summary>
  86         public string T_ItemName
  87         {
  88             get { return _t_ItemName; }
  89             set { _t_ItemName = value; }
  90         }
  91 
  92         /// <summary>
  93         /// 項目數值
  94         /// </summary>
  95         private string _t_ItemValue = "";
  96 
  97         /// <summary>
  98         /// 獲取--設置--項目數值
  99         /// </summary>
 100         public string T_ItemValue
 101         {
 102             get { return _t_ItemValue; }
 103             set { _t_ItemValue = value; }
 104         }
 105 
 106         /// <summary>
 107         /// X軸刻度
 108         /// </summary>
 109         private string _t_XScale = "";
 110 
 111         /// <summary>
 112         /// 獲取--設置--X軸刻度
 113         /// </summary>
 114         public string T_XScale
 115         {
 116             get { return _t_XScale; }
 117             set { _t_XScale = value; }
 118         }
 119 
 120 
 121         #endregion
 122 
 123         #region 圖表屬性
 124 
 125         /// <summary>
 126         /// 圖表名稱ID
 127         /// </summary>
 128         private string _name = "";
 129 
 130         /// <summary>
 131         /// 獲取--設置--圖表名稱ID
 132         /// </summary>
 133         public string Name
 134         {
 135             get { return _name; }
 136             set { _name = value; }
 137         }
 138 
 139         /// <summary>
 140         /// 圖表類型
 141         /// </summary>
 142         private EChartType _chartType = EChartType.Curve;
 143 
 144         /// <summary>
 145         /// 獲取--設置--圖表類型
 146         /// 默認:Line 折曲線
 147         /// </summary>
 148         public EChartType ChartType
 149         {
 150             get { return _chartType; }
 151             set { _chartType = value; }
 152         }
 153 
 154         /// <summary>
 155         /// 圖表寬度
 156         /// </summary>
 157         private int _chartWidth = 0;
 158 
 159         /// <summary>
 160         /// 獲取--設置--圖表寬度
 161         /// </summary>
 162         public int ChartWidth
 163         {
 164             get { return _chartWidth; }
 165             set { _chartWidth = value; }
 166         }
 167 
 168         /// <summary>
 169         /// 圖表高度
 170         /// </summary>
 171         private int _chartHeight = 0;
 172 
 173         /// <summary>
 174         /// 獲取--設置--圖表高度
 175         /// </summary>
 176         public int ChartHeight
 177         {
 178             get { return _chartHeight; }
 179             set { _chartHeight = value; }
 180         }
 181 
 182         /// <summary>
 183         /// 圖表背景顏色
 184         /// </summary>
 185         private Color _backColor = Color.White;
 186 
 187         /// <summary>
 188         /// 獲取--設置--圖表背景顏色
 189         /// </summary>
 190         public Color BackColor
 191         {
 192             get { return _backColor; }
 193             set { _backColor = value; }
 194         }
 195 
 196         /// <summary>
 197         /// 是否顯示圖表邊框
 198         /// </summary>
 199         private bool _showBorder = true;
 200 
 201         /// <summary>
 202         /// 獲取--設置--是否顯示圖表邊框
 203         /// 默認:true 顯示
 204         /// </summary>
 205         public bool ShowBorder
 206         {
 207             get { return _showBorder; }
 208             set { _showBorder = value; }
 209         }
 210 
 211         /// <summary>
 212         /// 圖表邊框顏色
 213         /// </summary>
 214         private Color _borderColor = Color.LightGray;
 215 
 216         /// <summary>
 217         /// 獲取--設置--圖表邊框顏色
 218         /// </summary>
 219         public Color BorderColor
 220         {
 221             get { return _borderColor; }
 222             set { _borderColor = value; }
 223         }
 224 
 225         /// <summary>
 226         /// 是否顯示網格線
 227         /// </summary>
 228         private bool _showGrid = true;
 229 
 230         /// <summary>
 231         /// 獲取--設置--是否顯示網格線
 232         /// 默認:true 顯示
 233         /// </summary>
 234         public bool ShowGrid
 235         {
 236             get { return _showGrid; }
 237             set { _showGrid = value; }
 238         }
 239 
 240         /// <summary>
 241         /// 線條張力系數
 242         /// </summary>
 243         private float _lineTension = 0.3f;
 244 
 245         /// <summary>
 246         /// 獲取--設置--線條張力系數
 247         /// 默認:0.3
 248         /// </summary>
 249         public float LineTension
 250         {
 251             get { return _lineTension; }
 252             set
 253             {
 254                 if (value < 0.0f && value > 1.0f)
 255                     _lineTension = 0.5f;
 256                 else
 257                     _lineTension = value;
 258             }
 259         }
 260 
 261         #endregion
 262 
 263         #region 標題屬性
 264 
 265         /// <summary>
 266         /// 是否顯示主標題
 267         /// </summary>
 268         private bool _showTitle = true;
 269 
 270         /// <summary>
 271         /// 獲取--設置--是否顯示主標題
 272         /// 默認:true 顯示
 273         /// </summary>
 274         public bool ShowTitle
 275         {
 276             get { return _showTitle; }
 277             set { _showTitle = value; }
 278         }
 279 
 280         /// <summary>
 281         /// 主標題文本
 282         /// </summary>
 283         private string _title = "";
 284 
 285         /// <summary>
 286         /// 獲取--設置--主標題文本
 287         /// </summary>
 288         public string Title
 289         {
 290             get { return _title; }
 291             set { _title = value; }
 292         }
 293 
 294         /// <summary>
 295         /// 主標題字體
 296         /// </summary>
 297         private Font _titleFont = new Font("黑體", 12);
 298 
 299         /// <summary>
 300         /// 獲取--設置--主標題字體
 301         /// </summary>
 302         public Font TitleFont
 303         {
 304             get { return _titleFont; }
 305             set { _titleFont = value; }
 306         }
 307 
 308         /// <summary>
 309         /// 主標題顏色
 310         /// </summary>
 311         private Color _titleColor = Color.Black;
 312 
 313         /// <summary>
 314         /// 獲取--設置--主標題顏色
 315         /// </summary>
 316         public Color TitleColor
 317         {
 318             get { return _titleColor; }
 319             set { _titleColor = value; }
 320         }
 321 
 322         /// <summary>
 323         /// 主標題對齊方式
 324         /// </summary>
 325         private EAlign _titleAlign = EAlign.center;
 326 
 327         /// <summary>
 328         /// 獲取--設置--主標題對齊方式
 329         /// </summary>
 330         public EAlign TitleAlign
 331         {
 332             get { return _titleAlign; }
 333             set { _titleAlign = value; }
 334         }
 335 
 336         /// <summary>
 337         /// 是否顯示副標題
 338         /// </summary>
 339         private bool _showSubTilte = true;
 340 
 341         /// <summary>
 342         /// 獲取--設置--是否顯示副標題
 343         /// 默認:true 顯示
 344         /// </summary>
 345         public bool ShowSubTitle
 346         {
 347             get { return _showSubTilte; }
 348             set { _showSubTilte = value; }
 349         }
 350 
 351         /// <summary>
 352         /// 副標題文本
 353         /// </summary>
 354         private string _subTitle = "";
 355 
 356         /// <summary>
 357         /// 獲取--設置--副標題文本
 358         /// </summary>
 359         public string SubTitle
 360         {
 361             get { return _subTitle; }
 362             set { _subTitle = value; }
 363         }
 364 
 365         /// <summary>
 366         /// 副標題字體
 367         /// </summary>
 368         private Font _subTitleFont = new Font("黑體", 10);
 369 
 370         /// <summary>
 371         /// 獲取--設置--副標題字體
 372         /// </summary>
 373         public Font SubTitleFont
 374         {
 375             get { return _subTitleFont; }
 376             set { _subTitleFont = value; }
 377         }
 378 
 379         /// <summary>
 380         /// 副標題顏色
 381         /// </summary>
 382         private Color _subTitleColor = Color.Blue;
 383 
 384         /// <summary>
 385         /// 獲取--設置--副標題顏色
 386         /// </summary>
 387         public Color SubTitleColor
 388         {
 389             get { return _subTitleColor; }
 390             set { _subTitleColor = value; }
 391         }
 392 
 393         /// <summary>
 394         /// 副標題對齊方式
 395         /// </summary>
 396         private EAlign _subTitleAlign = EAlign.center;
 397 
 398         /// <summary>
 399         /// 獲取--設置--副標題對齊方式
 400         /// </summary>
 401         public EAlign SubTitleAlign
 402         {
 403             get { return _subTitleAlign; }
 404             set { _subTitleAlign = value; }
 405         }
 406 
 407         /// <summary>
 408         /// 副標題水平方向偏移量
 409         /// + - 整數
 410         /// </summary>
 411         private int _subTitleOffset = 0;
 412 
 413         /// <summary>
 414         /// 獲取--設置--副標題水平方向偏移量
 415         /// </summary>
 416         public int SubTitleOffset
 417         {
 418             get { return _subTitleOffset; }
 419             set { _subTitleOffset = value; }
 420         }
 421 
 422         #endregion
 423 
 424         #region 圖例屬性
 425 
 426         /// <summary>
 427         /// 是否顯示圖例
 428         /// </summary>
 429         private bool _showLegend = true;
 430 
 431         /// <summary>
 432         /// 是否顯示圖例
 433         /// </summary>
 434         public bool ShowLegend
 435         {
 436             get { return _showLegend; }
 437             set { _showLegend = value; }
 438         }
 439 
 440         /// <summary>
 441         /// 圖例字體
 442         /// </summary>
 443         private Font _legendFont = new Font("宋體", 9);
 444 
 445         /// <summary>
 446         /// 獲取--設置--圖例字體
 447         /// </summary>
 448         public Font LegendFont
 449         {
 450             get { return _legendFont; }
 451             set { _legendFont = value; }
 452         }
 453 
 454         /// <summary>
 455         /// 圖例字體顏色
 456         /// </summary>
 457         private Color _legendColor = Color.Black;
 458 
 459         /// <summary>
 460         /// 獲取--設置--圖例字體顏色
 461         /// </summary>
 462         public Color LegendColor
 463         {
 464             get { return _legendColor; }
 465             set { _legendColor = value; }
 466         }
 467 
 468         /// <summary>
 469         /// 圖例對齊方式
 470         /// </summary>
 471         private EAlign _legendAlign = EAlign.center;
 472 
 473         /// <summary>
 474         /// 獲取--設置--圖例對齊方式
 475         /// </summary>
 476         public EAlign LegendAlign
 477         {
 478             get { return _legendAlign; }
 479             set { _legendAlign = value; }
 480         }
 481 
 482         #endregion
 483 
 484         #region 座標屬性
 485 
 486         /// <summary>
 487         /// 獲取--X軸分割段數
 488         /// </summary>
 489         public int XSplitNum
 490         {
 491             get { return _xScaleValues.Count; }
 492         }
 493 
 494         /// <summary>
 495         /// Y軸分割段數
 496         /// </summary>
 497         private int _ySplitNum = 5;
 498 
 499         /// <summary>
 500         /// 獲取--設置--分割段數
 501         /// 默認:5
 502         /// 範圍:最小5
 503         /// </summary>
 504         public int YSplitNum
 505         {
 506             get { return _ySplitNum; }
 507             set
 508             {
 509                 if (value < 5)
 510                     _ySplitNum = 5;
 511                 else
 512                     _ySplitNum = value;
 513 
 514             }
 515         }
 516 
 517         /// <summary>
 518         /// X 軸標
 519         /// </summary>
 520         private string _xAxisText = "";
 521 
 522         /// <summary>
 523         /// 獲取--設置--X 軸標
 524         /// </summary>
 525         public string XAxisText
 526         {
 527             get { return _xAxisText; }
 528             set { _xAxisText = value; }
 529         }
 530 
 531         /// <summary>
 532         /// Y 軸標
 533         /// </summary>
 534         private string _yAxisText = "";
 535 
 536         /// <summary>
 537         /// 獲取--設置--Y 軸標
 538         /// </summary>
 539         public string YAxisText
 540         {
 541             get { return _yAxisText; }
 542             set { _yAxisText = value; }
 543         }
 544 
 545         /// <summary>
 546         /// X軸文本旋轉角度
 547         /// 默認:0
 548         /// 範圍:0~90
 549         /// </summary>
 550         private float _xRotateAngle = 0.0f;
 551 
 552         /// <summary>
 553         /// 獲取--設置--X軸文本旋轉角度
 554         /// </summary>
 555         public float XRotateAngle
 556         {
 557             get { return _xRotateAngle; }
 558             set
 559             {
 560                 if (value >= 0.0f && value <= 90.0f)
 561                     _xRotateAngle = value;
 562                 else
 563                     _xRotateAngle = 0.0f;
 564             }
 565         }
 566 
 567         #endregion
 568 
 569         #region 繪圖變量
 570 
 571         /// <summary>
 572         /// 繪圖對象
 573         /// </summary>
 574         private Graphics g = null;
 575 
 576         /// <summary>
 577         /// 圖表顏色數組
 578         /// </summary>
 579         private static Color[] ChartColor = { 
 580                                                  Color.Red, Color.Blue, Color.Orange, Color.Green, Color.Cyan, Color.Purple,
 581                                                  Color.Coral, Color.Chocolate, Color.Gray, Color.Gold, Color.Lavender, Color.Linen,
 582                                                  Color.Magenta, Color.Moccasin, Color.Navy, Color.Olive, Color.Peru, Color.Plum,
 583                                                  Color.Purple, Color.Salmon, Color.Sienna, Color.Silver, Color.Tan, Color.Tomato, 
 584                                                  Color.Violet, Color.Turquoise, Color.Transparent
 585                                              };
 586 
 587         /// <summary>
 588         /// 邊距10px
 589         /// </summary>
 590         private float Margin = 10;
 591 
 592         /// <summary>
 593         /// 起點 X 座標
 594         /// </summary>
 595         private float Start_X = 0;
 596 
 597         /// <summary>
 598         /// 起點 Y 座標
 599         /// </summary>
 600         private float Start_Y = 0;
 601 
 602         /// <summary>
 603         /// 終點 X 座標
 604         /// </summary>
 605         private float End_X = 0;
 606 
 607         /// <summary>
 608         /// 終點 Y 座標
 609         /// </summary>
 610         private float End_Y = 0;
 611 
 612         /// <summary>
 613         /// X軸刻度寬度
 614         /// </summary>
 615         private float XScaleWidth = 0;
 616 
 617         /// <summary>
 618         /// Y軸刻度寬度
 619         /// </summary>
 620         private float YScaleWidth = 0;
 621 
 622         /// <summary>
 623         /// Y軸刻度間隔值
 624         /// 說明:Y軸座標所有采用整數,表示每一個間隔的計算單位值
 625         /// 包含正負數
 626         /// </summary>
 627         private double YScale_SplitValue = 0;
 628 
 629         /// <summary>
 630         /// Y軸刻度開始值
 631         /// </summary>
 632         private double YScale_StartValue = 0;
 633 
 634         /// <summary>
 635         /// 座標軸原點座標
 636         /// </summary>
 637         private PointF AxisZeroPt = new PointF(0f, 0f);
 638 
 639         /// <summary>
 640         /// 圖表數據
 641         /// </summary>
 642         private string _chartData = "";
 643 
 644         /// <summary>
 645         /// 獲取--設置--圖表數據
 646         /// </summary>
 647         public string ChartData
 648         {
 649             get { return _chartData; }
 650             set { _chartData = value; }
 651         }
 652 
 653         /// <summary>
 654         /// 繪圖筆刷
 655         /// </summary>
 656         private Brush brush;
 657 
 658         /// <summary>
 659         /// 繪製畫筆
 660         /// </summary>
 661         private Pen pen;
 662 
 663         /// <summary>
 664         /// 繪圖矩形
 665         /// </summary>
 666         private RectangleF rectF = new RectangleF(0, 0, 0, 0);
 667 
 668         /// <summary>
 669         /// 字符格式化
 670         /// </summary>
 671         private StringFormat stringFormat;
 672 
 673         /// <summary>
 674         /// 臨時變量 最大值
 675         /// </summary>
 676         private double myMaxValue = 0;
 677 
 678         /// <summary>
 679         /// 臨時變量 最小值
 680         /// </summary>
 681         private double myMinValue = 0;
 682 
 683         /// <summary>
 684         /// 臨時變量 X軸刻度最大高度
 685         /// 用於繪製座標軸的時候進行偏移
 686         /// </summary>
 687         private float myXScaleMaxHeight = 0;
 688 
 689         /// <summary>
 690         /// 臨時變量 Y軸刻度值字符串的最大寬度
 691         /// 用於繪製座標軸的時候進行偏移
 692         /// </summary>
 693         private float myYScaleMaxWidth = 0;
 694 
 695         #endregion
 696 
 697         #region 圖表數據
 698 
 699         /// <summary>
 700         /// X軸刻度值數組
 701         /// </summary>
 702         private List<string> _xScaleValues = new List<string>();
 703 
 704         /// <summary>
 705         /// 獲取--設置--X軸刻度值數組
 706         /// </summary>
 707         public List<string> XScaleValues
 708         {
 709             get { return _xScaleValues; }
 710             set { _xScaleValues = value; }
 711         }
 712 
 713         /// <summary>
 714         /// 圖表數據
 715         /// </summary>
 716         private List<EChartData> _chartDataArray = new List<EChartData>();
 717 
 718         /// <summary>
 719         /// 獲取--設置--圖表數據
 720         /// </summary>
 721         public List<EChartData> ChartDataArray
 722         {
 723             get { return _chartDataArray; }
 724             set { _chartDataArray = value; }
 725         }
 726 
 727         #endregion
 728 
 729         #endregion
 730 
 731         #region 構造方法
 732 
 733         /// <summary>
 734         /// 構造函數
 735         /// </summary>
 736         public EChart()
 737         {
 738 
 739         }
 740 
 741         /// <summary>
 742         /// 構造函數
 743         /// </summary>
 744         /// <param name="eChart"></param>
 745         public EChart(EChart eChart)
 746         {
 747 
 748         }
 749 
 750         #endregion
 751 
 752         #region 生成圖表
 753 
 754         /// <summary>
 755         /// 生成圖表
 756         /// </summary>
 757         /// <returns>返回:圖表圖像</returns>
 758         public Bitmap CreateImage()
 759         {
 760             Bitmap ChartImage = new Bitmap(ChartWidth, ChartHeight);
 761             g = Graphics.FromImage(ChartImage);
 762             g.SmoothingMode = SmoothingMode.Default;
 763             g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
 764             g.Clear(Color.White);
 765 
 766             Start_X = Margin;
 767             Start_Y = Margin;
 768             End_X = ChartWidth - Margin;
 769             End_Y = ChartHeight - Margin;
 770 
 771             DrawChart();
 772 
 773             g.Dispose();
 774 
 775             return ChartImage;
 776         }
 777 
 778         #endregion
 779 
 780         #region 繪製方法
 781 
 782         /// <summary>
 783         /// 繪製圖表
 784         /// </summary>
 785         private void DrawChart()
 786         {
 787             DrawChart_InitGraph();
 788             DrawChart_MainTitle();
 789             DrawChart_SubTitle();
 790             DrawChart_Legend();
 791             DrawChart_YAxisText();
 792             if (ChartType != EChartType.Pie)
 793             {
 794                 DrawChart_Axis();
 795                 if (ChartType == EChartType.Curve)
 796                     DrawChart_Curve();
 797                 else
 798                     DrawChart_Bar();
 799             }
 800             else
 801             {
 802                 DrawChart_Pie();
 803             }
 804         }
 805 
 806         /// <summary>
 807         /// 繪製圖表--繪製背景圖
 808         /// </summary>
 809         private void DrawChart_InitGraph()
 810         {
 811             // 繪製圖表外圍邊框
 812             if (_showBorder)
 813                 g.DrawRectangle(new Pen(BorderColor, 1), 0, 0, (ChartWidth - 1), (ChartHeight - 1));
 814 
 815             // 填充圖表背景顏色
 816             g.FillRectangle(new SolidBrush(BackColor), 1, 1, ChartWidth - 2, ChartHeight - 2);
 817 
 818         }
 819 
 820         /// <summary>
 821         /// 繪製圖表--繪製主標題
 822         /// </summary>
 823         private void DrawChart_MainTitle()
 824         {
 825             if (ShowTitle)
 826             {
 827                 if (Title != null && Title.Trim() != "")
 828                 {
 829                     brush = new SolidBrush(TitleColor);                     // 矩形填充筆刷
 830                     SizeF sizeF = g.MeasureString(Title, TitleFont);        // 測試字體大小
 831                     stringFormat = new StringFormat();                      // 格式化字符串
 832                     stringFormat.LineAlignment = StringAlignment.Center;    // 垂直對齊方式
 833                     switch (TitleAlign)                                     // 水平對齊方式
 834                     {
 835                         case EAlign.center:
 836                             stringFormat.Alignment = StringAlignment.Center;
 837                             break;
 838                         case EAlign.right:
 839                             stringFormat.Alignment = StringAlignment.Far;
 840                             break;
 841                         default:
 842                             stringFormat.Alignment = StringAlignment.Near;
 843                             break;
 844                     }
 845 
 846                     rectF = new RectangleF(Start_X, Start_Y, (float)(ChartWidth - 4), sizeF.Height);  // 文字的矩形
 847                     g.DrawString(Title, TitleFont, brush, rectF, stringFormat);                       // 繪製主標題
 848                     Start_Y += sizeF.Height + 3f;                                                     // 設置Y起點值 + 3px
 849                 }
 850             }
 851         }
 852 
 853         /// <summary>
 854         /// 繪製圖表--繪製副標題
 855         /// </summary>
 856         private void DrawChart_SubTitle()
 857         {
 858             if (ShowSubTitle)
 859             {
 860                 if (SubTitle != null && SubTitle.Trim() != "")
 861                 {
 862                     brush = new SolidBrush(SubTitleColor);                  // 矩形填充筆刷
 863                     SizeF sizeF = g.MeasureString(SubTitle, SubTitleFont);  // 測試字體大小
 864                     stringFormat = new StringFormat();                      // 格式化字符串
 865                     stringFormat.LineAlignment = StringAlignment.Center;    // 垂直對齊方式
 866                     switch (SubTitleAlign)                                  // 水平對齊方式
 867                     {
 868                         case EAlign.center:
 869                             stringFormat.Alignment = StringAlignment.Center;
 870                             break;
 871                         case EAlign.right:
 872                             stringFormat.Alignment = StringAlignment.Far;
 873                             break;
 874                         default:
 875                             stringFormat.Alignment = StringAlignment.Near;
 876                             break;
 877                     }
 878 
 879                     rectF = new RectangleF(Start_X + (float)SubTitleOffset, Start_Y, (float)(ChartWidth - 4), sizeF.Height);  // 文字的矩形
 880                     g.DrawString(SubTitle, SubTitleFont, brush, rectF, stringFormat);                                               // 繪製副標題

 881                     Start_Y += sizeF.Height + 3f;                                                                             // 設置Y起點值 + 3px
 882                 }
 883             }
 884 
 885         }
 886 
 887         /// <summary>
 888         /// 繪製圖表--繪製圖例
 889         /// </summary>
 890         private void DrawChart_Legend()
 891         {
 892             // 計算項目顏色
 893             int tmIndex = 0;
 894             for (int m = 0; m < ChartDataArray.Count; m++)
 895             {
 896                 tmIndex = m % ChartColor.Length;
 897                 ChartDataArray[m].ItemColor = ChartColor[tmIndex];
 898             }
 899 
 900             // 圖例的高度最大40px 3排
 901             if (ShowLegend)
 902             {
 903                 // 計算文字大小 
 904                 int LegendCount = ChartDataArray.Count;
 905                 Font tFont = new Font("宋體", 9);
 906                 for (int t = 0; t < LegendCount; t++)
 907                 {
 908                     SizeF tmSize = new SizeF();
 909                     tmSize = g.MeasureString(ChartDataArray[t].Name, tFont);
 910                     ChartDataArray[t].NameSize = tmSize;
 911                 }
 912 
 913                 #region 繪製一排圖例
 914 
 915                 // 首先斷定一行夠不夠
 916                 float largMax = 0;
 917                 for (int t = 0; t < LegendCount; t++)
 918                 {
 919                     if (t == 0)
 920                         largMax += ChartDataArray[t].NameSize.Width;
 921                     else
 922                         largMax += (35f + ChartDataArray[t].NameSize.Width);
 923                 }
 924 
 925                 if (largMax <= End_X - Start_X) // 圖例只需一排
 926                 {
 927                     End_Y -= 12.0f;
 928                     float tmX = (End_X - Start_X - largMax) / 2 + Start_X;
 929                     float tmY = End_Y;
 930                     for (int n = 0; n < LegendCount; n++)
 931                     {
 932                         g.FillRectangle(new SolidBrush(ChartDataArray[n].ItemColor), tmX, tmY + 1, 15, 10);
 933                         tmX += 20;
 934                         g.DrawString(ChartDataArray[n].Name, new Font("宋體", 9), new SolidBrush(Color.Black), tmX, tmY);
 935                         tmX += 15 + ChartDataArray[n].NameSize.Width;
 936                     }
 937                 }
 938 
 939                 #endregion
 940 
 941                 #region 繪製多排圖例
 942 
 943                 // 圖例最多繪製三排
 944                 else
 945                 {
 946 
 947                     bool TwoLine = true;                     // 是否兩行:true 是; false: 否,爲三行
 948 
 949                     // 斷定兩排仍是三排
 950                     float tmBX = Start_X - 5;
 951                     int tmBC = (int)Math.Ceiling((double)LegendCount / 2);
 952                     for (int T = 0; T < tmBC; T++)
 953                     {
 954                         float tmBW1 = -1F, tmBW2 = -1F, tmBM = 0F;
 955                         tmBW1 = ChartDataArray[T * 2].NameSize.Width;
 956                         if (ChartDataArray.Count > (T * 2 + 1))
 957                             tmBW2 = ChartDataArray[T * 2 + 1].NameSize.Width;
 958                         tmBM = tmBW1 > tmBW2 ? tmBW1 : tmBW2;
 959                         tmBX += 35 + tmBM;
 960                         if (tmBX > (End_X + 5))
 961                         {
 962                             TwoLine = false;
 963                             break;
 964                         }
 965                     }
 966 
 967                     // 繪製兩排圖例
 968                     if (TwoLine)
 969                     {
 970                         End_Y -= 24.0f;
 971                         float tmTX = (End_X + 10 - tmBX + Start_X + 5) / 2;       // 開始位置保持兩排水平居中
 972                         float tmTY = End_Y;
 973                         int tmTM = (int)Math.Ceiling((double)LegendCount / 2);
 974 
 975                         // 繪製兩排圖例
 976                         for (int T = 0; T < tmTM; T++)
 977                         {
 978                             float tmTW1 = -1F, tmTW2 = -1F, tmTW3 = 0F;
 979                             tmTW1 = ChartDataArray[T * 2].NameSize.Width;
 980                             if (ChartDataArray.Count > (T * 2 + 1))
 981                                 tmTW2 = ChartDataArray[T * 2 + 1].NameSize.Width;
 982                             tmTW3 = tmTW1 > tmTW2 ? tmTW1 : tmTW2;
 983 
 984                             // 繪製第一排圖例
 985                             g.FillRectangle(new SolidBrush(ChartDataArray[T * 2].ItemColor), tmTX, tmTY + 1, 15, 10);
 986                             g.DrawString(ChartDataArray[T * 2].Name, new Font("宋體", 9), new SolidBrush(Color.Black), (tmTX + 20), tmTY);
 987 
 988                             // 繪製第二排圖例
 989                             if (tmTW2 > 0)
 990                             {
 991                                 g.FillRectangle(new SolidBrush(ChartDataArray[T * 2 + 1].ItemColor), tmTX, (tmTY + 16 + 1), 15, 10);
 992                                 g.DrawString(ChartDataArray[T * 2 + 1].Name, new Font("宋體", 9), new SolidBrush(Color.Black), (tmTX + 20), (tmTY + 16));
 993                             }
 994                             tmTX += 35 + tmTW3;
 995                         }
 996                     }
 997 
 998                     // 繪製三排圖例
 999                     else
1000                     {
1001                         End_Y -= 40.0f;
1002                         // 若是三排還不夠,那麼就無論了,繪製超出範圍就超出範圍
1003                         float tmSX = Start_X - 5;
1004                         float tmSY = End_Y;
1005                         int tmSC = (int)Math.Ceiling((double)LegendCount / 3);
1006                         bool CanFlag = true;  // 三排是否足夠
1007 
1008                         // 首先計算三排的能排下的居中位置
1009                         for (int n = 0; n < tmSC; n++)
1010                         {
1011                             float tmSW1 = -1F, tmSW2 = -1F, tmSW3 = -1F, tmSW4 = 0F;
1012                             tmSW1 = ChartDataArray[n * 3].NameSize.Width;
1013                             if (ChartDataArray.Count > (n * 3 + 1))
1014                                 tmSW2 = ChartDataArray[n * 3 + 1].NameSize.Width;
1015                             if (ChartDataArray.Count > (n * 3 + 2))
1016                                 tmSW3 = ChartDataArray[n * 3 + 2].NameSize.Width;
1017                             tmSW4 = tmSW1 > tmSW2 ? tmSW1 : tmSW2;
1018                             tmSW4 = tmSW4 > tmSW3 ? tmSW4 : tmSW3;
1019                             tmSX += 35 + tmSW4;
1020                             if (tmSX > (End_X + 5))
1021                             {
1022                                 CanFlag = false;
1023                                 break;
1024                             }
1025                         }
1026 
1027                         // 再次執行三排繪製
1028                         if (CanFlag)             // 三排足夠,則設置居中開始位置
1029                             tmSX = (End_X + 10 - tmSX + Start_X + 5) / 2;
1030                         else
1031                             tmSX = Start_X - 5;  // 三排排不下的狀況就從5px 開始
1032 
1033                         for (int n = 0; n < tmSC; n++)
1034                         {
1035                             float tmSW1 = -1F, tmSW2 = -1F, tmSW3 = -1F, tmSW4 = 0F;
1036                             tmSW1 = ChartDataArray[n * 3].NameSize.Width;
1037                             if (ChartDataArray.Count > (n * 3 + 1))
1038                                 tmSW2 = ChartDataArray[n * 3 + 1].NameSize.Width;
1039                             if (ChartDataArray.Count > (n * 3 + 2))
1040                                 tmSW3 = ChartDataArray[n * 3 + 2].NameSize.Width;
1041                             tmSW4 = tmSW1 > tmSW2 ? tmSW1 : tmSW2;
1042                             tmSW4 = tmSW4 > tmSW3 ? tmSW4 : tmSW3;
1043 
1044                             // 繪製第一排圖例
1045                             g.FillRectangle(new SolidBrush(ChartDataArray[n * 3].ItemColor), tmSX, (tmSY + 1), 15, 10);
1046                             g.DrawString(ChartDataArray[n * 3].Name, new Font("宋體", 9), new SolidBrush(Color.Black), (tmSX + 20), tmSY);
1047 
1048                             // 繪製第二排圖例
1049                             if (tmSW2 > 0)
1050                             {
1051                                 g.FillRectangle(new SolidBrush(ChartDataArray[n * 3 + 1].ItemColor), tmSX, (tmSY + 16 + 1), 15, 10);
1052                                 g.DrawString(ChartDataArray[n * 3 + 1].Name, new Font("宋體", 9), new SolidBrush(Color.Black), (tmSX + 20), (tmSY + 16));
1053                             }
1054 
1055                             // 繪製第三排圖例
1056                             if (tmSW3 > 0)
1057                             {
1058                                 g.FillRectangle(new SolidBrush(ChartDataArray[n * 3 + 2].ItemColor), tmSX, (tmSY + 32 + 1), 15, 10);
1059                                 g.DrawString(ChartDataArray[n * 3 + 2].Name, new Font("宋體", 9), new SolidBrush(Color.Black), (tmSX + 20), (tmSY + 32));
1060                             }
1061 
1062                             tmSX += 35 + tmSW4;
1063                         }
1064                     }
1065                 }
1066 
1067                 #endregion
1068             }
1069         }
1070 
1071         /// <summary>
1072         /// 繪製圖表--繪製X軸標
1073         /// </summary>
1074         /// <param name="g"></param>
1075         private void DrawChart_XAxisText()
1076         {
1077             // X軸標就不繪製了,由於空間不夠,因此不執行X軸標的繪製
1078         }
1079 
1080         /// <summary>
1081         /// 繪製圖表--繪製Y軸標
1082         /// </summary>
1083         private void DrawChart_YAxisText()
1084         {
1085             if (ChartType != EChartType.Pie)
1086             {
1087                 if (YAxisText != null && YAxisText.Trim() != "")
1088                 {
1089                     brush = new SolidBrush(Color.Gray);
1090                     stringFormat = new StringFormat();                                    // 格式化字符串
1091                     stringFormat.LineAlignment = StringAlignment.Near;                    // 垂直對齊方式
1092                     stringFormat.Alignment = StringAlignment.Near;                        // 水平對齊方式
1093                     SizeF sizeF = g.MeasureString(YAxisText, new Font("宋體", 9));        // 測量文字大小
1094                     rectF = new RectangleF(Start_X, Start_Y, sizeF.Width, sizeF.Height);  // 文字外圍矩形
1095                     g.TranslateTransform((Start_X - Start_Y), (Start_X + Start_Y + sizeF.Width));    // 設置位置移動 X,Y 
1096                     g.RotateTransform(270);                                                          // 旋轉270度  以左上角做爲旋轉原點
1097                     g.DrawString(YAxisText, new Font("宋體", 9), brush, rectF, stringFormat);
1098                     g.ResetTransform();
1099 
1100                     Start_X += sizeF.Height + 2;                                          // 加2個像素
1101                 }
1102             }
1103         }
1104 
1105         /// <summary>
1106         /// 繪製圖表--繪製座標軸
1107         /// </summary>
1108         private void DrawChart_Axis()
1109         {
1110             // 一、圖表區下移10PX
1111             Start_Y += 10;
1112 
1113             // 二、計算座標軸參數
1114             Calc_XScaleHeight();
1115             Calc_YScaleValue();
1116 
1117             // 三、計算原點座標值
1118             AxisZeroPt = new PointF(0f, 0f); // 座標軸原點座標
1119             AxisZeroPt.X = Start_X + myYScaleMaxWidth;
1120             AxisZeroPt.Y = End_Y - myXScaleMaxHeight;
1121 
1122             // 3.一、繪製座標軸
1123             Pen pen2 = new Pen(Color.FromKnownColor(KnownColor.ControlDark), 2f);
1124             g.DrawLine(pen2, (Start_X + myYScaleMaxWidth - 4f), (End_Y - myXScaleMaxHeight), End_X + 2, (End_Y - myXScaleMaxHeight));     // 繪製 X座標軸
1125             g.DrawLine(pen2, (Start_X + myYScaleMaxWidth), (End_Y - myXScaleMaxHeight + 4f), (Start_X + myYScaleMaxWidth), Start_Y - 2);  // 繪製 Y座標軸
1126 
1127             // 3.二、計算分段寬
1128             XScaleWidth = (End_X - Start_X - myYScaleMaxWidth) / XSplitNum;      // 計算X軸分段寬
1129             YScaleWidth = (End_Y - Start_Y - myXScaleMaxHeight) / YSplitNum;     // 計算Y軸分段寬
1130 
1131             // 3.三、繪製刻度值
1132             pen = new Pen(Color.LightGray, 1f);
1133             pen.DashStyle = DashStyle.Dash;
1134             for (int k = 0; k < XSplitNum; k++)    // 繪製X軸刻度線 刻度值
1135             {
1136                 // 繪製X軸刻度線
1137                 g.DrawLine(pen2, (AxisZeroPt.X + XScaleWidth * (k + 1)), AxisZeroPt.Y, (AxisZeroPt.X + XScaleWidth * (k + 1)), AxisZeroPt.Y + 4f);
1138 
1139                 // 繪製X軸刻度值
1140                 g.TranslateTransform(AxisZeroPt.X + XScaleWidth * k + 15f * XRotateAngle / 90 + 4f, AxisZeroPt.Y + 4f);  // 平移原點
1141                 g.RotateTransform(XRotateAngle, MatrixOrder.Prepend);                                                    // 旋轉圖像
1142                 g.DrawString(XScaleValues[k], new Font("宋體", 9f), new SolidBrush(Color.Black), 0, 0);                  // 繪製字符
1143                 g.ResetTransform();
1144             }
1145 
1146             for (int k = 0; k < YSplitNum; k++)
1147             {
1148                 // 繪製Y軸刻度線
1149                 g.DrawLine(pen2, AxisZeroPt.X - 4, (AxisZeroPt.Y - YScaleWidth * (k + 1)), AxisZeroPt.X, (AxisZeroPt.Y - YScaleWidth * (k + 1)));
1150 
1151                 // 繪製Y軸刻度值
1152                 string tmYvalue = (YScale_StartValue + k * YScale_SplitValue).ToString();
1153                 SizeF tmF = g.MeasureString(tmYvalue, new Font("宋體", 9));
1154                 g.DrawString(tmYvalue, new Font("宋體", 9), new SolidBrush(Color.Black), (AxisZeroPt.X - tmF.Width - 4), (AxisZeroPt.Y - YScaleWidth * k - tmF.Height / 2 + 1));
1155 
1156                 if (k == YSplitNum - 1)
1157                 {
1158                     tmYvalue = (YScale_StartValue + (k + 1) * YScale_SplitValue).ToString();
1159                     tmF = g.MeasureString(tmYvalue, new Font("宋體", 9));
1160                     g.DrawString(tmYvalue, new Font("宋體", 9), new SolidBrush(Color.Black), (AxisZeroPt.X - tmF.Width - 4), (AxisZeroPt.Y - YScaleWidth * (k + 1) - tmF.Height / 2 + 1));
1161                 }
1162             }
1163 
1164 
1165             // 3.四、繪製網格線
1166             if (ShowGrid)
1167             {
1168                 for (int k = 1; k <= YSplitNum; k++)  // 繪製X軸平行橫向輔助線
1169                     g.DrawLine(pen, AxisZeroPt.X + 1, (AxisZeroPt.Y - YScaleWidth * k), End_X, (AxisZeroPt.Y - YScaleWidth * k));
1170 
1171                 for (int k = 1; k <= XSplitNum; k++)  // 繪製Y軸平行縱向輔助線
1172                     g.DrawLine(pen, (AxisZeroPt.X + XScaleWidth * k), Start_Y, (AxisZeroPt.X + XScaleWidth * k), AxisZeroPt.Y - 1);
1173             }
1174 
1175             pen2.Dispose();
1176         }
1177 
1178         /// <summary>
1179         /// 繪製曲線圖
1180         /// </summary>
1181         private void DrawChart_Curve()
1182         {
1183             g.SmoothingMode = SmoothingMode.HighQuality;
1184             g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
1185             g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
1186 
1187             int tmLength = 0;
1188             PointF[] CurvePointF = new PointF[tmLength];
1189             foreach (EChartData iItem in this.ChartDataArray)
1190             {
1191                 tmLength = iItem.Values.Count;
1192                 CurvePointF = new PointF[tmLength];
1193                 pen = new Pen(iItem.ItemColor, 2.0f);
1194                 for (int rr = 0; rr < iItem.Values.Count; rr++)
1195                 {
1196                     double dbValue = iItem.Values[rr];
1197                     CurvePointF[rr].X = AxisZeroPt.X + XScaleWidth * rr + XScaleWidth / 2;
1198                     CurvePointF[rr].Y = AxisZeroPt.Y - (float)((dbValue - YScale_StartValue) / YScale_SplitValue) * YScaleWidth;
1199                 }
1200 
1201                 // 繪製曲線
1202                 g.DrawCurve(pen, CurvePointF, LineTension);
1203 
1204                 // 繪製輔點
1205                 for (int tt = 0; tt < CurvePointF.Length; tt++)
1206                 {
1207                     // 點標數據值
1208                     string tmValStr = iItem.Values[tt].ToString();
1209 
1210                     // 繪製數據點
1211                     g.FillEllipse(new SolidBrush(iItem.ItemColor), CurvePointF[tt].X - 3, CurvePointF[tt].Y - 3, 6, 6);
1212 
1213                     // 繪製數據值
1214                     SizeF tmValueSize = g.MeasureString(tmValStr, new Font("Arial", 9));
1215                     g.DrawString(tmValStr, new Font("Arial", 9), new SolidBrush(iItem.ItemColor), (CurvePointF[tt].X - tmValueSize.Width / 2), (CurvePointF[tt].Y - tmValueSize.Height - 2f));
1216                 }
1217             }
1218         }
1219 
1220         /// <summary>
1221         /// 繪製柱狀圖
1222         /// </summary>
1223         private void DrawChart_Bar()
1224         {
1225             g.SmoothingMode = SmoothingMode.HighQuality;
1226             int tmLen = ChartDataArray.Count;                       // 柱形條目總數
1227             float tmBarWidth = XScaleWidth / (tmLen * 2 + 1);    // 每條柱形寬度 平均分配
1228             if (tmBarWidth < 2)
1229             {
1230                 tmBarWidth = 2f;
1231             }
1232 
1233             for (int kk = 0; kk < this.ChartDataArray.Count; kk++)
1234             {
1235                 EChartData iItem = this.ChartDataArray[kk];
1236                 pen = new Pen(Color.FromKnownColor(KnownColor.ControlDark), 1.0f);
1237                 for (int rr = 0; rr < iItem.Values.Count; rr++)
1238                 {
1239                     RectangleF barRect = new RectangleF(0, 0, 0, 0);
1240                     double dbValue = iItem.Values[rr];
1241                     barRect.X = AxisZeroPt.X + XScaleWidth * rr + (tmBarWidth * ((kk + 1) * 2 - 1));
1242                     barRect.Y = AxisZeroPt.Y - (float)((dbValue - YScale_StartValue) / YScale_SplitValue) * YScaleWidth;
1243                     barRect.Width = tmBarWidth;
1244                     barRect.Height = AxisZeroPt.Y - barRect.Y;
1245 
1246                     // 繪製柱形
1247                     g.DrawRectangle(pen, barRect.X, barRect.Y, barRect.Width, barRect.Height);
1248 
1249                     brush = new SolidBrush(iItem.ItemColor);
1250                     g.FillRectangle(brush, barRect.X + 1, barRect.Y + 1, barRect.Width - 2, barRect.Height - 2);
1251 
1252                     // 繪製數據
1253                     SizeF tmValueSize = g.MeasureString(dbValue.ToString(), new Font("Arial", 9));
1254                     g.DrawString(dbValue.ToString(), new Font("Arial", 9), new SolidBrush(iItem.ItemColor), (barRect.X + tmBarWidth / 2 - tmValueSize.Width / 2), (barRect.Y - tmValueSize.Height - 2f));
1255                 }
1256             }
1257         }
1258 
1259         /// <summary>
1260         /// 繪製圖表--繪製餅狀圖
1261         /// </summary>
1262         private void DrawChart_Pie()
1263         {
1264             // 上下預留20 PX 爲了標記餅圖的數據值        
1265             Start_Y += 20;
1266             End_Y -= 20;
1267 
1268             g.SmoothingMode = SmoothingMode.HighQuality;
1269             g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
1270             g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
1271 
1272             // 矩形座標點
1273             PointF piePoint = new PointF(0, 0);
1274             float tmPieW = End_X - Start_X;
1275             float tmPieH = End_Y - Start_Y;
1276             float tmPieR = tmPieW < tmPieH ? tmPieW / 2 : tmPieH / 2;  // 半徑
1277 
1278             piePoint.X = Start_X + tmPieW / 2 - tmPieR;
1279             piePoint.Y = Start_Y + tmPieH / 2 - tmPieR;
1280 
1281             // 圓心座標點
1282             PointF pieZero = new PointF(piePoint.X + tmPieR, piePoint.Y + tmPieR);
1283 
1284             // 繪製外圍圓
1285             pen = new Pen(Color.FromKnownColor(KnownColor.ControlDark), 1.5f);
1286             g.DrawEllipse(pen, piePoint.X - 5, piePoint.Y - 5, (tmPieR + 5) * 2, (tmPieR + 5) * 2);
1287 
1288             // 計算總數
1289             double pieCountValue = 0;
1290             foreach (EChartData iItem in this.ChartDataArray)
1291             {
1292                 if (iItem.Values.Count >= 1)
1293                     pieCountValue += iItem.Values[0];
1294             }
1295 
1296             // 繪製扇形
1297             if (pieCountValue > 0)
1298             {
1299                 float curAngle = 0; // 佔比角度
1300                 float sumAngle = 0; // 總角度和
1301 
1302                 foreach (EChartData iItem in this.ChartDataArray)
1303                 {
1304                     if (iItem.Values.Count >= 1)
1305                         curAngle = (float)(iItem.Values[0] / pieCountValue * 360);
1306                     else
1307                         curAngle = 0;
1308 
1309                     // 填充筆刷
1310                     brush = new SolidBrush(iItem.ItemColor);
1311 
1312                     // 繪製弧形
1313                     g.FillPie(brush, piePoint.X, piePoint.Y, tmPieR * 2, tmPieR * 2, sumAngle, curAngle);
1314 
1315                     // 繪製弧線
1316                     g.DrawPie(pen, piePoint.X, piePoint.Y, tmPieR * 2, tmPieR * 2, sumAngle, curAngle);
1317 
1318                     // 繪製數據
1319                     float tmPre = (float)Math.Round((iItem.Values[0] / pieCountValue) * 100, 2);
1320                     string tmStr = tmPre.ToString() + "%" + " [" + iItem.Values[0].ToString() + "]";
1321 
1322                     // 內圓信息
1323                     double relCur_X = tmPieR * Math.Cos((360 - sumAngle - curAngle / 2) * Math.PI / 180);
1324                     double relCur_Y = tmPieR * Math.Sin((360 - sumAngle - curAngle / 2) * Math.PI / 180);
1325                     double cur_X = relCur_X + pieZero.X;
1326                     double cur_Y = pieZero.Y - relCur_Y;
1327                     PointF cur_Point = new PointF((float)cur_X, (float)cur_Y);  // 內圓上弧線中間點的座標
1328 
1329                     // 外圓信息
1330                     float largerR = tmPieR + 10;
1331                     double relLarg_X = largerR * Math.Cos((360 - sumAngle - curAngle / 2) * Math.PI / 180);
1332                     double relLarg_Y = largerR * Math.Sin((360 - sumAngle - curAngle / 2) * Math.PI / 180);
1333                     double largerX = relLarg_X + pieZero.X;
1334                     double largerY = pieZero.Y - relLarg_Y;
1335                     PointF larger_Point = new PointF((float)largerX, (float)largerY);
1336 
1337                     SizeF calcSize = new SizeF(0, 0);
1338 
1339                     // 繪製連接斜線(內圓到外圓弧度中間點的鏈接線)
1340                     g.DrawLine(new Pen(new SolidBrush(iItem.ItemColor), 1.5f), cur_Point, larger_Point);                                               // 斜線
1341 
1342                     // 繪製橫向線條
1343                     //*如下是對四個象限、以及對90度、180度、270度和360度的判斷*//
1344                     float tmCurIf = sumAngle + curAngle / 2;
1345                     if (tmCurIf <= 90)
1346                     {
1347                         g.DrawLine(new Pen(new SolidBrush(iItem.ItemColor), 1.5f), larger_Point.X, larger_Point.Y, larger_Point.X + 15f, larger_Point.Y);  // 橫線
1348                         g.DrawString(tmStr, new Font("Arial", 9), new SolidBrush(iItem.ItemColor), larger_Point.X + 15f, larger_Point.Y - 8f);             // 文字
1349                     }
1350                     else if (tmCurIf > 90 && tmCurIf <= 180)
1351                     {
1352                         calcSize = g.MeasureString(tmStr, new Font("Arial", 9));
1353                         g.DrawLine(new Pen(new SolidBrush(iItem.ItemColor), 1.5f), larger_Point.X, larger_Point.Y, larger_Point.X - 15f, larger_Point.Y);       // 橫線
1354                         g.DrawString(tmStr, new Font("Arial", 9), new SolidBrush(iItem.ItemColor), larger_Point.X - 15f - calcSize.Width, larger_Point.Y - 8f); // 文字
1355                     }
1356                     else if (tmCurIf > 180 && tmCurIf <= 270)
1357                     {
1358                         calcSize = g.MeasureString(tmStr, new Font("Arial", 9));
1359                         g.DrawLine(new Pen(new SolidBrush(iItem.ItemColor), 1.5f), larger_Point.X, larger_Point.Y, larger_Point.X - 15f, larger_Point.Y);       // 橫線
1360                         g.DrawString(tmStr, new Font("Arial", 9), new SolidBrush(iItem.ItemColor), larger_Point.X - 15f - calcSize.Width, larger_Point.Y - 8f); // 文字
1361                     }
1362                     else
1363                     {
1364                         g.DrawLine(new Pen(new SolidBrush(iItem.ItemColor), 1.5f), larger_Point.X, larger_Point.Y, larger_Point.X + 15f, larger_Point.Y);  // 橫線
1365                         g.DrawString(tmStr, new Font("Arial", 9), new SolidBrush(iItem.ItemColor), larger_Point.X + 15f, larger_Point.Y - 8f);             // 文字
1366                     }
1367 
1368                     ////*如下是對四個象限、以及對90度、180度、270度和360度的判斷*//
1369                     //if ((sumAngle + curAngle / 2) < 90)
1370                     //{
1371                     //    Half = sumAngle + curAngle / 2;
1372                     //    double tem_sin = Math.Sin(Pi / 180 * Half);
1373                     //    double tem_cos = Math.Cos(Pi / 180 * Half);
1374 
1375                     //    //Math.PI
1376 
1377                     //    float Px = (float)(tmPieR * tem_cos);
1378                     //    float Py = (float)(tmPieR * tem_sin);
1379 
1380                     //    g.DrawString(tmStr, new Font("Arial", 9), new SolidBrush(Color.Black), piePoint.X + tmPieR + Px, piePoint.Y + Py);
1381                     //    //g.DrawString(arraylist_type[i].ToString(), font1, brush1, new Point(225 + x, 225 + y));
1382                     //    //g.DrawString((Convert.ToInt32(arraylist_tp[i])).ToString() + "%", font1, brush1, new Point(225 + x, 225 + y + 12));
1383                     //}
1384 
1385                     //else if (tem_angle + Convert.ToSingle(arraylist_angle[i]) / 2 == 90)
1386                     //{
1387                     //    g.DrawString(arraylist_type[i].ToString(), font1, brush1, new Point(225, 225 + 125));
1388                     //    g.DrawString((Convert.ToInt32(arraylist_tp[i])).ToString() + "%", font1, brush1, new Point(225, 225 + 125 + 12));
1389                     //}
1390 
1391                     //else if (tem_angle + Convert.ToSingle(arraylist_angle[i]) / 2 > 90 && tem_angle + Convert.ToSingle(arraylist_angle[i]) / 2 < 180)
1392                     //{
1393                     //    halfangle = (180 - tem_angle - Convert.ToSingle(arraylist_angle[i]) / 2);
1394                     //    double tem_sin = Math.Sin(T / 180 * halfangle);
1395                     //    double tem_cos = Math.Cos(T / 180 * halfangle);
1396 
1397                     //    int y = Convert.ToInt32(125 * tem_sin);
1398                     //    int x = Convert.ToInt32(125 * tem_cos);
1399                     //    g.DrawString(arraylist_type[i].ToString(), font1, brush1, new Point(225 - x, 225 + y));
1400                     //    g.DrawString((Convert.ToInt32(arraylist_tp[i])).ToString() + "%", font1, brush1, new Point(225 - x, 225 + y + 12));
1401                     //}
1402 
1403                     //else if (tem_angle + Convert.ToSingle(arraylist_angle[i]) / 2 == 180)
1404                     //{
1405                     //    g.DrawString(arraylist_type[i].ToString(), font1, brush1, new Point(225 - 125, 225));
1406                     //    g.DrawString((Convert.ToInt32(arraylist_tp[i])).ToString() + "%", font1, brush1, new Point(225 - 125, 225 + 12));
1407                     //}
1408 
1409                     //else if (tem_angle + Convert.ToSingle(arraylist_angle[i]) / 2 > 180 && tem_angle + Convert.ToSingle(arraylist_angle[i]) / 2 < 270)
1410                     //{
1411                     //    halfangle = (tem_angle - 180 + Convert.ToSingle(arraylist_angle[i]) / 2);
1412                     //    double tem_sin = Math.Sin(T / 180 * halfangle);
1413                     //    double tem_cos = Math.Cos(T / 180 * halfangle);
1414 
1415                     //    int y = Convert.ToInt32(125 * tem_sin);
1416                     //    int x = Convert.ToInt32(125 * tem_cos);
1417                     //    g.DrawString(arraylist_type[i].ToString(), font1, brush1, new Point(225 - x, 225 - y));
1418                     //    g.DrawString((Convert.ToInt32(arraylist_tp[i])).ToString() + "%", font1, brush1, new Point(225 - x, 225 - y + 12));
1419                     //}
1420 
1421                     //else if (tem_angle + Convert.ToSingle(arraylist_angle[i]) / 2 == 270)
1422                     //{
1423                     //    g.DrawString(arraylist_type[i].ToString(), font1, brush1, new Point(225, 225 - 125));
1424                     //    g.DrawString((Convert.ToInt32(arraylist_tp[i])).ToString() + "%", font1, brush1, new Point(225, 225 - 125 + 12));
1425                     //}
1426 
1427                     //else if (tem_angle + Convert.ToSingle(arraylist_angle[i]) / 2 > 270 && tem_angle + Convert.ToSingle(arraylist_angle[i]) / 2 < 360)
1428                     //{
1429                     //    halfangle = (360 - tem_angle - Convert.ToSingle(arraylist_angle[i]) / 2);
1430                     //    double tem_sin = Math.Sin(T / 180 * halfangle);
1431                     //    double tem_cos = Math.Cos(T / 180 * halfangle);
1432 
1433                     //    int y = Convert.ToInt32(125 * tem_sin);
1434                     //    int x = Convert.ToInt32(125 * tem_cos);
1435                     //    g.DrawString(arraylist_type[i].ToString(), font1, brush1, new Point(225 + x, 225 - y));
1436                     //    g.DrawString((Convert.ToInt32(arraylist_tp[i])).ToString() + "%", font1, brush1, new Point(225 + x, 225 - y + 12));
1437                     //}
1438 
1439                     //else if (tem_angle + Convert.ToSingle(arraylist_angle[i]) / 2 == 360)
1440                     //{
1441                     //    g.DrawString(arraylist_type[i].ToString(), font1, brush1, new Point(225 + 125, 225));
1442                     //    g.DrawString((Convert.ToInt32(arraylist_tp[i])).ToString() + "%", font1, brush1, new Point(225 + 125, 225 + 12));
1443                     //}
1444 
1445 
1446                     // 累加角度
1447                     sumAngle += curAngle;
1448 
1449                 }
1450 
1451             }
1452         }
1453 
1454         #endregion
1455 
1456         #region 輔助方法
1457 
1458         /// <summary>
1459         /// 計算X軸刻度值最大高度
1460         /// </summary>
1461         /// <returns></returns>
1462         private void Calc_XScaleHeight()
1463         {
1464             SizeF tmMaxSizeF = new SizeF(0, 0);
1465             for (int t = 0; t < XScaleValues.Count; t++)
1466             {
1467                 SizeF tmSizeF = g.MeasureString(XScaleValues[t], new Font("宋體", 9));
1468                 if (tmSizeF.Width > tmMaxSizeF.Width)
1469                 {
1470                     tmMaxSizeF.Width = tmSizeF.Width;
1471                     tmMaxSizeF.Height = tmSizeF.Height;
1472                 }
1473             }
1474             myXScaleMaxHeight = (((float)Math.Sqrt(tmMaxSizeF.Height * tmMaxSizeF.Height + tmMaxSizeF.Width * tmMaxSizeF.Width) - tmMaxSizeF.Height) * XRotateAngle / 90 + tmMaxSizeF.Height + 13f);
1475         }
1476 
1477         /// <summary>
1478         /// 計算座標Y軸的刻度值
1479         /// 適用於:曲線圖、柱狀圖
1480         /// 不適用:餅狀圖無需計算
1481         /// </summary>
1482         private void Calc_YScaleValue()
1483         {
1484             myMaxValue = 0; // 原始最大值
1485             myMinValue = 0; // 原始最小值
1486 
1487             // 計算全部數據的最大值和最小值
1488             for (int mm = 0; mm < this.ChartDataArray.Count; mm++)
1489             {
1490                 for (int nn = 0; nn < this.ChartDataArray[mm].Values.Count; nn++)
1491                 {
1492                     double iData = this.ChartDataArray[mm].Values[nn];
1493                     if (mm == 0 && nn == 0)
1494                     {
1495                         myMaxValue = iData;
1496                         myMinValue = iData;
1497                     }
1498                     else
1499                     {
1500                         myMaxValue = iData > myMaxValue ? iData : myMaxValue;
1501                         myMinValue = iData > myMinValue ? myMinValue : iData;
1502                     }
1503                 }
1504             }
1505 
1506             // 計算Y軸刻度
1507             double tmMax_New = Math.Ceiling(myMaxValue);  // 目標最大值 向上取整
1508             double tmMin_New = Math.Floor(myMinValue);    // 目標最小值 向下取整
1509             if (myMinValue == 0)
1510             {
1511                 YScale_SplitValue = Math.Ceiling(tmMax_New / (double)YSplitNum);                       // 計算Y軸刻度間隔值
1512                 YScale_StartValue = 0;                                                                 // 計算Y軸刻度開始值
1513             }
1514             else
1515             {
1516                 // 計算間隔值
1517                 double tmJD1 = Math.Ceiling((tmMax_New - tmMin_New) / (double)(YSplitNum));
1518                 double tmJD2 = tmJD1 - Math.Ceiling((tmMax_New - tmMin_New) / (double)(YSplitNum + 1));
1519                 if (tmJD1 == 0) tmJD1 = 1;
1520                 YScale_StartValue = tmJD1 * Math.Floor(tmMin_New / tmJD1);  // 計算Y軸刻度開始值
1521                 bool tmJDFlag = true;
1522                 while (tmJDFlag)
1523                 {
1524                     if (YScale_StartValue <= tmMin_New && (YScale_StartValue + tmJD1 * YSplitNum) >= tmMax_New)
1525                     {
1526                         tmJDFlag = false;
1527                         YScale_SplitValue = tmJD1;                          // 計算Y軸刻度間隔值
1528                         break;
1529                     }
1530                     else
1531                     {
1532                         tmJD1 += tmJD2;
1533                     }
1534                 }
1535             }
1536 
1537             // 計算Y軸刻度字符串的最大寬度
1538             SizeF tmYSizeF = g.MeasureString((YScale_StartValue + YScale_SplitValue * YSplitNum).ToString(), new Font("宋體", 9));
1539             myYScaleMaxWidth = tmYSizeF.Width + 9f;// 預留4個像素
1540         }
1541 
1542         #endregion
1543 
1544         #region 枚舉方法
1545 
1546         /// <summary>
1547         /// 枚舉圖表類型
1548         /// </summary>
1549         public enum EChartType
1550         {
1551             /// <summary>
1552             /// 曲線圖
1553             /// </summary>
1554             Curve,
1555 
1556             /// <summary>
1557             /// 柱狀圖
1558             /// </summary>
1559             Bar,
1560 
1561             /// <summary>
1562             /// 餅狀圖
1563             /// </summary>
1564             Pie
1565 
1566         }
1567 
1568         /// <summary>
1569         /// 枚舉對齊方式
1570         /// </summary>
1571         public enum EAlign
1572         {
1573 
1574             /// <summary>
1575             /// 居左
1576             /// </summary>
1577             left,
1578 
1579             /// <summary>
1580             /// 居中
1581             /// </summary>
1582             center,
1583 
1584             /// <summary>
1585             /// 居右
1586             /// </summary>
1587             right
1588         }
1589 
1590         #endregion
1591 
1592     }
1593 
1594     /// <summary>
1595     /// 圖表數據單個項目
1596     /// </summary>
1597     public class EChartData
1598     {
1599         private string _name;
1600         private List<double> _values;
1601         private Color _itemColor;
1602         private SizeF _nameSize;
1603 
1604         public EChartData()
1605         {
1606             _name = "";
1607             _values = new List<double>();
1608             _itemColor = Color.White;
1609             _nameSize = new SizeF(0, 0);
1610         }
1611 
1612         /// <summary>
1613         /// 項目名稱
1614         /// </summary>
1615         public string Name
1616         {
1617             get { return _name; }
1618             set { _name = value; }
1619         }
1620 
1621         /// <summary>
1622         /// 項目值數組
1623         /// </summary>
1624         public List<double> Values
1625         {
1626             get { return _values; }
1627             set { _values = value; }
1628         }
1629 
1630         /// <summary>
1631         /// 文字大小
1632         /// 用戶繪製圖例時候使用
1633         /// </summary>
1634         public SizeF NameSize
1635         {
1636             get { return _nameSize; }
1637             set { _nameSize = value; }
1638         }
1639 
1640         /// <summary>
1641         /// 項目顏色
1642         /// </summary>
1643         public Color ItemColor
1644         {
1645             get { return _itemColor; }
1646             set { _itemColor = value; }
1647         }
1648 
1649     }
1650 }
View Code

   表報設計DLL控件的源碼實在太多,這裏就再也不一一貼出來了,下載完整的源碼本身調試運行查看。
   此報表設計器結合上次的WEB打印控件,就組成了完整的報表設計。

   報表設計器實例完整源碼下載地址:www.sdpsoft.com/==》下載中心==》報表設計器簡易源碼----自定義報表控件(源碼)以及在Winform中的使用源碼  

   或直接下載地址:winform報表設計工具源碼

   歡迎廣大朋友一塊兒交流。

相關文章
相關標籤/搜索