I definitely hinted at a bit more visual of an example today in my last blog post in the Telerik Windows Phone 7 MVVM Series – so here we are today with the beta of RadChart for Windows Phone and a couple of examples of how these charts aren’t only insanely fast but easy to use for us developers. We’ve been working with MVVM for a while now, so rather than taking any time to discuss the benefits of this approach or any related goodness, I want to jump right into the viewmodel first so that we can spend more time talking about the fun stuff – the Xaml!
Step 1 – Making Some Data (ViewModel Style)
The quickest way to get data into RadChart is through doubles – a number format we all know and love and that is quite easy to demo. For the two scenarios I have in mind I will need two sets of data that look pretty similar, just with separate values. We are going to name them TestList and TestList2 and populate the lists on-demand with some random data. The full ViewModel is visible here – as you can see, no real surprises:
public
class
RadChartViewModel : ViewModelBase
{
private
Random rnd;
private
List<Double> _testList;
public
List<Double> TestList
{
get
{
if
(_testList ==
null
)
MakeTestList();
return
_testList;
}
set
{
if
(value != _testList)
{
_testList = value;
RaisePropertyChanged(
"TestList"
);
}
}
}
private
List<Double> _testList2;
public
List<Double> TestList2
{
get
{
if
(_testList2 ==
null
)
MakeTestList2();
return
_testList2;
}
set
{
if
(value != _testList2)
{
_testList2 = value;
RaisePropertyChanged(
"TestList2"
);
}
}
}
public
RadChartViewModel()
{
rnd =
new
Random();
}
void
MakeTestList()
{
_testList =
new
List<
double
>();
for
(
int
x = 0; x < 20; x++)
{
TestList.Add(Math.Floor(rnd.NextDouble() * 95));
}
}
void
MakeTestList2()
{
_testList2 =
new
List<
double
>();
for
(
int
x = 0; x < 20; x++)
{
TestList2.Add(Math.Floor(rnd.NextDouble() * 90));
}
}
}
Step 2 – Xaml Setup
Now that we have some data, we pull in our viewmodel and set the datacontext so that we can access our test lists, then since we want to show a couple of charts I’m going to add a Pivot control to the page to allow for some quick navigation between charts. Right now my Xaml is looking a bit like this:
<
phone:PhoneApplicationPage.Resources
>
<
viewmodels:RadChartViewModel
x:Key
=
"xRadChartViewModel"
/>
</
phone:PhoneApplicationPage.Resources
>
<
Grid
x:Name
=
"LayoutRoot"
DataContext
=
"{StaticResource xRadChartViewModel}"
Background
=
"Transparent"
>
<
controls:Pivot
Title
=
"{StaticResource xAppTitle}"
>
<
controls:PivotItem
Header
=
"tbd"
>
<
Grid
>
</
Grid
>
</
controls:PivotItem
>
<
controls:PivotItem
Header
=
"tbd"
>
<
Grid
>
</
Grid
>
</
controls:PivotItem
>
</
controls:Pivot
>
</
Grid
>
Before getting into my chart, I’m also going to add these two namespace references so I can handle chart elements as well as items from our charting engine:
xmlns:telerikChart="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Chart"
xmlns:chartEngine="clr-namespace:Telerik.Charting;assembly=Telerik.Windows.Controls.Chart"
Now let’s make a chart!
Step 3 – Single Series Chart
When working with RadChart for Windows Phone 7, there are a fair number of options for how we want to display our data based on what type of data we need to display. In our case, we know we are going to want a Linear YAxis, a Categorical XAxis, and a Line Series.
Also of note, you’ll notice in telerikChart we can choose either RadCartesianChart or RadPieChart – we aren’t displaying any pies today, but you’ll see those a little down the line, so instead we’re using RadCartesianChart for displaying our linear, categorical, or datetime data. So our starting chart Xaml will look like so:
<
telerikChart:RadCartesianChart
>
</
telerikChart:RadCartesianChart
>
Adding an XAxis, we want to set two quick properties since I know I have 20 data points coming in and will want my labels displaying nicely. LabelStep allows us to determine how often an axis label appears, while LabelOffset allows us to modify where the axis labels will start displaying. In this example, without LabelOffset we would start at 1 and see only odd numbers, but even numbers look so much nicer:
<
telerikChart:RadCartesianChart.XAxis
>
<
telerikChart:CategoricalAxis
LabelStep
=
"2"
LabelOffset
=
"1"
/>
</
telerikChart:RadCartesianChart.XAxis
>
For our YAxis, we know the values will range between two set marks (in our case, 0 and 100), so we can pretty easily utilize a LinearAxis to plot these values. All I’ve got to set is my Maximum value to ensure the chart will render how I want it to in my app:
<
telerikChart:RadCartesianChart.YAxis
>
<
telerikChart:LinearAxis
Maximum
=
"100"
/>
</
telerikChart:RadCartesianChart.YAxis
>
Last but certainly not least, I need a series to display my data! I’m going for a simple LineSeries in this case with a Stroke based on my phone theme choice and the ItemsSource bound to our TestList that we know exists in our ViewModel:
<
telerikChart:RadCartesianChart.Series
>
<
telerikChart:LineSeries
Stroke
=
"{StaticResource PhoneAccentBrush}"
StrokeThickness
=
"2"
ItemsSource
=
"{Binding TestList}"
/>
</
telerikChart:RadCartesianChart.Series
>
Our end result, taken straight from the emulator, looks pretty cool already:
Now that we’ve conquered a single series chart, how much tougher will it be to make a multi-series chart? Glad you asked!
Step 4 – Per Your Request, Multi-Series MVVM Chart
This is actually going to be pretty easy to accomplish, but since there are a lot of display options within our charting solution, I’m going to do some things slightly different just to show them off. :)
We start off with the same RadCartesianChart, except this time I’m not going to use LabelStep or LabelOffset, instead I want to display every value of the 20, but for this I need a nice way to ensure all labels are readable. RadChart team to the rescue, we’ve got a property just for that called LabelFitMode, allowing us to utilize MultiLine, Rotated, or no fit mode at all. I’m opting for MultiLine here so that the chart will intelligently display my labels (see the picture a little ways down for proof):
<
telerikChart:RadCartesianChart
>
<
telerikChart:RadCartesianChart.XAxis
>
<
telerikChart:CategoricalAxis
LabelFitMode
=
"MultiLine"
/>
</
telerikChart:RadCartesianChart.XAxis
>
</
telerikChart:RadCartesianChart
>
The YAxis will be the same as above (still working with data going between 0 and 100), so nothing new there:
<
telerikChart:RadCartesianChart.YAxis
>
<
telerikChart:LinearAxis
Maximum
=
"100"
/>
</
telerikChart:RadCartesianChart.YAxis
>
The real fun comes into play when we want to add additional series. As opposed to what you saw above where I set the RadCartesianChart.Series, I’m instead going to start dropping my series items into the chart like you would content items. Don’t worry, RadChart is intelligent enough to know what you want to do here. ;)
For the first series, I’m using the same exact line series as above to set our baseline for display, since we know the line series will display nicely. For the second series, however, we want to display a bar chart to give a nice comparison between the data. The BarSeries is easily customizable, so in my case I want some semi-transparent items with rounded corners:
<
telerikChart:LineSeries
Stroke
=
"{StaticResource PhoneAccentBrush}"
StrokeThickness
=
"2"
ItemsSource
=
"{Binding TestList2}"
/>
<
telerikChart:BarSeries
ItemsSource
=
"{Binding TestList}"
>
<
telerikChart:BarSeries.PointTemplate
>
<
DataTemplate
>
<
Rectangle
RadiusX
=
"5"
RadiusY
=
"5"
>
<
Rectangle.Fill
>
<
SolidColorBrush
Color
=
"OrangeRed"
Opacity
=
".4"
/>
</
Rectangle.Fill
>
</
Rectangle
>
</
DataTemplate
>
</
telerikChart:BarSeries.PointTemplate
>
</
telerikChart:BarSeries
>
As you can see, putting the data into the series is just as easy as working with the LineSeries, but thanks to the ease of use built into this control, setting my PointTemplate was a breeze. Looking at our emulator now, we can see both our series being displayed as well as that smart multi-line label in action:
And to get this running, we add another line into our MainPageViewModel to make the RadChart example browsable:
tempCollection.Add(
new
MyMVVMItem(3,
"RadChart"
,
"/Pages/RadChartMVVM.xaml"
,
"Data Viz"
));
Now I think you might be starting to get the point here that the RadControls for Windows Phone are pretty easy to use, very powerful in what they give you for your phone applications, and were built by some pretty smart people in that they fit in with the MVVM pattern flawlessly.
As always, check out the latest download of the source for this series (and be sure you’re working with the latest RadControls for Windows Phone Beta to get the charting bits!) and stay tuned for more!
Evan Hutnick works as a Developer Evangelist for Telerik specializing in Silverlight and WPF in addition to being a Microsoft MVP for Silverlight. After years as a development enthusiast in .Net technologies, he has been able to excel in XAML development helping to provide samples and expertise in these cutting edge technologies. You can find him on Twitter @EvanHutnick.