/// <summary> /// Calculates actual range /// </summary> /// <param name="axis">The axis.</param> /// <param name="range">The range.</param> /// <param name="logarithmicBase">The logarithmic base.</param> /// <returns></returns> internal static DoubleRange CalculateActualRange(ChartAxis axis, DoubleRange range, double logarithmicBase) { if (range.IsEmpty) { return(range); } double logStart = Math.Log(range.Start, logarithmicBase); logStart = double.IsInfinity(logStart) || double.IsNaN(logStart) ? range.Start : logStart; double logEnd = Math.Log(range.End, logarithmicBase); logEnd = double.IsInfinity(logEnd) || double.IsNaN(logEnd) ? logarithmicBase : logEnd; double mulS = ChartMath.Round(logStart, 1, false); double mulE = ChartMath.Round(logEnd, 1, true); range = new DoubleRange(mulS, mulE); return(range); }
/// <summary> /// Creates the segments of HistogramSeries. /// </summary> public override void CreateSegments() { List <double> xValues = GetXValues(); int index = 0; double x1, y1, y2; float median; 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) { Segments.Clear(); ClearUnUsedAdornments(Segments.Count); ActualYValues.Clear(); List <Point> dataPoints = new List <Point>(); List <ChartSegment> segmentsCollection = new List <ChartSegment>(); for (int i = 0; i < DataCount; i++) { dataPoints.Add(new Point(xValues[i], yValues[i])); } Array.Sort(dataPoints.ToArray(), new PointsSortByXComparer()); double interval = HistogramInterval; double start = 0; if (dataPoints.Count > 0) { start = ChartMath.Round(dataPoints[0].X, interval, false); } int pointsCount; double position = start; int intervalsCount = 0; List <Point> points = new List <Point>(); List <object> data = new List <object>(); HistogramSegment histogramSegment; for (int i = 0, ci = dataPoints.Count; i < ci; i++) { Point cdpt = dataPoints[i]; while (cdpt.X > position + interval) { pointsCount = points.Count; if (pointsCount > 0) { histogramSegment = new HistogramSegment(position, pointsCount, position + interval, 0, this); histogramSegment.XData = index; histogramSegment.YData = pointsCount; histogramSegment.Data = data; data = new List <object>(); segmentsCollection.Add(histogramSegment); ActualYValues.Add(pointsCount); points.Clear(); index++; } position += interval; intervalsCount++; } points.Add(dataPoints[i]); data.Add(ActualData[i]); } pointsCount = points.Count; if (pointsCount > 0) { intervalsCount++; histogramSegment = new HistogramSegment(position, pointsCount, position + interval, 0, this); histogramSegment.XData = index; histogramSegment.YData = pointsCount; histogramSegment.Data = data; data = new List <object>(); segmentsCollection.Add(histogramSegment); ActualYValues.Add(pointsCount); points.Clear(); } median = (float)interval / 2; if (AdornmentsInfo != null) { for (int i = 0; i < segmentsCollection.Count; i++) { x1 = (segmentsCollection[i] as HistogramSegment).XRange.Start; y1 = (segmentsCollection[i] as HistogramSegment).YData; y2 = origin; if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Top) { AddColumnAdornments( (segmentsCollection[i] as HistogramSegment).XData, (segmentsCollection[i] as HistogramSegment).YData, x1, y1, i, median); } else if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Bottom) { AddColumnAdornments( (segmentsCollection[i] as HistogramSegment).XData, (segmentsCollection[i] as HistogramSegment).YData, x1, y2, i, median); } else { AddColumnAdornments( (segmentsCollection[i] as HistogramSegment).XData, (segmentsCollection[i] as HistogramSegment).YData, x1, y1 + (y2 - y1) / 2, i, median); } } } #region Normal Distribution if (ShowNormalDistributionCurve) { double m, dev; GetHistogramMeanAndDeviation(dataPoints, out m, out dev); PointCollection distributionPoints = new PointCollection(); double min = start; double max = start + intervalsCount * interval; double del = (max - min) / (C_distributionPointsCount - 1); for (int i = 0; i < C_distributionPointsCount; i++) { double tx = min + i * del; double ty = NormalDistribution(tx, m, dev) * dataPoints.Count * interval; distributionPoints.Add(new Point(tx, ty)); } segmentsCollection.Add(new HistogramDistributionSegment(distributionPoints, this)); } foreach (var item in segmentsCollection) { Segments.Add(item); } #endregion } }