0

I have just created a simple windows form to display some data from a MySql table.

What I would like to know is how would I go about displaying this data graphically using some dials and a history graph of data.

This is what I have so far... When you click the button it starts reading and displaying the data in 2 TextBoxes. When you click the button again it stops.

I worked out how to add line graphs, still need to know how to add "dials instead of just TextBoxes...

Worked it out using aGauge...

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MySql.Data.MySqlClient;

namespace WindowsFormsApplication11
{
    public partial class Form1 : Form
    {
        MySqlConnection mcon = new MySqlConnection("Server=www.inshome.net.au;Port=3306;Database=wordpress;Uid=root;password=********");
        MySqlCommand mcd;
        MySqlDataReader mdr;
        string s;

        public Form1()
        {
            InitializeComponent();
        }

        private void getTemp_Click(object sender, EventArgs e)
        {
            // Toggle the timer's enabled state
            timer1.Enabled = !timer1.Enabled;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {
                mcon.Open();
                s = "SELECT time, dht22temp, dht22humidity FROM shed ORDER BY time DESC LIMIT 1";
                mcd = new MySqlCommand(s, mcon);
                mdr = mcd.ExecuteReader();
                if (mdr.Read())
                {
                    shedTemp.Text = mdr.GetString("dht22temp");
                    shedHumidity.Text = mdr.GetString("dht22humidity");
                    aGauge1.Value = float.Parse(mdr.GetString("dht22temp"));
                    aGauge2.Value = float.Parse(mdr.GetString("dht22humidity"));
                    this.chart1.Series["Temp"].Points.AddXY(mdr.GetString("time"), mdr.GetString("dht22temp"));
                    this.chart2.Series["Humidity"].Points.AddXY(mdr.GetString("time"), mdr.GetString("dht22humidity"));
                }
                else
                {
                    MessageBox.Show("NO DATA");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                mdr.Close();
                mcon.Close();
            }
        }
    }
}
John Wood
  • 1
  • 2
  • See [here](http://stackoverflow.com/questions/767999/random-number-generator-only-generating-one-random-number?rq=1) for how to draw a rotated line or consider a Pie chart. Other than that you question is far too broad, I'm afraid! – TaW Jul 04 '16 at 07:03
  • Thanks, ill try to explain better. What I mean is I would like to have 2 dials like speedometers with a moving needle displaying the current (in this case) Temperature and Humidity. Hope this helps. – John Wood Jul 04 '16 at 12:23

1 Answers1

0

There is nothing in the VS toolbox that will do that for you.

So you'll either have to look for a library, or workaround with something less graphical, like a text display that is styled nicely or with a totally twisted Pie Chart. Or you have to make it yourself.

This is an example that should get you started:

enter image description here

class DialLabel : Label
{
    public DialLabel()
    {
        AutoSize = false;
        NeedleColor = Color.Red;
        NeedleWidth = 3f;
    }

    public Color NeedleColor { get; set; }
    public float NeedleWidth { get; set; }
    public string Format { get; set; }

    public decimal MaxValue { get; set; }
    public decimal Value { get; set; }
    float angle { get { return 180f / 100f * (float)(MaxValue - Value); } }

    protected override void OnPaint(PaintEventArgs e)
    {
        Point center = new Point(Width / 2, (Height - 25)); // 25 pixels for text
        Rectangle textbox = new Rectangle(1, Height - 25, Width, 25);
        TextRenderer.DrawText(e.Graphics, Value.ToString(Format), Font,
                              textbox, ForeColor, BackColor);
        float nx = Width / 2f + 
                  (Width / 2f - 2) * (float)Math.Cos(angle * Math.PI / 180f);
        float ny = (Height - 25) - 
                   (Width / 2f - 2) * (float)Math.Sin(angle * Math.PI / 180f);

        using (Pen pen = new Pen(NeedleColor, NeedleWidth))
            e.Graphics.DrawLine(pen, center.X, center.Y, nx, ny);
    } 
}

The dial label exposes several properties you can use for basic styling. Set the Text to String.Empty and pick a nice Image.

If have set the Format to "##0 km/h" and changed the ForeColor to white and the BackColor to transparent.

You can change many details directly, all the others when you have studied the code..

To use it you add the class to your project, compile and add it from the top of the toolbox to your form.

To change a value use something like this:

private void trackBar1_Scroll(object sender, EventArgs e)
{
    dialLabel1.Value = trackBar1.Value;
    dialLabel1.Invalidate();
}
TaW
  • 53,122
  • 8
  • 69
  • 111
  • I love this very cool, thanks heaps. I have one question thou, how do I add the class to the project in Visual Studio 2015. I literally just started using VS and c# 2 days ago. Has been a steep learning curve, but lots of fun and very rewarding when you get it to work. Would be good to learn how to make my own classes rather than just using someone else's. As I have with the aGauge.dll I found, which works great thou and was easy for a beginner like me. – John Wood Jul 04 '16 at 15:29
  • You would copy the code into a a new class you add to your project. (right-click project: Add-New-Class ) give it the name DialLabel and add two using clauses for Winforms and Drawing. (See any form code). Compile and it appears in the Toolbox. Now you can drop it on a form.. – TaW Jul 04 '16 at 15:55
  • Or you could copy the code into your form class, __right before the very last curly__. Compile,etc.. – TaW Jul 04 '16 at 15:57