I have to implement a simple Column Chart output in a WPF project. I have chosen the OxyPlot Library for it. Design Pattern is of course MVVM. The relevant source code parts can be seen below. What I get, when I run the project is an empty chart with categories 1 thru 5 on the x axis (which is correct) and values 0 thru 100 on the y axis (which is correct also, as i am supposed to display percentages).
The data collections (named "difficulties" for the category axis and "percentages" for the values axis" are correctly filled with values, I´ve checked that one.
But there are no columns displayed. So I wonder what I am doing wrong. I have built my example according to this oxyplot demo and based on an example we got presented at the wpf class at university.
Any suggestions?
Regards Roland
using System;
using System.ComponentModel;
using System.Linq.Expressions;
namespace GeoCaching.Wpf.ViewModels
{
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
Console.WriteLine("PropertyChangedEventArgs called " + propertyName);
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
the Statistics Model itself goes here:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GeoCaching.BL;
using GeoCaching.BL.Interfaces;
using GeoCaching.BL.Factories;
using GeoCaching.DAL.Common.Domain;
using GeoCaching.Wpf.ViewModels;
using OxyPlot;
using OxyPlot.Wpf;
using OxyPlot.Annotations;
using OxyPlot.Axes;
namespace GeoCaching.Wpf.ViewModels
{
public class StatisticsVM : ViewModelBase
{
private IStatisticsMgr statManager;
Dictionary<int, double> testList;
List<int> difficulties;
List<double> percentages;
public StatisticsVM()
{
PlotModel = new PlotModel();
this.difficulties = new List<int>();
this.percentages = new List<double>();
LoadData();
SetUpModel();
}
private PlotModel plotModel;
public PlotModel PlotModel
{
get { return plotModel; }
set { plotModel = value; OnPropertyChanged("PlotModel"); }
}
private void SetUpModel()
{
var temp = new PlotModel("difficulties distribution");
OxyPlot.Axes.CategoryAxis catAxis = new OxyPlot.Axes.CategoryAxis(AxisPosition.Bottom);
OxyPlot.Axes.LinearAxis valAxis = new OxyPlot.Axes.LinearAxis(AxisPosition.Left, 0, 100);
valAxis.MinimumPadding = 0;
valAxis.AbsoluteMinimum = 0;
OxyPlot.Series.ColumnSeries cs = new OxyPlot.Series.ColumnSeries();
cs.ItemsSource = percentages;
temp.Axes.Add(catAxis);
temp.Axes.Add(valAxis);
temp.Series.Add(cs);
PlotModel = temp;
PlotModel.RefreshPlot(true);
}
//fetch statistics data from
//database
private void LoadData()
{
statManager = StatisticsMgrFactory.GetStatisticsManager();
testList = new Dictionary<int, double>();
testList = statManager.GroupByDifficulty();
//extract keys and values
//for statistical display on axes
foreach (KeyValuePair<int,double> item in testList)
{
difficulties.Add(item.Key);
percentages.Add(item.Value);
}
}
}
}
the code behind the xaml window:
using GeoCaching.Wpf.ViewModels;
namespace GeoCaching.Wpf
{
/// <summary>
/// Interaction logic for ChartTest.xaml
/// </summary>
public partial class ChartTest : Window
{
public ChartTest()
{
InitializeComponent();
this.DataContext = new StatisticsVM();
}
}
}
and the xaml itself:
<Window x:Class="GeoCaching.Wpf.ChartTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="http://oxyplot.codeplex.com"
Title="ChartTest" Height="300" Width="300">
<Grid>
<oxy:Plot Title="Bar series" LegendPlacement="Outside" LegendPosition="RightTop" LegendOrientation="Vertical" Model="{Binding PlotModel}">
</oxy:Plot>
</Grid>
</Window>
I believe your issue is coming from within the SetupModel
method, specifically, this line:
cs.ItemsSource = percentages;
I've been working with oxyPlot column charts and I've never been able to get a chart to work if I set the ItemSource
property. Instead, I have to add a new ColumnItem()
for every item within my item source.
Example:
foreach (double pc in percentages)
{
catAxis.ActualLabels.Add (/*Add your difficulty labels here for each column*/);
cs.Items.Add (new ColumnItem () { Value = pc });
}
I know this question is quite old, but I thought id share this for anyone else who's having trouble. (Feel free to update my answer if you know why using the actual ItemSource
property doesn't work!)