GDI+ Gauges

Here are some simple gauges I wrote in C# using GDI+

Posted on May 19, 2016 10:00PM

I was recently tasked with building a custom gauge for a report. Since I could not find an open source gauge that looked the way I needed it to I thought I would try my hand at GDI+. I have provided the source code below for the three gauges I created as well as added them to a RESTful service for incorporating them into my own sites.

I make no claim to be a GDI+ master which is why I am using an image for the needle of the range gauge since I could not figure out how to draw it in GDI+. If anyone could help me with this, message me.

Enjoy!

Percent Gauge
Percent Gauge
Range Gauge
Range Gauge
Percent Bar Gauge
Percent Bar Gauge

Percent Gauge REST Definition

http://logging.andyworks.com/PercentGauge/{Percent}/{Size in pixels (MAX 500)}/{Color (Name: green OR Hex: #00FF00)}

Percent Gauge Example REST URL

         http://logging.andyworks.com/PercentGauge/50/500/green
        

Percent Gauge Code

        public static byte[] PercentGauge(int value, int size, ImageFormat format, Color color)
        {
            if (size > 500) size = 500;
            using (var bmp = new Bitmap(500, 500))
            {
                bmp.SetResolution(300, 300);
                using (var g = Graphics.FromImage(bmp))
                {
                    g.SmoothingMode = SmoothingMode.HighQuality;
                    g.InterpolationMode = InterpolationMode.HighQualityBilinear;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    g.FillEllipse(new SolidBrush(Color.White), new Rectangle(0, 0, 500, 500));
                    g.FillPie(new SolidBrush(Color.LightGray), new Rectangle(20, 20, 460, 460), 0, 360);
                    g.FillPie(new SolidBrush(color), new Rectangle(20, 20, 460, 460), 270F, (float)(value * 3.6));
                    g.FillEllipse(new SolidBrush(Color.White), new Rectangle(125, 125, 250, 250));
                    g.DrawEllipse(new Pen(Color.LightGray, 10), new Rectangle(140, 140, 220, 220));
                    g.DrawEllipse(new Pen(Color.LightGray, 10), new Rectangle(5, 5, 490, 490));
                    var sf = new StringFormat
                    {
                        Alignment = StringAlignment.Center,
                        LineAlignment = StringAlignment.Center
                    };
                    g.TextRenderingHint = TextRenderingHint.AntiAlias;
                    g.DrawString(value + "%", new Font(new FontFamily("Impact"), 20, FontStyle.Regular), new SolidBrush(color),
                        new PointF(250, 250), sf);
                }
                using (var ms = new MemoryStream())
                {
                    if (size == 500)
                    {
                        bmp.Save(ms, format);
                        return ms.ToArray();
                    }
                    var newBmp = new Bitmap(bmp, size, size);
                    bmp.SetResolution(300, 300);
                    newBmp.Save(ms, format);
                    return ms.ToArray();
                }
            }
        }

Range Gauge REST Definition

http://logging.andyworks.com/RangeGauge?Value={Value}&size={Size in pixels (MAX 500)}&Label={Optional text to display at bottom of gauge}

Array of ranges: MinValue - Minimum value of range, MaxValue - Maximum value of range, Color - Color of range (Name: green OR Hex: #00FF00)

Range Gauge Example REST URL

        http://logging.andyworks.com/RangeGauge?Value=150&size=500&Label=Label%20Here&
        Ranges[0].MinValue=0&Ranges[0].MaxValue=100&Ranges[0].Color=green&
        Ranges[1].MinValue=100&Ranges[1].MaxValue=200&Ranges[1].Color=yellow&
        Ranges[2].MinValue=200&Ranges[2].MaxValue=300&Ranges[2].Color=red
        

Range Gauge Code

        public static byte[] RangeGauge(GaugeData data, int size, ImageFormat format)
        {
            var min = data.Ranges.Min(t => t.MinValue);
            var max = data.Ranges.Max(t => t.MaxValue);
            var rangeTotal = max - min;
            var value = data.Value;
            var valueAngle = (((value - min) / rangeTotal) * 270) + 135;
            using (var bmp = new Bitmap(500, 500))
            {
                bmp.SetResolution(300, 300);
                using (var g = Graphics.FromImage(bmp))
                {
                    g.SmoothingMode = SmoothingMode.HighQuality;
                    g.InterpolationMode = InterpolationMode.HighQualityBilinear;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    var rec = new Rectangle(0, 0, 500, 500);
                    g.FillPie(new SolidBrush(Color.White), rec, 45, 90);
                    var startDeg = 135f;
                    foreach (var item in data.Ranges.OrderBy(o => o.MinValue))
                    {
                        g.FillPie(new SolidBrush(item.TrueColor), rec, startDeg, (float)(((item.MaxValue - item.MinValue) / rangeTotal) * 270));
                        startDeg = (float)(startDeg + (((item.MaxValue - item.MinValue) / rangeTotal) * 270));
                    }
                    g.FillEllipse(new SolidBrush(Color.White), new Rectangle(125, 125, 250, 250));
                    //DRAW Needle
                    using (var needle = Graphics.FromImage(bmp))
                    {
                        needle.TranslateTransform(250, 250);
                        needle.RotateTransform((float)valueAngle);
                        needle.TranslateTransform(-105, -105);
                        var myAssembly = Assembly.GetExecutingAssembly();
                        var myStream = myAssembly.GetManifestResourceStream("LoggingService.Needle.png");
                        needle.DrawImage(Image.FromStream(myStream), new PointF(0, 0));
                    }
                    g.FillEllipse(new SolidBrush(Color.White), new Rectangle(175, 175, 150, 150));
                    var sf = new StringFormat
                    {
                        Alignment = StringAlignment.Center,
                        LineAlignment = StringAlignment.Center
                    };
                    g.TextRenderingHint = TextRenderingHint.AntiAlias;
                    g.DrawString(value.ToString(), new Font(new FontFamily("Impact"), 18, FontStyle.Regular), new SolidBrush(Color.Black),
                        new PointF(250, 250), sf);
                    g.DrawString(data.Label, new Font(new FontFamily("Impact"), 12, FontStyle.Regular), new SolidBrush(Color.Black),
                        new PointF(250, 425), sf);
                }
                using (var ms = new MemoryStream())
                {
                    if (size == 500)
                    {
                        bmp.Save(ms, format);
                        return ms.ToArray();
                    }
                    var newBmp = new Bitmap(bmp, size, size);
                    bmp.SetResolution(300, 300);
                    newBmp.Save(ms, format);
                    return ms.ToArray();
                }
            }
        }
    public class GaugeData
    {
        public Range[] Ranges { get; set; }
        public double Value { get; set; }
        public string Label { get; set; }
    }
    public class Range
    {
        public double MinValue { get; set; }
        public double MaxValue { get; set; }
        public string Color { get; set; }
        internal Color TrueColor => (Color) new ColorConverter().ConvertFromString(Color);
    }

Percent Bar Gauge REST Definition

http://logging.andyworks.com/PercentBarGauge/{Percent}/{Pixel Width (MAX 900)}/{Bar Color}/{Background Color}/{Font Color}

Percent Bar Gauge Example REST URL

        http://logging.andyworks.com/PercentBarGauge/50/900/green/lightgray/white
        

Percent Bar Gauge Code

        public static byte[] BarGraph(int percent, int maxWidth, Color barColor, Color fontColor, Color backGroundColor, ImageFormat format)
        {
            using (var bmp = new Bitmap(900, 80))
            {
                var size = (int)(percent * 8.5);
                if (percent < 13)
                    size = 100;
                bmp.SetResolution(300, 300);
                using (var g = Graphics.FromImage(bmp))
                {
                    g.SmoothingMode = SmoothingMode.HighQuality;
                    g.InterpolationMode = InterpolationMode.HighQualityBilinear;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    g.FillRectangle(new SolidBrush(backGroundColor), new Rectangle(0, 0, 900, 80));
                    g.FillRectangle(new SolidBrush(barColor), new Rectangle(0, 0, size, 80));
                    Point[] points = { new Point(size, 0), new Point(size, 80), new Point(size + 50, 40) };
                    g.FillPolygon(new SolidBrush(barColor), points);
                    var sf = new StringFormat
                    {
                        Alignment = StringAlignment.Center,
                        LineAlignment = StringAlignment.Center
                    };
                    g.TextRenderingHint = TextRenderingHint.AntiAlias;
                    g.DrawString(percent + "%", new Font(new FontFamily("Impact"), 12, FontStyle.Regular), new SolidBrush(fontColor), new PointF((size + 50) - 100, 44), sf);
                }
                using (var ms = new MemoryStream())
                {
                    if (maxWidth >= 900)
                    {
                        bmp.Save(ms, format);
                        return ms.ToArray();
                    }
                    var newBmp = new Bitmap(bmp, maxWidth, maxWidth * 80 / 900);
                    bmp.SetResolution(300, 300);
                    newBmp.Save(ms, format);
                    return ms.ToArray();
                }
            }
        }