internal bool RaiseSegmentCreatedEvent(WaterfallSegment segment, int index) { WaterfallSegmentCreatedEventArgs args = new WaterfallSegmentCreatedEventArgs(); args.Segment = segment; args.Index = index; OnSegmentCreated(args); return(args.IsSummary); }
/// <summary> /// Method implementation for Set points to given index /// </summary> /// <param name="index"></param> /// <param name="obj"></param> /// <param name="replace"></param> protected override void SetIndividualPoint(int index, object obj, bool replace) { // Updating summary value of the series. if (SummaryBindingPath != null) { object summaryValue = GetArrayPropertyValue(obj, new string[] { SummaryBindingPath }); if (replace && SummaryValues.Count > index) { SummaryValues[index] = Convert.ToBoolean(summaryValue); } else { SummaryValues.Insert(index, Convert.ToBoolean(summaryValue)); } } // Updating x and y value of the series. base.SetIndividualPoint(index, obj, replace); // Updating segment's SegmentType property based on yvalue. if (SummaryValues != null && index < Segments.Count && index < YValues.Count) { WaterfallSegment segment = Segments[index] as WaterfallSegment; if (SummaryValues[index] == false) { if (YValues[index] < 0) { segment.SegmentType = WaterfallSegmentType.Negative; } else { segment.SegmentType = WaterfallSegmentType.Positive; } } else { segment.SegmentType = WaterfallSegmentType.Sum; } // Updating changed segment interior property. segment.BindProperties(); } }
/// <summary> /// Method used to update the segment's interior color based on WaterfallSegmentType. /// </summary> /// <param name="segment"></param> internal void BindWaterfallSegmentInterior(WaterfallSegment segment) { Binding binding = new Binding(); binding.Source = segment.Series; if (segment.SegmentType == WaterfallSegmentType.Negative && (segment.Series as WaterfallSeries).NegativeSegmentBrush != null) { binding.Path = new PropertyPath("NegativeSegmentBrush"); BindingOperations.SetBinding(this, ChartSegment.InteriorProperty, binding); } else if (segment.SegmentType == WaterfallSegmentType.Sum && (segment.Series as WaterfallSeries).SummarySegmentBrush != null) { binding.Path = new PropertyPath("SummarySegmentBrush"); BindingOperations.SetBinding(this, ChartSegment.InteriorProperty, binding); } else { binding.Path = new PropertyPath("Interior"); binding.Converter = new InteriorConverter(segment.Series); binding.ConverterParameter = segment.Series.Segments.IndexOf(segment); BindingOperations.SetBinding(this, ChartSegment.InteriorProperty, binding); } }
private void OnUpdateSumSegmentValues(WaterfallSegment segment, int i, bool isSum, double origin) { double yData = !double.IsNaN(segment.YData) ? segment.YData : 0; // Setting previous segment if (i - 1 >= 0) { segment.PreviousWaterfallSegment = (Segments[i - 1] as WaterfallSegment); } // Set values for sum type segment if (isSum || (SummaryValues != null && i < SummaryValues.Count && SummaryValues[i])) { segment.SegmentType = WaterfallSegmentType.Sum; if (segment.PreviousWaterfallSegment != null) { segment.WaterfallSum = segment.PreviousWaterfallSegment.Sum; } else { segment.WaterfallSum = yData; } if (i - 1 >= 0 && AllowAutoSum) { segment.Bottom = origin; segment.Top = segment.WaterfallSum; } else { ////segment.Sum = YValues[i]; if (YValues[i] >= 0) { segment.Bottom = origin; segment.Top = YValues[i]; } else if (double.IsNaN(YValues[i])) { segment.Bottom = segment.Top = origin; } else { segment.Top = origin; segment.Bottom = YValues[i]; } } segment.YRange = new DoubleRange(segment.Top, segment.Bottom); } else { if (YValues[i] < 0) { segment.SegmentType = WaterfallSegmentType.Negative; } else { segment.SegmentType = WaterfallSegmentType.Positive; } } if (!AllowAutoSum && segment.SegmentType == WaterfallSegmentType.Sum) { segment.Sum = yData; } else if (segment.PreviousWaterfallSegment != null && segment.SegmentType != WaterfallSegmentType.Sum) { segment.Sum = yData + segment.PreviousWaterfallSegment.Sum; } else if (segment.PreviousWaterfallSegment != null) { segment.Sum = segment.PreviousWaterfallSegment.Sum; } else { segment.Sum = yData; } }
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> /// 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; }