Esempio n. 1
0
 private static void LogProcessingCompleted(AnalysisPhase phase, int exitCode, ILogger logger)
 {
     string phaseLabel = phase == AnalysisPhase.PreProcessing ? Resources.PhaseLabel_PreProcessing : Resources.PhaseLabel_PostProcessing;
     if (exitCode == ProcessRunner.ErrorCode)
     {
         logger.LogError(Resources.ERROR_ProcessingFailed, phaseLabel, exitCode);
     }
     else
     {
         logger.LogInfo(Resources.MSG_ProcessingSucceeded, phaseLabel);
     }
 }
        public BootstrapperSettings(AnalysisPhase phase, IEnumerable<string> childCmdLineArgs, string sonarQubeUrl, LoggerVerbosity verbosity, ILogger logger)
        {
            if (sonarQubeUrl == null)
            {
                throw new ArgumentNullException("sonarQubeUrl");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            this.sonarQubeUrl = sonarQubeUrl;
            this.analysisPhase = phase;
            this.childCmdLineArgs = childCmdLineArgs;
            this.verbosity = verbosity;

            this.logger = logger;
        }
Esempio n. 3
0
 private static void AssertExpectedPhase(AnalysisPhase expected, IBootstrapperSettings settings)
 {
     Assert.AreEqual(expected, settings.Phase, "Unexpected analysis phase");
 }
Esempio n. 4
0
        private static bool TryGetPhase(int originalArgCount, IEnumerable <ArgumentInstance> arguments, ILogger logger, out AnalysisPhase phase)
        {
            // The command line parser will already have checked for duplicates
            var hasBeginVerb = ArgumentInstance.TryGetArgument(BeginId, arguments, out ArgumentInstance argumentInstance);
            var hasEndVerb   = ArgumentInstance.TryGetArgument(EndId, arguments, out argumentInstance);

            if (hasBeginVerb && hasEndVerb) // both
            {
                phase = AnalysisPhase.Unspecified;
                logger.LogError(Resources.ERROR_CmdLine_BothBeginAndEndSupplied);
            }
            else if (!hasBeginVerb && !hasEndVerb) // neither
            {
                // Backwards compatibility - decide the phase based on the number of arguments passed
                phase = originalArgCount == 0 ? AnalysisPhase.PostProcessing : AnalysisPhase.PreProcessing;
                logger.LogWarning(Resources.WARN_CmdLine_v09_Compat);
            }
            else // begin or end
            {
                phase = hasBeginVerb ? AnalysisPhase.PreProcessing : AnalysisPhase.PostProcessing;
            }

            return(phase != AnalysisPhase.Unspecified);
        }
Esempio n. 5
0
 private static void AssertExpectedPhase(AnalysisPhase expected, IBootstrapperSettings settings)
 {
     settings.Phase.Should().Be(expected, "Unexpected analysis phase");
 }
        private void LogProcessingStarted(AnalysisPhase phase)
        {
            var phaseLabel = phase == AnalysisPhase.PreProcessing ? Resources.PhaseLabel_PreProcessing : Resources.PhaseLabel_PostProcessing;

            this.logger.LogInfo(Resources.MSG_ProcessingStarted, phaseLabel);
        }
 private static void AssertExpectedPhase(AnalysisPhase expected, IBootstrapperSettings settings)
 {
     Assert.AreEqual(expected, settings.Phase, "Unexpected analysis phase");
 }
        private static bool TryGetPhase(int originalArgCount, IEnumerable<ArgumentInstance> arguments, ILogger logger, out AnalysisPhase phase)
        {
            // The command line parser will already have checked for duplicates
            ArgumentInstance argumentInstance;
            bool hasBeginVerb = ArgumentInstance.TryGetArgument(BeginId, arguments, out argumentInstance);
            bool hasEndVerb = ArgumentInstance.TryGetArgument(EndId, arguments, out argumentInstance);

            if (hasBeginVerb && hasEndVerb) // both
            {
                phase = AnalysisPhase.Unspecified;
                logger.LogError(Resources.ERROR_CmdLine_BothBeginAndEndSupplied);
            }
            else if (!hasBeginVerb && !hasEndVerb) // neither
            {
                // Backwards compatibility - decide the phase based on the number of arguments passed
                phase = originalArgCount == 0 ? AnalysisPhase.PostProcessing : AnalysisPhase.PreProcessing;
                logger.LogWarning(Resources.WARN_CmdLine_v09_Compat);
            }
            else // begin or end
            {
                phase = hasBeginVerb ? AnalysisPhase.PreProcessing : AnalysisPhase.PostProcessing;
            }

            return phase != AnalysisPhase.Unspecified;
        }
Esempio n. 9
0
        /// <summary>
        /// Gets substruct (material block data) from file
        /// </summary>
        public void LoadSubstructData()
        {
            if (!File.Exists(FilePath))
            {
                MessageBox.Show("Could not find input data file.", "Error");
                return;
            }

            // get canvas dimensions/properties
            double originX = OriginOffsetX,
                   originY = OriginOffsetY,
                   scale   = Scale,
                   yHeight = ActualHeight;
            Units units    = Units;

            // get units dependent scaling factor
            double factor;

            switch (units)
            {
            case Units.Metres: factor = 0.0254; break;

            case Units.Millimetres: factor = 25.4; break;

            case Units.Feet: factor = 1.0 / 12.0; break;

            default: factor = 1.0; break;
            }

            // Load material blocks from source canvas
            substructs = new List <MaterialBlock>();
            using (TextReader tr = new StreamReader(FilePath))
            {
                // advance to material block data
                while (!tr.ReadLine().Contains("MATERIAL BLOCK DATA"))
                {
                    ;
                }

                tr.ReadLine();
                tr.ReadLine();

                int numMaterialBlocks = int.Parse(tr.ReadLine().Split('=')[1]);

                tr.ReadLine();

                if (numMaterialBlocks > 0)
                {
                    MaterialBlock  block;
                    MaterialType   mtl;
                    DrawingPoint   p1, p2;
                    LineConstraint newLC, existingLC;
                    LineLoad       newLL, existingLL;
                    PointLoad      newPL, existingPL;
                    Point[]        materialBoundPoints;
                    bool[]         isFixedX;
                    bool[]         isFixedY;
                    bool[]         isPrintPoint;
                    string         materialName;
                    int            numMaterialBoundPoints, numLineConstraints, numLineLoads, numPointLoads;
                    double         xCoord, yCoord;
                    string[]       coords, lineConstraint, lineLoad, pointLoad;

                    for (int i = 0; i < numMaterialBlocks; i++)
                    {
                        tr.ReadLine();

                        materialName = tr.ReadLine().Split(new char[] { '\"' }, StringSplitOptions.RemoveEmptyEntries)[1];
                        mtl          = materialTypes.Find(delegate(MaterialType mt) { return(mt.Name == materialName); });

                        numMaterialBoundPoints = int.Parse(tr.ReadLine().Split('=')[1]);

                        materialBoundPoints = new Point[numMaterialBoundPoints];
                        isFixedX            = new bool[numMaterialBoundPoints];
                        isFixedY            = new bool[numMaterialBoundPoints];
                        isPrintPoint        = new bool[numMaterialBoundPoints];

                        for (int j = 0; j < numMaterialBoundPoints; j++)
                        {
                            coords = tr.ReadLine().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
                            xCoord = double.Parse(coords[0]);
                            yCoord = double.Parse(coords[1]);
                            materialBoundPoints[j].X = xCoord / (factor * Scale) * dpiX + OriginOffsetX;
                            materialBoundPoints[j].Y = ActualHeight - (yCoord / (factor * Scale) * dpiY + OriginOffsetY);
                            isFixedX[j]     = coords[2] == bool.TrueString;
                            isFixedY[j]     = coords[3] == bool.TrueString;
                            isPrintPoint[j] = coords[4] == bool.TrueString;
                        }

                        block = new MaterialBlock(this, mtl, materialBoundPoints);
                        for (int j = 0; j < numMaterialBoundPoints; j++)
                        {
                            block.BoundaryPoints[j].IsFixedX     = isFixedX[j];
                            block.BoundaryPoints[j].IsFixedY     = isFixedY[j];
                            block.BoundaryPoints[j].IsPrintPoint = isPrintPoint[j];
                        }

                        substructs.Add(block);

                        numLineConstraints = int.Parse(tr.ReadLine().Split('=')[1]);
                        for (int j = 0; j < numLineConstraints; j++)
                        {
                            lineConstraint = tr.ReadLine().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);

                            p1 = block.BoundaryPoints[int.Parse(lineConstraint[0])];
                            p2 = block.BoundaryPoints[int.Parse(lineConstraint[1])];

                            existingLC = null;
                            foreach (MaterialBlock mb in substructs)
                            {
                                existingLC = mb.LineConstraints.Find(delegate(LineConstraint lc) { return(lc.Nodes.Contains(p1) && lc.Nodes.Contains(p2)); });
                                if (existingLC != null)
                                {
                                    break;
                                }
                            }

                            if (existingLC == null)
                            {
                                newLC = new LineConstraint(this, p1, p2,
                                                           //newMaterialBlock.BoundaryPoints[int.Parse( lineConstraint[0] )] ,
                                                           //newMaterialBlock.BoundaryPoints[int.Parse( lineConstraint[1] )] ,
                                                           lineConstraint[2] == bool.TrueString,
                                                           lineConstraint[3] == bool.TrueString);
                            }
                            else
                            {
                                block.LineConstraints.Add(existingLC);
                            }

                            //newLC = new LineConstraint( this ,
                            //    block.BoundaryPoints[int.Parse( lineConstraint[0] )] ,
                            //    block.BoundaryPoints[int.Parse( lineConstraint[1] )] ,
                            //    lineConstraint[2] == bool.TrueString ,
                            //    lineConstraint[3] == bool.TrueString );
                            //existingLC = null;
                            //foreach ( MaterialBlock mb in substructs )
                            //{
                            //    existingLC = mb.LineConstraints.Find(
                            //        delegate( LineConstraint lc )
                            //        {
                            //            return lc.Nodes.Contains( newLC.Nodes[0] ) && lc.Nodes.Contains( newLC.Nodes[1] );
                            //        } );
                            //    if ( existingLC != null ) break;
                            //}
                            //if ( existingLC != null )
                            //{
                            //    if ( !block.LineConstraints.Contains( existingLC ) )
                            //        block.LineConstraints.Add( existingLC );
                            //}
                            //else block.LineConstraints.Add( newLC );
                        }

                        numLineLoads = int.Parse(tr.ReadLine().Split('=')[1]);
                        for (int j = 0; j < numLineLoads; j++)
                        {
                            lineLoad = tr.ReadLine().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);

                            p1 = block.BoundaryPoints[int.Parse(lineLoad[0])];
                            p2 = block.BoundaryPoints[int.Parse(lineLoad[1])];

                            existingLL = null;
                            foreach (MaterialBlock mb in substructs)
                            {
                                existingLL = mb.LineLoads.Find(delegate(LineLoad ll) { return(ll.Nodes.Contains(p1) && ll.Nodes.Contains(p2)); });
                                if (existingLL != null)
                                {
                                    break;
                                }
                            }

                            if (existingLL == null)
                            {
                                newLL = new LineLoad(this, p1, p2,
                                                     //newMaterialBlock.BoundaryPoints[int.Parse( lineConstraint[0] )] ,
                                                     //newMaterialBlock.BoundaryPoints[int.Parse( lineConstraint[1] )] ,
                                                     lineLoad[2] == bool.TrueString, double.Parse(lineLoad[3]), double.Parse(lineLoad[4]),
                                                     lineLoad[5] == bool.TrueString, double.Parse(lineLoad[6]), double.Parse(lineLoad[7]));
                            }
                            else
                            {
                                block.LineLoads.Add(existingLL);
                            }

                            //block.LineLoads.Add( new LineLoad( this ,
                            //    block.BoundaryPoints[int.Parse( lineLoad[0] )] ,
                            //    block.BoundaryPoints[int.Parse( lineLoad[1] )] ,
                            //    lineLoad[2] == bool.TrueString , double.Parse( lineLoad[3] ) , double.Parse( lineLoad[4] ) ,
                            //    lineLoad[5] == bool.TrueString , double.Parse( lineLoad[6] ) , double.Parse( lineLoad[7] ) ) );
                        }

                        numPointLoads = int.Parse(tr.ReadLine().Split('=')[1]);
                        for (int j = 0; j < numPointLoads; j++)
                        {
                            pointLoad = tr.ReadLine().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);

                            p1 = block.BoundaryPoints[int.Parse(pointLoad[0])];

                            existingPL = null;
                            foreach (MaterialBlock mb in substructs)
                            {
                                existingPL = mb.PointLoads.Find(delegate(PointLoad pl) { return(pl.Node == p1); });
                                if (existingPL != null)
                                {
                                    break;
                                }
                            }

                            if (existingPL == null)
                            {
                                newPL = new PointLoad(this, p1,
                                                      //newMaterialBlock.BoundaryPoints[int.Parse( lineConstraint[0] )] ,
                                                      //newMaterialBlock.BoundaryPoints[int.Parse( lineConstraint[1] )] ,
                                                      pointLoad[1] == bool.TrueString, double.Parse(pointLoad[2]),
                                                      pointLoad[3] == bool.TrueString, double.Parse(pointLoad[4]));
                            }
                            else
                            {
                                block.PointLoads.Add(existingPL);
                            }

                            //block.PointLoads.Add( new PointLoad( this ,
                            //    block.BoundaryPoints[int.Parse( pointLoad[0] )] ,
                            //    pointLoad[1] == bool.TrueString , double.Parse( pointLoad[2] ) ,
                            //    pointLoad[3] == bool.TrueString , double.Parse( pointLoad[4] ) ) );
                        }



                        tr.ReadLine();
                    }
                }
            }

            // Set selected analysis phase to first (if present)
            if (source.AnalysisPhases.Count > 1)
            {
                ComboBox      phaseList = (ComboBox)((Grid)((GroupBox)((Grid)((ScrollViewer)((Grid)this.Parent).Children[2]).Content).Children[1]).Content).Children[1];
                AnalysisPhase initial   = source.AnalysisPhases[1];
                phaseList.SelectedItem = initial;
            }
        }
Esempio n. 10
0
        private static void LogProcessingStarted(AnalysisPhase phase, ILogger logger)
        {
            string phaseLabel = phase == AnalysisPhase.PreProcessing ? Resources.PhaseLabel_PreProcessing : Resources.PhaseLabel_PostProcessing;

            logger.LogInfo(Resources.MSG_ProcessingStarted, phaseLabel);
        }
Esempio n. 11
0
 private static void LogProcessingStarted(AnalysisPhase phase, ILogger logger)
 {
     string phaseLabel = phase == AnalysisPhase.PreProcessing ? Resources.PhaseLabel_PreProcessing : Resources.PhaseLabel_PostProcessing;
     logger.LogInfo(Resources.MSG_ProcessingStarted, phaseLabel);
 }
Esempio n. 12
0
 private void AddSplitMonitorDataToChart(Chart chart, AnalysisPhase phase, List <PlanSplitMonitor> plans)
 {
     //Table
     if (phase.Cycles.Items.Count > 0)
     {
         var maxSplitLength = 0;
         foreach (var plan in plans)
         {
             var highestSplit = plan.FindHighestRecordedSplitPhase();
             plan.FillMissingSplits(highestSplit);
             try
             {
                 chart.Series["Programed Split"].Points.AddXY(plan.StartTime, plan.Splits[phase.PhaseNumber]);
                 chart.Series["Programed Split"].Points.AddXY(plan.EndTime, plan.Splits[phase.PhaseNumber]);
                 if (plan.Splits[phase.PhaseNumber] > maxSplitLength)
                 {
                     maxSplitLength = plan.Splits[phase.PhaseNumber];
                 }
             }
             catch
             {
                 //System.Windows.MessageBox.Show(ex.ToString());
             }
         }
         foreach (var Cycle in phase.Cycles.Items)
         {
             if (Cycle.TerminationEvent == 4)
             {
                 chart.Series["GapOut"].Points.AddXY(Cycle.StartTime, Cycle.Duration.TotalSeconds);
             }
             if (Cycle.TerminationEvent == 5)
             {
                 chart.Series["MaxOut"].Points.AddXY(Cycle.StartTime, Cycle.Duration.TotalSeconds);
             }
             if (Cycle.TerminationEvent == 6)
             {
                 chart.Series["ForceOff"].Points.AddXY(Cycle.StartTime, Cycle.Duration.TotalSeconds);
             }
             if (Cycle.TerminationEvent == 0)
             {
                 chart.Series["Unknown"].Points.AddXY(Cycle.StartTime, Cycle.Duration.TotalSeconds);
             }
             if (Cycle.HasPed && ShowPedActivity)
             {
                 if (Cycle.PedDuration == 0)
                 {
                     if (Cycle.PedStartTime == DateTime.MinValue)
                     {
                         Cycle.SetPedStart(Cycle.StartTime);
                     }
                     if (Cycle.PedEndTime == DateTime.MinValue)
                     {
                         Cycle.SetPedEnd(Cycle.YellowEvent);
                     }
                 }
                 chart.Series["PedActivity"].Points.AddXY(Cycle.PedStartTime, Cycle.PedDuration);
             }
         }
         SetYAxisMaxAndInterval(chart, phase, maxSplitLength);
     }
 }
Esempio n. 13
0
        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);
                    }
                }
            }
        }