Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# WPF Live Charts - Creating a chart generically

Tags:

c#

wpf

I am using WPF Live Charts Library. I am trying to create a bar chart generically.

Following is my code. Can't do it in XAML as it doesn't support generics.

public abstract class AbstractGenericBarChart<T> : UserControl, INotifyPropertyChanged
{
    SeriesCollection _SeriesCollection;
    public SeriesCollection SeriesCollection { get { return _SeriesCollection; } set { _SeriesCollection = value; notifyPropertyChanged("SeriesCollection"); } }
    string[] _Labels;
    public string[] Labels { get { return _Labels; } set { _Labels = value; notifyPropertyChanged("Labels"); } }
    Func<int, string> _Formatter;
    public Func<int, string> Formatter { get { return _Formatter; } set { _Formatter = value; notifyPropertyChanged("Formatter"); } }

    public abstract void constructChart(List<T> chartItems);

    public void init(string xLabel, string yLabel)
    {
        renderChart(xLabel, yLabel);
    }

    public void renderChart(string xLabel, string yLabel)
    {
        CartesianChart chart = new CartesianChart { Margin = new Thickness(10, 10, 10, 10), LegendLocation = LegendLocation.Bottom, DataTooltip = new DefaultTooltip { SelectionMode = TooltipSelectionMode.SharedYValues } };
        Axis xAxis = new Axis { Foreground = Brushes.Black, FontSize = 14d, Title = xLabel };
        Axis yAxis = new Axis { Foreground = Brushes.Black, FontSize = 14d, Title = yLabel };
        chart.AxisX.Add(xAxis);
        chart.AxisY.Add(yAxis);
        setBinding("LabelFormatter", Formatter, xAxis, Axis.LabelFormatterProperty);
        setBinding("Labels", Labels, yAxis, Axis.LabelsProperty);
        setBinding("Series", SeriesCollection, chart, CartesianChart.SeriesProperty);
        Content = chart;
    }

    public void setBinding(string propertyName, object source, FrameworkElement control, DependencyProperty dependencyProperty)
    {
        Binding binding = new Binding(propertyName)
        {
            Source = source
        };
        control.SetBinding(dependencyProperty, binding);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void notifyPropertyChanged(string prop)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
    }
}


internal class BarChart : AbstractGenericBarChart<TopTransactingCount>
{
    public override void constructChart(List<TopTransactingCount> chartItems)
    {
        SeriesCollection = new SeriesCollection
        {
            new RowSeries
            {
                Title = "Transaction Count",
                Values = new ChartValues<long>(chartItems.Select(x=>x.TransCount))
            }
        };
        Labels = chartItems.Select(x => x.Date.ToShortDateString()).ToArray();
        Formatter = value => value.ToString();
        DataContext = this;
    }
}

At startup I see an empty chart control which is expected.

I call constructChart method on submit button click.

public partial class TotalTransCountsChart : UserControl, IChart
{
    private BarChart chart = new BarChart();
    List<object> chartData;

    public TotalTransCountsChart()
    {
        InitializeComponent();
    }

    public void init(List<object> chartData)
    {
        this.chartData = chartData;
        chart.init("Transaction Count", "Date");
        chart.constructChart(chartData.Cast<TopTransactingCount>().ToList());
        grid.Children.Add(chart);
        Grid.SetRow(chart, 3);
    }

    private void CmdSubmit_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        chart.constructChart(chartData.Cast<TopTransactingCount>().ToList());
    }
}

However, the chart still remains empty. I think the binding part in the code is not working as expected. I am stuck at this point.

like image 595
Nilesh Barai Avatar asked Nov 15 '19 11:11

Nilesh Barai


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.


1 Answers

it looks like you are creating Bindings incorrectly (try to confirm it from Visual Studio Output window - it reports messages about incorrect bindings).

for example:

setBinding("Labels", Labels, yAxis, Axis.LabelsProperty);

public void setBinding(string propertyName, object source, FrameworkElement control, DependencyProperty dependencyProperty)
{
    Binding binding = new Binding(propertyName)
    {
        Source = source
    };
    control.SetBinding(dependencyProperty, binding);
}

Labels is a string[], and you have a binding , which attempts to use "Labels" property - which doesn't exist.

you need a valid binding source, most likely DataContext:

setBinding("LabelFormatter", DataContext, xAxis, Axis.LabelFormatterProperty);
setBinding("Labels", DataContext, yAxis, Axis.LabelsProperty);
setBinding("Series", DataContext, chart, CartesianChart.SeriesProperty);

or better yet - don't specify source and all bindings will connect to current DataContext, even if it updates:

public void setBinding(string propertyName, object source, FrameworkElement control, DependencyProperty dependencyProperty)
{
    Binding binding = new Binding(propertyName);
    control.SetBinding(dependencyProperty, binding);
}
like image 144
ASh Avatar answered Oct 05 '22 21:10

ASh