/// <summary>
        /// Sets up the line chart series.
        /// </summary>
        protected override void SetupSeries()
        {
            // If no books return the default.
            if (BooksReadProvider == null)
            {
                base.SetupSeries();
                return;
            }

            // Set up the axis names and formatters.
            XAxisTitle = "Month of the year";
            YAxisTitle = "Pages Read";

            // get the books & pages read for each calendar year
            Dictionary <int, List <MonthOfYearTally> > bookListsByMonthOfYear =
                BookTotalsUtilities.GetBookListsByMonthOfYear(BooksReadProvider);

            // Set up the series for the overall and the trendline.
            Series = new SeriesCollection();
            List <ISeriesView> seriesViews = new List <ISeriesView>();

            MinY = 0;
            MaxY = 1;

            // Add a series for each year.
            List <Color> stdColors   = ColorUtilities.SetupStandardColourSet();
            int          colourIndex = 0;

            foreach (int year in bookListsByMonthOfYear.Keys.ToList().OrderBy(x => x))
            {
                // Get the totals for the months.
                List <double> pagesReadSeriesValues = new List <double>();
                List <double> months = new List <double>();
                double        total  = 0;
                for (int i = BookTotalsUtilities.FirstMonth; i <= BookTotalsUtilities.LastMonth; i++)
                {
                    // Get the tally for this month if set and add it to the total
                    MonthOfYearTally tally = bookListsByMonthOfYear[year].FirstOrDefault(x => x.MonthOfYear == i);
                    months.Add(i);
                    total += tally?.PagesReadThisMonth ?? 0;
                    pagesReadSeriesValues.Add(total);
                }

                // Create the series for the year.
                Color color = stdColors[colourIndex % stdColors.Count];
                seriesViews.Add(CreateLineSeries(year.ToString(), months, pagesReadSeriesValues, color, 0d));
                colourIndex++;

                // Update the Y-range.
                MinY = Math.Floor(Math.Min(pagesReadSeriesValues.Min(), MinY));
                MaxY = Math.Ceiling(Math.Max(pagesReadSeriesValues.Max(), MaxY));
            }

            Series.AddRange(seriesViews);
            SeriesCollection = Series;

            // Update the X-range.
            MinTick = BookTotalsUtilities.FirstMonth - 1;
            MaxTick = BookTotalsUtilities.LastMonth + 1;
        }
        private Dictionary<int, List<MonthOfYearTally>> GetBookListsByMonthOfYear()
        {
            // get the books foreach year
            Dictionary<int, List<BookRead>> bookListsByYear = new Dictionary<int, List<BookRead>>();

            foreach (BookRead book in BooksReadProvider.BooksRead)
            {
                int bookReadYear = book.Date.Year;
                if (bookListsByYear.ContainsKey(bookReadYear))
                    bookListsByYear[bookReadYear].Add(book);
                else
                    bookListsByYear.Add(bookReadYear, new List<BookRead>() { book });
            }

            // for each year get the lists of books read each day
            Dictionary<int, Dictionary<int, List<BookRead>>> bookTotalsByMonthAndYear =
                new Dictionary<int, Dictionary<int, List<BookRead>>>();
            foreach (var year in bookListsByYear.Keys)
            {
                Dictionary<int, List<BookRead>> booksByMonthOfYear = new Dictionary<int, List<BookRead>>();
                foreach (var book in bookListsByYear[year])
                {
                    int bookReadMonthOfYear = book.Date.Month;
                    if (booksByMonthOfYear.ContainsKey(bookReadMonthOfYear))
                        booksByMonthOfYear[bookReadMonthOfYear].Add(book);
                    else
                        booksByMonthOfYear.Add(bookReadMonthOfYear, new List<BookRead>() { book });
                }
                bookTotalsByMonthAndYear.Add(year, booksByMonthOfYear);
            }

            // from these get the daily tallies for each year
            Dictionary<int, List<MonthOfYearTally>> bookListsByMonthAndYear = 
                new Dictionary<int, List<MonthOfYearTally>>();
            foreach (var year in bookTotalsByMonthAndYear.Keys)
            {
                Dictionary<int, List<BookRead>> booksByMonthOfYear = bookTotalsByMonthAndYear[year];
                List<MonthOfYearTally> monthOfYearTallies = new List<MonthOfYearTally>();

                foreach (var monthOfYear in booksByMonthOfYear.Keys.ToList().OrderBy(x => x))
                {
                    List<BookRead> booksforMonth = booksByMonthOfYear[monthOfYear];
                    MonthOfYearTally tally = new MonthOfYearTally()
                    {
                        MonthOfYear = monthOfYear,
                        BooksReadThisMonth = booksforMonth.Count(),
                        PagesReadThisMonth = booksforMonth.Sum(x => x.Pages)
                    };


                    monthOfYearTallies.Add(tally);
                }
                bookListsByMonthAndYear.Add(year, monthOfYearTallies);
            }

            return bookListsByMonthAndYear;
        }
        /// <summary>
        /// Sets up the line chart series.
        /// </summary>
        protected override void SetupSeries()
        {
            // If no books return the default.
            if (BooksReadProvider == null)
            {
                base.SetupSeries();
                return;
            }

            // Set the categories.
            Categories = BookTotalsUtilities.MonthNames.Skip(1).Take(12).ToArray();

            // Set up the axis names and formatters.
            XAxisTitle = "Month of the year";
            YAxisTitle = "Books Read";

            // get the books & pages read for each calendar year
            Dictionary <int, List <MonthOfYearTally> > bookListsByMonthOfYear =
                BookTotalsUtilities.GetBookListsByMonthOfYear(BooksReadProvider);

            // Set up the series collection and initialise the min and max.
            Series = new SeriesCollection();
            List <ISeriesView> seriesViews = new List <ISeriesView>();

            MinY = 0;
            MaxY = 1;

            // Add a series for each year.
            List <Color> stdColors   = ColorUtilities.SetupStandardColourSet();
            int          colourIndex = 0;

            foreach (int year in bookListsByMonthOfYear.Keys.ToList().OrderBy(x => x))
            {
                // Get the totals for the months.
                List <double> booksReadSeriesValues = new List <double>();
                for (int i = BookTotalsUtilities.FirstMonth; i <= BookTotalsUtilities.LastMonth; i++)
                {
                    // Get the tally for this month if set, otherwise set to zero
                    MonthOfYearTally tally = bookListsByMonthOfYear[year].FirstOrDefault(x => x.MonthOfYear == i);
                    booksReadSeriesValues.Add(tally?.BooksReadThisMonth ?? 0);
                }

                // Create the series for the year.
                Color color = stdColors[colourIndex % stdColors.Count];
                seriesViews.Add(CreateColumnSeries(year.ToString(), booksReadSeriesValues, color, 0d));
                colourIndex++;

                // Update the Y-range.
                MinY = Math.Floor(Math.Min(booksReadSeriesValues.Min(), MinY));
                MaxY = Math.Ceiling(Math.Max(booksReadSeriesValues.Max(), MaxY));
            }

            Series.AddRange(seriesViews);
            SeriesCollection = Series;
        }