2024年4月25日发(作者:)

C#

.NET Win

Form

绘制

饼图,直方图,曲线图

详细代码 自定义图形类(饼图,直方图,曲线图)

using System;

using ;

using ;

using pServices;

using ;

using ;

using ent;

using ing;

using ;

using ption;

using m;

using ;

using er;

using c;

using entModel;

using g;

using graphy;

using g;

using tions;

public class Func

{

private static AChart chart = new AChart();

private static Object[] ChartColor ={ , , ,

,, , , ate, ,

, er, , a, in, ,

, , , , , ,

, , , , ise, arent};

///

/// 填充饼图、直方图、曲线图到容器里

///

/// 标题

/// 容器(Panel,Form,TabPage)

/// 对Table[0]进行操作,饼图取最前两列,第一

列为名字,第二列为值。单数据直方图取最前两列,第一列为横轴每列名称,第

二列为值。多数据直方图第一列为横轴父项名称,然后依次取前一列为横轴每列

名称,后一列为值。曲线图取第一列为横轴每列名称,往后每列都代表一条曲线,

列名为曲线名称。

/// 图表类型

/// 刻度最小值,此参数对饼图无效

/// 刻度最大值,此参数对饼图无效

/// 刻度值,此参数对饼图无效

/// 值的单位,此参数对饼图无效

public static void DrawingChart(string chartTitle, Control control, DataSet

dataSet, ChartType chartType, int minNumber, int maxNumber, int scale,string unit)

{

DrawingChartInclude(chartTitle, control, dataSet, chartType,

minNumber, maxNumber, scale,unit);

}

///

/// 填充饼图到容器里

///

/// 标题

/// 容器(Panel,Form,TabPage)

/// 对Table[0]进行操作,取最前两列,第一列为

名字,第二列为值

public static void DrawingChart(string chartTitle,Control control, DataSet

dataSet)

{

DrawingChartInclude(chartTitle, control, dataSet, ph,

0, 0, 0,"");

}

private static void DrawingChartInclude(string chartTitle, Control control,

DataSet dataSet, ChartType chartType, int minNumber, int maxNumber, int

scale,string unit)

{

if ( < 230 || < 230)

{

("容器宽度或长度设置过小!(宽度和长度必须>=230)

");

return;

}

if (e().("Form") ||

e().("TabPage") ||

e().("GroupBox") ||

e().("Panel"))

{

for (int i = 0; i < ; i++)

{

if (control == (Control)chart[i].crtObj)

{

Chart(i);

break;

}

}

rt(chartTitle, control, chartType, dataSet,

minNumber, maxNumber, scale,unit);

+= new PaintEventHandler(control_Paint);

ed += new EventHandler(control_Disposed);

h();

}

else

{

("该容器不是Form,TabPage,GroupBox,Panel类型!");

return;

}

}

static void control_Paint(object sender, PaintEventArgs e)

{

try

{

for (int i = 0; i < ; i++)

{

if (chart[i].crtType == )

{

break;

}

else if (chart[i].crtObj != sender)

{

continue;

}

int x = 0;

int y = 0;

int diameter = (((Control)chart[i].crtObj).Height,

((Control)chart[i].crtObj).Width) - 100;

if (((Control)chart[i].crtObj).Width >=

((Control)chart[i].crtObj).Height)

{

x = (((Control)chart[i].crtObj).Width -

((Control)chart[i].crtObj).Height) / 2 + 50;

y = 50;

}

else

{

x = 50;

y = (((Control)chart[i].crtObj).Height -

((Control)chart[i].crtObj).Width) / 2 + 50;

}

Pen line = new Pen(, 2);

SolidBrush linesb = new SolidBrush(een);

Rectangle rect = new Rectangle(x, y, diameter, diameter);

Pen title = new Pen(, 2);

SolidBrush B = new SolidBrush();

StringFormat Ll = new StringFormat();

ent = ;

int height = ((Control)chart[i].crtObj).Height - 20;

RectangleF RectTitle = new RectangleF(5, 5, diameter,

diameter);

ring(chart[i].crtTitle, new Font("Arial", 14),

B, RectTitle, Ll);

#region 饼图

if (chart[i].crtType == ph)

{

float total = 0;

float fontWidth = 0;

for (int j = 0; j < chart[i].[0].;

j++)

{

total +=

(float)le(chart[i].[0].Rows[j][1].ToString());

if (fontWidth <

eString(chart[i].[0].Rows[j][0].ToString(), new

Font("Arial", 10)).Width)

{

fontWidth =

eString(chart[i].[0].Rows[j][0].ToString(), new

Font("Arial", 10)).Width;

}

}

float next = 0;

for (int j = 0; j < chart[i].[0].;

j++)

{

SolidBrush sb = new

SolidBrush((Color)ChartColor[j % ]);

float tmp =

(float)(le(chart[i].[0].Rows[j][1].ToString()) / total *

100 * 3.6);

e(sb, rect, next, tmp);

RectTitle = new RectangleF(5, height, diameter,

diameter);

B = new SolidBrush();

ring(chart[i].[0].Rows[j][0].ToString(), new

Font("Arial", 10), B, RectTitle, Ll);

RectTitle = new RectangleF(5 + (int)fontWidth + 2,

height, 10, 12);

ctangle(sb, RectTitle);

RectTitle = new RectangleF(x + diameter + 2, height,

10, 12);

ctangle(sb, RectTitle);

RectTitle = new RectangleF(x + diameter + 14,

height, diameter, diameter);

ring(ng(((le(chart[i].crtDa

[0].Rows[j][1].ToString()) / total * 100), 0)) + "%", new Font("Arial", 10), B,

RectTitle, Ll);

height -= 20;

next += tmp;

}

}

#endregion

#region 直方图

else if (chart[i].crtType == ram)

{

ne(line, x, y, x, y + diameter);

height = y + diameter - 12;

int scaleBS = diameter / ((chart[i].crtMaxNumber -

chart[i].crtMinNumber) / chart[i].crtScale);

float fontWidth =

eString(chart[i].ng(), new Font("Arial",

10)).Width;

for (int j = chart[i].crtMinNumber; j <=

chart[i].crtMaxNumber; j += chart[i].crtScale)

{

RectangleF RectScaleHeightLine = new RectangleF(x

- fontWidth - 1, height, diameter, diameter);

ring(ng(), new Font("Arial",

10), linesb, RectScaleHeightLine, Ll);

height -= scaleBS;

}

height = y + diameter;

int width = x + 10;

for (int j = 0; j < chart[i].[0].;

j++)

{

if (chart[i].[0]. <=

2)

{

SolidBrush sb = new

SolidBrush((Color)ChartColor[j % ]);

RectangleF RectScale = new RectangleF(width,

height, diameter, diameter);

ring(chart[i].[0].Rows[j][0].ToString(), new

Font("Arial", 10), sb, RectScale, Ll);

double aa =

le(chart[i].[0].Rows[j][1].ToString()) / chart[i].crtScale

* scaleBS;

RectScale = new RectangleF(width, y +

diameter - (int)aa, 20, (int)aa);

ctangle(sb, RectScale);

RectScale = new RectangleF(width, y +

diameter - (int)aa - 15, diameter, diameter);

ring(chart[i].[0].Rows[j][1].ToString() +

chart[i].crtUnit, new Font("Arial", 10), sb, RectScale);

}

else

{

int sbnum = 0;

RectangleF RectScale = new RectangleF(width,

height + 24, diameter, diameter);

ring(chart[i].[0].Rows[j][0].ToString(), new

Font("Arial", 10), B, RectScale, Ll);

for (int k = 1; k <

chart[i].[0].; k += 2)

{

SolidBrush sb = new

SolidBrush((Color)ChartColor[sbnum % ]);

sbnum++;

RectScale = new RectangleF(width, height

+ (sbnum % 2) * 12, diameter, diameter);

ring(chart[i].[0].Rows[j][k].ToString(), new

Font("Arial", 8), sb, RectScale, Ll);

double aa =

le(chart[i].[0].Rows[j][k + 1].ToString()) /

chart[i].crtScale * scaleBS;

RectScale = new RectangleF(width, y +

diameter - (int)aa, 20, (int)aa);

ctangle(sb, RectScale);

RectScale = new RectangleF(width, y +

diameter - (int)aa - 15, diameter, diameter);

ring(chart[i].[0].Rows[j][k + 1].ToString() +

chart[i].crtUnit, new Font("Arial", 8), sb, RectScale);

width += 30;

}

}

if ((fontWidth +

eString(chart[i].crtUnit, new Font("Arial", 10)).Width) >= 30)

{

width += (int)fontWidth +

(int)eString(chart[i].crtUnit, new Font("Arial", 10)).Width + 10;

}

else

{

width += 30;

}

}

ne(line, x, y + diameter, width, y +

diameter);

}

#endregion

#region 曲线图

else if (chart[i].crtType == am)

{

int width = x;

int scaleBS = diameter / ((chart[i].crtMaxNumber -

chart[i].crtMinNumber) / chart[i].crtScale);

int scaleWidthBS = diameter /

chart[i].[0].;

height = y + diameter - ((chart[i].crtMaxNumber -

chart[i].crtMinNumber) / chart[i].crtScale) * scaleBS;

float fontWidth =

eString(chart[i].ng(), new Font("Arial",

10)).Width;

for (int j = 0; j <=

chart[i].[0].; j++)

{

ne(line, width, height, width, y +

diameter);

width += scaleWidthBS;

}

height = y + diameter - 12;

for (int j = chart[i].crtMinNumber; j <=

chart[i].crtMaxNumber; j += chart[i].crtScale)

{

ne(line, x, height + 12, x +

scaleWidthBS * chart[i].[0]., height + 12);

RectangleF RectScaleHeightLine = new RectangleF(x

- fontWidth - 1, height, diameter, diameter);

ring(ng(), new Font("Arial",

10), linesb, RectScaleHeightLine, Ll);

height -= scaleBS;

}

width = x;

height = y + diameter;

double nowheight = 0;

for (int j = 0; j < chart[i].[0].;

j++)

{

height = y + diameter;

SolidBrush textsb = new SolidBrush();

RectangleF rectText = new RectangleF(width +

scaleWidthBS, height + 2 + (j % 2) * 12, diameter, diameter);

ring(chart[i].[0].Rows[j][0].ToString(), new

Font("Arial", 10), textsb, rectText);

//

for (int k = 1; k <

chart[i].[0].; k++)

{

Pen polygramLine = new

Pen((Color)ChartColor[(k - 1) % ]);

SolidBrush valueSB = new

SolidBrush((Color)ChartColor[(k - 1) % ]);

double aa = y + diameter;

if (j > 0)

{

aa = y + diameter -

le(chart[i].[0].Rows[j - 1][k].ToString()) /

chart[i].crtScale * scaleBS;

}

nowheight = y + diameter -

le(chart[i].[0].Rows[j][k].ToString()) / chart[i].crtScale

* scaleBS;

ne(polygramLine, width,

(int)aa, width + scaleWidthBS, (int)nowheight);

RectangleF RectScale = new RectangleF(width

+ scaleWidthBS, (int)nowheight - 12, diameter, diameter);

ring(chart[i].[0].Rows[j][k].ToString() +

chart[i].crtUnit, new Font("Arial", 10), valueSB, RectScale);

}

width += scaleWidthBS;

}

fontWidth = 0;

for (int j = 1; j <

chart[i].[0].; j++)

{

if (fontWidth <

eString(chart[i].[0].Columns[j].

ng(), new Font("Arial", 10)).Width)

{

fontWidth =

eString(chart[i].[0].Columns[j].

ng(), new Font("Arial", 10)).Width;

}

}

height = y + diameter;

for (int j = 1; j <

chart[i].[0].; j++)

{

RectTitle = new RectangleF(5, height, diameter,

diameter);

B = new SolidBrush();

SolidBrush valueSB = new

SolidBrush((Color)ChartColor[(j - 1) % ]);

ring(chart[i].[0].Columns[j].ng(

), new Font("Arial", 10), B, RectTitle, Ll);

RectTitle = new RectangleF(5 + (int)fontWidth + 2,

height, 15, 12);

ctangle(valueSB, RectTitle);

height -= 20;

}

}

#endregion

break;

}

}

catch

{

return;

}

}

static void control_Disposed(object sender, EventArgs e)

{

for (int i=0;i<;i++)

{

if ((Control)sender == (Control)chart[i].crtObj)

{

Chart(i);

break;

}

}

}

}

public class pChart

{

public Object crtObj;

public ChartType crtType;

public DataSet crtDataSet;

public string crtTitle = "";

public int crtMinNumber = 0;

public int crtMaxNumber = 0;

public int crtScale = 0;

public string crtUnit = "";

public pChart(string chartTitle,Object chartObject, ChartType chartType,

DataSet chartDataSet, int minNumber, int maxNumber, int scale,string unit)

{

crtObj = chartObject;

crtType = chartType;

crtDataSet = chartDataSet;

crtTitle = chartTitle;

crtMinNumber = minNumber;

crtMaxNumber = maxNumber;

crtScale = scale;

crtUnit = unit;

}

}

public class AChart : tionBase

{

public AChart()

{ }

public void AddChart(string chartTitle, Object chartObject, ChartType

chartType, DataSet chartDataSet, int minNumber, int maxNumber, int scale,string unit)

{

(new

pChart(chartTitle,chartObject,chartType,chartDataSet,minNumber,maxNumber,scale,

unit));

}

public void RemoveChart(int index)

{

if (index > Count - 1 || index < 0)

{

("Index not valid!");

}

else

{

At(index);

}

}

public AChart Item

{

get

{

return this;

}

}

[rName("item")]

public pChart this[int index]

{

get

{

return (pChart)List[index];

}

}

}

///

/// 图表类型

///

public enum ChartType

{

///

/// 直方图

///

Histogram,

///

/// 饼图

///

Piegraph,

///

/// 曲线图

///

Polygram,

///

/// None

///

None

}

测试用例:

private void button1_Click(object sender, EventArgs e)

{

DataSet ds = new DataSet();

ds = ("select '甲' as name,50 as value union all select '乙

',60 union all select '丙',70 union all select '丁',80");

gChart("饼图测试", 1, ds);

}

private void button2_Click(object sender, EventArgs e)

{

DataSet ds = new DataSet();

ds = ("select '甲' as name,50 as value union all select '乙

',60 union all select '丙',70 union all select '丁',80");

gChart("直方图一测试", 1,

ds,ram,0,100,10,"万");

}

private void button3_Click(object sender, EventArgs e)

{

DataSet ds = new DataSet();

ds = ("select '一月' as 月份,'甲' as name,50 as value,'乙'

as name2,60 as value2 union all select '二月' as 月份,'甲',70,'乙',80");

gChart("直方图一测试", 1, ds,

ram, 0, 100, 10, "万");

}

private void button4_Click(object sender, EventArgs e)

{

DataSet ds = new DataSet();

ds = ("select '一月' as 月份,50 as 甲,60 as 乙 union all

select '二月', 60,40 union all select '三月',70,50 union all select '四月',30,60 union all

select '五月',40,80 union all select '六月',70,90");

gChart("曲线图测试", 1, ds, am,

0, 100, 10, "瓦");

}

注:测试用例内的ds数据请自行写数据库连接,用填充。