ASP.NET. - HttpHandler/System.Drawing



oo o o aa o. Oa a

     ASP.NET

a

     ASP.NET

o o o oa aa ao, (< img id="imgChart" runat="server" />) aa o , oa o a HttpHandler

a aaa o a a a a a a, oo o QueryString

SqlDataReader reader = null;
         
DataLayer data = new DataLayer();
         
// run the stored procedure and return an ADO.NET DataReader
         
reader = data.RunProcedure("P_GET_TESTS");
         
ArrayList rowList = new ArrayList();
         while (
reader.Read())
         {
            
object[] values = new object[ reader.FieldCount];
            
reader.GetValues(values);
            
rowList.Add(values);
         }
         
data.Close();

         
         
string strTypesLegend = "";
         
string strTestsData   = "";
         
string strSeparate    = "";
         foreach (
object[] row in rowList)
         {
            
strTypesLegend += String.Format("{0},", row[1].ToString());
            
strTestsData   += String.Format("{0},", row[2].ToString());
            
strSeparate    += String.Format("{0},", "False");
         }


         
// legend and data
         
strTypesLegend = strTypesLegend.Remove(strTypesLegend.Length - 1, 1);
         
strTestsData   = strTestsData.Remove(strTestsData.Length - 1, 1);
         
strSeparate    = strSeparate.Remove(strSeparate.Length - 1, 1);

         
imgChart.Attributes.Add("src", "chart.aspx?Legends=" + strTypesLegend +
                                       
"&Vals=" + strTestsData +
                                       
"&Separate=" + strSeparate);

oo a ao o a , a o o web.config:

< httphandlers>
    <
add verb="*" path="chart.aspx" type="Charts.Components.HttpHandler.PieChartHandler, Charts" />
< /
httphandlers>

o ProcessRequest a a o:

void IHttpHandler.ProcessRequest(HttpContext context)
      {
         
HttpRequest Request = context.Request;
         
HttpResponse Response = context.Response;

         
// 1.
         // o QueryString ,
         // o a oaa ao
         // ooo oa delimited strings

         
string strLegends  = Request.QueryString["Legends"];
         
string strValues   = Request.QueryString["Vals"];
         
string strSeparate = Request.QueryString["Separate"];

         
// 2.
         // a

         
string[] sLegends  = strLegends.Split(new char[] {','});
         
string[] sValues   = strValues.Split(new char[] {','});
         
string[] sSeparate = strSeparate.Split(new char[] {','});
            
         
// 3.
         // o a aa float a,
         // a oaa ao oa bool a

         
int iLen = sLegends.Length;
         
float[] fValues = new float[iLen];
         
bool[] bSeparate = new bool[iLen];
         for (
int i = 0; i < iLen; i++)
         {
            
fValues[i] = float.Parse(sValues[i], Thread.CurrentThread.CurrentCulture);
            
bSeparate[i] = (sSeparate[i] == "False") ? false : true;
         }

         
// 4.
         // oa instance oa PieChart (o aaao o)
         // oo oo oo oa
         // GetPieChart, oo oao a o a (a a) o
         // aoa aa stream

         
PieChart pchrt = new PieChart();
         
System.IO.Stream strm = pchrt.GetPieChart(fValues, sLegends, bSeparate);

         
// 5.
         // a o :
         // oa stream a a content-type

         
Bitmap btmp = new Bitmap(strm);
         
Response.Clear();
         
Response.ContentType = ConfigurationSettings.AppSettings["GIF_CONTENT_TYPE"];
         
System.Drawing.Imaging.ImageFormat outPutFormat = System.Drawing.Imaging.ImageFormat.Gif;
         
btmp.Save(Response.OutputStream, outPutFormat);
      }

o aoa o oa PieChart, GetPieChart, oo a oo 3 ao, oo oo a oo System.Drawing, oaa

public Stream GetPieChart(float[] fValues, string[] sLegends, bool[] bSeparate)
      {
         
// 2 aa oa a oa PieChartData,
         // oo oa a,
         // o o
         
...........
         ...........
         ...........
         ...........

         
/// 3
         /// oa Bitmap aa ao,
         /// oa o Graphics a oo oo Bitmap
         /// o graphics oo Clear

         
Bitmap memImg = new Bitmap(imgWidth, imgHeight, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
         
Graphics grph = Graphics.FromImage(memImg);
         
grph.Clear(ColorTranslator.FromHtml(ConfigurationSettings.AppSettings["FRAME_FILL_COLOR"]));

         
/// 4
         /// oa aaa, o oa

         
Brush backbrush  = new SolidBrush(ColorTranslator.FromHtml(ConfigurationSettings.AppSettings["FRAME_FILL_COLOR"]));
         
Brush mainbrush  = new SolidBrush(ColorTranslator.FromHtml(ConfigurationSettings.AppSettings["MAIN_BRUSH_COLOR"]));
         
Brush lightbrush = new SolidBrush(ColorTranslator.FromHtml(ConfigurationSettings.AppSettings["LIGHT_BRUSH_COLOR"]));
         
Pen   mainpen    = new Pen(ColorTranslator.FromHtml(ConfigurationSettings.AppSettings["MAIN_BRUSH_COLOR"]), 1);
         
Pen   lightpen   = new Pen(ColorTranslator.FromHtml(ConfigurationSettings.AppSettings["LIGHT_BRUSH_COLOR"]), 1);
      
         
/// 5
         /// oa o Rectangle legend
         /// aa o o aa (FillRectangle)

         
Rectangle legendrect = new Rectangle(
            (int)(
pchrtData.LeftMargin + pieWidth + pchrt.FontHeight * 0.5),
            
pchrtData.TopMargin,
            (int)(
pchrt.FontHeight * 2.2 + maxValuesWidth + maxNamesWidth + maxPercentWidth + 10),
            
pchrtData.Elements * pchrt.FontHeight + 7);
         
grph.FillRectangle(backbrush, legendrect);

, o oa 3d , a oo o, aoo, o a oo a oa PieChartData, a o a o o

...
         
/// 6
         /// create ellipse rectangle and
         /// draw pie sectors in loop for 3d
         
Rectangle rectangleEllipse;
         for (
int j = (int)(piedia * pchrtData.Pie3dRatio * 0.01F); j > 0; j--)
         {
            for (
int i = 0; i < pchrtData.Elements; i++)
            {
               
rectangleEllipse = new Rectangle(
                  
pchrt.PieRectangle[i].X,
                  
pchrt.PieRectangle[i].Y + j,
                  
pchrt.PieRectangle[i].Width,
                  
pchrt.PieRectangle[i].Height);

               
///
               /// fill ellipse pie with HatchBrush
               
grph.FillPie(
                  new
System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.Percent50,
                  
pchrtData.ColorVal[i]),
                  
rectangleEllipse,
                  
pchrtData.StartAngle[i],
                  
pchrtData.SwapAngle[i]);
            }
         }





a oo a o aa oa o:

...
         
/// 7
         /// o ao , o aoa
         /// o legend o o a
         
         
int startWidth = (int)(pieWidth + pchrt.FontHeight * 2.0 + pchrtData.LeftMargin);
         for (
int i = 0; i < pchrtData.Elements; i++)
         {
            
float yCoord = i * pchrt.FontHeight + 4 + pchrtData.TopMargin;

            
/// 7-1
            /// colors pie sectors

            
grph.FillPie(new SolidBrush(
               
pchrtData.ColorVal[i]),
               
pchrt.PieRectangle[i],
               
pchrtData.StartAngle[i],
               
pchrtData.SwapAngle[i]);



     ASP.NET

o , a legend o

...
            
///
            /// 7-2
            /// a aoo 3 a oo oa DrawString
            /// a, aa a oa

            
grph.DrawString(
               
pchrtData.Values[i].ToString(Thread.CurrentThread.CurrentCulture),
               
mainfont,
               
mainbrush,
               (int)
startWidth,
               
yCoord);

            
///
            
grph.DrawString(
               
pchrtData.Legends[i],
               
mainfont,
               
mainbrush,
               (int)(
startWidth + maxValuesWidth),
               
yCoord);

            
///
            
grph.DrawString(
               
pchrtData.PercentVal[i].ToString(Thread.CurrentThread.CurrentCulture) + "%",
               
mainfont,
               
mainbrush,
               (int)(
startWidth + maxValuesWidth + maxNamesWidth),
               
yCoord);
         
            
///
            /// 7-3
            /// aa a aa legend
            
grph.FillRectangle(
               new
SolidBrush(pchrtData.ColorVal[i]),
               new
Rectangle((int)(pieWidth + pchrt.FontHeight * 0.75 + pchrtData.LeftMargin),
               (
i * pchrt.FontHeight) + (pchrt.FontHeight) / 5 + 4 + pchrtData.TopMargin,
               (int)(
pchrt.FontHeight * 0.7),
               (int)(
pchrt.FontHeight * 0.7)));

            
/// 7-4
            /// o a aa
            
grph.DrawRectangle(
               
mainpen,
               new
Rectangle((int)(pieWidth + pchrt.FontHeight * 0.75 + pchrtData.LeftMargin),
               (
i * pchrt.FontHeight) + (pchrt.FontHeight) / 5 + 4 + pchrtData.TopMargin,
               (int)(
pchrt.FontHeight * 0.7),
               (int)(
pchrt.FontHeight * 0.7)));
         }

aaa: a aa - oo aa o o a aa o legend

oa o o stream o

/// 8
         /// draw big rectangle around legend
         
grph.DrawRectangle(lightpen, legendrect);

         
/// 9
         /// draw big rectangle around everything
         
grph.DrawRectangle(lightpen, new Rectangle(0, 0, imgWidth - 1, imgHeight - 1));
         
grph.DrawRectangle(lightpen, new Rectangle(0, 0, imgWidth - 2, imgHeight - 2));
         
         
/// 10
         /// return stream
         
Stream mystream = new MemoryStream();
         
memImg.Save(mystream, System.Drawing.Imaging.ImageFormat.Gif);
         return
mystream;
      }

oao aaa o o PieChartData, oo a a aa, o o o oo a o o o a, ao o constructor

public PieChartData(float[] fValues, string[] sLegends, bool[] bSeparate)
      {
         
///
         /// aa o oa a o,
         /// a a web.config

         
Color[] DefaultColors = new Color[15];
         for (
int i = 0; i < 15; i++)
         {
            
DefaultColors.SetValue(
               
ColorTranslator.FromHtml(ConfigurationSettings.AppSettings["ARRAY_COLOR_" + (i + 1).
               
ToString(Thread.CurrentThread.CurrentCulture)]), i);
         }

         
///
         /// set data

         
this.Values   = fValues;
         
this.Legends  = sLegends;
         
this.Separate = bSeparate;
         
         
///
         /// initialize arrays with size

         
this.Elements   = this.Values.Length;
         
this.PercentVal = new float[this.Elements];
         
this.StartAngle = new float[this.Elements];
         
this.SwapAngle  = new float[this.Elements];
         
this.ColorVal   = new Color[this.Elements];
         
         
///
         /// set default values for other properties
         /// from web.config

         
this.LeftMargin     = int.Parse(ConfigurationSettings.AppSettings["LEFT_MARGIN"], Thread.CurrentThread.CurrentCulture);
         
this.RightMargin    = int.Parse(ConfigurationSettings.AppSettings["RIGHT_MARGIN"], Thread.CurrentThread.CurrentCulture);
         
this.TopMargin      = int.Parse(ConfigurationSettings.AppSettings["TOP_MARGIN"], Thread.CurrentThread.CurrentCulture);
         
this.BottomMargin   = int.Parse(ConfigurationSettings.AppSettings["BOTTOM_MARGIN"], Thread.CurrentThread.CurrentCulture);
         
this.SeparateOffset = byte.Parse(ConfigurationSettings.AppSettings["SEPARATE_OFFSET"], Thread.CurrentThread.CurrentCulture);
         
this.Pie3dRatio     = byte.Parse(ConfigurationSettings.AppSettings["PIE_3DRATIO"], Thread.CurrentThread.CurrentCulture);
         
this.PieRatio       = byte.Parse(ConfigurationSettings.AppSettings["PIE_RATIO"], Thread.CurrentThread.CurrentCulture);
         
this.PieDiameter    = int.Parse(ConfigurationSettings.AppSettings["PIE_DIAMETER"], Thread.CurrentThread.CurrentCulture);
         
this.ChartFont      = new Font(ConfigurationSettings.AppSettings["FONT_FACE"], 8.0F, FontStyle.Bold);

         
///
         /// get total of all values in array

         
float totalval = 0;
         for (
int i = 0; i < this.Elements; i++)
         {
            
totalval += this.Values[i];
         }

aoo oa aa o, aa o, o oooa, oo o aa. oo o o, o a, a ooa ooo o :

float total = 0 ;
         
int j = 0;
         for (
int i = 0; i < this.Elements; i++)
         {
            
this.StartAngle[i] = total;
            
this.SwapAngle[i] = this.Values[i] * 360 / totalval;
            
this.PercentVal[i] = (float)((int)(this.Values[i] * 10000 / totalval)) / 100;
            
total = total + this.Values[i] * 360 / totalval;

            
this.ColorVal[i] = DefaultColors[j];
            if (
j + 1 >= this.ColorVal.Length)
            {
               
j = 0;
            }
            else
            {
               
j++;
            }
         }
      }

o o web.config oa oo a o oa ao:

< !-- default values for data -->
      <
add key="LEFT_MARGIN"       value="20" />
      <
add key="RIGHT_MARGIN"      value="20" />
      <
add key="TOP_MARGIN"        value="20" />
      <
add key="BOTTOM_MARGIN"     value="20" />
      <
add key="SEPARATE_OFFSET"   value="15" />
      <
add key="PIE_3DRATIO"       value="6" />
      <
add key="PIE_RATIO"         value="70" />
      <
add key="PIE_DIAMETER"      value="200" />

      <
add key="FONT_FACE"         value="Verdana" />
      <
add key="ADD_TO_DIAMETER"   value="50" />
      <
add key="NAMES_WIDTH"       value="75" />
      <
add key="VALS_WIDTH"        value="30" />
      <
add key="PERCENT_WIDTH"     value="50" />

.

o oo aa a. o aoo ooa ooa o - a managed code a aa o a o, a a ao. oao o o ao - -a, aoa o chart o aooa aoa oa oo oo o oaa. Oao ooa, ao Microsoft ao aa, ao a Avalon oa Tablet PC

: Anatoly Lubarsky