?? pieshape.cs
字號:
/*
C#發現之旅系列教程配套演示代碼
本代碼僅供學習和參考使用
編制 袁永福 2008-5-15
MSN yyf9989@hotmail.com
QQ 28348092
作者博客 http://xdesigner.cnblogs.com/
使用者請作者的尊重知識產權。
*/
using System;
using System.Drawing ;
using System.Drawing.Drawing2D ;
using System.Xml ;
namespace cs_discovery
{
/// <summary>
/// 單個餅圖形狀項目
/// </summary>
/// <remarks>該類型是PieShape列表的成員類型</remarks>
[System.Serializable()]
public class PieShapeItem
{
private double dblValue = 0 ;
/// <summary>
/// 數值
/// </summary>
public double Value
{
get{ return dblValue ;}
set{ dblValue = value;}
}
private string strText = null;
/// <summary>
/// 對象文本
/// </summary>
public string Text
{
get{ return strText ;}
set{ strText = value;}
}
private string strLink = null;
/// <summary>
/// 項目鏈接地址
/// </summary>
public string Link
{
get{ return strLink ;}
set{ strLink = value;}
}
private Color intColor = Color.Black ;
/// <summary>
/// 項目顏色
/// </summary>
public Color Color
{
get{ return intColor ;}
set{ intColor = value;}
}
/// <summary>
/// 開始角度
/// </summary>
internal float StartAngle = 0 ;
/// <summary>
/// 結束角度
/// </summary>
internal float EndAngle = 0 ;
}//public class PieShapeItem
/// <summary>
/// 平面餅圖形狀對象
/// </summary>
/// <remarks>
/// 本對象是元素類型為PieShapeItem的列表,并能繪制一個橢圓形的平面餅圖
/// 編制 袁永福 2008-1-10
/// </remarks>
[System.Serializable()]
public class PieShape : System.Collections.CollectionBase
{
/// <summary>
/// 初始化對象
/// </summary>
public PieShape( )
{
}
#region 定義對象坐標位置 **********************************************
private int intLeft = 0 ;
/// <summary>
/// 對象左端位置
/// </summary>
public int Left
{
get{ return intLeft ;}
set{ intLeft = value;}
}
private int intTop = 0 ;
/// <summary>
/// 對象頂端位置
/// </summary>
public int Top
{
get{ return intTop ;}
set{ intTop = value;}
}
private int intWidth = 300 ;
/// <summary>
/// 對象寬度
/// </summary>
public int Width
{
get{ return intWidth ;}
set{ intWidth = value;}
}
private int intHeight = 300 ;
/// <summary>
/// 對象高度
/// </summary>
public int Height
{
get{ return intHeight ;}
set{ intHeight = value;}
}
/// <summary>
/// 對象邊界
/// </summary>
public Rectangle Bounds
{
get
{
return new Rectangle(
intLeft ,
intTop ,
intWidth ,
intHeight );
}
set
{
intLeft = value.Left ;
intTop = value.Top ;
intWidth = value.Width ;
intHeight = value.Height ;
}
}
#endregion
#region 管理餅圖項目的代碼群 ******************************************
/// <summary>
/// 返回指定序號處的項目
/// </summary>
public PieShapeItem this[ int index ]
{
get{ return ( PieShapeItem) this.List[ index ] ;}
}
/// <summary>
/// 添加一個項目
/// </summary>
/// <param name="item">項目對象</param>
/// <returns>新加的項目在列表中的序號</returns>
public int Add( PieShapeItem item )
{
return this.List.Add( item );
}
/// <summary>
/// 添加一個項目
/// </summary>
/// <param name="Value">項目數值</param>
/// <param name="Text">項目文本</param>
/// <param name="Link">項目鏈接地址</param>
/// <param name="Color">項目顏色值</param>
/// <returns>新增項目在列表中的序號</returns>
public int Add( double Value , string Text , string Link , Color Color )
{
PieShapeItem item = new PieShapeItem();
item.Value = Value ;
item.Text = Text ;
item.Link = Link ;
item.Color = Color ;
return this.List.Add( item );
}
/// <summary>
/// 添加一個項目
/// </summary>
/// <param name="Value">項目數值</param>
/// <param name="Text">項目文本</param>
/// <param name="Link">項目鏈接地址</param>
/// <returns>新增項目在列表中的序號</returns>
public int Add( double Value , string Text , string Link )
{
PieShapeItem item = new PieShapeItem();
item.Value = Value ;
item.Text = Text ;
item.Link = Link ;
item.Color = StdColors[ this.Count % StdColors.Length ] ;
return this.List.Add( item );
}
/// <summary>
/// 刪除一個項目
/// </summary>
/// <param name="item">要刪除的指定的餅圖項目</param>
public void Remove( PieShapeItem item )
{
this.List.Remove( item );
}
#endregion
#region 繪制圖形相關 **************************************************
/// <summary>
/// 刷新對象狀態
/// </summary>
/// <remarks>
/// 本函數中反向遍歷所有的餅圖項目,
/// 計算各個餅圖項目的起始和終止角度</remarks>
public void RefreshState()
{
double TotalValue = 0 ;
foreach( PieShapeItem item in this )
{
TotalValue += item.Value ;
}
float AngleCount = 0 ;
for( int iCount = this.Count - 1 ; iCount >= 0 ; iCount -- )
{
PieShapeItem item = this[ iCount ] ;
float angle = ( float ) ( 360.0 * item.Value / TotalValue ) ;
item.StartAngle = ( float ) Math.Round( AngleCount , 3 ) ;
item.EndAngle = ( float ) Math.Round( AngleCount + angle , 3 ) ;
AngleCount += angle ;
item.StartAngle = ( float ) Math.Round( FixAngle( item.StartAngle ) , 3 );
item.EndAngle = ( float ) Math.Round( FixAngle( item.EndAngle ) , 3 ) ;
}
}
/// <summary>
/// 創建一個包含對象圖形位圖對象
/// </summary>
/// <returns>創建的位圖對象</returns>
public Bitmap CreateBitmap( )
{
Bitmap bmp = new Bitmap( intWidth + 1 , intHeight + 1 ) ;
using( Graphics g = Graphics.FromImage( bmp ))
{
g.Clear( Color.White );
g.TranslateTransform( intLeft , intTop );
g.SmoothingMode = SmoothingMode.HighQuality ;
Draw( g , this.Bounds );
}
return bmp ;
}
/// <summary>
/// 繪制餅圖圖形
/// </summary>
/// <param name="g">圖形繪制對象</param>
/// <param name="ClipRectangle">剪切矩形</param>
public void Draw( Graphics g , Rectangle ClipRectangle )
{
foreach( PieShapeItem item in this )
{
using( GraphicsPath path = CreatePath( item ))
{
using( SolidBrush b = new SolidBrush( item.Color ))
{
g.FillPath( b , path );
g.DrawPath( Pens.Black , path );
}
}
}
}
/// <summary>
/// 為一個餅圖項目創建路徑對象
/// </summary>
/// <param name="item">餅圖項目</param>
/// <returns>創建的路徑對象</returns>
public GraphicsPath CreatePath( PieShapeItem item )
{
GraphicsPath path = new GraphicsPath();
path.AddPie(
intLeft ,
intTop ,
intWidth ,
intHeight ,
item.StartAngle ,
item.EndAngle - item.StartAngle );
return path ;
}
#endregion
/// <summary>
/// 創建用于顯示餅圖圖片和超鏈接的HTML代碼字符串
/// </summary>
/// <param name="imgsrc">圖片地址</param>
/// <returns>創建的HTML字符串</returns>
/// <remarks>
/// 此處沒有簡單拼湊HTML字符串,而是利用XML和HTML的相似性
/// 使用一個XmlTextWriter來生成HTML字符串。
/// </remarks>
public string GetHtmlString( string imgsrc )
{
if( this.Count == 0 )
return "";
// 生成唯一的 map 元素名稱
string name = System.Guid.NewGuid().ToString("N");
// 生成 XmlTextWriter 對象
System.IO.StringWriter myStr = new System.IO.StringWriter();
System.Xml.XmlTextWriter writer = new XmlTextWriter( myStr );
writer.IndentChar = ' ' ;
writer.Indentation = 3 ;
writer.Formatting = System.Xml.Formatting.Indented ;
// 開始輸出HTML
writer.WriteStartDocument();
// 輸出圖片元素
writer.WriteRaw("\r\n<img src='" + imgsrc + "' usemap='#" + name + "' border='0'/>");
// 輸出 map 元素
writer.WriteStartElement("map");
writer.WriteAttributeString("name" , name );
foreach( PieShapeItem item in this )
{
// 輸出超鏈接區域
Point[] ps = this.GetPoints( item );
writer.WriteStartElement("area");
writer.WriteAttributeString("shape" , "poly");
writer.WriteStartAttribute("coords" , null );
for( int iCount = 0 ; iCount < ps.Length ; iCount ++ )
{
writer.WriteString( ps[ iCount ].X.ToString() );
writer.WriteString("," );
writer.WriteString( ps[ iCount ].Y.ToString() );
writer.WriteString("," );
}
writer.WriteEndAttribute();
if( item.Link != null && item.Link.Length > 0 )
{
writer.WriteAttributeString("href" , item.Link );
}
writer.WriteAttributeString("title" , item.Text );
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Close();
string html = myStr.ToString();
// 修正輸出的HTML字符串
int index = html.LastIndexOf("?>");
if( index > 0 )
{
html = html.Substring( index + 2 );
}
return html ;
}
#region 內部代碼 ******************************************************
/// <summary>
/// 獲得包圍餅圖區域的點坐標數組
/// </summary>
/// <param name="item">餅圖項目</param>
/// <returns>點坐標數組</returns>
private Point[] GetPoints( PieShapeItem item )
{
GraphicsPath path = CreatePath( item );
path.Flatten();
PointF[] ps = path.PathPoints ;
path.Dispose();
Point[] ps2 = new Point[ ps.Length ] ;
for( int iCount = 0 ; iCount < ps.Length ; iCount ++ )
{
ps2[ iCount ].X = ( int ) ( ps[ iCount ].X );
ps2[ iCount ].Y = ( int ) ( ps[ iCount ].Y );
}
return ps2 ;
}
/// <summary>
/// 根據橢圓形狀修正角度
/// </summary>
/// <param name="angle">原始角度</param>
/// <returns>修正后的角度值</returns>
private float FixAngle( float angle )
{
if( ( angle % 90.0 ) == 0 )
return angle ;
if( intWidth == intHeight )
return angle ;
double x = intWidth * Math.Cos( angle * Math.PI / 180 );
double y = intHeight * Math.Sin( angle * Math.PI / 180 );
float result = ( float ) ( Math.Atan2( y , x ) * 180 / Math.PI );
if( result < 0 )
result += 360 ;
return result ;
}
/// <summary>
/// 標準顏色列表
/// </summary>
private static Color[] StdColors = new Color[]{
Color.Purple,
Color.Red,
Color.Green,
Color.Blue,
Color.Yellow,
Color.Olive,
Color.Navy,
Color.Aqua,
Color.Lime,
Color.Maroon,
Color.Teal,
Color.Fuchsia
};
#endregion
}//public class PieShape : System.Collections.CollectionBase
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -