using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace DevComponents.DotNetBar.MicroCharts { /// /// Represents the base class each micro-chart implements /// internal abstract class MicroChartBase { internal const int PointRadius = 3; /// /// Creates the chart image. /// /// Rendering information. /// Image of the chart. public abstract void CreateChart(MicroChartRenderInfo info); protected virtual Point[] GetChartPointBounds(Point p) { return new Point[] { new Point(p.X, p.Y - PointRadius), new Point(p.X - PointRadius, p.Y), new Point(p.X, p.Y + PointRadius), new Point(p.X + PointRadius, p.Y), new Point(p.X, p.Y - PointRadius) }; } } internal struct TrendInfo { public double Slope; public double Intercept; public double Start; public double End; /// /// Initializes a new instance of the TrendInfo structure. /// /// /// /// /// public TrendInfo(double slope, double intercept, double start, double end) { Slope = slope; Intercept = intercept; Start = start; End = end; } /// /// Initializes a new instance of the TrendInfo structure. /// static TrendInfo() { } } internal class MicroChartRenderInfo { public List DataPoints; public MicroChartHotPoint[] MicroChartHotPoints; public Graphics Graphics; public int ChartWidth; public int ChartHeight; public double DataPointMaxValue; public double DataPointMinValue; public double Sum; public TrendInfo TrendInfo; /// /// Initializes a new instance of the MicroChartRenderInfo structure. /// /// /// /// /// public MicroChartRenderInfo(List dataPoints, Graphics graphics, int chartWidth, int chartHeight, double dataMax, double dataMin) { DataPoints = dataPoints; Graphics = graphics; ChartWidth = chartWidth; ChartHeight = chartHeight; MicroChartHotPoints = null; DataPointMaxValue = dataMax; DataPointMinValue = dataMin; Sum = 0; TrendInfo = new TrendInfo(); UpdateChartStats(); } private void UpdateChartStats() { if (DataPoints == null || DataPoints.Count == 0) return; double min = DataPoints[0], max = DataPoints[0]; // For trending double xxSum = 0, xySum = 0, xAxisValuesSum = 0, yAxisValuesSum = 0; Sum = Math.Abs(DataPoints[0]); for (int i = 1; i < DataPoints.Count; i++) { double value = DataPoints[i]; if (value < min) min = value; if (value > max) max = value; Sum += Math.Abs(value); xySum += value * (i + 1); xxSum = value * value; yAxisValuesSum += value; xAxisValuesSum += i + 1; } double slope = 0, intercept = 0, start = 0, end = 0; try { slope = ((DataPoints.Count * xySum) - (xAxisValuesSum * yAxisValuesSum)) / ((DataPoints.Count * xxSum) - (xAxisValuesSum * xAxisValuesSum)); } catch (DivideByZeroException) { } intercept = (yAxisValuesSum - (slope * xAxisValuesSum)) / DataPoints.Count; start = Math.Max(0, (slope * DataPoints[0]) + intercept); end = (slope * DataPoints[DataPoints.Count - 1]) + intercept; this.TrendInfo = new TrendInfo(slope, intercept, start, end); if(double.IsNaN(DataPointMaxValue)) DataPointMaxValue = max; if(double.IsNaN(DataPointMinValue)) DataPointMinValue = min; } } }