using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Drawing.Drawing2D; using System.ComponentModel; namespace DevComponents.DotNetBar.MicroCharts { internal class AreaMicroChart : MicroChartBase { public override void CreateChart(MicroChartRenderInfo info) { Graphics graphics = info.Graphics; int pointRadius = Dpi.Width(PointRadius); int chartHeight = info.ChartHeight - pointRadius * 2; int chartWidth = info.ChartWidth - pointRadius * 2; int drawStep = Math.Max(3, (chartWidth / (Math.Max(1, info.DataPoints.Count - 1)))); int dataStep = Math.Max(1, ((info.DataPoints.Count * drawStep) / chartWidth)); int x = pointRadius; double dataPointMinValue = info.DataPointMinValue; double zeroValue = _MicroChartStyle.ZeroLineValue; if (dataPointMinValue > zeroValue) dataPointMinValue = zeroValue; double range = info.DataPointMaxValue - dataPointMinValue; if (range == 0) range = 1; int zeroY = Math.Min((int)(chartHeight * (1 - (zeroValue - dataPointMinValue) / range)), chartHeight - 1) + pointRadius; int totalPoints = (int)Math.Ceiling((double)info.DataPoints.Count / dataStep); Point[] chartPoints = new Point[totalPoints]; MicroChartHotPoint[] microHotPoints = new MicroChartHotPoint[totalPoints]; int index = 0; GraphicsPath areaPath = new GraphicsPath(); Point lastPoint = new Point(0, zeroY); Point lowPoint = Point.Empty, highPoint = Point.Empty; for (int i = 0; i < info.DataPoints.Count; i += dataStep) { double value = info.DataPoints[i]; double nextValue = (i < (info.DataPoints.Count - 1)) ? info.DataPoints[i + 1] : zeroValue; Point p = new Point(x, Math.Min((int)(chartHeight * (1 - (value - dataPointMinValue) / range)), chartHeight - 1) + pointRadius); Point endPoint = new Point(x + drawStep, Math.Min((int)(chartHeight * (1 - (nextValue - dataPointMinValue) / range)), chartHeight - 1)); if (lowPoint.IsEmpty && value == info.DataPointMinValue) lowPoint = p; else if (/*highPoint.IsEmpty &&*/ value == info.DataPointMaxValue) highPoint = p; chartPoints[index] = p; if (i + dataStep >= info.DataPoints.Count) areaPath.AddPolygon(new Point[] { new Point(x, zeroY), p, endPoint, new Point(chartWidth, endPoint.Y), new Point(chartWidth, zeroY) }); else areaPath.AddPolygon(new Point[] { new Point(x, zeroY), p, endPoint, new Point(endPoint.X, zeroY) }); microHotPoints[index] = new MicroChartHotPoint(GetHotPointBounds(p, info), new Rectangle(p.X - drawStep / 2, 0, endPoint.X - p.X, chartHeight), Color.Gray /*_MicroChartStyle.LineColor*/, value, index); index++; x += drawStep; } using (SolidBrush brush = new SolidBrush(_MicroChartStyle.AreaColor)) graphics.FillPath(brush, areaPath); areaPath.Dispose(); if (!lowPoint.IsEmpty && !_MicroChartStyle.LowPointColor.IsEmpty) { using (SolidBrush brush = new SolidBrush(_MicroChartStyle.LowPointColor)) graphics.FillPolygon(brush, GetChartPointBounds(lowPoint)); } if (!highPoint.IsEmpty && !_MicroChartStyle.HighPointColor.IsEmpty) { using (SolidBrush brush = new SolidBrush(_MicroChartStyle.HighPointColor)) graphics.FillPolygon(brush, GetChartPointBounds(highPoint)); } if (!_MicroChartStyle.FirstPointColor.IsEmpty && chartPoints.Length > 0) { using (SolidBrush brush = new SolidBrush(_MicroChartStyle.FirstPointColor)) graphics.FillPolygon(brush, GetChartPointBounds(chartPoints[0])); } if (!_MicroChartStyle.LastPointColor.IsEmpty && chartPoints.Length > 1) { using (SolidBrush brush = new SolidBrush(_MicroChartStyle.LastPointColor)) graphics.FillPolygon(brush, GetChartPointBounds(chartPoints[chartPoints.Length - 1])); } info.MicroChartHotPoints = microHotPoints; } private static int HotPointOffset { get { return Dpi.Width4; } } private Rectangle GetHotPointBounds(Point hotPoint, MicroChartRenderInfo info) { //Rectangle bounds = new Rectangle(Math.Min(info.ChartWidth - HotPointOffset * 2, Math.Max(-1, hotPoint.X - HotPointOffset)), // Math.Min(info.ChartHeight - HotPointOffset * 2, Math.Max(-1, hotPoint.Y - HotPointOffset)), // HotPointOffset * 2, // HotPointOffset * 2); Rectangle bounds = new Rectangle(hotPoint.X - HotPointOffset, hotPoint.Y - HotPointOffset, HotPointOffset * 2, HotPointOffset * 2); return bounds; } private AreaMicroChartStyle _MicroChartStyle; public AreaMicroChartStyle Style { get { return _MicroChartStyle; } set { _MicroChartStyle = value; } } } /// /// Defines the style for Area micro chart. /// [System.ComponentModel.ToolboxItem(false), System.ComponentModel.DesignTimeVisible(false), TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))] public class AreaMicroChartStyle { /// /// Initializes a new instance of the AreaMicroChartStyle class. /// public AreaMicroChartStyle() { } /// /// Occurs when style appearance changes. /// public event EventHandler StyleChanged; /// /// Raises StyleChanged event. /// /// Provides event arguments. protected virtual void OnStyleChanged(EventArgs e) { EventHandler handler = StyleChanged; if (handler != null) handler(this, e); } private void OnStyleChanged() { OnStyleChanged(EventArgs.Empty); } private double _ZeroLineValue = 0d; /// /// Gets or sets the value of the zero line, i.e. where zero line is drawn. Default value is 0. /// [DefaultValue(0d), Category("Appearance"), Description("Indicates value of the zero line, i.e. where zero line is drawn.")] public double ZeroLineValue { get { return _ZeroLineValue; } set { _ZeroLineValue = value; OnStyleChanged(); } } private Color _AreaColor = ColorScheme.GetColor(0x938953); /// /// Gets or sets the chart area color. /// [Category("Columns"), Description("Indicates chart area color.")] public Color AreaColor { get { return _AreaColor; } set { _AreaColor = value; OnStyleChanged(); } } /// /// Gets whether property should be serialized. /// [EditorBrowsable(EditorBrowsableState.Never)] public bool ShouldSerializeAreaColor() { return _AreaColor != ColorScheme.GetColor(0x938953); } /// /// Resets property to its default value. /// [EditorBrowsable(EditorBrowsableState.Never)] public void ResetAreaColor() { this.AreaColor = ColorScheme.GetColor(0x938953); } private Color _HighPointColor = Color.Empty; /// /// Gets or sets the color of the high point dot on chart. /// [Category("Columns"), Description("Indicates color of high point dot on chart..")] public Color HighPointColor { get { return _HighPointColor; } set { _HighPointColor = value; OnStyleChanged(); } } /// /// Gets whether property should be serialized. /// [EditorBrowsable(EditorBrowsableState.Never)] public bool ShouldSerializeHighPointColor() { return !_HighPointColor.IsEmpty; } /// /// Resets property to its default value. /// [EditorBrowsable(EditorBrowsableState.Never)] public void ResetHighPointColor() { this.HighPointColor = Color.Empty; } private Color _LowPointColor = Color.Empty; /// /// Gets or sets the color of the low point dot on chart. /// [Category("Columns"), Description("Indicates color of low point dot on chart.")] public Color LowPointColor { get { return _LowPointColor; } set { _LowPointColor = value; OnStyleChanged(); } } /// /// Gets whether property should be serialized. /// [EditorBrowsable(EditorBrowsableState.Never)] public bool ShouldSerializeLowPointColor() { return !_LowPointColor.IsEmpty; } /// /// Resets property to its default value. /// [EditorBrowsable(EditorBrowsableState.Never)] public void ResetLowPointColor() { this.LowPointColor = Color.Empty; } private Color _FirstPointColor = Color.Empty; /// /// Gets or sets the color of the first point dot on chart. /// [Category("Columns"), Description("Indicates color of first point dot on chart..")] public Color FirstPointColor { get { return _FirstPointColor; } set { _FirstPointColor = value; OnStyleChanged(); } } /// /// Gets whether property should be serialized. /// [EditorBrowsable(EditorBrowsableState.Never)] public bool ShouldSerializeFirstPointColor() { return !_FirstPointColor.IsEmpty; } /// /// Resets property to its default value. /// [EditorBrowsable(EditorBrowsableState.Never)] public void ResetFirstPointColor() { this.FirstPointColor = Color.Empty; } private Color _LastPointColor = Color.Empty; /// /// Gets or sets the color of the last point dot on chart. /// [Category("Columns"), Description("Indicates color of last point dot on chart.")] public Color LastPointColor { get { return _LastPointColor; } set { _LastPointColor = value; OnStyleChanged(); } } /// /// Gets whether property should be serialized. /// [EditorBrowsable(EditorBrowsableState.Never)] public bool ShouldSerializeLastPointColor() { return !_LastPointColor.IsEmpty; } /// /// Resets property to its default value. /// [EditorBrowsable(EditorBrowsableState.Never)] public void ResetLastPointColor() { this.LastPointColor = Color.Empty; } } }