private void AddDataPoints(RecordGroupCollection recordIterator, List <PlayerStats> selected = null, Predicate <object> filter = null)
        {
            DateTime newTaskTime = DateTime.Now;

            Task.Run(() =>
            {
                double lastTime  = double.NaN;
                double firstTime = double.NaN;
                Dictionary <string, DataPoint> playerData               = new Dictionary <string, DataPoint>();
                Dictionary <string, DataPoint> needAccounting           = new Dictionary <string, DataPoint>();
                Dictionary <string, ChartValues <DataPoint> > theValues = new Dictionary <string, ChartValues <DataPoint> >();

                foreach (var dataPoint in recordIterator)
                {
                    double diff = double.IsNaN(lastTime) ? 1 : dataPoint.CurrentTime - lastTime;

                    if (!playerData.TryGetValue(dataPoint.Name, out DataPoint aggregate))
                    {
                        aggregate = new DataPoint()
                        {
                            Name = dataPoint.Name
                        };
                        playerData[dataPoint.Name] = aggregate;
                    }

                    if (double.IsNaN(firstTime) || diff > DataManager.FIGHT_TIMEOUT)
                    {
                        firstTime = dataPoint.CurrentTime;

                        if (diff > DataManager.FIGHT_TIMEOUT)
                        {
                            UpdateRemaining(theValues, needAccounting, firstTime, lastTime);
                            foreach (var value in playerData.Values)
                            {
                                value.RollingTotal    = 0;
                                value.RollingCritHits = 0;
                                value.RollingHits     = 0;
                                value.CurrentTime     = lastTime + 6;
                                Insert(value, theValues);
                                value.CurrentTime = firstTime - 6;
                                Insert(value, theValues);
                            }
                        }
                    }

                    aggregate.Total           += dataPoint.Total;
                    aggregate.RollingTotal    += dataPoint.Total;
                    aggregate.RollingHits     += 1;
                    aggregate.RollingCritHits += LineModifiersParser.IsCrit(dataPoint.ModifiersMask) ? (uint)1 : 0;
                    aggregate.BeginTime        = firstTime;
                    aggregate.CurrentTime      = dataPoint.CurrentTime;
                    lastTime = dataPoint.CurrentTime;

                    if (diff >= 1)
                    {
                        Insert(aggregate, theValues);
                        UpdateRemaining(theValues, needAccounting, firstTime, lastTime, aggregate.Name);
                    }
                    else
                    {
                        needAccounting[aggregate.Name] = aggregate;
                    }
                }

                UpdateRemaining(theValues, needAccounting, firstTime, lastTime);
                Plot(theValues, newTaskTime, selected, filter);
            });
        }
        private void AddDataPoints(RecordGroupCollection recordIterator, List <PlayerStats> selected = null, Predicate <object> filter = null)
        {
            DateTime newTaskTime = DateTime.Now;

            Task.Run(() =>
            {
                double lastTime  = double.NaN;
                double firstTime = double.NaN;
                Dictionary <string, DataPoint> petData              = new Dictionary <string, DataPoint>();
                Dictionary <string, DataPoint> playerData           = new Dictionary <string, DataPoint>();
                Dictionary <string, DataPoint> totalPlayerData      = new Dictionary <string, DataPoint>();
                Dictionary <string, DataPoint> raidData             = new Dictionary <string, DataPoint>();
                Dictionary <string, DataPoint> needTotalAccounting  = new Dictionary <string, DataPoint>();
                Dictionary <string, DataPoint> needPlayerAccounting = new Dictionary <string, DataPoint>();
                Dictionary <string, DataPoint> needPetAccounting    = new Dictionary <string, DataPoint>();
                Dictionary <string, DataPoint> needRaidAccounting   = new Dictionary <string, DataPoint>();

                foreach (var dataPoint in recordIterator)
                {
                    double diff = double.IsNaN(lastTime) ? 1 : dataPoint.CurrentTime - lastTime;

                    if (double.IsNaN(firstTime) || diff > DataManager.FIGHTTIMEOUT)
                    {
                        firstTime = dataPoint.CurrentTime;
                    }

                    var raidName = "Raid";
                    if (!raidData.TryGetValue(raidName, out DataPoint raidAggregate))
                    {
                        raidAggregate = new DataPoint()
                        {
                            Name = raidName
                        };
                        raidData[raidName] = raidAggregate;
                    }

                    Aggregate(raidData, RaidValues, needRaidAccounting, dataPoint, raidAggregate, firstTime, lastTime, diff);

                    var playerName = dataPoint.PlayerName ?? dataPoint.Name;
                    var petName    = dataPoint.PlayerName == null ? null : dataPoint.Name;
                    var totalName  = playerName + " +Pets";
                    if (!totalPlayerData.TryGetValue(totalName, out DataPoint totalAggregate))
                    {
                        totalAggregate = new DataPoint()
                        {
                            Name = totalName, PlayerName = playerName
                        };
                        totalPlayerData[totalName] = totalAggregate;
                    }

                    Aggregate(totalPlayerData, PlayerPetValues, needTotalAccounting, dataPoint, totalAggregate, firstTime, lastTime, diff);

                    if (dataPoint.PlayerName == null)
                    {
                        if (!playerData.TryGetValue(dataPoint.Name, out DataPoint aggregate))
                        {
                            aggregate = new DataPoint()
                            {
                                Name = dataPoint.Name
                            };
                            playerData[dataPoint.Name] = aggregate;
                        }

                        Aggregate(playerData, PlayerValues, needPlayerAccounting, dataPoint, aggregate, firstTime, lastTime, diff);
                    }
                    else if (dataPoint.PlayerName != null)
                    {
                        if (!HasPets.ContainsKey(totalName))
                        {
                            HasPets[totalName] = new Dictionary <string, byte>();
                        }

                        HasPets[totalName][petName] = 1;
                        if (!petData.TryGetValue(petName, out DataPoint petAggregate))
                        {
                            petAggregate = new DataPoint()
                            {
                                Name = petName, PlayerName = playerName
                            };
                            petData[petName] = petAggregate;
                        }

                        Aggregate(petData, PetValues, needPetAccounting, dataPoint, petAggregate, firstTime, lastTime, diff);
                    }

                    lastTime = dataPoint.CurrentTime;
                }

                UpdateRemaining(RaidValues, needRaidAccounting, firstTime, lastTime);
                UpdateRemaining(PlayerPetValues, needTotalAccounting, firstTime, lastTime);
                UpdateRemaining(PlayerValues, needPlayerAccounting, firstTime, lastTime);
                UpdateRemaining(PetValues, needPetAccounting, firstTime, lastTime);
                Plot(selected, filter);
            });
        }