Using OxyPlot With Xamarin.Forms

Those who are working with Xamarin.Forms, know that there is no out-of-the-box support for charts/graphs in Xamarin Forms. If you want to show any data report in the form of charts/graph like Pie, Bar etc., you will have to use third party graph controls like Syncfusion (Some Xamarin pre-built examples use these), Infragistics, or Telerik controls and you have to pay license fees for them.

There is a little known open source plotting library for Xamarin.Forms called OxyPlot. This library is not only free/open source but it’s easy to use too. However, you may have to play around with code samples to understand the working of these graph controls. In this article, we will learn how to use a few of graph options in OxyPlot.

  • As usual, create a new Xamarin.Forms XAML Project.
  • Add the NuGet Package named ‘OxyPlot.Xamarin.Forms’ to all your projects, as shown in the below image.

  • Just like Xamarin.Forms, Oxyplot also needs to be initialized in the platform specific projects so that it can work.

  • Add the following code in MainActivity.cs file of your Android project, just after global::Xamarin.Forms.Forms.Init(this, bundle); line in onCreate method.
    1. OxyPlot.Xamarin.Forms.Platform.Android.PlotViewRenderer.Init();   
  • Similarly, Add the following code in AppDelegate.cs file of your iOS project, just after global::Xamarin.Forms.Forms.Init(); line in FinishedLaunching method.
    1. OxyPlot.Xamarin.Forms.Platform.iOS.PlotViewRenderer.Init();  
  • And in the same way, add the following code in App.xaml.cs file of your UWP project, just after Xamarin.Forms.Forms.Init(e); line in FinishedLaunching method.
    1. OxyPlot.Xamarin.Forms.Platform.UWP.PlotViewRenderer.Init();  
  • Once the Oxyplot component is initialized in all the platform projects of the application, we can use the component in the same way as we use any user control in Xamarin.Forms. For example, the following code is of the file “PieEx.xaml” where we are declaring the Oxyplot component with local namespace and the creating the control of same.
    1. <?xml version="1.0" encoding="utf-8" ?>  
    2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
    3.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
    4.              xmlns:oxy="clr-namespace:OxyPlot.Xamarin.Forms;assembly=OxyPlot.Xamarin.Forms"  
    5.              x:Class="OxyPlotEx.PieEx">  
    6.   <AbsoluteLayout>  
    7.     <oxy:PlotView Model="{Binding PieModel}"  
    8.                   AbsoluteLayout.LayoutBounds="20,0,.9,.9"  
    9.                   AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional" />  
    10.   </AbsoluteLayout>  
    11. </ContentPage>  

    As you can see from the code that the PlotView control requires Model to show the data, that’s why we have bound that property with PieModel which is object of type PlotModel available in OxyPlot Library.

  • The ContentPage shown in previous step is bound with the object of following class, which has three properties named PieModel, AreaModel, BarModel, StackedBarModel all of type PlotModel as this same object is used to bind rest of 3 pages used in the example to show different types of graphs like Area, Stacked Bar, and Normal Comparison Bar. These charts are created using hard coded values in the example, however you can use similar code to show any data you get from Web service or database.
    1. public class OxyExData  
    2.     {  
    3.         public PlotModel PieModel { get; set; }  
    4.         public PlotModel AreaModel { get; set; }  
    5.         public PlotModel BarModel { get; set; }  
    6.         public PlotModel StackedBarModel { get; set; }  
    7.    
    8.         public OxyExData()  
    9.         {  
    10.             PieModel = CreatePieChart();  
    11.             AreaModel = CreateAreaChart();  
    12.             StackedBarModel = CreateBarChart(true,"Stacked Bar");  
    13.             BarModel = CreateBarChart(false"Un-Stacked Bar");  
    14.         }  
    15.         private PlotModel CreatePieChart()  
    16.         {  
    17.             var model = new PlotModel { Title = "World population by continent" };  
    18.    
    19.             var ps = new PieSeries  
    20.             {        
    21.                 StrokeThickness = .25,  
    22.                 InsideLabelPosition = .25,  
    23.                 AngleSpan = 360,  
    24.                 StartAngle = 0  
    25.             };  
    26.    
    27.             // http://www.nationsonline.org/oneworld/world_population.htm  
    28.             // http://en.wikipedia.org/wiki/Continent  
    29.             ps.Slices.Add(new PieSlice("Africa", 1030) { IsExploded = false });  
    30.             ps.Slices.Add(new PieSlice("Americas", 929) { IsExploded = false });  
    31.             ps.Slices.Add(new PieSlice("Asia", 4157));  
    32.             ps.Slices.Add(new PieSlice("Europe", 739) { IsExploded = false });  
    33.             ps.Slices.Add(new PieSlice("Oceania", 35) { IsExploded = false });  
    34.             model.Series.Add(ps);  
    35.             return model;  
    36.         }  
    37.    
    38.         public PlotModel CreateAreaChart()  
    39.         {  
    40.             var plotModel1 = new PlotModel { Title = "AreaSeries with crossing lines" };  
    41.             var areaSeries1 = new AreaSeries();  
    42.             areaSeries1.Points.Add(new DataPoint(0, 50));  
    43.             areaSeries1.Points.Add(new DataPoint(10, 140));  
    44.             areaSeries1.Points.Add(new DataPoint(20, 60));  
    45.             areaSeries1.Points2.Add(new DataPoint(0, 60));  
    46.             areaSeries1.Points2.Add(new DataPoint(5, 80));  
    47.             areaSeries1.Points2.Add(new DataPoint(20, 70));  
    48.             plotModel1.Series.Add(areaSeries1);  
    49.             return plotModel1;  
    50.         }  
    51.    
    52.         private PlotModel CreateBarChart(bool stacked, string title)  
    53.         {  
    54.             var model = new PlotModel  
    55.             {  
    56.                 Title = title,  
    57.                 LegendPlacement = LegendPlacement.Outside,  
    58.                 LegendPosition = LegendPosition.BottomCenter,  
    59.                 LegendOrientation = LegendOrientation.Horizontal,  
    60.                 LegendBorderThickness = 0  
    61.             };  
    62.    
    63.             var s1 = new BarSeries { Title = "Series 1", IsStacked = stacked, StrokeColor = OxyColors.Black, StrokeThickness = 1 };  
    64.             s1.Items.Add(new BarItem { Value = 25 });  
    65.             s1.Items.Add(new BarItem { Value = 137 });  
    66.             s1.Items.Add(new BarItem { Value = 18 });  
    67.             s1.Items.Add(new BarItem { Value = 40 });  
    68.    
    69.             var s2 = new BarSeries { Title = "Series 2", IsStacked = stacked, StrokeColor = OxyColors.Black, StrokeThickness = 1 };  
    70.             s2.Items.Add(new BarItem { Value = 12 });  
    71.             s2.Items.Add(new BarItem { Value = 14 });  
    72.             s2.Items.Add(new BarItem { Value = 120 });  
    73.             s2.Items.Add(new BarItem { Value = 26 });  
    74.    
    75.             var categoryAxis = new CategoryAxis { Position = CategoryAxisPosition() };  
    76.             categoryAxis.Labels.Add("Category A");  
    77.             categoryAxis.Labels.Add("Category B");  
    78.             categoryAxis.Labels.Add("Category C");  
    79.             categoryAxis.Labels.Add("Category D");  
    80.             var valueAxis = new LinearAxis { Position = ValueAxisPosition(), MinimumPadding = 0, MaximumPadding = 0.06, AbsoluteMinimum = 0 };  
    81.             model.Series.Add(s1);  
    82.             model.Series.Add(s2);  
    83.             model.Axes.Add(categoryAxis);  
    84.             model.Axes.Add(valueAxis);  
    85.             return model;  
    86.         }  
    87.    
    88.         private AxisPosition CategoryAxisPosition()  
    89.         {  
    90.             if (typeof(BarSeries) == typeof(ColumnSeries))  
    91.             {  
    92.                 return AxisPosition.Bottom;  
    93.             }  
    94.    
    95.             return AxisPosition.Left;  
    96.         }  
    97.    
    98.         private AxisPosition ValueAxisPosition()  
    99.         {  
    100.             if (typeof(BarSeries) == typeof(ColumnSeries))  
    101.             {  
    102.                 return AxisPosition.Left;  
    103.             }  
    104.    
    105.             return AxisPosition.Bottom;  
    106.         }  
    107.    
    108.     }  
  • As you can see from the above example, we can use same PlotModel type of object to show different types of data by adding different types of series object to it.

  • The sample code given in this article is published on Github and it has 3 more screens showing Area Graph, Stacked Bar Graph, and Comparison Bar Graph.

  • This is how the sample application looks, when executed in the iOS simulator.


This article has just scratched the surface of using Oxyplot controls to create different types of charts and graphs. You can experiment more with it by trying out these examples. Let me know if you need any particular graph example.


Similar Articles