Пример #1
0
        /// <summary>
        /// Fill collection of axis scale segments.
        /// </summary>
        /// <param name="axisSegments">Collection of axis segments.</param>
        private void FillAxisSegmentCollection(AxisScaleSegmentCollection axisSegments)
        {
            // Clear axis segments collection
            axisSegments.Clear();

            // Get statistics for the series attached to the axis
            double minYValue   = 0.0;
            double maxYValue   = 0.0;
            double segmentSize = 0.0;

            double[] segmentMaxValue    = null;
            double[] segmentMinValue    = null;
            int[]    segmentPointNumber = GetSeriesDataStatistics(
                this._totalNumberOfSegments,
                out minYValue,
                out maxYValue,
                out segmentSize,
                out segmentMaxValue,
                out segmentMinValue);
            if (segmentPointNumber == null)
            {
                return;
            }

            // Calculate scale maximum and minimum
            double minimum = minYValue;
            double maximum = maxYValue;

            this.axis.EstimateNumberAxis(
                ref minimum,
                ref maximum,
                this.axis.IsStartedFromZero,
                this.axis.prefferedNumberofIntervals,
                true,
                true);

            // Make sure max/min Y values are not the same
            if (maxYValue == minYValue)
            {
                return;
            }

            // Calculate the percentage of the scale range covered by the data range.
            double dataRangePercent = (maxYValue - minYValue) / ((maximum - minimum) / 100.0);

            // Get sequences of empty segments
            ArrayList emptySequences = new ArrayList();
            bool      doneFlag       = false;

            while (!doneFlag)
            {
                doneFlag = true;

                // Get longest sequence of segments with no points
                int startSegment     = 0;
                int numberOfSegments = 0;
                this.GetLargestSequenseOfSegmentsWithNoPoints(
                    segmentPointNumber,
                    out startSegment,
                    out numberOfSegments);

                // Adjust minimum empty segments  number depending on current segments
                int minEmptySegments = (int)(this._minimumNumberOfEmptySegments * (100.0 / dataRangePercent));
                if (axisSegments.Count > 0 && numberOfSegments > 0)
                {
                    // Find the segment which contain newly found empty segments sequence
                    foreach (AxisScaleSegment axisScaleSegment in axisSegments)
                    {
                        if (startSegment > 0 && (startSegment + numberOfSegments) <= segmentMaxValue.Length - 1)
                        {
                            if (segmentMaxValue[startSegment - 1] >= axisScaleSegment.ScaleMinimum &&
                                segmentMinValue[startSegment + numberOfSegments] <= axisScaleSegment.ScaleMaximum)
                            {
                                // Get percentage of segment scale that is empty and suggested for collapsing
                                double segmentScaleRange = axisScaleSegment.ScaleMaximum - axisScaleSegment.ScaleMinimum;
                                double emptySpaceRange   = segmentMinValue[startSegment + numberOfSegments] - segmentMaxValue[startSegment - 1];
                                double emptySpacePercent = emptySpaceRange / (segmentScaleRange / 100.0);
                                emptySpacePercent = emptySpacePercent / 100 * axisScaleSegment.Size;

                                if (emptySpacePercent > minEmptySegments &&
                                    numberOfSegments > this._minSegmentSize)
                                {
                                    minEmptySegments = numberOfSegments;
                                }
                            }
                        }
                    }
                }

                // Check if found sequence is long enough
                if (numberOfSegments >= minEmptySegments)
                {
                    doneFlag = false;

                    // Store start segment and number of segments in the list
                    emptySequences.Add(startSegment);
                    emptySequences.Add(numberOfSegments);

                    // Check if there are any emty segments sequence found
                    axisSegments.Clear();
                    if (emptySequences.Count > 0)
                    {
                        double segmentFrom = double.NaN;
                        double segmentTo   = double.NaN;

                        // Based on the segments that need to be excluded create axis segments that
                        // will present on the axis scale.
                        int numberOfPoints = 0;
                        for (int index = 0; index < segmentPointNumber.Length; index++)
                        {
                            // Check if current segment is excluded
                            bool excludedSegment = this.IsExcludedSegment(emptySequences, index);

                            // If not excluded segment - update from/to range if they were set
                            if (!excludedSegment &&
                                !double.IsNaN(segmentMinValue[index]) &&
                                !double.IsNaN(segmentMaxValue[index]))
                            {
                                // Calculate total number of points
                                numberOfPoints += segmentPointNumber[index];

                                // Set From/To of the visible segment
                                if (double.IsNaN(segmentFrom))
                                {
                                    segmentFrom = segmentMinValue[index];
                                    segmentTo   = segmentMaxValue[index];
                                }
                                else
                                {
                                    segmentTo = segmentMaxValue[index];
                                }
                            }

                            // If excluded or last segment - add current visible segment range
                            if (!double.IsNaN(segmentFrom) &&
                                (excludedSegment || index == (segmentPointNumber.Length - 1)))
                            {
                                // Make sure To and From do not match
                                if (segmentTo == segmentFrom)
                                {
                                    segmentFrom -= segmentSize;
                                    segmentTo   += segmentSize;
                                }

                                // Add axis scale segment
                                AxisScaleSegment axisScaleSegment = new AxisScaleSegment();
                                axisScaleSegment.ScaleMaximum = segmentTo;
                                axisScaleSegment.ScaleMinimum = segmentFrom;
                                axisScaleSegment.Tag          = numberOfPoints;
                                axisSegments.Add(axisScaleSegment);

                                // Reset segment range
                                segmentFrom    = double.NaN;
                                segmentTo      = double.NaN;
                                numberOfPoints = 0;
                            }
                        }
                    }

                    // Calculate the position of each segment
                    this.SetAxisSegmentPosition(axisSegments);
                }

                // Make sure we do not exceed specified number of breaks
                if ((axisSegments.Count - 1) >= this._maximumNumberOfBreaks)
                {
                    doneFlag = true;
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Get collection of axis segments to present scale breaks.
        /// </summary>
        /// <param name="axisSegments">Collection of axis scale segments.</param>
        internal void GetAxisSegmentForScaleBreaks(AxisScaleSegmentCollection axisSegments)
        {
            // Clear segment collection
            axisSegments.Clear();

            // Check if scale breaks are enabled
            if (this.IsEnabled())
            {
                // Fill collection of segments
                this.FillAxisSegmentCollection(axisSegments);

                // Check if more than 1 segments were defined
                if (axisSegments.Count >= 1)
                {
                    // Get index of segment which scale should start from zero
                    int startFromZeroSegmentIndex = this.GetStartScaleFromZeroSegmentIndex(axisSegments);

                    // Calculate segment interaval and round the scale
                    int index = 0;
                    foreach (AxisScaleSegment axisScaleSegment in axisSegments)
                    {
                        // Check if segment scale should start from zero
                        bool startFromZero = (index == startFromZeroSegmentIndex) ? true : false;

                        // Calculate interval and round scale
                        double minimum = axisScaleSegment.ScaleMinimum;
                        double maximum = axisScaleSegment.ScaleMaximum;
                        axisScaleSegment.Interval = this.axis.EstimateNumberAxis(
                            ref minimum, ref maximum, startFromZero, this.axis.prefferedNumberofIntervals, true, true);
                        axisScaleSegment.ScaleMinimum = minimum;
                        axisScaleSegment.ScaleMaximum = maximum;

                        // Make sure new scale break value range do not exceed axis current scale
                        if (axisScaleSegment.ScaleMinimum < this.axis.Minimum)
                        {
                            axisScaleSegment.ScaleMinimum = this.axis.Minimum;
                        }
                        if (axisScaleSegment.ScaleMaximum > this.axis.Maximum)
                        {
                            axisScaleSegment.ScaleMaximum = this.axis.Maximum;
                        }

                        // Increase segment index
                        ++index;
                    }

                    // Defined axis scale segments cannot overlap.
                    // Check for overlapping and join segments or readjust min/max.
                    bool             adjustPosition = false;
                    AxisScaleSegment prevSegment    = axisSegments[0];
                    for (int segmentIndex = 1; segmentIndex < axisSegments.Count; segmentIndex++)
                    {
                        AxisScaleSegment currentSegment = axisSegments[segmentIndex];
                        if (currentSegment.ScaleMinimum <= prevSegment.ScaleMaximum)
                        {
                            if (currentSegment.ScaleMaximum > prevSegment.ScaleMaximum)
                            {
                                // If segments are partially overlapping make sure the previous
                                // segment scale is extended
                                prevSegment.ScaleMaximum = currentSegment.ScaleMaximum;
                            }

                            // Remove the overlapped segment
                            adjustPosition = true;
                            axisSegments.RemoveAt(segmentIndex);
                            --segmentIndex;
                        }
                        else
                        {
                            prevSegment = currentSegment;
                        }
                    }

                    // Calculate the position of each segment
                    if (adjustPosition)
                    {
                        this.SetAxisSegmentPosition(axisSegments);
                    }
                }
            }
        }