The C1Chart control supports built-in grouping and aggregation. This allows you to display summarized data in a chart without the extra work of grouping the data yourself. In this blog post I’ll show you two ways you can take advantage of the built-in grouping and aggregation features found in ComponentOne Chart for WPF, Silverlight, Windows Phone and WinRT XAML.

Data Series Aggregation


The C1Chart control can automatically group and aggregate each data series into a single plotted value by just setting one property. This action combines all values for a single series into one value using one of the supported aggregation functions (sum, count, average, min, max, variance, standard deviation, etc).

Just set the Aggregate property on the C1Chart control to apply the grouping for all series. For example, if we have a chart with four data series and we set the Aggregate property to Sum, the result would look something like this:

C1Chart_Aggregates

This might look familiar because I’ve blogged about it before. For a full sample, with more details on this feature check out my previous blog post here: http://our.componentone.com/2010/03/17/whats-new-chart-aggregates/

Custom Grouping


The C1Chart control also allows custom aggregation on any data series. By defining your own custom function for the AggregateGroupSelector property, the C1Chart control can group your data however you would like. For instance, you can provide grouping on a date field to summarize values per month or year. You can even set up your own value ranges and categories to group data points.

For this tutorial let me walk you through grouping a chart on a date field.

First, I’ve added a C1Chart control to my page and cleared out the default data. In code I’ve generated a collection of items to populate my chart.


Random rnd = new Random();
ObservableCollection<SampleItem> _items = new ObservableCollection<SampleItem>();
for(int i = 0; i < 400; i++)
{
_items.Add(new SampleItem { Value = rnd.Next(0, 100), Date = DateTime.Now.AddDays(i) });
}


My business object in this case, SampleItem, is a very simple class that just has two properties: Value (double) and Date (DateTime). Next, I’ve configured my XYDataSeries to be bound to this collection of items.


// configure data series
var ds = new XYDataSeries()
{
ItemsSource = _items,
ValueBinding = new Binding("Value"),
XValueBinding = new Binding("Date"),
Aggregate = Aggregate.Sum,
AggregateGroupSelector = GroupSelectorByDate,
Label = "Sales"
};


Notice two key properties that I’ve set above. The Aggregate property determines the aggregation function to be used by the chart. In this case I’ve selected Sum which will combine my values into a complete total. The AggregateGroupSelector property has been set to a function that will provide the grouping selector key to my data series. Before I explain this function, let me add this series to the chart and configure it to display dates along the X-Axis.


// configure chart
c1Chart1.BeginUpdate();
c1Chart1.ChartType = ChartType.Column;

// add data series
c1Chart1.Data.Children.Add(ds);

// use time axis with specific formatting
c1Chart1.View.AxisX.IsTime = true;
c1Chart1.View.AxisX.AnnoFormat = "yyyy";
c1Chart1.View.AxisX.UseExactLimits = true;

// apply some style
c1Chart1.View.AxisX.MajorGridStrokeThickness = 0;
c1Chart1.View.AxisY.MajorGridFill = new SolidColorBrush(Colors.LightGray);
c1Chart1.EndUpdate();


Notice that none of the code above is specific to the grouping feature, but when displaying dates along the X-Axis it’s required that you set the IsTime property to true. I’ve also formatted my axis labels to display the full year which is best since I’ll be grouping by year.

Finally, I’ve defined the GroupSelectorByDate function as seen below. This function gets called for every data point and it’s in here that you will determine the group in which the point belongs. Depending on your data source your function may look differently, but if you are grouping by DateTime information then this is a great starting point.


double GroupSelectorByDate(double x, double y, object o)
{
// return year as double
DateTime dt = DateTime.FromOADate(x);

// to group by year we return the dates year
// also set the AnnoFormat to "yyyy"
return new DateTime(dt.Year, 1, 1).ToOADate();

}


The group selector function will always have 3 parameters and return a double. Data points that belong in the same group should return the same value from this function. In my sample, since I am grouping by Year, I simply return a new DateTime value set to the first date of the year. So that way every data point that occurs in 2013 will return the same date value (as a double) from this function, and therefore be put into the same group. And wa-la I have accomplished grouping my data in the chart.

Chart_Grouping1

Now let’s say you wanted to group by Month as well. You just have to modify two lines of code. In the GroupSelectorByDate function include the data point’s month in the returned date value.


double GroupSelectorByDate(double x, double y, object o)
{
// return year as double
DateTime dt = DateTime.FromOADate(x);

// to group by month we return the date's year and month
// also set the AnnoFormat to "MM/yyyy"
return new DateTime(dt.Year, dt.Month, 1).ToOADate();

}


And then modify the annotation format to display months properly on the X-Axis.


c1Chart1.View.AxisX.AnnoFormat = "MM/yyyy";


Chart_Grouping3

Download the source for this sample here.

Conclusion


Grouping is a great way to summarize your data and see results more quickly. To see the real benefit, imagine if we were to plot the same data without grouping the chart would look like the following:

Chart_Grouping4

Of course, grouping is nothing new, and you can always group the data before loading it into the chart. But now that this feature is more built-in to the C1Chart control, it’s easier to provide summarized views of your data. You can also provide custom grouping logic for string-based categories, which I will save for another topic. In the mean-time you can find more Grouping and Aggregation samples included in our Chart Samples collection.