Getting started with free Metro (Modern UI) charts for Windows 8

Getting started with free Metro (Modern UI) charts for Windows 8

Charts are a part of (probably) all the commercial controls that are being sold for different platforms (WPF, Silverlight, Windows Phone, Windows 8 etc.). Those commercial controls often bring a lot more than just charts and sometimes they cost a lot more than a single, hobby developer can afford. What if you need only to visualize your data using charts and you're low on budget? Try the free Metro (Modern UI) charts.

Free Metro (Modern UI) charts

Free Modern UI charts are available on CodePlex since the beginning of this month. They were written by Torsten Mandelkow for Windows 8, WPF and Silverlight. They are open source (Ms-PL) so you can modify them if needed. The following chart types are available:

  • ColumnChart (ClusteredColumnChart, StackedColumnChart, StackedColumnChart100Percent)
  • PieChart (PieChart and Dognut)
  • BarChart (ClusteredBarChart, StackedBarChart, StackedBarChart100Percent)
  • Doughnut Chart
  • Radial Gauge Chart

This is what they look like in light and dark option:

free Metro (Modern UI) charts light theme

free Metro (Modern UI) charts dark theme

In my opinion they look absolutely amazing. The background changes according to the requested theme, but can be set manually, too.

There's quite a large demo that can be downloaded from CodePlex, but it's huge so I decided to write a small getting started guide. There's also a how-to as a part of the documentation, but it doesn't really work. I documented it here. The charts didn't get rendered, and I followed the how-to step by step. Something was obviously missing, so the solution was to use a NuGet package created by SO user Xyroid.

Getting started - pie, doughnut and gauge charts

Start a new Windows 8 project or use the existing one. Add the charts package over NuGet. Search for "modern ui charts" and go to page 9. Install the nuget package.

nuget

I will be displaying world's largest populations in a chart. So let's create a Population class first:

    public class Population : INotifyPropertyChanged
    {
        private string _name = string.Empty;
        private int _count = 0; 

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
                NotifyPropertyChanged("Name");
            }
        }

        public int Count 
        {
            get
            {
                return _count;
            }
            set
            {
                _count = value;
                NotifyPropertyChanged("Count");
            }

        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

The Population class has a Name and a Count property. The largest populations have been taken from Wolfram Alpha.

Now we can create a simple viewmodel to be used as the page DataContext

    public class MainViewModel
    {
        private readonly ObservableCollection<Population> _populations = new ObservableCollection<Population>();
        public ObservableCollection<Population> Populations
        {
            get
            {
                return _populations;
            }
        }

        public MainViewModel()
        {
            _populations.Add(new Population() { Name = "China", Count = 1340 });
            _populations.Add(new Population() { Name = "India", Count = 1220 });
            _populations.Add(new Population() { Name = "United States", Count = 309 });
            _populations.Add(new Population() { Name = "Indonesia", Count = 240 });
            _populations.Add(new Population() { Name = "Brazil", Count = 195 });
            _populations.Add(new Population() { Name = "Pakistan", Count = 174 });
            _populations.Add(new Population() { Name = "Nigeria", Count = 158 });
        }
    }

In the page code behind we simple set the DataContext to the viewmodel:

    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.DataContext = new MainViewModel();
        }
    }

Now we only need to create the charts in XAML. Add the following chart namespace reference to MainPage.xaml

xmlns:chart="using:De.TorstenMandelkow.MetroChart"  

The XAML code to define a simple PieChart is very simple:

<chart:PieChart ChartSubTitle="Population in millions"  
                ChartTitle="Countries by population">
    <chart:PieChart.Series>
        <chart:ChartSeries DisplayMember="Name"
                            ItemsSource="{Binding Path=Populations}"
                            SeriesTitle="World largest populations"
                            ValueMember="Count" />
    </chart:PieChart.Series>
</chart:PieChart>  

Any chart can have one or more series of data displayed. In this case I used only one. What do all the properties mean?

  • ChartTitle is the main title of the chart
  • ChartSubTitle is the subtitle, displayed in smaller font of course
  • DisplayMember is the name of the property which holds the name of the value
  • ValueMember is the name of the property which holds the value
  • ItemsSource is the source of items for this series.
  • SeriesTitle holds the title of the particular series

The result is a great looking pie chart:

doughnut Metro UI charts

If you wish to use a doughnut instead of a pie chart, just change the chart type, but leave the pie series as the type of series:

<chart:DoughnutChart ChartSubTitle="Population in millions"  
                     ChartTitle="Countries by population"
                     InnerRadiusRatio="0.67">
    <chart:PieChart.Series>
        <chart:ChartSeries DisplayMember="Name"
                           ItemsSource="{Binding Path=Populations}"
                           SeriesTitle="World largest populations"
                           ValueMember="Count" />
    </chart:PieChart.Series>
</chart:DoughnutChart>  

Use the InnerRadiusRation to define the size of the inner circle. The larger the ration, the larger the inner circle is.

doughnut Metro UI charts

You can use the gauge type, too. I changed the background this time manually on purpose.

<chart:RadialGaugeChart ChartSubTitle="Population in millions"  
                        ChartTitle="Countries by population" Background="White">
    <chart:RadialGaugeChart.Series>
        <chart:ChartSeries DisplayMember="Name"
                           ItemsSource="{Binding Path=SmallestDummyPopulations}"
                           SeriesTitle="World smallest populations"
                           ValueMember="Count" />
    </chart:RadialGaugeChart.Series>
</chart:RadialGaugeChart>  

Have in mind that the data I have is not the best for gauge representations, so I created a smaller dummy set to show how they work.

gauge Metro UI charts

Multiple data series displayed in one chart

Now let's expand the viewmodel with the world's smallest populations.

public class MainViewModel  
{
    private readonly ObservableCollection<Population> _populations = new ObservableCollection<Population>();
    public ObservableCollection<Population> Populations
    {
        get
        {
            return _populations;
        }
    }

    private readonly ObservableCollection<Population> _smallestPopulations = new ObservableCollection<Population>();
    public ObservableCollection<Population> SmallestPopulations
    {
        get
        {
            return _smallestPopulations;
        }
    }

    public MainViewModel()
    {
        _populations.Add(new Population() { Name = "China", Count = 1340 });
        _populations.Add(new Population() { Name = "India", Count = 1220 });
        _populations.Add(new Population() { Name = "United States", Count = 309 });
        _populations.Add(new Population() { Name = "Indonesia", Count = 240 });
        _populations.Add(new Population() { Name = "Brazil", Count = 195 });
        _populations.Add(new Population() { Name = "Pakistan", Count = 174 });
        _populations.Add(new Population() { Name = "Nigeria", Count = 158 });

        _smallestPopulations.Add(new Population() { Name = "Pitcairn Islands", Count = 48 });
        _smallestPopulations.Add(new Population() { Name = "Cocos Keeling Islands", Count = 605 });
        _smallestPopulations.Add(new Population() { Name = "Vatican City", Count = 826 });
        _smallestPopulations.Add(new Population() { Name = "Niue", Count = 1000 });
        _smallestPopulations.Add(new Population() { Name = "Tokelau", Count = 1416 });
        _smallestPopulations.Add(new Population() { Name = "Christmas Island", Count = 1462 });
        _smallestPopulations.Add(new Population() { Name = "Norfolk Island", Count = 2141 });
    }
}

Have in mind that the largest populations are, of course, expressed in millions. If we add another series, we get two pie charts instead of one side by side. I also set the width and height of the chart manually.

<chart:PieChart ChartSubTitle="Population in millions" ChartTitle="Countries by population" Width="500" Height="500">  
    <chart:PieChart.Series>
    <chart:ChartSeries DisplayMember="Name"
                       ItemsSource="{Binding Path=Populations}"
                       SeriesTitle="World largest populations"
                       ValueMember="Count" />

    <chart:ChartSeries DisplayMember="Name"
                       ItemsSource="{Binding Path=SmallestPopulations}"
                       SeriesTitle="World smallest populations [e-06]"
                       ValueMember="Count" />
    </chart:PieChart.Series>
</chart:PieChart>  

two pie Metro UI charts

Bar and column charts

Column and bar charts are two very interesting types of charts. Maybe even more exciting for the type of data that I'm displaying in this demo. It's simple to use them instead of pie charts. Let's start with a simple bar chart:

<chart:ClusteredBarChart ChartSubTitle="Population in millions" ChartTitle="Countries by population">  
    <chart:ClusteredBarChart.Series>
        <chart:ChartSeries DisplayMember="Name"
                           ItemsSource="{Binding Path=Populations}"
                           SeriesTitle="World largest populations"
                           ValueMember="Count" />

    </chart:ClusteredBarChart.Series>
</chart:ClusteredBarChart>  

horizontal bar Metro UI charts

And then the column chart, which is easily defined similarly:

<chart:ClusteredColumnChart ChartSubTitle="Population in millions" ChartTitle="Countries by population">  
    <chart:ClusteredColumnChart.Series>
        <chart:ChartSeries DisplayMember="Name"
                           ItemsSource="{Binding Path=Populations}"
                           SeriesTitle="World largest populations"
                           ValueMember="Count" />

    </chart:ClusteredColumnChart.Series>
</chart:ClusteredColumnChart>  

vertical Metro UI charts

In the next post I'll take a deeper dive - to show how to style charts, use tooltips, selections etc.

Igor Ralic

igor ralic

View Comments
Microsoft Certified Solutions Developer: Windows Store Apps in C#