Exemple #1
0
        /// <summary>
        /// Creates the segments of Box and Whisker Series.
        /// </summary>
        public override void CreateSegments()
        {
            ClearUnUsedSegments(this.DataCount);
            ClearUnUsedAdornments(this.DataCount * 5);
            DoubleRange   sbsInfo = this.GetSideBySideInfo(this);
            double        start   = sbsInfo.Start;
            double        end     = sbsInfo.End;
            List <double> xValues = GetXValues();

            ////UpdatePercentile();
            UpdateWhiskerWidth();

            if (adornmentInfo != null)
            {
                UpdateAdornmentLabelPositiion();
            }

            outlierSegments = new List <ChartSegment>();

            if (YCollection == null || YCollection.Count == 0)
            {
                return;
            }

            for (int i = 0; i < DataCount; i++)
            {
                double median, lowerQuartile, upperQuartile, minimum, maximum, x1, x2, average = 0d;

                List <double> outliers = new List <double>();

                var ylist = YCollection[i].Where(x => !double.IsNaN(x)).ToArray();

                if (ylist.Count() > 0)
                {
                    Array.Sort(ylist);
                    average = ylist.Average();
                }

                int yCount = ylist.Length;

                isEvenList = yCount % 2 == 0;

                // Getting the required values.
                x1 = xValues[i] + start;
                x2 = xValues[i] + end;

                if (yCount == 0)
                {
                    ////To create an empty segment for the additional space requirement in range calculation.
                    if (i < Segments.Count)
                    {
                        var segment = Segments[i] as BoxAndWhiskerSegment;
                        segment.SetData(x1, x2, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, xValues[i] + sbsInfo.Median, double.NaN);
                        segment.Item = ActualData[i];
                    }
                    else
                    {
                        BoxAndWhiskerSegment boxEmptySegment = new BoxAndWhiskerSegment(this);
                        boxEmptySegment.SetData(x1, x2, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, xValues[i] + sbsInfo.Median, double.NaN);
                        boxEmptySegment.Item = ActualData[i];
                        Segments.Add(boxEmptySegment);
                    }

                    if (AdornmentsInfo != null)
                    {
                        if (i < Adornments.Count / 5)
                        {
                            SetBoxWhiskerAdornments(sbsInfo, xValues[i], double.NaN, double.NaN, x1, double.NaN, double.NaN, double.NaN, outliers, i);
                        }
                        else
                        {
                            AddBoxWhiskerAdornments(sbsInfo, xValues[i], double.NaN, double.NaN, x1, double.NaN, double.NaN, double.NaN, outliers, i);
                        }
                    }

                    continue;
                }

                if (BoxPlotMode == BoxPlotMode.Exclusive)
                {
                    lowerQuartile = GetExclusiveQuartileValue(ylist, yCount, 0.25d);
                    upperQuartile = GetExclusiveQuartileValue(ylist, yCount, 0.75d);
                    median        = GetExclusiveQuartileValue(ylist, yCount, 0.5d);
                }
                else if (BoxPlotMode == BoxPlotMode.Inclusive)
                {
                    lowerQuartile = GetInclusiveQuartileValue(ylist, yCount, 0.25d);
                    upperQuartile = GetInclusiveQuartileValue(ylist, yCount, 0.75d);
                    median        = GetInclusiveQuartileValue(ylist, yCount, 0.5d);
                }
                else
                {
                    // Take the first half of the list.
                    median = GetMedianValue(ylist);
                    GetQuartileValues(ylist, yCount, out lowerQuartile, out upperQuartile);
                }

                GetMinMaxandOutlier(lowerQuartile, upperQuartile, ylist, out minimum, out maximum, outliers);

                double actualMinimum = minimum;
                double actualMaximum = maximum;

                if (outliers.Count > 0)
                {
                    actualMinimum = Math.Min(outliers.Min(), actualMinimum);
                    actualMaximum = Math.Max(outliers.Max(), actualMaximum);
                }

                ChartSegment currentSegment = null;
                if (i < Segments.Count)
                {
                    currentSegment = Segments[i];
                    var segment = Segments[i] as BoxAndWhiskerSegment;
                    segment.SetData(x1, x2, actualMinimum, minimum, lowerQuartile, median, upperQuartile, maximum, actualMaximum, xValues[i] + sbsInfo.Median, average);
                    WhiskerWidth = whiskerWidth;
                    segment.Item = ActualData[i];
                }
                else
                {
                    BoxAndWhiskerSegment boxSegment = new BoxAndWhiskerSegment(this);
                    boxSegment.SetData(x1, x2, actualMinimum, minimum, lowerQuartile, median, upperQuartile, maximum, actualMaximum, xValues[i] + sbsInfo.Median, average);
                    boxSegment.Item         = ActualData[i];
                    boxSegment.Outliers     = outliers;
                    boxSegment.WhiskerWidth = whiskerWidth;
                    currentSegment          = boxSegment;
                    Segments.Add(boxSegment);
                }

                if (AdornmentsInfo != null)
                {
                    if (i < Adornments.Count / 5)
                    {
                        SetBoxWhiskerAdornments(sbsInfo, xValues[i], minimum, maximum, x1, median, lowerQuartile, upperQuartile, outliers, i);
                    }
                    else
                    {
                        AddBoxWhiskerAdornments(sbsInfo, xValues[i], minimum, maximum, x1, median, lowerQuartile, upperQuartile, outliers, i);
                    }
                }

                if (outliers.Count > 0)
                {
                    foreach (var outlier in outliers)
                    {
                        ScatterSegment scatterSegment = new ScatterSegment();
                        var            position       = x1 + (x2 - x1) / 2;
                        scatterSegment.SetData(position, outlier);
                        scatterSegment.ScatterWidth   = 10;
                        scatterSegment.ScatterHeight  = 10;
                        scatterSegment.Item           = ActualData[i];
                        scatterSegment.Series         = this;
                        scatterSegment.CustomTemplate = OutlierTemplate;

                        // The bindings are done with the segment not with the series.
                        BindProperties(scatterSegment, currentSegment);
                        outlierSegments.Add(scatterSegment);
                    }
                }

                isEvenList = false;
            }

            foreach (ScatterSegment outlierSegment in outlierSegments)
            {
                this.Segments.Add(outlierSegment);
                if (AdornmentsInfo != null)
                {
                    var adornment = this.CreateAdornment(this, outlierSegment.XData, outlierSegment.YData, outlierSegment.XData, outlierSegment.YData);
                    adornment.ActualLabelPosition = topLabelPosition;
                    adornment.Item = outlierSegment.Item;
                    this.Adornments.Add(adornment);
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// creates the segments of StackingColumnSeries.
        /// </summary>
        public override void CreateSegments()
        {
            List <double> xValues = null;
            var           isGrouped = ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed;
            DoubleRange   sbsInfo = this.GetSideBySideInfo(this);
            double        x1, x2, y1, y2;
            double        Origin = this.ActualXAxis != null ? this.ActualXAxis.Origin : 0;

            if (ActualXAxis != null && ActualXAxis.Origin == 0 && ActualYAxis is LogarithmicAxis &&
                (ActualYAxis as LogarithmicAxis).Minimum != null)
            {
                Origin = (double)(ActualYAxis as LogarithmicAxis).Minimum;
            }
            double median = sbsInfo.Delta / 2;

            if (isGrouped)
            {
                xValues = GroupedXValuesIndexes;
            }
            else
            {
                xValues = GetXValues();
            }
            var stackingValues = GetCumulativeStackValues(this);

            if (stackingValues != null)
            {
                YRangeStartValues = stackingValues.StartValues;
                YRangeEndValues   = stackingValues.EndValues;
#if NETFX_CORE
                // Designer crashes when rebuild the SfChart
                bool _isInDesignMode = Windows.ApplicationModel.DesignMode.DesignModeEnabled;
                if (_isInDesignMode)
                {
                    if (YRangeStartValues.Count == 0 && YRangeEndValues.Count == 0)
                    {
                        return;
                    }
                }
#endif
                if (YRangeStartValues == null)
                {
                    YRangeStartValues = (from val in xValues select Origin).ToList();
                }

                if (xValues != null)
                {
                    if (isGrouped)
                    {
                        Segments.Clear();
                        Adornments.Clear();
                        int segmentCount = 0;

                        for (int i = 0; i < DistinctValuesIndexes.Count; i++)
                        {
                            for (int j = 0; j < DistinctValuesIndexes[i].Count; j++)
                            {
                                int index = DistinctValuesIndexes[i][j];
                                if (j < xValues.Count)
                                {
                                    x1 = i + sbsInfo.Start;
                                    x2 = i + sbsInfo.End;
                                    y2 = double.IsNaN(YRangeStartValues[segmentCount]) ? Origin : YRangeStartValues[segmentCount];
                                    y1 = double.IsNaN(YRangeEndValues[segmentCount]) ? Origin : YRangeEndValues[segmentCount];
                                    StackingColumnSegment columnSegment = new StackingColumnSegment(x1, y1, x2, y2, this);
                                    columnSegment.XData = xValues[segmentCount];
                                    columnSegment.YData = GroupedSeriesYValues[0][index];
                                    columnSegment.Item  = GroupedActualData[segmentCount];
                                    Segments.Add(columnSegment);

                                    if (AdornmentsInfo != null)
                                    {
                                        if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Top)
                                        {
                                            AddColumnAdornments(i, GroupedSeriesYValues[0][index], x1, y1, segmentCount, median);
                                        }
                                        else if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Bottom)
                                        {
                                            AddColumnAdornments(i, GroupedSeriesYValues[0][index], x1, y2, segmentCount, median);
                                        }
                                        else
                                        {
                                            AddColumnAdornments(i, GroupedSeriesYValues[0][index], x1, y1 + (y2 - y1) / 2, segmentCount, median);
                                        }
                                    }

                                    segmentCount++;
                                }
                            }
                        }
                    }
                    else
                    {
                        ClearUnUsedSegments(this.DataCount);
                        ClearUnUsedAdornments(this.DataCount);
                        for (int i = 0; i < DataCount; i++)
                        {
                            x1 = xValues[i] + sbsInfo.Start;
                            x2 = xValues[i] + sbsInfo.End;
                            y2 = double.IsNaN(YRangeStartValues[i]) ? Origin : YRangeStartValues[i];
                            y1 = double.IsNaN(YRangeEndValues[i]) ? Origin : YRangeEndValues[i];

                            if (i < Segments.Count)
                            {
                                (Segments[i]).Item = ActualData[i];
                                (Segments[i] as StackingColumnSegment).XData = xValues[i];
                                (Segments[i] as StackingColumnSegment).YData = YValues[i];
                                (Segments[i]).SetData(x1, y1, x2, y2);
                                if (SegmentColorPath != null && !Segments[i].IsEmptySegmentInterior && ColorValues.Count > 0 && !Segments[i].IsSelectedSegment)
                                {
                                    Segments[i].Interior = (Interior != null) ? Interior : ColorValues[i];
                                }
                            }
                            else
                            {
                                StackingColumnSegment columnSegment = new StackingColumnSegment(x1, y1, x2, y2, this);
                                columnSegment.XData = xValues[i];
                                columnSegment.YData = ActualSeriesYValues[0][i];
                                columnSegment.Item  = ActualData[i];
                                Segments.Add(columnSegment);
                            }

                            if (AdornmentsInfo != null)
                            {
                                if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Top)
                                {
                                    AddColumnAdornments(xValues[i], YValues[i], x1, y1, i, median);
                                }
                                else if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Bottom)
                                {
                                    AddColumnAdornments(xValues[i], YValues[i], x1, y2, i, median);
                                }
                                else
                                {
                                    AddColumnAdornments(xValues[i], YValues[i], x1, y1 + (y2 - y1) / 2, i, median);
                                }
                            }
                        }
                    }

                    if (ShowEmptyPoints)
                    {
                        if (this is StackingColumn100Series)
                        {
                            var index = EmptyPointIndexes[0];

                            if (EmptyPointStyle == Charts.EmptyPointStyle.Symbol || EmptyPointStyle == Charts.EmptyPointStyle.SymbolAndInterior)
                            {
                                foreach (var n in index)
                                {
                                    this.ActualSeriesYValues[0][n] = double.IsNaN(YRangeEndValues[n]) ? 0 : this.YRangeEndValues[n];
                                }
                            }

                            UpdateEmptyPointSegments(xValues, true);
                            ReValidateYValues(EmptyPointIndexes);
                            ValidateYValues();
                        }
                        else
                        {
                            UpdateEmptyPointSegments(xValues, true);
                        }
                    }
                }
            }
        }
        internal static DoubleRange ApplyBusinessHoursRangePadding(DateTimeAxis axis, DoubleRange range, double interval, DateTimeRangePadding rangePadding, DateTimeIntervalType intervalType)
        {
            DateTime startDate = range.Start.FromOADate();
            DateTime endDate   = range.End.FromOADate();
            var      startTime = new TimeSpan((int)axis.OpenTime, 0, 0);
            var      endTime   = new TimeSpan((int)axis.CloseTime, 0, 0);

            if (rangePadding == DateTimeRangePadding.Round || rangePadding == DateTimeRangePadding.Additional)
            {
                switch (intervalType)
                {
                case DateTimeIntervalType.Years:
                    int startYear = (int)((int)(startDate.Year / interval) * interval);
                    int endYear   = endDate.Year + (startDate.Year - startYear);
                    if (startYear <= 0)
                    {
                        startYear = 1;
                    }

                    if (endYear <= 0)
                    {
                        endYear = 1;
                    }

                    if (rangePadding == DateTimeRangePadding.Round)
                    {
                        range = new DoubleRange(new DateTime(startYear, 1, 1, 0, 0, 0).ToOADate(), new DateTime(endYear, 12, 31, 23, 59, 59).ToOADate());
                    }
                    else
                    {
                        range = new DoubleRange(new DateTime(startYear - (int)interval, 1, 1, 0, 0, 0).ToOADate(), new DateTime(endYear + (int)interval, 12, 31, 23, 59, 59).ToOADate());
                    }
                    break;

                case DateTimeIntervalType.Months:
                    int month = (int)((int)(startDate.Month / interval) * interval);
                    if (month <= 0)
                    {
                        month = 1;
                    }

                    int endmonth = range.End.FromOADate().Month + (startDate.Month - month);
                    if (endmonth <= 0)
                    {
                        endmonth = 1;
                    }

                    if (endmonth > 12)
                    {
                        endmonth = 12;
                    }
                    if (rangePadding == DateTimeRangePadding.Round)
                    {
                        range = new DoubleRange(new DateTime(startDate.Year, month, 1, 0, 0, 0).ToOADate(), new DateTime(endDate.Year, endmonth, endmonth == 2 ? 28 : 30, 0, 0, 0).ToOADate());
                    }
                    else
                    {
                        range = new DoubleRange(new DateTime(startDate.Year, month, 1, 0, 0, 0).AddMonths((int)(-interval)).ToOADate(), new DateTime(endDate.Year, endmonth, endmonth == 2 ? 28 : 30, 0, 0, 0).AddMonths((int)interval).ToOADate());
                    }
                    break;

                case DateTimeIntervalType.Days:
                    int day = (int)((int)(startDate.Day / interval) * interval);

                    if (day <= 0)
                    {
                        day = 1;
                    }

                    int endday = startDate.Day - day;
                    if (endday < 0)
                    {
                        endday = 1;
                    }

                    if (rangePadding == DateTimeRangePadding.Round)
                    {
                        range = new DoubleRange(
                            new DateTime(startDate.Year, startDate.Month, day, startTime.Hours, startTime.Minutes, startTime.Seconds).ToOADate(),
                            new DateTime(endDate.Year, endDate.Month, endDate.Day, endTime.Hours, endTime.Minutes, endTime.Seconds).AddDays(endday).ToOADate());
                    }
                    else
                    {
                        range = new DoubleRange(new DateTime(startDate.Year, startDate.Month, day, startTime.Hours, startTime.Minutes, startTime.Seconds).AddDays(-interval).ToOADate(),
                                                new DateTime(endDate.Year, endDate.Month, endDate.Day, endTime.Hours, endTime.Minutes, endTime.Seconds).AddDays(interval + endday).ToOADate());
                    }
                    break;

                case DateTimeIntervalType.Hours:
                    if (rangePadding == DateTimeRangePadding.Round)
                    {
                        range = new DoubleRange(
                            new DateTime(
                                startDate.Year,
                                startDate.Month,
                                startDate.Day,
                                startTime.Hours,
                                0,
                                0).ToOADate(), new DateTime(
                                endDate.Year,
                                endDate.Month,
                                endDate.Day,
                                endTime.Hours,
                                0,
                                0).ToOADate());
                    }
                    else
                    {
                        range = new DoubleRange(new DateTime(
                                                    startDate.Year,
                                                    startDate.Month,
                                                    startDate.Day,
                                                    startDate.Hour,
                                                    0,
                                                    0).AddHours(-interval).ToOADate(), new DateTime(
                                                    endDate.Year,
                                                    endDate.Month,
                                                    endDate.Day,
                                                    endDate.Hour,
                                                    0,
                                                    0).AddHours(interval).ToOADate());
                    }
                    break;

                case DateTimeIntervalType.Minutes:
                    int minute    = (int)((int)(startDate.Minute / interval) * interval);
                    int endminute = range.End.FromOADate().Minute + (startDate.Minute - minute);
                    if (rangePadding == DateTimeRangePadding.Round)
                    {
                        range = new DoubleRange(
                            new DateTime(
                                startDate.Year,
                                startDate.Month,
                                startDate.Day,
                                startDate.Hour,
                                minute,
                                0).ToOADate(), new DateTime(
                                endDate.Year,
                                endDate.Month,
                                endDate.Day,
                                endDate.Hour,
                                endminute,
                                0).ToOADate());
                    }
                    else
                    {
                        range = new DoubleRange(new DateTime(
                                                    startDate.Year,
                                                    startDate.Month,
                                                    startDate.Day,
                                                    startDate.Hour,
                                                    startDate.Minute,
                                                    0).AddMinutes(-interval).ToOADate(), new DateTime(
                                                    endDate.Year,
                                                    endDate.Month,
                                                    endDate.Day,
                                                    endDate.Hour,
                                                    endDate.Minute,
                                                    0).AddMinutes(interval).ToOADate());
                    }
                    break;

                case DateTimeIntervalType.Seconds:
                    int second    = (int)((int)(startDate.Second / interval) * interval);
                    int endsecond = range.End.FromOADate().Second + (startDate.Second - second);
                    if (rangePadding == DateTimeRangePadding.Round)
                    {
                        range = new DoubleRange(
                            new DateTime(
                                startDate.Year,
                                startDate.Month,
                                startDate.Day,
                                startDate.Hour,
                                startDate.Minute,
                                second,
                                0).ToOADate(),
                            new DateTime(
                                endDate.Year,
                                endDate.Month,
                                endDate.Day,
                                endDate.Hour,
                                endDate.Minute,
                                endsecond,
                                0).ToOADate());
                    }
                    else
                    {
                        range = new DoubleRange(new DateTime(
                                                    startDate.Year,
                                                    startDate.Month,
                                                    startDate.Day,
                                                    startDate.Hour,
                                                    startDate.Minute,
                                                    startDate.Second,
                                                    0).AddSeconds(-interval).ToOADate(), new DateTime(
                                                    endDate.Year,
                                                    endDate.Month,
                                                    endDate.Day,
                                                    endDate.Hour,
                                                    endDate.Minute,
                                                    endDate.Second,
                                                    0).AddSeconds(interval).ToOADate());
                    }
                    break;

                case DateTimeIntervalType.Milliseconds:
                    int milliseconds    = (int)((int)(startDate.Millisecond / interval) * interval);
                    int endmilliseconds = range.End.FromOADate().Millisecond + (startDate.Millisecond - milliseconds);
                    if (rangePadding == DateTimeRangePadding.Round)
                    {
                        range = new DoubleRange(
                            new DateTime(
                                startDate.Year,
                                startDate.Month,
                                startDate.Day,
                                startDate.Hour,
                                startDate.Minute,
                                startDate.Second,
                                milliseconds).ToOADate(),
                            new DateTime(
                                endDate.Year,
                                endDate.Month,
                                endDate.Day,
                                endDate.Hour,
                                endDate.Minute,
                                endDate.Second,
                                endmilliseconds).ToOADate());
                    }
                    else
                    {
                        range = new DoubleRange(
                            new DateTime(
                                startDate.Year,
                                startDate.Month,
                                startDate.Day,
                                startDate.Hour,
                                startDate.Minute,
                                startDate.Second,
                                startDate.Millisecond).AddMilliseconds(-interval).ToOADate(),
                            new DateTime(
                                endDate.Year,
                                endDate.Month,
                                endDate.Day,
                                endDate.Hour,
                                endDate.Minute,
                                endDate.Second,
                                endDate.Millisecond).AddMilliseconds(interval).ToOADate());
                    }
                    break;
                }

                var newStartDate = range.Start.FromOADate();
                var newEndDate   = range.End.FromOADate();

                newStartDate = newStartDate.ValidateNonWorkingDate(axis.InternalWorkingDays, true, axis.NonWorkingDays.Count);
                newStartDate = newStartDate.ValidateNonWorkingHours(axis.OpenTime, axis.CloseTime, true);
                newStartDate = newStartDate.ValidateNonWorkingDate(axis.InternalWorkingDays, true, axis.NonWorkingDays.Count);

                newEndDate = newEndDate.ValidateNonWorkingDate(axis.InternalWorkingDays, false, axis.NonWorkingDays.Count);
                newEndDate = newEndDate.ValidateNonWorkingHours(axis.OpenTime, axis.CloseTime, false);
                newEndDate = newEndDate.ValidateNonWorkingDate(axis.InternalWorkingDays, false, axis.NonWorkingDays.Count);

                return(new DoubleRange(newStartDate.ToOADate(), newEndDate.ToOADate()));
            }

            return(range);
        }
Exemple #4
0
        /// <summary>
        /// Finds the nearest point in ChartSeries relative to the mouse point/touch position.
        /// </summary>
        /// <param name="point">The co-ordinate point representing the current mouse point /touch position.</param>
        /// <param name="x">x-value of the nearest point.</param>
        /// <param name="y">y-value of the nearest point</param>
        /// <param name="stackedYValue"></param>
        public override void FindNearestChartPoint(Point point, out double x, out double y, out double stackedYValue)
        {
            x             = double.NaN;
            y             = 0d;
            stackedYValue = double.NaN;
            Point nearPoint = new Point();

            if (this.IsIndexed || !(this.ActualXValues is IList <double>))
            {
                if (ActualArea != null)
                {
                    double xStart = ActualXAxis.VisibleRange.Start;
                    double xEnd   = ActualXAxis.VisibleRange.End;
                    point = new Point(ActualArea.PointToValue(ActualXAxis, point), ActualArea.PointToValue(ActualYAxis, point));
                    double range = Math.Round(point.X);
                    {
                        var count = this.YCollection.Count;
                        if (range <= xEnd && range >= xStart && range < count && range >= 0)
                        {
                            x = range;
                        }
                    }
                }
            }
            else
            {
                IList <double> xValues = this.ActualXValues as IList <double>;
                nearPoint.X = ActualXAxis.VisibleRange.Start;

                if (IsSideBySide)
                {
                    DoubleRange sbsInfo = this.GetSideBySideInfo(this);
                    nearPoint.X = ActualXAxis.VisibleRange.Start + sbsInfo.Start;
                }

                point = new Point(ActualArea.PointToValue(ActualXAxis, point), ActualArea.PointToValue(ActualYAxis, point));

                for (int i = 0; i < DataCount; i++)
                {
                    double x1 = xValues[i];
                    double y1 = 0d;

                    if (this.ActualXAxis is LogarithmicAxis)
                    {
                        var logAxis = ActualXAxis as LogarithmicAxis;
                        if (Math.Abs(point.X - x1) <= Math.Abs(point.X - nearPoint.X) &&
                            (Math.Log(point.X, logAxis.LogarithmicBase) > ActualXAxis.VisibleRange.Start &&
                             Math.Log(point.X, logAxis.LogarithmicBase) < ActualXAxis.VisibleRange.End))
                        {
                            nearPoint = new Point(x1, y1);
                            x         = xValues[i];
                        }
                    }
                    else if (Math.Abs((point.X - x1)) <= Math.Abs((point.X - nearPoint.X)) &&
                             (point.X > ActualXAxis.VisibleRange.Start) && (point.X < ActualXAxis.VisibleRange.End))
                    {
                        nearPoint = new Point(x1, y1);
                        x         = xValues[i];
                    }
                }
            }
        }
        private void OnCalculateSegmentValues(
            out double x1,
            out double x2,
            out double y1,
            out double y2,
            int i,
            double origin,
            double xVal)
        {
            DoubleRange sbsInfo = this.GetSideBySideInfo(this);

            #region Datapoint calculation

            x1 = xVal + sbsInfo.Start;
            x2 = xVal + sbsInfo.End;

            if (i == 0)
            {
                if (YValues[i] >= 0)
                {
                    y1 = YValues[i];
                    y2 = origin;
                }
                else if (double.IsNaN(YValues[i]))
                {
                    y2 = origin;
                    y1 = origin;
                }
                else
                {
                    y2 = YValues[i];
                    y1 = origin;
                }
            }
            else
            {
                WaterfallSegment prevSegment = Segments[i - 1] as WaterfallSegment;

                // Positive value calculation
                if (YValues[i] >= 0)
                {
                    if (YValues[i - 1] >= 0 || prevSegment.SegmentType == WaterfallSegmentType.Sum)
                    {
                        y1 = YValues[i] + prevSegment.Top;
                        y2 = prevSegment.Top;
                    }
                    else if (double.IsNaN(YValues[i - 1]))
                    {
                        y1 = YValues[i] == 0 ? prevSegment.Bottom
                            : prevSegment.Bottom + YValues[i];
                        y2 = prevSegment.Bottom;
                    }
                    else
                    {
                        y1 = YValues[i] + prevSegment.Bottom;
                        y2 = prevSegment.Bottom;
                    }
                }
                else if (double.IsNaN(YValues[i]))
                {
                    // Empty value calculation
                    if (YValues[i - 1] >= 0 || prevSegment.SegmentType == WaterfallSegmentType.Sum)
                    {
                        y1 = y2 = prevSegment.Top;
                    }
                    else
                    {
                        y1 = y2 = prevSegment.Bottom;
                    }
                }
                else
                {
                    // Negative value calculation
                    if (YValues[i - 1] >= 0 || prevSegment.SegmentType == WaterfallSegmentType.Sum)
                    {
                        y1 = prevSegment.Top;
                        y2 = YValues[i] + prevSegment.Top;
                    }
                    else
                    {
                        y1 = prevSegment.Bottom;
                        y2 = YValues[i] + prevSegment.Bottom;
                    }
                }
            }
            #endregion
        }
        /// <summary>
        /// This method is used to gets the selected data point segment pixel positions
        /// </summary>
        internal void GenerateStackingBarPixels()
        {
            WriteableBitmap bmp = Area.fastRenderSurface;

            ChartTransform.ChartCartesianTransformer cartesianTransformer = CreateTransformer(
                new Size(
                    Area.SeriesClipRect.Width,
                    Area.SeriesClipRect.Height),
                true) as ChartTransform.ChartCartesianTransformer;

            bool isLogarithmic = cartesianTransformer.XAxis.IsLogarithmic || cartesianTransformer.YAxis.IsLogarithmic;
            bool x_isInversed  = cartesianTransformer.XAxis.IsInversed;
            bool y_isInversed  = cartesianTransformer.YAxis.IsInversed;

            double        x1ChartVal, x2ChartVal, y1ChartVal, y2ChartVal;
            double        xStart, xEnd, yStart, yEnd, width, height, left, top;
            int           i       = dataPoint.Index;
            DoubleRange   sbsInfo = this.GetSideBySideInfo(this);
            List <double> xValues = GetStackingSeriesXValues(this);

            if (!this.IsIndexed)
            {
                x1ChartVal = xValues[i] + sbsInfo.Start;
                x2ChartVal = xValues[i] + sbsInfo.End;
                y1ChartVal = YRangeEndValues[i];
                y2ChartVal = YRangeStartValues[i];
            }
            else
            {
                x1ChartVal = i + sbsInfo.Start;
                x2ChartVal = i + sbsInfo.End;
                y1ChartVal = YRangeEndValues[i];
                y2ChartVal = YRangeStartValues[i];
            }

            xStart = cartesianTransformer.XAxis.VisibleRange.Start;
            xEnd   = cartesianTransformer.XAxis.VisibleRange.End;

            yStart = cartesianTransformer.YAxis.VisibleRange.Start;
            yEnd   = cartesianTransformer.YAxis.VisibleRange.End;

            width  = cartesianTransformer.XAxis.RenderedRect.Height;
            height = cartesianTransformer.YAxis.RenderedRect.Width;

            // WPF-14441 - Calculating Bar Position for the Series
            left = Area.SeriesClipRect.Right - cartesianTransformer.YAxis.RenderedRect.Right;
            top  = Area.SeriesClipRect.Bottom - cartesianTransformer.XAxis.RenderedRect.Bottom;

            Size availableSize = new Size(width, height);

            if (x_isInversed)
            {
                double temp = xStart;
                xStart = xEnd;
                xEnd   = temp;
            }

            if (y_isInversed)
            {
                double temp = yStart;
                yStart = yEnd;
                yEnd   = temp;
            }

            float x1Value = 0, x2Value = 0, y1Value = 0, y2Value = 0;

            // Removed the screen point calculation methods and added the point to value method.
            if (!isLogarithmic)
            {
                double x1Val = x_isInversed
                                   ? x2ChartVal < xEnd ? xEnd : x2ChartVal
                                   : x1ChartVal < xStart ? xStart : x1ChartVal;
                double x2Val = x_isInversed
                                   ? x1ChartVal > xStart ? xStart : x1ChartVal
                                   : x2ChartVal > xEnd ? xEnd : x2ChartVal;

                double y1Val = y_isInversed
                                   ? y2ChartVal > yStart ? yStart : y2ChartVal <yEnd?yEnd : y2ChartVal
                                                                                : y1ChartVal> yEnd ? yEnd : y1ChartVal < yStart ? yStart : y1ChartVal;
                double y2Val = y_isInversed
                                   ? y1ChartVal <yEnd?yEnd : y1ChartVal> yStart ? yStart : y1ChartVal
                                   : y2ChartVal <yStart?yStart : y2ChartVal> yEnd ? yEnd : y2ChartVal;
                x1Value = (float)(top + (availableSize.Width) * cartesianTransformer.XAxis.ValueToCoefficientCalc(x1Val));
                x2Value = (float)(top + (availableSize.Width) * cartesianTransformer.XAxis.ValueToCoefficientCalc(x2Val));
                y1Value = (float)(left + (availableSize.Height) * (1 - cartesianTransformer.YAxis.ValueToCoefficientCalc(y1Val)));
                y2Value = (float)(left + (availableSize.Height) * (1 - cartesianTransformer.YAxis.ValueToCoefficientCalc(y2Val)));
            }
            else
            {
                double xBase = cartesianTransformer.XAxis.IsLogarithmic ? (cartesianTransformer.XAxis as LogarithmicAxis).LogarithmicBase : 1;
                double yBase = cartesianTransformer.YAxis.IsLogarithmic ? (cartesianTransformer.YAxis as LogarithmicAxis).LogarithmicBase : 1;

                double logx1 = xBase == 1 ? x1ChartVal : Math.Log(x1ChartVal, xBase);
                double logx2 = xBase == 1 ? x2ChartVal : Math.Log(x2ChartVal, xBase);
                double logy1 = yBase == 1 ? y1ChartVal : Math.Log(y1ChartVal, yBase);
                double logy2 = yBase == 1 ? y2ChartVal : Math.Log(y2ChartVal, yBase);

                double x1Val = x_isInversed ? logx2 < xEnd ? xEnd : logx2 : logx1 < xStart ? xStart : logx1;
                double x2Val = x_isInversed ? logx1 > xStart ? xStart : logx1 : logx2 > xEnd ? xEnd : logx2;

                double y1Val = y_isInversed
                                   ? logy2 > yStart ? yStart : logy2 <yEnd?yEnd : logy2
                                                                      : logy1> yEnd ? yEnd : logy1 < yStart ? yStart : logy1;

                double y2Val = y_isInversed
                                   ? logy1 <yEnd?yEnd : logy1> yStart ? yStart : logy1
                                   : logy2 <yStart?yStart : logy2> yEnd ? yEnd : logy2;
                x1Value = (float)(top + (availableSize.Width) * cartesianTransformer.XAxis.ValueToCoefficientCalc(x1Val));
                x2Value = (float)(top + (availableSize.Width) * cartesianTransformer.XAxis.ValueToCoefficientCalc(x2Val));
                y1Value = (float)(left + (availableSize.Height) * (1 - cartesianTransformer.YAxis.ValueToCoefficientCalc(y1Val)));
                y2Value = (float)(left + (availableSize.Height) * (1 - cartesianTransformer.YAxis.ValueToCoefficientCalc(y2Val)));
            }

            float x1 = 0, x2, y1, y2, diff = 0;

            width  = (int)Area.SeriesClipRect.Width;
            height = (int)Area.SeriesClipRect.Height;

            x1 = x1Value;
            x2 = x2Value;
            y1 = y1ChartVal > 0 ? y1Value : y2Value;
            y2 = y1ChartVal > 0 ? y2Value : y1Value;

            var spacingSegment = this as ISegmentSpacing;

            if (spacingSegment != null)
            {
                double spacing = spacingSegment.SegmentSpacing;
                if (spacing > 0 && spacing <= 1)
                {
                    double leftpos  = spacingSegment.CalculateSegmentSpacing(spacing, x1, x2);
                    double rightpos = spacingSegment.CalculateSegmentSpacing(spacing, x2, x1);
                    x2 = (float)leftpos;
                    x1 = (float)rightpos;
                }
            }

            diff = x2 - x1;

            selectedSegmentPixels.Clear();

            if (y1 < y2)
            {
                selectedSegmentPixels = bmp.GetRectangle(
                    (int)width,
                    (int)height,
                    (int)(width - y2),
                    (int)(height - x1 - diff),
                    (int)(width - y1),
                    (int)(height - x1),
                    selectedSegmentPixels);
            }
            else
            {
                selectedSegmentPixels = bmp.GetRectangle(
                    (int)width,
                    (int)height,
                    (int)(width - y1),
                    (int)(height - x1 - diff),
                    (int)(width - y2),
                    (int)(height - x1),
                    selectedSegmentPixels);
            }
        }
Exemple #7
0
        /// <summary>
        /// Creates the segments of CandleSeries.
        /// </summary>
        public override void CreateSegments()
        {
            DoubleRange   sbsInfo = this.GetSideBySideInfo(this);
            double        center  = sbsInfo.Median;
            List <double> xValues = null;

            if (ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed)
            {
                xValues = GroupedXValuesIndexes;
            }
            else
            {
                xValues = GetXValues();
            }
            IList <double> values = GetComparisionModeValues();

            if (xValues != null)
            {
                ClearUnUsedSegments(this.DataCount);

                if (AdornmentsInfo != null)
                {
                    if (AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.TopAndBottom)
                    {
                        ClearUnUsedAdornments(this.DataCount * 4);
                    }
                    else
                    {
                        ClearUnUsedAdornments(this.DataCount * 2);
                    }
                }

                if (this.ActualXAxis is CategoryAxis && (!(this.ActualXAxis as CategoryAxis).IsIndexed))
                {
                    Segments.Clear();
                    Adornments.Clear();
                    for (int i = 0; i < xValues.Count; i++)
                    {
                        if (i < xValues.Count && GroupedSeriesYValues[0].Count > i)
                        {
                            double x1     = xValues[i] + sbsInfo.Start;
                            double x2     = xValues[i] + sbsInfo.End;
                            double y1     = GroupedSeriesYValues[2][i];
                            double y2     = GroupedSeriesYValues[3][i];
                            bool   isbull = false;
                            if (i == 0 || this.ComparisonMode == FinancialPrice.None)
                            {
                                isbull = GroupedSeriesYValues[3][i] > GroupedSeriesYValues[2][i];
                            }
                            else
                            {
                                isbull = values[i] >= values[i - 1];
                            }
                            ChartPoint cdpBottomLeft = new ChartPoint(x1, y1);
                            ChartPoint cdpRightTop   = new ChartPoint(x2, y2);

                            ChartPoint hipoint = new ChartPoint(xValues[i] + center, GroupedSeriesYValues[0][i]);
                            ChartPoint lopoint = new ChartPoint(xValues[i] + center, GroupedSeriesYValues[1][i]);
                            var        segment = new CandleSegment();
                            segment.Series        = this;
                            segment.BullFillColor = BullFillColor;
                            segment.BearFillColor = BearFillColor;
                            segment.Item          = ActualData[i];
                            segment.SetData(cdpBottomLeft, cdpRightTop, hipoint, lopoint, isbull);
                            segment.High  = GroupedSeriesYValues[0][i];
                            segment.Low   = GroupedSeriesYValues[1][i];
                            segment.Open  = GroupedSeriesYValues[2][i];
                            segment.Close = GroupedSeriesYValues[3][i];
                            Segments.Add(segment);

                            if (AdornmentsInfo != null)
                            {
                                AddAdornments(xValues[i], hipoint, lopoint, cdpBottomLeft, cdpBottomLeft, cdpRightTop, cdpRightTop, i, 0);
                            }
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < DataCount; i++)
                    {
                        double x1     = xValues[i] + sbsInfo.Start;
                        double x2     = xValues[i] + sbsInfo.End;
                        double y1     = OpenValues[i];
                        double y2     = CloseValues[i];
                        bool   isbull = false;
                        if (i == 0 || this.ComparisonMode == FinancialPrice.None)
                        {
                            isbull = CloseValues[i] > OpenValues[i];
                        }
                        else
                        {
                            isbull = values[i] >= values[i - 1];
                        }
                        ChartPoint cdpBottomLeft = new ChartPoint(x1, y1);
                        ChartPoint cdpRightTop   = new ChartPoint(x2, y2);

                        ChartPoint hipoint = new ChartPoint(xValues[i] + center, HighValues[i]);
                        ChartPoint lopoint = new ChartPoint(xValues[i] + center, LowValues[i]);

                        if (i < Segments.Count)
                        {
                            (Segments[i]).SetData(cdpBottomLeft, cdpRightTop, hipoint, lopoint, isbull);
                            (Segments[i] as CandleSegment).High  = HighValues[i];
                            (Segments[i] as CandleSegment).Low   = LowValues[i];
                            (Segments[i] as CandleSegment).Open  = OpenValues[i];
                            (Segments[i] as CandleSegment).Close = CloseValues[i];
                            Segments[i].Item = ActualData[i];
                        }
                        else
                        {
                            var segment = new CandleSegment();
                            segment.Series        = this;
                            segment.BullFillColor = BullFillColor;
                            segment.BearFillColor = BearFillColor;
                            segment.Item          = ActualData[i];
                            segment.SetData(cdpBottomLeft, cdpRightTop, hipoint, lopoint, isbull);
                            segment.High  = HighValues[i];
                            segment.Low   = LowValues[i];
                            segment.Open  = OpenValues[i];
                            segment.Close = CloseValues[i];
                            Segments.Add(segment);
                        }

                        if (AdornmentsInfo != null)
                        {
                            AddAdornments(xValues[i], hipoint, lopoint, cdpBottomLeft, cdpBottomLeft, cdpRightTop, cdpRightTop, i, 0);
                        }
                    }
                }

                if (ShowEmptyPoints)
                {
                    UpdateEmptyPointSegments(xValues, true);
                }
            }
        }
Exemple #8
0
        protected internal override double CalculateNiceInterval(DoubleRange actualRange, Size availableSize)
        {
            DateTime dateTimeMin = actualRange.Start.FromOADate();
            DateTime dateTimeMax = actualRange.End.FromOADate();
            TimeSpan timeSpan    = dateTimeMax.Subtract(dateTimeMin);
            double   interval    = 0;

            switch (IntervalType)
            {
            case DateTimeIntervalType.Years:
                interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalDays / 365), availableSize);
                break;

            case DateTimeIntervalType.Months:
                interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalDays / 30), availableSize);
                break;

            case DateTimeIntervalType.Days:
                interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalDays), availableSize);
                break;

            case DateTimeIntervalType.Hours:
                interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalHours), availableSize);
                break;

            case DateTimeIntervalType.Minutes:
                interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalMinutes), availableSize);
                break;

            case DateTimeIntervalType.Seconds:
                interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalSeconds), availableSize);
                break;

            case DateTimeIntervalType.Milliseconds:
                interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalMilliseconds), availableSize);
                break;

            case DateTimeIntervalType.Auto:
                interval = actualRange.Delta / GetActualDesiredIntervalsCount(availableSize);
                if (interval <= base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalDays / 365), availableSize))
                {
                    interval           = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalDays / 365), availableSize);
                    ActualIntervalType = DateTimeIntervalType.Years;
                }
                else if (interval <= base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalDays / 30), availableSize))
                {
                    interval           = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalDays / 30), availableSize);
                    ActualIntervalType = DateTimeIntervalType.Months;
                }
                else if (interval <= base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalDays), availableSize))
                {
                    interval           = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalDays), availableSize);
                    ActualIntervalType = DateTimeIntervalType.Days;
                }
                else if (interval <= base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalHours), availableSize))
                {
                    interval           = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalHours), availableSize);
                    ActualIntervalType = DateTimeIntervalType.Hours;
                }
                else if (interval <= base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalMinutes), availableSize))
                {
                    interval           = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalMinutes), availableSize);
                    ActualIntervalType = DateTimeIntervalType.Minutes;
                }
                else if (interval <= base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalSeconds), availableSize))
                {
                    interval           = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalSeconds), availableSize);
                    ActualIntervalType = DateTimeIntervalType.Seconds;
                }
                else if (interval <= base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalMilliseconds), availableSize))
                {
                    interval           = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalMilliseconds), availableSize);
                    ActualIntervalType = DateTimeIntervalType.Milliseconds;
                }

                break;
            }

            return(Math.Max(1d, interval));
        }
        /// <summary>
        /// This method used to get the chart data at an index.
        /// </summary>
        /// <param name="mousePos"></param>
        /// <returns></returns>
        internal override void GeneratePixels()
        {
            WriteableBitmap bmp = Area.fastRenderSurface;

            ChartTransform.ChartCartesianTransformer cartesianTransformer = CreateTransformer(new Size(Area.SeriesClipRect.Width,
                                                                                                       Area.SeriesClipRect.Height),
                                                                                              true) as ChartTransform.ChartCartesianTransformer;

            bool x_isInversed = cartesianTransformer.XAxis.IsInversed;
            bool y_isInversed = cartesianTransformer.YAxis.IsInversed;

            DoubleRange sbsInfo = GetSideBySideInfo(this);
            double      center  = sbsInfo.Median;
            double      Left    = sbsInfo.Start;
            double      Right   = sbsInfo.End;

            double xChartValue      = dataPoint.XData;
            double yOpenChartValue  = dataPoint.Open;
            double yCloseChartValue = dataPoint.Close;
            double yHighChartValue  = dataPoint.High;
            double yLowChartValue   = dataPoint.Low;
            int    i = dataPoint.Index;
            float  xValue, yHiValue, yLoValue, yOpenStartValue, yOpenEndValue, yCloseValue, yCloseEndValue;

            double spacing  = (this as ISegmentSpacing).SegmentSpacing;
            double leftpos  = (this as ISegmentSpacing).CalculateSegmentSpacing(spacing, Right, Left);
            double rightpos = (this as ISegmentSpacing).CalculateSegmentSpacing(spacing, Left, Right);

            if (spacing > 0 && spacing <= 1)
            {
                Left  = leftpos;
                Right = rightpos;
            }

            double highValue     = yHighChartValue;
            double lowValue      = yLowChartValue;
            var    alignedValues = Segments[0].AlignHiLoSegment(yOpenChartValue, yCloseChartValue, highValue, lowValue);

            highValue = alignedValues[0];
            lowValue  = alignedValues[1];

            if (IsIndexed)
            {
                Point hiPoint        = cartesianTransformer.TransformToVisible(i + center, highValue);
                Point loPoint        = cartesianTransformer.TransformToVisible(xChartValue + center, lowValue);
                Point startopenpoint = cartesianTransformer.TransformToVisible(xChartValue + center, yOpenChartValue);
                Point endopenpoint   = cartesianTransformer.TransformToVisible(xChartValue + Left, yOpenChartValue);
                Point endclosepoint  = cartesianTransformer.TransformToVisible(i + Right, yCloseChartValue);

                if (!IsActualTransposed)
                {
                    xValue          = (float)hiPoint.X;
                    yHiValue        = (float)hiPoint.Y;
                    yLoValue        = (float)loPoint.Y;
                    yOpenStartValue = (float)startopenpoint.Y;
                    yOpenEndValue   = (float)endopenpoint.X;
                    yCloseValue     = (float)endclosepoint.Y;
                    yCloseEndValue  = (float)endclosepoint.X;
                }
                else
                {
                    xValue          = (float)hiPoint.Y;
                    yHiValue        = (float)hiPoint.X;
                    yLoValue        = (float)loPoint.X;
                    yOpenStartValue = (float)startopenpoint.X;
                    yOpenEndValue   = (float)endopenpoint.Y;
                    yCloseValue     = (float)endclosepoint.X;
                    yCloseEndValue  = (float)endclosepoint.Y;
                }
            }
            else
            {
                Point hiPoint        = cartesianTransformer.TransformToVisible(xChartValue + center, highValue);
                Point loPoint        = cartesianTransformer.TransformToVisible(xChartValue + center, lowValue);
                Point startopenpoint = cartesianTransformer.TransformToVisible(xChartValue + center, yOpenChartValue);
                Point endopenpoint   = cartesianTransformer.TransformToVisible(xChartValue + Left, yOpenChartValue);
                Point endclosepoint  = cartesianTransformer.TransformToVisible(xChartValue + Right, yCloseChartValue);

                if (!IsActualTransposed)
                {
                    xValue          = (float)hiPoint.X;
                    yHiValue        = (float)hiPoint.Y;
                    yLoValue        = (float)loPoint.Y;
                    yOpenStartValue = (float)startopenpoint.Y;
                    yOpenEndValue   = (float)endopenpoint.X;
                    yCloseValue     = (float)endclosepoint.Y;
                    yCloseEndValue  = (float)endclosepoint.X;
                }
                else
                {
                    xValue          = (float)hiPoint.Y;
                    yHiValue        = (float)hiPoint.X;
                    yLoValue        = (float)loPoint.X;
                    yOpenStartValue = (float)startopenpoint.X;
                    yOpenEndValue   = (float)endopenpoint.Y;
                    yCloseValue     = (float)endclosepoint.X;
                    yCloseEndValue  = (float)endclosepoint.Y;
                }
            }

            int width          = (int)Area.SeriesClipRect.Width;
            int height         = (int)Area.SeriesClipRect.Height;
            int leftThickness  = (int)StrokeThickness / 2;
            int rightThickness = (int)(StrokeThickness % 2 == 0
                ? (StrokeThickness / 2) : StrokeThickness / 2 + 1);

            selectedSegmentPixels.Clear();

            float xStart = 0;
            float yStart = 0;
            float yEnd = 0;
            float yOpen = 0;
            float yOpenEnd = 0;
            float yClose = 0;
            float yCloseEnd = 0;
            int   leftOffset, rightOffset;

            xStart    = xValue;
            yStart    = y_isInversed ? yLoValue : yHiValue;
            yEnd      = y_isInversed ? yHiValue : yLoValue;
            yOpen     = x_isInversed ? yCloseValue : yOpenStartValue;
            yOpenEnd  = x_isInversed ? yCloseEndValue : yOpenEndValue;
            yClose    = x_isInversed ? yOpenStartValue : yCloseValue;
            yCloseEnd = x_isInversed ? yOpenEndValue : yCloseEndValue;

            if (!IsActualTransposed)
            {
                leftOffset            = (int)xStart - leftThickness;
                rightOffset           = (int)xStart + rightThickness;
                selectedSegmentPixels = bmp.GetRectangle(width, height, leftOffset, (int)yStart, rightOffset, (int)yEnd, selectedSegmentPixels);
                leftOffset            = (int)yOpen - leftThickness;
                rightOffset           = (int)yOpen + rightThickness;
                selectedSegmentPixels = bmp.GetRectangle(width, height, (int)yOpenEnd, leftOffset, (int)xStart - leftThickness, (int)rightOffset, selectedSegmentPixels);
                leftOffset            = (int)yClose - leftThickness;
                rightOffset           = (int)yClose + rightThickness;
                selectedSegmentPixels = bmp.GetRectangle(width, height, (int)xStart + leftThickness, leftOffset, (int)yCloseEnd, (int)rightOffset, selectedSegmentPixels);
            }
            else
            {
                leftOffset            = (int)xStart - leftThickness;
                rightOffset           = (int)xStart + rightThickness;
                selectedSegmentPixels = bmp.GetRectangle(width, height, (int)yEnd, (int)leftOffset, (int)yStart, (int)rightOffset, selectedSegmentPixels);
                leftOffset            = (int)yOpen - leftThickness;
                rightOffset           = (int)yOpen + rightThickness;
                selectedSegmentPixels = bmp.GetRectangle(width, height, leftOffset, (int)xStart + leftThickness, (int)rightOffset, (int)yOpenEnd, selectedSegmentPixels);
                leftOffset            = (int)yClose - leftThickness;
                rightOffset           = (int)yClose + rightThickness;
                selectedSegmentPixels = bmp.GetRectangle(width, height, leftOffset, (int)yCloseEnd, (int)rightOffset, (int)xStart - leftThickness, selectedSegmentPixels);
            }
        }
Exemple #10
0
        protected override DoubleRange CalculateActualRange()
        {
            if (ActualRange.IsEmpty) // Executes when Minimum and Maximum aren't set.
            {
                DoubleRange range = base.CalculateActualRange();

                // Execute when include the annotion range for Auto Range
                if (IncludeAnnotationRange)
                {
                    foreach (var annotation in (Area as SfChart).Annotations)
                    {
                        if (Orientation == Orientation.Vertical && annotation.CoordinateUnit == CoordinateUnit.Axis && annotation.YAxis == this)
                        {
                            range += new DoubleRange(
                                Annotation.ConvertData(annotation.Y1, this),
                                annotation is TextAnnotation ?
                                Annotation.ConvertData(annotation.Y1, this) : annotation is ImageAnnotation ?
                                Annotation.ConvertData((annotation as ImageAnnotation).Y2, this) :
                                Annotation.ConvertData((annotation as ShapeAnnotation).Y2, this));
                        }
                        else if (Orientation == Orientation.Horizontal && annotation.CoordinateUnit == CoordinateUnit.Axis && annotation.XAxis == this)
                        {
                            range += new DoubleRange(
                                Annotation.ConvertData(annotation.X1, this),
                                annotation is TextAnnotation ?
                                Annotation.ConvertData(annotation.X1, this) : annotation is ImageAnnotation ?
                                Annotation.ConvertData((annotation as ImageAnnotation).X2, this) :
                                Annotation.ConvertData((annotation as ShapeAnnotation).X2, this));
                        }
                    }
                }

                return(range);
            }
            else if (Minimum != null && Maximum != null) // Executes when Minimum and Maximum are set.
            {
                return(ActualRange);
            }
            else
            {
                // Executes when either Minimum or Maximum is set.
                DoubleRange range = base.CalculateActualRange();
                if (StartRangeFromZero && range.Start > 0)
                {
                    return(new DoubleRange(0, range.End));
                }
                else if (Minimum != null)
                {
                    return(new DoubleRange(ActualRange.Start, double.IsNaN(range.End) ? ActualRange.Start + 1 : range.End));
                }
                else if (Maximum != null)
                {
                    return(new DoubleRange(double.IsNaN(range.Start) ? ActualRange.End - 1 : range.Start, ActualRange.End));
                }
                else
                {
                    if (IncludeAnnotationRange)
                    {
                        foreach (var annotation in (Area as SfChart).Annotations)
                        {
                            if (Orientation == Orientation.Vertical && annotation.CoordinateUnit == CoordinateUnit.Axis && annotation.YAxis == this)
                            {
                                range += new DoubleRange(
                                    Annotation.ConvertData(annotation.Y1, this), annotation is TextAnnotation ?
                                    Annotation.ConvertData(annotation.Y1, this) : annotation is ImageAnnotation ?
                                    Annotation.ConvertData((annotation as ImageAnnotation).Y2, this) :
                                    Annotation.ConvertData((annotation as ShapeAnnotation).Y2, this));
                            }
                            else if (Orientation == Orientation.Horizontal && annotation.CoordinateUnit == CoordinateUnit.Axis && annotation.XAxis == this)
                            {
                                range += new DoubleRange(
                                    Annotation.ConvertData(annotation.X1, this), annotation is TextAnnotation ?
                                    Annotation.ConvertData(annotation.X1, this) : annotation is ImageAnnotation ?
                                    Annotation.ConvertData((annotation as ImageAnnotation).X2, this) :
                                    Annotation.ConvertData((annotation as ShapeAnnotation).X2, this));
                            }
                        }
                    }

                    return(range);
                }
            }
        }
        /// <summary>
        /// Creates the segments of FastHiLoOpenCloseBitmapSeries
        /// </summary>
        public override void CreateSegments()
        {
            List <double> xValues   = null;
            var           isGrouped = ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed;

            if (isGrouped)
            {
                xValues = GroupedXValuesIndexes;
            }
            else
            {
                xValues = GetXValues();
            }

            if (xValues != null)
            {
                if (isGrouped)
                {
                    Segments.Clear();
                    Adornments.Clear();

                    if (Segment == null || Segments.Count == 0)
                    {
                        FastHiLoOpenCloseSegment segment = new FastHiLoOpenCloseSegment(xValues, GroupedSeriesYValues[0], GroupedSeriesYValues[1], GroupedSeriesYValues[2], GroupedSeriesYValues[3], this);
                        segment.Series = this;
                        segment.Item   = ActualData;
                        segment.SetData(xValues, GroupedSeriesYValues[0], GroupedSeriesYValues[1], GroupedSeriesYValues[2], GroupedSeriesYValues[3]);
                        Segment = segment;
                        this.Segments.Add(Segment);
                    }

                    DoubleRange sbsInfo  = this.GetSideBySideInfo(this);
                    double      median   = sbsInfo.Delta / 2;
                    double      center   = sbsInfo.Median;
                    double      Left     = sbsInfo.Start;
                    double      Right    = sbsInfo.End;
                    double      leftpos  = (this as ISegmentSpacing).CalculateSegmentSpacing(SegmentSpacing, Right, Left);
                    double      rightpos = (this as ISegmentSpacing).CalculateSegmentSpacing(SegmentSpacing, Left, Right);

                    if (SegmentSpacing > 0 && SegmentSpacing <= 1)
                    {
                        Left  = leftpos;
                        Right = rightpos;
                    }

                    for (int i = 0; i < xValues.Count; i++)
                    {
                        if (i < xValues.Count && GroupedSeriesYValues[0].Count > i)
                        {
                            ChartPoint highPt       = new ChartPoint(xValues[i] + center, GroupedSeriesYValues[0][i]);
                            ChartPoint lowPt        = new ChartPoint(xValues[i] + center, GroupedSeriesYValues[1][i]);
                            ChartPoint startOpenPt  = new ChartPoint(xValues[i] + Left, GroupedSeriesYValues[2][i]);
                            ChartPoint endOpenPt    = new ChartPoint(xValues[i] + center, GroupedSeriesYValues[2][i]);
                            ChartPoint startClosePt = new ChartPoint(xValues[i] + Right, GroupedSeriesYValues[3][i]);
                            ChartPoint endClosePt   = new ChartPoint(xValues[i] + center, GroupedSeriesYValues[3][i]);

                            if (AdornmentsInfo != null)
                            {
                                AddAdornments(xValues[i], highPt, lowPt, startOpenPt, endOpenPt, startClosePt, endClosePt, i, median);
                            }
                        }
                    }
                }
                else
                {
                    if (AdornmentsInfo != null)
                    {
                        if (AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.TopAndBottom)
                        {
                            ClearUnUsedAdornments(this.DataCount * 4);
                        }
                        else
                        {
                            ClearUnUsedAdornments(this.DataCount * 2);
                        }
                    }

                    if (Segment == null || Segments.Count == 0)
                    {
                        FastHiLoOpenCloseSegment segment = new FastHiLoOpenCloseSegment(xValues, HighValues, LowValues, OpenValues, CloseValues, this);
                        segment.Series = this;
                        segment.Item   = ActualData;
                        segment.SetData(xValues, HighValues, LowValues, OpenValues, CloseValues);

                        Segment = segment;
                        this.Segments.Add(Segment);
                    }
                    else if (xValues != null)
                    {
                        (Segment as FastHiLoOpenCloseSegment).Item = ActualData;
                        (Segment as FastHiLoOpenCloseSegment).SetData(xValues, HighValues, LowValues, OpenValues, CloseValues);
                    }

                    if (AdornmentsInfo != null)
                    {
                        if (AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.TopAndBottom)
                        {
                            ClearUnUsedAdornments(this.DataCount * 4);
                        }
                        else
                        {
                            ClearUnUsedAdornments(this.DataCount * 2);
                        }
                    }

                    DoubleRange sbsInfo  = this.GetSideBySideInfo(this);
                    double      median   = sbsInfo.Delta / 2;
                    double      center   = sbsInfo.Median;
                    double      Left     = sbsInfo.Start;
                    double      Right    = sbsInfo.End;
                    double      leftpos  = (this as ISegmentSpacing).CalculateSegmentSpacing(SegmentSpacing, Right, Left);
                    double      rightpos = (this as ISegmentSpacing).CalculateSegmentSpacing(SegmentSpacing, Left, Right);

                    if (SegmentSpacing > 0 && SegmentSpacing <= 1)
                    {
                        Left  = leftpos;
                        Right = rightpos;
                    }

                    for (int i = 0; i < this.DataCount; i++)
                    {
                        ChartPoint highPt       = new ChartPoint(xValues[i] + center, HighValues[i]);
                        ChartPoint lowPt        = new ChartPoint(xValues[i] + center, LowValues[i]);
                        ChartPoint startOpenPt  = new ChartPoint(xValues[i] + Left, OpenValues[i]);
                        ChartPoint endOpenPt    = new ChartPoint(xValues[i] + center, OpenValues[i]);
                        ChartPoint startClosePt = new ChartPoint(xValues[i] + Right, CloseValues[i]);
                        ChartPoint endClosePt   = new ChartPoint(xValues[i] + center, CloseValues[i]);

                        if (AdornmentsInfo != null)
                        {
                            AddAdornments(xValues[i], highPt, lowPt, startOpenPt, endOpenPt, startClosePt, endClosePt, i, median);
                        }
                    }
                }
            }
        }
Exemple #12
0
        /// <summary>
        /// Excludes the specified range.
        /// </summary>
        /// <param name="range">The range.</param>
        /// <param name="excluder">The excluder.</param>
        /// <param name="leftRange">The left range.</param>
        /// <param name="rightRange">The right range.</param>
        /// <returns>True if empty</returns>
        public static bool Exclude(DoubleRange range, DoubleRange excluder, out DoubleRange leftRange, out DoubleRange rightRange)
        {
            leftRange  = DoubleRange.Empty;
            rightRange = DoubleRange.Empty;

            if (!(range.IsEmpty || excluder.IsEmpty))
            {
                if (excluder.m_end < range.m_start)
                {
                    if (excluder.m_end > range.m_start)
                    {
                        leftRange = new DoubleRange(excluder.m_start, range.m_start);
                    }
                    else
                    {
                        leftRange = excluder;
                    }
                }

                if (excluder.m_end > range.m_end)
                {
                    if (excluder.m_start < range.m_end)
                    {
                        rightRange = new DoubleRange(range.m_end, excluder.m_end);
                    }
                    else
                    {
                        rightRange = excluder;
                    }
                }
            }

            return(!(leftRange.IsEmpty && rightRange.IsEmpty));
        }
Exemple #13
0
        /// <summary>
        /// Creates the segments of HiLoOpenCloseSeries
        /// </summary>
        public override void CreateSegments()
        {
            List <double> xValues    = null;
            bool          isGrouping = this.ActualXAxis is CategoryAxis ? (this.ActualXAxis as CategoryAxis).IsIndexed : true;

            if (!isGrouping)
            {
                xValues = GroupedXValuesIndexes;
            }
            else
            {
                xValues = GetXValues();
            }
            IList <double> values = GetComparisionModeValues();
            bool           isBull = false;

            if (xValues != null)
            {
                DoubleRange sbsInfo  = this.GetSideBySideInfo(this);
                double      median   = sbsInfo.Delta / 2;
                double      center   = sbsInfo.Median;
                double      Left     = sbsInfo.Start;
                double      Right    = sbsInfo.End;
                double      leftpos  = (this as ISegmentSpacing).CalculateSegmentSpacing(SegmentSpacing, Right, Left);
                double      rightpos = (this as ISegmentSpacing).CalculateSegmentSpacing(SegmentSpacing, Left, Right);

                if (SegmentSpacing > 0 && SegmentSpacing <= 1)
                {
                    Left  = leftpos;
                    Right = rightpos;
                }

                if (!isGrouping)
                {
                    Segments.Clear();
                    Adornments.Clear();

                    for (int i = 0; i < xValues.Count; i++)
                    {
                        ChartPoint highPt       = new ChartPoint(xValues[i] + center, GroupedSeriesYValues[0][i]);
                        ChartPoint lowPt        = new ChartPoint(xValues[i] + center, GroupedSeriesYValues[1][i]);
                        ChartPoint startOpenPt  = new ChartPoint(xValues[i] + Left, GroupedSeriesYValues[2][i]);
                        ChartPoint endOpenPt    = new ChartPoint(xValues[i] + center, GroupedSeriesYValues[2][i]);
                        ChartPoint startClosePt = new ChartPoint(xValues[i] + Right, GroupedSeriesYValues[3][i]);
                        ChartPoint endClosePt   = new ChartPoint(xValues[i] + center, GroupedSeriesYValues[3][i]);
                        if (i == 0 || this.ComparisonMode == FinancialPrice.None)
                        {
                            isBull = GroupedSeriesYValues[2][i] < GroupedSeriesYValues[3][i];
                        }
                        else
                        {
                            isBull = values[i] >= values[i - 1];
                        }

                        HiLoOpenCloseSegment hiloOpenClose = new HiLoOpenCloseSegment(highPt, lowPt, startOpenPt, endOpenPt, startClosePt, endClosePt, isBull, this, ActualData[i]);
                        hiloOpenClose.SetData(highPt, lowPt, startOpenPt, endOpenPt, startClosePt, endClosePt, isBull);
                        hiloOpenClose.BullFillColor = BullFillColor;
                        hiloOpenClose.BearFillColor = BearFillColor;
                        hiloOpenClose.High          = GroupedSeriesYValues[0][i];
                        hiloOpenClose.Low           = GroupedSeriesYValues[1][i];
                        hiloOpenClose.Open          = GroupedSeriesYValues[2][i];
                        hiloOpenClose.Close         = GroupedSeriesYValues[3][i];
                        hiloOpenClose.Item          = ActualData[i];
                        Segments.Add(hiloOpenClose);
                        if (AdornmentsInfo != null)
                        {
                            AddAdornments(xValues[i], highPt, lowPt, startOpenPt, endOpenPt, startClosePt, endClosePt, i, median);
                        }
                    }
                }
                else
                {
                    if (Segments.Count > this.DataCount)
                    {
                        ClearUnUsedSegments(this.DataCount);
                    }

                    if (AdornmentsInfo != null)
                    {
                        if (AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.TopAndBottom)
                        {
                            ClearUnUsedAdornments(this.DataCount * 4);
                        }
                        else
                        {
                            ClearUnUsedAdornments(this.DataCount * 2);
                        }
                    }

                    for (int i = 0; i < this.DataCount; i++)
                    {
                        ChartPoint highPt       = new ChartPoint(xValues[i] + center, HighValues[i]);
                        ChartPoint lowPt        = new ChartPoint(xValues[i] + center, LowValues[i]);
                        ChartPoint startOpenPt  = new ChartPoint(xValues[i] + Left, OpenValues[i]);
                        ChartPoint endOpenPt    = new ChartPoint(xValues[i] + center, OpenValues[i]);
                        ChartPoint startClosePt = new ChartPoint(xValues[i] + Right, CloseValues[i]);
                        ChartPoint endClosePt   = new ChartPoint(xValues[i] + center, CloseValues[i]);

                        if (i == 0 || this.ComparisonMode == FinancialPrice.None)
                        {
                            isBull = OpenValues[i] < CloseValues[i];
                        }
                        else
                        {
                            isBull = values[i] >= values[i - 1];
                        }

                        if (i < Segments.Count)
                        {
                            Segments[i].Item = ActualData[i];
                            (Segments[i]).SetData(highPt, lowPt, startOpenPt, endOpenPt, startClosePt, endClosePt, isBull);
                            (Segments[i] as HiLoOpenCloseSegment).High  = HighValues[i];
                            (Segments[i] as HiLoOpenCloseSegment).Low   = LowValues[i];
                            (Segments[i] as HiLoOpenCloseSegment).Open  = OpenValues[i];
                            (Segments[i] as HiLoOpenCloseSegment).Close = CloseValues[i];
                        }
                        else
                        {
                            HiLoOpenCloseSegment hiloOpenClose = new HiLoOpenCloseSegment(highPt, lowPt, startOpenPt, endOpenPt, startClosePt, endClosePt, isBull, this, ActualData[i]);
                            hiloOpenClose.SetData(highPt, lowPt, startOpenPt, endOpenPt, startClosePt, endClosePt, isBull);
                            hiloOpenClose.BullFillColor = BullFillColor;
                            hiloOpenClose.BearFillColor = BearFillColor;
                            hiloOpenClose.High          = HighValues[i];
                            hiloOpenClose.Low           = LowValues[i];
                            hiloOpenClose.Open          = OpenValues[i];
                            hiloOpenClose.Close         = CloseValues[i];
                            hiloOpenClose.Item          = ActualData[i];
                            Segments.Add(hiloOpenClose);
                        }

                        if (AdornmentsInfo != null)
                        {
                            AddAdornments(xValues[i], highPt, lowPt, startOpenPt, endOpenPt, startClosePt, endClosePt, i, median);
                        }
                    }
                }

                if (ShowEmptyPoints)
                {
                    UpdateEmptyPointSegments(xValues, true);
                }
            }
        }
        /// <summary>
        /// Apply padding based on interval
        /// </summary>
        /// <param name="axis">The axis.</param>
        /// <param name="range">The range.</param>
        /// <param name="interval">The interval.</param>
        /// <param name="rangePadding">The range padding.</param>
        /// <returns></returns>
        internal static DoubleRange ApplyRangePadding(ChartAxis axis, DoubleRange range, double interval, NumericalPadding rangePadding)
        {
            if (rangePadding == NumericalPadding.Normal)
            {
                double minimum = 0,
                       remaining,
                       start = range.Start;

                if (range.Start < 0)
                {
                    start   = 0;
                    minimum = range.Start + (range.Start / 20);

                    remaining = interval + (minimum % interval);

                    if ((0.365 * interval) >= remaining)
                    {
                        minimum -= interval;
                    }

                    if (minimum % interval < 0)
                    {
                        minimum = (minimum - interval) - (minimum % interval);
                    }
                }
                else
                {
                    minimum = range.Start < ((5.0 / 6.0) * range.End)
                                         ? 0
                                         : (range.Start - (range.End - range.Start) / 2);
                    if (minimum % interval > 0)
                    {
                        minimum -= (minimum % interval);
                    }
                }

                double maximum = (range.End + (range.End - start) / 20);

                remaining = interval - (maximum % interval);

                if ((0.365 * interval) >= remaining)
                {
                    maximum += interval;
                }

                if (maximum % interval > 0)
                {
                    maximum = (maximum + interval) - (maximum % interval);
                }

                range = new DoubleRange(minimum, maximum);

                if (minimum == 0d)
                {
                    axis.ActualInterval = axis.CalculateActualInterval(range, axis.AvailableSize);
                    return(new DoubleRange(0, Math.Ceiling(maximum / axis.ActualInterval) * axis.ActualInterval));
                }
            }
            else if (rangePadding == NumericalPadding.Round ||
                     rangePadding == NumericalPadding.Additional)
            {
                double minimum = Math.Floor(range.Start / interval) * interval;
                double maximum = Math.Ceiling(range.End / interval) * interval;

                if (rangePadding == NumericalPadding.Additional)
                {
                    minimum -= interval;
                    maximum += interval;
                }

                return(new DoubleRange(minimum, maximum));
            }

            return(range);
        }
Exemple #15
0
 /// <summary>
 /// Calculates actual interval
 /// </summary>
 /// <param name="range">The Range</param>
 /// <param name="availableSize">The Available Size</param>
 /// <returns>Actual Interval</returns>
 protected internal override double CalculateActualInterval(DoubleRange range, Size availableSize)
 {
     return(CategoryAxisHelper.CalculateActualInterval(this, range, availableSize, this.Interval));
 }
 /// <summary>
 /// Calculates nice interval.
 /// </summary>
 /// <param name="actualRange">The Actual Range</param>
 /// <param name="availableSize">The Available Range</param>
 /// <returns>Returns the calculated nice interval.</returns>
 protected internal override double CalculateNiceInterval(DoubleRange actualRange, Size availableSize)
 {
     return(LogarithmicAxisHelper.CalculateNiceInterval(this, actualRange, availableSize));
 }
Exemple #17
0
 /// <summary>
 /// Apply padding based on interval
 /// </summary>
 /// <param name="range">The Range</param>
 /// <param name="interval">The Interval</param>
 /// <returns>The Range Padding</returns>
 protected override DoubleRange ApplyRangePadding(DoubleRange range, double interval)
 {
     return(CategoryAxisHelper.ApplyRangePadding(this, range, interval, LabelPlacement));
 }
        /// <summary>
        /// Creates the segments of WaterfallSeries.
        /// </summary>
        public override void CreateSegments()
        {
            List <double> xValues = GetXValues();
            double        median  = 0d;
            DoubleRange   sbsInfo = this.GetSideBySideInfo(this);

            median = sbsInfo.Delta / 2;
            double origin = ActualXAxis != null ? ActualXAxis.Origin : 0;

            if (ActualXAxis != null && ActualXAxis.Origin == 0 &&
                ActualYAxis is LogarithmicAxis &&
                (ActualYAxis as LogarithmicAxis).Minimum != null)
            {
                origin = (double)(ActualYAxis as LogarithmicAxis).Minimum;
            }

            if (xValues != null)
            {
                double x1, x2, y1, y2;
                ClearUnUsedSegments(this.DataCount);
                ClearUnUsedAdornments(this.DataCount);

                for (int i = 0; i < this.DataCount; i++)
                {
                    if (i < this.DataCount)
                    {
                        // Calculate the waterfall segment rendering values.
                        OnCalculateSegmentValues(
                            out x1,
                            out x2,
                            out y1,
                            out y2,
                            i,
                            origin,
                            xValues[i]);

                        WaterfallSegment segment = null;
                        bool             isSum   = false;
                        if (i < Segments.Count)
                        {
                            segment = Segments[i] as WaterfallSegment;

                            segment.SetData(x1, y1, x2, y2);
                            segment.XData = xValues[i];
                            segment.YData = YValues[i];
                            segment.Item  = ActualData[i];

                            if (segment.SegmentType == WaterfallSegmentType.Sum)
                            {
                                isSum = true;
                            }

                            // Update sum segment values.
                            OnUpdateSumSegmentValues(segment, i, isSum, origin);

                            segment.BindProperties();
                        }
                        else
                        {
                            segment = new WaterfallSegment(x1, y1, x2, y2, this)
                            {
                                XData = xValues[i],
                                YData = YValues[i],
                                Item  = ActualData[i]
                            };

                            // Raise segment created event.
                            isSum = RaiseSegmentCreatedEvent(segment, i);

                            // Update sum segment values.
                            OnUpdateSumSegmentValues(segment, i, isSum, origin);

                            Segments.Add(segment);
                        }

                        #region Adornment calculation

                        if (AdornmentsInfo != null)
                        {
                            if (segment.SegmentType == WaterfallSegmentType.Sum)
                            {
                                if (Segments.IndexOf(segment) > 0 && AllowAutoSum)
                                {
                                    if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.TopAndBottom)
                                    {
                                        AddColumnAdornments(xValues[i], segment.WaterfallSum, x1, segment.WaterfallSum / 2, i, median);
                                    }
                                    else if (segment.WaterfallSum >= 0)
                                    {
                                        AddColumnAdornments(xValues[i], segment.WaterfallSum, x1, segment.Top, i, median);
                                    }
                                    else
                                    {
                                        AddColumnAdornments(xValues[i], segment.WaterfallSum, x1, segment.Bottom, i, median);
                                    }
                                }
                                else
                                {
                                    if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.TopAndBottom)
                                    {
                                        AddColumnAdornments(xValues[i], YValues[i], x1, y1 + (y2 - y1) / 2, i, median);
                                    }
                                    else if (YValues[i] >= 0)
                                    {
                                        AddColumnAdornments(xValues[i], YValues[i], x1, segment.Top, i, median);
                                    }
                                    else
                                    {
                                        AddColumnAdornments(xValues[i], YValues[i], x1, segment.Bottom, i, median);
                                    }
                                }
                            }
                            else if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Top)
                            {
                                if (segment.SegmentType == WaterfallSegmentType.Positive)
                                {
                                    AddColumnAdornments(xValues[i], YValues[i], x1, y1, i, median);
                                }
                                else
                                {
                                    AddColumnAdornments(xValues[i], YValues[i], x1, y2, i, median);
                                }
                            }
                            else if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Bottom)
                            {
                                if (segment.SegmentType == WaterfallSegmentType.Positive)
                                {
                                    AddColumnAdornments(xValues[i], YValues[i], x1, y2, i, median);
                                }
                                else
                                {
                                    AddColumnAdornments(xValues[i], YValues[i], x1, y1, i, median);
                                }
                            }
                            else
                            {
                                AddColumnAdornments(xValues[i], YValues[i], x1, y1 + (y2 - y1) / 2, i, median);
                            }
                        }

                        #endregion
                    }
                }
            }

            this.ActualArea.IsUpdateLegend = true;
        }
        /// <summary>
        /// Apply padding based on interval
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="range"></param>
        /// <param name="interval"></param>
        /// <param name="rangePadding"></param>
        /// <param name="intervalType"></param>
        /// <returns></returns>
        internal static DoubleRange ApplyRangePadding(ChartAxis axis, DoubleRange range, double interval, DateTimeRangePadding rangePadding, DateTimeIntervalType intervalType)
        {
            DateTime startDate    = range.Start.FromOADate();
            DateTime endDate      = range.End.FromOADate();
            var      dateTimeAxis = axis as DateTimeAxis;

            if (dateTimeAxis != null && dateTimeAxis.EnableBusinessHours)
            {
                return(ApplyBusinessHoursRangePadding(dateTimeAxis, range, interval, rangePadding, intervalType));
            }
            if (rangePadding == DateTimeRangePadding.Round || rangePadding == DateTimeRangePadding.Additional)
            {
                switch (intervalType)
                {
                case DateTimeIntervalType.Years:
                    int startYear = (int)((int)(startDate.Year / interval) * interval);
                    int endYear   = endDate.Year + (startDate.Year - startYear);
                    if (startYear <= 0)
                    {
                        startYear = 1;
                    }

                    if (endYear <= 0)
                    {
                        endYear = 1;
                    }

                    if (rangePadding == DateTimeRangePadding.Round)
                    {
                        range = new DoubleRange(new DateTime(startYear, 1, 1, 0, 0, 0).ToOADate(), new DateTime(endYear, 12, 31, 23, 59, 59).ToOADate());
                    }
                    else
                    {
                        range = new DoubleRange(new DateTime(startYear - (int)interval, 1, 1, 0, 0, 0).ToOADate(), new DateTime(endYear + (int)interval, 12, 31, 23, 59, 59).ToOADate());
                    }
                    break;

                case DateTimeIntervalType.Months:
                    int month = (int)((int)(startDate.Month / interval) * interval);
                    if (month <= 0)
                    {
                        month = 1;
                    }

                    int endmonth = range.End.FromOADate().Month + (startDate.Month - month);
                    if (endmonth <= 0)
                    {
                        endmonth = 1;
                    }

                    if (endmonth > 12)
                    {
                        endmonth = 12;
                    }
                    if (rangePadding == DateTimeRangePadding.Round)
                    {
                        range = new DoubleRange(new DateTime(startDate.Year, month, 1, 0, 0, 0).ToOADate(), new DateTime(endDate.Year, endmonth, endmonth == 2 ? 28 : 30, 0, 0, 0).ToOADate());
                    }
                    else
                    {
                        range = new DoubleRange(new DateTime(startDate.Year, month, 1, 0, 0, 0).AddMonths((int)(-interval)).ToOADate(), new DateTime(endDate.Year, endmonth, endmonth == 2 ? 28 : 30, 0, 0, 0).AddMonths((int)interval).ToOADate());
                    }
                    break;

                case DateTimeIntervalType.Days:
                    int day = (int)((int)(startDate.Day / interval) * interval);
                    if (day <= 0)
                    {
                        day = 1;
                    }

                    int endday = startDate.Day - day;
                    if (endday <= 0)
                    {
                        endday = 1;
                    }

                    if (rangePadding == DateTimeRangePadding.Round)
                    {
                        range = new DoubleRange(new DateTime(startDate.Year, startDate.Month, day, 0, 0, 0).ToOADate(), new DateTime(endDate.Year, endDate.Month, endDate.Day, 23, 59, 59).AddDays(endday).ToOADate());
                    }
                    else
                    {
                        range = new DoubleRange(new DateTime(startDate.Year, startDate.Month, day, 0, 0, 0).AddDays(-interval).ToOADate(), new DateTime(endDate.Year, endDate.Month, endDate.Day, 23, 59, 59).AddDays(interval + endday).ToOADate());
                    }
                    break;

                case DateTimeIntervalType.Hours:
                    int hour    = (int)((int)(startDate.Hour / interval) * interval);
                    int endhour = endDate.Hour + (startDate.Hour - hour);
                    if (rangePadding == DateTimeRangePadding.Round)
                    {
                        range = new DoubleRange(
                            new DateTime(
                                startDate.Year,
                                startDate.Month,
                                startDate.Day,
                                hour,
                                0,
                                0).ToOADate(), new DateTime(
                                endDate.Year,
                                endDate.Month,
                                endDate.Day,
                                endhour,
                                0,
                                0).ToOADate());
                    }
                    else
                    {
                        range = new DoubleRange(new DateTime(
                                                    startDate.Year,
                                                    startDate.Month,
                                                    startDate.Day,
                                                    startDate.Hour,
                                                    0,
                                                    0).AddHours(-interval).ToOADate(), new DateTime(
                                                    endDate.Year,
                                                    endDate.Month,
                                                    endDate.Day,
                                                    endDate.Hour,
                                                    0,
                                                    0).AddHours(interval).ToOADate());
                    }
                    break;

                case DateTimeIntervalType.Minutes:
                    int minute    = (int)((int)(startDate.Minute / interval) * interval);
                    int endminute = range.End.FromOADate().Minute + (startDate.Minute - minute);
                    if (rangePadding == DateTimeRangePadding.Round)
                    {
                        range = new DoubleRange(
                            new DateTime(
                                startDate.Year,
                                startDate.Month,
                                startDate.Day,
                                startDate.Hour,
                                minute,
                                0).ToOADate(), new DateTime(
                                endDate.Year,
                                endDate.Month,
                                endDate.Day,
                                endDate.Hour,
                                endminute,
                                0).ToOADate());
                    }
                    else
                    {
                        range = new DoubleRange(new DateTime(
                                                    startDate.Year,
                                                    startDate.Month,
                                                    startDate.Day,
                                                    startDate.Hour,
                                                    startDate.Minute,
                                                    0).AddMinutes(-interval).ToOADate(), new DateTime(
                                                    endDate.Year,
                                                    endDate.Month,
                                                    endDate.Day,
                                                    endDate.Hour,
                                                    endDate.Minute,
                                                    0).AddMinutes(interval).ToOADate());
                    }
                    break;

                case DateTimeIntervalType.Seconds:
                    int second    = (int)((int)(startDate.Second / interval) * interval);
                    int endsecond = range.End.FromOADate().Second + (startDate.Second - second);
                    if (rangePadding == DateTimeRangePadding.Round)
                    {
                        range = new DoubleRange(
                            new DateTime(
                                startDate.Year,
                                startDate.Month,
                                startDate.Day,
                                startDate.Hour,
                                startDate.Minute,
                                second,
                                0).ToOADate(), new DateTime(
                                endDate.Year,
                                endDate.Month,
                                endDate.Day,
                                endDate.Hour,
                                endDate.Minute,
                                endsecond,
                                0).ToOADate());
                    }
                    else
                    {
                        range = new DoubleRange(new DateTime(
                                                    startDate.Year,
                                                    startDate.Month,
                                                    startDate.Day,
                                                    startDate.Hour,
                                                    startDate.Minute,
                                                    startDate.Second,
                                                    0).AddSeconds(-interval).ToOADate(), new DateTime(
                                                    endDate.Year,
                                                    endDate.Month,
                                                    endDate.Day,
                                                    endDate.Hour,
                                                    endDate.Minute,
                                                    endDate.Second,
                                                    0).AddSeconds(interval).ToOADate());
                    }
                    break;

                case DateTimeIntervalType.Milliseconds:
                    int milliseconds    = (int)((int)(startDate.Millisecond / interval) * interval);
                    int endmilliseconds = range.End.FromOADate().Millisecond + (startDate.Millisecond - milliseconds);
                    if (rangePadding == DateTimeRangePadding.Round)
                    {
                        range = new DoubleRange(
                            new DateTime(
                                startDate.Year,
                                startDate.Month,
                                startDate.Day,
                                startDate.Hour,
                                startDate.Minute,
                                startDate.Second,
                                milliseconds).ToOADate(), new DateTime(
                                endDate.Year,
                                endDate.Month,
                                endDate.Day,
                                endDate.Hour,
                                endDate.Minute,
                                endDate.Second,
                                endmilliseconds).ToOADate());
                    }
                    else
                    {
                        range = new DoubleRange(new DateTime(
                                                    startDate.Year,
                                                    startDate.Month,
                                                    startDate.Day,
                                                    startDate.Hour,
                                                    startDate.Minute,
                                                    startDate.Second,
                                                    startDate.Millisecond).AddMilliseconds(-interval).ToOADate(), new DateTime(
                                                    endDate.Year,
                                                    endDate.Month,
                                                    endDate.Day,
                                                    endDate.Hour,
                                                    endDate.Minute,
                                                    endDate.Second,
                                                    endDate.Millisecond).AddMilliseconds(interval).ToOADate());
                    }
                    break;
                }

                return(range);
            }

            return(range);
        }
Exemple #20
0
        /// <summary>
        /// Updates the segments based on its data point value. This method is not
        /// intended to be called explicitly outside the Chart but it can be overridden by
        /// any derived class.
        /// </summary>
        /// <param name="transformer">Represents the view port of chart control.(refer <see cref="IChartTransformer"/>)</param>
        public override void Update(IChartTransformer transformer)
        {
            if (isSegmentUpdated)
            {
                Series.SeriesRootPanel.Clip = null;
            }
            ChartTransform.ChartCartesianTransformer cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer;
            double      xEnd  = cartesianTransformer.XAxis.VisibleRange.End;
            DoubleRange range = cartesianTransformer.XAxis.VisibleRange;

            PathFigure         figure          = new PathFigure();
            PathGeometry       segmentGeometry = new PathGeometry();
            double             origin          = containerSeries.ActualXAxis != null ? containerSeries.ActualXAxis.Origin : 0;//setting origin value for splinearea segment
            WindowsLineSegment lineSegment;

            figure.StartPoint = transformer.TransformToVisible(segmentPoints[0].X, segmentPoints[0].Y);
            lineSegment       = new WindowsLineSegment();
            lineSegment.Point = transformer.TransformToVisible(segmentPoints[1].X, segmentPoints[1].Y);
            figure.Segments.Add(lineSegment);

            strokeGeometry = new PathGeometry();
            strokeFigure   = new PathFigure();
            strokePath     = new Path();

            if (containerSeries.IsClosed && isEmpty)
            {
                AddStroke(figure.StartPoint);
                lineSegment       = new WindowsLineSegment();
                lineSegment.Point = transformer.TransformToVisible(segmentPoints[1].X, segmentPoints[1].Y);
                strokeFigure.Segments.Add(lineSegment);
            }
            else if (!containerSeries.IsClosed)
            {
                AddStroke(transformer.TransformToVisible(segmentPoints[1].X, segmentPoints[1].Y));
            }

            int i;

            for (i = 2; i < segmentPoints.Count; i += 3)
            {
                double xVal = segmentPoints[i].X;
                if (xVal >= range.Start && xVal <= range.End || xEnd >= range.Start && xEnd <= range.End)
                {
                    if (Series.ShowEmptyPoints || ((!double.IsNaN(segmentPoints[i].Y) && !double.IsNaN(segmentPoints[i + 1].Y) && !double.IsNaN(segmentPoints[i + 2].Y))))
                    {
                        BezierSegment segment = new BezierSegment();
                        segment.Point1 = transformer.TransformToVisible(segmentPoints[i].X, segmentPoints[i].Y);
                        segment.Point2 = transformer.TransformToVisible(segmentPoints[i + 1].X, segmentPoints[i + 1].Y);
                        segment.Point3 = transformer.TransformToVisible(segmentPoints[i + 2].X, segmentPoints[i + 2].Y);
                        figure.Segments.Add(segment);
                        if ((isEmpty && !Series.ShowEmptyPoints) || !containerSeries.IsClosed)
                        {
                            BezierSegment strokeSegment = new BezierSegment();
                            strokeSegment.Point1 = segment.Point1;
                            strokeSegment.Point2 = segment.Point2;
                            strokeSegment.Point3 = segment.Point3;
                            strokeFigure.Segments.Add(strokeSegment);
                        }
                    }
                    else
                    {
                        if ((double.IsNaN(segmentPoints[i].Y) && double.IsNaN(segmentPoints[i + 1].Y) && double.IsNaN(segmentPoints[i + 2].Y)))
                        {
                            lineSegment       = new WindowsLineSegment();
                            lineSegment.Point = transformer.TransformToVisible(segmentPoints[i - 1].X, origin);
                            figure.Segments.Add(lineSegment);
                            lineSegment       = new WindowsLineSegment();
                            lineSegment.Point = transformer.TransformToVisible(segmentPoints[i + 2].X, origin);
                            figure.Segments.Add(lineSegment);
                        }
                        else if (i > 0 && (double.IsNaN(segmentPoints[i - 1].Y) || double.IsNaN(segmentPoints[i].Y)))
                        {
                            lineSegment       = new WindowsLineSegment();
                            lineSegment.Point = transformer.TransformToVisible(segmentPoints[i + 2].X, origin);

                            figure.Segments.Add(lineSegment);
                            lineSegment       = new WindowsLineSegment();
                            lineSegment.Point = transformer.TransformToVisible(segmentPoints[i + 2].X, double.IsNaN(segmentPoints[i + 2].Y) ? origin : segmentPoints[i + 2].Y);
                            if ((!Series.ShowEmptyPoints && !double.IsNaN(segmentPoints[i + 2].Y)) || !containerSeries.IsClosed)
                            {
                                strokeFigure            = new PathFigure();
                                strokeFigure.StartPoint = lineSegment.Point;
                                strokeGeometry.Figures.Add(strokeFigure);
                            }
                            figure.Segments.Add(lineSegment);
                        }
                    }
                }
            }
            Point point = transformer.TransformToVisible(segmentPoints[i - 1].X, origin);

            lineSegment       = new WindowsLineSegment();
            lineSegment.Point = point;
            figure.Segments.Add(lineSegment);
            if (containerSeries.IsClosed && !double.IsNaN(segmentPoints[i - 1].Y))
            {
                lineSegment       = new WindowsLineSegment();
                lineSegment.Point = point;
                strokeFigure.Segments.Add(lineSegment);
            }
            //figure.IsClosed = true;
            isSegmentUpdated = true;
            segmentGeometry.Figures.Add(figure);
            this.segPath.Data = segmentGeometry;
        }
        /// <summary>
        /// This method is used to gets the selected data point segment pixel positions
        /// </summary>
        internal void GenerateStackingColumnPixels()
        {
            WriteableBitmap bmp = Area.fastRenderSurface;

            ChartTransform.ChartCartesianTransformer cartesianTransformer = CreateTransformer(
                new Size(
                    Area.SeriesClipRect.Width,
                    Area.SeriesClipRect.Height),
                true) as ChartTransform.ChartCartesianTransformer;

            bool x_isInversed = cartesianTransformer.XAxis.IsInversed;
            bool y_isInversed = cartesianTransformer.YAxis.IsInversed;

            double        x1ChartVal, x2ChartVal, y1ChartVal, y2ChartVal;
            int           i       = dataPoint.Index;
            DoubleRange   sbsInfo = this.GetSideBySideInfo(this);
            List <double> xValues = GetStackingSeriesXValues(this);

            if (!this.IsIndexed)
            {
                x1ChartVal = xValues[i] + sbsInfo.Start;
                x2ChartVal = xValues[i] + sbsInfo.End;
                y1ChartVal = YRangeEndValues[i];
                y2ChartVal = YRangeStartValues[i];
            }
            else
            {
                x1ChartVal = i + sbsInfo.Start;
                x2ChartVal = i + sbsInfo.End;
                y1ChartVal = YRangeEndValues[i];
                y2ChartVal = YRangeStartValues[i];
            }

            double x1Val = x_isInversed
                                  ? x2ChartVal
                                  : x1ChartVal;
            double x2Val = x_isInversed
                               ? x1ChartVal
                               : x2ChartVal;
            double y2Val = y_isInversed
                               ? y1ChartVal
                               : y2ChartVal;
            double y1Val = y_isInversed
                               ? y2ChartVal
                               : y1ChartVal;
            Point tlpoint = cartesianTransformer.TransformToVisible(x1Val, y1Val);
            Point rbpoint = cartesianTransformer.TransformToVisible(x2Val, y2Val);
            float x1Value = ((float)tlpoint.X);
            float x2Value = ((float)rbpoint.X);
            float y1Value = ((float)tlpoint.Y);
            float y2Value = ((float)rbpoint.Y);

            float x1     = 0;
            float x2     = 0;
            float y1     = 0;
            float y2     = 0;
            int   width  = (int)Area.SeriesClipRect.Width;
            int   height = (int)Area.SeriesClipRect.Height;

            selectedSegmentPixels.Clear();

            x1 = x1Value;
            x2 = x2Value;
            y1 = y1ChartVal > 0 ? y1Value : y2Value;
            y2 = y1ChartVal > 0 ? y2Value : y1Value;

            var spacingSegment = this as ISegmentSpacing;

            if (spacingSegment != null)
            {
                double spacing = spacingSegment.SegmentSpacing;
                if (spacing > 0 && spacing <= 1)
                {
                    double leftpos  = spacingSegment.CalculateSegmentSpacing(spacing, x2, x1);
                    double rightpos = spacingSegment.CalculateSegmentSpacing(spacing, x1, x2);
                    x1 = (float)(leftpos);
                    x2 = (float)(rightpos);
                }
            }

            if (y1 < y2)
            {
                selectedSegmentPixels = bmp.GetRectangle(width, height, (int)(x1), (int)y1, (int)x2, (int)y2, selectedSegmentPixels);
            }
            else
            {
                selectedSegmentPixels = bmp.GetRectangle(width, height, (int)(x1), (int)y2, (int)x2, (int)y1, selectedSegmentPixels);
            }
        }