Search code examples
c#livecharts

c# LiveCharts WPF how to add 0 value to a date where data does not exist to show in CartesianChart


This question is propably more a concept question, but I'm stuck here logically. I'm using LiveChart for WPF and I try to build a simple CartesianChart dynamically.

I load my Data from a CSV into a List, I'm counting how many times each datapair is in that file and add the amount. The result from this Linq request looks like this:

[0] { Dates = "20191123", Rank = "1st", Amount = 1 }    <Anonymous Type>

I go through this result to pick me each date individually for the Lables of my CartesianChart

Now I would like to add my result Data into the CartesianChart for that I need a SeriesCollection mine looks like this:

 SeriesCollection = new SeriesCollection
        {
            new LineSeries
            {
                Title = "1st",
                 Values = new ChartValues<int> {}
            },
            new LineSeries
            {
                Title = "2nd",
                 Values = new ChartValues<int> {}
            },
            new LineSeries
            {
                Title = "3rd",
                 Values = new ChartValues<int> {}
            }
}

But when I go through my data on some dates I dont have for example first place, so I need a 0 amount value for this day. I'm struggeling to add this to my data.

Here is pretty much the whole code block im experimenting with, that also why it looks a little messy.

        var data = File.ReadAllLines(FilePathes.resultPath).ToList();
        var rankHistoryList = new List<RankHistory>();
        foreach (var line in data)
        {
            rankHistoryList.Add(RankHistory.parse(line));
        };


        var result = rankHistoryList.GroupBy(x => new { x.Dates, x.Rank })
               .Select(g => new { g.Key.Dates, g.Key.Rank, Amount = g.Count() })

               .ToList();

        var dates = new List<string>();

        foreach (var entry in result)
        {
            dates.Add(entry.Dates);                     
        }
        var singleDates = dates.GroupBy(x => x).Select(grp => grp.First()).ToArray();

        foreach (var day in singleDates) { 
            foreach (var entry in result) { 
                if (entry.Rank == "1st" && day == entry.Dates)
                {
                    SeriesCollection[0].Values.Add(entry.Amount);                                                
                }
                else if (entry.Rank != "1st" && day == entry.Dates)  
                { SeriesCollection[0].Values.Add(0); }
            }
        }

Solution

  • I think my answer is the most complicated but at least it works:

     var allRanks = new List<string>
            {
                "1st"
                ,"2nd"
                ,"3rd"
    
            };
    
            foreach (var entry in result)
            {
                dates.Add(entry.Dates);
            }
            var singleDates = dates.GroupBy(x => x).Select(grp => grp.First()).ToArray();
            Labels = singleDates;
    
            foreach (var ran in allRanks)
            {
                foreach (var day in singleDates)
                {
                    if (ran == "1st")
                    {
                        if (result.Exists(x => x.Dates == day && x.Rank == ran) == true)
                        {                 
                        SeriesCollection[0].Values.Add(result.Where(w => w.Dates == day && w.Rank == ran).Select(x => x.Amount).First());
                        }
                        else SeriesCollection[0].Values.Add(0);
                    }
    
                    if (ran == "2nd")
                    {
                        if (result.Exists(x => x.Dates == day && x.Rank == ran) == true)
                        {
                            SeriesCollection[1].Values.Add(result.Where(w => w.Dates == day && w.Rank == ran).Select(x => x.Amount).First());
                        }
                        else SeriesCollection[1].Values.Add(0);
                    }
                    if (ran == "3rd")
                    {
                        if (result.Exists(x => x.Dates == day && x.Rank == ran) == true)
                        {
                            SeriesCollection[2].Values.Add(result.Where(w => w.Dates == day && w.Rank == ran).Select(x => x.Amount).First());
                        }
                        else SeriesCollection[2].Values.Add(0);
                    }
    
                }
            }