Beispiel #1
0
        private void SetScatterDraggingSegment(FrameworkElement frameworkElement, ref bool isAdornment)
        {
            // Empty point support only given for the interior case and not for symbol case.
            if (frameworkElement.Tag is EmptyPointSegment || frameworkElement.DataContext is EmptyPointSegment)
            {
                return;
            }
            if (frameworkElement.Tag is ScatterSegment || frameworkElement.DataContext is ScatterSegment)
            {
                draggingSegment = GetDraggingSegment(frameworkElement) as ScatterSegment;
                if (ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed)
                {
                    SegmentIndex = ActualData.IndexOf(draggingSegment.Item);
                }
                else
                {
                    SegmentIndex = Segments.IndexOf(draggingSegment);
                }
            }
            else
            {
                isAdornment = true;

                // Get the selected adornment index and select the adornment marker
                SegmentIndex = ChartExtensionUtils.GetAdornmentIndex(frameworkElement);
                if (SegmentIndex > -1)
                {
                    draggingSegment = Segments[SegmentIndex] as ScatterSegment;
                }
            }
        }
Beispiel #2
0
        private static void BindProperties(ScatterSegment scatterSegment, ChartSegment currentSegment)
        {
            Binding binding = new Binding();

            binding.Source = currentSegment;
            binding.Path   = new PropertyPath("Interior");
            BindingOperations.SetBinding(scatterSegment, ChartSegment.InteriorProperty, binding);
        }
Beispiel #3
0
        private UIElement GetPreviewEllipse()
        {
            ScatterSegment scatter = new ScatterSegment();

            scatter.SetData(draggingSegment.XData, draggingSegment.YData);
            scatter.CustomTemplate = this.CustomTemplate;
            scatter.Series         = this;

            // This size is not used and empty size is given in segment calculation.
            var uIElement = scatter.CreateSegmentVisual(new Size(double.PositiveInfinity, double.PositiveInfinity));

            // In line series preview dragging segment value is assigned. It is binded for the good working of the segment selection
            // and empty point interior condition.
            var colorBinding = new Binding()
            {
                Source = Segments[SegmentIndex], Path = new PropertyPath("Interior")
            };

            BindingOperations.SetBinding(scatter, ScatterSegment.InteriorProperty, colorBinding);

            scatter.Update(this.ChartTransformer);
            return(uIElement);
        }
Beispiel #4
0
        // Animation Ellipse logic.
        private void UpdatePreviewIndicatorPosition(Point mousePos, FrameworkElement frameworkElement)
        {
            if (previewElement == null)
            {
                double positionX, positionY;
                bool   isAdornment = false;

                // WPF_18250 DragDelta Event returns undesired delta value.
                // Here we have reset the prevDraggedValue when dragged segment is changed.
                int previousIndex = SegmentIndex;

                draggingSegment = null;

                SetScatterDraggingSegment(frameworkElement, ref isAdornment);

                if (draggingSegment == null)
                {
                    return;
                }

                if (previousIndex != SegmentIndex)
                {
                    prevDraggedXValue = 0;
                    prevDraggedValue  = 0;
                }

                XySegmentEnterEventArgs args = new XySegmentEnterEventArgs
                {
                    XValue       = GetActualXValue(SegmentIndex),
                    YValue       = draggingSegment.YData,
                    SegmentIndex = SegmentIndex,
                    CanDrag      = true,
                };
                RaiseDragEnter(args);
                if (!args.CanDrag)
                {
                    return;
                }

                positionY = Area.ValueToLogPoint(ActualYAxis, draggingSegment.YData);
                positionX = Area.ValueToLogPoint(ActualXAxis, draggingSegment.XData);

                if (CustomTemplate != null)
                {
                    AnimationElement = GetPreviewEllipse() as ContentControl;
                    AnimateSegmentTemplate(positionX, positionY, draggingSegment);
                }
                else if (isAdornment)
                {
                    if (AdornmentsInfo.Symbol.ToString() == "Custom")
                    {
                        AnimateAdornmentSymbolTemplate(positionX, positionY);
                    }
                    else
                    {
                        AddAnimationEllipse(
                            ChartDictionaries.GenericSymbolDictionary["Animation" + AdornmentsInfo.Symbol.ToString() + "Template"] as ControlTemplate,
                            AdornmentsInfo.SymbolHeight,
                            AdornmentsInfo.SymbolWidth,
                            positionX,
                            positionY,
                            Adornments[SegmentIndex],
                            true);
                    }
                }
                else
                {
                    AddAnimationEllipse(
                        ChartDictionaries.GenericSymbolDictionary["AnimationEllipseTemplate"] as ControlTemplate,
                        ScatterHeight,
                        ScatterWidth,
                        positionX,
                        positionY,
                        Segments[SegmentIndex],
                        false);
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Creates the segments of ScatterSeries
        /// </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)
            {
                if (isGrouping)
                {
                    Segments.Clear();
                    Adornments.Clear();
                    for (int i = 0; i < xValues.Count; i++)
                    {
                        if (i < GroupedSeriesYValues[0].Count)
                        {
                            ScatterSegment scatterSegment = new ScatterSegment(xValues[i], GroupedSeriesYValues[0][i], this);
                            scatterSegment.Series = this;
                            scatterSegment.SetData(xValues[i], GroupedSeriesYValues[0][i]);
                            scatterSegment.YData = GroupedSeriesYValues[0][i];
                            scatterSegment.XData = xValues[i];
                            scatterSegment.Item  = ActualData[i];
                            Segments.Add(scatterSegment);
                            if (AdornmentsInfo != null)
                            {
                                AddAdornments(xValues[i], GroupedSeriesYValues[0][i], i);
                            }
                        }
                    }
                }
                else
                {
                    ClearUnUsedSegments(this.DataCount);
                    ClearUnUsedAdornments(this.DataCount);
                    for (int i = 0; i < this.DataCount; i++)
                    {
                        if (i < Segments.Count)
                        {
                            (Segments[i].Item) = ActualData[i];
                            (Segments[i]).SetData(xValues[i], YValues[i]);
                            (Segments[i] as ScatterSegment).XData = xValues[i];
                            (Segments[i] as ScatterSegment).Item  = ActualData[i];
                            if (SegmentColorPath != null && !Segments[i].IsEmptySegmentInterior && ColorValues.Count > 0 && !Segments[i].IsSelectedSegment)
                            {
                                Segments[i].Interior = (Interior != null) ? Interior : ColorValues[i];
                            }
                        }
                        else
                        {
                            ScatterSegment scatterSegment = new ScatterSegment(xValues[i], YValues[i], this);
                            scatterSegment.Series = this;
                            scatterSegment.SetData(xValues[i], YValues[i]);
                            scatterSegment.YData = YValues[i];
                            scatterSegment.XData = xValues[i];
                            scatterSegment.Item  = ActualData[i];
                            Segments.Add(scatterSegment);
                        }

                        if (AdornmentsInfo != null)
                        {
                            AddAdornments(xValues[i], YValues[i], i);
                        }
                    }
                }

                if (ShowEmptyPoints)
                {
                    UpdateEmptyPointSegments(xValues, false);
                }
            }
        }
Beispiel #6
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);
                }
            }
        }