您的位置:首页 > 其它

.net实现3D饼图(源码1)

2007-12-18 23:39 387 查看
点击此处下载源码+test代码(99KB,rar)
本来想改改几个bug再整理下发上来的。但是最近工作比较紧张,没有时间。发出来大家看看。多提提意见。帮忙改改。 


using System;


using System.Collections;


using System.Drawing;


using System.IO;


using System.Drawing.Imaging;






namespace qchart




...{




    /**//// 


    /// chart 的摘要说明。


    /// 抽象类,所有chart的父类


    /// 


    public abstract class Chart




    ...{


        


        public int width,height;


        public int count = -1;


        public ArrayList al =  null;


        public Bitmap bitmap = null;




        public Chart()




        ...{


            init(400, 300);


        }




        public Chart(int w,int h)




        ...{


            init(w, h);


        }




        private void init(int w, int h)




        ...{


            width = w;


            height = h;


        }






        public void saveBitmap(string file)




        ...{


            bitmap.Save(file, ImageFormat.Jpeg);


        }




        public void saveBitmap(Stream stream)




        ...{




            bitmap.Save(stream, ImageFormat.Jpeg);


        }




        public abstract void createBitmap();




    }



 


 


using System;


using System.Drawing;


using System.Drawing.Imaging;


using System.Collections;


using System.IO;




namespace qchart




...{




    /**//// 


    /// 饼图的抽象类,所有样式的饼图继承此类


    /// 


    public abstract class PieChart : Chart




    ...{


        public int startAngle = 0;




        public PieChart()




        ...{


            init(400, 300);


        }


        public PieChart(int w,int h)




        ...{


            init(w, h);


        }




        private void init(int w, int h)




        ...{


            width = w;


            height = h;


            al = new ArrayList();


        }




    




        public void addPieData(int val,string name)




        ...{


            PieData pd = new PieData(val,name);


            al.Add(pd);


            count++;


        }




        public void addPieData(int[] vals,string[] names)




        ...{


            int l = vals.Length

            for(int i=0;i



            ...{


                addPieData(vals[i],names[i]);


            }


            //count += l ;


        }




        public void removePieData(int index)




        ...{


            if(index >= 0 && index <=count)




            ...{


                al.RemoveAt(index);


                count--;


            }


        }








    }


}


 


using System;


using System.Drawing;


using System.Drawing.Imaging;


using System.Collections;


using System.IO;




namespace qchart




...{




    /**//// 


    /// 


    /// 


    public  class PieChart2D : PieChart




    ...{




        public PieChart2D() : base()




        ...{


           


        }


        public PieChart2D(int w, int h)  : base(w, h)




        ...{




        }






        public override void createBitmap()




        ...{


            //用指定的大小和格式初始化 Bitmap 类的新实例


            bitmap = new Bitmap(width, height);


            //创建绘图对象


            Graphics g = Graphics.FromImage(bitmap);


            //清除整个绘图面并以透明背景色填充


            //g.Clear(Color.Transparent);


            g.Clear(Color.Snow);




            Rectangle r = new Rectangle(0, 0, width, height);




            //int[] angle = {30,60,90,45,135} ;


            int sum = startAngle;




            Pen p = new Pen(Color.YellowGreen);




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




            ...{


                PieData pd = (PieData)al[i];


                float f = Convert.ToSingle(pd.val);


                g.FillPie(Qcommon.b[i % 12], r, sum, f);


                g.DrawPie(p, r, sum, f);


                sum += Convert.ToInt32(f);


            }




        }










    }


}


 


using System;


using System.Drawing;


using System.Drawing.Imaging;


using System.Collections;


using System.IO;


using System.Drawing.Drawing2D;




namespace qchart




...{




    /**//// 


    /// 


    /// 


    public  class PieChart3D : PieChart




    ...{


        static readonly int deta = 30;


        //static readonly int dpt  = 5;




        public PieChart3D() : base()




        ...{


           


        }


        public PieChart3D(int w, int h):base(w,h)




        ...{


            


        }






        public override void createBitmap()




        ...{


            //bool flag = false;




            //用指定的大小和格式初始化 Bitmap 类的新实例


            bitmap = new Bitmap(width , height );


            //创建绘图对象


            Graphics g = Graphics.FromImage(bitmap);


            //清除整个绘图面并以透明背景色填充


            //g.Clear(Color.Transparent);


            g.Clear(Color.Snow);




            Rectangle rs = new Rectangle((width - 400) / 2 - 50, (height - 300) / 2 + deta/2, 400, 300);




            //g.FillPie(Qcommon.b[0], rs, 0, 180);




            Rectangle r  = new Rectangle((width - 400) / 2 - 50 , (height - 300)/2 - deta/2, 400, 300);


            //Rectangle rc = new Rectangle((width - 400) / 2 + 50, (height - 300) / 2, 300, 300);




            int sum = startAngle % 360;




            Pen p = new Pen(Color.YellowGreen);


            Pen ps = new Pen(Color.DarkGray);




            Point pt = new Point();


            double a = r.Width / 2d;


            double b = r.Height / 2d;


            pt.X = r.X + r.Width / 2;


            pt.Y = r.Y + r.Height / 2;




            //画底面和侧边


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




            ...{


                double af = sum / 180d * Math.PI;


                int sign = Math.Sign(Math.Cos(af));


                double k = Math.Tan(af);




                double dx = sign * Math.Sqrt(1 / (1 / (a * a) + k * k / (b * b)));


                double dy = k * dx;




                int x = pt.X + (int)dx;


                int y = pt.Y + (int)dy;






                PieData pd = (PieData)al[i];


                float f = Convert.ToSingle(pd.val);




                int nextsum = (sum + Convert.ToInt32(f)) % 360;




                g.FillPie(Qcommon.b[i % 12], rs, sum, f);






                if (sum > 180)




                ...{


                    if (nextsum < 180)




                    ...{




                        g.FillPolygon(Qcommon.b[i % 12], new Point[] ...{ new Point(pt.X + (int)a, pt.Y), new Point(pt.X + (int)a, pt.Y + deta), pt });


                        g.DrawLine(p, new Point(pt.X + (int)a, pt.Y), new Point(pt.X + (int)a, pt.Y + deta));




                        //pt = subsidy(g, sum, p, pt, a, b, i + 1, x, y, nextsum);




                        Point pend = findPoint(nextsum, a, b, pt);


                        if (nextsum < 90)




                        ...{


                            printSmailRect(g, i, pend);


                            g.DrawLine(p, new Point(pend.X, pend.Y + deta), new Point(pt.X, pt.Y + deta));


                        }




                    }


                }


                else




                ...{


                    if (nextsum > 180)




                    ...{


                        if (sum <= 90)




                        ...{


                            // 第一象限,补上小正方形就可以了。


                            g.FillRectangle(Qcommon.b[i % 12], x - deta, y, deta, deta);


                        }


                        else




                        ...{






                            /**////// start




                            pt = subsidy(g, sum, p, pt, a, b, i, x, y, nextsum);






                            /**////// end 


                        }




                        // 处理180 度


                        if (sum == 180)




                        ...{


                            if (i == 0)




                            ...{




                                g.FillPolygon(Qcommon.b[(al.Count - 1) % 12], new Point[] ...{ new Point(pt.X - (int)a, pt.Y), new Point(pt.X - (int)a, pt.Y + deta), pt });


                            }


                            else




                            ...{




                                g.FillPolygon(Qcommon.b[(i - 1) % 12], new Point[] ...{ new Point(pt.X - (int)a, pt.Y), new Point(pt.X - (int)a, pt.Y + deta), pt });


                            }




                        }




                        g.DrawLine(p, new Point(pt.X - (int)a, pt.Y), new Point(pt.X - (int)a, pt.Y + deta));




                    }


                    else




                    ...{




                        pt = subsidy(g, sum, p, pt, a, b, i, x, y, nextsum);




                    }




                    // 画底图扇形


                    g.DrawPie(ps, rs, sum, f);


                    // 画start本处竖线


                    g.DrawLine(p, new Point(x, y), new Point(x, y + deta));






                }




                sum = nextsum;




                //this.saveBitmap("e:/qchart/temp/A" + i.ToString() + ".jpg");




            }//for




            int labelWidth = r.Right + deta;


            int labelHeight = deta;




            sum = startAngle % 360;




            // 画顶面


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




            ...{




                PieData pd = (PieData)al[i];


                float f = Convert.ToSingle(pd.val);




                int nextsum = sum + Convert.ToInt32(f);






                g.FillPie(Qcommon.b[i % 12], r, sum, f);


                g.DrawPie(p, r, sum, f);




                g.FillRectangle(Qcommon.b[i % 12], labelWidth, labelHeight, 10, 10);


                g.DrawString(pd.name, Qcommon.LegendFont, Qcommon.b[i % 12], new PointF(labelWidth + 14, labelHeight));




                labelHeight += 16;




                sum = nextsum;






                /**/////this.saveBitmap("e:/qchart/temp/B" + i.ToString() + ".jpg");




            }//for




           




            //g.DrawArc(p, rs, 0, 180);




        }




        private void printSmailRect(Graphics g, int i, Point pend)




        ...{


            Brush br = null;


            if (i == count)


                br = Qcommon.b[0];


            else




            ...{


                br = Qcommon.b[(i>0?(i - 1):i) % 12];


            }




            g.FillRectangle(Qcommon.b[0], pend.X - deta, pend.Y, deta, deta);




            


        }






        private Point subsidy(Graphics g, int sum, Pen p, Point pt, double a, double b, int i, int x, int y, int nextsum)




        ...{


            Point pend = findPoint(nextsum, a, b, pt);




            // 填充底图扇形




            /**/////g.FillPie(Qcommon.b[i % 12], rs, sum, f);


            // 补偿三角形 :// 侧面的竖线端点加上前一个位置的上面的顶点




            if (i == 0)




            ...{


                if (sum <= 90)




                ...{


                    // 第一象限,补上小正方形就可以了。


                    g.FillRectangle(Qcommon.b[0], x - deta, y, deta, deta);


                }


                else




                ...{




                    g.FillPolygon(Qcommon.b[0], new Point[] ...{ new Point(x, y), new Point(x, y + deta), new Point(pt.X + (int)a, pt.Y) });


                }


            }


            else




            ...{


                //g.FillPolygon(Qcommon.b[i - 1], new Point[] { new Point(x, y), new Point(pend.X, pend.Y + deta), pend });




                if (sum <= 90)




                ...{


                    // 第一象限,补上小正方形就可以了。


                    g.FillRectangle(Qcommon.b[i % 12], x - deta, y, deta, deta);


                }


                else




                ...{


                    float pref = Convert.ToSingle(((PieData)al[i - 1]).val);


                    int presum = sum - Convert.ToInt32(pref);


                    if (presum < 0) presum += 360;




                    // 侧面的竖线端点加上前一个位置的上面的顶点


                    Point prept = findPoint(presum, a, b, pt);




                    g.FillPolygon(Qcommon.b[i - 1], new Point[] ...{ new Point(x, y), new Point(x, y + deta), prept });


                }




            }




            if (i == count)




            ...{


                printLine(g, p, pend);


            }


            return pt;


        }




        private void printLine(Graphics g, Pen p, Point pend)




        ...{


            g.DrawLine(p,pend,new Point(pend.X,pend.Y + deta));


        }






        private Point findPoint(int presum,double a,double b,Point pt)




        ...{


            double af = presum / 180d * Math.PI;


            int sign = Math.Sign(Math.Cos(af));


            double k = Math.Tan(af);




            double dx = sign * Math.Sqrt(1 / (1 / (a * a) + k * k / (b * b)));


            double dy = k * dx;




            int x = pt.X + (int)dx;




            int y = pt.Y + (int)dy;




            return new Point(x,y);


        }










    }


}


 


using System;


using System.Drawing;


using System.Drawing.Imaging;




namespace qchart




...{




    /**//// 


    /// qcommon 的摘要说明。


    /// 


    public class Qcommon




    ...{




        public static Brush[] b = ...{   Brushes.Purple,


                                      Brushes.LightSkyBlue,


                                      Brushes.Pink,


                                      Brushes.SeaGreen,


                                      Brushes.Tomato,


                                      Brushes.RoyalBlue,


                                      Brushes.Orange,


                                      Brushes.DarkGray,


                                      Brushes.PowderBlue,


                                      Brushes.OliveDrab,


                                      Brushes.Navy,


                                      Brushes.Magenta


                                  };






        public static Font LegendFont = new Font("宋体", 8, FontStyle.Regular);






    }


}


 


using System;




namespace qchart




...{




    /**//// 


    /// 饼图的数据格式


    /// 


    public class PieData




    ...{


        public PieData(double val,string name)




        ...{


            this.val = val ;


            this.name = name ;


        }




        public double val;


        public string name = null;


    }


}



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1645728
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: