0%

csharp 在饼型图的外围显示说明文字

  • 来源:明日科技
  • 在饼型图的外围显示说明文字

    实例说明

    饼型图可以很直观的显示一些信息的比例,如果信息过多则需要在饼型图上绘制说明文字,这样,才可以更好的了解饼型图所代表的含义。本实例使用C#实现了在饼型图的外围绘制说明文字的功能,实例运行效果如图1所示。
    图1 在饼型图的外围显示说明文字

    关键技术

    本实例实现时主要使用Graphics 类的FillPie方法绘制饼型图,使用FillRectangle方法和DrawRectangle方法绘制说明文字的矩形框及矩形框的边,使用DrawString方法绘制说明文字。下面对本实例中用到的关键技术进行详细讲解。
    DrawRectangle方法用于绘制由坐标对、宽度和高度指定的矩形,其语法格式如下:
    public void DrawRectangle(Pen pen,int x,int y,int width,int height)
    DrawRectangle方法语法中的参数及说明如表1所示。 表1
    DrawRectangle方法语法中的参数及说明

    参数 说明
    pen Pen,它确定矩形的颜色、宽度和样式
    x 要绘制的矩形的左上角的x坐标
    y 要绘制的矩形的左上角的y坐标
    width 要绘制的矩形的宽度
    height 要绘制的矩形的高度

    设计过程

    (1)打开Visual Studio 2008开发环境,新建一个Windows窗体应用程序,命名为TextInCaky。
    (2)更改默认窗体Form1的Name属性为Frm_Main,在该窗体中添加一个Panel控件,用来显示带有说明文字的饼型图。
    (3)程序主要代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    public void ProtractArea(Graphics g)       //绘制饼型图表

    {

    AreaValue(); //计算最长说明文字的大小

    mypen = new Pen(Color.Black, 1); //设置画笔的颜色及大小

    float f = 0; //记录百分比

    float TimeNum = 0; //扇形的绘制度数

    float AXLeft = 0; //设置饼型图的X坐标

    float AYUp = 0; //设置饼型图的Y坐标

    float AXSize = 0; //设置饼型图的宽度

    float AYSize = 0; //设置饼型图的高度

    float Atop = 0; //记录饼型的高度为长和宽的最小值

    float Aleft = 0; //记录饼型的高度为长和宽的最小值

    TimeNum = AreaAngle; //设置饼型图的起始度数

    //计算饼型图的初始位置

    XLeft = panel1.Width - (panel1.Width - 5); //去了边框后饼型图的X位置

    XSize = panel1.Width - 10; //设置饼型图的宽度

    temXLeft = AXLeft; //记录饼型图的X坐标

    AXLeft = XLeft; //记录饼型图的X坐标

    AXSize = XSize; //记录饼型图的宽度

    //通过说明文字的大小计算饼型图的位置

    AXLeft = AXLeft + AreaXMaxWidth + Aline; //设置去除说明文字后的饼型图X坐标

    AYUp = AYUp + AreaXMaxHeight; //设置去除说明文字后的饼型图Y坐标

    AXSize = XSize - AreaXMaxWidth * 2 - Aline * 2; //设置去除说明文字后的饼型图宽度

    AYSize = YSize - AreaXMaxHeight * 2; //设置去除说明文字后的饼型图高度

    if (AXSize >= AYSize)//如果饼型图的宽度大于等于高度

    {

    Aleft = AXSize - AYSize; //记录饼型图的X坐标

    AXSize = AYSize; //将高度设为宽度

    }

    else

    {

    Atop = AYSize - AXSize; //记录饼型图的Y坐标

    AYSize = AXSize; //将宽度设为高度

    }

    if (Aleft != 0)//如果宽大于高

    {

    AXLeft = AXLeft + Aleft / 2; //设置饼型图横向局中

    }

    if (Atop != 0)//如果高大于宽

    {

    AYUp = AYUp + Atop / 2; //设置饼型图纵向局中

    }

    temXLeft = XLeft;

    //绘制饼型图

    if (AXSize > 0 && AYSize > 0) //如果饼型图的宽和高大于0

    {

    for (int i = 0; i < SzData.Length; i++) //遍历数据

    {

    f = SzData[i] / ASum; //获取当前数据的百分比

    //设置当前扇形图的填充颜色

    if (i >= WearColor.Length) //如果没有超出颜色数组

    mybrush = new SolidBrush(WearColor[i - WearColor.Length]);

    else

    mybrush = new SolidBrush(WearColor[i]);

    g.FillPie(mybrush, AXLeft, AYUp, AXSize, AYSize, TimeNum, f * 360); //绘制扇形图

    TimeNum += f * 360; //设置下一个扇形图的度数

    }

    ProAreaSign(g); //绘制饼型图的说明文字

    }

    else

    return;

    }

    #endregion

    #region 绘制饼型图标识(Area)

    public void ProAreaSign(Graphics g)

    {

    AreaValue(); //存储最长的名称

    mypen = new Pen(Color.Black, 1); //设置画笔的颜色及大小

    Font LSfont = new System.Drawing.Font("宋体", 8); //设置说明文字的字体样式

    SolidBrush Zbrush = new SolidBrush(Color.Black); //设置存放说明文字边框的画刷

    SolidBrush ATbrush = new SolidBrush(Color.Khaki); //设置存放说明文字方块的背景画刷

    float f = 0; //记录百分比

    float TimeNum = 0; //扇形的绘制度数

    float AXLeft = 0; //设置饼型图的X坐标

    float AYUp = 0; //设置饼型图的Y坐标

    float AXSize = 0; //设置饼型图的宽度

    float AYSize = 0; //设置饼型图的高度

    float Atop = 0; //记录饼型的高度为长和宽的最小值

    float Aleft = 0; //记录饼型的高度为长和宽的最小值

    Graphics TitG = panel1.CreateGraphics(); //创建Graphics对象

    SizeF XMaxSize = TitG.MeasureString("", LSfont); //将绘制的字符串进行格式化

    float SWidth = 0; //获取字符串的宽度

    float SHeight = 0; //获取字符串的高度

    //计算饼型图的初始位置

    XLeft = panel1.Width - (panel1.Width - 5); //去了边框后饼型图的X位置

    XSize = panel1.Width - 10; //设置饼型图的宽度

    temXLeft = AXLeft; //记录饼型图的X坐标

    AXLeft = XLeft; //记录饼型图的X坐标

    AXSize = XSize; //记录饼型图的宽度

    //通过说明文字的大小计算饼型图的位置

    AXLeft = AXLeft + AreaXMaxWidth + Aline; //设置去除说明文字后的饼型图X坐标

    AYUp = AYUp + AreaXMaxHeight; //设置去除说明文字后的饼型图Y坐标

    AXSize = XSize - AreaXMaxWidth * 2 - Aline * 2; //设置去除说明文字后的饼型图宽度

    AYSize = YSize - AreaXMaxHeight * 2; //设置去除说明文字后的饼型图高度

    if (AXSize >= AYSize)//如果饼型图的宽度大于等于高度

    {

    Aleft = AXSize - AYSize; //记录饼型图的X坐标

    AXSize = AYSize; //将高度设为宽度

    }

    else

    {

    Atop = AYSize - AXSize; //记录饼型图的Y坐标

    AYSize = AXSize; //将宽度设为高度

    }

    if (Aleft != 0)//如果宽大于高

    {

    AXLeft = AXLeft + Aleft / 2; //设置饼型图横向局中

    }

    if (Atop != 0)//如果高大于宽

    {

    AYUp = AYUp + Atop / 2; //设置饼型图纵向局中

    }

    temXLeft = XLeft;

    //初始化说明文字前横线的变量

    float X1 = 0;

    float Y1 = 0;

    float X2 = 0;

    float Y2 = 0;

    //初始化说明文字位置的变量

    float TX1 = 0;

    float TY1 = 0;

    float TX2 = 0;

    float TY2 = 0;

    float temf = 0; //记录百分比

    double radians = 0; //记录扇形的角度

    temf = (this.AreaAngle * (ASum / 360) / ASum); //记录起始位置的度数

    TimeNum = this.AreaAngle; //记录扇形的起始角度

    //绘制说明文字

    if (AXSize > 0 && AYSize > 0)

    {

    for (int i = 0; i < SzData.Length; i++) //遍历所有说明文字

    {

    f = SzData[i] / ASum; //获取当前记录的百分比

    if (f == 0) //如果当前值为0

    continue; //执行下一次循环

    radians = ((double)((temf + f / 2) * 360) * Math.PI) / (double)180;

    X1 = Convert.ToSingle(AXLeft + (AXSize / 2.0 + (int)((float)(AXSize / 2.0) * Math.Cos(radians))));

    Y1 = Convert.ToSingle(AYUp + (AYSize / 2.0 + (int)((float)(AYSize / 2.0) * Math.Sin(radians))));

    XMaxSize = TitG.MeasureString(AreaText[i].Trim(), LSfont); //将绘制的字符串进行格式化

    SWidth = XMaxSize.Width; //获取字符串的宽度

    SHeight = XMaxSize.Height; //获取字符串的高度

    if ((temf + f / 2) * 360 > 90 && (temf + f / 2) * 360 <= 270)

    {

    X2 = X1 - Aline;

    TX1 = X2 - 1 - SWidth;

    TY1 = Y1 - SHeight / 2 - Asash;

    TX2 = SWidth;

    TY2 = SHeight + Asash * 2;

    g.FillRectangle(ATbrush, TX1, TY1, TX2, TY2); //绘制内矩形

    g.DrawRectangle(new Pen(Color.Black, 1), TX1, TY1, TX2, TY2); //绘制矩形

    g.DrawString(AreaText[i].Trim(), LSfont, Zbrush, new PointF(X2 - SWidth + Asash - 1, Y1 - SHeight / 2));

    }

    else

    {

    X2 = X1 + Aline;

    TX1 = X2 + 1;

    TY1 = Y1 - SHeight / 2 - Asash;

    TX2 = SWidth;

    TY2 = SHeight + Asash * 2;

    g.FillRectangle(ATbrush, TX1, TY1, TX2, TY2); //绘制内矩形

    g.DrawRectangle(new Pen(Color.Black, 1), TX1, TY1, TX2, TY2); //绘制矩形

    g.DrawString(AreaText[i].Trim(), LSfont, Zbrush, new PointF(X2 + Asash + 1, Y1 - SHeight / 2));

    }

    Y2 = Y1;

    g.DrawLine(new Pen(new SolidBrush(Color.Black), 1), X1, Y1, X2, Y2);

    TimeNum += f * 360;

    temf = temf + f;

    }

    }

    else

    return;

    }

    #endregion

    秘笈心法

    心法领悟015:使用DrawString方法实现水印文字。
    对于一些有可能侵权的图片,或者要作为宣传的图片,可以通过使用DrawString方法将用到的文字绘制到图片上,从而得到所谓的“水印文字”。

    觉得文章有用?请我喝杯咖啡~