请教各位,我在asp.net 2.0下用GDI绘制统计图表,我想实现像EXCEL那样能自动根据数据确定纵轴的间隔个数和间隔代表的数值,能用算法实现吗

解决方案 »

  1.   

    这个不是很简单的么?
            /// <summary>
            /// 画单条柱状图
            /// </summary>
            /// <param name="dt">传入datatable</param>
            public void DrawColumns(DataTable dt, string outPutFile)
            {
                #region 将datatable分解为两个数组
                int rowNum = dt.Rows.Count;
                float[] NumsIp = new float[rowNum];
                float[] NumsPage = new float[rowNum];
                string[] Description = new string[rowNum];
                for (int i = 0; i < rowNum; i++)
                {
                    NumsPage[i] = (float)Convert.ToDouble(dt.Rows[i][0]);
                    if (dt.Columns.Count == 2)
                        Description[i] = dt.Rows[i][1].ToString();
                    else
                    {
                        NumsIp[i] = (float)Convert.ToDouble(dt.Rows[i][1]);
                        Description[i] = dt.Rows[i][1].ToString();
                    }
                }
                #endregion            float NumsSum = 0;//获取所有元素的和
                for (int i = 0; i < NumsPage.Length; i++)
                {
                    NumsSum += NumsPage[i];
                }            ////////开始画图了////////////////            Bitmap bmp = new Bitmap(760, 480);//创建画板            Graphics g = Graphics.FromImage(bmp);//找了一个画家            g.SmoothingMode = SmoothingMode.HighQuality;//设置高质量,低速度呈现平滑程度            g.CompositingQuality = CompositingQuality.HighQuality; //高质量低速度复合            g.InterpolationMode = InterpolationMode.HighQualityBicubic;//设置高质量插值法            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;//文字呈现            g.Clear(Color.White);//画家把画板涂白,这里不用画刷的,系统莫非已经给了这人一个刷子?            Pen p = new Pen(Color.Black);//画家又找了一个Black颜色的画笔来画轮廓            #region 画左上角文字
                g.DrawString(this._strTitle, new Font("宋体", 14), new SolidBrush(Color.Black), 10, 10);
                #endregion            #region 画右边的矩形
                //g.DrawRectangle(p, 540, 40, 180, 400);
                //g.DrawString("明通信息技术有限公司", new Font("宋体", 10), new SolidBrush(Color.Black), 570, 450);
                //Pen pSmall = new Pen(Color.Fuchsia);
                //for (int i = 0; i < newcolors.Length; i++)
                //{
                //    g.DrawRectangle(pSmall, 550, i * 20 + 50, 14, 14);
                //    g.FillRectangle(new SolidBrush(Color.FromName(newcolors[i])), 550, i * 20 + 50, 14, 14);
                //    g.DrawString(Description[i], new Font("Arial", 8), new SolidBrush(Color.Black), 570, i * 20 + 50);
                //}
                #endregion            //开始画坐标
                Pen p2 = new Pen(Color.Black, 3);
                int x1 = 90;
                int y1 = 400;
                int x2 = 670;
                int y2 = 400;
                int x3 = 90;
                int y3 = 90;
                int x4 = 90;
                int y4 = 400;
                g.DrawLine(p2, x1, y1, x2, y2);
                g.DrawLine(p2, x3, y3, x4, y4);            //计算中间的矩形块宽度
                float xwidth = (x2 - x1) / NumsPage.Length;
                float halfxwidth = xwidth / 3;
                float maxheight = 0;
                float recheight = 0;
                recheight = y1 - y3;
                for (int i = 0; i < NumsPage.Length; i++)
                {
                    if (maxheight < NumsPage[i])
                        maxheight = NumsPage[i];
                }
                Pen p3 = new Pen(Color.Lavender);
                p3.DashStyle = DashStyle.Dash;
                for (int i = 0; i < NumsPage.Length; i++)
                {
                    g.DrawLine(p3, x1 + xwidth * (i + 1), y3, x1 + xwidth * (i + 1), y1 - 2);
                }
                //计算中间的矩形的高度
                float ywidth = (y4 - y3) / 10;
                for (int i = 0; i < 10; i++)
                {
                    if (i < 9)
                        g.DrawLine(p3, x3 + 2, y3 + ywidth * (i + 1), x2, y3 + ywidth * (i + 1));
                    g.DrawString(Convert.ToString(NumsSum / 10 * (10 - i)), new Font("Arial", 8), new SolidBrush(Color.Black), 50, y3 - 6 + ywidth * (i));
                }            //画中间的矩形
                if (dt.Columns.Count == 2)
                { //只有一条PAGE的
                    Font f;
                    if (NumsPage.Length <= 14)
                    {
                        f = new Font("Arial", 9);
                    }
                    else if (NumsPage.Length > 14 && NumsPage.Length <= 18)
                    {
                        f = new Font("Arial", 8);
                    }
                    else
                    {
                        f = new Font("Arial", 7);
                    }
                    float fWidth = f.SizeInPoints;
                    for (int i = 0; i < NumsPage.Length; i++)
                    {
                        g.DrawRectangle(p, x1 + xwidth * i + halfxwidth, y2 - NumsPage[i] / maxheight * recheight, halfxwidth, NumsPage[i] / maxheight * recheight - 2);
                        //填充颜色
                        g.FillRectangle(new SolidBrush(Color.Aqua), x1 + xwidth * i + halfxwidth, y2 - NumsPage[i] / maxheight * recheight, halfxwidth, NumsPage[i] / maxheight * recheight - 2);
                        g.DrawString(NumsPage[i].ToString(), f, new SolidBrush(Color.Black), x1 + xwidth * i + halfxwidth + (halfxwidth - GetStrWidth(NumsPage[i].ToString(), f)) / 2, y2 - NumsPage[i] / maxheight * recheight - 15);//注意GetStrWidth第二个参数
                        //写上标识
                        StringFormat stringFormat = new StringFormat();
                        stringFormat.FormatFlags = StringFormatFlags.DirectionVertical;
                        g.DrawString(Description[i], f, new SolidBrush(Color.Black), x1 + xwidth * i + halfxwidth + (halfxwidth - GetStrWidth(f)) / 2 - 4, y1 + 4, stringFormat);//注意GetStrWidth第二个参数
                    }
                }
                bmp.Save(outPutFile, ImageFormat.Bmp);
                //bmp.Save(HttpContext.Current.Response.OutputStream, ImageFormat.Jpeg);
                g.Dispose();
                bmp.Dispose();
            }
      

  2.   

    //计算中间的矩形的高度
                float ywidth = (y4 - y3) / 10;
     这样的话,还是把Y轴固定分成了10段,我的意思是根据数据动态生成,有的不需要10段