本对象定义了一个完整的饼图,是本程序的核心模块。本对象首先是PieShapeItem的一个强类型列表,它是从System.Collections.CollectionBase上面派生的,通过使用对象的Add或Remove方法就能往这个对象添加或删除饼图项目对象PieShapeItem。当向列表添加项目时未指定项目颜色时会创建一个默认颜色,本类型定义了一个StdColors的静态的颜色数组,新饼图元素的颜色就根据这个颜色数组进行分配。
对象定义了一个RefreshState方法用来计算各个饼图元素对应的扇形区域的起始角度和终止角度。
/// <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> /// <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 ; } |
在这个方法中,我们首先计算所有项目的数值和。然后遍历所有的项目,计算它的扇形区域的起始角度和终止角度。由于要显示的是椭圆形饼图,相对于正圆图形是被压扁的,因此这个起始角度和终止角度需要调用FixAngle函数进行修正。