Design perfect website

We made it for You!

Design perfect website

We made it for You!
Charts in WPF C# – OxyPlot
Blog > C# > Charts in WPF C# – OxyPlot

Charts in WPF C# – OxyPlot

PL

Charts in WPF C# – OxyPlot


An inherent element of working on numerical data is their analysis. And what form of data interpretation could be more pleasing to the eye than the dependency chart? Therefore, the entry will concern a tool that allows you to draw charts in WPF C # – OxyPlot that facilitates this task.
Charts in WPF C# – OxyPlot


In projects that require a few points to be displayed in a simple way, you can easily do it with your own classes. Sometimes, however, the amount of data increases and the display method is complicated, eg by the logarithmic scale, the possibility of zooming in on a part of the graph. In such situations, programming such a tool can take a significant amount of time for the original project. It is worth using the extensive tools that will definitely meet our requirements.


There are many tools on the market that support the display of charts, for example XPlot, Chart, ZedGraph. Most of the tools are written under WinForms and they work great there. What if the project is designed from the beginning to the end in WPF? You can of course connect the WPF project with WinForms, but there is a tool that solves this problem.


OxyPlot is a library that allows direct implementation in WPF, Windows 8, Windows Phone, Windows Phone Silverlight, Windows Forms, Silverlight, GTK #, Xwt, Xamarin.iOS, Xamarin.Android, Xamarin.Forms and Xamarin.Mac. It is available under the MIT license, which allows you to use it freely, as long as the content of the license is included in the derivative programs.




Where to start – Charts in WPF C# – OxyPlot


Work with OxyPlot should start with adding libraries to your own WPF project. There are three ways to add the appropriate references:


The easiest way to do this is to use nuget. After launching the Package Manager Console, enter:

– Install-Package Oxyplot.Core

– Install-Package Oxyplot.Wpf


The second way is to search for the Oxyplot.Core and Oxyplot.Wpf libraries through the nuget interface – Manage Nuget Packages as shown below:

nuget - Charts in WPF C# - OxyPlot
nuget – Charts in WPF C# – OxyPlot

The third way is for those who do not work the previous ways.
Charts in WPF C# – OxyPlot


This method should be used if there was a problem during the installation, some OxyPlot functions do not work or for some reason you do not want to use nugets.


ATTENTION

Both the description and the examples provided by the manufacturer refer to the version 2013.1.38.1, unfortunately the version currently in the nuget is 2014.1.546 and may cause errors. One of them is:
The name “plot” does not exist in the namespace “http://oxyplot.codeplex.com”
The solution to this problem is to add references to an older version of the files that can be downloaded from here:

OxyPlot


The downloaded file should be unpacked and then a reference should be added to them as shown below:


1. In Solution Explorer, find the reference, right-click and select Add Reference.

ref1 - Charts in WPF C#
Charts in WPF C# – OxyPlot

2. In the newly opened window, click Browse and find the downloaded files, then click Add.


ref2 - OxyPlot
Charts in WPF C# – OxyPlot

3. Finally, check whether they are marked on the list and click OK.


ref3 - Charts in WPF C# - OxyPlot
Charts in WPF C# – OxyPlot

ATTENTION
The addition of any file by nuget will update files to a newer version. If the error mentioned above occurs, it will appear again.


Declaration of the graph control


The control should be declared in the XAML code of the project. In the Window header, a line should be added:


xmlns:oxy="http://oxyplot.codeplex.com"

Then, in the place where the graph should appear, enter the code:


<oxy:Plot x:Name="Plot1" Title="A Graph" Model="{Binding PlotModel}" Margin="10" Grid.Row="1"> </oxy:Plot>

The parameter worth clarifying here is the Model to which Binding has been set. This is a parameter that allows you to set the appearance, range, colors, data series, etc.


OxyPlot, despite functioning in WPF and the Binding Model, does not fully support the MVVM model (Model View ViewModel). This means that displaying changes in the graph requires updating the data in the PlotModel object in code-behind.


Implementation of the PlotModel object of the chart


Now that there is a control in the project in which the graph will be displayed, its appearance should be taken care of.


The model has been set to Binding, so it is necessary to declare the class with a field whose change will trigger a reaction through accessors. This class must inherit from INotifyPropertyChanged and override the OnPropertyChanged method:


public class OxyPlotModel : INotifyPropertyChanged
{

  private OxyPlot.PlotModel plotModel;
  public OxyPlot.PlotModel PlotModel
  {
      get
      {
         return plotModel;
      }
      set
      {
         plotModel = value;
         OnPropertyChanged("PlotModel");
      }
  }

  public event PropertyChangedEventHandler PropertyChanged;
  protected void OnPropertyChanged(string name)
  {
     PropertyChangedEventHandler handler = PropertyChanged;
     if (handler != null)
     {
        handler(this, new PropertyChangedEventArgs(name));
     }
  }
}

The object of the defined class should be connected to the interface with the graph control.


//Declaration of the object
private OxyPlotModel oxyPlotModel;

//In the constructor
oxyPlotModel = new OxyPlotModel();
this.DataContext = oxyPlotModel; // This allows you to combine controls with OxyPlotModel classes

Setting chart parameters


Now that everything is connected to each other, the setting of the appropriate parameters of the PlotModel field remains. For this purpose, the OxyPlotModel class will be expanded. The method of supplementing these parameters is arbitrary, but in the following example it has been separated into two stages. Parameters that do not change are replenished at the beginning, and those dependent on the chart are added before displaying. Fixed parameters are only those relating to the chart legend:


private void SetUpLegend()
{
  plotModel.LegendTitle = "Legenda";
  plotModel.LegendOrientation = OxyPlot.LegendOrientation.Horizontal;

  //Horizontal orientation
  plotModel.LegendPlacement = OxyPlot.LegendPlacement.Outside; //In addition to the chart plot
  plotModel.LegendPosition = OxyPlot.LegendPosition.TopRight; //Position: up, right
  plotModel.LegendBackground = OxyPlot.OxyColor.FromAColor(200, OxyPlot.OxyColors.White);//White background
  plotModel.LegendBorder = OxyPlot.OxyColors.Black; //Window frame black
}

I do not recommend the initial declaration of the axis of the chart, because the numerical values from the declarations and from the input data themselves can overlap and this will cause a visual mess.


The second class method, called whenever the chart content needs to be changed. The simplest example allowing to draw a cosine is the method:


public void PodajDaneDoWykresu()
{
  this.MyModel = new PlotModel { Title = "Przykład 1" };
  this.MyModel.Series.Add(new FunctionSeries(Math.Cos, 0, 10, 0.1, "cos(x)"));
}

In the case of a graph based on its own X and Y points, the same class would look like this:


public IList<OxyPlot.DataPoint> Points { get; private set; }
public void PodajDaneDoWykresu()
{
  this.plotModel.Title = "Przykład 2";
  this.Points = new List<OxyPlot.DataPoint>
  {
    new OxyPlot.DataPoint(5, 3),
    new OxyPlot.DataPoint(15, 17),
    new OxyPlot.DataPoint(25, 12),
    new OxyPlot.DataPoint(35, 4),
    new OxyPlot.DataPoint(45, 15),
    new OxyPlot.DataPoint(55, 10)
  };
}

or:


OxyPlot.Series.LineSeries punktySerii;
public void PodajDaneDoWykresu()
{
  this.plotModel.Title = "Przykład 3";

  punktySerii.Points.Add(new OxyPlot.DataPoint(5, 3));
  punktySerii.Points.Add(new OxyPlot.DataPoint(15, 17));
  punktySerii.Points.Add(new OxyPlot.DataPoint(25, 12));
  punktySerii.Points.Add(new OxyPlot.DataPoint(35, 4));
  punktySerii.Points.Add(new OxyPlot.DataPoint(45, 15));
  punktySerii.Points.Add(new OxyPlot.DataPoint(55, 10));

  plotModel.Series.Add(punktySerii);
}

In addition, this method can be supplemented with information on the axis axis parameters such as linear / logarithmic, data range, and minimum / maximum value:


var xAxis = new OxyPlot.Axes.LinearAxis(OxyPlot.Axes.AxisPosition.Bottom, "a - offered traffic [Erl]")
{
  MajorGridlineStyle = OxyPlot.LineStyle.Solid,
  MinorGridlineStyle = OxyPlot.LineStyle.Dot
};
plotModel.Axes.Add(xAxis); var yAxis = new OxyPlot.Axes.LogarithmicAxis(OxyPlot.Axes.AxisPosition.Left, "Ei")
{
  MajorGridlineStyle = OxyPlot.LineStyle.Solid,
  MinorGridlineStyle = OxyPlot.LineStyle.Dot
};
plotModel.Axes.Add(yAxis);

If the series of data is more then it is worth to be clearly different from each other, therefore you should define the parameters of the series:


//declaration outside the method
OxyPlot.Series.LineSeries punktySerii;

//implementation in the method
punktySerii = new OxyPlot.Series.LineSeries
{
  MarkerType = OxyPlot.MarkerType.Plus, //marking of points
  MarkerSize = 4, //point size
  MarkerStroke = OxyPlot.OxyColors.Tomato, //The color of the chart line
  Title = "Seria danych" //title of the series
};

Collecting all the information discussed below, the code for the data series given as a list in the parameter was presented below:


public void PodajDaneDoWykresu(List<double> X, List<double> Y)//List X and Y given as a method parameter
{
  this.PlotModel = new OxyPlot.PlotModel();
  //Removing the set parameters from the previous method run
  plotModel.Series = new System.Collections.ObjectModel.Collection<OxyPlot.Series.Series> { };
  plotModel.Axes = new System.Collections.ObjectModel.Collection<OxyPlot.Axes.Axis> { };


  //Graphical graph settings
  punktySerii = new OxyPlot.Series.LineSeries
  {
    MarkerType = ksztaltPunktowWykresu[0], //point marking - definition below
    MarkerSize = 4, //point size
    MarkerStroke = koloryWykresow[0], //Chart line color - definition below
    Title = "Seria nr: " + (1).ToString() //title of the series
  };

  //Supplementing data
  for (int n = 0; n < X.Count; n++) 
    punktySerii.Points.Add(new OxyPlot.DataPoint(X[n], Y[n]));//adding all series to the chart

  plotModel.Series.Add(punktySerii);

  //Description and parameters of the chart's axis
  var xAxis = new OxyPlot.Axes.LinearAxis(OxyPlot.Axes.AxisPosition.Bottom, "a - offered traffic [Erl]")
  {
    MajorGridlineStyle = OxyPlot.LineStyle.Solid,
    MinorGridlineStyle = OxyPlot.LineStyle.Dot
  };
  plotModel.Axes.Add(xAxis);
  var yAxis = new OxyPlot.Axes.LogarithmicAxis(OxyPlot.Axes.AxisPosition.Left, "Ei")
  {
    MajorGridlineStyle = OxyPlot.LineStyle.Solid,
    MinorGridlineStyle = OxyPlot.LineStyle.Dot
  };
  plotModel.Axes.Add(yAxis);
}

In the above code, the series used subsequent values of tables ksztaltPunktowWykresu and koloryWykresow. These are lists with listed values of these parameters, so that you can use them in a loop. An example of implementation of such tables is below:


//Printed to change the color and shape with the class number
private readonly List<OxyPlot.OxyColor> koloryWykresow = new List<OxyPlot.OxyColor>
{
  OxyPlot.OxyColors.Green,
  OxyPlot.OxyColors.IndianRed,
  OxyPlot.OxyColors.Coral,
  OxyPlot.OxyColors.Chartreuse,
  OxyPlot.OxyColors.Peru
};

private readonly List<OxyPlot.MarkerType> ksztaltPunktowWykresu = new List<OxyPlot.MarkerType>
{
  OxyPlot.MarkerType.Plus,
  OxyPlot.MarkerType.Star,
  OxyPlot.MarkerType.Cross,
  OxyPlot.MarkerType.Custom,
  OxyPlot.MarkerType.Square
};

Record the chart to a file


When we have worked so hard to display the graph, it would be good to keep it in the form of a file for later reproduction. OxyPlot allows you to use the keyboard shortcut ctrl + c to save its image in temporary memory, then simply paste it in any graphic editor.


A more convenient option, however, is to use a method that allows such a file to be saved:


OxyPlot.Wpf.PngExporter.Export(PlotModel, filename, 1600, 1600, OxyPlot.OxyColors.White, 96);

The parameters of the method are:


– Object with a chart model;

– The file name, including location and extension;

– Width in pixels;

– Height in pixels;

– Chart background color;

– The number of pixels per inch;


TOP