private void SetSplitMonitorStatistics(List <PlanSplitMonitor> plans, AnalysisPhase phase, Chart chart) { //find the phase Cycles that occure during the plan. foreach (var plan in plans) { var Cycles = from cycle in phase.Cycles.Items where cycle.StartTime > plan.StartTime && cycle.EndTime < plan.EndTime orderby cycle.Duration select cycle; // find % Skips if (ShowPercentSkip) { if (plan.CycleCount > 0) { double CycleCount = plan.CycleCount; double SkippedPhases = plan.CycleCount - Cycles.Count(); double SkipPercent = 0; if (CycleCount > 0) { SkipPercent = SkippedPhases / CycleCount; } var skipLabel = ChartTitleFactory.GetCustomLabelForTitle( $"{SkipPercent:0.0%} Skips", plan.StartTime.ToOADate(), plan.EndTime.ToOADate(), 1, Color.Black); //new CustomLabel(); //skipLabel.FromPosition = plan.StartTime.ToOADate(); //skipLabel.ToPosition = plan.EndTime.ToOADate(); //skipLabel.Text = string.Format("{0:0.0%} Skips", SkipPercent); //skipLabel.LabelMark = LabelMarkStyle.LineSideMark; //skipLabel.ForeColor = Color.Black; //skipLabel.RowIndex = 1; chart.ChartAreas[0].AxisX2.CustomLabels.Add(skipLabel); } } // find % GapOuts if (ShowPercentGapOuts) { var GapOuts = from cycle in Cycles where cycle.TerminationEvent == 4 select cycle; double CycleCount = plan.CycleCount; double gapouts = GapOuts.Count(); double GapPercent = 0; if (CycleCount > 0) { GapPercent = gapouts / CycleCount; } var gapLabel = new CustomLabel(); gapLabel.FromPosition = plan.StartTime.ToOADate(); gapLabel.ToPosition = plan.EndTime.ToOADate(); gapLabel.Text = string.Format("{0:0.0%} GapOuts", GapPercent); gapLabel.LabelMark = LabelMarkStyle.LineSideMark; gapLabel.ForeColor = Color.OliveDrab; gapLabel.RowIndex = 2; chart.ChartAreas[0].AxisX2.CustomLabels.Add(gapLabel); } //Set Max Out if (ShowPercentMaxOutForceOff && plan.PlanNumber == 254) { var MaxOuts = from cycle in Cycles where cycle.TerminationEvent == 5 select cycle; double CycleCount = plan.CycleCount; double maxouts = MaxOuts.Count(); double MaxPercent = 0; if (CycleCount > 0) { MaxPercent = maxouts / CycleCount; } var maxLabel = new CustomLabel(); maxLabel.FromPosition = plan.StartTime.ToOADate(); maxLabel.ToPosition = plan.EndTime.ToOADate(); maxLabel.Text = string.Format("{0:0.0%} MaxOuts", MaxPercent); maxLabel.LabelMark = LabelMarkStyle.LineSideMark; maxLabel.ForeColor = Color.Red; maxLabel.RowIndex = 3; chart.ChartAreas[0].AxisX2.CustomLabels.Add(maxLabel); } // Set Force Off if (ShowPercentMaxOutForceOff && plan.PlanNumber != 254 ) { var ForceOffs = from cycle in Cycles where cycle.TerminationEvent == 6 select cycle; double CycleCount = plan.CycleCount; double forceoffs = ForceOffs.Count(); double ForcePercent = 0; if (CycleCount > 0) { ForcePercent = forceoffs / CycleCount; } var forceLabel = new CustomLabel(); forceLabel.FromPosition = plan.StartTime.ToOADate(); forceLabel.ToPosition = plan.EndTime.ToOADate(); forceLabel.Text = string.Format("{0:0.0%} ForceOffs", ForcePercent); forceLabel.LabelMark = LabelMarkStyle.LineSideMark; forceLabel.ForeColor = Color.MediumBlue; forceLabel.RowIndex = 3; chart.ChartAreas[0].AxisX2.CustomLabels.Add(forceLabel); } //Average Split if (ShowAverageSplit) { double runningTotal = 0; double averageSplits = 0; foreach (var Cycle in Cycles) { runningTotal = runningTotal + Cycle.Duration.TotalSeconds; } if (Cycles.Count() > 0) { averageSplits = runningTotal / Cycles.Count(); } var avgLabel = new CustomLabel(); avgLabel.FromPosition = plan.StartTime.ToOADate(); avgLabel.ToPosition = plan.EndTime.ToOADate(); avgLabel.Text = string.Format("{0: 0.0} Avg. Split", averageSplits); avgLabel.LabelMark = LabelMarkStyle.LineSideMark; avgLabel.ForeColor = Color.Black; avgLabel.RowIndex = 4; chart.ChartAreas[0].AxisX2.CustomLabels.Add(avgLabel); //Percentile Split if (SelectedPercentileSplit != null && Cycles.Count() > 2) { double percentileResult = 0; var Percentile = Convert.ToDouble(SelectedPercentileSplit) / 100; var setCount = Cycles.Count(); var PercentilIndex = Percentile * setCount; if (PercentilIndex % 1 == 0) { percentileResult = Cycles.ElementAt(Convert.ToInt16(PercentilIndex) - 1).Duration .TotalSeconds; } else { var indexMod = PercentilIndex % 1; //subtracting .5 leaves just the integer after the convert. //There was probably another way to do that, but this is easy. int indexInt = Convert.ToInt16(PercentilIndex - .5); var step1 = Cycles.ElementAt(Convert.ToInt16(indexInt) - 1).Duration.TotalSeconds; var step2 = Cycles.ElementAt(Convert.ToInt16(indexInt)).Duration.TotalSeconds; var stepDiff = step2 - step1; var step3 = stepDiff * indexMod; percentileResult = step1 + step3; } var percentileLabel = new CustomLabel(); percentileLabel.FromPosition = plan.StartTime.ToOADate(); percentileLabel.ToPosition = plan.EndTime.ToOADate(); percentileLabel.Text = string.Format("{0: 0.0} - {1} Percentile Split", percentileResult, Convert.ToDouble(SelectedPercentileSplit)); percentileLabel.LabelMark = LabelMarkStyle.LineSideMark; percentileLabel.ForeColor = Color.Purple; percentileLabel.RowIndex = 5; chart.ChartAreas[0].AxisX2.CustomLabels.Add(percentileLabel); } } } }