首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

.net应用gdi+绘半饼图

2012-09-01 
.net使用gdi+绘半饼图前两天web项目中遇到要绘一个半饼图,图表控件中没有这样的图,就用gdi+简单的绘了一个

.net使用gdi+绘半饼图

前两天web项目中遇到要绘一个半饼图,图表控件中没有这样的图,就用gdi+简单的绘了一个。

实现思路:

基于xml进行半饼图的数据提供,格式如下:

<imagedraw><imagedata data="100" color="#1B3C72" /><imagedata data="200" color="#1B3Cad" /><imagedata data="200" color="#ffccdd" /></imagedraw>

半饼图中每个区域可以分别指定颜色。每个区域的大小由提供数据的data属性值决定。每个区域的角度大小为:

iCurrAngle = Convert.ToInt32(当前区域数据 / 所有区域数据和 * 180);,因为是半饼图所以*180度。对于每个区域上绘制文字坐标,使用放大半径求圆弧所在点的位置的方式。

具体实现如下:

BaseDraw:绘图基类

PartPieDraw:绘半饼图实现类,主要是 RenerImage方法

?

using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Drawing2D;

/// <summary>
/// BaseDraw 的摘要说明
/// </summary>
public? class BaseDraw
{
??? private int imageWidth = 0;
??? private int imageHeight = 0;
??? private string xmlData = "";

??? public BaseDraw()
??? {
??? ??? //
??? ??? // TODO: 在此处添加构造函数逻辑
??? ??? //
??? }

??? public int ImageWidth
??? {
??????? get { return this.imageWidth; }
??????? set { this.imageWidth = value; }
??? }

??? public int ImageHeight
??? {
??????? get { return this.imageHeight; }
??????? set { this.imageHeight = value; }
??? }

??? public string XmlData
??? {
??????? get { return this.xmlData; }
??????? set { this.xmlData = value; }
??? }

??? public byte[] Draw()
??? {
??????? System.Drawing.Bitmap image = new System.Drawing.Bitmap(this.imageWidth,this.imageHeight);
??????? Graphics g = Graphics.FromImage(image);
??????? this.RenerImage(g);
??????? System.IO.MemoryStream ms = new System.IO.MemoryStream();
??????? image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
??????? byte[] buffer = ms.ToArray();
??????? g.Dispose();
??????? image.Dispose();
??????? return buffer;
??? }

??? public virtual ArrayList ParseXmlData()
??? {
??????? return null;
??? }

??? public virtual void RenerImage(Graphics g)
??? {

??? }
}

?

using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml;

/// <summary>
/// PartPieDraw 的摘要说明
/// </summary>
public class PartPieDraw:BaseDraw
{
??? public PartPieDraw()
??? {
??? ??? //
??? ??? // TODO: 在此处添加构造函数逻辑
??? ??? //
??? }

??? public override void RenerImage(System.Drawing.Graphics g)
??? {
??????? ArrayList dataList = this.ParseXmlData();
??????? //开始计算总的数值
??????? double sumValue = 0.00;
??????? foreach (ImageData data in dataList)
??????? {
??????????? sumValue += Convert.ToDouble(Math.Round(data.DrawData, 2));
??????? }
??????? sumValue = Convert.ToDouble(Math.Round(sumValue, 2));
??????? int iSumAngle = 180;??? //总要绘的角度
??????? int iCurrAngle = 0;?? //当前角度
??????? int iPosAngle = 180;?? //当前角度的基值
??????? int iCurrSumAngle = 0;
??????? double dCurrBfb = 0;
??????? //定义半图所在的矩形区域大小,画缓的位置占整个图的2/3
??????? int iAreaX = Convert.ToInt32((this.ImageWidth - Convert.ToInt32(this.ImageWidth * 2 / 3)) / 2);
??????? int iAreaY = iAreaX;
??????? int iAreaWidth = Convert.ToInt32(this.ImageWidth * 2 / 3);??? //长边
??????? int iAreaHeight = iAreaWidth;
??????? double r = iAreaWidth / 2;??? //半径
??????? double rx = Convert.ToDouble(iAreaX) + r;??? //圆心x
??????? double ry = Convert.ToDouble(iAreaY) + r;??? //圆心y
??????? //重设置半径
??????? r += 20;
??????? g.Clear(Color.White); //清除背景
??????? g.SmoothingMode = SmoothingMode.AntiAlias;? //消除绘的时候的锯齿
??????? g.DrawRectangle(new System.Drawing.Pen(Color.Black, 1), 0, 0, this.ImageWidth, this.ImageHeight);
??????? for (int i = 0; i < dataList.Count; i++)
??????? {
??????????? ImageData imageData = (ImageData)dataList[i];
??????????? dCurrBfb += imageData.DrawData / sumValue * 100;
??????????? dCurrBfb = Convert.ToDouble(Math.Round(dCurrBfb, 2));? //格式化两位小数
??????????? if (i < dataList.Count - 1)
??????????? {
??????????????? iCurrAngle = Convert.ToInt32(imageData.DrawData / sumValue * iSumAngle);
??????????? }
??????????? else
??????????? {
??????????????? iCurrAngle = 360 - iPosAngle;
??????????? }
??????????? g.SmoothingMode = SmoothingMode.AntiAlias;? //消除绘的时候的锯齿
??????????? g.FillPie(new SolidBrush(imageData.DrawColor), iAreaX, iAreaY, iAreaWidth, iAreaHeight, iPosAngle, iCurrAngle);
??????????? g.DrawPie(new Pen(new SolidBrush(imageData.DrawColor)), iAreaX, iAreaY, iAreaWidth, iAreaHeight, iPosAngle, iCurrAngle);
??????????? //计算绘数字
??????????? //求圆弧所在点的位置,有偏差
??????????? iCurrSumAngle += iCurrAngle;
??????????? double pointX = Math.Cos(iCurrSumAngle * Math.PI / 180) * r;? //对边,
??????????? double pointY = Math.Sin(iCurrSumAngle * Math.PI / 180) * r;? //邻边
??????????? pointY = ry - pointY;

??????????? pointX = rx - pointX;
??????????? Font strFont=new Font("宋体", 12, FontStyle.Italic);
??????????? //开始测试绘字符需要的位置
??????????? SizeF sizeF = g.MeasureString(dCurrBfb.ToString(), strFont);

??????????? pointX = pointX - sizeF.Width / 2;
??????????? pointY = pointY + sizeF.Height / 2;

??????????? g.DrawString(dCurrBfb.ToString(), strFont, new SolidBrush(Color.Red), Convert.ToInt32(pointX), Convert.ToInt32(pointY) - 20);

??????????? iPosAngle += iCurrAngle;
??????????? iCurrAngle = 0;
???????????
??????? }
??? }

??? public override ArrayList ParseXmlData()
??? {
??????? //解析数据格式
??????? //<imagedraw>
??????? //?? <imagedata data="100" color="#fff000">
??????? //</imagedraw>
??????? ArrayList dataList = new ArrayList();
??????? System.Xml.XmlDocument doc = new XmlDocument();
??????? doc.LoadXml(this.XmlData);
??????? System.Xml.XmlElement root = doc.DocumentElement;
??????? foreach (System.Xml.XmlNode node in root.ChildNodes)
??????? {
??????????? string sData = node.Attributes["data"].Value;
??????????? string sColor = node.Attributes["color"].Value;
??????????? dataList.Add(new ImageData(sData, sColor));
??????? }
??????? return dataList;
??? }

??? public class ImageData
??? {
??????? private double drawData = 0.00;
??????? private Color drawColor=Color.White;

??????? public ImageData(string data, string htmlColor)
??????? {
??????????? this.drawData = Convert.ToDouble(data);
??????????? drawColor = System.Drawing.ColorTranslator.FromHtml(htmlColor);
??????? }

??????? public double DrawData
??????? {
??????????? get { return this.drawData; }
??????? }

??????? public Color DrawColor
??????? {
??????????? get { return drawColor; }
??????? }

??? }

}

?

热点排行