zoukankan      html  css  js  c++  java
  • 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报表设计工具源码

       欢迎广大朋友一起交流。

  • 相关阅读:
    第01组 Alpha冲刺 (1/6)
    第01组(17) 需求分析报告
    第01组(17) 团队展示
    结对编程作业
    05 RDD编程
    第九次作业
    HDFS
    Hadoop安装 与 HDFS体系结构
    第三次作业
    作业2
  • 原文地址:https://www.cnblogs.com/szzzzn/p/5566227.html
Copyright © 2011-2022 走看看