最近在做一个统计投票数量的图形报表,主要借鉴了一个51aspx中的一个例子,因为要在一页中显示多个图形,所以选择了在pannel中动态添加Image控件.效果图如下:
/// <summary>
/// 饼形图形报表
/// </summary>
/// <param name="target">Stream对象的实例</param>
/// <param name="p_dt">数据源</param>
/// <param name="p_strTitle">大标题</param>
/// <param name="p_strText">小标题字段</param>
/// <param name="p_strCount">统计数量字段</param>
public void DrawPic(Stream target,DataTable p_dt,string p_strTitle,string p_strText,string p_strCount)
{
//DataTable m_dt = QVoteService.Instance().GetVoteCount(p_strFID);
float[] angle = new float[p_dt.Rows.Count];
string[] sTxt = new string[p_dt.Rows.Count];
float AllCount = 0;
for (int i = 0; i < p_dt.Rows.Count; i++)
{
DataRow m_dr = p_dt.Rows[i];
AllCount += Convert.ToSingle(m_dr[p_strCount].ToString());
}
//计算选项在总体中所占的比例
for (int i = 0; i < p_dt.Rows.Count; i++)
{
DataRow m_dr = p_dt.Rows[i];
if (AllCount != 0)
{
angle[i] = Convert.ToSingle(m_dr[p_strCount].ToString()) * 360.0f / AllCount;
sTxt[i] = m_dr[p_strText].ToString() + " " + (Math.Round(Convert.ToSingle(m_dr[p_strCount].ToString()) / AllCount, 2)) * 100 + "%";
}
else
{
angle[i] = Convert.ToSingle(1 * 360.0f / p_dt.Rows.Count);
sTxt[i] = m_dr[p_strText].ToString() + " " + (Convert.ToSingle(1 / p_dt.Rows.Count)) * 100 + "%";
}
}
float x = 75.0f, y = 65.0f, d = 100.0f, offset = 15.0f, x1 = 0.0f, y1 = 0.0f;//圆形x,y坐标,半径,偏移距离,x,y方向的偏移值
float curangle = 0.0f;//当前已转的角度
int ox = 100, oy =100;//圆心坐标
int px1 = 0, py1 = 0, px2 = 0, py2 = 0;//直线的端点
System.Drawing.Image bitmap = new Bitmap(385, 200, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);//建立了一个BitMap对象,它为要创建的图形提供了内存空间
Graphics g = Graphics.FromImage(bitmap);//产生一个Graphics对象,它封装了GDI+画图接口
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//20项颜色。
Color[] color = new Color[]{Color.PapayaWhip,Color.Red,Color.Salmon,Color.Thistle,Color.Blue,Color.Coral,Color.DarkGoldenrod,Color.Black,Color.Firebrick,Color.Gold,Color.Honeydew,Color.Indigo,Color.Khaki,Color.LemonChiffon,Color.Maroon,Color.Navy,
Color.Orange,Color.Violet,Color.Wheat,Color.YellowGreen};
g.Clear(Color.FromArgb(227, 240,255));//清屏
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
g.DrawString(p_strTitle, new Font(FontFamily.GenericSansSerif,8), new SolidBrush(Color.Black), new RectangleF(0.0f, 10.0f, 420.0f, 20.0f), sf);//标题
//画右侧的大矩形
g.FillRectangle(new SolidBrush(Color.FromArgb(128, 128, 128)), 457, 105, 150, (angle.Length + 1) * 12);//阴影
g.FillRectangle(new SolidBrush(Color.FromArgb(253, 245, 230)), 455, 105, 150, (angle.Length + 1) * 12);//前景
g.DrawRectangle(new Pen(Color.FromArgb(128, 128, 128), 1), 455, 105, 150, (angle.Length + 1) * 12);//轮廓
/**/
/////////////////////////////////////////////
for (int i = 0; i < angle.Length; i++)
{
sf.Alignment = StringAlignment.Near;
ox = Convert.ToInt32(x + d / 2);
oy = Convert.ToInt32(y + d / 2);
px1 = Convert.ToInt32((d / 2 + 20) * Math.Cos((curangle + angle[i] / 2) * Math.PI / 180.0f)) + ox;
py2 = py1 = Convert.ToInt32((d / 2 + 20) * Math.Sin((curangle + angle[i] / 2) * Math.PI / 180.0f)) + oy;
if ((curangle + angle[i] / 2) >= 270 || (curangle + angle[i] / 2) < 90) px2 = px1 + 10;
else px2 = px1 - 10;
//g.DrawLine(new Pen(Color.FromArgb(120, 120, 120), 1), new Point(ox, oy), new Point(px1, py1));//画直线-标释用。
//g.DrawLine(new Pen(Color.FromArgb(120, 120, 120), 1), new Point(px1, py1), new Point(px2, py2));//直线
//if ((curangle + angle[i] / 2) >= 270 || (curangle + angle[i] / 2) < 90)
//{
// g.DrawString(sTxt[i], new Font(FontFamily.GenericSansSerif, 8), new SolidBrush(Color.FromArgb(120, 120, 120)), px2, py2 - 4, sf);
//}
//else
//{
// g.DrawString(sTxt[i], new Font(FontFamily.GenericSansSerif, 8), new SolidBrush(Color.FromArgb(120, 120, 120)), px2 - sTxt[i].Length * 12 - 2, py2 - 4, sf);
//}
g.FillPie(new SolidBrush(Color.FromArgb(128, 128, 128)), x + 2, y + 2, d, d, curangle, angle[i]);
g.FillPie(new SolidBrush(color[i]), x, y, d, d, curangle, angle[i]);
g.DrawPie(new Pen(Color.FromArgb(128, 128, 128),0), x, y, d, d, curangle, angle[i]);
curangle += angle[i];
//画右侧的小矩形,与文字
g.FillRectangle(new SolidBrush(Color.FromArgb(128, 128, 128)), 427, i * 14 + 6 + 58 + 2, 20, 10);//阴影
g.FillRectangle(new SolidBrush(color[i]), 207, i * 14 + 6 + 60, 20, 10);//前景
g.DrawRectangle(new Pen(Color.FromArgb(120, 120, 120), 1),207, i * 14 + 6 + 60, 20, 10);//轮廓
g.DrawString(sTxt[i], new Font(FontFamily.GenericSansSerif,8), new SolidBrush(Color.FromArgb(80, 80, 80)), 227, i * 14 + 6 +60, sf);
}
bitmap.Save(target, ImageFormat.Gif);
bitmap.Dispose();
g.Dispose();
}
///pannel中动态添加
DataTable m_dt = 数据源
for (int i = 0; i < m_dt.Rows.Count;i++ )
{
Image m_img = new Image();
m_img.Style.Add("margin-top", "5px");
m_img.Style.Add("float","left");
m_img.Style.Add("margin-left","5px");
m_img.ImageUrl = "GraphicStatements.aspx?FID=" + m_dt.Rows[i]["FID"].ToString()+"&&FTitle="+Server.UrlEncode(m_dt.Rows[i]["FTitle"].ToString());
Panel1.Controls.Add(m_img);
}