in
Forums
Blogs
DevExpress.com
Client Center
Support Center
DevExpress Channel

Gary's Blog

XPO – Charting Local Weather Conditions #2

In the last post on this topic I showed you how to pull down weather information from your local METAR station and persist it using XPO. In this post we’ll go ahead and use that persisted information to graph some interesting weather data.

First thing we’re going to do is to add a new win forms project to our solution to provide a front end for our graphing application. We’ll add folders for Helpers, Model and Views too:

image

After that we’ll start the coding by pointing XPO at the Access database we created in the last post. We’ll do this in the form load event:

private void MainView_Load(object sender, EventArgs e)
{
    //GS - Connect to the access database created earlier
    XpoDefault.ConnectionString =
        AccessConnectionProvider.GetConnectionString("pathToYourAccessDatabaseFile");
}

Next we’ll create a UI that will allows us to graph three interesting pieces of weather data; wind speed by direction, temperature fluctuation throughout a day and the prevailing wind direction for this area:

image

Starting with wind speed by direction, what we’ll do is handle the button click event:

private void btnNorth_Click(object sender, EventArgs e)
{
    //GS - Display northerly wind speeds
    DisplayWindSpeedByDirectionWithTitle("Northerly Wind Speeds", "N");
}

by calling a method to display the data:

private void DisplayWindSpeedByDirectionWithTitle(string title, string direction)
{
    //GS - Get all the Northerly wind direction reports
    XPQuery<Report> reportQuery = new XPQuery<Report>(XpoDefault.Session);

    var reports = from r in reportQuery
                  where r.WindDirection.StartsWith(direction)
                  select r;

    //GS - Ask a helper method to create a chart from this info
    ChartControl chart = ChartHelper.CreateBarChartFromLinqResult("WindSpeed", "TimeStamp", title, reports);

    //GS - Ask a helper method to display this chart
    ViewHelper.DisplayChart(chart);
}

This method will firstly use a linq statement to get all the weather reports where the wind direction starts with the required direction: “N” for North; “S” for South; etc. The next thing it will do is call a helper method, passing in the chart title, the qualitative and quantitative properties of the Report object and the result of the linq query. Lastly, this method then calls another helper method in order to display the chart returned by the first helper method.

Let’s have a look at this first helper method:

public static ChartControl CreateBarChartFromLinqResult(
    string valueMember, 
    string dataMember, 
    string title, 
    IQueryable<Report> reports)
{
    ChartControl chart = new ChartControl();
    chart.Titles.Add(new ChartTitle { Text = title });
    chart.Legend.Visible = false;

    //GS - Create an empty Bar series and add it to the chart.
    Series series = new Series(title, ViewType.Bar);
    chart.Series.Add(series);

    //GS - Supply the data
    series.DataSource = reports.ToList<Report>();

    //GS - Bind the data
    series.ArgumentScaleType = ScaleType.Qualitative;
    series.ArgumentDataMember = dataMember;
    series.ValueScaleType = ScaleType.Numerical;
    series.ValueDataMembers.AddRange(new string[] { valueMember });

    //GS - Dock the chart into its parent
    chart.Dock = DockStyle.Fill;

    //GS - Return the chart
    return chart;
}

This method is fairly simple, all it does is create a new chart object and add a series to it. We then attach our linq results as the data source and then tell the chart how to bind to that data. Finally, we set the dock style to fill and return the chart to the calling method.

The second helper method is simpler still:

public static void DisplayChart(ChartControl chart)
{
    ChartViewer viewer = new ChartViewer();
    viewer.Controls.Add(chart);
    viewer.Show();
}

It takes in a chart object and instantiates a ChartViewer form before adding the chart to the form’s controls and then showing the form.

So having explained how we do it, let’s have a look at the results, pressing the “North” button yields this chart:

image

The remaining “South”, “East” and “West” buttons are a repeat of the same pattern so there is no point in going over those.

The next thing we are going to look at is charting the temperature fluctuations throughout the day. To do this we select a date and press the “Chart” button:

image

The event handler for the “Chart” button is shown below:

private void bntChartWindSpeedByDay_Click(object sender, EventArgs e)
{
    //GS - Get the selected data
    DateTime target = dateTimePicker1.Value;
    
    XPQuery<Report> reportQuery = new XPQuery<Report>(XpoDefault.Session);

    var reports = from r in reportQuery
                  where r.TimeStamp.Date == target.Date
                  select r;            

    //GS - If there is no matching data for the target date then we're done
    if (reports.Count<Report>() < 1)
        return;

    //GS - Ask a helper method to create a chart from this info
    ChartControl chart = ChartHelper.CreateBarChartFromLinqResult(
        "Temperature", "TimeStamp", 
        String.Format("Temperatures for: {0}", target.Date.ToLongDateString()), 
        reports);

    //GS - Ask a helper method to display this chart
    ViewHelper.DisplayChart(chart);
}

As you can see, we follow a similar pattern to that already discussed, whereby we execute a linq query against the XPO source, passing the result to a helper method which constructs and returns a chart object and we then pass that chart object to another helper function which displays the chart. The result of selecting a date and pressing the “Chart” button is shown below:

image

The last interesting piece of information that we are going to graph is the prevailing wind direction. The event handler for the “Show Prevailing Wind Direction” button is shown below:

private void btnMeanWindDirection_Click(object sender, EventArgs e)
{
    //GS - Fetch all the reports
    XPQuery<Report> reportQuery = new XPQuery<Report>(XpoDefault.Session);

    var reports = from r in reportQuery
                  select r;

    //GS - Ask a helper method to create a pie chart of the directionCounts
    ChartControl chart = ChartHelper.CreateWindDirectionPieChart(reports);

    //GS - Ask a helper method to display this chart
    ViewHelper.DisplayChart(chart);
}  

You will recognise this now familiar pattern of executing a linq statement and then passing the result to a helper method to construct and return a chart object before passing that chart object, in turn, to another helper method to display the chart. The only difference this time is the helper method which constructs the chart is different, let’s take a look at it now:

public static ChartControl CreateWindDirectionPieChart(IQueryable<Report> reports)
{
    ChartControl chart = new ChartControl();
    chart.Titles.Add(new ChartTitle { Text = "Prevailing Wind Direction" });
    chart.Legend.Visible = true;

    //GS - Create an empty Bar series and add it to the chart.
    Series series = new Series(String.Empty, ViewType.Pie3D);
    series.LegendPointOptions.PointView = PointView.ArgumentAndValues;
    series.PointOptions.ValueNumericOptions.Format = NumericFormat.Percent;
    chart.Series.Add(series);

    //GS - Supply the data
    List<WindDirectionCount> directionCounts = new List<WindDirectionCount>();
    directionCounts.Add(
        new WindDirectionCount
        {
            Direction = "North",
            Count = reports.Count<Report>(x => x.WindDirection.StartsWith("N"))
        });

    directionCounts.Add(
        new WindDirectionCount
        {
            Direction = "South",
            Count = reports.Count<Report>(x => x.WindDirection.StartsWith("S"))
        });

    directionCounts.Add(
        new WindDirectionCount
        {
            Direction = "East",
            Count = reports.Count<Report>(x => x.WindDirection.StartsWith("E"))
        });

    directionCounts.Add(
        new WindDirectionCount
        {
            Direction = "West",
            Count = reports.Count<Report>(x => x.WindDirection.StartsWith("W"))
        });


    series.DataSource = directionCounts;

    //GS - Bind the data
    series.ArgumentScaleType = ScaleType.Qualitative;
    series.ArgumentDataMember = "Direction";
    series.ValueScaleType = ScaleType.Numerical;
    series.ValueDataMembers.AddRange(new string[] { "Count" });

    //GS - Dock the chart into its parent
    chart.Dock = DockStyle.Fill;

    //GS - Return the chart
    return chart;
}

This helper method is similar, but a little different, to the previous one. Again it creates a chart object and adds a series to it. The series is a little different this time though:

//GS - Create an empty Pie series and add it to the chart.
Series series = new Series(String.Empty, ViewType.Pie3D);
series.LegendPointOptions.PointView = PointView.ArgumentAndValues;
series.PointOptions.ValueNumericOptions.Format = NumericFormat.Percent;
chart.Series.Add(series);

As you can see we are creating a pie chart this time and so we use the PointView.ArgumentAndValues enum to specify that we want to show the wind direction as well as the values and the NumericFormat.Percent enum to specify that we want to show the values as a percentage of the total.

We then go on to count the number of weather reports that state the wind was from a particular direction (N, NNW all count as North etc.) and we go ahead and store this information in a list of objects we created for that purpose. These objects are very simple in nature and they are defined like so:

using System;

namespace XPOWeather2
{
    public class WindDirectionCount
    {
        public string Direction { get; set; }
        public int Count { get; set; }        
    }
}

Then we set the data and bind to is as before, specifying the qualitative and the quantitative properties, before finishing by asking the same helper method to display the chart. The result of all this is shown below:

image

As you can see, the prevailing wind direction in this part of the world is shown as westerly (which it actually is!).

Well that about wraps it up for this post, ‘til the next time, happy XPOing!

Published Nov 17 2009, 05:21 PM by Gary Short (Developer Express)
Filed under:
Technorati tags: XPO

Comments

 

Ralph Hall said:

Excellant article. Is the source available?

November 17, 2009 9:17 PM
 

Gary Short (Developer Express) said:

Hello Ralph, glad you liked the post. As for the code, well as long as you remember that the code is a demonstration of what you can do with XPO and not a good demo of how to architect an application (there's a lot of code polluting the event handlers for example) then I don't see any harm in making it public.

November 18, 2009 2:48 PM
 

Saif Khan said:

Yeah! We need to see more with XPO in order to convince more users. At first I was a bit scared jumping into another piece of technology after reading the online-help. Seeing small samples like this is a bit more convencing. Keep them coming!!

November 18, 2009 4:15 PM
 

Ralph Hall said:

Thanks Gary. I look forward to using it as an example of XPO and the charting options.

Let us know where to download it.

November 18, 2009 8:34 PM

Leave a Comment

(required)  
(optional)
(required)  
Verification code: Required
   
Add
Copyright © 1998-2010 Developer Express Inc.
ALL RIGHTS RESERVED