Creating Thermometer Chart in C#

Have you ever had someone calling you up and saying to you that they needed a chart that looked like a thermometer today and they didn't want it to be simply an image that they update? No? Well I did the other day. So I quickly slapped together a handler to create the chart for me. Note that this isn't a nicely created piece of code but hey, I thought someone might get something out of it:

    public class Thermometer : IHttpHandler
    {
        #region IHttpHandler Members

        public bool IsReusable
        {
            get { return false; }
        }

        public void ProcessRequest(HttpContext context)
        {
            if (context.Request.QueryString["Percent"] != null)
            {
                int Percent = int.Parse(context.Request.QueryString["Percent"]);
                int Max = int.Parse(context.Request.QueryString["Max"]);
                bool Dollar = int.Parse(context.Request.QueryString["Dollars"]) == 1;
                float Pixels=(float)Percent*2.15f;
                Bitmap TempImage = new Bitmap(100, 270);
                Graphics TempGraphics = Graphics.FromImage(TempImage);
                TempGraphics.FillRectangle(Brushes.White, new Rectangle(0, 0, 100, 270));
                Pen TempPen = new Pen(Color.Black);
                Pen RedPen=new Pen(Color.Red);
                TempGraphics.DrawArc(TempPen, 45, 230, 30, 30, 320, 260);
                TempGraphics.DrawLine(TempPen, 49, 235, 49, 20);
                TempGraphics.DrawLine(TempPen, 71, 235, 71, 20);
                TempGraphics.DrawArc(TempPen, 49, 15, 22, 11, 180, 180);
                GreyFloodFill(TempImage);
                FloodFill(TempImage, Percent);
                bool DrawText = true;
                float Amount = Max;
                for (float y = 20.0f; y < 235.0f; y += 10.75f)
                {
                    TempGraphics.DrawLine(TempPen, 49, y, 55, y);
                    if (DrawText)
                    {
                        Font TempFont = new Font("Arial", 8.0f, FontStyle.Bold);
                        if (Dollar)
                        {
                            TempGraphics.DrawString("$" + Amount.ToString(), TempFont, Brushes.Black, 5, y);
                        }
                        else
                        {
                            TempGraphics.DrawString(Amount.ToString(), TempFont, Brushes.Black, 5, y);
                        }
                        DrawText = false;
                    }
                    else DrawText = true;
                    Amount -= ((Max / 100) * 5.0f);
                }

                string etag = "\"" + Percent.GetHashCode() + "\"";
                string incomingEtag = context.Request.Headers["If-None-Match"];

                context.Response.Cache.SetExpires(DateTime.Now.ToUniversalTime().AddDays(1));
                context.Response.Cache.SetCacheability(HttpCacheability.Public);
                context.Response.Cache.SetMaxAge(new TimeSpan(7, 0, 0, 0));
                context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
                context.Response.Cache.SetETag(etag);

                if (String.Compare(incomingEtag, etag) == 0)
                {
                    context.Response.StatusCode = (int)HttpStatusCode.NotModified;
                    context.Response.End();
                }
                else
                {
                    context.Response.ContentType = "image/Gif";
                    TempImage.Save(context.Response.OutputStream, ImageFormat.Gif);
                }
            }
        }

        private void GreyFloodFill(Bitmap TempImage)
        {
            int RedColor = 255;
            for (int y = 20; y <= 235; ++y)
            {
                for (int x = 50; x <= 70; ++x)
                {
                    float Distance = Math.Abs(60 - x);
                    RedColor = (int)(255.0f * (1.0f - (Distance / 30.0f)));
                    TempImage.SetPixel(x, y, Color.FromArgb(RedColor, RedColor, RedColor));
                }
            }
        }

        private void FloodFill(Bitmap TempImage,int Percent)
        {
            if (Percent == 100)
            {
                FillCircle(TempImage, 60, 245, 15);
                FillCircle(TempImage, 60, 20, 10);
                FillRectangle(TempImage, 60, 20, 235);
            }
            else
            {
                FillCircle(TempImage, 60, 245, 15);
                FillRectangle(TempImage, 60, (int)(235.0f - ((float)Percent * 2.15f)), 235);
            }
        }

        private void FillRectangle(Bitmap TempImage, int x, int y1,int y2)
        {
            int MaxDistance=10;
            for (int i = x - MaxDistance; i < x + MaxDistance; ++i)
            {
                for (int j = y1; j < y2; ++j)
                {
                    float Distance = (float)Math.Abs((i - x));
                    int RedColor = (int)(255.0f * (1.0f - (Distance / (2.0f * MaxDistance))));
                    TempImage.SetPixel(i, j, Color.FromArgb(RedColor, 0, 0));
                }
            }
        }

        private void FillCircle(Bitmap TempImage, int x, int y, int MaxDistance)
        {
            for (int i = x - MaxDistance; i < x + MaxDistance; ++i)
            {
                for (int j = y - MaxDistance; j < y + MaxDistance; ++j)
                {
                    float Distance = (float)Math.Sqrt(((j - y) * (j - y)) + ((i - x) * (i - x)));
                    if (Distance < MaxDistance)
                    {
                        int RedColor = (int)(255.0f * (1.0f - (Distance / (2.0f * MaxDistance))));
                        TempImage.SetPixel(i, j, Color.FromArgb(RedColor, 0, 0));
                    }
                }
            }
        }

        #endregion
    }

The code above is a handler that takes in a Percent (percent of the graph to show as red), Max (maximum value), and Dollars value (Whether this is a number or dollar amount). But in return it creates a decent looking graph, as you can see below.

I mean it isn't perfect, but it works... Anyway, try it out, leave feedback, and happy coding.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 6/11/2009 at 11:48 AM
Tags: , , ,
Categories: ASP.Net | C#
Post Information: Permalink | Comments (2) | Post RSSRSS comment feed

Comments

AQEEL Australia

Wednesday, November 25, 2009 6:12 PM

AQEEL

Hi There, just want to say awesome, at least i can know how to work with graphics, just one question how do i call it?

AQEEL Australia

Wednesday, November 25, 2009 7:05 PM

AQEEL

use like this


in Default.aspx on load event  type following

Thermometer tm = new Thermometer();
tm.ProcessRequest(HttpContext.Current);

and call default.aspx?Percent=50&Max=100&Dollars=5000

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading