C# 报表设计器 (winform 设计端)开发与实现生成网页的HTML报表

    记得2010年之前,公司的项目基本上都要用到报表,以前我们常用的方法就是针对客户的需求来定制化开发(基本上是死写代码)来实现,经常导致项目经常性的延期,因为客户的需求经常会变化,随着用户的使用认知度的提高,对报表的要求越来越高,导致程序员不停的修改代码来实现,效率不高、结束遥遥无期。。。非常的痛苦;当然市面上有很多报表开发工具可以实现,但是针对小公司来说采购一套这样的系统的成本也非常的高,所以我们决定自己来开发一套像目前的润乾、FineReport 这样的报表设计器,来实现快速的报表设计制作。

   当初为了开发这样的系统,花费的了很长的时间学习查阅各种资料,其痛苦只有程序员才能体会,因为没有任何现成的实例代码可供参考,只有看别人的思路来一步步的摸索,本文将我们当初设计制作的报表设计器的功能分享出来,让有需要的或想开发报表设计的朋友们提供一个参考,尽量少走很动弯路,设计端可以直接使用,但是计算引擎和网页的计算的源码就不能分享出来了(请不要介意,因为涉及到公司的保密原因)

   记得当初为了制作报表设计器,在网上查找有没有相关的实例资料,找了很久,也是没有找到合适的,后来发现 SourceGrid 可以实现单元格的合并拆分功能,所以决定修改实现winform端的报表设计。下面我将制作的E_Report 报表控件抽取出来建立一个简易的Winform的可运行的实例提供给大伙下载,希望能给你的开发提供一点帮助和借鉴;当然你可以直接使用也可以,里面的设计功能基本全部能。

   抽取出来的源码包含:E_Report 报表设计自定义控件DLL源码;  EReportDemo 建立的简易Winform 端设计器使用DLL的实例源码;

  一、运行效果

    实例中,只做了一个简单的效果,工具栏的按钮在单元格右击属性中都有,只是放了几个常用的在工具导航栏中(右击单元格属性可以看到设计导航)

    可以进行单元格的合并、拆分、字体、颜色、背景、边框等的设置,朋友们可以自己编写保存发布等功能,实现报表的真实功能;

  

      例如单元格属性(其他还有很多的属性,自己下载源码后运行起来就能看到了)

    

       对表格的斜线、斜线文字有很好的支持;可以设置表头、表位、标题等 实际效果图如下

    

 

二、使用介绍

1、页面初始化的时候,通过 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

2、工具导航栏 设置单元格相关属性

  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

3、报表控件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             // 1、图表区下移10PX
1111             Start_Y += 10;
1112 
1113             // 2、计算坐标轴参数
1114             Calc_XScaleHeight();
1115             Calc_YScaleValue();
1116 
1117             // 3、计算原点坐标值
1118             AxisZeroPt = new PointF(0f, 0f); // 坐标轴原点坐标
1119             AxisZeroPt.X = Start_X + myYScaleMaxWidth;
1120             AxisZeroPt.Y = End_Y - myXScaleMaxHeight;
1121 
1122             // 3.1、绘制坐标轴
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.2、计算分段宽
1128             XScaleWidth = (End_X - Start_X - myYScaleMaxWidth) / XSplitNum;      // 计算X轴分段宽
1129             YScaleWidth = (End_Y - Start_Y - myXScaleMaxHeight) / YSplitNum;     // 计算Y轴分段宽
1130 
1131             // 3.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.4、绘制网格线
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报表设计工具源码

   欢迎广大朋友一起交流。

 

posted @ 2016-06-07 13:34  SDP软件快速开发平台  阅读(11521)  评论(18编辑  收藏  举报