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); }
/// <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); } } }
/// <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); } } }