Пример #1
0
        private void AddStackingAreaAdornments(IList <double> yValues)
        {
            double         adornX = 0d, adornY = 0d;
            int            i             = 0;
            List <double>  xValues       = null;
            IList <double> actualYValues = YValues;

            if (ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed)
            {
                xValues       = GroupedXValuesIndexes;
                actualYValues = GroupedSeriesYValues[0];
            }
            else
            {
                xValues = GetXValues();
            }

            for (i = 0; i < xValues.Count; i++)
            {
                adornX = xValues[i];
                adornY = yValues[i];

                if (i < Adornments.Count)
                {
                    Adornments[i].SetData(adornX, actualYValues[i], adornX, adornY);
                }
                else
                {
                    Adornments.Add(this.CreateAdornment(this, adornX, actualYValues[i], adornX, adornY));
                }

                Adornments[i].Item = ActualData[i];
            }
        }
Пример #2
0
        private void AddBoxWhiskerAdornments(DoubleRange sbsInfo, double xValue, double minimum, double maximum, double x1, double median, double lowerQuartile, double upperQuartile, List <double> outliers, int index)
        {
            if (AdornmentsInfo != null)
            {
                ChartAdornment adornment = null;
                var            sbsMedian = sbsInfo.Delta / 2;

                adornment = this.CreateAdornment(this, xValue, minimum, x1 + sbsMedian, minimum);
                adornment.ActualLabelPosition = bottomLabelPosition;
                adornment.Item = ActualData[index];
                Adornments.Add(adornment);

                adornment = this.CreateAdornment(this, xValue, lowerQuartile, x1 + sbsMedian, lowerQuartile);
                adornment.ActualLabelPosition = bottomLabelPosition;
                adornment.Item = ActualData[index];
                Adornments.Add(adornment);

                adornment = this.CreateAdornment(this, xValue, median, x1 + sbsMedian, median);
                adornment.ActualLabelPosition = topLabelPosition;
                adornment.Item = ActualData[index];
                Adornments.Add(adornment);

                adornment = this.CreateAdornment(this, xValue, upperQuartile, x1 + sbsMedian, upperQuartile);
                adornment.ActualLabelPosition = topLabelPosition;
                adornment.Item = ActualData[index];
                Adornments.Add(adornment);

                adornment = this.CreateAdornment(this, xValue, maximum, x1 + sbsMedian, maximum);
                adornment.ActualLabelPosition = topLabelPosition;
                adornment.Item = ActualData[index];
                Adornments.Add(adornment);
            }
        }
Пример #3
0
        private void AddPieAdornments(double x, double y, double startAngle, double endAngle, int i, int index, PieSegment pieSegment)
        {
            double angle = (startAngle + endAngle) / 2;

            if (Area == null || Area.RootPanelDesiredSize == null || Area.RootPanelDesiredSize.Value == null)
            {
                return;
            }

            var actualheight = Area.RootPanelDesiredSize.Value.Height;
            var actualwidth  = Area.RootPanelDesiredSize.Value.Width;

            var pieSeries      = (from series in Area.VisibleSeries where series is PieSeries select series).ToList();
            var pieSeriesCount = pieSeries.Count();

            double pieIndex     = pieSeries.IndexOf(this);
            double actualRadius = (Math.Min(actualwidth, actualheight)) / 2;
            double equalParts   = actualRadius / (pieSeriesCount);
            double radius       = (equalParts * (pieIndex + 1)) - (equalParts * (1 - InternalPieCoefficient));

            if (index < Adornments.Count)
            {
                (Adornments[index] as ChartPieAdornment).SetData(x, y, angle, radius);
            }
            else
            {
                Adornments.Add(this.CreateAdornment(this, x, y, angle, radius));
            }

            Adornments[index].Item = !double.IsNaN(GroupTo) ? Segments[index].Item : ActualData[index];
        }
Пример #4
0
        /// <summary>
        /// Method implementation for Add ColumnAdornments in Chart.
        /// </summary>
        /// <param name="values">The Value</param>
        protected virtual void AddColumnAdornments(params double[] values)
        {
            // values[0] -->   xData
            // values[1] -->   yData
            // values[2] -->   xPos
            // values[3] -->   yPos
            // values[4] -->   data point index
            // values[5] -->   Median value.
            double adornposX = values[2] + values[5], adornposY = values[3];
            var    pointIndex = (int)values[4];

            if (pointIndex < Adornments.Count)
            {
                Adornments[pointIndex].SetData(values[0], values[1], adornposX, adornposY, values[6]);
            }
            else
            {
                Adornments.Add(this.CreateAdornment(this, values[0], values[1], adornposX, adornposY, values[6]));
            }

            if (ActualXAxis is CategoryAxis3D && !(ActualXAxis as CategoryAxis3D).IsIndexed)
            {
                Adornments[pointIndex].Item = this.GroupedActualData[pointIndex];
            }
            else
            {
                Adornments[pointIndex].Item = this.ActualData[pointIndex];
            }
        }
Пример #5
0
        /// <summary>
        /// Adds the pie adornments.
        /// </summary>
        /// <param name="x">The X Value</param>
        /// <param name="y">The Y Value</param>
        /// <param name="startAngle">The Start Angle</param>
        /// <param name="endAngle">The End Angle</param>
        /// <param name="index">The Index</param>
        /// <param name="radius">The Radius</param>
        /// <param name="startDepth">The Start Depth</param>
        private void AddPieAdornments(double x, double y, double startAngle, double endAngle, int index, double radius, double startDepth)
        {
            startAngle = CircularSeriesBase3D.DegreeToRadianConverter(startAngle);
            endAngle   = DegreeToRadianConverter(endAngle);
            var angle = (startAngle + endAngle) / 2;

            Adornments.Add(PieSeries3D.CreateAdornment(this, x, y, angle, radius, startDepth));
            Adornments[(int)x].Item = this.ActualData[index];
        }
Пример #6
0
        /// <summary>
        /// Called when VisibleRange property changed
        /// </summary>
        protected override void OnVisibleRangeChanged(VisibleRangeChangedEventArgs e)
        {
            if (AdornmentsInfo != null && isAdornmentPending)
            {
                if (xValues != null && ActualXAxis != null &&
                    !ActualXAxis.VisibleRange.IsEmpty)
                {
                    double xBase          = ActualXAxis.IsLogarithmic ? (ActualXAxis as LogarithmicAxis).LogarithmicBase : 1;
                    bool   xIsLogarithmic = ActualXAxis.IsLogarithmic;
                    double start          = ActualXAxis.VisibleRange.Start;
                    double end            = ActualXAxis.VisibleRange.End;

                    for (int i = 0; i < DataCount; i++)
                    {
                        double x, y;
                        if (this.ActualXAxis is CategoryAxis && !(this.ActualXAxis as CategoryAxis).IsIndexed)
                        {
                            if (i < xValues.Count)
                            {
                                y = GroupedSeriesYValues[0][i];
                                x = xValues[i];
                            }
                            else
                            {
                                return;
                            }
                        }
                        else
                        {
                            x = xValues[i];
                            y = YValues[i];
                        }

                        double edgeValue = xIsLogarithmic ? Math.Log(x, xBase) : x;
                        if (edgeValue >= start && edgeValue <= end && !double.IsNaN(y))
                        {
                            if (i < Adornments.Count)
                            {
                                Adornments[i].SetData(x, y, x, y);
                                Adornments[i].Item = ActualData[i];
                            }
                            else
                            {
                                Adornments.Add(this.CreateAdornment(this, x, y, x, y));
                                Adornments[Adornments.Count - 1].Item = ActualData[i];
                            }
                        }
                    }
                }

                isAdornmentPending = false;
            }
        }
Пример #7
0
        /// <summary>
        /// Method implementation for Add Adornments at XY
        /// </summary>
        /// <param name="x">The X Value</param>
        /// <param name="y">The Y Value</param>
        /// <param name="pointindex">The Point Index</param>
        /// <param name="startDepth">The Start Depth</param>
        protected virtual void AddAdornmentAtXY(double x, double y, int pointindex, double startDepth)
        {
            double adornposX = x, adornposY = y;

            if (pointindex < Adornments.Count)
            {
                Adornments[pointindex].SetData(x, y, adornposX, adornposY);
            }
            else
            {
                Adornments.Add(this.CreateAdornment(this, x, y, adornposX, adornposY, startDepth));
            }
        }
Пример #8
0
        /// <summary>
        /// To calculate the segments if the pyramid mode is surface
        /// </summary>
        private void CalculateSurfaceSegments(double sumValues, int count, double gapHeight, List <double> xValues)
        {
            var toggledYValues = YValues.ToList();

            if (ToggledLegendIndex.Count > 0)
            {
                toggledYValues = GetYValues();
            }
            currY = 0;
            double[] y      = new double[count];
            double[] height = new double[count];
            double   preSum = GetSurfaceHeight(0, sumValues);

            for (int i = 0; i < count; i++)
            {
                y[i]      = currY;
                height[i] = GetSurfaceHeight(currY, Math.Abs(double.IsNaN(toggledYValues[i]) ? 0 : toggledYValues[i]));
                currY    += height[i] + gapHeight * preSum;
            }

            double coef = 1 / (currY - gapHeight * preSum);

            for (int i = 0; i < count; i++)
            {
                double currHeight = 0;
                if (!double.IsNaN(YValues[i]))
                {
                    currHeight = coef * y[i];
                    PyramidSegment pyramidSegment = new PyramidSegment(currHeight, coef * height[i], this.ExplodeOffset, this, i == this.ExplodeIndex || this.ExplodeAll ? true : false);
                    pyramidSegment.Item  = ActualData[i];
                    pyramidSegment.XData = xValues[i];
                    pyramidSegment.YData = Math.Abs(YValues[i]);
                    if (ToggledLegendIndex.Contains(i))
                    {
                        pyramidSegment.IsSegmentVisible = false;
                    }
                    else
                    {
                        pyramidSegment.IsSegmentVisible = true;
                    }
                    this.Segments.Add(pyramidSegment);

                    if (AdornmentsInfo != null)
                    {
                        Adornments.Add(this.CreateAdornment(this, xValues[i], toggledYValues[i], 0, double.IsNaN(currHeight) ? 1 - height[i] / 2 : currHeight + coef * height[i] / 2));
                    }
                }
            }
        }
Пример #9
0
        /// <summary>
        /// Method implementation for Add ColumnAdornments in Chart
        /// </summary>
        /// <param name="values"></param>
        protected virtual void AddColumnAdornments(params double[] values)
        {
            ////values[0] -->   xData
            ////values[1] -->   yData
            ////values[2] -->   xPos
            ////values[3] -->   yPos
            ////values[4] -->   data point index
            ////values[5] -->   Median value.

            double adornposX = values[2] + values[5], adornposY = values[3];
            int    pointIndex = (int)values[4];

            if ((EmptyPointIndexes != null && EmptyPointIndexes.Any() && EmptyPointIndexes[0].Contains(pointIndex) &&
                 (EmptyPointStyle == Charts.EmptyPointStyle.Symbol ||
                  EmptyPointStyle == Charts.EmptyPointStyle.SymbolAndInterior)))
            {
                if (this is StackingSeriesBase)
                {
                    adornposY = (EmptyPointValue == EmptyPointValue.Average) ? values[3] : values[1];
                }
                else
                {
                    adornposY = values[1]; // WPF-13874-EmptyPoint segment adornmentinfo positioning wrongly when EmptyPointValues is Average
                }
            }
            if (pointIndex < Adornments.Count)
            {
                Adornments[pointIndex].SetData(values[0], values[1], adornposX, adornposY);
            }
            else
            {
                Adornments.Add(CreateAdornment(this, values[0], values[1], adornposX, adornposY));
            }

            if (!(this is HistogramSeries))
            {
                if (ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed &&
                    this.GroupedActualData.Count > 0)
                {
                    Adornments[pointIndex].Item = this.GroupedActualData[pointIndex];
                }
                else
                {
                    Adornments[pointIndex].Item = ActualData[pointIndex];
                }
            }
        }
Пример #10
0
        private void AddAdornments(double x, double yValue, int i)
        {
            double adornX = 0d, adornY = 0d;

            adornX = x;
            adornY = yValue;
            if (i < Adornments.Count)
            {
                Adornments[i].SetData(adornX, adornY, adornX, adornY);
            }
            else
            {
                Adornments.Add(this.CreateAdornment(this, adornX, adornY, adornX, adornY));
            }

            Adornments[i].Item = ActualData[i];
        }
Пример #11
0
        /// <summary>
        /// Adds the adornment to the adornments collection.
        /// </summary>
        /// <param name="xValue">The X Value</param>
        /// <param name="yValue">The Y Value</param>
        /// <param name="index">The Index</param>
        /// <param name="depth">The Depth</param>
        protected virtual void AddAdornments(double xValue, double yValue, int index, double depth)
        {
            double adornX = 0d, adornY = 0d;

            adornX = xValue;
            adornY = yValue;
            if (index < Adornments.Count)
            {
                Adornments[index].SetData(adornX, adornY, adornX, adornY, depth);
            }
            else
            {
                Adornments.Add(this.CreateAdornment(this, adornX, adornY, adornX, adornY, depth));
            }

            Adornments[index].Item = this.ActualData[index];
        }
Пример #12
0
        /// <summary>
        /// Method implementation for Add Adornments at XY
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="pointindex"></param>
        protected virtual void AddAdornmentAtXY(double x, double y, int pointindex)
        {
            double adornposX = x, adornposY = y;

            if (pointindex < Adornments.Count)
            {
                Adornments[pointindex].SetData(x, y, adornposX, adornposY);
            }
            else
            {
                Adornments.Add(CreateAdornment(this, x, y, adornposX, adornposY));
            }

            if (pointindex < ActualData.Count)
            {
                Adornments[pointindex].Item = ActualData[pointindex];
            }
        }
Пример #13
0
        private void AddDoughnutAdornments(double x, double y, double startAngle, double endAngle, int i, int index)
        {
            double angle = (startAngle + endAngle) / 2;

            if (Area == null || Area.RootPanelDesiredSize == null || Area.RootPanelDesiredSize.Value == null)
            {
                return;
            }

            var actualheight = Area.RootPanelDesiredSize.Value.Height;
            var actualwidth  = Area.RootPanelDesiredSize.Value.Width;

            double doughnutIndex = 0d, actualRadius = 0d, remainingWidth = 0, equalParts = 0d, radius = 0d;

            if (IsStackedDoughnut)
            {
                int doughnutSegmentsCount = DataCount;
                actualRadius   = this.InternalDoughnutSize * (Math.Min(actualwidth, actualheight)) / 2;
                remainingWidth = actualRadius - (actualRadius * ActualArea.InternalDoughnutHoleSize);
                equalParts     = (remainingWidth / doughnutSegmentsCount) * InternalDoughnutCoefficient;

                // Segments count is not updated so datacount is used. For more safer update in dynamic updates the radius is also updated in the ChartPieAdornment.Update.
                radius = actualRadius - (equalParts * (doughnutSegmentsCount - (index + 1)));
            }
            else
            {
                var doughnutSeries      = (from series in Area.VisibleSeries where series is DoughnutSeries select series).ToList();
                var doughnutSeriesCount = doughnutSeries.Count();
                doughnutIndex  = doughnutSeries.IndexOf(this);
                actualRadius   = this.InternalDoughnutSize * (Math.Min(actualwidth, actualheight)) / 2;
                remainingWidth = actualRadius - (actualRadius * Area.InternalDoughnutHoleSize);
                equalParts     = remainingWidth / doughnutSeriesCount;
                radius         = actualRadius - (equalParts * (doughnutSeriesCount - (doughnutIndex + 1)));
            }
            if (index < Adornments.Count)
            {
                Adornments[index].SetData(x, y, angle, radius);
            }
            else
            {
                Adornments.Add(this.CreateAdornment(this, x, y, angle, radius));
            }
            Adornments[index].Item = !double.IsNaN(GroupTo) ? Segments[index].Item :  ActualData[index];
        }
Пример #14
0
        /// <summary>
        /// To calculate the segments if the pyramid mode is linear
        /// </summary>
        private void CalculateLinearSegments(double sumValues, double gapRatio, int count, List <double> xValues)
        {
            var toggledYValues = YValues.ToList();

            if (ToggledLegendIndex.Count > 0)
            {
                toggledYValues = GetYValues();
            }
            currY = 0;
            double coef = 1d / (sumValues * (1 + gapRatio / (1 - gapRatio)));

            for (int i = 0; i < count; i++)
            {
                double height = 0;
                if (!double.IsNaN(YValues[i]))
                {
                    height = coef * Math.Abs(double.IsNaN(toggledYValues[i]) ? 0 : toggledYValues[i]);
                    PyramidSegment pyramidSegment = new PyramidSegment(currY, height, this.ExplodeOffset, this, i == ExplodeIndex || this.ExplodeAll ? true : false);
                    pyramidSegment.Item  = ActualData[i];
                    pyramidSegment.XData = xValues[i];
                    pyramidSegment.YData = Math.Abs(YValues[i]);
                    if (ToggledLegendIndex.Contains(i))
                    {
                        pyramidSegment.IsSegmentVisible = false;
                    }
                    else
                    {
                        pyramidSegment.IsSegmentVisible = true;
                    }
                    this.Segments.Add(pyramidSegment);
                    currY += (gapRatio / (count - 1)) + height;
                    if (AdornmentsInfo != null)
                    {
                        Adornments.Add(this.CreateAdornment(this, xValues[i], toggledYValues[i], 0, double.IsNaN(currY) ? 1 - height / 2 : currY - height / 2));
                        Adornments[Segments.Count - 1].Item = ActualData[i];
                    }
                }
            }
        }
Пример #15
0
        /// <summary>
        /// Method implementation for Add AreaAdornments in ChartAdornments
        /// </summary>
        /// <param name="values"></param>
        protected virtual void AddAreaAdornments(params IList <double>[] values)
        {
            IList <double> yValues = values[0];
            List <double>  xValues = new List <double>();

            if (ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed)
            {
                xValues = GroupedXValuesIndexes;
            }
            else
            {
                xValues = GetXValues();
            }

            if (values.Length == 1)
            {
                int i;
                for (i = 0; i < DataCount; i++)
                {
                    if (i < xValues.Count && i < yValues.Count)
                    {
                        double adornX = xValues[i];
                        double adornY = yValues[i];

                        if (i < Adornments.Count)
                        {
                            Adornments[i].SetData(xValues[i], yValues[i], adornX, adornY);
                        }
                        else
                        {
                            Adornments.Add(CreateAdornment(this, xValues[i], yValues[i], adornX, adornY));
                        }

                        Adornments[i].Item = ActualData[i];
                    }
                }
            }
        }
Пример #16
0
        /// <summary>
        /// To calculate the segments if the pyramid mode is vlaueisHeight.
        /// </summary>
        private void CalculateValueIsHeightSegments(IList <double> yValues, List <double> xValues, double sumValues, double gapRatio, int dataCount, int explodedIndex)
        {
            currY = 0d;
            double coefHeight = 1 / sumValues;
            double spacing    = gapRatio / (DataCount - 1);

            for (int i = DataCount - 1; i >= 0; i--)
            {
                double height = 0;
                if (!double.IsNaN(YValues[i]))
                {
                    height = Math.Abs(double.IsNaN(yValues[i]) ? 0 : yValues[i]) * coefHeight;
                    FunnelSegment funnelSegment = new FunnelSegment(currY, height, this, explodedIndex == i || this.ExplodeAll ? true : false);
                    funnelSegment.Item  = ActualData[i]; // WPF-14426 Funnel series legend and segment colour is changing while setting emptypoint
                    funnelSegment.XData = xValues[i];
                    funnelSegment.YData = YValues[i];

                    if (ToggledLegendIndex.Contains(i))
                    {
                        funnelSegment.IsSegmentVisible = false;
                    }
                    else
                    {
                        funnelSegment.IsSegmentVisible = true;
                    }
                    Segments.Add(funnelSegment);

                    if (AdornmentsInfo != null)
                    {
                        ChartAdornment adornment = (this.CreateAdornment(this, xValues[i], yValues[i], 0, double.IsNaN(currY) ? 0 : currY + (height + spacing) / 2));
                        adornment.Item = ActualData[i];
                        Adornments.Add(adornment);
                    }

                    currY += height + spacing;
                }
            }
        }
Пример #17
0
        /// <summary>
        /// To calculate the segments if the pyramid mode is valueisWidth.
        /// </summary>
        private void CalculateValueIsWidthSegments(IList <double> yValues, List <double> xValues, double sumValues, double gapRatio, int count, int explodedIndex)
        {
            currY = 0d;
            if (ToggledLegendIndex.Count > 0)
            {
                count = YValues.Count - ToggledLegendIndex.Count;
            }
            double offset = 1d / (count - 1);
            double height = (1 - gapRatio) / (count - 1);

            for (int i = DataCount - 1; i > 0; i--)
            {
                if (!double.IsNaN(YValues[i]))
                {
                    double w1 = Math.Abs(YValues[i]);
                    double w2 = 0;
                    if (ToggledLegendIndex.Contains(i - 1))
                    {
                        for (int k = i - 2; k >= 0; k--)
                        {
                            if (!(ToggledLegendIndex.Contains(k)))
                            {
                                w2 = Math.Abs(YValues[k]);
                                break;
                            }
                        }
                    }
                    else
                    {
                        w2 = Math.Abs(YValues[i - 1]);
                    }

                    if (ToggledLegendIndex.Contains(i))
                    {
                        height = 0;
                        w2     = w1;
                    }
                    else
                    {
                        height = (1 - gapRatio) / (count - 1);
                    }

                    FunnelSegment funnelSegment = new FunnelSegment(currY, height, w1 / sumValues, w2 / sumValues, this, explodedIndex == i || this.ExplodeAll ? true : false);
                    funnelSegment.Item  = ActualData[i];
                    funnelSegment.XData = xValues[i];
                    funnelSegment.YData = YValues[i];

                    if (ToggledLegendIndex.Contains(i))
                    {
                        funnelSegment.IsSegmentVisible = false;
                    }
                    else
                    {
                        funnelSegment.IsSegmentVisible = true;
                    }

                    Segments.Add(funnelSegment);
                    if (AdornmentsInfo != null)
                    {
                        Adornments.Add(this.CreateAdornment(this, xValues[i], yValues[i], height, currY));
                        Adornments[Adornments.Count - 1].Item = ActualData[i];
                    }

                    if (!(ToggledLegendIndex.Contains(i)))
                    {
                        currY += offset;
                    }
                }
            }

            if (AdornmentsInfo != null && DataCount > 0)
            {
                Adornments.Add(this.CreateAdornment(this, xValues[0], yValues[0], height, currY));
                Adornments[Adornments.Count - 1].Item = ActualData[0];
            }
        }
Пример #18
0
        /// <summary>
        /// Creates the Segments of RadarSeries.
        /// </summary>
        public override void CreateSegments()
        {
            Segments.Clear(); Segment = null;

            if (DrawType == ChartSeriesDrawType.Area)
            {
                double        Origin      = this.ActualXAxis != null ? this.ActualXAxis.Origin : 0;
                List <double> xValues     = GetXValues().ToList();
                List <double> tempYValues = new List <double>();
                tempYValues = (from val in YValues select val).ToList();

                if (xValues != null)
                {
                    if (!IsClosed)
                    {
                        xValues.Insert((int)DataCount - 1, xValues[(int)DataCount - 1]);
                        xValues.Insert(0, xValues[0]);
                        tempYValues.Insert(0, Origin);
                        tempYValues.Insert(tempYValues.Count, Origin);
                    }
                    else
                    {
                        xValues.Insert(0, xValues[0]);
                        tempYValues.Insert(0, YValues[0]);
                        xValues.Insert(0, xValues[(int)DataCount]);
                        tempYValues.Insert(0, YValues[(int)DataCount - 1]);
                    }

                    if (Segment == null)
                    {
                        Segment = new AreaSegment(xValues, tempYValues, this, null);
                        Segment.SetData(xValues, tempYValues);
                        Segments.Add(Segment);
                    }
                    else
                    {
                        Segment.SetData(xValues, tempYValues);
                    }
                    if (AdornmentsInfo != null)
                    {
                        AddAreaAdornments(YValues);
                    }
                }
            }
            else if (DrawType == ChartSeriesDrawType.Line)
            {
                int           index        = -1;
                int           i            = 0;
                double        xIndexValues = 0d;
                List <double> xValues      = ActualXValues as List <double>;

                if (IsIndexed || xValues == null)
                {
                    xValues = xValues != null ? (from val in (xValues)select(xIndexValues++)).ToList()
                          : (from val in (ActualXValues as List <string>)select(xIndexValues++)).ToList();
                }

                if (xValues != null)
                {
                    for (i = 0; i < this.DataCount; i++)
                    {
                        index = i + 1;
                        if (index < this.DataCount)
                        {
                            if (i < Segments.Count)
                            {
                                (Segments[i]).SetData(xValues[i], YValues[i], xValues[index], YValues[index]);
                            }
                            else
                            {
                                LineSegment line = new LineSegment(xValues[i], YValues[i], xValues[index], YValues[index], this, this);
                                Segments.Add(line);
                            }
                        }

                        if (AdornmentsInfo != null)
                        {
                            if (i < Adornments.Count)
                            {
                                Adornments[i].SetData(xValues[i], YValues[i], xValues[i], YValues[i]);
                            }
                            else
                            {
                                Adornments.Add(this.CreateAdornment(this, xValues[i], YValues[i], xValues[i], YValues[i]));
                            }

                            Adornments[i].Item = ActualData[i];
                        }
                    }

                    if (IsClosed)
                    {
                        LineSegment line = new LineSegment(xValues[0], YValues[0], xValues[i - 1], YValues[i - 1], this, this);
                        Segments.Add(line);
                    }

                    if (ShowEmptyPoints)
                    {
                        UpdateEmptyPointSegments(xValues, false);
                    }
                }
            }
        }
Пример #19
0
        internal void AddAdornments(double xVal, double xOffset, double high, double low, int index)
        {
            double adornX = 0d, adornTop = 0d, adornBottom = 0d;
            ActualLabelPosition topLabelPosition;
            ActualLabelPosition bottomLabelPosition;
            ChartAdornment      chartAdornment;
            var isRangeColumnSingleValue = this is RangeColumnSeries && !IsMultipleYPathRequired;

            if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Top && !isRangeColumnSingleValue)
            {
                adornX = xVal + xOffset;

                if (high > low)
                {
                    adornTop = high;
                }
                else
                {
                    adornTop = low;
                }

                topLabelPosition = this.IsActualTransposed ? this.ActualYAxis.IsInversed ? ActualLabelPosition.Left : ActualLabelPosition.Right
                                                           : this.ActualYAxis.IsInversed ? ActualLabelPosition.Bottom : ActualLabelPosition.Top;

                if (index < Adornments.Count)
                {
                    Adornments[index].ActualLabelPosition = topLabelPosition;
                    Adornments[index].SetData(xVal, adornTop, adornX, adornTop);
                }
                else
                {
                    chartAdornment = this.CreateAdornment(this, xVal, adornTop, adornX, adornTop);
                    chartAdornment.ActualLabelPosition = topLabelPosition;
                    Adornments.Add(chartAdornment);
                }

                Adornments[index].Item = ActualData[index];
            }
            else if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Bottom && !isRangeColumnSingleValue)
            {
                adornX = xVal + xOffset;
                if (high > low)
                {
                    adornBottom = low;
                }
                else
                {
                    adornBottom = high;
                }

                bottomLabelPosition = this.IsActualTransposed ? this.ActualYAxis.IsInversed ?
                                      ActualLabelPosition.Right : ActualLabelPosition.Left
                                     : this.ActualYAxis.IsInversed ?
                                      ActualLabelPosition.Top : ActualLabelPosition.Bottom;

                if (index < Adornments.Count)
                {
                    Adornments[index].ActualLabelPosition = bottomLabelPosition;
                    Adornments[index].SetData(xVal, adornBottom, adornX, adornBottom);
                }
                else
                {
                    chartAdornment = this.CreateAdornment(this, xVal, adornBottom, adornX, adornBottom);
                    chartAdornment.ActualLabelPosition = bottomLabelPosition;
                    Adornments.Add(chartAdornment);
                }

                Adornments[index].Item = ActualData[index];
            }
            else
            {
                adornX = xVal + xOffset;

                if (this.IsActualTransposed)
                {
                    if (this.ActualYAxis.IsInversed)
                    {
                        topLabelPosition    = ActualLabelPosition.Left;
                        bottomLabelPosition = ActualLabelPosition.Right;
                    }
                    else
                    {
                        topLabelPosition    = ActualLabelPosition.Right;
                        bottomLabelPosition = ActualLabelPosition.Left;
                    }
                }
                else
                {
                    if (this.ActualYAxis.IsInversed)
                    {
                        topLabelPosition    = ActualLabelPosition.Bottom;
                        bottomLabelPosition = ActualLabelPosition.Top;
                    }
                    else
                    {
                        topLabelPosition    = ActualLabelPosition.Top;
                        bottomLabelPosition = ActualLabelPosition.Bottom;
                    }
                }

                if (high > low)
                {
                    adornTop    = high;
                    adornBottom = low;
                }
                else
                {
                    adornTop    = low;
                    adornBottom = high;
                }

                var adornmentCount = isRangeColumnSingleValue ? Adornments.Count : Adornments.Count / 2;

                if (index < adornmentCount)
                {
                    if (isRangeColumnSingleValue)
                    {
                        Adornments[index].ActualLabelPosition = topLabelPosition;
                        Adornments[index].SetData(xVal, adornTop, adornX, adornTop);
                    }
                    else
                    {
                        int j = 2 * index;
                        Adornments[j].ActualLabelPosition = topLabelPosition;
                        Adornments[j++].SetData(xVal, adornTop, adornX, adornTop);

                        Adornments[j].ActualLabelPosition = bottomLabelPosition;
                        Adornments[j].SetData(xVal, adornBottom, adornX, adornBottom);
                    }
                }
                else
                {
                    chartAdornment = this.CreateAdornment(this, xVal, adornTop, adornX, adornTop);
                    chartAdornment.ActualLabelPosition = topLabelPosition;
                    Adornments.Add(chartAdornment);

                    if (isRangeColumnSingleValue)
                    {
                        Adornments[index].Item = ActualData[index];
                        return;
                    }

                    chartAdornment = this.CreateAdornment(this, xVal, adornBottom, adornX, adornBottom);
                    chartAdornment.ActualLabelPosition = bottomLabelPosition;
                    Adornments.Add(chartAdornment);
                }

                if (!isRangeColumnSingleValue)
                {
                    int k = 2 * index;
                    Adornments[k++].Item = ActualData[index];
                    Adornments[k].Item   = ActualData[index];
                }
                else
                {
                    Adornments[index].Item = ActualData[index];
                }
            }
        }
Пример #20
0
        internal void AddAdornments(double xVal, ChartPoint highPt, ChartPoint lowPt, ChartPoint startOpenPt, ChartPoint endOpenPt, ChartPoint startClosePt, ChartPoint endClosePt, int i, double median)
        {
            double adornX1, adornX2, adornX3, adornX4, adornMax, adornMin, adornOpen, adornClose;

            ActualLabelPosition topLabelPosition;
            ActualLabelPosition leftLabelPosition;
            ActualLabelPosition bottomLabelPosition;
            ActualLabelPosition rightLabelPosition;
            ChartAdornment      chartAdornment;

            // To check whether the high or low value is empty
            bool isEmpty = double.IsNaN(highPt.Y) || double.IsNaN(lowPt.Y);

            // When high or low value is empty, the empty point must be considered instead of the greatest value for AdornmentPosition.
            if (isEmpty || highPt.Y > lowPt.Y)
            {
                adornMax = highPt.Y;
                adornMin = lowPt.Y;
            }
            else
            {
                adornMax = lowPt.Y;
                adornMin = highPt.Y;
            }

            // To check whether the open or close value is empty.
            isEmpty = double.IsNaN(startOpenPt.Y) || double.IsNaN(startClosePt.Y);

            if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Top)
            {
                adornX1 = highPt.X;

                // When open or close value is empty, the empty point must be considered instead of the greatest value for the top AdornmentPostion.
                if (isEmpty || startOpenPt.Y > startClosePt.Y)
                {
                    adornOpen = startOpenPt.Y;

                    if (this is HiLoOpenCloseSeries || this is FastHiLoOpenCloseBitmapSeries)
                    {
                        adornX2 = startOpenPt.X;
                    }
                    else
                    {
                        adornX2 = highPt.X - median;
                    }

                    if (this.IsActualTransposed)
                    {
                        topLabelPosition  = this.ActualYAxis.IsInversed ? ActualLabelPosition.Left : ActualLabelPosition.Right;
                        leftLabelPosition = this.ActualXAxis.IsInversed ? ActualLabelPosition.Top : ActualLabelPosition.Bottom;
                    }
                    else
                    {
                        topLabelPosition  = this.ActualYAxis.IsInversed ? ActualLabelPosition.Bottom : ActualLabelPosition.Top;
                        leftLabelPosition = this.ActualXAxis.IsInversed ? ActualLabelPosition.Right : ActualLabelPosition.Left;
                    }
                }
                else
                {
                    adornOpen = startClosePt.Y;

                    if (this is HiLoOpenCloseSeries || this is FastHiLoOpenCloseBitmapSeries)
                    {
                        adornX2 = startClosePt.X;
                    }
                    else
                    {
                        adornX2 = highPt.X + median;
                    }

                    if (this.IsActualTransposed)
                    {
                        topLabelPosition  = this.ActualYAxis.IsInversed ? ActualLabelPosition.Left : ActualLabelPosition.Right;
                        leftLabelPosition = this.ActualXAxis.IsInversed ? ActualLabelPosition.Bottom : ActualLabelPosition.Top;
                    }
                    else
                    {
                        topLabelPosition  = this.ActualYAxis.IsInversed ? ActualLabelPosition.Bottom : ActualLabelPosition.Top;
                        leftLabelPosition = this.ActualXAxis.IsInversed ? ActualLabelPosition.Left : ActualLabelPosition.Right;
                    }
                }

                if (this is CandleSeries || this is FastCandleBitmapSeries)
                {
                    leftLabelPosition = topLabelPosition;
                }

                if (i < Adornments.Count / 2)
                {
                    int j = 2 * i;
                    Adornments[j].ActualLabelPosition = topLabelPosition;
                    Adornments[j++].SetData(xVal, adornMax, adornX1, adornMax);
                    Adornments[j].ActualLabelPosition = leftLabelPosition;
                    Adornments[j].SetData(xVal, adornOpen, adornX2, adornOpen);
                }
                else
                {
                    chartAdornment = this.CreateAdornment(this, xVal, adornMax, adornX1, adornMax);
                    chartAdornment.ActualLabelPosition = topLabelPosition;
                    Adornments.Add(chartAdornment);

                    chartAdornment = this.CreateAdornment(this, xVal, adornOpen, adornX2, adornOpen);
                    chartAdornment.ActualLabelPosition = leftLabelPosition;
                    Adornments.Add(chartAdornment);
                }

                int k = 2 * i;
                Adornments[k++].Item = ActualData[i];
                Adornments[k].Item   = ActualData[i];
            }
            else if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Bottom)
            {
                adornX1 = lowPt.X;

                // When open or close value is empty, the empty point must be considered instead of the smallest value for the bottom AdornmentPosition.
                if (isEmpty || startClosePt.Y < startOpenPt.Y)
                {
                    adornClose = endClosePt.Y;

                    if (this is HiLoOpenCloseSeries || this is FastHiLoOpenCloseBitmapSeries)
                    {
                        adornX2 = startClosePt.X;
                    }
                    else
                    {
                        adornX2 = lowPt.X + median;
                    }

                    if (this.IsActualTransposed)
                    {
                        bottomLabelPosition = this.ActualYAxis.IsInversed ? ActualLabelPosition.Right : ActualLabelPosition.Left;
                        rightLabelPosition  = this.ActualXAxis.IsInversed ? ActualLabelPosition.Bottom : ActualLabelPosition.Top;
                    }
                    else
                    {
                        bottomLabelPosition = this.ActualYAxis.IsInversed ? ActualLabelPosition.Top : ActualLabelPosition.Bottom;
                        rightLabelPosition  = this.ActualXAxis.IsInversed ? ActualLabelPosition.Left : ActualLabelPosition.Right;
                    }
                }
                else
                {
                    adornClose = startOpenPt.Y;

                    if (this is HiLoOpenCloseSeries || this is FastHiLoOpenCloseBitmapSeries)
                    {
                        adornX2 = startOpenPt.X;
                    }
                    else
                    {
                        adornX2 = lowPt.X - median;
                    }

                    if (this.IsActualTransposed)
                    {
                        bottomLabelPosition = this.ActualYAxis.IsInversed ? ActualLabelPosition.Right : ActualLabelPosition.Left;
                        rightLabelPosition  = this.ActualXAxis.IsInversed ? ActualLabelPosition.Top : ActualLabelPosition.Bottom;
                    }
                    else
                    {
                        bottomLabelPosition = this.ActualYAxis.IsInversed ? ActualLabelPosition.Top : ActualLabelPosition.Bottom;
                        rightLabelPosition  = this.ActualXAxis.IsInversed ? ActualLabelPosition.Right : ActualLabelPosition.Left;
                    }
                }

                if (this is CandleSeries || this is FastCandleBitmapSeries)
                {
                    rightLabelPosition = bottomLabelPosition;
                }

                if (i < Adornments.Count / 2)
                {
                    int j = 2 * i;
                    Adornments[j].ActualLabelPosition = bottomLabelPosition;
                    Adornments[j++].SetData(xVal, adornMin, adornX1, adornMin);
                    Adornments[j].ActualLabelPosition = rightLabelPosition;
                    Adornments[j].SetData(xVal, adornClose, adornX2, adornClose);
                }
                else
                {
                    chartAdornment = this.CreateAdornment(this, xVal, adornMin, adornX1, adornMin);
                    chartAdornment.ActualLabelPosition = bottomLabelPosition;
                    Adornments.Add(chartAdornment);

                    chartAdornment = this.CreateAdornment(this, xVal, adornClose, adornX2, adornClose);
                    chartAdornment.ActualLabelPosition = rightLabelPosition;
                    Adornments.Add(chartAdornment);
                }

                int k = 2 * i;
                Adornments[k++].Item = ActualData[i];
                Adornments[k].Item   = ActualData[i];
            }
            else
            {
                adornX1 = highPt.X;

                if (this is HiLoOpenCloseSeries || this is FastHiLoOpenCloseBitmapSeries)
                {
                    adornX2 = startClosePt.X;
                    adornX4 = startOpenPt.X;
                }
                else
                {
                    adornX2 = highPt.X + median;
                    adornX4 = lowPt.X - median;
                }

                adornX3    = lowPt.X;
                adornOpen  = startOpenPt.Y;
                adornClose = endClosePt.Y;

                if (this.IsActualTransposed)
                {
                    topLabelPosition    = this.ActualYAxis.IsInversed ? ActualLabelPosition.Left : ActualLabelPosition.Right;
                    leftLabelPosition   = this.ActualXAxis.IsInversed ? ActualLabelPosition.Top : ActualLabelPosition.Bottom;
                    bottomLabelPosition = this.ActualYAxis.IsInversed ? ActualLabelPosition.Right : ActualLabelPosition.Left;
                    rightLabelPosition  = this.ActualXAxis.IsInversed ? ActualLabelPosition.Bottom : ActualLabelPosition.Top;
                }
                else
                {
                    topLabelPosition    = this.ActualYAxis.IsInversed ? ActualLabelPosition.Bottom : ActualLabelPosition.Top;
                    leftLabelPosition   = this.ActualXAxis.IsInversed ? ActualLabelPosition.Right : ActualLabelPosition.Left;
                    bottomLabelPosition = this.ActualYAxis.IsInversed ? ActualLabelPosition.Top : ActualLabelPosition.Bottom;
                    rightLabelPosition  = this.ActualXAxis.IsInversed ? ActualLabelPosition.Left : ActualLabelPosition.Right;
                }

                if (this is CandleSeries || this is FastCandleBitmapSeries)
                {
                    leftLabelPosition  = topLabelPosition;
                    rightLabelPosition = bottomLabelPosition;
                }

                if (i < Adornments.Count / 4)
                {
                    int j = 4 * i;
                    Adornments[j].ActualLabelPosition = topLabelPosition;
                    Adornments[j++].SetData(xVal, adornMax, adornX1, adornMax);

                    Adornments[j].ActualLabelPosition = leftLabelPosition;
                    Adornments[j++].SetData(xVal, adornOpen, adornX4, adornOpen);

                    Adornments[j].ActualLabelPosition = bottomLabelPosition;
                    Adornments[j++].SetData(xVal, adornMin, adornX3, adornMin);

                    Adornments[j].ActualLabelPosition = rightLabelPosition;
                    Adornments[j].SetData(xVal, adornClose, adornX2, adornClose);
                }
                else
                {
                    chartAdornment = this.CreateAdornment(this, xVal, adornMax, adornX1, adornMax);
                    chartAdornment.ActualLabelPosition = topLabelPosition;
                    Adornments.Add(chartAdornment);

                    chartAdornment = this.CreateAdornment(this, xVal, adornOpen, adornX4, adornOpen);
                    chartAdornment.ActualLabelPosition = leftLabelPosition;
                    Adornments.Add(chartAdornment);

                    chartAdornment = this.CreateAdornment(this, xVal, adornMin, adornX3, adornMin);
                    chartAdornment.ActualLabelPosition = bottomLabelPosition;
                    Adornments.Add(chartAdornment);

                    chartAdornment = this.CreateAdornment(this, xVal, adornClose, adornX2, adornClose);
                    chartAdornment.ActualLabelPosition = rightLabelPosition;
                    Adornments.Add(chartAdornment);
                }

                int k = 4 * i;
                Adornments[k++].Item = ActualData[i];
                Adornments[k++].Item = ActualData[i];
                Adornments[k++].Item = ActualData[i];
                Adornments[k].Item   = ActualData[i];
            }
        }
        protected override void OnVisibleRangeChanged(VisibleRangeChangedEventArgs e)
        {
            if (AdornmentsInfo != null && isAdornmentPending)
            {
                List <double> xValues   = null;
                var           isGrouped = ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed;

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

                if (xValues != null && ActualXAxis != null &&
                    !ActualXAxis.VisibleRange.IsEmpty)
                {
                    double xBase = ActualXAxis.IsLogarithmic ? (ActualXAxis as LogarithmicAxis).LogarithmicBase : 1;
                    double start = ActualXAxis.VisibleRange.Start;
                    double end   = ActualXAxis.VisibleRange.End;

                    if (isGrouped)
                    {
                        for (int i = 0; i < xValues.Count; i++)
                        {
                            if (i < xValues.Count)
                            {
                                double x       = xValues[i];
                                double actualX = ActualXAxis.IsLogarithmic ? Math.Log(x, xBase) : x;

                                if (actualX >= start && actualX <= end)
                                {
                                    double y = GroupedSeriesYValues[0][i];

                                    if (i < Adornments.Count)
                                    {
                                        Adornments[i].SetData(x, y, x, y);
                                    }
                                    else
                                    {
                                        Adornments.Add(this.CreateAdornment(this, x, y, x, y));
                                    }

                                    Adornments[i].Item = ActualData[i];
                                }
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < DataCount; i++)
                        {
                            double x       = xValues[i];
                            double actualX = ActualXAxis.IsLogarithmic ? Math.Log(x, xBase) : x;

                            if (actualX >= start && actualX <= end)
                            {
                                double y = YValues[i];

                                if (i < Adornments.Count)
                                {
                                    Adornments[i].SetData(x, y, x, y);
                                }
                                else
                                {
                                    Adornments.Add(this.CreateAdornment(this, x, y, x, y));
                                }

                                Adornments[i].Item = ActualData[i];
                            }
                        }
                    }
                }

                isAdornmentPending = false;
            }
        }
Пример #22
0
        /// <summary>
        /// Creates the segments of StepLineSeries.
        /// </summary>
        public override void CreateSegments()
        {
            List <double> xValues    = null;
            bool          isGrouping = this.ActualXAxis is CategoryAxis && !(this.ActualXAxis as CategoryAxis).IsIndexed;

            if (isGrouping)
            {
                xValues = GroupedXValuesIndexes;
            }
            else
            {
                xValues = GetXValues();
            }
            if (xValues == null)
            {
                return;
            }
            double xOffset = 0d;

            if (ActualXAxis is CategoryAxis &&
                (ActualXAxis as CategoryAxis).LabelPlacement == LabelPlacement.BetweenTicks)
            {
                xOffset = 0.5d;
            }

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

                for (int i = 0; i < xValues.Count; i++)
                {
                    int        index = i + 1;
                    ChartPoint point1, point2, stepPoint;

                    if (AdornmentsInfo != null)
                    {
                        Adornments.Add(this.CreateAdornment(this, xValues[i], GroupedSeriesYValues[0][i], xValues[i], GroupedSeriesYValues[0][i]));
                        Adornments[i].Item = ActualData[i];
                    }

                    if (index < xValues.Count)
                    {
                        point1    = new ChartPoint(xValues[i] - xOffset, GroupedSeriesYValues[0][i]);
                        point2    = new ChartPoint(xValues[index] - xOffset, GroupedSeriesYValues[0][i]);
                        stepPoint = new ChartPoint(xValues[index] - xOffset, GroupedSeriesYValues[0][index]);
                    }
                    else
                    {
                        if (!(xOffset > 0))
                        {
                            continue;
                        }
                        point1    = new ChartPoint(xValues[i] - xOffset, GroupedSeriesYValues[0][i]);
                        point2    = new ChartPoint(xValues[i] + xOffset, GroupedSeriesYValues[0][i]);
                        stepPoint = new ChartPoint(xValues[i] - xOffset, GroupedSeriesYValues[0][i]);
                    }

                    var segment = new StepLineSegment(point1, stepPoint, point2, this)
                    {
                        Item = ActualData[i]
                    };

                    segment.Series = this;
                    List <ChartPoint> listPoints = new List <ChartPoint>();
                    listPoints.Add(point1);
                    listPoints.Add(stepPoint);
                    listPoints.Add(point2);
                    segment.SetData(listPoints);
                    Segments.Add(segment);
                    listPoints = null;
                }
            }
            else
            {
                ClearUnUsedStepLineSegment(DataCount);
                ClearUnUsedAdornments(DataCount);
                for (int i = 0; i < DataCount; i++)
                {
                    int        index = i + 1;
                    ChartPoint point1, point2, stepPoint;

                    if (AdornmentsInfo != null)
                    {
                        if (i < Adornments.Count)
                        {
                            Adornments[i].SetData(xValues[i], YValues[i], xValues[i], YValues[i]);
                            Adornments[i].Item = ActualData[i];
                        }
                        else
                        {
                            Adornments.Add(this.CreateAdornment(this, xValues[i], YValues[i], xValues[i], YValues[i]));
                            Adornments[i].Item = ActualData[i];
                        }
                    }

                    if (index < DataCount)
                    {
                        point1    = new ChartPoint(xValues[i] - xOffset, YValues[i]);
                        point2    = new ChartPoint(xValues[index] - xOffset, YValues[i]);
                        stepPoint = new ChartPoint(xValues[index] - xOffset, YValues[index]);
                    }
                    else
                    {
                        if (!(xOffset > 0))
                        {
                            continue;
                        }
                        point1    = new ChartPoint(xValues[i] - xOffset, YValues[i]);
                        point2    = new ChartPoint(xValues[i] + xOffset, YValues[i]);
                        stepPoint = new ChartPoint(xValues[i] - xOffset, YValues[i]);
                    }

                    if (i < Segments.Count)
                    {
                        Segments[i].SetData(new List <ChartPoint> {
                            point1, stepPoint, point2
                        });
                        Segments[i].Item = ActualData[i];
                        (Segments[i] as StepLineSegment).YData = YValues[i];
                        if (SegmentColorPath != null && !Segments[i].IsEmptySegmentInterior && ColorValues.Count > 0 && !Segments[i].IsSelectedSegment)
                        {
                            Segments[i].Interior = (Interior != null) ? Interior : ColorValues[i];
                        }
                    }
                    else
                    {
                        var segment = new StepLineSegment(point1, stepPoint, point2, this)
                        {
                            Item = ActualData[i]
                        };
                        segment.Series = this;
                        List <ChartPoint> listPoints = new List <ChartPoint>();
                        listPoints.Add(point1);
                        listPoints.Add(stepPoint);
                        listPoints.Add(point2);
                        segment.SetData(listPoints);
                        Segments.Add(segment);
                        listPoints = null;
                    }
                }
            }

            if (ShowEmptyPoints)
            {
                UpdateEmptyPointSegments(xValues, false);
            }
        }