10638 lines
		
	
	
		
			316 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			10638 lines
		
	
	
		
			316 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.ComponentModel;
 | |
| using System.Drawing;
 | |
| using System.Drawing.Design;
 | |
| using System.Drawing.Drawing2D;
 | |
| using System.Globalization;
 | |
| using System.Runtime.InteropServices;
 | |
| using System.Text;
 | |
| using System.Text.RegularExpressions;
 | |
| using System.Windows.Forms;
 | |
| using DevComponents.DotNetBar.Charts.Style;
 | |
| 
 | |
| namespace DevComponents.DotNetBar.Charts
 | |
| {
 | |
|     /// <summary>
 | |
|     /// Represents the collection of ChartSeries.
 | |
|     /// </summary>
 | |
|     [Editor("DevComponents.Charts.Design.ChartSeriesCollectionEditor, DevComponents.Charts.Design, " +
 | |
|             "Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
 | |
|     public class ChartSeriesCollection : CustomNamedCollection<ChartSeries>
 | |
|     {
 | |
|         #region GetUniqueName
 | |
| 
 | |
|         public string GetUniqueName()
 | |
|         {
 | |
|             return (GetUniqueName("Series"));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|     }
 | |
| 
 | |
|     public class ChartSeries : ChartVisualElement, ILegendItem
 | |
|     {
 | |
|         #region Constants
 | |
| 
 | |
|         private const int StockHigh = 0;
 | |
|         private const int StockLow = 1;
 | |
|         private const int StockClose = 2;
 | |
|         private const int StockOpen = 3;
 | |
|         private const int StockMedian = 4;
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Private variables
 | |
| 
 | |
|         private States _States;
 | |
| 
 | |
|         private SeriesType _SeriesType = SeriesType.Point;
 | |
|         private SeriesPointCollection _SeriesPoints;
 | |
| 
 | |
|         private PointData _PointData;
 | |
|         private PointData _EmptyPointData;
 | |
|         private PointData _StepPointData;
 | |
| 
 | |
|         private object _DataSource;
 | |
|         private string _DataMember;
 | |
|         private DataBinder _DataBinder;
 | |
| 
 | |
|         private string _DataPropertyNameSeries;
 | |
|         private string _DataPropertyNameX;
 | |
|         private CustomCollection<string> _DataPropertyNamesY;
 | |
| 
 | |
|         private int _SeriesId;
 | |
|         private object _SeriesKey;
 | |
| 
 | |
|         private ChartAxis _AxisX;
 | |
|         private ChartAxis _AxisY;
 | |
| 
 | |
|         private int _BarOffset;
 | |
|         private int _BarWidth;
 | |
|         private double _BarWidthRatio;
 | |
| 
 | |
|         private Tbool _BarShadingEnabled = Tbool.NotSet;
 | |
|         private BarFillRange _BarFillRange = BarFillRange.NotSet;
 | |
|         private BarLabelPosition _BarLabelPosition = BarLabelPosition.NotSet;
 | |
| 
 | |
|         private Color[] _BarShadingColors;
 | |
| 
 | |
|         private ChartLegendItemVisualStyles _ChartLegendItemVisualStyles;
 | |
| 
 | |
|         private ChartSeriesVisualStyle _ChartSeriesVisualStyle;
 | |
|         private EffectiveStyle<ChartSeriesVisualStyle> _EffectiveChartSeriesStyle;
 | |
| 
 | |
|         private DataLabelVisualStyle _DataLabelVisualStyle;
 | |
|         private EffectiveStyle<DataLabelVisualStyle> _EffectiveDataLabelStyle;
 | |
| 
 | |
|         private Tbool _CrosshairEnabled = Tbool.NotSet;
 | |
|         private Tbool _CrosshairHighlightPoints = Tbool.NotSet;
 | |
|         private Tbool _CrosshairShowLabels = Tbool.NotSet;
 | |
| 
 | |
|         private ScaleType _ScaleTypeX = ScaleType.NotSet;
 | |
|         private ScaleType _ScaleTypeY = ScaleType.NotSet;
 | |
|         private ScaleType _ActualScaleTypeX = ScaleType.NotSet;
 | |
|         private ScaleType _ActualScaleTypeY = ScaleType.NotSet;
 | |
| 
 | |
|         private string _LegendText;
 | |
|         private ChartLegendItem _LegendItem;
 | |
| 
 | |
|         private object _MinValueX;
 | |
|         private object _MinValueY;
 | |
| 
 | |
|         private object _MaxValueX;
 | |
|         private object _MaxValueY;
 | |
| 
 | |
|         private object _AreaBaseValue;
 | |
| 
 | |
|         private bool _SeriesRangeChanged = true;
 | |
|         private SortedSeriesPoints _SortedSeriesPoints;
 | |
|         private object[] _EmptyValues;
 | |
| 
 | |
|         private List<object> _QualitativeXValues;
 | |
|         private List<object> _QualitativeYValues;
 | |
| 
 | |
|         private PointMarker _PointMarker;
 | |
|         private Image _PointMarkerImage;
 | |
|         private Image _PointMarkerEmptyImage;
 | |
|         private Image _PointMarkerHighlightImage;
 | |
|         private Point _PointOffset;
 | |
| 
 | |
|         private int _GroupId;
 | |
|         private object _PlotData;
 | |
|         private double _DotPlotIndexValue = 1.0d;
 | |
| 
 | |
|         private ChartIndicatorCollection _ChartIndicators;
 | |
|         private Point[] _ConvexHullPoints;
 | |
| 
 | |
|         private double _BubbleScaleFactor = 1.0d;
 | |
|         private double _BubbleMaxPercentage = .25d;
 | |
|         private int _BubbleMinSize = 4;
 | |
|         private BubbleSizeMode _BubbleSizeMode = BubbleSizeMode.NotSet;
 | |
| 
 | |
|         private BubbleIntensityMode _BubbleIntensityMode = BubbleIntensityMode.NotSet;
 | |
|         private ChartLineDisplayMode _ChartLineDisplayMode = ChartLineDisplayMode.NotSet;
 | |
|         private ChartLineAreaDisplayMode _ChartLineAreaDisplayMode = ChartLineAreaDisplayMode.NotSet;
 | |
|         private ConvexHullDisplayMode _ConvexHullDisplayMode = ConvexHullDisplayMode.NotSet;
 | |
|         private PointLabelDisplayMode _PointLabelDisplayMode = PointLabelDisplayMode.NotSet;
 | |
| 
 | |
|         private StepLines _StepLines = StepLines.NotSet;
 | |
|         private StepLineMode _StepLineMode = StepLineMode.NotSet;
 | |
|         private StepLineMode _LastStepLineMode = StepLineMode.NotSet;
 | |
| 
 | |
|         private Color _DefaultPaletteColor = Color.Empty;
 | |
| 
 | |
|         private DataLabelCollection _DataLabels;
 | |
|         private int _PointLabelSkip;
 | |
|         private int _PointLabelMinDistance;
 | |
| 
 | |
|         private HiLoBarType _HiLoBarType = HiLoBarType.Box;
 | |
|         private Rectangle _RenderBounds;
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Constructors
 | |
| 
 | |
|         public ChartSeries()
 | |
|             : this(null, SeriesType.Point)
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         public ChartSeries(string name)
 | |
|             : this(name, SeriesType.Point)
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         public ChartSeries(SeriesType seriesType)
 | |
|             : this(null, seriesType)
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         public ChartSeries(string name, SeriesType seriesType)
 | |
|         {
 | |
|             Name = name;
 | |
|             SeriesType = seriesType;
 | |
| 
 | |
|             InitDefaultStates();
 | |
| 
 | |
|             _EffectiveChartSeriesStyle = new EffectiveStyle<ChartSeriesVisualStyle>(this);
 | |
|             _EffectiveDataLabelStyle = new EffectiveStyle<DataLabelVisualStyle>(this);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region InitDefaultStates
 | |
| 
 | |
|         private void InitDefaultStates()
 | |
|         {
 | |
|             SetState(States.ShowInLegend, true);
 | |
|             SetState(States.ShowInParentLegend, true);
 | |
|             SetState(States.ShowCheckBoxInLegend, true);
 | |
|             SetState(States.ShowMarkerInLegend, true);
 | |
|             SetState(States.CheckedInLegend, true);
 | |
|             SetState(States.DisplayLinePointsOnTop, true);
 | |
|             SetState(States.StackQualitativePoints, true);
 | |
|             SetState(States.ShowOriginValueLabels, true);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Public properties
 | |
| 
 | |
|         #region ActualScaleTypeX
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets the Actual X axis Scale Type (may be
 | |
|         /// different than XScaleType when XScaleType is 'Auto').
 | |
|         ///</summary>
 | |
|         [Browsable(false)]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | |
|         public ScaleType ActualScaleTypeX
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (IsRotated == false)
 | |
|                     return (_ActualScaleTypeX);
 | |
| 
 | |
|                 return (_ActualScaleTypeY);
 | |
|             }
 | |
| 
 | |
|             internal set { _ActualScaleTypeX = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ActualScaleTypeY
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets the Actual Y axis Scale Type (may be
 | |
|         /// different than YScaleType when YScaleType is 'Auto').
 | |
|         ///</summary>
 | |
|         [Browsable(false)]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | |
|         public ScaleType ActualScaleTypeY
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (IsRotated == true)
 | |
|                     return (_ActualScaleTypeX);
 | |
| 
 | |
|                 return (_ActualScaleTypeY);
 | |
|             }
 | |
| 
 | |
|             internal set { _ActualScaleTypeY = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region AreaBaseValue
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the base, reference value for displaying Line/Spline/Step Areas.
 | |
|         ///</summary>
 | |
|         [DefaultValue(null), Category("Data")]
 | |
|         [Description("Indicates the base, reference value for displaying Line/Spline/Step Areas.")]
 | |
|         [TypeConverter("DevComponents.Charts.Design.PointValueConverter," +
 | |
|             "DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")]
 | |
|         public object AreaBaseValue
 | |
|         {
 | |
|             get { return (_AreaBaseValue); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _AreaBaseValue)
 | |
|                 {
 | |
|                     _AreaBaseValue = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("AreaBaseValue", Style.VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region AxisX
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets a reference to the X-Axis associated with the series.
 | |
|         /// </summary>
 | |
|         [Category("Axis"), DefaultValue(null)]
 | |
|         [Description("Indicates the reference to the X-Axis associated with the series.")]
 | |
|         [TypeConverter(typeof(AxisTypeConverter))]
 | |
|         [Editor("DevComponents.Charts.Design.AxisListTypeEditor, DevComponents.Charts.Design, " +
 | |
|                 "Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
 | |
|         public ChartAxis AxisX
 | |
|         {
 | |
|             get { return (_AxisX); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _AxisX)
 | |
|                 {
 | |
|                     ChartXy chartXy = Parent as ChartXy;
 | |
| 
 | |
|                     if (value != null)
 | |
|                     {
 | |
|                         if (value.IsPrimaryAxis == false)
 | |
|                         {
 | |
|                             if (chartXy != null)
 | |
|                             {
 | |
|                                 if (chartXy.AncillaryAxesX.Contains(value) == false)
 | |
|                                 {
 | |
|                                     throw new Exception("Cannot set the series XAxis. The axis is not primary " +
 | |
|                                         "or a member of the chart's AncillaryAxesX collection.");
 | |
|                                 }
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     if (_AxisX != null)
 | |
|                     {
 | |
|                         _AxisX.SeriesRangeChanged = true;
 | |
|                         _AxisX.PropertyChanged -= AxisX_PropertyChanged;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (chartXy != null)
 | |
|                             chartXy.AxisX.SeriesRangeChanged = true;
 | |
|                     }
 | |
| 
 | |
|                     _AxisX = value;
 | |
| 
 | |
|                     if (_AxisX != null)
 | |
|                     {
 | |
|                         _AxisX.SeriesRangeChanged = true;
 | |
|                         _AxisX.PropertyChanged += AxisX_PropertyChanged;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (chartXy != null)
 | |
|                             chartXy.AxisX.SeriesRangeChanged = true;
 | |
|                     }
 | |
| 
 | |
|                     OnPropertyChangedEx("AxisX", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         void AxisX_PropertyChanged(object sender, PropertyChangedEventArgs e)
 | |
|         {
 | |
|             InvalidateLayout();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region AxisY
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets a reference to the Y-Axis associated with the series.
 | |
|         /// </summary>
 | |
|         [Category("Axis"), DefaultValue(null)]
 | |
|         [Description("Indicates the reference to the Y-Axis associated with the series.")]
 | |
|         [Editor("DevComponents.Charts.Design.AxisListTypeEditor, DevComponents.Charts.Design, " +
 | |
|                 "Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
 | |
|         public ChartAxis AxisY
 | |
|         {
 | |
|             get { return (_AxisY); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _AxisY)
 | |
|                 {
 | |
|                     ChartXy chartXy = Parent as ChartXy;
 | |
| 
 | |
|                     if (value != null)
 | |
|                     {
 | |
|                         if (value.IsPrimaryAxis == false)
 | |
|                         {
 | |
|                             if (chartXy != null)
 | |
|                             {
 | |
|                                 if (chartXy.AncillaryAxesY.Contains(value) == false)
 | |
|                                 {
 | |
|                                     throw new Exception("Cannot set the series YAxis. The axis is not primary " +
 | |
|                                         "or a member of the chart's AncillaryAxesY collection.");
 | |
|                                 }
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     if (_AxisY != null)
 | |
|                     {
 | |
|                         _AxisY.SeriesRangeChanged = true;
 | |
|                         _AxisY.PropertyChanged -= AxisY_PropertyChanged;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (chartXy != null)
 | |
|                             chartXy.AxisY.SeriesRangeChanged = true;
 | |
|                     }
 | |
| 
 | |
|                     _AxisY = value;
 | |
| 
 | |
|                     if (_AxisY != null)
 | |
|                     {
 | |
|                         _AxisY.SeriesRangeChanged = true;
 | |
|                         _AxisY.PropertyChanged += AxisY_PropertyChanged;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (chartXy != null)
 | |
|                             chartXy.AxisY.SeriesRangeChanged = true;
 | |
|                     }
 | |
| 
 | |
|                     OnPropertyChangedEx("AxisY", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         void AxisY_PropertyChanged(object sender, PropertyChangedEventArgs e)
 | |
|         {
 | |
|             InvalidateLayout();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region BarFillRange
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets how series bars are filled (either according to
 | |
|         /// each individual bar range, or the entire series range).
 | |
|         /// </summary>
 | |
|         [DefaultValue(BarFillRange.NotSet), Category("Bar Display")]
 | |
|         [Description("Indicates how series bars are filled (either according to each individual bar range, or the entire series range).")]
 | |
|         public BarFillRange BarFillRange
 | |
|         {
 | |
|             get { return (_BarFillRange); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _BarFillRange)
 | |
|                 {
 | |
|                     _BarFillRange = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("BarFillRange", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region BarLabelPosition
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the position of bar series labels (default is Center).
 | |
|         /// </summary>
 | |
|         [DefaultValue(BarLabelPosition.NotSet), Category("Bar Display")]
 | |
|         [Description("Indicates the position of bar series labels (default is Center).")]
 | |
|         public BarLabelPosition BarLabelPosition
 | |
|         {
 | |
|             get { return (_BarLabelPosition); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _BarLabelPosition)
 | |
|                 {
 | |
|                     _BarLabelPosition = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("BarLabelPosition", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region BarShadingEnabled
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets whether Bar shading is enabled for Horizontal and Vertical Bar series.
 | |
|         ///</summary>
 | |
|         [DefaultValue(Tbool.NotSet), Category("Bar Display")]
 | |
|         [Description("Indicates whether Bar shading is enabled for Horizontal and Vertical Bar series.")]
 | |
|         public Tbool BarShadingEnabled
 | |
|         {
 | |
|             get { return (_BarShadingEnabled); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _BarShadingEnabled)
 | |
|                 {
 | |
|                     _BarShadingEnabled = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("BarShadingEnabled", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region BarWidthRatio
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the ratio of bar width to bar spacing within
 | |
|         /// the same series (defaults to 2 - bar is twice as wide as spacing).
 | |
|         /// </summary>
 | |
|         [DefaultValue(0d), Category("Bar Display")]
 | |
|         [Description("Indicates the ratio of bar width to bar spacing within the same series (defaults to 2 - bar is twice as wide as spacing).")]
 | |
|         public double BarWidthRatio
 | |
|         {
 | |
|             get { return (_BarWidthRatio); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _BarWidthRatio)
 | |
|                 {
 | |
|                     if (value < 0)
 | |
|                         throw new ArgumentException("Value must be > 0");
 | |
| 
 | |
|                     _BarWidthRatio = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("BarWidthRatio", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region BubbleIntensityMode
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the mode used to determine bubble intensities.
 | |
|         /// </summary>
 | |
|         [DefaultValue(BubbleIntensityMode.NotSet), Category("Display")]
 | |
|         [Description("Indicates the mode used to determine bubble intensities.")]
 | |
|         public BubbleIntensityMode BubbleIntensityMode
 | |
|         {
 | |
|             get { return (_BubbleIntensityMode); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _BubbleIntensityMode)
 | |
|                 {
 | |
|                     _BubbleIntensityMode = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("BubbleIntensityMode", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region BubbleMaxPercentage
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the max percentage of the display
 | |
|         /// area used to calculate series bubble sizes (default is .25).
 | |
|         /// </summary>
 | |
|         [DefaultValue(0.25d), Category("Display")]
 | |
|         [Description("Indicates the max percentage of the display area used to calculate series bubble sizes (default is .25).")]
 | |
|         public double BubbleMaxPercentage
 | |
|         {
 | |
|             get { return (_BubbleMaxPercentage); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _BubbleMaxPercentage)
 | |
|                 {
 | |
|                     if (value <= 0 || value > 1)
 | |
|                         throw new ArgumentException("Value must be between 0 and 1");
 | |
| 
 | |
|                     _BubbleMaxPercentage = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("BubbleMaxPercentage", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region BubbleMinSize
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the minimum series bubble size (in pixels) Default is 4.
 | |
|         /// </summary>
 | |
|         [DefaultValue(4), Category("Display")]
 | |
|         [Description("Indicates the minimum series bubble size (in pixels). Default is 4.")]
 | |
|         public int BubbleMinSize
 | |
|         {
 | |
|             get { return (_BubbleMinSize); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _BubbleMinSize)
 | |
|                 {
 | |
|                     if (value < 0)
 | |
|                         throw new ArgumentException("Value must be > 0");
 | |
| 
 | |
|                     _BubbleMinSize = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("BubbleMinSize", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region BubbleScaleFactor
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the Scale Factor used to calculate series bubble sizes.
 | |
|         /// </summary>
 | |
|         [DefaultValue(1.0d), Category("Display")]
 | |
|         [Description("Indicates the Scale Factor used to calculate series bubble sizes.")]
 | |
|         public double BubbleScaleFactor
 | |
|         {
 | |
|             get { return (_BubbleScaleFactor); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _BubbleScaleFactor)
 | |
|                 {
 | |
|                     _BubbleScaleFactor = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("BubbleScaleFactor", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region BubbleSizeMode
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the mode used to calculate series bubble sizes.
 | |
|         /// </summary>
 | |
|         [DefaultValue(BubbleSizeMode.NotSet), Category("Display")]
 | |
|         [Description("Indicates the mode used to calculate series bubble sizes.")]
 | |
|         public BubbleSizeMode BubbleSizeMode
 | |
|         {
 | |
|             get { return (_BubbleSizeMode); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _BubbleSizeMode)
 | |
|                 {
 | |
|                     _BubbleSizeMode = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("BubbleSizeMode", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ChartIndicators
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets a reference to the Chart Indicators collection.
 | |
|         ///</summary>
 | |
|         [DefaultValue(null), Category("Appearance")]
 | |
|         [Description("Indicates the Chart Indicators collection.")]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | |
|         public ChartIndicatorCollection ChartIndicators
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_ChartIndicators == null)
 | |
|                 {
 | |
|                     _ChartIndicators = new ChartIndicatorCollection();
 | |
| 
 | |
|                     _ChartIndicators.CollectionChanged += ChartIndicators_CollectionChanged;
 | |
|                 }
 | |
| 
 | |
|                 return (_ChartIndicators);
 | |
|             }
 | |
| 
 | |
|             internal set
 | |
|             {
 | |
|                 if (_ChartIndicators != null)
 | |
|                     _ChartIndicators.CollectionChanged -= ChartIndicators_CollectionChanged;
 | |
| 
 | |
|                 _ChartIndicators = value;
 | |
| 
 | |
|                 if (_ChartIndicators != null)
 | |
|                     _ChartIndicators.CollectionChanged += ChartIndicators_CollectionChanged;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region ChartIndicators_CollectionChanged
 | |
| 
 | |
|         void ChartIndicators_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
 | |
|         {
 | |
|             bool updateLayout = false;
 | |
| 
 | |
|             switch (e.Action)
 | |
|             {
 | |
|                 case NotifyCollectionChangedAction.Add:
 | |
|                     foreach (ChartIndicator ci in e.NewItems)
 | |
|                     {
 | |
|                         if (ci.ShowInLegend == true || ci.ShowInParentLegend == true)
 | |
|                             updateLayout = true;
 | |
| 
 | |
|                         ci.Parent = this;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case NotifyCollectionChangedAction.Replace:
 | |
|                     foreach (ChartIndicator ci in e.OldItems)
 | |
|                     {
 | |
|                         if (ci.ShowInLegend == true || ci.ShowInParentLegend == true)
 | |
|                             updateLayout = true;
 | |
| 
 | |
|                         ci.Parent = null;
 | |
|                     }
 | |
| 
 | |
|                     foreach (ChartIndicator ci in e.NewItems)
 | |
|                     {
 | |
|                         if (ci.ShowInLegend == true || ci.ShowInParentLegend == true)
 | |
|                             updateLayout = true;
 | |
| 
 | |
|                         ci.Parent = this;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case NotifyCollectionChangedAction.Remove:
 | |
|                     foreach (ChartIndicator ci in e.OldItems)
 | |
|                     {
 | |
|                         if (ci.ShowInLegend == true || ci.ShowInParentLegend == true)
 | |
|                             updateLayout = true;
 | |
| 
 | |
|                         ci.Parent = null;
 | |
|                     }
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             if (updateLayout == true)
 | |
|                 InvalidateLayout();
 | |
|             else
 | |
|                 InvalidateRender();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ChartLegendItemVisualStyles
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the visual styles for the Legend item.
 | |
|         /// </summary>
 | |
|         [Category("Style")]
 | |
|         [Description("Indicates the visual styles for the Legend item.")]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | |
|         public ChartLegendItemVisualStyles ChartLegendItemVisualStyles
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_ChartLegendItemVisualStyles == null)
 | |
|                 {
 | |
|                     _ChartLegendItemVisualStyles = new ChartLegendItemVisualStyles();
 | |
| 
 | |
|                     StyleVisualChangeHandler(null, _ChartLegendItemVisualStyles);
 | |
|                 }
 | |
| 
 | |
|                 return (_ChartLegendItemVisualStyles);
 | |
|             }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_ChartLegendItemVisualStyles != value)
 | |
|                 {
 | |
|                     ChartLegendItemVisualStyles oldValue = _ChartLegendItemVisualStyles;
 | |
| 
 | |
|                     _ChartLegendItemVisualStyles = value;
 | |
| 
 | |
|                     OnStyleChanged("ChartLegendItemVisualStyles", oldValue, value);
 | |
| 
 | |
|                     if (oldValue != null)
 | |
|                         oldValue.Dispose();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ChartLineAreaDisplayMode
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the Line 'Area' display mode.
 | |
|         /// </summary>
 | |
|         [DefaultValue(ChartLineAreaDisplayMode.NotSet), Category("Display")]
 | |
|         [Description("Indicates the Line ChartType display mode.")]
 | |
|         [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " +
 | |
|                 "Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
 | |
|         public ChartLineAreaDisplayMode ChartLineAreaDisplayMode
 | |
|         {
 | |
|             get { return (_ChartLineAreaDisplayMode); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _ChartLineAreaDisplayMode)
 | |
|                 {
 | |
|                     _ChartLineAreaDisplayMode = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("ChartLineAreaDisplayMode", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ChartLineDisplayMode
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the Line ChartType display mode.
 | |
|         /// </summary>
 | |
|         [DefaultValue(ChartLineDisplayMode.NotSet), Category("Display")]
 | |
|         [Description("Indicates the Line ChartType display mode.")]
 | |
|         [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " +
 | |
|                 "Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
 | |
|         public ChartLineDisplayMode ChartLineDisplayMode
 | |
|         {
 | |
|             get { return (_ChartLineDisplayMode); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _ChartLineDisplayMode)
 | |
|                 {
 | |
|                     _ChartLineDisplayMode = value;
 | |
| 
 | |
|                     _SortedSeriesPoints = null;
 | |
| 
 | |
|                     OnPropertyChangedEx("ChartLineDisplayMode", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ChartSeriesVisualStyle
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the visual style for the series.
 | |
|         /// </summary>
 | |
|         [Category("Style")]
 | |
|         [Description("Indicates the visual style for the series.")]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | |
|         public ChartSeriesVisualStyle ChartSeriesVisualStyle
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_ChartSeriesVisualStyle == null)
 | |
|                 {
 | |
|                     _ChartSeriesVisualStyle = new ChartSeriesVisualStyle();
 | |
| 
 | |
|                     StyleVisualChangeHandler(null, _ChartSeriesVisualStyle);
 | |
|                 }
 | |
| 
 | |
|                 return (_ChartSeriesVisualStyle);
 | |
|             }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_ChartSeriesVisualStyle != value)
 | |
|                 {
 | |
|                     ChartSeriesVisualStyle oldValue = _ChartSeriesVisualStyle;
 | |
| 
 | |
|                     _ChartSeriesVisualStyle = value;
 | |
| 
 | |
|                     OnStyleChanged("ChartSeriesVisualStyle", oldValue, value);
 | |
| 
 | |
|                     if (oldValue != null)
 | |
|                         oldValue.Dispose();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ConvexHullDisplayMode
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the ConvexHull display mode.
 | |
|         /// </summary>
 | |
|         [DefaultValue(ConvexHullDisplayMode.NotSet), Category("Display")]
 | |
|         [Description("Indicates the ConvexHull display mode.")]
 | |
|         [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " +
 | |
|                 "Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
 | |
|         public ConvexHullDisplayMode ConvexHullDisplayMode
 | |
|         {
 | |
|             get { return (_ConvexHullDisplayMode); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _ConvexHullDisplayMode)
 | |
|                 {
 | |
|                     _ConvexHullDisplayMode = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("ConvexHullDisplayMode", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CrosshairEnabled
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets whether Crosshair support is enabled for the series.
 | |
|         ///</summary>
 | |
|         [DefaultValue(Tbool.NotSet), Category("Crosshair")]
 | |
|         [Description("Indicates whether Crosshair support is enabled for the series.")]
 | |
|         public Tbool CrosshairEnabled
 | |
|         {
 | |
|             get { return (_CrosshairEnabled); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _CrosshairEnabled)
 | |
|                 {
 | |
|                     _CrosshairEnabled = value;
 | |
| 
 | |
|                     OnPropertyChanged("CrosshairEnabled");
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CrosshairHighlightPoints
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets whether Crosshair Point highlighting is enabled for the series.
 | |
|         ///</summary>
 | |
|         [DefaultValue(Tbool.NotSet), Category("Crosshair")]
 | |
|         [Description("Indicates whether Crosshair Point highlighting is enabled for the series.")]
 | |
|         public Tbool CrosshairHighlightPoints
 | |
|         {
 | |
|             get { return (_CrosshairHighlightPoints); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _CrosshairHighlightPoints)
 | |
|                 {
 | |
|                     _CrosshairHighlightPoints = value;
 | |
| 
 | |
|                     OnPropertyChanged("CrosshairHighlightPoints");
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CrosshairShowLabels
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets whether Crosshair labels are shown for the series.
 | |
|         ///</summary>
 | |
|         [DefaultValue(Tbool.NotSet), Category("Crosshair")]
 | |
|         [Description("Indicates whether Crosshair labels are shown for the series.")]
 | |
|         public Tbool CrosshairShowLabels
 | |
|         {
 | |
|             get { return (_CrosshairShowLabels); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _CrosshairShowLabels)
 | |
|                 {
 | |
|                     _CrosshairShowLabels = value;
 | |
| 
 | |
|                     OnPropertyChanged("CrosshairShowLabels");
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region DataLabels
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the list of instance Data Labels.
 | |
|         ///</summary>
 | |
|         [DefaultValue(null), Category("DataLabel")]
 | |
|         [Description("Indicates the list of instance Data Labels.")]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | |
|         public DataLabelCollection DataLabels
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_DataLabels == null)
 | |
|                 { 
 | |
|                     _DataLabels = new DataLabelCollection();
 | |
| 
 | |
|                     _DataLabels.PropertyChanged += DataLabels_PropertyChanged;
 | |
|                     _DataLabels.CollectionChanged += DataLabels_CollectionChanged;
 | |
|                 }
 | |
| 
 | |
|                 return (_DataLabels);
 | |
|             }
 | |
| 
 | |
|             internal set
 | |
|             {
 | |
|                 if (_DataLabels != null)
 | |
|                 {
 | |
|                     _DataLabels.PropertyChanged -= DataLabels_PropertyChanged;
 | |
|                     _DataLabels.CollectionChanged -= DataLabels_CollectionChanged;
 | |
|                 }
 | |
| 
 | |
|                 _DataLabels = value;
 | |
| 
 | |
|                 if (_DataLabels != null)
 | |
|                 {
 | |
|                     _DataLabels.PropertyChanged += DataLabels_PropertyChanged;
 | |
|                     _DataLabels.CollectionChanged += DataLabels_CollectionChanged;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region DataLabels_PropertyChanged
 | |
| 
 | |
|         void DataLabels_PropertyChanged(object sender, PropertyChangedEventArgs e)
 | |
|         {
 | |
|             InvalidateRender();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region DataLabels_CollectionChanged
 | |
| 
 | |
|         private void DataLabels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
 | |
|         {
 | |
|             switch (e.Action)
 | |
|             {
 | |
|                 case NotifyCollectionChangedAction.Add:
 | |
|                     foreach (DataLabel dl in e.NewItems)
 | |
|                     {
 | |
|                         dl.Parent = this;
 | |
|                         dl.PropertyChanged += DataLabel_PropertyChanged;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case NotifyCollectionChangedAction.Replace:
 | |
|                     foreach (DataLabel dl in e.OldItems)
 | |
|                     {
 | |
|                         dl.Parent = null;
 | |
|                         dl.PropertyChanged -= DataLabel_PropertyChanged;
 | |
|                     }
 | |
| 
 | |
|                     foreach (DataLabel dl in e.NewItems)
 | |
|                     {
 | |
|                         dl.Parent = this;
 | |
|                         dl.PropertyChanged += DataLabel_PropertyChanged;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case NotifyCollectionChangedAction.Remove:
 | |
|                 case NotifyCollectionChangedAction.Reset:
 | |
|                     if (e.OldItems != null)
 | |
|                     {
 | |
|                         foreach (DataLabel dl in e.OldItems)
 | |
|                             dl.PropertyChanged -= DataLabel_PropertyChanged;
 | |
|                     }
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             InvalidateLayout();
 | |
|         }
 | |
| 
 | |
|         private void DataLabel_PropertyChanged(object sender, PropertyChangedEventArgs e)
 | |
|         {
 | |
|             InvalidateLayout();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region DataLabelVisualStyle
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the visual style for the data labels.
 | |
|         /// </summary>
 | |
|         [Category("Style")]
 | |
|         [Description("Indicates the visual style for the data labels.")]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | |
|         public DataLabelVisualStyle DataLabelVisualStyle
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_DataLabelVisualStyle == null)
 | |
|                 {
 | |
|                     _DataLabelVisualStyle = new DataLabelVisualStyle();
 | |
| 
 | |
|                     StyleVisualChangeHandler(null, _DataLabelVisualStyle);
 | |
|                 }
 | |
| 
 | |
|                 return (_DataLabelVisualStyle);
 | |
|             }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_DataLabelVisualStyle != value)
 | |
|                 {
 | |
|                     DataLabelVisualStyle oldValue = _DataLabelVisualStyle;
 | |
| 
 | |
|                     _DataLabelVisualStyle = value;
 | |
| 
 | |
|                     OnStyleChanged("DataLabelVisualStyle", oldValue, value);
 | |
| 
 | |
|                     if (oldValue != null)
 | |
|                         oldValue.Dispose();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region DataPropertyNameSeries
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the name of the data field to which the Series Name is bound.
 | |
|         ///</summary>
 | |
|         [DefaultValue(null), Category("Data")]
 | |
|         [Description("Indicates the name of the data field to which the Series Name is bound.")]
 | |
|         public string DataPropertyNameSeries
 | |
|         {
 | |
|             get { return (_DataPropertyNameSeries); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _DataPropertyNameSeries)
 | |
|                 {
 | |
|                     _DataPropertyNameSeries = value;
 | |
| 
 | |
|                     if (NeedToUpdateBindings == false)
 | |
|                     {
 | |
|                         NeedToUpdateBindings = true;
 | |
| 
 | |
|                         InvalidateLayout();
 | |
|                     }
 | |
| 
 | |
|                     OnPropertyChangedEx("DataPropertyNameSeries", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region DataPropertyNameX
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the name of the data field to which the X-Axis data is bound.
 | |
|         ///</summary>
 | |
|         [DefaultValue(null), Category("Data")]
 | |
|         [Description("Indicates the name of the data field to which the X-Axis data is bound.")]
 | |
|         public string DataPropertyNameX
 | |
|         {
 | |
|             get { return (_DataPropertyNameX); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _DataPropertyNameX)
 | |
|                 {
 | |
|                     _DataPropertyNameX = value;
 | |
| 
 | |
|                     if (NeedToUpdateBindings == false)
 | |
|                     {
 | |
|                         NeedToUpdateBindings = true;
 | |
| 
 | |
|                         InvalidateLayout();
 | |
|                     }
 | |
| 
 | |
|                     OnPropertyChangedEx("DataPropertyNameX", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region DataPropertyNamesY
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the names of the data fields to which the Y-Axis data is bound.
 | |
|         ///</summary>
 | |
|         [DefaultValue(null), Category("Data")]
 | |
|         [Description("Indicates the names of the data fields to which the Y-Axis data is bound.")]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | |
|         public CustomCollection<string> DataPropertyNamesY
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_DataPropertyNamesY == null)
 | |
|                 {
 | |
|                     _DataPropertyNamesY = new CustomCollection<string>();
 | |
| 
 | |
|                     _DataPropertyNamesY.CollectionChanged += DataPropertyNamesY_CollectionChanged;
 | |
|                 }
 | |
| 
 | |
|                 return (_DataPropertyNamesY);
 | |
|             }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _DataPropertyNamesY)
 | |
|                 {
 | |
|                     if (_DataPropertyNamesY != null)
 | |
|                     {
 | |
|                         _DataPropertyNamesY.Clear();
 | |
| 
 | |
|                         _DataPropertyNamesY.CollectionChanged -= DataPropertyNamesY_CollectionChanged;
 | |
|                     }
 | |
| 
 | |
|                     _DataPropertyNamesY = value;
 | |
| 
 | |
|                     if (_DataPropertyNamesY != null)
 | |
|                         _DataPropertyNamesY.CollectionChanged += DataPropertyNamesY_CollectionChanged;
 | |
| 
 | |
|                     OnPropertyChangedEx("DataPropertyNamesY", Style.VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         void DataPropertyNamesY_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
 | |
|         {
 | |
|             if (NeedToUpdateBindings == false)
 | |
|             {
 | |
|                 NeedToUpdateBindings = true;
 | |
| 
 | |
|                 InvalidateLayout();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region DataMember
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the name of the list or table
 | |
|         /// in the data source that the Series is bound to.
 | |
|         ///</summary>
 | |
|         [DefaultValue(null), Category("Data")]
 | |
|         [Description("Indicates the name of the list or table in the data source that the Series is bound to.")]
 | |
|         public string DataMember
 | |
|         {
 | |
|             get { return (_DataMember); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_DataBinder != null)
 | |
|                     _DataBinder.Clear();
 | |
| 
 | |
|                 _DataMember = value;
 | |
| 
 | |
|                 NeedToUpdateBindings = true;
 | |
| 
 | |
|                 OnPropertyChangedEx("DataMember", VisualChangeType.Layout);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region DataSource
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the data source that the Series is bound to.
 | |
|         ///</summary>
 | |
|         [DefaultValue(null), AttributeProvider(typeof(IListSource)), Category("Data")]
 | |
|         [Description("Indicates the data source that the Series is bound to.")]
 | |
|         public object DataSource
 | |
|         {
 | |
|             get { return (_DataSource); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_DataBinder != null)
 | |
|                     _DataBinder.Clear();
 | |
| 
 | |
|                 _DataSource = value;
 | |
| 
 | |
|                 NeedToUpdateBindings = true;
 | |
| 
 | |
|                 OnPropertyChangedEx("DataSource", VisualChangeType.Layout);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region DefaultPaletteColor
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the default palette color assigned to the series when it
 | |
|         /// is added to the chart.
 | |
|         /// </summary>
 | |
|         [Browsable(false)]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | |
|         [Description("Indicates the default palette color assigned to the series when it is added to the chart.")]
 | |
|         public Color DefaultPaletteColor
 | |
|         {
 | |
|             get { return (_DefaultPaletteColor); }
 | |
| 
 | |
|             internal set
 | |
|             {
 | |
|                 if (value != _DefaultPaletteColor)
 | |
|                 {
 | |
|                     _DefaultPaletteColor = value;
 | |
| 
 | |
|                     InvalidateStyle();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region DisplayLinePointsOnTop
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether series points are displayed on top of series line.
 | |
|         /// </summary>
 | |
|         [DefaultValue(true), Category("Appearance")]
 | |
|         [Description("Indicates whether series points are displayed on top of series line.")]
 | |
|         public bool DisplayLinePointsOnTop
 | |
|         {
 | |
|             get { return (TestState(States.DisplayLinePointsOnTop)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != DisplayLinePointsOnTop)
 | |
|                 {
 | |
|                     SetState(States.DisplayLinePointsOnTop, value);
 | |
| 
 | |
|                     OnPropertyChangedEx("DisplayLinePointsOnTop", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region DotPlotIndexValue
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the value used to index between DotPlot points. Default is 1.
 | |
|         /// </summary>
 | |
|         [DefaultValue(1.0d), Category("Display")]
 | |
|         [Description("Indicates the value used to index between DotPlot points. Default is 1.")]
 | |
|         public double DotPlotIndexValue
 | |
|         {
 | |
|             get { return (_DotPlotIndexValue); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _DotPlotIndexValue)
 | |
|                 {
 | |
|                     if (value < 0)
 | |
|                         throw new ArgumentException("Value must be > 0");
 | |
| 
 | |
|                     _DotPlotIndexValue = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("DotPlotIndexValue", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region EffectiveDataLabelStyle
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets a reference to the DataLabel effective (cached, composite) style.
 | |
|         /// </summary>
 | |
|         [Browsable(false)]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | |
|         public DataLabelVisualStyle EffectiveDataLabelStyle
 | |
|         {
 | |
|             get { return (_EffectiveDataLabelStyle.Style); }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region EffectiveSeriesStyle
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets a reference to the Series's effective (cached, composite) style.
 | |
|         /// </summary>
 | |
|         [Browsable(false)]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | |
|         [Description("Indicates a reference to the Series's Effective (cached, composite) style.")]
 | |
|         public ChartSeriesVisualStyle EffectiveChartSeriesStyle
 | |
|         {
 | |
|             get { return (_EffectiveChartSeriesStyle.Style); }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region EmptyValues
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the value(s) used to determine if
 | |
|         /// a series point is empty or missing.
 | |
|         ///</summary>
 | |
|         [Category("Empty")]
 | |
|         [Description("Indicates the value(s) used to determine if a series point is empty or missing.")]
 | |
|         [Editor("DevComponents.Charts.Design.SeriesPointValueEditor, DevComponents.Charts.Design, " +
 | |
|                 "Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
 | |
|         public object[] EmptyValues
 | |
|         {
 | |
|             get { return (_EmptyValues); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _EmptyValues)
 | |
|                 {
 | |
|                     _EmptyValues = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("EmptyValue", Style.VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region EnableEmptyValues
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether EmptyValues are processed in the series
 | |
|         /// </summary>
 | |
|         [DefaultValue(false), Category("Empty")]
 | |
|         [Description("Indicates whether EmptyValues are processed in the series.")]
 | |
|         public bool EnableEmptyValues
 | |
|         {
 | |
|             get { return (TestState(States.EnableEmptyValues)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != EnableEmptyValues)
 | |
|                 {
 | |
|                     SetState(States.EnableEmptyValues, value);
 | |
| 
 | |
|                     _PointData = null;
 | |
|                     _EmptyPointData = null;
 | |
|                     _StepPointData = null;
 | |
| 
 | |
|                     OnPropertyChangedEx("EnableEmptyValues", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GroupId
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the logical grouping Id used to group qualitative series.
 | |
|         ///</summary>
 | |
|         [Browsable(false)]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | |
|         public int GroupId
 | |
|         {
 | |
|             get { return (_GroupId); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _GroupId)
 | |
|                 {
 | |
|                     _GroupId = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("GroupId", Style.VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region HiLoBarType
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the Series HiLoBar Type.
 | |
|         ///</summary>
 | |
|         [DefaultValue(HiLoBarType.Box), Category("Appearance")]
 | |
|         [Description("Indicates the Series HiLoBar Type.")]
 | |
|         public HiLoBarType HiLoBarType
 | |
|         {
 | |
|             get { return (_HiLoBarType); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _HiLoBarType)
 | |
|                 {
 | |
|                     _HiLoBarType = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("HiLoBarType", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IsDisplayed
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets whether the series is displayed (based upon Visibility and Legend state).
 | |
|         ///</summary>
 | |
|         [Browsable(false)]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | |
|         public bool IsDisplayed
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 ChartXy chartXy = Parent as ChartXy;
 | |
| 
 | |
|                 ItemCheckAction ica = (chartXy != null)
 | |
|                     ? chartXy.Legend.ItemCheckAction : ItemCheckAction.ShowItem;
 | |
| 
 | |
|                 return ((Visible == true) &&
 | |
|                         (ica == ItemCheckAction.None ||
 | |
|                         (ShowCheckBoxInLegend == false || CheckedInLegend == true)));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region MaxValueX
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets the series Maximum X value.
 | |
|         ///</summary>
 | |
|         [Browsable(false)]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | |
|         public object MaxValueX
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 UpdateSeriesRange();
 | |
| 
 | |
|                 if (IsRotated == true)
 | |
|                     return (_MaxValueY);
 | |
| 
 | |
|                 return (_MaxValueX);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region MaxValueY
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets the series Maximum Y value.
 | |
|         ///</summary>
 | |
|         [Browsable(false)]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | |
|         public object MaxValueY
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 UpdateSeriesRange();
 | |
| 
 | |
|                 if (IsRotated == true)
 | |
|                     return (_MaxValueX);
 | |
| 
 | |
|                 return (_MaxValueY);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region MinValueX
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets the series minimum X value.
 | |
|         ///</summary>
 | |
|         [Browsable(false)]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | |
|         public object MinValueX
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 UpdateSeriesRange();
 | |
| 
 | |
|                 if (IsRotated == true)
 | |
|                     return (_MinValueY);
 | |
| 
 | |
|                 return (_MinValueX);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region MinValueY
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets the series minimum Y value.
 | |
|         ///</summary>
 | |
|         [Browsable(false)]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | |
|         public object MinValueY
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 UpdateSeriesRange();
 | |
| 
 | |
|                 if (IsRotated == true)
 | |
|                     return (_MinValueX);
 | |
| 
 | |
|                 return (_MinValueY);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PointLabelDisplayMode
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the display mode for the chart PointLabels.
 | |
|         /// </summary>
 | |
|         [DefaultValue(PointLabelDisplayMode.NotSet), Category("DataLabel")]
 | |
|         [Description("Indicates the display mode for the chart PointLabels.")]
 | |
|         [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " +
 | |
|                 "Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
 | |
|         public PointLabelDisplayMode PointLabelDisplayMode
 | |
|         {
 | |
|             get { return (_PointLabelDisplayMode); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _PointLabelDisplayMode)
 | |
|                 {
 | |
|                     _PointLabelDisplayMode = value;
 | |
| 
 | |
|                     InvalidatePointLabels();
 | |
| 
 | |
|                     OnPropertyChangedEx("PointLabelDisplayMode", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PointLabelMinDistance
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the minimum distance between label data points.
 | |
|         ///</summary>
 | |
|         [DefaultValue(0), Category("DataLabel")]
 | |
|         [Description("Indicates the minimum distance between label data points.")]
 | |
|         public int PointLabelMinDistance
 | |
|         {
 | |
|             get { return (_PointLabelMinDistance); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _PointLabelMinDistance)
 | |
|                 {
 | |
|                     if (value < 0)
 | |
|                         throw new Exception("Minimum Distance must be >= 0");
 | |
| 
 | |
|                     _PointLabelMinDistance = value;
 | |
| 
 | |
|                     InvalidatePointLabels();
 | |
| 
 | |
|                     OnPropertyChangedEx("PointLabelMinDistance", Style.VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PointLabelSkip
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the number of inter-label points to skip.
 | |
|         ///</summary>
 | |
|         [DefaultValue(0), Category("DataLabel")]
 | |
|         [Description("Indicates the number of inter-label points to skip.")]
 | |
|         public int PointLabelSkip
 | |
|         {
 | |
|             get { return (_PointLabelSkip); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _PointLabelSkip)
 | |
|                 {
 | |
|                     if (value < 0)
 | |
|                         throw new Exception("Skip value must be >= 0");
 | |
| 
 | |
|                     _PointLabelSkip = value;
 | |
| 
 | |
|                     InvalidatePointLabels();
 | |
| 
 | |
|                     OnPropertyChangedEx("PointLabelSkip", Style.VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ScaleTypeX
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the X axis Scale Type.
 | |
|         ///</summary>
 | |
|         [DefaultValue(ScaleType.NotSet), Category("Axis")]
 | |
|         [Description("Indicates the X axis Scale Type.")]
 | |
|         public ScaleType ScaleTypeX
 | |
|         {
 | |
|             get { return (_ScaleTypeX); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _ScaleTypeX)
 | |
|                 {
 | |
|                     if (ValidScaleTypeX(value) == false)
 | |
|                         throw new Exception("Incompatible ScaleTypeX for defined series data.");
 | |
| 
 | |
|                     _ScaleTypeX = value;
 | |
| 
 | |
|                     InvalidatePoints();
 | |
| 
 | |
|                     OnPropertyChangedEx("ScaleTypeX", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region ValidScaleTypeX
 | |
| 
 | |
|         private bool ValidScaleTypeX(ScaleType scaleType)
 | |
|         {
 | |
|             if (scaleType == ScaleType.NotSet || scaleType == ScaleType.Auto)
 | |
|                 return (true);
 | |
| 
 | |
|             if (SeriesPoints.Count > 0)
 | |
|             {
 | |
|                 for (int i = 0; i < SeriesPoints.Count; i++)
 | |
|                 {
 | |
|                     SeriesPoint sp = SeriesPoints[i];
 | |
| 
 | |
|                     if (sp.ValueX != null)
 | |
|                     {
 | |
|                         Type dataType = sp.ValueX.GetType();
 | |
|                         ScaleType autoType = SeriesPoint.GetScaleType(dataType);
 | |
| 
 | |
|                         if (scaleType == autoType)
 | |
|                             return (true);
 | |
| 
 | |
|                         if (scaleType == ScaleType.Qualitative)
 | |
|                             return (true);
 | |
| 
 | |
|                         return (false);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (true);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ScaleTypeY
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the Y axis Scale Type.
 | |
|         ///</summary>
 | |
|         [DefaultValue(ScaleType.NotSet), Category("Axis")]
 | |
|         [Description("Indicates the Y axis Scale Type.")]
 | |
|         public ScaleType ScaleTypeY
 | |
|         {
 | |
|             get { return (_ScaleTypeY); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _ScaleTypeY)
 | |
|                 {
 | |
|                     if (ValidScaleTypeY(value) == false)
 | |
|                         throw new Exception("Incompatible ScaleTypeY for defined series data.");
 | |
| 
 | |
|                     _ScaleTypeY = value;
 | |
| 
 | |
|                     InvalidatePoints();
 | |
| 
 | |
|                     OnPropertyChangedEx("ScaleTypeY", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region ValidScaleTypeY
 | |
| 
 | |
|         private bool ValidScaleTypeY(ScaleType scaleType)
 | |
|         {
 | |
|             if (scaleType == ScaleType.NotSet || scaleType == ScaleType.Auto)
 | |
|                 return (true);
 | |
| 
 | |
|             if (SeriesPoints.Count > 0)
 | |
|             {
 | |
|                 for (int i = 0; i < SeriesPoints.Count; i++)
 | |
|                 {
 | |
|                     SeriesPoint sp = SeriesPoints[i];
 | |
| 
 | |
|                     if (sp.ValueY != null && sp.ValueY.Length > 0)
 | |
|                     {
 | |
|                         Type dataType = sp.ValueY[0].GetType();
 | |
|                         ScaleType autoType = SeriesPoint.GetScaleType(dataType);
 | |
| 
 | |
|                         if (scaleType == autoType)
 | |
|                             return (true);
 | |
| 
 | |
|                         if (scaleType == ScaleType.Qualitative)
 | |
|                             return (true);
 | |
| 
 | |
|                         return (false);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (true);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region SeriesPoints
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets the series point data collection
 | |
|         ///</summary>
 | |
|         [Category("Data")]
 | |
|         [Description("Indicates the series point data collection.")]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | |
|         public SeriesPointCollection SeriesPoints
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_SeriesPoints == null)
 | |
|                 {
 | |
|                     _SeriesPoints = new SeriesPointCollection();
 | |
| 
 | |
|                     _SeriesPoints.CollectionChanged += SeriesPoints_CollectionChanged;
 | |
|                 }
 | |
| 
 | |
|                 return (_SeriesPoints);
 | |
|             }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _SeriesPoints)
 | |
|                 {
 | |
|                     if (_SeriesPoints != null)
 | |
|                         _SeriesPoints.CollectionChanged -= SeriesPoints_CollectionChanged;
 | |
| 
 | |
|                     _SeriesPoints = value;
 | |
| 
 | |
|                     if (_SeriesPoints != null)
 | |
|                         _SeriesPoints.CollectionChanged += SeriesPoints_CollectionChanged;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region SeriesPoints_CollectionChanged
 | |
| 
 | |
|         void SeriesPoints_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
 | |
|         {
 | |
|             SeriesRangeChanged = true;
 | |
| 
 | |
|             InvalidateLayout();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region SeriesType
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the Series Type.
 | |
|         ///</summary>
 | |
|         [DefaultValue(SeriesType.Point), Category("Appearance")]
 | |
|         [Description("Indicates the Series Type.")]
 | |
|         public SeriesType SeriesType
 | |
|         {
 | |
|             get { return (_SeriesType); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _SeriesType)
 | |
|                 {
 | |
|                     _SeriesType = value;
 | |
| 
 | |
|                     IsRotated = (
 | |
|                         SeriesType == SeriesType.HorizontalDot ||
 | |
|                         SeriesType == SeriesType.HorizontalBar ||
 | |
|                         SeriesType == SeriesType.HorizontalHiLoBar);
 | |
| 
 | |
|                     BaseChart chart = Parent as BaseChart;
 | |
| 
 | |
|                     if (chart != null)
 | |
|                     {
 | |
|                         SeriesRangeChanged = true;
 | |
|                         chart.SeriesRangeChanged = true;
 | |
|                     }
 | |
| 
 | |
|                     OnPropertyChangedEx("SeriesType", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ShowHiLoBarMedianLines
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether defined HiLoBar Median lines are shown.
 | |
|         /// </summary>
 | |
|         [DefaultValue(false), Category("Empty")]
 | |
|         [Description("Indicates whether defined HiLoBar Median lines are shown.")]
 | |
|         public bool ShowHiLoBarMedianLines
 | |
|         {
 | |
|             get { return (TestState(States.ShowHiLoBarMedianLines)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != ShowHiLoBarMedianLines)
 | |
|                 {
 | |
|                     SetState(States.ShowHiLoBarMedianLines, value);
 | |
| 
 | |
|                     OnPropertyChangedEx("ShowHiLoBarMedianLines", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ShowEmptyLines
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether EmptyLines are shown in the series.
 | |
|         /// </summary>
 | |
|         [DefaultValue(false), Category("Empty")]
 | |
|         [Description("Indicates whether EmptyLines are shown in the series.")]
 | |
|         public bool ShowEmptyLines
 | |
|         {
 | |
|             get { return (TestState(States.ShowEmptyLines)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != ShowEmptyLines)
 | |
|                 {
 | |
|                     SetState(States.ShowEmptyLines, value);
 | |
| 
 | |
|                     InvalidatePoints();
 | |
| 
 | |
|                     OnPropertyChangedEx("ShowEmptyLines", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ShowEmptyPoints
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether EmptyPoints are shown in the series.
 | |
|         /// </summary>
 | |
|         [DefaultValue(false), Category("Empty")]
 | |
|         [Description("Indicates whether EmptyPoints are shown in the series.")]
 | |
|         public bool ShowEmptyPoints
 | |
|         {
 | |
|             get { return (TestState(States.ShowEmptyPoints)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != ShowEmptyPoints)
 | |
|                 {
 | |
|                     SetState(States.ShowEmptyPoints, value);
 | |
| 
 | |
|                     InvalidatePoints();
 | |
| 
 | |
|                     OnPropertyChangedEx("ShowEmptyPoints", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ShowOriginValueLabels
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether labels are shown for 'Origin' data values.
 | |
|         /// </summary>
 | |
|         [DefaultValue(true), Category("Appearance")]
 | |
|         [Description("Indicates whether labels are shown for 'Origin' data values.")]
 | |
|         public bool ShowOriginValueLabels
 | |
|         {
 | |
|             get { return (TestState(States.ShowOriginValueLabels)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != ShowOriginValueLabels)
 | |
|                 {
 | |
|                     SetState(States.ShowOriginValueLabels, value);
 | |
| 
 | |
|                     OnPropertyChangedEx("ShowOriginValueLabels", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region StackQualitativePoints
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether Qualitative points are
 | |
|         /// stacked or spread across the associated grouped column.
 | |
|         /// </summary>
 | |
|         [DefaultValue(true), Category("Appearance")]
 | |
|         [Description("Indicates whether Qualitative points are stacked or spread across the associated grouped column.")]
 | |
|         public bool StackQualitativePoints
 | |
|         {
 | |
|             get { return (TestState(States.StackQualitativePoints)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != StackQualitativePoints)
 | |
|                 {
 | |
|                     SetState(States.StackQualitativePoints, value);
 | |
| 
 | |
|                     OnPropertyChangedEx("StackQualitativePoints", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region StepLines
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets which 'Step lines' are displayed.
 | |
|         /// </summary>
 | |
|         [DefaultValue(StepLines.NotSet), Category("Display")]
 | |
|         [Description("Indicates which 'Step lines' are displayed.")]
 | |
|         public StepLines StepLines
 | |
|         {
 | |
|             get { return (_StepLines); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _StepLines)
 | |
|                 {
 | |
|                     _StepLines = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("StepLines", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region StepLineMode
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the mode used to render "Step Lines" in
 | |
|         /// the defined Line series.
 | |
|         /// </summary>
 | |
|         [DefaultValue(StepLineMode.NotSet), Category("Display")]
 | |
|         [Description("Indicates the mode used to render 'Step Lines' in the defined Line series.")]
 | |
|         public StepLineMode StepLineMode
 | |
|         {
 | |
|             get { return (_StepLineMode); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _StepLineMode)
 | |
|                 {
 | |
|                     _StepLineMode = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("StepLineMode", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Internal properties
 | |
| 
 | |
|         #region BarOffset
 | |
| 
 | |
|         internal int BarOffset
 | |
|         {
 | |
|             get { return (_BarOffset); }
 | |
|             set { _BarOffset = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region BarShadingColors
 | |
| 
 | |
|         internal Color[] BarShadingColors
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_BarShadingColors == null)
 | |
|                 {
 | |
|                     // Top, Bottom, Left, Right
 | |
| 
 | |
|                     _BarShadingColors = new Color[] {
 | |
|                         Color.FromArgb(200, Color.White),
 | |
|                         Color.FromArgb(100, Color.Black),
 | |
|                         Color.FromArgb(100, Color.Black),
 | |
|                         Color.FromArgb(100, Color.Black)};
 | |
|                 }
 | |
| 
 | |
|                 return (_BarShadingColors);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region BarWidth
 | |
| 
 | |
|         internal int BarWidth
 | |
|         {
 | |
|             get { return (_BarWidth); }
 | |
|             set { _BarWidth = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region DataBinder
 | |
| 
 | |
|         internal DataBinder DataBinder
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_DataBinder == null)
 | |
|                     _DataBinder = new DataBinder(this);
 | |
| 
 | |
|                 return (_DataBinder);
 | |
|             }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_DataBinder != null)
 | |
|                     _DataBinder.Clear();
 | |
| 
 | |
|                 _DataBinder = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IsQualitativeXValues
 | |
| 
 | |
|         internal bool IsQualitativeXValues
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 UpdateSeriesRange();
 | |
| 
 | |
|                 return (QualitativeXValues.Count > 0);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IsQualitativeYValues
 | |
| 
 | |
|         internal bool IsQualitativeYValues
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 UpdateSeriesRange();
 | |
| 
 | |
|                 return (QualitativeYValues.Count > 0); 
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IsBarSeries
 | |
| 
 | |
|         internal bool IsBarSeries
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return (_SeriesType == SeriesType.HorizontalBar ||
 | |
|                         _SeriesType == SeriesType.VerticalBar ||
 | |
|                         _SeriesType == SeriesType.HorizontalHiLoBar ||
 | |
|                         _SeriesType == SeriesType.VerticalHiLoBar);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IsRotated
 | |
| 
 | |
|         internal bool IsRotated
 | |
|         {
 | |
|             get { return (TestState(States.IsRotated)); }
 | |
|             set { SetState(States.IsRotated, value); }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IsSorted
 | |
| 
 | |
|         internal bool IsSorted
 | |
|         {
 | |
|             get { return (TestState(States.IsSorted)); }
 | |
|             set { SetState(States.IsSorted, value); }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region NeedToUpdateBindings
 | |
| 
 | |
|         internal bool NeedToUpdateBindings
 | |
|         {
 | |
|             get { return (TestState(States.NeedToUpdateBindings)); }
 | |
|             set { SetState(States.NeedToUpdateBindings, value); }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PlotData
 | |
| 
 | |
|         internal object PlotData
 | |
|         {
 | |
|             get { return (_PlotData); }
 | |
|             set { _PlotData = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PointMarkerEmptyImage
 | |
| 
 | |
|         internal Image PointMarkerEmptyImage
 | |
|         {
 | |
|             get { return (_PointMarkerEmptyImage); }
 | |
|             set { _PointMarkerEmptyImage = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PointMarkerImage
 | |
| 
 | |
|         internal Image PointMarkerImage
 | |
|         {
 | |
|             get { return (_PointMarkerImage); }
 | |
|             set { _PointMarkerImage = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PointMarkerHighlightImage
 | |
| 
 | |
|         internal Image PointMarkerHighlightImage
 | |
|         {
 | |
|             get { return (_PointMarkerHighlightImage); }
 | |
|             set { _PointMarkerHighlightImage = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PointOffset
 | |
| 
 | |
|         internal Point PointOffset
 | |
|         {
 | |
|             get { return (_PointOffset); }
 | |
|             set { _PointOffset = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region QualitativeXValues
 | |
| 
 | |
|         internal List<object> QualitativeXValues
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_QualitativeXValues == null)
 | |
|                     _QualitativeXValues = new List<object>();
 | |
| 
 | |
|                 return (_QualitativeXValues);
 | |
|             }
 | |
| 
 | |
|             set { _QualitativeXValues = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region QualitativeYValues
 | |
| 
 | |
|         internal List<object> QualitativeYValues
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_QualitativeYValues == null)
 | |
|                     _QualitativeYValues = new List<object>();
 | |
| 
 | |
|                 return (_QualitativeYValues);
 | |
|             }
 | |
| 
 | |
|             set { _QualitativeYValues = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region SeriesId
 | |
| 
 | |
|         internal int SeriesId
 | |
|         {
 | |
|             get { return (_SeriesId); }
 | |
|             set { _SeriesId = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region SeriesKey
 | |
| 
 | |
|         internal object SeriesKey
 | |
|         {
 | |
|             get { return (_SeriesKey); }
 | |
|             set { _SeriesKey = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region SeriesRangeChanged
 | |
| 
 | |
|         internal bool SeriesRangeChanged
 | |
|         {
 | |
|             get { return (_SeriesRangeChanged); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _SeriesRangeChanged)
 | |
|                 {
 | |
|                     _SeriesRangeChanged = value;
 | |
| 
 | |
|                     if (value == true)
 | |
|                     {
 | |
|                         BaseChart chart = Parent as BaseChart;
 | |
| 
 | |
|                         if (chart != null)
 | |
|                             chart.SeriesRangeChanged = true;
 | |
| 
 | |
|                         _SortedSeriesPoints = null;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region MeasureOverride
 | |
| 
 | |
|         protected override void MeasureOverride(ChartLayoutInfo layoutInfo)
 | |
|         {
 | |
|             UpdateDataBindings();
 | |
|             UpdateMarkerImage(layoutInfo.Graphics);
 | |
|         }
 | |
| 
 | |
|         #region UpdateDataBindings
 | |
| 
 | |
|         internal void UpdateDataBindings()
 | |
|         {
 | |
|             if (NeedToUpdateBindings == true)
 | |
|             {
 | |
|                 BaseChart chart = Parent as BaseChart;
 | |
| 
 | |
|                 object dataSource = DataSource ?? chart.DataSource;
 | |
|                 string dataMember = (string.IsNullOrEmpty(DataMember) == false) ? DataMember : chart.DataMember;
 | |
| 
 | |
|                 if (dataSource != null)
 | |
|                 {
 | |
|                     SeriesPoints.Clear();
 | |
| 
 | |
|                     DataBinder dataBinder = DataBinder;
 | |
| 
 | |
|                     dataBinder.Clear();
 | |
| 
 | |
|                     dataBinder.DataConnect(dataSource, dataMember);
 | |
|                     dataBinder.LoadSeriesData(this);
 | |
|                 }
 | |
| 
 | |
|                 NeedToUpdateBindings = false;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region UpdateMarkerImage
 | |
| 
 | |
|         private void UpdateMarkerImage(Graphics g)
 | |
|         {
 | |
|             switch (SeriesType)
 | |
|             {
 | |
|                 case SeriesType.Bubble:
 | |
|                 case SeriesType.VerticalDot:
 | |
|                 case SeriesType.Line:
 | |
|                 case SeriesType.Point:
 | |
|                 case SeriesType.HorizontalDot:
 | |
|                     if (PointMarkerImage == null)
 | |
|                     {
 | |
|                         ChartXy chartXy = Parent as ChartXy;
 | |
|                         ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle;
 | |
| 
 | |
|                         PointMarkerImage = chartXy.GetPointMarker(g, sstyle.MarkerVisualStyle);
 | |
|                     }
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ArrangeOverride
 | |
| 
 | |
|         protected override void ArrangeOverride(ChartLayoutInfo layoutInfo)
 | |
|         {
 | |
|             BoundsRelative = layoutInfo.LayoutBounds;
 | |
| 
 | |
|             if (SeriesType == SeriesType.Bubble)
 | |
|                 UpdateBubblePointOffset();
 | |
|         }
 | |
| 
 | |
|         #region UpdateBubblePointOffset
 | |
| 
 | |
|         private void UpdateBubblePointOffset()
 | |
|         {
 | |
|             BubblePlotData bdata = _PlotData as BubblePlotData;
 | |
| 
 | |
|             if (bdata != null)
 | |
|             {
 | |
|                 ChartXy chartXy = Parent as ChartXy;
 | |
| 
 | |
|                 Rectangle bounds = chartXy.ContentBoundsEx;
 | |
| 
 | |
|                 float minSize = Dpi.Width(BubbleMinSize);
 | |
|                 float maxSize = (float)(Math.Min(bounds.Width, bounds.Height) * BubbleMaxPercentage);
 | |
| 
 | |
|                 double minTotalSize;
 | |
|                 double maxTotalSize;
 | |
|                 chartXy.GetChartBubbleData(out minTotalSize, out maxTotalSize);
 | |
| 
 | |
|                 BubbleSizeMode smode = GetBubbleSizeMode(chartXy);
 | |
| 
 | |
|                 double range = maxSize - minSize;
 | |
| 
 | |
|                 double sizeRange = (smode == BubbleSizeMode.Diameter)
 | |
|                     ? maxTotalSize - minTotalSize : AMath.ToScalar((float)(maxTotalSize - minTotalSize));
 | |
| 
 | |
|                 SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy);
 | |
| 
 | |
|                 for (int i = 0; i < ssp.Count; i++)
 | |
|                 {
 | |
|                     SeriesPoint sp = ssp[i];
 | |
| 
 | |
|                     if (sp.Visible == true)
 | |
|                     {
 | |
|                         int size = GetBubbleSize(sp, smode, minSize, maxSize, range, sizeRange);
 | |
| 
 | |
|                         sp.PointSize = new Size(size, size);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetBubbleSize
 | |
| 
 | |
|         private int GetBubbleSize(SeriesPoint sp,
 | |
|             BubbleSizeMode smode, double minSize, double maxSize, double range, double sizeRange)
 | |
|         {
 | |
|             if (sp.ValueY == null || sp.ValueY.Length < 2 || sizeRange == 0)
 | |
|                 return (int)minSize;
 | |
| 
 | |
|             double size = Math.Abs(GetDoubleValue(sp.ValueY[1]));
 | |
| 
 | |
|             double value = (smode == BubbleSizeMode.Diameter)
 | |
|                 ? (size * range) / sizeRange
 | |
|                 : (AMath.ToScalar((float)size) * range) / sizeRange;
 | |
| 
 | |
|             if (BubbleScaleFactor > 0)
 | |
|                 value *= BubbleScaleFactor;
 | |
| 
 | |
|             value = Math.Max(minSize, value);
 | |
| 
 | |
|             return ((int)Math.Min(maxSize, value));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderOverride
 | |
| 
 | |
|         protected override void RenderOverride(ChartRenderInfo renderInfo)
 | |
|         {
 | |
|             Graphics g = renderInfo.Graphics;
 | |
| 
 | |
|             if (SeriesPoints.Count > 0)
 | |
|             {
 | |
|                 ChartXy chartXy = Parent as ChartXy;
 | |
|                 ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle;
 | |
| 
 | |
|                 SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy);
 | |
|                 ssp.SeriesLayoutCount = chartXy.SeriesLayoutCount;
 | |
| 
 | |
|                 UpdateMarkerImage(g);
 | |
| 
 | |
|                 int n = Dpi.Width1;
 | |
| 
 | |
|                 _RenderBounds = chartXy.ContentBounds;
 | |
|                 _RenderBounds.Location = chartXy.GetGlobalAdjustedPoint(_RenderBounds.Location);
 | |
| 
 | |
|                 if (_RenderBounds.Width > 0 && _RenderBounds.Height > 0)
 | |
|                 {
 | |
|                     switch (SeriesType)
 | |
|                     {
 | |
|                         case SeriesType.Bubble:
 | |
|                             RenderBubblePlot(g, chartXy, ssp, sstyle);
 | |
|                             break;
 | |
| 
 | |
|                         case SeriesType.HorizontalBar:
 | |
|                             RenderHBarPlot(g, chartXy, ssp, sstyle);
 | |
|                             break;
 | |
| 
 | |
|                         case SeriesType.HorizontalDot:
 | |
|                             RenderHDotPlot(g, chartXy, ssp, sstyle);
 | |
|                             break;
 | |
| 
 | |
|                         case SeriesType.HorizontalHiLoBar:
 | |
|                             RenderHStockPlot(renderInfo, chartXy, ssp, sstyle);
 | |
|                             break;
 | |
| 
 | |
|                         case SeriesType.Point:
 | |
|                             RenderPointPlot(g, chartXy, ssp, true, sstyle);
 | |
|                             break;
 | |
| 
 | |
|                         case SeriesType.Line:
 | |
|                             RenderLinePlot(g, chartXy, ssp, sstyle);
 | |
|                             break;
 | |
| 
 | |
|                         case SeriesType.VerticalBar:
 | |
|                             RenderVBarPlot(g, chartXy, ssp, sstyle);
 | |
|                             break;
 | |
| 
 | |
|                         case SeriesType.VerticalDot:
 | |
|                             RenderVDotPlot(g, chartXy, ssp, sstyle);
 | |
|                             break;
 | |
| 
 | |
|                         case SeriesType.VerticalHiLoBar:
 | |
|                             RenderVStockPlot(renderInfo, chartXy, ssp, sstyle);
 | |
|                             break;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetSortedSeriesPoints
 | |
| 
 | |
|         internal SortedSeriesPoints GetSortedSeriesPoints(ChartXy chartXy)
 | |
|         {
 | |
|             if (_SortedSeriesPoints == null)
 | |
|             {
 | |
|                 bool sort = (IsSorted == false && NeedSortedSeries(chartXy) == true);
 | |
| 
 | |
|                 _SortedSeriesPoints = new SortedSeriesPoints(this, sort);
 | |
| 
 | |
|                 if (SeriesType == SeriesType.VerticalDot || SeriesType == SeriesType.HorizontalDot)
 | |
|                     CombineDuplicates(_SortedSeriesPoints);
 | |
|             }
 | |
| 
 | |
|             return (_SortedSeriesPoints);
 | |
|         }
 | |
| 
 | |
|         #region CombineDuplicates
 | |
| 
 | |
|         private void CombineDuplicates(SortedSeriesPoints ssp)
 | |
|         {
 | |
|             SeriesPoint spLast = null;
 | |
| 
 | |
|             List<int> cList = new List<int>();
 | |
|             List<int> iList = new List<int>();
 | |
| 
 | |
|             int dcount = 0;
 | |
|             int spLastIndex = 0;
 | |
| 
 | |
|             for (int i = 0; i < ssp.Count; i++)
 | |
|             {
 | |
|                 SeriesPoint sp = ssp[i];
 | |
| 
 | |
|                 if (spLast != null && spLast.ValueX.Equals(sp.ValueX) == false)
 | |
|                 {
 | |
|                     iList.Add(spLastIndex);
 | |
|                     cList.Add(dcount);
 | |
| 
 | |
|                     dcount = 0;
 | |
| 
 | |
|                     spLast = sp;
 | |
|                     spLastIndex = (ssp.IndexArray != null ? ssp.IndexArray[i] : i);
 | |
|                 }
 | |
| 
 | |
|                 dcount += GetDotCount(sp);
 | |
| 
 | |
|                 if (spLast == null)
 | |
|                 {
 | |
|                     spLast = sp;
 | |
|                     spLastIndex = (ssp.IndexArray != null ? ssp.IndexArray[i] : i);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (dcount > 0)
 | |
|             {
 | |
|                 iList.Add(spLastIndex);
 | |
|                 cList.Add(dcount);
 | |
|             }
 | |
| 
 | |
|             int[] indexArray = new int[iList.Count];
 | |
|             int[] countArray = new int[iList.Count];
 | |
| 
 | |
|             for (int i = 0; i < iList.Count; i++)
 | |
|             {
 | |
|                 indexArray[i] = iList[i];
 | |
|                 countArray[i] = cList[i];
 | |
|             }
 | |
| 
 | |
|             ssp.IndexArray = indexArray;
 | |
|             ssp.CountArray = countArray;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region NeedSortedSeries
 | |
| 
 | |
|         private bool NeedSortedSeries(ChartXy chartXy)
 | |
|         {
 | |
|             if (IsSorted == true || _ActualScaleTypeX == ScaleType.Qualitative)
 | |
|                 return (false);
 | |
| 
 | |
|             if (SeriesType != SeriesType.Line)
 | |
|                 return (true);
 | |
| 
 | |
|             ChartLineDisplayMode mode = GetLineDisplayMode(chartXy);
 | |
| 
 | |
|             return ((mode & ChartLineDisplayMode.DisplayUnsorted) != ChartLineDisplayMode.DisplayUnsorted);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderBarPlot
 | |
| 
 | |
|         #region RenderHBarPlot
 | |
| 
 | |
|         private void RenderHBarPlot(Graphics g,
 | |
|             ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             g.RenderingOrigin = chartXy.GetLocalAdjustedPoint(Point.Empty);
 | |
| 
 | |
|             BarRenderData rd = new BarRenderData(chartXy, AxisX ?? chartXy.AxisX);
 | |
| 
 | |
|             rd.FillRange = GetBarFillRange(chartXy);
 | |
|             rd.BarShading = GetBarShading(chartXy);
 | |
|             
 | |
|             rd.SeriesStyle = sstyle;
 | |
| 
 | |
|             int index = 0;
 | |
|             bool isHistogram = false;
 | |
| 
 | |
|             if (chartXy.BarShowAsHistogram == Tbool.True)
 | |
|             {
 | |
|                 ChartAxis axisY = AxisY ?? chartXy.AxisY;
 | |
|                 AxisBar axisBar = axisY.AxisBars[(int)AxisBarType.Bar];
 | |
| 
 | |
|                 if (axisBar.BarCount == 1)
 | |
|                 {
 | |
|                     TickmarkLayout layout = axisY.TickmarkLayout;
 | |
| 
 | |
|                     for (int i = 0; i < layout.Ticks.Length; i++)
 | |
|                     {
 | |
|                         if (layout.Ticks[i].LabelIndex >= 0)
 | |
|                         {
 | |
|                             index = i;
 | |
|                             break;
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     isHistogram = true;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             for (int i = 0; i < ssp.Count; i++)
 | |
|             {
 | |
|                 SeriesPoint sp = ssp[i];
 | |
| 
 | |
|                 if (sp.Visible == true)
 | |
|                 {
 | |
|                     rd.Spt = sp.Point[0];
 | |
|                     rd.Sp = sp;
 | |
| 
 | |
|                     RenderHBar(g, rd, isHistogram, i + index);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderHBar
 | |
| 
 | |
|         private void RenderHBar(
 | |
|             Graphics g, BarRenderData rd, bool isHistogram, int index)
 | |
|         {
 | |
|             ChartXy chartXy = rd.ChartXy;
 | |
|             SeriesPoint sp = rd.Sp;
 | |
| 
 | |
|             sp.PointSize = new Size(5, BarWidth);
 | |
| 
 | |
|             Point ptt = chartXy.GetDataPointEx(this, sp, 0);
 | |
| 
 | |
|             int y = (int)(ptt.Y + BarOffset - BarWidth / 2);
 | |
|             int height = BarWidth;
 | |
| 
 | |
|             if (isHistogram == true)
 | |
|                 y = GetHistogramSizeY(chartXy, ptt, index, out height);
 | |
| 
 | |
|             int x1 = ptt.X;
 | |
|             int x2 = GetHBarStart(chartXy, sp);
 | |
|             int xOrigin = GetHBarOrigin(chartXy, rd.Axis, sp);
 | |
| 
 | |
|             if (x1 > x2)
 | |
|             {
 | |
|                 int xtemp = x1;
 | |
|                 x1 = x2;
 | |
|                 x2 = xtemp;
 | |
|             }
 | |
| 
 | |
|             if (x2 <= xOrigin)
 | |
|             {
 | |
|                 RenderLeftBar(g, rd, y, height, x1, x2, xOrigin);
 | |
|             }
 | |
|             else if (x1 >= xOrigin)
 | |
|             {
 | |
|                 RenderRightBar(g, rd, y, height, x1, x2, xOrigin);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 RenderLeftBar(g, rd, y, height, x1, xOrigin, xOrigin);
 | |
|                 RenderRightBar(g, rd, y, height, xOrigin, x2, xOrigin);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetHistogramSizeY
 | |
| 
 | |
|         private int GetHistogramSizeY(
 | |
|             ChartXy chartXy, Point spt, int index, out int height)
 | |
|         {
 | |
|             ChartAxis axis = AxisY ?? chartXy.AxisY;
 | |
|             TickmarkLayout layout = axis.TickmarkLayout;
 | |
| 
 | |
|             if (index < layout.Ticks.Length)
 | |
|                 height = layout.Ticks[index + 1].TickPoint.Y - spt.Y;
 | |
|             else
 | |
|                 height = (int)layout.MajorInterval;
 | |
| 
 | |
|             int y = spt.Y - (int)(layout.MajorInterval / 2);
 | |
| 
 | |
|             return (y);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetHBarStart
 | |
| 
 | |
|         internal int GetHBarStart(ChartXy chartXy, SeriesPoint sp)
 | |
|         {
 | |
|             ChartAxis axis = AxisX ?? chartXy.AxisX;
 | |
| 
 | |
|             object value = ((sp.ValueY.Length > 1)
 | |
|                 ? sp.ValueY[1] : chartXy.BarOrigin ?? null);
 | |
| 
 | |
|             if (value == null)
 | |
|             {
 | |
|                 if (axis.ScaleType == ScaleType.Quantitative)
 | |
|                     value = 0;
 | |
|                 else
 | |
|                     value = axis.ActualMinValue;
 | |
|             }
 | |
| 
 | |
|             return (chartXy.GetDataPointX(axis, value));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetHBarOrigin
 | |
| 
 | |
|         private int GetHBarOrigin(
 | |
|             ChartXy chartXy, ChartAxis axis, SeriesPoint sp)
 | |
|         {
 | |
|             object value = ((sp.ValueY != null && sp.ValueY.Length > 2)
 | |
|                 ? sp.ValueY[2] : (chartXy.BarOrigin ?? null));
 | |
| 
 | |
|             if (value == null)
 | |
|             {
 | |
|                 if (axis.ScaleType == ScaleType.Quantitative)
 | |
|                     value = 0;
 | |
|                 else
 | |
|                     value = axis.ActualMinValue;
 | |
|             }
 | |
| 
 | |
|             return (chartXy.GetDataPointX(axis, value));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderRightBar
 | |
| 
 | |
|         private void RenderRightBar(Graphics g,
 | |
|             BarRenderData rd, int y, int height, int x1, int x2, int xOrigin)
 | |
|         {
 | |
|             Rectangle r = new Rectangle(x1, y, x2 - x1, Math.Max(1, height - 1));
 | |
| 
 | |
|             if (r.IntersectsWith(_RenderBounds))
 | |
|             {
 | |
|                 Background bk = rd.SeriesStyle.BarVisualStyle.Background;
 | |
|                 ChartLineVisualStyle lstyle = rd.SeriesStyle.BarVisualStyle.Border;
 | |
| 
 | |
|                 // r is actual area, r2 is FillRange area
 | |
| 
 | |
|                 Rectangle r2 = r;
 | |
| 
 | |
|                 if (rd.FillRange == BarFillRange.BySeries)
 | |
|                 {
 | |
|                     r2.X = xOrigin;
 | |
|                     r2.Width = rd.ChartXy.GetDataPointX(rd.Axis, MaxValueX) - r2.X;
 | |
|                 }
 | |
| 
 | |
|                 BarSegment segment = (x1 > xOrigin) ? BarSegment.Right : BarSegment.RightPartial;
 | |
| 
 | |
|                 RenderFullHBar(g, rd, r, r2, bk, lstyle, segment);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderLeftBar
 | |
| 
 | |
|         private void RenderLeftBar(Graphics g,
 | |
|             BarRenderData rd, int y, int height, int x1, int x2, int xOrigin)
 | |
|         {
 | |
|             Rectangle r = new Rectangle(x1, y, x2 - x1, Math.Max(1, height - 1));
 | |
| 
 | |
|             if (r.IntersectsWith(_RenderBounds))
 | |
|             {
 | |
|                 ChartSeriesVisualStyle sstyle = rd.SeriesStyle;
 | |
| 
 | |
|                 Background bk = sstyle.BarVisualStyle.AlternateBackground;
 | |
| 
 | |
|                 if (bk.IsEmpty)
 | |
|                     bk = sstyle.BarVisualStyle.Background;
 | |
| 
 | |
|                 ChartLineVisualStyle lstyle = sstyle.BarVisualStyle.AlternateBorder;
 | |
| 
 | |
|                 if (lstyle.IsEmpty)
 | |
|                     lstyle = sstyle.BarVisualStyle.Border;
 | |
| 
 | |
|                 Rectangle r2 = r;
 | |
| 
 | |
|                 if (rd.FillRange == BarFillRange.BySeries)
 | |
|                 {
 | |
|                     int left = rd.ChartXy.GetDataPointX(rd.Axis, MinValueX);
 | |
| 
 | |
|                     r2.X = left;
 | |
|                     r2.Width = xOrigin - left;
 | |
|                 }
 | |
| 
 | |
|                 BarSegment segment = (x2 < xOrigin) ? BarSegment.Left : BarSegment.LeftPartial;
 | |
| 
 | |
|                 RenderFullHBar(g, rd, r, r2, bk, lstyle, segment);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderFullHBar
 | |
| 
 | |
|         private void RenderFullHBar(Graphics g, BarRenderData rd,
 | |
|             Rectangle r, Rectangle r2, Background bk, ChartLineVisualStyle lstyle, BarSegment segment)
 | |
|         {
 | |
|             if (r2.Width > 0 && r2.Height > 0)
 | |
|             {
 | |
|                 ChartXy chartXy = rd.ChartXy;
 | |
|                 ChartControl chartControl = ChartControl;
 | |
| 
 | |
|                 if (chartControl.DoPreRenderSeriesBarEvent(g, chartXy, this, rd.Sp, r, r2, segment) == false)
 | |
|                 {
 | |
|                     using (Brush br = bk.GetBrush(r2))
 | |
|                         g.FillRectangle(br, r);
 | |
| 
 | |
|                     int lw = 0;
 | |
| 
 | |
|                     if (lstyle.LinePattern != LinePattern.None)
 | |
|                     {
 | |
|                         SmoothingMode sm = g.SmoothingMode;
 | |
|                         g.SmoothingMode = SmoothingMode.None;
 | |
| 
 | |
|                         using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth)))
 | |
|                         {
 | |
|                             lw = (int)pen.Width;
 | |
| 
 | |
|                             if (lstyle.LinePattern != LinePattern.NotSet)
 | |
|                                 pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | |
| 
 | |
|                             g.DrawRectangle(pen, r);
 | |
|                         }
 | |
| 
 | |
|                         g.SmoothingMode = sm;
 | |
|                     }
 | |
| 
 | |
|                     if (rd.BarShading == true)
 | |
|                     {
 | |
|                         Rectangle t = r;
 | |
|                         t.Inflate(-lw/2, -lw/2);
 | |
| 
 | |
|                         t.Width++;
 | |
|                         t.Height++;
 | |
| 
 | |
|                         RenderHBarShading(g, t, r2, segment);
 | |
|                     }
 | |
| 
 | |
|                     chartControl.DoPostRenderSeriesBarEvent(g, chartXy, this, rd.Sp, r, r2, segment);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderHBarShading
 | |
| 
 | |
|         private void RenderHBarShading(
 | |
|             Graphics g, Rectangle r, Rectangle r2, BarSegment segment)
 | |
|         {
 | |
|             if (r.Width > 6)
 | |
|             {
 | |
|                 SmoothingMode sm = g.SmoothingMode;
 | |
|                 g.SmoothingMode = SmoothingMode.None;
 | |
| 
 | |
|                 int n = (int)(r.Height *.15);
 | |
| 
 | |
|                 Color[] colors = (Color[])BarShadingColors.Clone();
 | |
| 
 | |
|                 colors[2] = Color.FromArgb(Math.Max(0,colors[2].A - 30), colors[2]);
 | |
|                 colors[3] = Color.FromArgb(Math.Max(0, colors[3].A - 30), colors[3]);
 | |
| 
 | |
|                 Rectangle r3 = r;
 | |
| 
 | |
|                 r3.Inflate(1, 1);
 | |
| 
 | |
|                 using (LinearGradientBrush lbr = new LinearGradientBrush(r3, Color.Empty, Color.Empty, 90f))
 | |
|                 {
 | |
|                     lbr.WrapMode = WrapMode.Tile;
 | |
| 
 | |
|                     ColorBlend cb = new ColorBlend(4);
 | |
| 
 | |
|                     cb.Colors = new Color[] { colors[0], Color.Transparent, Color.Transparent, colors[1] };
 | |
|                     cb.Positions = new float[] { 0f, .25f, .75f, 1f };
 | |
| 
 | |
|                     lbr.InterpolationColors = cb;
 | |
| 
 | |
|                     r3.Inflate(-1, -1);
 | |
| 
 | |
|                     g.FillRectangle(lbr, r3);
 | |
|                 }
 | |
| 
 | |
|                 switch (segment)
 | |
|                 {
 | |
|                     case BarSegment.LeftPartial:
 | |
|                         FillLeft(g, r, n, colors);
 | |
|                         break;
 | |
| 
 | |
|                     case BarSegment.RightPartial:
 | |
|                         FillRight(g, r, n, colors);
 | |
|                         break;
 | |
| 
 | |
|                     default:
 | |
|                         FillLeft(g, r, n, colors);
 | |
|                         FillRight(g, r, n, colors);
 | |
|                         break;
 | |
|                 }
 | |
| 
 | |
|                 g.SmoothingMode = sm;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region FillLeft
 | |
| 
 | |
|         private void FillLeft(Graphics g, Rectangle r, int n, Color[] colors)
 | |
|         {
 | |
|             r.Width = n - 1;
 | |
|             r.Inflate(1, 0);
 | |
| 
 | |
|             using (LinearGradientBrush lbr = new LinearGradientBrush(r, colors[2], Color.Transparent, 0f))
 | |
|             {
 | |
|                 lbr.WrapMode = WrapMode.TileFlipX;
 | |
| 
 | |
|                 r.X++;
 | |
| 
 | |
|                 g.FillRectangle(lbr, r);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region FillRight
 | |
| 
 | |
|         private void FillRight(Graphics g, Rectangle r, int n, Color[] colors)
 | |
|         {
 | |
|             r.X = r.Right - n;
 | |
|             r.Width = n;
 | |
|             r.Inflate(1, 0);
 | |
|             
 | |
|             using (LinearGradientBrush lbr = new LinearGradientBrush(r, colors[2], Color.Transparent, 180f))
 | |
|             {
 | |
|                 r.X++;
 | |
|                 r.Width--;
 | |
| 
 | |
|                 g.FillRectangle(lbr, r);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderVBarPlot
 | |
| 
 | |
|         private void RenderVBarPlot(Graphics g,
 | |
|             ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             PointData pd = GatherSeriesPoints(chartXy, ssp, 0, ssp.Count, false);
 | |
| 
 | |
|             if (pd.Points.Count > 0)
 | |
|             {
 | |
|                 g.RenderingOrigin = chartXy.GetLocalAdjustedPoint(Point.Empty);
 | |
| 
 | |
|                 BarRenderData rd = new BarRenderData(chartXy, AxisY ?? chartXy.AxisY);
 | |
| 
 | |
|                 rd.FillRange = GetBarFillRange(chartXy);
 | |
|                 rd.BarShading = GetBarShading(chartXy);
 | |
| 
 | |
|                 rd.SeriesStyle = sstyle;
 | |
| 
 | |
|                 int index = 0;
 | |
|                 bool isHistogram = false;
 | |
| 
 | |
|                 if (chartXy.BarShowAsHistogram == Tbool.True)
 | |
|                 {
 | |
|                     ChartAxis axisX = AxisX ?? chartXy.AxisX;
 | |
|                     AxisBar axisBar = axisX.AxisBars[(int)AxisBarType.Bar];
 | |
| 
 | |
|                     if (axisBar.BarCount == 1)
 | |
|                     {
 | |
|                         TickmarkLayout layout = axisX.TickmarkLayout;
 | |
| 
 | |
|                         for (int i = 0; i < layout.Ticks.Length; i++)
 | |
|                         {
 | |
|                             if (layout.Ticks[i].LabelIndex >= 0)
 | |
|                             {
 | |
|                                 index = i;
 | |
|                                 break;
 | |
|                             }
 | |
|                         }
 | |
| 
 | |
|                         isHistogram = true;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 for (int i = 0; i < pd.Points.Count; i++)
 | |
|                 {
 | |
|                     Point[] pts = pd.Points[i];
 | |
|                     SeriesPoint[] spts = pd.SeriesPoints[i];
 | |
| 
 | |
|                     for (int j = 0; j < pts.Length; j++)
 | |
|                     {
 | |
|                         rd.Spt = pts[j];
 | |
|                         rd.Sp = spts[j];
 | |
| 
 | |
|                         RenderVBar(g, rd, isHistogram, j + index);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderVBar
 | |
| 
 | |
|         private void RenderVBar(
 | |
|             Graphics g, BarRenderData rd, bool isHistogram, int index)
 | |
|         {
 | |
|             ChartXy chartXy = rd.ChartXy;
 | |
|             SeriesPoint sp = rd.Sp;
 | |
|             Point spt = rd.Spt;
 | |
| 
 | |
|             sp.PointSize = new Size(BarWidth, 5);
 | |
| 
 | |
|             int x = (int)(spt.X + BarOffset - BarWidth / 2);
 | |
|             int width = BarWidth;
 | |
| 
 | |
|             if (isHistogram == true)
 | |
|                 x = GetHistogramSizeX(chartXy, spt, index, out width);
 | |
| 
 | |
|             int y1 = spt.Y;
 | |
|             int y2 = GetVBarStart(chartXy, sp);
 | |
|             int yOrigin = GetVBarOrigin(chartXy, rd.Axis, sp);
 | |
| 
 | |
|             if (y1 > y2)
 | |
|             {
 | |
|                 int ytemp = y1;
 | |
|                 y1 = y2;
 | |
|                 y2 = ytemp;
 | |
|             }
 | |
| 
 | |
|             if (y2 <= yOrigin)
 | |
|             {
 | |
|                 RenderAscendingBar(g, rd, x, width, y1, y2, yOrigin);
 | |
|             }
 | |
|             else if (y1 >= yOrigin)
 | |
|             {
 | |
|                 RenderDescendingBar(g, rd, x, width, y1, y2, yOrigin);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 RenderAscendingBar(g, rd, x, width, y1, yOrigin, yOrigin);
 | |
|                 RenderDescendingBar(g, rd, x, width, yOrigin, y2, yOrigin);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetHistogramSizeX
 | |
| 
 | |
|         private int GetHistogramSizeX(
 | |
|             ChartXy chartXy, Point spt, int index, out int width)
 | |
|         {
 | |
|             ChartAxis axis = AxisX ?? chartXy.AxisX;
 | |
|             TickmarkLayout layout = axis.TickmarkLayout;
 | |
| 
 | |
|             if (index < layout.Ticks.Length)
 | |
|                 width = layout.Ticks[index + 1].TickPoint.X - spt.X;
 | |
|             else
 | |
|                 width = (int)layout.MajorInterval;
 | |
| 
 | |
|             int x = spt.X - (int)(layout.MajorInterval / 2);
 | |
| 
 | |
|             return (x);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetVBarStart
 | |
| 
 | |
|         internal int GetVBarStart(ChartXy chartXy, SeriesPoint sp)
 | |
|         {
 | |
|             ChartAxis axis = AxisY ?? chartXy.AxisY;
 | |
| 
 | |
|             object value = ((sp.ValueY != null  && sp.ValueY.Length > 1)
 | |
|                 ? sp.ValueY[1] : (chartXy.BarOrigin ?? null));
 | |
| 
 | |
|             if (value == null)
 | |
|             {
 | |
|                 if (axis.ScaleType == ScaleType.Quantitative)
 | |
|                     value = 0;
 | |
|                 else
 | |
|                     value = axis.ActualMinValue;
 | |
|             }
 | |
| 
 | |
|             return (chartXy.GetDataPointY(axis, value));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetVBarOrigin
 | |
| 
 | |
|         private int GetVBarOrigin(
 | |
|             ChartXy chartXy, ChartAxis axis, SeriesPoint sp)
 | |
|         {
 | |
|             object value = ((sp.ValueY != null && sp.ValueY.Length > 2)
 | |
|                 ? sp.ValueY[2] : (chartXy.BarOrigin ?? null));
 | |
| 
 | |
|             if (value == null)
 | |
|             {
 | |
|                 if (axis.ScaleType == ScaleType.Quantitative)
 | |
|                     value = 0;
 | |
|                 else
 | |
|                     value = axis.ActualMinValue;
 | |
|             }
 | |
| 
 | |
|             return (chartXy.GetDataPointY(axis, value));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderAscendingBar
 | |
| 
 | |
|         private void RenderAscendingBar(Graphics g,
 | |
|             BarRenderData rd, int x, int width, int y1, int y2, int yOrigin)
 | |
|         {
 | |
|             Rectangle r = new Rectangle(x, y1, Math.Max(1, width - 1), y2 - y1);
 | |
| 
 | |
|             if (r.IntersectsWith(_RenderBounds))
 | |
|             {
 | |
|                 Background bk = rd.SeriesStyle.BarVisualStyle.Background;
 | |
|                 ChartLineVisualStyle lstyle = rd.SeriesStyle.BarVisualStyle.Border;
 | |
| 
 | |
|                 Rectangle r2 = r;
 | |
| 
 | |
|                 if (rd.FillRange == BarFillRange.BySeries)
 | |
|                 {
 | |
|                     int top = rd.ChartXy.GetDataPointY(rd.Axis, MaxValueY);
 | |
| 
 | |
|                     r2.Y = top;
 | |
|                     r2.Height = yOrigin - top;
 | |
|                 }
 | |
| 
 | |
|                 BarSegment segment = (y2 < yOrigin) ? BarSegment.Top : BarSegment.TopPartial;
 | |
| 
 | |
|                 RenderFullVBar(g, rd, r, r2, bk, lstyle, segment);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderDescendingBar
 | |
| 
 | |
|         private void RenderDescendingBar(Graphics g,
 | |
|             BarRenderData rd, int x, int width, int y1, int y2, int yOrigin)
 | |
|         {
 | |
|             Rectangle r = new Rectangle(x, y1, Math.Max(1, width - 1), y2 - y1);
 | |
| 
 | |
|             if (r.IntersectsWith(_RenderBounds))
 | |
|             {
 | |
|                 ChartSeriesVisualStyle sstyle = rd.SeriesStyle;
 | |
| 
 | |
|                 Background bk = sstyle.BarVisualStyle.AlternateBackground;
 | |
| 
 | |
|                 if (bk.IsEmpty)
 | |
|                     bk = sstyle.BarVisualStyle.Background;
 | |
| 
 | |
|                 ChartLineVisualStyle lstyle = sstyle.BarVisualStyle.AlternateBorder;
 | |
| 
 | |
|                 if (lstyle.IsEmpty)
 | |
|                     lstyle = sstyle.BarVisualStyle.Border;
 | |
| 
 | |
|                 Rectangle r2 = r;
 | |
| 
 | |
|                 if (GetBarFillRange(rd.ChartXy) == BarFillRange.BySeries)
 | |
|                 {
 | |
|                     r2.Y = yOrigin;
 | |
|                     r2.Height = rd.ChartXy.GetDataPointY(rd.Axis, MinValueY) - r2.Y;
 | |
|                 }
 | |
| 
 | |
|                 BarSegment segment = (y1 > yOrigin) ? BarSegment.Bottom : BarSegment.BottomPartial;
 | |
| 
 | |
|                 RenderFullVBar(g, rd, r, r2, bk, lstyle, segment);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderFullVBar
 | |
| 
 | |
|         private void RenderFullVBar(Graphics g, BarRenderData rd,
 | |
|             Rectangle r, Rectangle r2, Background bk, ChartLineVisualStyle lstyle, BarSegment segment)
 | |
|         {
 | |
|             if (r2.Width > 0 && r2.Height > 0)
 | |
|             {
 | |
|                 ChartXy chartXy = rd.ChartXy;
 | |
|                 ChartControl chartControl = ChartControl;
 | |
| 
 | |
|                 if (chartControl.DoPreRenderSeriesBarEvent(g, chartXy, this, rd.Sp, r, r2, segment) == false)
 | |
|                 {
 | |
|                     using (Brush br = bk.GetBrush(r2))
 | |
|                         g.FillRectangle(br, r);
 | |
| 
 | |
|                     int lw = 0;
 | |
| 
 | |
|                     if (lstyle.LinePattern != LinePattern.None)
 | |
|                     {
 | |
|                         SmoothingMode sm = g.SmoothingMode;
 | |
|                         g.SmoothingMode = SmoothingMode.None;
 | |
| 
 | |
|                         using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth)))
 | |
|                         {
 | |
|                             lw = (int)pen.Width;
 | |
| 
 | |
|                             if (lstyle.LinePattern != LinePattern.NotSet)
 | |
|                                 pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | |
| 
 | |
|                             g.DrawRectangle(pen, r);
 | |
|                         }
 | |
| 
 | |
|                         g.SmoothingMode = sm;
 | |
|                     }
 | |
| 
 | |
|                     if (rd.BarShading == true)
 | |
|                     {
 | |
|                         Rectangle t = r;
 | |
|                         t.Inflate(-lw/2, -lw/2);
 | |
| 
 | |
|                         t.Width++;
 | |
|                         t.Height++;
 | |
| 
 | |
|                         RenderVBarShading(g, t, r2, segment);
 | |
|                     }
 | |
| 
 | |
|                     chartControl.DoPostRenderSeriesBarEvent(g, chartXy, this, rd.Sp, r, r2, segment);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderVBarShading
 | |
| 
 | |
|         private void RenderVBarShading(
 | |
|             Graphics g, Rectangle r, Rectangle r2, BarSegment segment)
 | |
|         {
 | |
|             int n = r.Width / 10 + 1;
 | |
| 
 | |
|             if (r.Width > 6 && r.Height > n)
 | |
|             {
 | |
|                 SmoothingMode sm = g.SmoothingMode;
 | |
|                 g.SmoothingMode = SmoothingMode.None;
 | |
| 
 | |
|                 Color[] colors = (Color[])BarShadingColors.Clone();
 | |
| 
 | |
|                 Rectangle r3 = r;
 | |
| 
 | |
|                 using (LinearGradientBrush lbr = new LinearGradientBrush(r3, Color.Empty, Color.Empty, 0f))
 | |
|                 {
 | |
|                     lbr.WrapMode = WrapMode.TileFlipX;
 | |
| 
 | |
|                     ColorBlend cb = new ColorBlend(4);
 | |
| 
 | |
|                     cb.Colors = new Color[] { colors[2], Color.Transparent, Color.Transparent, colors[3] };
 | |
|                     cb.Positions = new float[] { 0f, .15f, .85f, 1f };
 | |
| 
 | |
|                     lbr.InterpolationColors = cb;
 | |
| 
 | |
|                     g.FillRectangle(lbr, r3);
 | |
|                 }
 | |
| 
 | |
|                 switch (segment)
 | |
|                 {
 | |
|                     case BarSegment.TopPartial:
 | |
|                         FillTop(g, r, n, colors);
 | |
|                         break;
 | |
| 
 | |
|                     case BarSegment.BottomPartial:
 | |
|                         FillBottom(g, r, n, colors);
 | |
|                         break;
 | |
| 
 | |
|                     default:
 | |
|                         FillTop(g, r, n, colors);
 | |
|                         FillBottom(g, r, n, colors);
 | |
|                         break;
 | |
|                 }
 | |
| 
 | |
|                 g.SmoothingMode = sm;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region FillTop
 | |
| 
 | |
|         private void FillTop(Graphics g, Rectangle r, int n, Color[] colors)
 | |
|         {
 | |
|             using (Pen pen = new Pen(colors[0]))
 | |
|             {
 | |
|                 Point pt1 = new Point(r.X + 1, r.Y);
 | |
|                 Point pt2 = new Point(r.Right - 2, r.Y);
 | |
| 
 | |
|                 for (int i = 0; i < n; i++)
 | |
|                 {
 | |
|                     g.DrawLine(pen, pt1, pt2);
 | |
| 
 | |
|                     pt1.X++;
 | |
|                     pt2.X--;
 | |
| 
 | |
|                     pt1.Y++;
 | |
|                     pt2.Y++;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region FillBottom
 | |
| 
 | |
|         private void FillBottom(Graphics g, Rectangle r, int n, Color[] colors)
 | |
|         {
 | |
|             using (Pen pen = new Pen(colors[1]))
 | |
|             {
 | |
|                 Point pt1 = new Point(r.X + 1, r.Bottom - 1);
 | |
|                 Point pt2 = new Point(r.Right - 2, r.Bottom - 1);
 | |
| 
 | |
|                 for (int i = 0; i < n; i++)
 | |
|                 {
 | |
|                     g.DrawLine(pen, pt1, pt2);
 | |
| 
 | |
|                     pt1.X++;
 | |
|                     pt2.X--;
 | |
| 
 | |
|                     pt1.Y--;
 | |
|                     pt2.Y--;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetBarFillRange
 | |
| 
 | |
|         private BarFillRange GetBarFillRange(ChartXy chartXy)
 | |
|         {
 | |
|             BarFillRange fillRange = BarFillRange;
 | |
| 
 | |
|             if (fillRange == BarFillRange.NotSet)
 | |
|                 fillRange = chartXy.BarFillRange;
 | |
| 
 | |
|             return ((fillRange != BarFillRange.NotSet)
 | |
|                 ? fillRange : BarFillRange.ByBar);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetBarLabelPosition
 | |
| 
 | |
|         internal BarLabelPosition GetBarLabelPosition(ChartXy chartXy)
 | |
|         {
 | |
|             BarLabelPosition labelPos = BarLabelPosition;
 | |
| 
 | |
|             if (labelPos == BarLabelPosition.NotSet)
 | |
|                 labelPos = chartXy.BarLabelPosition;
 | |
| 
 | |
|             return ((labelPos != BarLabelPosition.NotSet)
 | |
|                 ? labelPos : BarLabelPosition.Center);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetBarShading
 | |
| 
 | |
|         private bool GetBarShading(ChartXy chartXy)
 | |
|         {
 | |
|             Tbool barShading = BarShadingEnabled;
 | |
| 
 | |
|             if (barShading == Tbool.NotSet)
 | |
|                 barShading = chartXy.BarShadingEnabled;
 | |
| 
 | |
|             return (barShading == Tbool.True);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderBubblePlot
 | |
| 
 | |
|         private void RenderBubblePlot(Graphics g,
 | |
|             ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             BubblePlotData bdata = _PlotData as BubblePlotData;
 | |
| 
 | |
|             if (bdata != null)
 | |
|             {
 | |
|                 double minIntensity = 32;
 | |
|                 double maxIntensity = 255;
 | |
| 
 | |
|                 PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle;
 | |
|                 PointMarkerVisualStyle hstyle = GetHighlightStyle(chartXy, sstyle);
 | |
| 
 | |
|                 if (DisplayLinePointsOnTop == true)
 | |
|                     RenderConvexHull(g, chartXy, ssp, sstyle, pstyle);
 | |
| 
 | |
|                 BubbleIntensityMode imode = GetBubbleIntensityMode(chartXy);
 | |
|                 
 | |
|                 for (int i = 0; i < ssp.Count; i++)
 | |
|                 {
 | |
|                     SeriesPoint sp = ssp[i];
 | |
| 
 | |
|                     if (sp.Visible == true)
 | |
|                     {
 | |
|                         int size = sp.PointSize.Width;
 | |
| 
 | |
|                         Point pt = chartXy.GetDataPointNa(this, sp, 0);
 | |
|                         Rectangle r = new Rectangle(pt.X - size / 2, pt.Y - size / 2, size, size);
 | |
| 
 | |
|                         if (r.IntersectsWith(_RenderBounds))
 | |
|                         {
 | |
|                             Point ppt = chartXy.GetLocalAdjustedPoint(pt);
 | |
| 
 | |
|                             bool isCrossPoint = chartXy.IsCrosshairSeriesPoint(this, ppt);
 | |
|                             int intensity = GetIntensity(sp, imode, bdata, minIntensity, maxIntensity);
 | |
| 
 | |
|                             PointMarkerVisualStyle style = (hstyle != null && isCrossPoint) ? hstyle : pstyle;
 | |
| 
 | |
|                             Image image = style.GetPointMarkerImage();
 | |
| 
 | |
|                             if (image == null)
 | |
|                                 image = GetPointMarker(g, style, r.Size);
 | |
| 
 | |
|                             if (image != null)
 | |
|                             {
 | |
|                                 g.DrawImage(image, r);
 | |
|                             }
 | |
|                             else if (style.Type == PointMarkerType.Ellipse || style.Type == PointMarkerType.NotSet)
 | |
|                             {
 | |
|                                 using (Brush br = style.Background.GetBrush(r, intensity))
 | |
|                                 {
 | |
|                                     g.FillEllipse(br, r);
 | |
| 
 | |
|                                     if (style.BorderColor.IsEmpty == false && style.BorderWidth > 0)
 | |
|                                     {
 | |
|                                         using (Pen pen = new Pen(style.BorderColor, Dpi.Width(style.BorderWidth)))
 | |
|                                             g.DrawEllipse(pen, r);
 | |
|                                     }
 | |
|                                 }
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (DisplayLinePointsOnTop == false)
 | |
|                     RenderConvexHull(g, chartXy, ssp, sstyle, pstyle);
 | |
| 
 | |
|                 if (hstyle != null)
 | |
|                     hstyle.Dispose();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetIntensity
 | |
| 
 | |
|         private int GetIntensity(SeriesPoint sp,
 | |
|             BubbleIntensityMode imode, BubblePlotData bdata, double minIntensity, double maxIntensity)
 | |
|         {
 | |
|             if (imode != BubbleIntensityMode.None && imode != BubbleIntensityMode.NotSet)
 | |
|             {
 | |
|                 if (sp.ValueY.Length > 2)
 | |
|                 {
 | |
|                     double intensity = -1;
 | |
| 
 | |
|                     if (sp.ValueY[2] is double)
 | |
|                         intensity = (double)sp.ValueY[2];
 | |
| 
 | |
|                     else if (sp.ValueY[2] is int)
 | |
|                         intensity = Convert.ToDouble(sp.ValueY[2]);
 | |
| 
 | |
|                     if (imode == BubbleIntensityMode.Alpha)
 | |
|                         return ((int)intensity);
 | |
| 
 | |
|                     if (intensity >= 0)
 | |
|                     {
 | |
|                         double range = maxIntensity - minIntensity;
 | |
|                         double intensityRange = bdata.MaxIntensity - bdata.MinIntensity;
 | |
| 
 | |
|                         if (intensityRange <= 0)
 | |
|                             return (-1);
 | |
| 
 | |
|                         return (int)(((intensity - bdata.MinIntensity) * range) / intensityRange + minIntensity);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (-1);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetBubbleSizeMode
 | |
| 
 | |
|         private BubbleSizeMode GetBubbleSizeMode(ChartXy chartXy)
 | |
|         {
 | |
|             if (BubbleSizeMode != BubbleSizeMode.NotSet)
 | |
|                 return (BubbleSizeMode);
 | |
| 
 | |
|             if (chartXy.BubbleSizeMode != BubbleSizeMode.NotSet)
 | |
|                 return (chartXy.BubbleSizeMode);
 | |
| 
 | |
|             return (BubbleSizeMode.Area);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetBubbleIntensityMode
 | |
| 
 | |
|         private BubbleIntensityMode GetBubbleIntensityMode(ChartXy chartXy)
 | |
|         {
 | |
|             if (BubbleIntensityMode != BubbleIntensityMode.NotSet)
 | |
|                 return (BubbleIntensityMode);
 | |
| 
 | |
|             if (chartXy.BubbleIntensityMode != BubbleIntensityMode.NotSet)
 | |
|                 return (chartXy.BubbleIntensityMode);
 | |
| 
 | |
|             return (BubbleIntensityMode.None);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetPointMarker
 | |
| 
 | |
|         internal Image GetPointMarker(Graphics g, PointMarkerVisualStyle style, Size size)
 | |
|         {
 | |
|             if (style.Type == PointMarkerType.NotSet ||
 | |
|                 style.Type == PointMarkerType.None || style.Type == PointMarkerType.Ellipse)
 | |
|             {
 | |
|                 return (null);
 | |
|             }
 | |
| 
 | |
|             if (_PointMarker == null)
 | |
|                 _PointMarker = new PointMarker();
 | |
| 
 | |
|             return (_PointMarker.GetMarkerBitmap(g, style.Type, style.PointCount, 
 | |
|                 size, style.Rotation, style.Background, style.BorderColor, style.BorderWidth));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderDotPlot
 | |
| 
 | |
|         #region RenderHDotPlot
 | |
| 
 | |
|         private void RenderHDotPlot(Graphics g,
 | |
|             ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             Image marker = PointMarkerImage;
 | |
| 
 | |
|             if (marker != null)
 | |
|             {
 | |
|                 Size maxSize = chartXy.GetMaxDotPlotMarkerSize();
 | |
| 
 | |
|                 for (int i = 0; i < ssp.Count; i++)
 | |
|                 {
 | |
|                     SeriesPoint sp = ssp[i];
 | |
| 
 | |
|                     if (sp.Visible == true)
 | |
|                     {
 | |
|                         object pointValueX = chartXy.GetDataPointValueX(this, sp);
 | |
| 
 | |
|                         Point pt = chartXy.GetPointFromValue(this, 0, pointValueX);
 | |
| 
 | |
|                         Point ppt = new Point(pt.X + maxSize.Width / 2, pt.Y);
 | |
| 
 | |
|                         int dcount = ssp.CountArray[i];
 | |
| 
 | |
|                         for (int j = 0; j < dcount; j++)
 | |
|                         {
 | |
|                             RenderPointMarker(g, chartXy, sp, ppt, maxSize, marker);
 | |
| 
 | |
|                             ppt.X += maxSize.Width;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderVDotPlot
 | |
| 
 | |
|         private void RenderVDotPlot(Graphics g,
 | |
|             ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             Image marker = PointMarkerImage;
 | |
| 
 | |
|             if (marker != null)
 | |
|             {
 | |
|                 Size maxSize = chartXy.GetMaxDotPlotMarkerSize();
 | |
| 
 | |
|                 for (int i = 0; i < ssp.Count; i++)
 | |
|                 {
 | |
|                     SeriesPoint sp = ssp[i];
 | |
| 
 | |
|                     if (sp.Visible == true)
 | |
|                     {
 | |
|                         Point pt = chartXy.GetDataPointNa(this, sp, -1);
 | |
|                         Point ppt = new Point(pt.X, pt.Y - maxSize.Height / 2);
 | |
| 
 | |
|                         int dcount = ssp.CountArray[i];
 | |
| 
 | |
|                         for (int j = 0; j < dcount; j++)
 | |
|                         {
 | |
|                             RenderPointMarker(g, chartXy, sp, ppt, maxSize, marker);
 | |
| 
 | |
|                             ppt.Y -= maxSize.Height;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetDotCount
 | |
| 
 | |
|         private int GetDotCount(SeriesPoint sp)
 | |
|         {
 | |
|             if (sp.ValueY != null && sp.ValueY.Length > 0)
 | |
|             {
 | |
|                 int count = 0;
 | |
| 
 | |
|                 foreach (object o in sp.ValueY)
 | |
|                 {
 | |
|                     if (o is int)
 | |
|                         count += (int)o;
 | |
| 
 | |
|                     else if (o is double)
 | |
|                         count += (int)Convert.ChangeType(o, typeof(int));
 | |
|                 }
 | |
| 
 | |
|                 return (count);
 | |
|             }
 | |
| 
 | |
|             return (1);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderPointPlot
 | |
| 
 | |
|         private void RenderPointPlot(Graphics g, ChartXy chartXy,
 | |
|             SortedSeriesPoints ssp, bool showHull, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             PointData pd = GatherSeriesPoints(chartXy, ssp, 0, ssp.Count, true);
 | |
| 
 | |
|             if (pd.Points.Count > 0)
 | |
|             {
 | |
|                 PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle;
 | |
|                 PointMarkerVisualStyle hstyle = GetHighlightStyle(chartXy, sstyle);
 | |
| 
 | |
|                 if (showHull == true)
 | |
|                     RenderConvexHull(g, chartXy, ssp, sstyle, pstyle);
 | |
| 
 | |
|                 if (hstyle == null)
 | |
|                 {
 | |
|                     Image marker = chartXy.GetPointMarker(g, pstyle);
 | |
| 
 | |
|                     if (marker != null)
 | |
|                     {
 | |
|                         for (int i=0; i<pd.Points.Count; i++)
 | |
|                         {
 | |
|                             Point[] pts = pd.Points[i];
 | |
|                             SeriesPoint[] spts = pd.SeriesPoints[i];
 | |
| 
 | |
|                             for (int j = 0; j < pts.Length; j++)
 | |
|                                 RenderPointMarker(g, chartXy, spts[j], pts[j], Size.Empty, marker);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     for (int i = 0; i < pd.Points.Count; i++)
 | |
|                     {
 | |
|                         Point[] pts = pd.Points[i];
 | |
|                         SeriesPoint[] spts = pd.SeriesPoints[i];
 | |
| 
 | |
|                         for (int j = 0; j < pts.Length; j++)
 | |
|                         {
 | |
|                             Point ppt = pts[j];
 | |
|                             Point ppt2 = chartXy.GetLocalAdjustedPoint(ppt);
 | |
| 
 | |
|                             Image marker = (chartXy.IsCrosshairSeriesPoint(this, ppt2))
 | |
|                                 ? GetHighlightImage(g, chartXy, hstyle) : PointMarkerImage;
 | |
| 
 | |
|                             RenderPointMarker(g, chartXy, spts[j], ppt, Size.Empty, marker);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (ShowEmptyPoints == true)
 | |
|                     RenderEmptyPoints(g, chartXy, pd, sstyle);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderPointMarker
 | |
| 
 | |
|         private void RenderPointMarker(Graphics g,
 | |
|             ChartXy chartXy, SeriesPoint sp, Point pt, Size maxSize, Image marker)
 | |
|         {
 | |
|             if (marker != null)
 | |
|             {
 | |
|                 ChartControl control = ChartControl;
 | |
| 
 | |
|                 Image ptMarker = marker;
 | |
| 
 | |
|                 Size markerSize = marker.Size;
 | |
|                 Size size = maxSize.IsEmpty ? markerSize : maxSize;
 | |
| 
 | |
|                 sp.PointSize = size;
 | |
| 
 | |
|                 Point ptc = new Point(
 | |
|                     pt.X - markerSize.Width / 2,
 | |
|                     pt.Y - markerSize.Height / 2);
 | |
| 
 | |
|                 Rectangle r = new Rectangle(ptc, markerSize);
 | |
| 
 | |
|                 if (r.IntersectsWith(_RenderBounds))
 | |
|                 {
 | |
|                     if (control.DoPreRenderSeriesPointEvent(g,
 | |
|                         chartXy, this, sp, pt, size, ref ptMarker) == false)
 | |
|                     {
 | |
|                         if (ptMarker != null)
 | |
|                         {
 | |
|                             g.DrawImageUnscaled(ptMarker, ptc);
 | |
| 
 | |
|                             control.DoPostRenderSeriesPointEvent(g,
 | |
|                                 chartXy, this, sp, pt, ptMarker.Size, ptMarker);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderConvexHull
 | |
| 
 | |
|         private void RenderConvexHull(Graphics g, ChartXy chartXy,
 | |
|             SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle, PointMarkerVisualStyle pstyle)
 | |
|         {
 | |
|             ConvexHullDisplayMode mode = GetConvexHullDisplayMode(chartXy);
 | |
| 
 | |
|             if (mode != ConvexHullDisplayMode.None)
 | |
|             {
 | |
|                 if (_ConvexHullPoints == null)
 | |
|                 {
 | |
|                     PointData pd = GatherSeriesPointsEx(chartXy, ssp, 0, ssp.Count, true);
 | |
| 
 | |
|                     _ConvexHullPoints = ConvexHull.GetConvexHull(
 | |
|                         (pd.Points.Count == 1) ? pd.Points[0] : CombineListPoints(pd.Points));
 | |
|                 }
 | |
| 
 | |
|                 if (_ConvexHullPoints.Length > 3)
 | |
|                 {
 | |
|                     using (GraphicsPath path = new GraphicsPath())
 | |
|                     {
 | |
|                         path.AddPolygon(_ConvexHullPoints);
 | |
| 
 | |
|                         if ((mode & ConvexHullDisplayMode.DisplayBackground) == ConvexHullDisplayMode.DisplayBackground)
 | |
|                         {
 | |
|                             Rectangle r = Rectangle.Round(path.GetBounds());
 | |
| 
 | |
|                             Background bg = (sstyle.ConvexHullBackground.IsEmpty)
 | |
|                                 ? pstyle.Background : sstyle.ConvexHullBackground;
 | |
| 
 | |
|                             using (Brush br = bg.GetBrush(r))
 | |
|                                 g.FillPath(br, path);
 | |
|                         }
 | |
| 
 | |
|                         if ((mode & ConvexHullDisplayMode.DisplayBorder) == ConvexHullDisplayMode.DisplayBorder)
 | |
|                         {
 | |
|                             Color color;
 | |
|                             int width;
 | |
|                             LinePattern pattern;
 | |
| 
 | |
|                             if (sstyle.ConvexHullLineStyle.IsEmpty == false)
 | |
|                             {
 | |
|                                 color = sstyle.ConvexHullLineStyle.LineColor;
 | |
|                                 width = sstyle.ConvexHullLineStyle.LineWidth;
 | |
|                                 pattern = sstyle.ConvexHullLineStyle.LinePattern;
 | |
|                             }
 | |
|                             else
 | |
|                             {
 | |
|                                 color = pstyle.BorderColor;
 | |
|                                 width = pstyle.BorderWidth;
 | |
|                                 pattern = LinePattern.Solid;
 | |
|                             }
 | |
| 
 | |
|                             if (pattern != LinePattern.None)
 | |
|                             {
 | |
|                                 using (Pen pen = new Pen(color, Dpi.Width(width)))
 | |
|                                 {
 | |
|                                     if (pattern != LinePattern.NotSet)
 | |
|                                         pen.DashStyle = (DashStyle)pattern;
 | |
| 
 | |
|                                     g.DrawPath(pen, path);
 | |
|                                 }
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetConvexHullDisplayMode
 | |
| 
 | |
|         private ConvexHullDisplayMode GetConvexHullDisplayMode(ChartXy chartXy)
 | |
|         {
 | |
|             if (ConvexHullDisplayMode != ConvexHullDisplayMode.NotSet)
 | |
|                 return (ConvexHullDisplayMode);
 | |
| 
 | |
|             ConvexHullDisplayMode mode = chartXy.ConvexHullDisplayMode;
 | |
| 
 | |
|             if (mode != ConvexHullDisplayMode.NotSet) 
 | |
|                 return (mode);
 | |
| 
 | |
|             return (ConvexHullDisplayMode.None);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CombineListPoints
 | |
| 
 | |
|         private Point[] CombineListPoints(List<Point[]> plist)
 | |
|         {
 | |
|             int n = 0;
 | |
| 
 | |
|             foreach (Point[] points in plist)
 | |
|                 n += points.Length;
 | |
| 
 | |
|             Point[] fpoints = new Point[n];
 | |
| 
 | |
|             n = 0;
 | |
| 
 | |
|             foreach (Point[] points in plist)
 | |
|             {
 | |
|                 for (int i = 0; i < points.Length; i++)
 | |
|                     fpoints[n++] = points[i];
 | |
|             }
 | |
| 
 | |
|             return (fpoints);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderEmptyPoints
 | |
| 
 | |
|         private void RenderEmptyPoints(Graphics g,
 | |
|             ChartXy chartXy, PointData pd, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             PointData epd = _EmptyPointData;
 | |
| 
 | |
|             if (epd != null && epd.Points.Count > 0)
 | |
|             {
 | |
|                 PointMarkerVisualStyle pstyle = sstyle.MarkerEmptyVisualStyle;
 | |
| 
 | |
|                 Image marker = GetEmptyMarkerImage(g, chartXy, pstyle);
 | |
| 
 | |
|                 if (marker != null)
 | |
|                 {
 | |
|                     for (int i = 0; i < epd.Points.Count; i++)
 | |
|                     {
 | |
|                         Point[] epts = epd.Points[i];
 | |
|                         SeriesPoint[] septs = epd.SeriesPoints[i];
 | |
| 
 | |
|                         Point[] pts = GetEmptyPointRange(epts[0]);
 | |
| 
 | |
|                         int run = pts[0].X - pts[1].X;
 | |
|                         int rise = pts[0].Y - pts[1].Y;
 | |
| 
 | |
|                         double slope = (run != 0) ? (double)rise / run : 0;
 | |
|                         double b = pts[0].Y - (slope * pts[0].X);
 | |
| 
 | |
|                         for (int j = 0; j < epts.Length; j++)
 | |
|                         {
 | |
|                             Point ept = epts[j];
 | |
|                             SeriesPoint sept = septs[j];
 | |
| 
 | |
|                             Point ppt = new Point(ept.X, (int)(slope * ept.X + b));
 | |
| 
 | |
|                             RenderPointMarker(g, chartXy, sept, ppt, Size.Empty, marker);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetEmptyPointRange
 | |
| 
 | |
|         private Point[] GetEmptyPointRange(Point pt)
 | |
|         {
 | |
|             Point[] pts = new Point[2];
 | |
| 
 | |
|             pts[0] = Point.Empty;
 | |
|             pts[1] = Point.Empty;
 | |
| 
 | |
|             PointData pd = _PointData;
 | |
| 
 | |
|             for (int i = 0; i < pd.Points.Count; i++)
 | |
|             {
 | |
|                 Point[] lps = pd.Points[i];
 | |
| 
 | |
|                 if (pt.X <= lps[0].X)
 | |
|                 {
 | |
|                     pts[1] = lps[0];
 | |
| 
 | |
|                     if (i == 0)
 | |
|                         pts[0] = pts[1];
 | |
| 
 | |
|                     return (pts);
 | |
|                 }
 | |
| 
 | |
|                 pts[0] = lps[lps.Length - 1];
 | |
|             }
 | |
| 
 | |
|             pts[1] = pts[0];
 | |
| 
 | |
|             return (pts);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderLinePlot
 | |
| 
 | |
|         private void RenderLinePlot(Graphics g,
 | |
|             ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             PointData pd = GatherSeriesPoints(chartXy, ssp, 0, ssp.Count, false);
 | |
| 
 | |
|             if (pd.Points.Count > 0)
 | |
|             {
 | |
|                 ChartLineDisplayMode lineMode = GetLineDisplayMode(chartXy);
 | |
|                 ChartLineAreaDisplayMode areaMode = GetAreaDisplayMode(chartXy);
 | |
| 
 | |
|                 PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle;
 | |
| 
 | |
|                 RenderConvexHull(g, chartXy, ssp, sstyle, pstyle);
 | |
| 
 | |
|                 if (DisplayLinePointsOnTop == true)
 | |
|                     RenderLinePlotLines(g, chartXy, pd, lineMode, areaMode, sstyle);
 | |
| 
 | |
|                 if ((lineMode & ChartLineDisplayMode.DisplayPoints) == ChartLineDisplayMode.DisplayPoints)
 | |
|                 {
 | |
|                     RenderPointPlot(g, chartXy, ssp, false, sstyle);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     if (ShowEmptyPoints == true)
 | |
|                         RenderEmptyPoints(g, chartXy, pd, sstyle);
 | |
| 
 | |
|                     RenderPointLabelPoints(g, chartXy, sstyle);
 | |
| 
 | |
|                     if (HighLightPoints(chartXy) == true)
 | |
|                         RenderHighlightPoints(g, chartXy, pd, sstyle);
 | |
|                 }
 | |
| 
 | |
|                 if (DisplayLinePointsOnTop == false)
 | |
|                     RenderLinePlotLines(g, chartXy, pd, lineMode, areaMode, sstyle);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderPointLabelPoints
 | |
| 
 | |
|         private void RenderPointLabelPoints(Graphics g,
 | |
|             ChartXy chartXy, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             List<PointLabelGroup> pointLabels = chartXy.PointLabels;
 | |
| 
 | |
|             if (pointLabels != null && pointLabels.Count > 0)
 | |
|             {
 | |
|                 foreach (PointLabelGroup lg in pointLabels)
 | |
|                 {
 | |
|                     if (lg.ChartSeries == this)
 | |
|                     {
 | |
|                         PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle;
 | |
| 
 | |
|                         Image marker = chartXy.GetPointMarker(g, pstyle);
 | |
| 
 | |
|                         if (marker != null)
 | |
|                         {
 | |
|                             Size size = marker.Size;
 | |
| 
 | |
|                             for (int i = 0; i < lg.PointLabels.Count; i++)
 | |
|                             {
 | |
|                                 PointLabel pl = lg.PointLabels[i];
 | |
| 
 | |
|                                 if (pl.Visible == true && pl.SeriesPoint.IsEmpty == false)
 | |
|                                 {
 | |
|                                     DataLabelVisualStyle dstyle = GetPointLabelVisualStyle(pl);
 | |
| 
 | |
|                                     if (dstyle.DrawPointMarker != Tbool.False)
 | |
|                                     {
 | |
|                                         SeriesPoint spt = pl.SeriesPoint;
 | |
| 
 | |
|                                         Point ppt = pl.Point;
 | |
|                                         Point ppc = new Point(ppt.X, ppt.Y);
 | |
| 
 | |
|                                         RenderPointMarker(g, chartXy, spt, ppc, Size.Empty, marker);
 | |
|                                     }
 | |
|                                 }
 | |
|                             }
 | |
|                         }
 | |
|                         break;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderLinePlotLines
 | |
| 
 | |
|         private void RenderLinePlotLines(Graphics g, ChartXy chartXy, PointData pd,
 | |
|             ChartLineDisplayMode lineMode, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             if ((lineMode & ChartLineDisplayMode.DisplayStepLine) == ChartLineDisplayMode.DisplayStepLine)
 | |
|             {
 | |
|                 StepLineMode slm = GetStepLineMode(chartXy);
 | |
| 
 | |
|                 if (slm != StepLineMode.None)
 | |
|                     RenderStepLines(g, chartXy, pd, slm, areaMode, sstyle);
 | |
|             }
 | |
| 
 | |
|             if ((lineMode & ChartLineDisplayMode.DisplayLine) == ChartLineDisplayMode.DisplayLine)
 | |
|                 RenderLines(g, chartXy, pd, lineMode, areaMode, sstyle);
 | |
| 
 | |
|             if ((lineMode & ChartLineDisplayMode.DisplaySpline) == ChartLineDisplayMode.DisplaySpline)
 | |
|                 RenderSplines(g, chartXy, pd, lineMode, areaMode, sstyle);
 | |
| 
 | |
|             if (ShowEmptyLines == true)
 | |
|             {
 | |
|                 if ((lineMode & (ChartLineDisplayMode.DisplayLine | ChartLineDisplayMode.DisplaySpline)) != 0)
 | |
|                     RenderEmptyLines(g, chartXy, pd.Points, areaMode, sstyle);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetStepLineMode
 | |
| 
 | |
|         private StepLineMode GetStepLineMode(ChartXy chartXy)
 | |
|         {
 | |
|             StepLineMode mode = StepLineMode;
 | |
| 
 | |
|             if (mode == StepLineMode.NotSet)
 | |
|                 mode = chartXy.StepLineMode;
 | |
| 
 | |
|             if (mode == StepLineMode.NotSet)
 | |
|                 mode = StepLineMode.HorizontalThenVertical;
 | |
| 
 | |
|             return (mode);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderLines
 | |
| 
 | |
|         private void RenderLines(Graphics g, ChartXy chartXy,
 | |
|             PointData pd, ChartLineDisplayMode lineMode, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             ChartLineVisualStyle lstyle = sstyle.LineStyle;
 | |
| 
 | |
|             if (lstyle.LinePattern != LinePattern.None)
 | |
|             {
 | |
|                 using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth)))
 | |
|                 {
 | |
|                     if (lstyle.LinePattern != LinePattern.NotSet)
 | |
|                         pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | |
| 
 | |
|                     if ((lineMode & ChartLineDisplayMode.DisplayClosed) == ChartLineDisplayMode.DisplayClosed)
 | |
|                     {
 | |
|                         foreach (Point[] points in pd.Points)
 | |
|                         {
 | |
|                             if (points.Length > 1)
 | |
|                                 g.DrawLines(pen, points);
 | |
|                         }
 | |
| 
 | |
|                         Point fp = pd.Points[0][0];
 | |
|                         Point[] lps = pd.Points[pd.Points.Count - 1];
 | |
|                         Point lp = lps[lps.Length - 1];
 | |
| 
 | |
|                         if (fp.Equals(lp) == false)
 | |
|                             g.DrawLine(pen, lp, fp);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         foreach (Point[] points in pd.Points)
 | |
|                         {
 | |
|                             if (points.Length > 1)
 | |
|                             {
 | |
|                                 using (GraphicsPath path = new GraphicsPath())
 | |
|                                 {
 | |
|                                     path.AddLines(points);
 | |
| 
 | |
|                                     if ((areaMode & ChartLineAreaDisplayMode.DisplayLine) == ChartLineAreaDisplayMode.DisplayLine)
 | |
|                                         RenderAreaBackground(g, chartXy, points, path, sstyle.LineAreaBackground);
 | |
| 
 | |
|                                     g.DrawPath(pen, path);
 | |
|                                 }
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderSplines
 | |
| 
 | |
|         private void RenderSplines(Graphics g, ChartXy chartXy, PointData pd,
 | |
|             ChartLineDisplayMode lineMode, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             ChartLineVisualStyle lstyle = sstyle.SplineStyle;
 | |
| 
 | |
|             if (lstyle.LinePattern != LinePattern.None)
 | |
|             {
 | |
|                 using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth)))
 | |
|                 {
 | |
|                     if (lstyle.LinePattern != LinePattern.NotSet)
 | |
|                         pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | |
| 
 | |
|                     if ((pd.Points.Count == 1) &&
 | |
|                         (lineMode & ChartLineDisplayMode.DisplayClosed) == ChartLineDisplayMode.DisplayClosed)
 | |
|                     {
 | |
|                         Point[] points = pd.Points[0];
 | |
| 
 | |
|                         if (points.Length > 1)
 | |
|                             g.DrawClosedCurve(pen, points);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         foreach (Point[] points in pd.Points)
 | |
|                         {
 | |
|                             if (points.Length > 1)
 | |
|                             {
 | |
|                                 using (GraphicsPath path = new GraphicsPath())
 | |
|                                 {
 | |
|                                     path.AddCurve(points);
 | |
| 
 | |
|                                     if ((areaMode & ChartLineAreaDisplayMode.DisplaySpline) == ChartLineAreaDisplayMode.DisplaySpline)
 | |
|                                         RenderAreaBackground(g, chartXy, points, path, sstyle.SplineAreaBackground);
 | |
| 
 | |
|                                     g.DrawPath(pen, path);
 | |
|                                 }
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderStepLines
 | |
| 
 | |
|         private void RenderStepLines(Graphics g, ChartXy chartXy, PointData pd,
 | |
|             StepLineMode slm, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             StepLines sls = GetStepLines(chartXy);
 | |
| 
 | |
|             if (sls != StepLines.None)
 | |
|             {
 | |
|                 PointData sd = GetStepPointData(chartXy, pd, slm);
 | |
| 
 | |
|                 if (sd != null)
 | |
|                 {
 | |
|                     SmoothingMode sm = g.SmoothingMode;
 | |
|                     g.SmoothingMode = SmoothingMode.Default;
 | |
| 
 | |
|                     ChartCapLineVisualStyle lstyle = sstyle.StepLineStyle;
 | |
| 
 | |
|                     if (sls == StepLines.Both)
 | |
|                     {
 | |
|                         RenderStepLinesEx1(g, sd, lstyle);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         int n = ((sls == StepLines.Horizontal && (slm == StepLineMode.HorizontalThenVertical || slm == StepLineMode.MidPoint)) ||
 | |
|                                  (sls == StepLines.Vertical && slm == StepLineMode.VerticalThenHorizontal)) ? 0 : 1;
 | |
| 
 | |
|                         RenderStepLinesEx2(g, sd, n, lstyle);
 | |
| 
 | |
|                         if (sstyle.StepLineAltStyle.IsEmpty == false)
 | |
|                             RenderStepLinesEx2(g, sd, n ^ 1, sstyle.StepLineAltStyle);
 | |
|                     }
 | |
| 
 | |
|                     g.SmoothingMode = sm;
 | |
| 
 | |
|                     if ((areaMode & ChartLineAreaDisplayMode.DisplayStepLine) == ChartLineAreaDisplayMode.DisplayStepLine)
 | |
|                     {
 | |
|                         foreach (Point[] points in sd.Points)
 | |
|                         {
 | |
|                             using (GraphicsPath path = new GraphicsPath())
 | |
|                             {
 | |
|                                 path.AddLines(points);
 | |
| 
 | |
|                                 RenderAreaBackground(g, chartXy, points, path, sstyle.StepLineAreaBackground);
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetStepLines
 | |
| 
 | |
|         private StepLines GetStepLines(ChartXy chartXy)
 | |
|         {
 | |
|             StepLines mode = StepLines;
 | |
| 
 | |
|             if (mode == StepLines.NotSet)
 | |
|                 mode = chartXy.StepLines;
 | |
| 
 | |
|             if (mode == StepLines.NotSet)
 | |
|                 mode = StepLines.Both;
 | |
| 
 | |
|             return (mode);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetStepPointData
 | |
| 
 | |
|         private PointData GetStepPointData(
 | |
|             ChartXy chartXy, PointData pd, Charts.StepLineMode slm)
 | |
|         {
 | |
|             if (_LastStepLineMode != slm)
 | |
|                 _StepPointData = null;
 | |
| 
 | |
|             if (_StepPointData == null)
 | |
|             {
 | |
|                 PointData sd = new PointData();
 | |
| 
 | |
|                 sd.Points = new List<Point[]>();
 | |
| 
 | |
|                 foreach (Point[] points in pd.Points)
 | |
|                 {
 | |
|                     if (points.Length > 1)
 | |
|                         sd.Points.Add(GetStepPoints(slm, points));
 | |
|                 }
 | |
| 
 | |
|                 _StepPointData = sd;
 | |
| 
 | |
|                 _LastStepLineMode = slm;
 | |
|             }
 | |
| 
 | |
|             return (_StepPointData);
 | |
|         }
 | |
| 
 | |
|         #region GetStepPoints
 | |
| 
 | |
|         private Point[] GetStepPoints(StepLineMode slm, Point[] pts)
 | |
|         {
 | |
|             if (slm == StepLineMode.HorizontalThenVertical || slm == StepLineMode.VerticalThenHorizontal)
 | |
|             {
 | |
|                 Point[] points = new Point[pts.Length * 2 - 1];
 | |
| 
 | |
|                 if (slm == StepLineMode.HorizontalThenVertical)
 | |
|                 {
 | |
|                     for (int i = 0; i < pts.Length; i++)
 | |
|                     {
 | |
|                         int n = i * 2;
 | |
| 
 | |
|                         points[n] = pts[i];
 | |
| 
 | |
|                         if (i + 1 < pts.Length)
 | |
|                             points[n + 1] = new Point(pts[i + 1].X, pts[i].Y);
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     for (int i = 0; i < pts.Length; i++)
 | |
|                     {
 | |
|                         int n = i * 2;
 | |
| 
 | |
|                         points[n] = pts[i];
 | |
| 
 | |
|                         if (i + 1 < pts.Length)
 | |
|                             points[n + 1] = new Point(pts[i].X, pts[i + 1].Y);
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 return (points);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 Point[] points = new Point[pts.Length * 2];
 | |
| 
 | |
|                 points[0] = pts[0];
 | |
| 
 | |
|                 for (int i = 0; i < pts.Length - 1; i++)
 | |
|                 {
 | |
|                     int n0 = i * 2 + 1;
 | |
|                     int n1 = n0 + 1;
 | |
| 
 | |
|                     points[n0] = new Point((pts[i].X + pts[i + 1].X) / 2, pts[i].Y);
 | |
|                     points[n1] = new Point(points[n0].X, pts[i + 1].Y);
 | |
|                 }
 | |
| 
 | |
|                 points[points.Length - 1] = pts[pts.Length - 1];
 | |
| 
 | |
|                 return (points);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderStepLinesEx1
 | |
| 
 | |
|         private void RenderStepLinesEx1(Graphics g, PointData sd, ChartCapLineVisualStyle lstyle)
 | |
|         {
 | |
|             if (lstyle.LinePattern != LinePattern.None)
 | |
|             {
 | |
|                 using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth)))
 | |
|                 {
 | |
|                     if (lstyle.LinePattern != LinePattern.NotSet)
 | |
|                         pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | |
| 
 | |
|                     if (lstyle.StartCap != ChartLineCap.NotSet)
 | |
|                         pen.StartCap = (LineCap)lstyle.StartCap;
 | |
| 
 | |
|                     if (lstyle.EndCap != ChartLineCap.NotSet)
 | |
|                         pen.EndCap = (LineCap)lstyle.EndCap;
 | |
| 
 | |
|                     foreach (Point[] points in sd.Points)
 | |
|                     {
 | |
|                         if (points.Length > 1)
 | |
|                             g.DrawLines(pen, points);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderStepLinesEx2
 | |
| 
 | |
|         private void RenderStepLinesEx2(Graphics g,
 | |
|             PointData sd, int n, ChartCapLineVisualStyle lstyle)
 | |
|         {
 | |
|             if (lstyle.LinePattern != LinePattern.None)
 | |
|             {
 | |
|                 using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth)))
 | |
|                 {
 | |
|                     if (lstyle.LinePattern != LinePattern.NotSet)
 | |
|                         pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | |
| 
 | |
|                     if (lstyle.StartCap != ChartLineCap.NotSet)
 | |
|                         pen.StartCap = (LineCap)lstyle.StartCap;
 | |
| 
 | |
|                     if (lstyle.EndCap != ChartLineCap.NotSet)
 | |
|                         pen.EndCap = (LineCap)lstyle.EndCap;
 | |
| 
 | |
|                     foreach (Point[] points in sd.Points)
 | |
|                     {
 | |
|                         if (points.Length > 1)
 | |
|                         {
 | |
|                             for (int i = n; i < points.Length - 1; i += 2)
 | |
|                             {
 | |
|                                 Point pt1 = points[i];
 | |
|                                 Point pt2 = points[i + 1];
 | |
| 
 | |
|                                 g.DrawLine(pen, pt1, pt2);
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderEmptyLines
 | |
| 
 | |
|         private void RenderEmptyLines(Graphics g, ChartXy chartXy,
 | |
|             List<Point[]> lpoints, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             if (lpoints.Count > 1)
 | |
|             {
 | |
|                 ChartLineVisualStyle lstyle = sstyle.EmptyStyle;
 | |
| 
 | |
|                 if (lstyle.LinePattern != LinePattern.None)
 | |
|                 {
 | |
|                     Point[] points = new Point[(lpoints.Count - 1) * 2];
 | |
|                     Point[][] epoints = new Point[lpoints.Count - 1][];
 | |
| 
 | |
|                     for (int i = 0; i < lpoints.Count - 1; i++)
 | |
|                     {
 | |
|                         Point[] pts1 = lpoints[i];
 | |
|                         Point[] pts2 = lpoints[i + 1];
 | |
| 
 | |
|                         epoints[i] = new Point[2];
 | |
| 
 | |
|                         epoints[i][0] = pts1[pts1.Length - 1];
 | |
|                         epoints[i][1] = pts2[0];
 | |
|                     }
 | |
| 
 | |
|                     for (int i = 0; i < points.Length / 2; i++ )
 | |
|                     {
 | |
|                         using (GraphicsPath path = new GraphicsPath())
 | |
|                         {
 | |
|                             path.AddLines(epoints[i]);
 | |
| 
 | |
|                             if ((areaMode & ChartLineAreaDisplayMode.DisplayEmptyLine) == ChartLineAreaDisplayMode.DisplayEmptyLine)
 | |
|                                 RenderAreaBackground(g, chartXy, epoints[i], path, sstyle.EmptyAreaBackground);
 | |
| 
 | |
|                             using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth)))
 | |
|                             {
 | |
|                                 if (lstyle.LinePattern != LinePattern.NotSet)
 | |
|                                     pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | |
| 
 | |
|                                 g.DrawPath(pen, path);
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderAreaBackground
 | |
| 
 | |
|         private void RenderAreaBackground(Graphics g,
 | |
|             ChartXy chartXy, Point[] points, GraphicsPath path, Background background)
 | |
|         {
 | |
|             bool backEmpty = (background == null || background.IsEmpty == true);
 | |
| 
 | |
|             if (backEmpty == true)
 | |
|                 background = new Background(Color.FromArgb(100, DefaultPaletteColor));
 | |
| 
 | |
|             if (background != null && background.IsEmpty == false)
 | |
|             {
 | |
|                 int y = chartXy.ContentBoundsEx.Bottom;
 | |
| 
 | |
|                 if (AreaBaseValue != null)
 | |
|                 {
 | |
|                     ChartAxis axis = _AxisY ?? chartXy.AxisY;
 | |
| 
 | |
|                     y = chartXy.GetDataPointY(axis, AreaBaseValue);
 | |
|                 }
 | |
| 
 | |
|                 using (GraphicsPath path2 = new GraphicsPath())
 | |
|                 {
 | |
|                     path2.AddLine(new Point(points[0].X, y), points[0]);
 | |
|                     path2.AddPath(path, true);
 | |
|                     path2.AddLine(points[points.Length - 1], new Point(points[points.Length - 1].X, y));
 | |
| 
 | |
|                     path2.CloseFigure();
 | |
| 
 | |
|                     Rectangle r = Rectangle.Round(path2.GetBounds());
 | |
| 
 | |
|                     using (Brush br = background.GetBrush(r))
 | |
|                         g.FillPath(br, path2);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (backEmpty == true)
 | |
|                 background.Dispose();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderHighlightPoints
 | |
| 
 | |
|         private void RenderHighlightPoints(Graphics g,
 | |
|             ChartXy chartXy, PointData pd, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             PointMarkerVisualStyle hstyle = GetHighlightStyle(chartXy, sstyle);
 | |
| 
 | |
|             Image marker = GetHighlightImage(g, chartXy, hstyle);
 | |
| 
 | |
|             if (marker != null)
 | |
|             {
 | |
|                 Size size = marker.Size;
 | |
| 
 | |
|                 Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty);
 | |
| 
 | |
|                 for (int i=0; i<pd.Points.Count; i++)
 | |
|                 {
 | |
|                     Point[] pts = pd.Points[i];
 | |
|                     SeriesPoint[] spts = pd.SeriesPoints[i];
 | |
| 
 | |
|                     for (int j=0; j<pts.Length; j++)
 | |
|                     {
 | |
|                         Point ppt = pts[j];
 | |
|                         Point ppc = new Point(ppt.X, ppt.Y);
 | |
|                         Point lppc = new Point(ppt.X + pt.X, ppt.Y + pt.Y);
 | |
| 
 | |
|                         if (chartXy.IsCrosshairSeriesPoint(this, lppc) == true)
 | |
|                             RenderPointMarker(g, chartXy, spts[j], ppc, Size.Empty, marker);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetLineDisplayMode
 | |
| 
 | |
|         private ChartLineDisplayMode GetLineDisplayMode(ChartXy chartXy)
 | |
|         {
 | |
|             ChartLineDisplayMode mode = ChartLineDisplayMode;
 | |
| 
 | |
|             if (mode == ChartLineDisplayMode.NotSet)
 | |
|                 mode = chartXy.ChartLineDisplayMode;
 | |
| 
 | |
|             if (mode == ChartLineDisplayMode.NotSet)
 | |
|                 mode = ChartLineDisplayMode.DisplayLine;
 | |
| 
 | |
|             return (mode);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetAreaDisplayMode
 | |
| 
 | |
|         private ChartLineAreaDisplayMode GetAreaDisplayMode(ChartXy chartXy)
 | |
|         {
 | |
|             ChartLineAreaDisplayMode mode = ChartLineAreaDisplayMode;
 | |
| 
 | |
|             if (mode == ChartLineAreaDisplayMode.NotSet)
 | |
|                 mode = chartXy.ChartLineAreaDisplayMode;
 | |
| 
 | |
|             if (mode == ChartLineAreaDisplayMode.NotSet)
 | |
|                 mode = ChartLineAreaDisplayMode.None;
 | |
| 
 | |
|             return (mode);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderStockPlot
 | |
| 
 | |
|         #region RenderHStockPlot
 | |
| 
 | |
|         private void RenderHStockPlot(ChartRenderInfo renderInfo,
 | |
|             ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             HiLoRenderData rd = new HiLoRenderData(chartXy, AxisX ?? chartXy.AxisX);
 | |
| 
 | |
|             rd.SeriesStyle = sstyle;
 | |
| 
 | |
|             for (int i = 0; i < ssp.Count; i++)
 | |
|             {
 | |
|                 SeriesPoint sp = ssp[i];
 | |
| 
 | |
|                 if (sp.Visible == true)
 | |
|                 {
 | |
|                     rd.Sp = sp;
 | |
|                     rd.Spt = sp.Point[0];
 | |
|                     rd.Index = i;
 | |
| 
 | |
|                     RenderHStock(renderInfo, rd);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderHStock
 | |
| 
 | |
|         private void RenderHStock(ChartRenderInfo renderInfo, HiLoRenderData rd)
 | |
|         {
 | |
|             Graphics g = renderInfo.Graphics;
 | |
|             
 | |
|             rd.Value = GetHStockValues(rd.ChartXy, rd.Sp);
 | |
| 
 | |
|             if (rd.Value[StockHigh] != int.MinValue)
 | |
|             {
 | |
|                 Point pt = rd.ChartXy.GetDataPointEx(this, rd.Sp, 0);
 | |
| 
 | |
|                 Rectangle r = GetHBoundingRect(rd, pt);
 | |
| 
 | |
|                 if (r.IntersectsWith(_RenderBounds) == true)
 | |
|                 {
 | |
|                     int y = pt.Y + BarOffset;
 | |
| 
 | |
|                     rd.Sp.PointSize = new Size(5, BarWidth / 3);
 | |
| 
 | |
|                     switch (HiLoBarType)
 | |
|                     {
 | |
|                         case HiLoBarType.Box:
 | |
|                         case HiLoBarType.Candle:
 | |
|                             RenderHStockBox(g, rd, y);
 | |
|                             break;
 | |
| 
 | |
|                         default:
 | |
|                             RenderHStockHiLo(g, rd, y);
 | |
|                             break;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetHBoundingRect
 | |
| 
 | |
|         private Rectangle GetHBoundingRect(HiLoRenderData rd, Point pt)
 | |
|         {
 | |
|             int x1 = rd.Value[StockHigh];
 | |
|             int x2 = rd.Value[StockLow];
 | |
| 
 | |
|             if (rd.Value[StockOpen] != int.MinValue)
 | |
|             {
 | |
|                 if (rd.Value[StockOpen] > x1)
 | |
|                     x1 = rd.Value[StockOpen];
 | |
| 
 | |
|                 if (rd.Value[StockOpen] < x2)
 | |
|                     x2 = rd.Value[StockOpen];
 | |
|             }
 | |
| 
 | |
|             if (rd.Value[StockClose] != int.MinValue)
 | |
|             {
 | |
|                 if (rd.Value[StockClose] > x1)
 | |
|                     x1 = rd.Value[StockClose];
 | |
| 
 | |
|                 if (rd.Value[StockClose] < x2)
 | |
|                     x2 = rd.Value[StockClose];
 | |
|             }
 | |
| 
 | |
|             int y = pt.Y + BarOffset - BarWidth / 2;
 | |
| 
 | |
|             return (new Rectangle(x2, y, x1 - x2, BarWidth));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderHStockBox
 | |
| 
 | |
|         private void RenderHStockBox(Graphics g, HiLoRenderData rd, int y)
 | |
|         {
 | |
|             int x1 = rd.Value[StockClose];
 | |
|             int x2 = rd.Value[StockOpen];
 | |
| 
 | |
|             if (rd.Value[StockOpen] != int.MinValue && rd.Value[StockClose] != int.MinValue)
 | |
|             {
 | |
|                 if (rd.Value[StockOpen] < rd.Value[StockClose])
 | |
|                 {
 | |
|                     x1 = rd.Value[StockOpen];
 | |
|                     x2 = rd.Value[StockClose];
 | |
|                 }
 | |
| 
 | |
|                 if (rd.Value[StockLow] > x1)
 | |
|                     rd.Value[StockLow] = x1;
 | |
| 
 | |
|                 if (rd.Value[StockHigh] < x2)
 | |
|                     rd.Value[StockHigh] = x2;
 | |
| 
 | |
|                 rd.IsAlternate = (rd.Value[StockOpen] > rd.Value[StockClose]);
 | |
| 
 | |
|                 RenderHStockBoxWhisker(g, rd,
 | |
|                     rd.Value[StockLow], x1, y, HiLoBarSegment.LowWhisker);
 | |
| 
 | |
|                 RenderHStockBoxWhisker(g, rd,
 | |
|                     x2, rd.Value[StockHigh], y, HiLoBarSegment.HighWhisker);
 | |
| 
 | |
|                 RenderHStockBoxOpenClose(g, rd, x1, x2, y);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 int x = (x1 != int.MinValue) ? x1 : x2;
 | |
| 
 | |
|                 if (x != int.MinValue)
 | |
|                 {
 | |
|                     if (x > rd.Value[StockHigh])
 | |
|                         rd.Value[StockHigh] = x;
 | |
| 
 | |
|                     if (x < rd.Value[StockLow])
 | |
|                         rd.Value[StockLow] = x;
 | |
|                 }
 | |
| 
 | |
|                 if (x < rd.Value[StockHigh] && x > rd.Value[StockLow])
 | |
|                 {
 | |
|                     RenderHStockBoxWhisker(g, rd, x, rd.Value[StockHigh], y, HiLoBarSegment.HighWhisker);
 | |
|                     RenderHStockBoxWhisker(g, rd, rd.Value[StockLow], x, y, HiLoBarSegment.LowWhisker);
 | |
| 
 | |
|                     RenderHStockBoxOpenClose(g, rd, x, x, y);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     RenderHStockBoxWhisker(g, rd,
 | |
|                         rd.Value[StockLow], rd.Value[StockHigh], y, HiLoBarSegment.CenterLine);
 | |
| 
 | |
|                     if (x != int.MinValue)
 | |
|                         RenderHStockBoxOpenClose(g, rd, x, x, y);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderHStockBoxWhisker
 | |
| 
 | |
|         private void RenderHStockBoxWhisker(Graphics g,
 | |
|             HiLoRenderData rd, int x1, int x2, int y, HiLoBarSegment segment)
 | |
|         {
 | |
|             if (x2 > x1)
 | |
|             {
 | |
|                 Point pt1 = new Point(x1, y);
 | |
|                 Point pt2 = new Point(x2 + 1, y);
 | |
| 
 | |
|                 RenderBoxWhisker(g, rd, pt1, pt2, segment);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderHStockBoxOpenClose
 | |
| 
 | |
|         private void RenderHStockBoxOpenClose(
 | |
|             Graphics g, HiLoRenderData rd, int x1, int x2, int y)
 | |
|         {
 | |
|             if (x2 == x1)
 | |
|             {
 | |
|                 x1--;
 | |
|                 x2++;
 | |
|             }
 | |
| 
 | |
|             x2++;
 | |
| 
 | |
|             Point pt1 = new Point(x1, y - BarWidth / 2);
 | |
|             Point pt2 = new Point(x2, pt1.Y + BarWidth);
 | |
| 
 | |
|             int lw = RenderStockBox(g, rd, pt1, pt2);
 | |
| 
 | |
|             Rectangle r = new Rectangle(pt1.X, pt1.Y, pt2.X - pt1.X, pt2.Y - pt1.Y);
 | |
| 
 | |
|             if (r.Width > 0 && r.Height > 0)
 | |
|             {
 | |
|                 if (GetBarShading(rd.ChartXy) == true)
 | |
|                 {
 | |
|                     ChartControl chartControl = ChartControl;
 | |
| 
 | |
|                     if (chartControl.DoPreRenderSeriesHiloBarEvent(
 | |
|                         g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.BarShading) == false)
 | |
|                     {
 | |
|                         RenderHBarShading(g, r, r, BarSegment.Left);
 | |
| 
 | |
|                         chartControl.DoPostRenderSeriesHiLoBarEvent(
 | |
|                             g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.BarShading);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderHStockBoxMedian
 | |
| 
 | |
|         private void RenderHStockBoxMedian(
 | |
|             Graphics g, HiLoRenderData rd, int y, int x1, int x2)
 | |
|         {
 | |
|             if (rd.Value.Length > StockMedian)
 | |
|             {
 | |
|                 int x3 = rd.Value[StockMedian];
 | |
| 
 | |
|                 if (x3 > x1 && x3 < x2)
 | |
|                 {
 | |
|                     Point pt1 = new Point(x3, y);
 | |
|                     Point pt2 = new Point(x3, y + BarWidth - 1);
 | |
| 
 | |
|                      ChartControl chartControl = ChartControl;
 | |
| 
 | |
|                      if (chartControl.DoPreRenderSeriesHiloBarEvent(
 | |
|                          g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.MedianLine) == false)
 | |
|                      {
 | |
|                          ChartLineVisualStyle lstyle = GetSegLineStyle(rd, HiLoBarSegment.MedianLine);
 | |
| 
 | |
|                          if (lstyle.LinePattern != LinePattern.None)
 | |
|                          {
 | |
|                              using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth)))
 | |
|                              {
 | |
|                                  if (lstyle.LinePattern != LinePattern.NotSet)
 | |
|                                      pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | |
| 
 | |
|                                  if (lstyle.LineWidth > 1)
 | |
|                                      pt2.Y++;
 | |
| 
 | |
|                                  g.DrawLine(pen, pt1, pt2);
 | |
|                              }
 | |
|                          }
 | |
| 
 | |
|                          chartControl.DoPostRenderSeriesHiLoBarEvent(
 | |
|                             g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.MedianLine);
 | |
|                      }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderHStockHiLo
 | |
| 
 | |
|         private void RenderHStockHiLo(Graphics g, HiLoRenderData rd, int y)
 | |
|         {
 | |
|             int x1, x2, x3, x4;
 | |
|             NormalizeHiLoValues(rd, out x1, out x2, out x3, out x4);
 | |
| 
 | |
|             ChartLineVisualStyle ostyle, cstyle;
 | |
|             NormalizeHiLoStyles(rd, out ostyle, out cstyle);
 | |
| 
 | |
|             if (rd.Value[StockOpen] != int.MinValue)
 | |
|             {
 | |
|                 Point pt1 = new Point(x2, y - BarWidth / 2);
 | |
|                 Point pt2 = new Point(pt1.X, pt1.Y + BarWidth / 2);
 | |
| 
 | |
|                 RenderHiLoWhisker(g, rd, pt1, pt2, ostyle, HiLoBarSegment.OpenWhisker);
 | |
|             }
 | |
| 
 | |
|             if (rd.Value[StockClose] != int.MinValue)
 | |
|             {
 | |
|                 Point pt1 = new Point(x3, y);
 | |
|                 Point pt2 = new Point(pt1.X, pt1.Y + BarWidth / 2 + 1);
 | |
| 
 | |
|                 RenderHiLoWhisker(g, rd, pt1, pt2, cstyle, HiLoBarSegment.CloseWhisker);
 | |
|             }
 | |
| 
 | |
|             if (rd.IsAlternate == false)
 | |
|             {
 | |
|                 int x = x2;
 | |
|                 x2 = x3;
 | |
|                 x3 = x;
 | |
| 
 | |
|                 ChartLineVisualStyle style = ostyle;
 | |
|                 ostyle = cstyle;
 | |
|                 cstyle = ostyle;
 | |
|             }
 | |
| 
 | |
|             if ((rd.IsAlternate == false && _RenderFullDefRange == true) ||
 | |
|                 (rd.IsAlternate == true && _RenderFullAltRange == true))
 | |
|             {
 | |
|                 RenderHiLoRange(g, rd,
 | |
|                     new Point(x1, y), new Point(x4, y), HiLoBarSegment.FullRange);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 // Open value either not specified or is
 | |
|                 // set to High value.
 | |
| 
 | |
|                 if (x1 == x2 && x3 != x4)
 | |
|                     x2 = x3;
 | |
| 
 | |
|                 if (x2 < x1)
 | |
|                 {
 | |
|                     int n = (ostyle != null) ? (ostyle.LineWidth + 1) / 2 : 1;
 | |
| 
 | |
|                     RenderHiLoRange(g, rd,
 | |
|                         new Point(x1, y), new Point(x2 + n, y), HiLoBarSegment.HighWhisker);
 | |
|                 }
 | |
| 
 | |
|                 if (x3 > x4)
 | |
|                 {
 | |
|                     int n = 1;
 | |
| 
 | |
|                     // Low segment extends to the top.
 | |
| 
 | |
|                     if (x3 == x1)
 | |
|                         n = (cstyle.LineWidth + 1) / 2;
 | |
| 
 | |
|                     // We have a Center segment.
 | |
| 
 | |
|                     else if (x3 != x2)
 | |
|                         n = -cstyle.LineWidth / 2;
 | |
| 
 | |
|                     RenderHiLoRange(g, rd,
 | |
|                         new Point(x3 + n, y), new Point(x4, y), HiLoBarSegment.LowWhisker);
 | |
|                 }
 | |
| 
 | |
|                 if (x2 > x3 || (x1 == x2 && x3 == x4))
 | |
|                 {
 | |
|                     ChartLineVisualStyle y2Style = (x2 == rd.Value[StockOpen]) ? ostyle : cstyle;
 | |
|                     ChartLineVisualStyle y3Style = (x3 == rd.Value[StockOpen]) ? ostyle : cstyle;
 | |
| 
 | |
|                     if (y2Style != null)
 | |
|                         x2 += ((y2Style.LineWidth + 1) / 2 );
 | |
| 
 | |
|                     if (y3Style != null)
 | |
|                         x3 -= (y3Style.LineWidth / 2);
 | |
| 
 | |
|                     RenderHiLoRange(g, rd,
 | |
|                         new Point(x2, y), new Point(x3, y), HiLoBarSegment.CenterLine);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderVStockPlot
 | |
| 
 | |
|         private void RenderVStockPlot(ChartRenderInfo renderInfo,
 | |
|             ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             HiLoRenderData rd = new HiLoRenderData(chartXy, AxisY ?? chartXy.AxisY);
 | |
| 
 | |
|             rd.SeriesStyle = sstyle;
 | |
| 
 | |
|             for (int i = 0; i < ssp.Count; i++)
 | |
|             {
 | |
|                 SeriesPoint sp = ssp[i];
 | |
| 
 | |
|                 if (sp.Visible == true)
 | |
|                 {
 | |
|                     if (sp.ValueY.Length > 0)
 | |
|                     {
 | |
|                         rd.Sp = sp;
 | |
|                         rd.Spt = sp.Point[0];
 | |
|                         rd.Index = i;
 | |
| 
 | |
|                         rd.IsAlternate = false;
 | |
| 
 | |
|                         RenderVStock(renderInfo, rd);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderVStock
 | |
| 
 | |
|         private void RenderVStock(ChartRenderInfo renderInfo, HiLoRenderData rd)
 | |
|         {
 | |
|             Graphics g = renderInfo.Graphics;
 | |
| 
 | |
|             rd.Value = GetVStockValues(rd.ChartXy, rd.Sp);
 | |
| 
 | |
|             if (rd.Value[StockHigh] != int.MinValue)
 | |
|             {
 | |
|                 Point pt = rd.ChartXy.GetDataPointEx(this, rd.Sp, 0);
 | |
| 
 | |
|                 Rectangle r = GetVBoundingRect(rd, pt);
 | |
| 
 | |
|                 if (r.IntersectsWith(_RenderBounds) == true)
 | |
|                 {
 | |
|                     int x = pt.X + BarOffset;
 | |
| 
 | |
|                     rd.Sp.PointSize = new Size(BarWidth/3, 5);
 | |
| 
 | |
|                     switch (HiLoBarType)
 | |
|                     {
 | |
|                         case HiLoBarType.Box:
 | |
|                         case HiLoBarType.Candle:
 | |
|                             RenderVStockBox(g, rd, x);
 | |
|                             break;
 | |
| 
 | |
|                         default:
 | |
|                             RenderVStockHiLo(g, rd, x);
 | |
|                             break;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetVBoundingRect
 | |
| 
 | |
|         private Rectangle GetVBoundingRect(HiLoRenderData rd, Point pt)
 | |
|         {
 | |
|             int y1 = rd.Value[StockHigh];
 | |
|             int y2 = rd.Value[StockLow];
 | |
| 
 | |
|             if (rd.Value[StockOpen] != int.MinValue)
 | |
|             {
 | |
|                 if (y1 > rd.Value[StockOpen])
 | |
|                     y1 = rd.Value[StockOpen];
 | |
| 
 | |
|                 if (y2 < rd.Value[StockOpen])
 | |
|                     y2 = rd.Value[StockOpen];
 | |
|             }
 | |
| 
 | |
|             if (rd.Value[StockClose] != int.MinValue)
 | |
|             {
 | |
|                 if (y1 > rd.Value[StockClose])
 | |
|                     y1 = rd.Value[StockClose];
 | |
| 
 | |
|                 if (y2 < rd.Value[StockClose])
 | |
|                     y2 = rd.Value[StockClose];
 | |
|             }
 | |
| 
 | |
|             int x = pt.X + BarOffset - BarWidth / 2;
 | |
| 
 | |
|             return (new Rectangle(x, y1, BarWidth, y2 - y1));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderVStockBox
 | |
| 
 | |
|         private void RenderVStockBox(Graphics g, HiLoRenderData rd, int x)
 | |
|         {
 | |
|             int y1 = rd.Value[StockOpen];
 | |
|             int y2 = rd.Value[StockClose];
 | |
| 
 | |
|             if (rd.Value[StockOpen] != int.MinValue && rd.Value[StockClose] != int.MinValue)
 | |
|             {
 | |
|                 if (rd.Value[StockOpen] > rd.Value[StockClose])
 | |
|                 {
 | |
|                     y1 = rd.Value[StockClose];
 | |
|                     y2 = rd.Value[StockOpen];
 | |
|                 }
 | |
| 
 | |
|                 if (rd.Value[StockHigh] > y1)
 | |
|                     rd.Value[StockHigh] = y1;
 | |
| 
 | |
|                 if (rd.Value[StockLow] < y2)
 | |
|                     rd.Value[StockLow] = y2;
 | |
| 
 | |
|                 rd.IsAlternate = (rd.Value[StockOpen] < rd.Value[StockClose]);
 | |
| 
 | |
|                 RenderVStockBoxWhisker(g, rd, x,
 | |
|                     rd.Value[StockHigh], y1, HiLoBarSegment.HighWhisker);
 | |
| 
 | |
|                 RenderVStockBoxWhisker(g, rd, x,
 | |
|                     y2, rd.Value[StockLow], HiLoBarSegment.LowWhisker);
 | |
| 
 | |
|                 RenderVStockBoxOpenClose(g, rd, x, y1, y2);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 int y = (y1 != int.MinValue) ? y1 : y2;
 | |
| 
 | |
|                 if (y != int.MinValue)
 | |
|                 {
 | |
|                     if (y < rd.Value[StockHigh])
 | |
|                         rd.Value[StockHigh] = y;
 | |
| 
 | |
|                     if (y > rd.Value[StockLow])
 | |
|                         rd.Value[StockLow] = y;
 | |
|                 }
 | |
| 
 | |
|                 if (y > rd.Value[StockHigh] && y < rd.Value[StockLow])
 | |
|                 {
 | |
|                     RenderVStockBoxWhisker(g, rd, x, rd.Value[StockHigh], y, HiLoBarSegment.HighWhisker);
 | |
|                     RenderVStockBoxWhisker(g, rd, x, y, rd.Value[StockLow], HiLoBarSegment.LowWhisker);
 | |
| 
 | |
|                     RenderVStockBoxOpenClose(g, rd, x, y, y);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     RenderVStockBoxWhisker(g, rd, x, 
 | |
|                         rd.Value[StockHigh], rd.Value[StockLow], HiLoBarSegment.CenterLine);
 | |
| 
 | |
|                     if (y != int.MinValue)
 | |
|                         RenderVStockBoxOpenClose(g, rd, x, y, y);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderVStockBoxWhisker
 | |
| 
 | |
|         private void RenderVStockBoxWhisker(Graphics g, 
 | |
|             HiLoRenderData rd, int x, int y1, int y2, HiLoBarSegment segment)
 | |
|         {
 | |
|             if (y2 > y1)
 | |
|             {
 | |
|                 Point pt1 = new Point(x, y1);
 | |
|                 Point pt2 = new Point(x, y2 + 1);
 | |
| 
 | |
|                 RenderBoxWhisker(g, rd, pt1, pt2, segment);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderVStockBoxOpenClose
 | |
| 
 | |
|         private void RenderVStockBoxOpenClose(
 | |
|             Graphics g, HiLoRenderData rd, int x, int y1, int y2)
 | |
|         {
 | |
|             if (y2 == y1)
 | |
|             {
 | |
|                 y1--;
 | |
|                 y2++;
 | |
|             }
 | |
| 
 | |
|             y2++;
 | |
| 
 | |
|             Point pt1 = new Point(x - BarWidth / 2, y1);
 | |
|             Point pt2 = new Point(pt1.X + BarWidth, y2);
 | |
| 
 | |
|             int lw = RenderStockBox(g, rd, pt1, pt2);
 | |
| 
 | |
|             Rectangle r = new Rectangle(pt1.X, pt1.Y, pt2.X - pt1.X, pt2.Y - pt1.Y);
 | |
| 
 | |
|             if (r.Width > 0 && r.Height > 0)
 | |
|             {
 | |
|                 if (GetBarShading(rd.ChartXy) == true)
 | |
|                 {
 | |
|                     ChartControl chartControl = ChartControl;
 | |
| 
 | |
|                     if (chartControl.DoPreRenderSeriesHiloBarEvent(
 | |
|                         g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.BarShading) == false)
 | |
|                     {
 | |
| 
 | |
|                         RenderVBarShading(g, r, r, BarSegment.Top);
 | |
| 
 | |
|                         chartControl.DoPostRenderSeriesHiLoBarEvent(
 | |
|                             g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.BarShading);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderVStockBoxMedian
 | |
| 
 | |
|         private void RenderVStockBoxMedian(
 | |
|             Graphics g, HiLoRenderData rd, int x, int y1, int y2)
 | |
|         {
 | |
|             if (rd.Value.Length > StockMedian)
 | |
|             {
 | |
|                 int y3 = rd.Value[StockMedian];
 | |
| 
 | |
|                 if (y3 > y1 && y3 < y2)
 | |
|                 {
 | |
|                     Point pt1 = new Point(x, y3);
 | |
|                     Point pt2 = new Point(x + BarWidth - 1, y3);
 | |
| 
 | |
|                     ChartControl chartControl = ChartControl;
 | |
| 
 | |
|                     if (chartControl.DoPreRenderSeriesHiloBarEvent(
 | |
|                         g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.MedianLine) == false)
 | |
|                     {
 | |
|                         ChartLineVisualStyle lstyle = GetSegLineStyle(rd, HiLoBarSegment.MedianLine);
 | |
| 
 | |
|                         if (lstyle.LinePattern != LinePattern.None)
 | |
|                         {
 | |
|                             using (Pen pen = new Pen(lstyle.LineColor, lstyle.LineWidth))
 | |
|                             {
 | |
|                                 if (lstyle.LinePattern != LinePattern.NotSet)
 | |
|                                     pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | |
| 
 | |
|                                 if (lstyle.LineWidth > 1)
 | |
|                                     pt2.X++;
 | |
| 
 | |
|                                 g.DrawLine(pen, pt1, pt2);
 | |
|                             }
 | |
|                         }
 | |
| 
 | |
|                         chartControl.DoPostRenderSeriesHiLoBarEvent(
 | |
|                             g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.MedianLine);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderVStockHiLo
 | |
| 
 | |
|         private void RenderVStockHiLo(Graphics g, HiLoRenderData rd, int x)
 | |
|         {
 | |
|             int y1, y2, y3, y4;
 | |
|             NormalizeHiLoValues(rd, out y1, out y2, out y3, out y4);
 | |
| 
 | |
|             ChartLineVisualStyle ostyle, cstyle;
 | |
|             NormalizeHiLoStyles(rd, out ostyle, out cstyle);
 | |
| 
 | |
|             if (rd.Value[StockOpen] != int.MinValue)
 | |
|             {
 | |
|                 Point pt1 = new Point(x - BarWidth / 2, y2);
 | |
|                 Point pt2 = new Point(pt1.X + BarWidth / 2, pt1.Y);
 | |
| 
 | |
|                 RenderHiLoWhisker(g, rd, pt1, pt2, ostyle, HiLoBarSegment.OpenWhisker);
 | |
|             }
 | |
| 
 | |
|             if (rd.Value[StockClose] != int.MinValue)
 | |
|             {
 | |
|                 Point pt1 = new Point(x + 1, y3);
 | |
|                 Point pt2 = new Point(pt1.X + BarWidth / 2, pt1.Y);
 | |
| 
 | |
|                 RenderHiLoWhisker(g, rd, pt1, pt2, cstyle, HiLoBarSegment.CloseWhisker);
 | |
|             }
 | |
| 
 | |
|             NormalizeHiLoDir(rd, ref y2, ref y3, ref ostyle, ref cstyle);
 | |
| 
 | |
|             if ((rd.IsAlternate == false && _RenderFullDefRange == true) ||
 | |
|                 (rd.IsAlternate == true && _RenderFullAltRange == true))
 | |
|             {
 | |
|                 RenderHiLoRange(g, rd,
 | |
|                     new Point(x, y1), new Point(x, y4), HiLoBarSegment.FullRange);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (y1 == y2 && y3 != y4)
 | |
|                     y2 = y3;
 | |
| 
 | |
|                 // High segment
 | |
| 
 | |
|                 if (y2 > y1)
 | |
|                 {
 | |
|                     int n = (ostyle != null) ? ostyle.LineWidth / 2 : 0;
 | |
| 
 | |
|                     RenderHiLoRange(g, rd,
 | |
|                         new Point(x, y1), new Point(x, y2 - n), HiLoBarSegment.HighWhisker);
 | |
|                 }
 | |
| 
 | |
|                 // Low segment
 | |
| 
 | |
|                 if (y3 < y4)
 | |
|                 {
 | |
|                     int n = 0;
 | |
| 
 | |
|                     if (y3 == y1)
 | |
|                         n = -cstyle.LineWidth / 2;
 | |
| 
 | |
|                     else if (y3 != y2)
 | |
|                         n = (cstyle.LineWidth + 1) / 2;
 | |
| 
 | |
|                     RenderHiLoRange(g, rd,
 | |
|                         new Point(x, y3 + n), new Point(x, y4), HiLoBarSegment.LowWhisker);
 | |
|                 }
 | |
| 
 | |
|                 // Center segment.
 | |
| 
 | |
|                 if (y2 < y3 || (y1 == y2 && y3 == y4))
 | |
|                 {
 | |
|                     ChartLineVisualStyle y2Style = (y2 == rd.Value[StockOpen]) ? ostyle : cstyle;
 | |
|                     ChartLineVisualStyle y3Style = (y3 == rd.Value[StockOpen]) ? ostyle : cstyle;
 | |
| 
 | |
|                     if (y2Style != null)
 | |
|                         y2 -= (y2Style.LineWidth / 2);
 | |
| 
 | |
|                     if (y3Style != null)
 | |
|                         y3 += ((y3Style.LineWidth + 1) / 2);
 | |
| 
 | |
|                     RenderHiLoRange(g, rd,
 | |
|                         new Point(x, y2), new Point(x, y3), HiLoBarSegment.CenterLine);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetHStockValues
 | |
| 
 | |
|         internal int[] GetHStockValues(ChartXy chartXy, SeriesPoint sp)
 | |
|         {
 | |
|             ChartAxis axis = AxisX ?? chartXy.AxisX;
 | |
| 
 | |
|             int[] values = new int[Math.Max(4, sp.ValueY.Length)];
 | |
| 
 | |
|             for (int i = 0; i < sp.ValueY.Length; i++)
 | |
|                 values[i] = chartXy.GetDataPointX(axis, sp.ValueY[i]);
 | |
| 
 | |
|             NormalizeStockValues(sp, values);
 | |
| 
 | |
|             return (values);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetVStockValues
 | |
| 
 | |
|         internal int[] GetVStockValues(ChartXy chartXy, SeriesPoint sp)
 | |
|         {
 | |
|             ChartAxis axis = AxisY ?? chartXy.AxisY;
 | |
| 
 | |
|             int[] values = new int[Math.Max(4, sp.ValueY.Length)];
 | |
| 
 | |
|             for (int i = 0; i < sp.ValueY.Length; i++)
 | |
|                 values[i] = chartXy.GetDataPointY(axis, sp.ValueY[i]);
 | |
| 
 | |
|             NormalizeStockValues(sp, values);
 | |
| 
 | |
|             return (values);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region NormalizeStockValues
 | |
| 
 | |
|         private void NormalizeStockValues(SeriesPoint sp, int[] values)
 | |
|         {
 | |
|             for (int i = sp.ValueY.Length; i < values.Length; i++)
 | |
|                 values[i] = int.MinValue;
 | |
| 
 | |
|             if (values[StockLow] == int.MinValue)
 | |
|                 values[StockLow] = values[StockHigh];
 | |
| 
 | |
|             if ((IsRotated == true && values[StockLow] > values[StockHigh]) ||
 | |
|                 (IsRotated == false && values[StockLow] < values[StockHigh]))
 | |
|             {
 | |
|                 int temp = values[StockLow];
 | |
|                 values[StockLow] = values[StockHigh];
 | |
|                 values[StockHigh] = temp;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region NormalizeHiLoValues
 | |
| 
 | |
|         private void NormalizeHiLoValues(
 | |
|             HiLoRenderData rd, out int v1, out int v2, out int v3, out int v4)
 | |
|         {
 | |
|             v1 = rd.Value[StockHigh];
 | |
|             v4 = rd.Value[StockLow];
 | |
| 
 | |
|             v2 = (rd.Value[StockOpen] != int.MinValue) ? rd.Value[StockOpen] : v1;
 | |
|             v3 = (rd.Value[StockClose] != int.MinValue) ? rd.Value[StockClose] : v4;
 | |
| 
 | |
|             if (v1 > v4)
 | |
|             {
 | |
|                 if (v1 <v2)
 | |
|                     v1 = v2;
 | |
| 
 | |
|                 if (v4 > v3)
 | |
|                     v4 = v3;
 | |
| 
 | |
|                 rd.IsAlternate = (v2 > v3);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (v1 > v2)
 | |
|                     v1 = v2;
 | |
| 
 | |
|                 if (v4 < v3)
 | |
|                     v4 = v3;
 | |
| 
 | |
|                 rd.IsAlternate = (v2 < v3);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region NormalizeHiLoDir
 | |
| 
 | |
|         private void NormalizeHiLoDir(HiLoRenderData rd,
 | |
|             ref int v1, ref int v2, ref ChartLineVisualStyle style1, ref ChartLineVisualStyle style2)
 | |
|         {
 | |
|             if (rd.IsAlternate == false)
 | |
|             {
 | |
|                 int y = v1;
 | |
|                 v1 = v2;
 | |
|                 v2 = y;
 | |
| 
 | |
|                 ChartLineVisualStyle style = style1;
 | |
|                 style1 = style2;
 | |
|                 style2 = style1;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region NormalizeHiLoStyles
 | |
| 
 | |
|         private void NormalizeHiLoStyles(HiLoRenderData rd,
 | |
|             out ChartLineVisualStyle ostyle, out ChartLineVisualStyle cstyle)
 | |
|         {
 | |
|             ostyle = (rd.Value[StockOpen] != int.MinValue) ? GetSegLineStyle(rd, HiLoBarSegment.OpenWhisker) : null;
 | |
|             cstyle = (rd.Value[StockClose] != int.MinValue) ? GetSegLineStyle(rd, HiLoBarSegment.CloseWhisker) : null;
 | |
| 
 | |
|             rd.EndDelta = GetHiLoEndDelta(ostyle, cstyle);
 | |
|         }
 | |
| 
 | |
|         #region GetHiLoEndDelta
 | |
| 
 | |
|         private int GetHiLoEndDelta(
 | |
|             ChartLineVisualStyle ostyle, ChartLineVisualStyle cstyle)
 | |
|         {
 | |
|             int delta = 0;
 | |
| 
 | |
|             if (ostyle != null)
 | |
|             {
 | |
|                 if (ostyle.LineWidth > 1)
 | |
|                 {
 | |
|                     if (ostyle.LinePattern != LinePattern.None)
 | |
|                         delta = (ostyle.LineWidth + 1) / 2;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (cstyle != null)
 | |
|             {
 | |
|                 if (cstyle.LineWidth > 1)
 | |
|                 {
 | |
|                     if (cstyle.LinePattern != LinePattern.None)
 | |
|                         delta = Math.Max(delta, (cstyle.LineWidth + 1) / 2);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (delta);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderBoxWhisker
 | |
| 
 | |
|         private void RenderBoxWhisker(Graphics g,
 | |
|             HiLoRenderData rd, Point pt1, Point pt2, HiLoBarSegment segment)
 | |
|         {
 | |
|             ChartXy chartXy = rd.ChartXy;
 | |
|             ChartControl chartControl = ChartControl;
 | |
| 
 | |
|             SmoothingMode sm = g.SmoothingMode;
 | |
|             g.SmoothingMode = SmoothingMode.None;
 | |
| 
 | |
|             if (chartControl.DoPreRenderSeriesHiloBarEvent(g, chartXy, this, rd, pt1, pt2, segment) == false)
 | |
|             {
 | |
|                 ChartLineVisualStyle lstyle = GetSegLineStyle(rd, segment);
 | |
| 
 | |
|                 if (lstyle.LinePattern != LinePattern.None)
 | |
|                 {
 | |
|                     using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth)))
 | |
|                     {
 | |
|                         if (lstyle.LinePattern != LinePattern.NotSet)
 | |
|                             pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | |
| 
 | |
|                         Point pt3 = pt2;
 | |
| 
 | |
|                         if (lstyle.LineWidth == 1)
 | |
|                         {
 | |
|                             if (pt1.X == pt2.X)
 | |
|                                 pt3.Y--;
 | |
|                             else
 | |
|                                 pt3.X--;
 | |
|                         }
 | |
| 
 | |
|                         g.DrawLine(pen, pt1, pt3);
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 chartControl.DoPostRenderSeriesHiLoBarEvent(g, chartXy, this, rd, pt1, pt2, segment);
 | |
|             }
 | |
| 
 | |
|             if (rd.SeriesStyle.HiLoBarVisualStyle.ShowWhiskerCaps == Tbool.True)
 | |
|                 RenderWhiskerCap(g, rd, pt1, pt2, segment);
 | |
| 
 | |
|             g.SmoothingMode = sm;
 | |
|         }
 | |
| 
 | |
|         #region RenderWhiskerCap
 | |
| 
 | |
|         private void RenderWhiskerCap(Graphics g,
 | |
|             HiLoRenderData rd, Point pt1, Point pt2, HiLoBarSegment segment)
 | |
|         {
 | |
|             if (segment == HiLoBarSegment.HighWhisker || segment == HiLoBarSegment.LowWhisker)
 | |
|             {
 | |
|                 HiLoBarSegment capSegment = (segment == HiLoBarSegment.HighWhisker)
 | |
|                     ? HiLoBarSegment.HighWhiskerCap : HiLoBarSegment.LowWhiskerCap;
 | |
| 
 | |
|                 GetWhiskerCapPoints(segment, ref pt1, ref pt2);
 | |
| 
 | |
|                 ChartControl chartControl = ChartControl;
 | |
| 
 | |
|                 if (chartControl.DoPreRenderSeriesHiloBarEvent(
 | |
|                     g, rd.ChartXy, this, rd, pt1, pt2, capSegment) == false)
 | |
|                 {
 | |
|                     ChartLineVisualStyle lstyle = GetSegLineStyle(rd, capSegment);
 | |
| 
 | |
|                     if (lstyle.LinePattern != LinePattern.None)
 | |
|                     {
 | |
|                         using (Pen pen = new Pen(lstyle.LineColor, lstyle.LineWidth))
 | |
|                         {
 | |
|                             if (lstyle.LinePattern != LinePattern.NotSet)
 | |
|                                 pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | |
| 
 | |
|                             if (lstyle.LineWidth == 1)
 | |
|                             {
 | |
|                                 if (pt1.X == pt2.X)
 | |
|                                     pt2.Y--;
 | |
|                                 else
 | |
|                                     pt2.X--;
 | |
|                             }
 | |
| 
 | |
|                             g.DrawLine(pen, pt1, pt2);
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     chartControl.DoPostRenderSeriesHiLoBarEvent(
 | |
|                         g, rd.ChartXy, this, rd, pt1, pt2, capSegment);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetWhiskerCapPoints
 | |
| 
 | |
|         private void GetWhiskerCapPoints(
 | |
|             HiLoBarSegment segment, ref Point pt1, ref Point pt2)
 | |
|         {
 | |
|             int n = BarWidth / 3;
 | |
| 
 | |
|             switch (segment)
 | |
|             {
 | |
|                 case HiLoBarSegment.HighWhisker:
 | |
|                     if (pt1.X == pt2.X)
 | |
|                     {
 | |
|                         pt1.X -= n;
 | |
|                         pt2.X += n + 1;
 | |
|                         pt2.Y = pt1.Y;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         pt1.Y -= n;
 | |
|                         pt2.Y += n + 1;
 | |
|                         pt1.X = pt2.X;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case HiLoBarSegment.LowWhisker:
 | |
|                     if (pt1.X == pt2.X)
 | |
|                     {
 | |
|                         pt1.X -= n;
 | |
|                         pt2.X += n + 1;
 | |
|                         pt1.Y = pt2.Y;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         pt1.Y -= n;
 | |
|                         pt2.Y += n + 1;
 | |
|                         pt2.X = pt1.X;
 | |
|                     }
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderStockBox
 | |
| 
 | |
|         private int RenderStockBox(
 | |
|             Graphics g, HiLoRenderData rd, Point pt1, Point pt2)
 | |
|         {
 | |
|             int lineWidth = 0;
 | |
| 
 | |
|             Rectangle r = new Rectangle(pt1.X, pt1.Y, pt2.X - pt1.X, pt2.Y - pt1.Y);
 | |
| 
 | |
|             if (r.Width > 0 && r.Height > 0)
 | |
|             {
 | |
|                 ChartXy chartXy = rd.ChartXy;
 | |
|                 ChartControl chartControl = ChartControl;
 | |
| 
 | |
|                 SmoothingMode sm = g.SmoothingMode;
 | |
|                 g.SmoothingMode = SmoothingMode.None;
 | |
| 
 | |
|                 if (chartControl.DoPreRenderSeriesHiloBarEvent(
 | |
|                     g, chartXy, this, rd, pt1, pt2, HiLoBarSegment.Box) == false)
 | |
|                 {
 | |
|                     if (HiLoBarType == HiLoBarType.Box)
 | |
|                         RenderStockBoxBackground(g, rd, r);
 | |
|                     else
 | |
|                         RenderStockCandleBackground(g, rd, r);
 | |
| 
 | |
|                     ChartLineVisualStyle lstyle = rd.DefaultStyle.BoxBorder;
 | |
| 
 | |
|                     if (CanUseAlternateSegmentStyle(rd) == true)
 | |
|                     {
 | |
|                         if (rd.IsAlternate == true && rd.AlternateStyle.BoxBorder.IsEmpty == false)
 | |
|                             lstyle = rd.AlternateStyle.BoxBorder;
 | |
|                     }
 | |
| 
 | |
|                     if (lstyle.LinePattern != LinePattern.None)
 | |
|                     {
 | |
|                         using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth)))
 | |
|                         {
 | |
|                             lineWidth = (int)pen.Width;
 | |
| 
 | |
|                             if (lstyle.LinePattern != LinePattern.NotSet)
 | |
|                                 pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | |
| 
 | |
|                             if (pt1.X == pt2.X || pt1.Y == pt2.Y)
 | |
|                             {
 | |
|                                 g.DrawLine(pen, pt1, pt2);
 | |
|                             }
 | |
|                             else
 | |
|                             {
 | |
|                                 pen.Alignment = PenAlignment.Inset;
 | |
| 
 | |
|                                 if (lstyle.LineWidth == 1)
 | |
|                                 {
 | |
|                                     r.Width--;
 | |
|                                     r.Height--;
 | |
|                                 }
 | |
| 
 | |
|                                 if (r.Width > 0 && r.Height > 0)
 | |
|                                     g.DrawRectangle(pen, r);
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     chartControl.DoPostRenderSeriesHiLoBarEvent(
 | |
|                         g, chartXy, this, rd, pt1, pt2, HiLoBarSegment.Box);
 | |
|                 }
 | |
| 
 | |
|                 if (ShowHiLoBarMedianLines == true)
 | |
|                 {
 | |
|                     if (IsRotated == false)
 | |
|                         RenderVStockBoxMedian(g, rd, r.X, r.Y, r.Bottom);
 | |
|                     else
 | |
|                         RenderHStockBoxMedian(g, rd, r.Y, r.X, r.Right);
 | |
|                 }
 | |
| 
 | |
|                 g.SmoothingMode = sm;
 | |
|             }
 | |
| 
 | |
|             return (lineWidth);
 | |
|         }
 | |
| 
 | |
|         #region RenderStockCandleBackground
 | |
| 
 | |
|         private void RenderStockCandleBackground(
 | |
|             Graphics g, HiLoRenderData rd, Rectangle r)
 | |
|         {
 | |
|             Background bk =
 | |
|                 GetBoxBackground(rd, rd.AlternateStyle.BoxBackground, rd.DefaultStyle.BoxBackground);
 | |
| 
 | |
|             if (bk.IsEmpty == false)
 | |
|             {
 | |
|                 using (Brush br = bk.GetBrush(r))
 | |
|                     g.FillRectangle(br, r);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderStockBoxBackground
 | |
| 
 | |
|         private void RenderStockBoxBackground(
 | |
|             Graphics g, HiLoRenderData rd, Rectangle r)
 | |
|         {
 | |
|             Background bkDef = rd.DefaultStyle.BoxBackground;
 | |
|             Background bkAlt = rd.AlternateStyle.BoxBackground;
 | |
| 
 | |
|             if (bkAlt.IsEmpty == true)
 | |
|                 bkAlt = bkDef;
 | |
| 
 | |
|             if (rd.IsAlternate == true)
 | |
|             {
 | |
|                 Background bkSave = bkDef;
 | |
|                 bkDef = bkAlt;
 | |
|                 bkAlt = bkSave;
 | |
|             }
 | |
| 
 | |
|             if ((ShowHiLoBarMedianLines == true) && (rd.Value.Length > StockMedian))
 | |
|             {
 | |
|                 if (bkAlt.IsEmpty == false)
 | |
|                 {
 | |
|                     if (IsRotated == false)
 | |
|                         r = RenderVBox(g, rd.Value[StockMedian], bkAlt, r);
 | |
|                     else
 | |
|                         r = RenderHBox(g, rd.Value[StockMedian], bkAlt, r);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (r.Width > 0 && r.Height > 0)
 | |
|             {
 | |
|                 if (bkDef.IsEmpty == false)
 | |
|                 {
 | |
|                     using (Brush br = bkDef.GetBrush(r))
 | |
|                         g.FillRectangle(br, r);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderVBox
 | |
| 
 | |
|         private Rectangle RenderVBox(Graphics g, int y, Background bk, Rectangle r)
 | |
|         {
 | |
|             if ((y > r.Y && y < r.Bottom) && bk.IsEmpty == false)
 | |
|             {
 | |
|                 int ry = r.Y;
 | |
| 
 | |
|                 r.Height = r.Bottom - y;
 | |
|                 r.Y = y;
 | |
| 
 | |
|                 using (Brush br = bk.GetBrush(r))
 | |
|                     g.FillRectangle(br, r);
 | |
| 
 | |
|                 r.Y = ry;
 | |
|                 r.Height = y - ry;
 | |
|             }
 | |
| 
 | |
|             return (r);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderHBox
 | |
| 
 | |
|         private Rectangle RenderHBox(Graphics g, int x, Background bk, Rectangle r)
 | |
|         {
 | |
|             if (x > r.X && x < r.Right)
 | |
|             {
 | |
|                 int rw = r.Width;
 | |
| 
 | |
|                 r.Width = x - r.X;
 | |
| 
 | |
|                 using (Brush br = bk.GetBrush(r))
 | |
|                     g.FillRectangle(br, r);
 | |
| 
 | |
|                 r.X = r.Right;
 | |
|                 r.Width = rw - r.Width;
 | |
|             }
 | |
| 
 | |
|             return (r);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderHiLoWhisker
 | |
| 
 | |
|         private ChartLineVisualStyle RenderHiLoWhisker(Graphics g,
 | |
|             HiLoRenderData rd, Point pt1, Point pt2, ChartLineVisualStyle style, HiLoBarSegment segment)
 | |
|         {
 | |
|             ChartXy chartXy = rd.ChartXy;
 | |
|             ChartControl chartControl = ChartControl;
 | |
| 
 | |
|             SmoothingMode sm = g.SmoothingMode;
 | |
|             g.SmoothingMode = SmoothingMode.None;
 | |
| 
 | |
|             if (chartControl.DoPreRenderSeriesHiloBarEvent(g, chartXy, this, rd, pt1, pt2, segment) == false)
 | |
|             {
 | |
|                 if (style.LinePattern != LinePattern.None)
 | |
|                 {
 | |
|                     using (Pen pen = new Pen(style.LineColor, Dpi.Width(style.LineWidth)))
 | |
|                     {
 | |
|                         if (style.LinePattern != LinePattern.NotSet)
 | |
|                             pen.DashStyle = (DashStyle)style.LinePattern;
 | |
| 
 | |
|                         if (style.LineWidth == 1)
 | |
|                         {
 | |
|                             if (pt1.X == pt2.X)
 | |
|                                 pt2.Y--;
 | |
|                             else
 | |
|                                 pt2.X--;
 | |
|                         }
 | |
| 
 | |
|                         g.DrawLine(pen, pt1, pt2);
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 chartControl.DoPostRenderSeriesHiLoBarEvent(g, chartXy, this, rd, pt1, pt2, segment);
 | |
|             }
 | |
| 
 | |
|             g.SmoothingMode = sm;
 | |
| 
 | |
|             return (style);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderHiLoRange
 | |
| 
 | |
|         private void RenderHiLoRange(
 | |
|             Graphics g, HiLoRenderData rd, Point pt1, Point pt2, HiLoBarSegment segment)
 | |
|         {
 | |
|             ChartXy chartXy = rd.ChartXy;
 | |
|             ChartControl chartControl = ChartControl;
 | |
| 
 | |
|             if (pt1.X == pt2.X)
 | |
|             {
 | |
|                 if (segment == HiLoBarSegment.HighWhisker || segment == HiLoBarSegment.FullRange)
 | |
|                     pt1.Y -= rd.EndDelta;
 | |
| 
 | |
|                 if (segment == HiLoBarSegment.LowWhisker || segment == HiLoBarSegment.FullRange)
 | |
|                     pt2.Y += rd.EndDelta;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (segment == HiLoBarSegment.LowWhisker || segment == HiLoBarSegment.FullRange)
 | |
|                     pt2.X -= rd.EndDelta;
 | |
| 
 | |
|                 if (segment == HiLoBarSegment.HighWhisker || segment == HiLoBarSegment.FullRange)
 | |
|                     pt1.X += rd.EndDelta;
 | |
|             }
 | |
| 
 | |
|             SmoothingMode sm = g.SmoothingMode;
 | |
|             g.SmoothingMode = SmoothingMode.None;
 | |
| 
 | |
|             if (chartControl.DoPreRenderSeriesHiloBarEvent(g, chartXy, this, rd, pt1, pt2, segment) == false)
 | |
|             {
 | |
|                 ChartLineVisualStyle lstyle = GetSegLineStyle(rd, segment);
 | |
| 
 | |
|                 if (lstyle.LinePattern != LinePattern.None)
 | |
|                 {
 | |
|                     using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth)))
 | |
|                     {
 | |
|                         if (lstyle.LinePattern != LinePattern.NotSet)
 | |
|                             pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | |
| 
 | |
| 
 | |
|                         g.DrawLine(pen, pt1, pt2);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (ShowHiLoBarMedianLines == true)
 | |
|             {
 | |
|                 if (segment == HiLoBarSegment.CenterLine || segment == HiLoBarSegment.FullRange)
 | |
|                 {
 | |
|                     if (IsRotated == false)
 | |
|                         RenderVStockBoxMedian(g, rd, pt1.X - BarWidth / 2, pt1.Y, pt2.Y);
 | |
|                     else
 | |
|                         RenderHStockBoxMedian(g, rd, pt1.Y - BarWidth / 2, pt2.X, pt1.X);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             chartControl.DoPostRenderSeriesHiLoBarEvent(g, chartXy, this, rd, pt1, pt2, segment);
 | |
| 
 | |
|             g.SmoothingMode = sm;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetSegLineStyle
 | |
| 
 | |
|         private ChartLineVisualStyle GetSegLineStyle(HiLoRenderData rd, HiLoBarSegment segment)
 | |
|         {
 | |
|             ChartLineVisualStyle style = rd.DefaultStyle.Default;
 | |
| 
 | |
|             if (CanUseAlternateSegmentStyle(rd) == true)
 | |
|             {
 | |
|                 if (rd.IsAlternate == true && rd.AlternateStyle.Default.IsEmpty == false)
 | |
|                     style = rd.AlternateStyle.Default;
 | |
|             }
 | |
| 
 | |
|             switch (segment)
 | |
|             {
 | |
|                 case HiLoBarSegment.FullRange:
 | |
|                     break;
 | |
| 
 | |
|                 case HiLoBarSegment.Box:
 | |
|                     if (rd.IsAlternate == true && rd.AlternateStyle.BoxBorder.IsEmpty == false)
 | |
|                     {
 | |
|                         style = rd.AlternateStyle.BoxBorder;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (rd.DefaultStyle.BoxBorder.IsEmpty == false)
 | |
|                             style = rd.DefaultStyle.BoxBorder;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case HiLoBarSegment.MedianLine:
 | |
|                     if (rd.IsAlternate == true && rd.AlternateStyle.MedianLine.IsEmpty == false)
 | |
|                     {
 | |
|                         style = rd.AlternateStyle.MedianLine;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (rd.DefaultStyle.MedianLine.IsEmpty == false)
 | |
|                             style = rd.DefaultStyle.MedianLine;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case HiLoBarSegment.HighWhiskerCap:
 | |
|                     if (rd.IsAlternate == true && rd.AlternateStyle.HighWhiskerCap.IsEmpty == false)
 | |
|                     {
 | |
|                         style = rd.AlternateStyle.HighWhiskerCap;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (rd.DefaultStyle.HighWhiskerCap.IsEmpty == false)
 | |
|                             style = rd.DefaultStyle.HighWhiskerCap;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case HiLoBarSegment.LowWhiskerCap:
 | |
|                     if (rd.IsAlternate == true && rd.AlternateStyle.LowWhiskerCap.IsEmpty == false)
 | |
|                     {
 | |
|                         style = rd.AlternateStyle.LowWhiskerCap;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (rd.DefaultStyle.LowWhiskerCap.IsEmpty == false)
 | |
|                             style = rd.DefaultStyle.LowWhiskerCap;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case HiLoBarSegment.HighWhisker:
 | |
|                     if (rd.IsAlternate == true && rd.AlternateStyle.HighWhisker.IsEmpty == false)
 | |
|                     {
 | |
|                         style = rd.AlternateStyle.HighWhisker;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (rd.DefaultStyle.HighWhisker.IsEmpty == false)
 | |
|                             style = rd.DefaultStyle.HighWhisker;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case HiLoBarSegment.LowWhisker:
 | |
|                     if (rd.IsAlternate == true && rd.AlternateStyle.LowWhisker.IsEmpty == false)
 | |
|                     {
 | |
|                         style = rd.AlternateStyle.LowWhisker;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (rd.DefaultStyle.LowWhisker.IsEmpty == false)
 | |
|                             style = rd.DefaultStyle.LowWhisker;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case HiLoBarSegment.OpenWhisker:
 | |
|                     if (rd.IsAlternate == true && rd.AlternateStyle.OpenWhisker.IsEmpty == false)
 | |
|                     {
 | |
|                         style = rd.AlternateStyle.OpenWhisker;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (rd.DefaultStyle.OpenWhisker.IsEmpty == false)
 | |
|                             style = rd.DefaultStyle.OpenWhisker;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case HiLoBarSegment.CloseWhisker:
 | |
|                     if (rd.IsAlternate == true && rd.AlternateStyle.CloseWhisker.IsEmpty == false)
 | |
|                     {
 | |
|                         style = rd.AlternateStyle.CloseWhisker;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (rd.DefaultStyle.CloseWhisker.IsEmpty == false)
 | |
|                             style = rd.DefaultStyle.CloseWhisker;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case HiLoBarSegment.CenterLine:
 | |
|                     if (rd.IsAlternate == true && rd.AlternateStyle.CenterLine.IsEmpty == false)
 | |
|                     {
 | |
|                         style = rd.AlternateStyle.CenterLine;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (rd.DefaultStyle.CenterLine.IsEmpty == false)
 | |
|                             style = rd.DefaultStyle.CenterLine;
 | |
|                     }
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             return (style);
 | |
|         }
 | |
| 
 | |
|         #region CanUseAlternateSegmentStyle
 | |
| 
 | |
|         private bool CanUseAlternateSegmentStyle(HiLoRenderData rd)
 | |
|         {
 | |
|             Tbool uas = rd.SeriesStyle.HiLoBarVisualStyle.UseAlternateSegmentStyle;
 | |
| 
 | |
|             if (uas == Tbool.NotSet)
 | |
|                 return (HiLoBarType == HiLoBarType.Candle);
 | |
| 
 | |
|             return (uas == Tbool.True);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetBoxBackground
 | |
| 
 | |
|         private Background GetBoxBackground(HiLoRenderData rd, Background abk, Background sbk)
 | |
|         {
 | |
|             if (rd.IsAlternate == true && abk.IsEmpty == false)
 | |
|                 return (abk);
 | |
| 
 | |
|             return (sbk);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region HighLightPoints
 | |
| 
 | |
|         private bool HighLightPoints(ChartXy chartXy)
 | |
|         {
 | |
|             if (chartXy.ChartCrosshair.Visible == false)
 | |
|                 return (false);
 | |
| 
 | |
|             if (CrosshairHighlightPoints != Tbool.NotSet)
 | |
|                 return (CrosshairHighlightPoints == Tbool.True);
 | |
| 
 | |
|             return (chartXy.ChartCrosshair.HighlightPoints);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetHighlightStyle
 | |
| 
 | |
|         private PointMarkerVisualStyle GetHighlightStyle(
 | |
|             ChartXy chartXy, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             if (HighLightPoints(chartXy) == true)
 | |
|             {
 | |
|                 PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle;
 | |
|                 PointMarkerVisualStyle hstyle = pstyle.Copy();
 | |
| 
 | |
|                 if (sstyle.MarkerHighlightVisualStyle.IsEmpty == false)
 | |
|                 {
 | |
|                     hstyle.ApplyStyle(sstyle.MarkerHighlightVisualStyle);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     Size size = hstyle.Size;
 | |
| 
 | |
|                     size.Width += 4;
 | |
|                     size.Height += 4;
 | |
| 
 | |
|                     hstyle.Size = size;
 | |
|                 }
 | |
| 
 | |
|                 return (hstyle);
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetPointMarkerImage
 | |
| 
 | |
|         private Image GetPointMarkerImage(
 | |
|             Graphics g, ChartXy chartXy, PointMarkerVisualStyle style)
 | |
|         {
 | |
|             Image image = PointMarkerImage;
 | |
| 
 | |
|             if (image == null)
 | |
|             {
 | |
|                 image = chartXy.GetPointMarker(g, style);
 | |
| 
 | |
|                 PointMarkerImage = image;
 | |
|             }
 | |
| 
 | |
|             return (image);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetHighlightImage
 | |
| 
 | |
|         private Image GetHighlightImage(
 | |
|             Graphics g, ChartXy chartXy, PointMarkerVisualStyle style)
 | |
|         {
 | |
|             Image image = PointMarkerHighlightImage;
 | |
| 
 | |
|             if (image == null)
 | |
|             {
 | |
|                 image = chartXy.GetPointMarker(g, style);
 | |
| 
 | |
|                 PointMarkerHighlightImage = image;
 | |
|             }
 | |
| 
 | |
|             return (image);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetEmptyMarkerImage
 | |
| 
 | |
|         private Image GetEmptyMarkerImage(
 | |
|             Graphics g, ChartXy chartXy, PointMarkerVisualStyle style)
 | |
|         {
 | |
|             Image image = PointMarkerEmptyImage;
 | |
| 
 | |
|             if (image == null)
 | |
|             {
 | |
|                 image = chartXy.GetPointMarker(g, style);
 | |
| 
 | |
|                 PointMarkerEmptyImage = image;
 | |
|             }
 | |
| 
 | |
|             return (image);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GatherSeriesPoints
 | |
| 
 | |
|         private PointData GatherSeriesPoints(
 | |
|             ChartXy chartXy, SortedSeriesPoints ssp, int index, int count, bool allArgs)
 | |
|         {
 | |
|             if (_PointData == null)
 | |
|                 _PointData = GatherSeriesPointsEx(chartXy, ssp, index, count, allArgs);
 | |
| 
 | |
|             return (_PointData);
 | |
|         }
 | |
| 
 | |
|         private PointData GatherSeriesPointsEx(
 | |
|             ChartXy chartXy, SortedSeriesPoints ssp, int index, int count, bool allArgs)
 | |
|         {
 | |
|             PointData pd = new PointData();
 | |
| 
 | |
|             pd.Points = new List<Point[]>();
 | |
|             pd.SeriesPoints = new List<SeriesPoint[]>();
 | |
| 
 | |
|             if (EnableEmptyValues == true)
 | |
|             {
 | |
|                 PointData epd = new PointData();
 | |
| 
 | |
|                 epd.Points = new List<Point[]>();
 | |
|                 epd.SeriesPoints = new List<SeriesPoint[]>();
 | |
| 
 | |
|                 int n = 0;
 | |
|                 bool empty = false;
 | |
| 
 | |
|                 for (int i = 0; i < count; i++)
 | |
|                 {
 | |
|                     if (ssp[index + i].IsEmpty != empty)
 | |
|                     {
 | |
|                         int cnt = i - n;
 | |
| 
 | |
|                         if (cnt > 0)
 | |
|                             GetPointList(chartXy, ssp, index + n, cnt, allArgs, empty ? epd : pd);
 | |
| 
 | |
|                         empty = !empty;
 | |
| 
 | |
|                         n = i;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (n < count)
 | |
|                     GetPointList(chartXy, ssp, index + n, count - n, allArgs, empty ? epd : pd);
 | |
| 
 | |
|                 _EmptyPointData = epd;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 GetPointList(chartXy, ssp, index, count, allArgs, pd);
 | |
|             }
 | |
| 
 | |
|             return (pd);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetPointList
 | |
| 
 | |
|         private void GetPointList(ChartXy chartXy,
 | |
|             SortedSeriesPoints ssp, int index, int cnt, bool allArgs, PointData pd)
 | |
|         {
 | |
|             GetPointList(chartXy, ssp, index, cnt, 0, 0, allArgs, pd);
 | |
|         }
 | |
| 
 | |
|         private void GetPointList(ChartXy chartXy, SortedSeriesPoints ssp,
 | |
|             int index, int cnt, int skip, int minDistance, bool allArgs, PointData pd)
 | |
|         {
 | |
|             if (cnt > 0)
 | |
|             {
 | |
|                 Stack<object> stack = new Stack<object>();
 | |
| 
 | |
|                 skip++;
 | |
| 
 | |
|                 Point lpt = new Point(-5000, -5000);
 | |
| 
 | |
|                 if (allArgs == false)
 | |
|                 {
 | |
|                     if (cnt > skip && skip > 1)
 | |
|                         cnt = (cnt + skip - 1) / skip;
 | |
| 
 | |
|                     for (int i = 0; i < cnt; i++)
 | |
|                     {
 | |
|                         int n = index + (i * skip);
 | |
| 
 | |
|                         if (n >= ssp.Count)
 | |
|                             break;
 | |
| 
 | |
|                         SeriesPoint sp = ssp[n];
 | |
| 
 | |
|                         if (sp.Visible == true)
 | |
|                         {
 | |
|                             Point pt = chartXy.GetDataPointEx(this, sp, 0);
 | |
| 
 | |
|                             if (minDistance <= 0 || DataPointDistanceOk(lpt, pt, minDistance) == true)
 | |
|                             {
 | |
|                                 stack.Push(sp);
 | |
|                                 stack.Push(pt);
 | |
| 
 | |
|                                 lpt = pt;
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     int n = 0;
 | |
| 
 | |
|                     for (int i = 0; i < cnt; i++)
 | |
|                         n += ssp[index + i].ValueY.Length;
 | |
| 
 | |
|                     n /= (n + skip - 1) / skip;
 | |
| 
 | |
|                     int m = 0;
 | |
| 
 | |
|                     for (int i = 0; i < cnt; i++)
 | |
|                     {
 | |
|                         SeriesPoint sp = ssp[index + i];
 | |
| 
 | |
|                         for (int j = 0; j < sp.ValueY.Length; j++)
 | |
|                         {
 | |
|                             if (m % skip == 0)
 | |
|                             {
 | |
|                                 int w = m / skip;
 | |
| 
 | |
|                                 Point pt = chartXy.GetDataPointNa(this, sp, j);
 | |
| 
 | |
|                                 if (minDistance <= 0 || DataPointDistanceOk(lpt, pt, minDistance) == true)
 | |
|                                 {
 | |
|                                     stack.Push(sp);
 | |
|                                     stack.Push(pt);
 | |
| 
 | |
|                                     lpt = pt;
 | |
|                                 }
 | |
|                             }
 | |
| 
 | |
|                             m++;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (stack.Count > 0)
 | |
|                 {
 | |
|                     int n = stack.Count / 2;
 | |
| 
 | |
|                     Point[] points = new Point[n];
 | |
|                     SeriesPoint[] seriesPoints = new SeriesPoint[n];
 | |
| 
 | |
|                     for (int i = n - 1; i >= 0; i--)
 | |
|                     {
 | |
|                         points[i] = (Point)stack.Pop();
 | |
|                         seriesPoints[i] = (SeriesPoint)stack.Pop();
 | |
|                     }
 | |
| 
 | |
|                     pd.Points.Add(points);
 | |
|                     pd.SeriesPoints.Add(seriesPoints);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region DataPointDistanceOk
 | |
| 
 | |
|         private bool DataPointDistanceOk(Point lpt, Point pt, int minDistance)
 | |
|         {
 | |
|             int dx = (lpt.X - pt.X);
 | |
|             int dy = (lpt.Y - pt.Y);
 | |
| 
 | |
|             int h = (int)AMath.Sqrt(dx * dx + dy * dy);
 | |
| 
 | |
|             return (h >= minDistance);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Render
 | |
| 
 | |
|         internal override void Render(ChartRenderInfo renderInfo)
 | |
|         {
 | |
|             if (Displayed == true)
 | |
|             {
 | |
|                 Rectangle bounds = BoundsRelative;
 | |
| 
 | |
|                 if (renderInfo.ClipRectangle.IntersectsWith(bounds))
 | |
|                     RenderOverride(renderInfo);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderIndicators
 | |
| 
 | |
|         internal void RenderIndicators(ChartRenderInfo renderInfo, bool onTop)
 | |
|         {
 | |
|             if (SeriesType != SeriesType.HorizontalDot || SeriesType != SeriesType.VerticalDot)
 | |
|             {
 | |
|                 if (SeriesPoints.Count > 0)
 | |
|                 {
 | |
|                     Graphics g = renderInfo.Graphics;
 | |
| 
 | |
|                     ChartXy chartXy = Parent as ChartXy;
 | |
|                     ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle;
 | |
| 
 | |
|                     SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy);
 | |
| 
 | |
|                     foreach (ChartIndicator indicator in ChartIndicators)
 | |
|                     {
 | |
|                         if (indicator.DisplayOnTop == onTop)
 | |
|                         {
 | |
|                             if (indicator.IsDisplayed == true)
 | |
|                             {
 | |
|                                 ssp.SlopeIndex = indicator.ValueYIndex;
 | |
| 
 | |
|                                 switch (indicator.IndicatorType)
 | |
|                                 {
 | |
|                                     case ChartIndicatorType.RegressionLine:
 | |
|                                         RenderRegressionLine(g, chartXy, ssp, (RegressionLine)indicator);
 | |
|                                         break;
 | |
| 
 | |
|                                     case ChartIndicatorType.TrendLine:
 | |
|                                         RenderTrendLine(g, chartXy, ssp, (TrendLine)indicator);
 | |
|                                         break;
 | |
|                                 }
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderRegressionLine
 | |
| 
 | |
|         private void RenderRegressionLine(Graphics g,
 | |
|             ChartXy chartXy, SortedSeriesPoints ssp, RegressionLine regline)
 | |
|         {
 | |
|             double m = regline.Slope;
 | |
|             double b = regline.Intercept;
 | |
| 
 | |
|             if (m.Equals(double.NaN) == false && b.Equals(double.NaN) == false)
 | |
|             {
 | |
|                 ChartAxis axis = AxisX ?? chartXy.AxisX;
 | |
| 
 | |
|                 double x1, x2;
 | |
| 
 | |
|                 switch (ActualScaleTypeX)
 | |
|                 {
 | |
|                     case ScaleType.DateTime:
 | |
|                         x1 = chartXy.GetDateTimePointValue(axis, axis.TickmarkLayout, (DateTime)MinValueX);
 | |
|                         x2 = chartXy.GetDateTimePointValue(axis, axis.TickmarkLayout, (DateTime)MaxValueX);
 | |
|                         break;
 | |
| 
 | |
|                     default:
 | |
|                         x1 = Convert.ToDouble(MinValueX);
 | |
|                         x2 = Convert.ToDouble(MaxValueX);
 | |
|                         break;
 | |
|                 }
 | |
| 
 | |
|                 Point pt1 = chartXy.GetPointFromValue(this, MinValueX, m * x1 + b);
 | |
|                 Point pt2 = chartXy.GetPointFromValue(this, MaxValueX, m * x2 + b);
 | |
| 
 | |
|                 if (SeriesType == SeriesType.VerticalBar ||
 | |
|                     SeriesType == SeriesType.VerticalHiLoBar)
 | |
|                 {
 | |
|                     pt1.X += BarOffset;
 | |
|                     pt2.X += BarOffset;
 | |
|                 }
 | |
|                 else if (SeriesType == SeriesType.HorizontalBar ||
 | |
|                          SeriesType == SeriesType.HorizontalHiLoBar)
 | |
|                 {
 | |
|                     pt1.Y += BarOffset;
 | |
|                     pt2.Y += BarOffset;
 | |
|                 }
 | |
| 
 | |
|                 RegressionLineVisualStyle rstyle = regline.RegressionLineVisualStyle;
 | |
| 
 | |
|                 Color color = rstyle.LineColor;
 | |
| 
 | |
|                 if (color.IsEmpty)
 | |
|                     color = DefaultPaletteColor;
 | |
| 
 | |
|                 using (Pen pen = new Pen(color, Dpi.Width(rstyle.LineWidth)))
 | |
|                 {
 | |
|                     if (rstyle.LinePattern != LinePattern.NotSet)
 | |
|                         pen.DashStyle = (DashStyle)rstyle.LinePattern;
 | |
| 
 | |
|                     if (rstyle.StartCap != ChartLineCap.NotSet)
 | |
|                         pen.StartCap = (LineCap)rstyle.StartCap;
 | |
| 
 | |
|                     if (rstyle.EndCap != ChartLineCap.NotSet)
 | |
|                         pen.EndCap = (LineCap)rstyle.EndCap;
 | |
| 
 | |
|                     g.DrawLine(pen, pt1, pt2);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderTrendLine
 | |
| 
 | |
|         private void RenderTrendLine(Graphics g,
 | |
|             ChartXy chartXy, SortedSeriesPoints ssp, TrendLine trendLine)
 | |
|         {
 | |
|             SeriesPoint sp1 = ssp.GetSeriesPoint(trendLine.ValueX1);
 | |
|             SeriesPoint sp2 = ssp.GetSeriesPoint(trendLine.ValueX2);
 | |
| 
 | |
|             if (sp1 != null && sp2 != null)
 | |
|             {
 | |
|                 Point pt1 = chartXy.GetDataPointEx(this, sp1, trendLine.ValueYIndex);
 | |
|                 Point pt2 = chartXy.GetDataPointEx(this, sp2, trendLine.ValueYIndex);
 | |
| 
 | |
|                 if (SeriesType == SeriesType.VerticalBar ||
 | |
|                     SeriesType == SeriesType.VerticalHiLoBar)
 | |
|                 {
 | |
|                     pt1.X += BarOffset;
 | |
|                     pt2.X += BarOffset;
 | |
|                 }
 | |
|                 else if (SeriesType == SeriesType.HorizontalBar ||
 | |
|                          SeriesType == SeriesType.HorizontalHiLoBar)
 | |
|                {
 | |
|                     pt1.Y += BarOffset;
 | |
|                     pt2.Y += BarOffset;
 | |
|                 }
 | |
| 
 | |
|                 if (pt1.X >= chartXy.ContentBounds.X && pt2.X < chartXy.ContentBounds.Right)
 | |
|                 {
 | |
|                     TrendLineVisualStyle tstyle = trendLine.TrendLineVisualStyle;
 | |
| 
 | |
|                     Color color = tstyle.LineColor;
 | |
| 
 | |
|                     if (color.IsEmpty)
 | |
|                         color = DefaultPaletteColor;
 | |
| 
 | |
|                     using (Pen pen = new Pen(color, Dpi.Width(tstyle.LineWidth)))
 | |
|                     {
 | |
|                         if (tstyle.LinePattern != LinePattern.NotSet)
 | |
|                             pen.DashStyle = (DashStyle)tstyle.LinePattern;
 | |
| 
 | |
|                         if (tstyle.StartCap != ChartLineCap.NotSet)
 | |
|                             pen.StartCap = (LineCap)tstyle.StartCap;
 | |
| 
 | |
|                         if (tstyle.EndCap != ChartLineCap.NotSet)
 | |
|                             pen.EndCap = (LineCap)tstyle.EndCap;
 | |
| 
 | |
|                         g.DrawLine(pen, pt1, pt2);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region InvalidatePoints
 | |
| 
 | |
|         internal void InvalidatePoints()
 | |
|         {
 | |
|             _PointData = null;
 | |
|             _EmptyPointData = null;
 | |
|             _ConvexHullPoints = null;
 | |
|             _StepPointData = null;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region InvalidatePointLabels
 | |
| 
 | |
|         internal void InvalidatePointLabels()
 | |
|         {
 | |
|             ChartXy chartXy = Parent as ChartXy;
 | |
| 
 | |
|             if (chartXy != null)
 | |
|                 chartXy.InvalidatePointLabelsEx();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RefreshSeries
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Causes the series to refresh its display, as the underlying
 | |
|         /// series data (potentially) has changed in some way.
 | |
|         ///</summary>
 | |
|         public void RefreshSeries()
 | |
|         {
 | |
|             SeriesRangeChanged = true;
 | |
| 
 | |
|             InvalidateLayout();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region UpdateSeriesRange
 | |
| 
 | |
|         internal void UpdateSeriesRange()
 | |
|         {
 | |
|             if (SeriesRangeChanged == true)
 | |
|             {
 | |
|                 if (Parent == null)
 | |
|                     return;
 | |
| 
 | |
|                 SeriesRangeChanged = false;
 | |
| 
 | |
|                 IsSorted = true;
 | |
| 
 | |
|                 QualitativeXValues.Clear();
 | |
|                 QualitativeYValues.Clear();
 | |
| 
 | |
|                 _MinValueX = null;
 | |
|                 _MinValueY = null;
 | |
|                 _MaxValueX = null;
 | |
|                 _MaxValueY = null;
 | |
| 
 | |
|                 if (SeriesPoints.Count > 0)
 | |
|                 {
 | |
|                     ChartXy chartXy = Parent as ChartXy;
 | |
| 
 | |
|                     Type dataTypeX = null;
 | |
|                     Type dataTypeY = null;
 | |
| 
 | |
|                     if (ChartControl != null && ChartControl.DesignerHosted == true)
 | |
|                     {
 | |
|                         dataTypeX = GetDataTypeX(SeriesPoints);
 | |
|                         dataTypeY = GetDataTypeY(SeriesPoints);
 | |
| 
 | |
|                         ActualScaleTypeX = GetActualScaleType(dataTypeX, ScaleTypeX);
 | |
|                         ActualScaleTypeY = GetActualScaleType(dataTypeY, ScaleTypeY);
 | |
| 
 | |
|                         _PlotData = null;
 | |
|                     }
 | |
| 
 | |
|                     for (int i = 0; i < SeriesPoints.Count; i++)
 | |
|                     {
 | |
|                         SeriesPoint sp = SeriesPoints[i];
 | |
| 
 | |
|                         if (sp.Visible == true)
 | |
|                         {
 | |
|                             UpdateXValueRange(chartXy, sp, ref dataTypeX);
 | |
| 
 | |
|                             switch (SeriesType)
 | |
|                             {
 | |
|                                 case SeriesType.VerticalDot:
 | |
|                                 case SeriesType.HorizontalDot:
 | |
|                                     ActualScaleTypeY = ScaleType.Quantitative;
 | |
|                                     break;
 | |
| 
 | |
|                                 case SeriesType.Bubble:
 | |
|                                     UpdateYBubbleRange(chartXy, sp, ref dataTypeY);
 | |
|                                     break;
 | |
| 
 | |
|                                 default:
 | |
|                                     UpdateYValueRange(chartXy, sp, ref dataTypeY);
 | |
|                                     break;
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     if (SeriesType == SeriesType.VerticalDot ||
 | |
|                         SeriesType == SeriesType.HorizontalDot)
 | |
|                     {
 | |
|                         UpdateStackedYValueRange();
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (QualitativeXValues.Count > 0)
 | |
|                         {
 | |
|                             _MinValueX = 0;
 | |
|                             _MaxValueX = QualitativeXValues.Count - 1;
 | |
|                         }
 | |
| 
 | |
|                         if (QualitativeYValues.Count > 0)
 | |
|                         {
 | |
|                             _MinValueY = 0;
 | |
|                             _MaxValueY = QualitativeYValues.Count - 1;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetDataTypeX
 | |
| 
 | |
|         private Type GetDataTypeX(SeriesPointCollection spc)
 | |
|         {
 | |
|             Type dataType = null;
 | |
| 
 | |
|             for (int i = 0; i < spc.Count; i++)
 | |
|             {
 | |
|                 SeriesPoint sp = spc[i];
 | |
| 
 | |
|                 if (sp.Visible == true)
 | |
|                 {
 | |
|                     if (sp.ValueX != null)
 | |
|                     {
 | |
|                         dataType = sp.ValueX.GetType();
 | |
| 
 | |
|                         if (dataType != typeof(int))
 | |
|                             break;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (dataType);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetDataTypeY
 | |
| 
 | |
|         private Type GetDataTypeY(SeriesPointCollection spc)
 | |
|         {
 | |
|             Type dataType = null;
 | |
| 
 | |
|             for (int i = 0; i < spc.Count; i++)
 | |
|             {
 | |
|                 SeriesPoint sp = spc[i];
 | |
| 
 | |
|                 if (sp.Visible == true)
 | |
|                 {
 | |
|                     if (sp.ValueY != null && sp.ValueY.Length > 0)
 | |
|                     {
 | |
|                         for (int j = 0; j < sp.ValueY.Length; j++)
 | |
|                         {
 | |
|                             object valueY = sp.ValueY[j];
 | |
| 
 | |
|                             if (valueY != null)
 | |
|                             {
 | |
|                                 dataType = valueY.GetType();
 | |
| 
 | |
|                                 if (dataType != typeof(int))
 | |
|                                     return (dataType);
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (dataType);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region UpdateXValueRange
 | |
| 
 | |
|         private int _CmpLast;
 | |
| 
 | |
|         private void UpdateXValueRange(ChartXy chartXy, SeriesPoint sp, ref Type dataType)
 | |
|         {
 | |
|             object value = sp.ValueX;
 | |
| 
 | |
|             if (value != null)
 | |
|             {
 | |
|                 if (dataType == null)
 | |
|                 {
 | |
|                     dataType = value.GetType();
 | |
| 
 | |
|                     ActualScaleTypeX = GetActualScaleType(dataType, ScaleTypeX);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     if (value.GetType() != dataType)
 | |
|                     {
 | |
|                         if (ChartControl.DesignerHosted == true)
 | |
|                         {
 | |
|                             try
 | |
|                             {
 | |
|                                 sp.ValueX = Convert.ChangeType(value, dataType);
 | |
|                             }
 | |
|                             catch
 | |
|                             {
 | |
|                                 sp.ValueX = null;
 | |
|                             }
 | |
| 
 | |
|                             value = sp.ValueX;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             throw new Exception("Cannot mix ValueX data types (" +
 | |
|                                 dataType + "," + value.GetType() + ").");
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 switch (_ActualScaleTypeX)
 | |
|                 {
 | |
|                     case ScaleType.Qualitative:
 | |
|                         if (QualitativeXValues.Contains(value) == false)
 | |
|                             QualitativeXValues.Add(value);
 | |
|                         break;
 | |
| 
 | |
|                     default:
 | |
|                         if (_MinValueX == null)
 | |
|                         {
 | |
|                             _MinValueX = value;
 | |
|                             _MaxValueX = value;
 | |
| 
 | |
|                             _CmpLast = 0;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             if (chartXy.DataCompare(value, _MaxValueX) >= 0)
 | |
|                             {
 | |
|                                 _MaxValueX = value;
 | |
| 
 | |
|                                 if (_CmpLast == 0)
 | |
|                                     _CmpLast = 1;
 | |
| 
 | |
|                                 else if (_CmpLast < 0)
 | |
|                                     IsSorted = false;
 | |
|                             }
 | |
|                             else
 | |
|                             {
 | |
|                                 if (chartXy.DataCompare(value, _MinValueX) <= 0)
 | |
|                                     _MinValueX = value;
 | |
| 
 | |
|                                 if (_CmpLast == 0)
 | |
|                                     _CmpLast = -1;
 | |
| 
 | |
|                                 else if (_CmpLast > 0)
 | |
|                                     IsSorted = false;
 | |
|                             }
 | |
|                         }
 | |
|                         break;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region UpdateYBubbleRange
 | |
| 
 | |
|         private void UpdateYBubbleRange(ChartXy chartXy, SeriesPoint sp, ref Type dataType)
 | |
|         {
 | |
|             if (sp.ValueY == null || sp.ValueY.Length < 1)
 | |
|                 throw new Exception("Invalid Bubble Chart 'Y' arguments.");
 | |
| 
 | |
|             if (_PlotData == null)
 | |
|                 _PlotData = new BubblePlotData();
 | |
| 
 | |
|             BubblePlotData bdata = (BubblePlotData)_PlotData;
 | |
| 
 | |
|             object value = sp.ValueY[0];
 | |
| 
 | |
|             sp.IsEmptyValue = IsEmptyValue(value);
 | |
| 
 | |
|             if (sp.IsEmpty == false)
 | |
|             {
 | |
|                 if (dataType == null)
 | |
|                 {
 | |
|                     bdata.Clear();
 | |
| 
 | |
|                     dataType = value.GetType();
 | |
| 
 | |
|                     ActualScaleTypeY = GetActualScaleType(dataType, ScaleTypeY);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     if (value.GetType() != dataType)
 | |
|                     {
 | |
|                         if (ChartControl.DesignerHosted == true)
 | |
|                         {
 | |
|                             sp.ValueY[0] = Convert.ChangeType(value, dataType);
 | |
| 
 | |
|                             value = sp.ValueY[0];
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             throw new Exception("Cannot mix ValueY data types (" +
 | |
|                                 dataType + "," + value.GetType() + ").");
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 ProcessYValueRange(chartXy, value);
 | |
| 
 | |
|                 if (sp.ValueY.Length > 1)
 | |
|                 {
 | |
|                     double bvalue = GetDoubleValue(sp.ValueY[1]);
 | |
| 
 | |
|                     bvalue = Math.Abs(bvalue);
 | |
| 
 | |
|                     if (bvalue < bdata.MinSize)
 | |
|                         bdata.MinSize = bvalue;
 | |
| 
 | |
|                     if (bvalue > bdata.MaxSize)
 | |
|                         bdata.MaxSize = bvalue;
 | |
| 
 | |
|                     bdata.TotalSize += bvalue;
 | |
| 
 | |
|                     if (sp.ValueY.Length > 2)
 | |
|                     {
 | |
|                         double ivalue = GetDoubleValue(sp.ValueY[2]);
 | |
| 
 | |
|                         if (ivalue < bdata.MinIntensity)
 | |
|                             bdata.MinIntensity = ivalue;
 | |
| 
 | |
|                         if (ivalue > bdata.MaxIntensity)
 | |
|                             bdata.MaxIntensity = ivalue;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         #endregion
 | |
| 
 | |
|         #region UpdateYValueRange
 | |
| 
 | |
|         private void UpdateYValueRange(ChartXy chartXy, SeriesPoint sp, ref Type dataType)
 | |
|         {
 | |
|             if (sp.ValueY != null)
 | |
|             {
 | |
|                 for (int j = 0; j < sp.ValueY.Length; j++)
 | |
|                 {
 | |
|                     object value = sp.ValueY[j];
 | |
| 
 | |
|                     sp.IsEmptyValue = IsEmptyValue(value);
 | |
| 
 | |
|                     if (sp.IsEmpty == false)
 | |
|                     {
 | |
|                         if (dataType == null)
 | |
|                         {
 | |
|                             dataType = value.GetType();
 | |
| 
 | |
|                             ActualScaleTypeY = GetActualScaleType(dataType, ScaleTypeY);
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             if (value.GetType() != dataType)
 | |
|                             {
 | |
|                                 if (ChartControl.DesignerHosted == true)
 | |
|                                 {
 | |
|                                     try
 | |
|                                     {
 | |
|                                         sp.ValueY[j] = Convert.ChangeType(value, dataType);
 | |
|                                     }
 | |
|                                     catch
 | |
|                                     {
 | |
|                                         sp.ValueY[j] = null;
 | |
|                                     }
 | |
| 
 | |
|                                     value = sp.ValueY[j];
 | |
|                                 }
 | |
|                                 else
 | |
|                                 {
 | |
|                                     throw new Exception("Cannot mix ValueY data types (" +
 | |
|                                         dataType + "," + value.GetType() + ").");
 | |
|                                 }
 | |
|                             }
 | |
|                         }
 | |
| 
 | |
|                         ProcessYValueRange(chartXy, value);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 sp.IsEmptyValue = true;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region IsEmptyValue
 | |
| 
 | |
|         private bool IsEmptyValue(object value)
 | |
|         {
 | |
|             if (value == null)
 | |
|                 return (true);
 | |
| 
 | |
|             if (EmptyValues != null)
 | |
|             {
 | |
|                 Type dataType = value.GetType();
 | |
| 
 | |
|                 for (int i = 0; i < EmptyValues.Length; i++)
 | |
|                 {
 | |
|                     if (EmptyValues[i] != null)
 | |
|                     {
 | |
|                         if (dataType == EmptyValues[i].GetType())
 | |
|                         {
 | |
|                             if (value.Equals(EmptyValues[i]) == true)
 | |
|                                 return (true);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (false);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region UpdateStackedYValueRange
 | |
| 
 | |
|         private void UpdateStackedYValueRange()
 | |
|         {
 | |
|             if (QualitativeXValues.Count > 0 || QualitativeYValues.Count > 0)
 | |
|                 throw new Exception("Dot plots can not contain Qualitative values.");
 | |
| 
 | |
|             Dictionary<object, double> pd = new Dictionary<object, double>();
 | |
| 
 | |
|             for (int i = 0; i < SeriesPoints.Count; i++)
 | |
|             {
 | |
|                 SeriesPoint sp = SeriesPoints[i];
 | |
| 
 | |
|                 if (sp.Visible == true)
 | |
|                 {
 | |
|                     object ox = sp.ValueX;
 | |
| 
 | |
|                     double count = 0;
 | |
| 
 | |
|                     if (sp.ValueY != null && sp.ValueY.Length > 0)
 | |
|                     {
 | |
|                         foreach (object oy in sp.ValueY)
 | |
|                         {
 | |
|                             sp.IsEmptyValue = IsEmptyValue(oy);
 | |
| 
 | |
|                             if (sp.IsEmpty == false)
 | |
|                                 count += GetDoubleValue(oy);
 | |
|                         }
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (sp.IsEmpty == false)
 | |
|                             count++;
 | |
|                     }
 | |
| 
 | |
|                     if (sp.IsEmpty == false)
 | |
|                     {
 | |
|                         if (pd.ContainsKey(ox) == true)
 | |
|                             pd[ox] += count;
 | |
|                         else
 | |
|                             pd.Add(ox, count);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             double maxValue = 0;
 | |
| 
 | |
|             foreach (KeyValuePair<object, double> kvp in pd)
 | |
|             {
 | |
|                 if (kvp.Value > maxValue)
 | |
|                     maxValue = kvp.Value;
 | |
|             }
 | |
| 
 | |
|             _MinValueY = 0.0;
 | |
|             _MaxValueY = maxValue;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ProcessYValueRange
 | |
| 
 | |
|         private void ProcessYValueRange(ChartXy chartXy, object value)
 | |
|         {
 | |
|             switch (_ActualScaleTypeY)
 | |
|             {
 | |
|                 case ScaleType.Qualitative:
 | |
|                     if (QualitativeYValues.Contains(value) == false)
 | |
|                         QualitativeYValues.Add(value);
 | |
|                     break;
 | |
| 
 | |
|                 default:
 | |
|                     if (_MinValueY == null)
 | |
|                     {
 | |
|                         _MinValueY = value;
 | |
|                         _MaxValueY = value;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         int cmpMax = chartXy.DataCompare(value, _MaxValueY);
 | |
| 
 | |
|                         if (cmpMax >= 0)
 | |
|                         {
 | |
|                             _MaxValueY = value;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             int cmpMin = chartXy.DataCompare(value, _MinValueY);
 | |
| 
 | |
|                             if (cmpMin <= 0)
 | |
|                                 _MinValueY = value;
 | |
|                         }
 | |
|                     }
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetActualScaleType
 | |
| 
 | |
|         private ScaleType GetActualScaleType(Type dataType, ScaleType scaleType)
 | |
|         {
 | |
|             ScaleType autoType = SeriesPoint.GetScaleType(dataType);
 | |
| 
 | |
|             if (scaleType == ScaleType.NotSet || scaleType == ScaleType.Auto)
 | |
|                 return (autoType);
 | |
| 
 | |
|             if (scaleType == autoType)
 | |
|                 return (scaleType);
 | |
| 
 | |
|             if (scaleType == ScaleType.Qualitative)
 | |
|                 return (scaleType);
 | |
| 
 | |
|             throw new Exception("Set ScaleType is incompatible with series data.");
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ResetSortedPoints
 | |
| 
 | |
|         internal void ResetSortedPoints()
 | |
|         {
 | |
|             if (IsSorted == false)
 | |
|                 _SortedSeriesPoints = null;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetValueX
 | |
| 
 | |
|         internal object GetValueX(SeriesPoint sp)
 | |
|         {
 | |
|             if (IsRotated == false)
 | |
|                 return (sp.ValueX);
 | |
| 
 | |
|             if (sp.ValueY != null && sp.ValueY.Length > 0)
 | |
|                 return (sp.ValueY[0]);
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetValueY
 | |
| 
 | |
|         internal object GetValueY(SeriesPoint sp, int index)
 | |
|         {
 | |
|             if (IsRotated == true)
 | |
|                 return (sp.ValueX);
 | |
| 
 | |
|             if (sp.ValueY != null && sp.ValueY.Length > index)
 | |
|                 return (sp.ValueY[index]);
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetQualitativeValueX
 | |
| 
 | |
|         internal object GetQualitativeValueX(int index)
 | |
|         {
 | |
|             if (IsRotated == false)
 | |
|             {
 | |
|                 if (QualitativeXValues != null && QualitativeXValues.Count > index)
 | |
|                     return (QualitativeXValues[index]);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (QualitativeYValues != null && QualitativeYValues.Count > index)
 | |
|                     return (QualitativeYValues[index]);
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetQualitativeValueY
 | |
| 
 | |
|         internal object GetQualitativeValueY(int index)
 | |
|         {
 | |
|             if (IsRotated == true)
 | |
|             {
 | |
|                 if (QualitativeXValues != null && QualitativeXValues.Count > index)
 | |
|                     return (QualitativeXValues[index]);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (QualitativeYValues != null && QualitativeYValues.Count > index)
 | |
|                     return (QualitativeYValues[index]);
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetDoubleValue
 | |
| 
 | |
|         private double GetDoubleValue(object value)
 | |
|         {
 | |
|             if (value is double)
 | |
|                 return (double)value;
 | |
| 
 | |
|             return (Convert.ToDouble(value));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetBarWidthRatio
 | |
| 
 | |
|         internal double GetBarWidthRatio(ChartXy chartXy)
 | |
|         {
 | |
|             return (_BarWidthRatio > 0 ? _BarWidthRatio : 
 | |
|                 (chartXy.BarWidthRatio > 0 ? chartXy.BarWidthRatio : 1));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetPointLabels
 | |
| 
 | |
|         internal List<PointLabel> GetPointLabels(Graphics g)
 | |
|         {
 | |
|             ChartXy chartXy = Parent as ChartXy;
 | |
| 
 | |
|             PointLabelDisplayMode plmode = GetPointLabelDisplayType(chartXy);
 | |
| 
 | |
|             if (plmode != PointLabelDisplayMode.None)
 | |
|             {
 | |
|                 ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle;
 | |
| 
 | |
|                 SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy);
 | |
|                 ssp.SeriesLayoutCount = chartXy.SeriesLayoutCount;
 | |
| 
 | |
|                 ChartAxis axisX = (IsRotated == true) ? AxisY ?? chartXy.AxisY : AxisX ?? chartXy.AxisX;
 | |
|                 ChartAxis axisY = (IsRotated == true) ? AxisX ?? chartXy.AxisX : AxisY ?? chartXy.AxisY;
 | |
| 
 | |
|                 if (ssp.Count > 0)
 | |
|                 {
 | |
|                     DataLabelVisualStyle dstyle = EffectiveDataLabelStyle;
 | |
| 
 | |
|                     PointData pd = GetLabelPoints(chartXy, ssp, 0, ssp.Count, plmode);
 | |
| 
 | |
|                     List<PointLabel> plabels = new List<PointLabel>();
 | |
| 
 | |
|                     if (pd.Points.Count > 0)
 | |
|                     {
 | |
|                         for (int i = 0; i < pd.Points.Count; i++)
 | |
|                         {
 | |
|                             Point[] pts = pd.Points[i];
 | |
|                             SeriesPoint[] spts = pd.SeriesPoints[i];
 | |
| 
 | |
|                             for (int j = 0; j < pts.Length; j++)
 | |
|                             {
 | |
|                                 SeriesPoint sp = spts[j];
 | |
|                                 Point pt = pts[j];
 | |
| 
 | |
|                                 if (IsBarSeries == true && ShowOriginValueLabels == false)
 | |
|                                 {
 | |
|                                     if (IsBarOrigin(chartXy, sp) == true)
 | |
|                                         continue;
 | |
|                                 }
 | |
| 
 | |
|                                 string text = GetPointLabelText(sp, axisX, axisY, dstyle);
 | |
| 
 | |
|                                 PointLabel pl = new PointLabel(sp, pt, text);
 | |
| 
 | |
|                                 pl.LabelSize = MeasurePointLabel(g, pl);
 | |
| 
 | |
|                                 plabels.Add(pl);
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     if ((plmode & PointLabelDisplayMode.DataLabels) == PointLabelDisplayMode.DataLabels)
 | |
|                         GetDataLabels(g, plabels, chartXy, axisX, axisY, dstyle);
 | |
| 
 | |
|                     return (plabels);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #region GetPointLabelDisplayType
 | |
| 
 | |
|         private PointLabelDisplayMode GetPointLabelDisplayType(ChartXy chartXy)
 | |
|         {
 | |
|             PointLabelDisplayMode ptype = PointLabelDisplayMode;
 | |
| 
 | |
|             if (ptype != PointLabelDisplayMode.NotSet)
 | |
|                 return (ptype);
 | |
| 
 | |
|             ptype = chartXy.PointLabelDisplayMode;
 | |
| 
 | |
|             return (ptype != PointLabelDisplayMode.NotSet ? ptype : PointLabelDisplayMode.None);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetLabelPoints
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the collection of series PointData for the given PointLabelDisplayType.
 | |
|         /// </summary>
 | |
|         /// <param name="plmode"></param>
 | |
|         /// <returns></returns>
 | |
|         public PointData GetLabelPoints(PointLabelDisplayMode displayType)
 | |
|         {
 | |
|             ChartXy chartXy = Parent as ChartXy;
 | |
| 
 | |
|             if (chartXy != null)
 | |
|             {
 | |
|                 SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy);
 | |
| 
 | |
|                 return (GetLabelPoints(chartXy, ssp, 0, ssp.Count, displayType));
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         private PointData GetLabelPoints(ChartXy chartXy,
 | |
|             SortedSeriesPoints ssp, int index, int count, PointLabelDisplayMode displayType)
 | |
|         {
 | |
|             PointData pd = new PointData();
 | |
| 
 | |
|             pd.Points = new List<Point[]>();
 | |
|             pd.SeriesPoints = new List<SeriesPoint[]>();
 | |
| 
 | |
|             if ((displayType & PointLabelDisplayMode.AllSeriesPoints) == PointLabelDisplayMode.AllSeriesPoints)
 | |
|                 GetPointList(chartXy, ssp, index, count, _PointLabelSkip, _PointLabelMinDistance, false, pd);
 | |
| 
 | |
|             else if ((displayType & ~PointLabelDisplayMode.AllSeriesPoints) != 0)
 | |
|             {
 | |
|                 List<SeriesPoint> lmmsp = new List<SeriesPoint>();
 | |
| 
 | |
|                 if ((displayType & PointLabelDisplayMode.MinValueX) == PointLabelDisplayMode.MinValueX)
 | |
|                 {
 | |
|                     int n;
 | |
|                     
 | |
|                     if (IsRotated == true)
 | |
|                     {
 | |
|                         if (QualitativeYValues.Count > 0)
 | |
|                             n = (int)MinValueX;
 | |
|                         else
 | |
|                             n = ssp.SearchY(MinValueX);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (QualitativeXValues.Count > 0)
 | |
|                             n = (int)MinValueX;
 | |
|                         else
 | |
|                             n = (ssp.IsSorted == true) ? 0 : ssp.SearchX(MinValueX);
 | |
|                     }
 | |
| 
 | |
|                     if (n >= 0)
 | |
|                         lmmsp.Add(ssp[n]);
 | |
|                 }
 | |
| 
 | |
|                 if ((displayType & PointLabelDisplayMode.MaxValueX) == PointLabelDisplayMode.MaxValueX)
 | |
|                 {
 | |
|                     int n;
 | |
| 
 | |
|                     if (IsRotated == true)
 | |
|                     {
 | |
|                         if (QualitativeYValues.Count > 0)
 | |
|                             n = (int)MaxValueX;
 | |
|                         else
 | |
|                             n = ssp.SearchY(MaxValueX);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (QualitativeXValues.Count > 0)
 | |
|                             n = (int)MaxValueX;
 | |
|                         else
 | |
|                             n = (ssp.IsSorted == true) ? ssp.Count - 1 : ssp.SearchX(MaxValueX);
 | |
|                     }
 | |
| 
 | |
|                     if (n >= 0 && lmmsp.Contains(ssp[n]) == false)
 | |
|                         lmmsp.Add(ssp[n]);
 | |
|                 }
 | |
| 
 | |
|                 if ((displayType & PointLabelDisplayMode.MinValueY) == PointLabelDisplayMode.MinValueY)
 | |
|                 {
 | |
|                     int n;
 | |
| 
 | |
|                     if (IsRotated == true)
 | |
|                     {
 | |
|                         if (QualitativeXValues.Count > 0)
 | |
|                             n = (int)MinValueY;
 | |
|                         else
 | |
|                             n = (ssp.IsSorted == true) ? 0 : ssp.SearchX(MinValueY);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (QualitativeYValues.Count > 0)
 | |
|                             n = (int)MinValueY;
 | |
|                         else
 | |
|                             n = ssp.SearchY(MinValueY);
 | |
|                     }
 | |
| 
 | |
|                     if (n >= 0 && lmmsp.Contains(ssp[n]) == false)
 | |
|                         lmmsp.Add(ssp[n]);
 | |
|                 }
 | |
| 
 | |
|                 if ((displayType & PointLabelDisplayMode.MaxValueY) == PointLabelDisplayMode.MaxValueY)
 | |
|                 {
 | |
|                     int n;
 | |
| 
 | |
|                     if (IsRotated == true)
 | |
|                     {
 | |
|                         if (QualitativeXValues.Count > 0)
 | |
|                             n = (int)MaxValueY;
 | |
|                         else
 | |
|                             n = ssp.SearchX(MaxValueY);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (QualitativeYValues.Count > 0)
 | |
|                             n = (int)MaxValueY;
 | |
|                         else
 | |
|                             n = ssp.SearchY(MaxValueY);
 | |
|                     }
 | |
| 
 | |
|                     if (n >= 0 && lmmsp.Contains(ssp[n]) == false)
 | |
|                         lmmsp.Add(ssp[n]);
 | |
|                 }
 | |
| 
 | |
|                 if (lmmsp.Count > 0)
 | |
|                 {
 | |
|                     SeriesPoint[] mmsp = new SeriesPoint[lmmsp.Count];
 | |
|                     Point[] mmpt = new Point[lmmsp.Count];
 | |
| 
 | |
|                     for (int i = 0; i < lmmsp.Count; i++)
 | |
|                     {
 | |
|                         mmsp[i] = lmmsp[i];
 | |
|                         mmpt[i] = chartXy.GetDataPointNa(this, lmmsp[i], 0);
 | |
|                     }
 | |
| 
 | |
|                     pd.SeriesPoints.Add(mmsp);
 | |
|                     pd.Points.Add(mmpt);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (pd);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetDataLabels
 | |
| 
 | |
|         private void GetDataLabels(Graphics g, List<PointLabel> plabels, 
 | |
|             ChartXy chartXy, ChartAxis axisX, ChartAxis axisY, DataLabelVisualStyle dstyle)
 | |
|         {
 | |
|             foreach (DataLabel dlabel in DataLabels)
 | |
|             {
 | |
|                 DataLabelVisualStyle xstyle = dlabel.EffectiveDataLabelStyle;
 | |
| 
 | |
|                 PointLabel pl = FindPointLabel(plabels, dlabel);
 | |
| 
 | |
|                 if (pl != null)
 | |
|                 {
 | |
|                     if (string.IsNullOrEmpty(dlabel.Text) == false)
 | |
|                         pl.Label = dlabel.Text;
 | |
| 
 | |
|                     pl.DataLabelVisualStyle = xstyle;
 | |
|                     pl.BarLabelPosition = dlabel.BarLabelPosition;
 | |
| 
 | |
|                     pl.LabelSize = MeasurePointLabel(g, pl);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     SeriesPoint sp = new SeriesPoint(dlabel.ValueX, dlabel.ValueY);
 | |
| 
 | |
|                     string label = (string.IsNullOrEmpty(dlabel.Text) == false) ? dlabel.Text :
 | |
|                             GetPointLabelText(sp, axisX, axisY, xstyle);
 | |
| 
 | |
|                     Point pt = chartXy.GetDataPointNa(this, sp, 0);
 | |
| 
 | |
|                     pl = new PointLabel(sp, pt, label);
 | |
| 
 | |
|                     pl.IsDataLabel = true;
 | |
| 
 | |
|                     pl.DataLabelVisualStyle = xstyle;
 | |
|                     pl.BarLabelPosition = dlabel.BarLabelPosition;
 | |
| 
 | |
|                     pl.LabelSize = MeasurePointLabel(g, pl);
 | |
| 
 | |
|                     plabels.Add(pl);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region FindPointLabel
 | |
| 
 | |
|         private PointLabel FindPointLabel(List<PointLabel> plabels, DataLabel dlabel)
 | |
|         {
 | |
|             for (int i = 0; i < plabels.Count; i++)
 | |
|             {
 | |
|                 SeriesPoint sp = plabels[i].SeriesPoint;
 | |
| 
 | |
|                 if ((sp.ValueX != null) &&
 | |
|                     (sp.ValueY != null && sp.ValueY.Length > 0) &&
 | |
|                     (sp.ValueX.Equals(dlabel.ValueX) && sp.ValueY[0].Equals(dlabel.ValueY)))
 | |
|                 {
 | |
|                     return (plabels[i]);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IsBarOrigin
 | |
| 
 | |
|         internal bool IsBarOrigin(ChartXy chartXy, SeriesPoint sp)
 | |
|         {
 | |
|             object value = ((sp.ValueY != null  && sp.ValueY.Length > 1) ? sp.ValueY[1] : (chartXy.BarOrigin ?? 0));
 | |
| 
 | |
|             ChartAxis axis = AxisY ?? chartXy.AxisY;
 | |
| 
 | |
|             switch (axis.ScaleType)
 | |
|             {
 | |
|                 case ScaleType.Quantitative:
 | |
|                     double d1 = Convert.ToDouble(value);
 | |
|                     double d2 = Convert.ToDouble(sp.ValueY[0]);
 | |
| 
 | |
|                     return (d1.Equals(d2));
 | |
| 
 | |
|                 case ScaleType.Qualitative:
 | |
|                     string s1 = axis.QualitativeValues[0] as string;
 | |
|                     string s2 = sp.ValueY[0] as string;
 | |
| 
 | |
|                     if (s1 != null)
 | |
|                         return (s1.Equals(s2));
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             return (false);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetPointLabelText
 | |
| 
 | |
|         private string GetPointLabelText(SeriesPoint sp,
 | |
|             ChartAxis axisX, ChartAxis axisY, DataLabelVisualStyle dstyle)
 | |
|         {
 | |
|             string pattern = dstyle.TextFormat;
 | |
| 
 | |
|             if (string.IsNullOrEmpty(pattern) == true)
 | |
|                 return (GetDefaultPointLabelText(sp, axisX, axisY, dstyle));
 | |
| 
 | |
|             pattern = pattern.Replace("\\n", "\n");
 | |
|             pattern = pattern.Replace("\\r", "\r");
 | |
| 
 | |
|             Regex regex = new Regex("{([^}]*)}");
 | |
|             MatchCollection mc = regex.Matches(pattern);
 | |
| 
 | |
|             StringBuilder sb = new StringBuilder();
 | |
| 
 | |
|             int index = 0;
 | |
| 
 | |
|             foreach (Match ma in mc)
 | |
|             {
 | |
|                 if (ma.Index > index)
 | |
|                     sb.Append(pattern.Substring(index, ma.Index - index));
 | |
| 
 | |
|                 sb.Append(ProcessFormatSpecifier(sp, axisX, axisY, ma.Value));
 | |
| 
 | |
|                 index = ma.Index + ma.Length;
 | |
|             }
 | |
| 
 | |
|             if (index < pattern.Length)
 | |
|                 sb.Append(pattern.Substring(index));
 | |
| 
 | |
|             return (sb.ToString());
 | |
|         }
 | |
| 
 | |
|         #region ProcessFormatSpecifier
 | |
| 
 | |
|         private string ProcessFormatSpecifier(
 | |
|             SeriesPoint sp, ChartAxis axisX, ChartAxis axisY, string pattern)
 | |
|         {
 | |
|             string s = pattern.Substring(1, pattern.Length - 2);
 | |
| 
 | |
|             int n = s.IndexOf(':');
 | |
| 
 | |
|             if ((uint)n > s.Length - 1)
 | |
|                 n = s.Length;
 | |
| 
 | |
|             string placeHolder = s.Substring(0, n).Trim().ToUpper();
 | |
|             string formatSpecifier = (n + 1 < s.Length) ? s.Substring(n + 1) : "";
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 switch (placeHolder)
 | |
|                 {
 | |
|                     case "X":
 | |
|                         return (GetPointLabelText(sp.ValueX, axisX, formatSpecifier));
 | |
| 
 | |
|                     case "Y":
 | |
|                     case "Y0":
 | |
|                         if (sp.ValueY != null && sp.ValueY.Length > 0)
 | |
|                             return (GetPointLabelText(sp.ValueY[0], axisY, formatSpecifier));
 | |
| 
 | |
|                         return ("");
 | |
| 
 | |
|                     case "S":
 | |
|                         if (string.IsNullOrEmpty(formatSpecifier) == false)
 | |
|                             return (String.Format(formatSpecifier, Name));
 | |
| 
 | |
|                         return (Name);
 | |
| 
 | |
|                     default:
 | |
|                         if (placeHolder.StartsWith("Y") == true)
 | |
|                         {
 | |
|                             int index = int.Parse(placeHolder.Substring(1));
 | |
| 
 | |
|                             if (sp.ValueY != null && sp.ValueY.Length > index)
 | |
|                                 return (GetPointLabelText(sp.ValueY[index], axisY, formatSpecifier));
 | |
|                         }
 | |
| 
 | |
|                         return (s);
 | |
|                 }
 | |
|             }
 | |
|             catch
 | |
|             {
 | |
|             }
 | |
| 
 | |
|             return (s);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetDefaultPointLabelText
 | |
| 
 | |
|         private string GetDefaultPointLabelText(SeriesPoint sp,
 | |
|             ChartAxis axisX, ChartAxis axisY, DataLabelVisualStyle dstyle)
 | |
|         {
 | |
|             String text = string.Empty;
 | |
| 
 | |
|             if (IsBarSeries == true)
 | |
|             {
 | |
|                 text = GetPointLabelText(sp.ValueY[0], axisY, string.Empty);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 text = GetPointLabelText(sp.ValueX, axisX, string.Empty);
 | |
| 
 | |
|                 if (sp.ValueY != null)
 | |
|                     text += " : " + GetPointLabelText(sp.ValueY[0], axisY, string.Empty);
 | |
|             }
 | |
| 
 | |
|             return (text);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetPointLabelText
 | |
| 
 | |
|         private string GetPointLabelText(
 | |
|             object value, ChartAxis axis, string format)
 | |
|         {
 | |
|             switch (axis.ScaleType)
 | |
|             {
 | |
|                 case ScaleType.DateTime:
 | |
|                     if (string.IsNullOrEmpty(format) == false)
 | |
|                     {
 | |
|                         if (value is DateTime)
 | |
|                         {
 | |
|                             DateTime date = (DateTime)value;
 | |
| 
 | |
|                             return (date.ToString(format));
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     return (GetDateTimeLabelText(axis, (DateTime)value));
 | |
| 
 | |
|                 case ScaleType.Qualitative:
 | |
|                     if (string.IsNullOrEmpty(format) == false)
 | |
|                         return (string.Format(format, value));
 | |
| 
 | |
|                     return (value.ToString());
 | |
| 
 | |
|                 default:
 | |
|                     double d = Convert.ToDouble(value);
 | |
| 
 | |
|                     if (string.IsNullOrEmpty(format) == false)
 | |
|                         return (d.ToString(format));
 | |
| 
 | |
|                     return (d.ToString("F3"));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetDateTimeLabelText
 | |
| 
 | |
|         internal string GetDateTimeLabelText(ChartAxis axis, DateTime dt)
 | |
|         {
 | |
|             switch (axis.ActualDateTimeUnits)
 | |
|             {
 | |
|                 case DateTimeUnits.Ticks:
 | |
|                     return (dt.Ticks.ToString());
 | |
| 
 | |
|                 case DateTimeUnits.Milliseconds:
 | |
|                     return (dt.Millisecond.ToString());
 | |
| 
 | |
|                 case DateTimeUnits.Seconds:
 | |
|                     return (dt.Second.ToString());
 | |
| 
 | |
|                 case DateTimeUnits.Minutes:
 | |
|                     return (dt.Minute.ToString());
 | |
| 
 | |
|                 case DateTimeUnits.Hours:
 | |
|                     return (dt.ToShortTimeString());
 | |
| 
 | |
|                 case DateTimeUnits.Days:
 | |
|                     return (dt.ToShortDateString());
 | |
| 
 | |
|                 case DateTimeUnits.Months:
 | |
|                     return (dt.Year + " " + dt.Month);
 | |
| 
 | |
|                 default:
 | |
|                     return (dt.Year.ToString());
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region MeasurePointLabel
 | |
| 
 | |
|         internal Size MeasurePointLabel(Graphics g, PointLabel pl)
 | |
|         {
 | |
|             DataLabelVisualStyle dstyle = GetPointLabelVisualStyle(pl);
 | |
| 
 | |
|             int width = (dstyle.MaxTextWidth > 0) ? dstyle.MaxTextWidth : 0;
 | |
| 
 | |
|             using (StringFormat sf = new StringFormat())
 | |
|             {
 | |
|                 if (dstyle.MaxTextLineCount <= 1)
 | |
|                     sf.FormatFlags |= StringFormatFlags.NoWrap;
 | |
| 
 | |
|                 Size size = g.MeasureString(pl.Label, dstyle.Font, width, sf).ToSize();
 | |
|                 size.Width++;
 | |
| 
 | |
|                 if (dstyle.MaxTextLineCount > 1)
 | |
|                 {
 | |
|                     int lineHeight = (int)(Math.Ceiling(dstyle.Font.GetHeight())) * dstyle.MaxTextLineCount;
 | |
| 
 | |
|                     if (size.Height > lineHeight)
 | |
|                         size.Height = lineHeight;
 | |
|                 }
 | |
| 
 | |
|                 return (size);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetPointLabelVisualStyle
 | |
| 
 | |
|         internal DataLabelVisualStyle GetPointLabelVisualStyle(PointLabel pl)
 | |
|         {
 | |
|             DataLabelVisualStyle dstyle = EffectiveDataLabelStyle.Copy();
 | |
| 
 | |
|             if (pl.DataLabelVisualStyle != null)
 | |
|                 dstyle.ApplyStyle(pl.DataLabelVisualStyle);
 | |
|             else
 | |
|                 dstyle = EffectiveDataLabelStyle;
 | |
| 
 | |
|             return (dstyle);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetRotateDegrees
 | |
| 
 | |
|         internal RotateDegrees GetRotateDegrees(DataLabelVisualStyle dstyle)
 | |
|         {
 | |
|             RotateDegrees degrees = dstyle.RotateDegrees;
 | |
| 
 | |
|             if (degrees == RotateDegrees.Auto || degrees == RotateDegrees.NotSet)
 | |
|             {
 | |
|                 switch (SeriesType)
 | |
|                 {
 | |
|                     case SeriesType.HorizontalBar:
 | |
|                     case SeriesType.HorizontalHiLoBar:
 | |
|                         return (RotateDegrees.None);
 | |
| 
 | |
|                     case SeriesType.VerticalBar:
 | |
|                     case SeriesType.VerticalHiLoBar:
 | |
|                         return (RotateDegrees.Rotate270);
 | |
| 
 | |
|                     default:
 | |
|                         return (RotateDegrees.None);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (dstyle.RotateDegrees);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IsConvexHullPoint
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Determines whether the given SeriesPoint is a ConvexHull point.
 | |
|         /// </summary>
 | |
|         /// <param name="sp"></param>
 | |
|         /// <returns></returns>
 | |
|         public bool IsConvexHullPoint(SeriesPoint sp)
 | |
|         {
 | |
|             if (sp != null && _ConvexHullPoints != null)
 | |
|             {
 | |
|                 ChartXy chartXy = Parent as ChartXy;
 | |
| 
 | |
|                 if (chartXy != null)
 | |
|                 {
 | |
|                     ConvexHullDisplayMode mode = GetConvexHullDisplayMode(chartXy);
 | |
| 
 | |
|                     if (mode != ConvexHullDisplayMode.None)
 | |
|                     {
 | |
|                         foreach (Point ptc in _ConvexHullPoints)
 | |
|                         {
 | |
|                             if (ptc.Equals(sp.Point[0]) == true)
 | |
|                                 return (true);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (false);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IsHighLightPoint
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Determines if the given SeriesPoint is a HighLight Point (a
 | |
|         /// point highlighted by the Crosshair setup).
 | |
|         /// </summary>
 | |
|         /// <param name="sp"></param>
 | |
|         /// <returns></returns>
 | |
|         public bool IsHighLightPoint(SeriesPoint sp)
 | |
|         {
 | |
|             if (sp != null)
 | |
|             {
 | |
|                 ChartXy chartXy = Parent as ChartXy;
 | |
| 
 | |
|                 if (chartXy != null)
 | |
|                     return (chartXy.IsCrosshairSeriesPoint(this, sp.Point[0]));
 | |
|             }
 | |
| 
 | |
|             return (false);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Style handling
 | |
| 
 | |
|         #region ApplyStyles
 | |
| 
 | |
|         internal override void ApplyStyles(BaseVisualStyle style)
 | |
|         {
 | |
|             ChartSeriesVisualStyle sstyle = style as ChartSeriesVisualStyle;
 | |
| 
 | |
|             if (sstyle != null)
 | |
|             {
 | |
|                 ApplyParentStyles(sstyle, Parent as ChartContainer);
 | |
| 
 | |
|                 sstyle.ApplyStyle(ChartSeriesVisualStyle);
 | |
| 
 | |
|                 ApplyDefaultLineStyles(sstyle.LineStyle);
 | |
|                 ApplyDefaultLineStyles(sstyle.SplineStyle);
 | |
|                 ApplyDefaultLineStyles(sstyle.StepLineStyle);
 | |
|                 ApplyDefaultLineStyles(sstyle.EmptyStyle);
 | |
| 
 | |
|                 ApplyDefaultMarkerStyles(sstyle.MarkerVisualStyle);
 | |
|                 ApplyDefaultMarkerStyles(sstyle.MarkerEmptyVisualStyle);
 | |
| 
 | |
|                 if (sstyle.EmptyAreaBackground.IsEmpty)
 | |
|                     sstyle.EmptyAreaBackground = new Background(Color.FromArgb(100, Color.LightGray));
 | |
| 
 | |
|                 if (SeriesType == SeriesType.Bubble)
 | |
|                 {
 | |
|                     if (sstyle.MarkerVisualStyle.Background.IsEmpty)
 | |
|                         sstyle.MarkerVisualStyle.Background = new Background(DefaultPaletteColor);
 | |
|                 }
 | |
| 
 | |
|                 ApplyDefaultBarStyles(sstyle.BarVisualStyle);
 | |
|                 ApplyDefaultOhlcBarStyles(sstyle.HiLoBarVisualStyle);
 | |
|             }
 | |
|             else if (style is DataLabelVisualStyle)
 | |
|             {
 | |
|                 DataLabelVisualStyle dstyle = (DataLabelVisualStyle)style;
 | |
| 
 | |
|                 ApplyParentStyles(dstyle, Parent as ChartContainer);
 | |
| 
 | |
|                 dstyle.ApplyStyle(_DataLabelVisualStyle);
 | |
| 
 | |
|                 dstyle.ApplyDefaults();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region ApplyParentStyles (ChartSeriesVisualStyle)
 | |
| 
 | |
|         private void ApplyParentStyles(
 | |
|             ChartSeriesVisualStyle pstyle, ChartContainer item)
 | |
|         {
 | |
|             if (item != null)
 | |
|             {
 | |
|                 ApplyParentStyles(pstyle, item.Parent as ChartContainer);
 | |
| 
 | |
|                 if (item is BaseChart)
 | |
|                     pstyle.ApplyStyle(((BaseChart)item).ChartSeriesVisualStyle);
 | |
| 
 | |
|                 if (item is ChartPanel)
 | |
|                     pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.ChartSeriesVisualStyle);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 pstyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartPanelVisualStyle);
 | |
|                 pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartPanelVisualStyle);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ApplyParentStyles (DataLabelVisualStyle)
 | |
| 
 | |
|         private void ApplyParentStyles(
 | |
|             DataLabelVisualStyle dstyle, ChartContainer item)
 | |
|         {
 | |
|             if (item != null)
 | |
|             {
 | |
|                 ApplyParentStyles(dstyle, item.Parent as ChartContainer);
 | |
| 
 | |
|                 if (item is BaseChart)
 | |
|                     dstyle.ApplyStyle(((BaseChart)item).DataLabelVisualStyle);
 | |
| 
 | |
|                 if (item is ChartPanel)
 | |
|                     dstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.DataLabelVisualStyle);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 dstyle.ApplyStyle(ChartControl.BaseVisualStyles.DataLabelVisualStyle);
 | |
|                 dstyle.ApplyStyle(ChartControl.DefaultVisualStyles.DataLabelVisualStyle);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ApplyDefaultLineStyles
 | |
| 
 | |
|         private void ApplyDefaultLineStyles(ChartLineVisualStyle lstyle)
 | |
|         {
 | |
|             if (lstyle.LineColor.IsEmpty == true)
 | |
|                 lstyle.LineColor = DefaultPaletteColor;
 | |
| 
 | |
|             lstyle.ApplyDefaults();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ApplyDefaultMarkerStyles
 | |
| 
 | |
|         private void ApplyDefaultMarkerStyles(PointMarkerVisualStyle pstyle)
 | |
|         {
 | |
|             if (pstyle.Background.IsEmpty && pstyle.BorderColor.IsEmpty)
 | |
|                 pstyle.BorderColor = DefaultPaletteColor;
 | |
| 
 | |
|             pstyle.ApplyDefaults();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ApplyDefaultBarStyles
 | |
| 
 | |
|         private void ApplyDefaultBarStyles(ChartBarVisualStyle bstyle)
 | |
|         {
 | |
|             if (bstyle.Background.IsEmpty == true)
 | |
|                 bstyle.Background = new Background(DefaultPaletteColor);
 | |
| 
 | |
|             ApplyDefaultLineStyles(bstyle.Border);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ApplyDefaultOhlcBarStyles
 | |
| 
 | |
|         private void ApplyDefaultOhlcBarStyles(ChartHiLoBarVisualStyle bstyle)
 | |
|         {
 | |
|             HiLoBarSegmentStyle sstyle = bstyle.DefaultSegmentStyle;
 | |
| 
 | |
|             if (sstyle.Default.LineColor.IsEmpty == true)
 | |
|                 sstyle.Default.LineColor = Color.Black;
 | |
| 
 | |
|             sstyle.Default.ApplyDefaults();
 | |
| 
 | |
|             switch (HiLoBarType)
 | |
|             {
 | |
|                 case HiLoBarType.Candle:
 | |
|                     bool backSet = (sstyle.BoxBackground.IsEmpty == true);
 | |
| 
 | |
|                     if (backSet == true)
 | |
|                         sstyle.BoxBackground = new Background(DefaultPaletteColor);
 | |
| 
 | |
|                     Background bk = sstyle.BoxBackground;
 | |
| 
 | |
|                     sstyle = bstyle.AlternateSegmentStyle;
 | |
| 
 | |
|                     if (sstyle.BoxBackground.IsEmpty == true)
 | |
|                     {
 | |
|                         if (backSet == true)
 | |
|                         {
 | |
|                             sstyle.BoxBackground = new Background(Color.Black, DefaultPaletteColor);
 | |
|                             sstyle.BoxBackground.HatchFillType = HatchFillType.ForwardDiagonal;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             if (bk.IsSolidBrush == true)
 | |
|                             {
 | |
|                                 sstyle.BoxBackground = new Background(Color.Black, bk.Color1);
 | |
|                                 sstyle.BoxBackground.HatchFillType = HatchFillType.ForwardDiagonal;
 | |
|                             }
 | |
|                             else if (bk.Color1.IsEmpty == false && bk.Color2.IsEmpty == false)
 | |
|                             {
 | |
|                                 sstyle.BoxBackground = new Background(bk.Color2, bk.Color1);
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case Charts.HiLoBarType.Box:
 | |
|                     if (sstyle.BoxBackground.IsEmpty == true)
 | |
|                         sstyle.BoxBackground = new Background(DefaultPaletteColor);
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             sstyle = bstyle.DefaultSegmentStyle;
 | |
| 
 | |
|             _RenderFullDefRange = sstyle.CenterLine.IsEmpty &&
 | |
|                 sstyle.HighWhisker.IsEmpty && sstyle.LowWhisker.IsEmpty;
 | |
| 
 | |
|             sstyle = bstyle.AlternateSegmentStyle;
 | |
| 
 | |
|             _RenderFullAltRange = sstyle.CenterLine.IsEmpty &&
 | |
|                 sstyle.HighWhisker.IsEmpty && sstyle.LowWhisker.IsEmpty;
 | |
|         }
 | |
| 
 | |
|         private bool _RenderFullDefRange;
 | |
|         private bool _RenderFullAltRange;
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region InvalidateStyle
 | |
| 
 | |
|         ///<summary>
 | |
|         ///Invalidate the cached Style definition
 | |
|         ///</summary>
 | |
|         public void InvalidateStyle()
 | |
|         {
 | |
|             if (_EffectiveChartSeriesStyle.InvalidateStyle() == true)
 | |
|                 InvalidateLayout();
 | |
| 
 | |
|             _EffectiveDataLabelStyle.InvalidateStyle();
 | |
| 
 | |
|             foreach (DataLabel dl in DataLabels)
 | |
|                 dl.InvalidateStyle();
 | |
| 
 | |
|             PointMarkerImage = null;
 | |
|             PointMarkerEmptyImage = null;
 | |
|             PointMarkerHighlightImage = null;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ClearEffectiveStyles
 | |
| 
 | |
|         protected override void ClearEffectiveStyles()
 | |
|         {
 | |
|             _EffectiveChartSeriesStyle.InvalidateStyle();
 | |
|             _EffectiveDataLabelStyle.InvalidateStyle();
 | |
| 
 | |
|             if (LegendItem != null)
 | |
|                 LegendItem.EffectiveStyles.InvalidateStyles();
 | |
| 
 | |
|             PointMarkerImage = null;
 | |
|             PointMarkerEmptyImage = null;
 | |
|             PointMarkerHighlightImage = null;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region StyleChanged
 | |
| 
 | |
|         protected override void StyleChanged(object sender, PropertyChangedEventArgs e)
 | |
|         {
 | |
|             base.StyleChanged(sender, e);
 | |
| 
 | |
|             if (sender is ChartLegendItemVisualStyles && LegendItem != null)
 | |
|                 InvalidateRender(LegendItem.Bounds);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region InvalidateRender
 | |
| 
 | |
|         public override void InvalidateRender()
 | |
|         {
 | |
|             ChartXy chartXy = Parent as ChartXy;
 | |
| 
 | |
|             if (chartXy != null)
 | |
|                 chartXy.InvalidateRender();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ILegendItem
 | |
| 
 | |
|         #region CheckedInLegend
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether the series is checked in the Legend.
 | |
|         /// </summary>
 | |
|         [DefaultValue(true), Category("Legend")]
 | |
|         [Description("Indicates whether the series is checked in the Legend.")]
 | |
|         public bool CheckedInLegend
 | |
|         {
 | |
|             get { return (TestState(States.CheckedInLegend)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != CheckedInLegend)
 | |
|                 {
 | |
|                     SetState(States.CheckedInLegend, value);
 | |
| 
 | |
|                     if (IsQualitativeXValues || IsQualitativeYValues)
 | |
|                         InvalidateLayout();
 | |
| 
 | |
|                     if (PointLabelDisplayMode != PointLabelDisplayMode.None)
 | |
|                         InvalidatePointLabels();
 | |
| 
 | |
|                     if (LegendItem != null)
 | |
|                         LegendItem.UpdateCheckState();
 | |
| 
 | |
|                     OnPropertyChangedEx("CheckedInLegend", VisualChangeType.Render);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ShowCheckBoxInLegend
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether a checkbox for the series is shown in the Legend.
 | |
|         /// </summary>
 | |
|         [DefaultValue(true), Category("Legend")]
 | |
|         [Description("Indicates whether a checkbox for the series is shown in the Legend.")]
 | |
|         public bool ShowCheckBoxInLegend
 | |
|         {
 | |
|             get { return (TestState(States.ShowCheckBoxInLegend)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != ShowCheckBoxInLegend)
 | |
|                 {
 | |
|                     SetState(States.ShowCheckBoxInLegend, value);
 | |
| 
 | |
|                     OnPropertyChangedEx("ShowCheckBoxInLegend", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ShowInLegend
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether the series is shown in the Legend.
 | |
|         /// </summary>
 | |
|         [DefaultValue(true), Category("Legend")]
 | |
|         [Description("Indicates whether the series is shown in the Legend.")]
 | |
|         public bool ShowInLegend
 | |
|         {
 | |
|             get { return (TestState(States.ShowInLegend)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != ShowInLegend)
 | |
|                 {
 | |
|                     SetState(States.ShowInLegend, value);
 | |
| 
 | |
|                     OnPropertyChangedEx("ShowInLegend", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ShowInParentLegend
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether the series is shown in parent Legend(s).
 | |
|         /// </summary>
 | |
|         [DefaultValue(true), Category("Legend")]
 | |
|         [Description("Indicates whether the series is shown in parent Legend(s).")]
 | |
|         public bool ShowInParentLegend
 | |
|         {
 | |
|             get { return (TestState(States.ShowInParentLegend)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != ShowInParentLegend)
 | |
|                 {
 | |
|                     SetState(States.ShowInParentLegend, value);
 | |
| 
 | |
|                     OnPropertyChangedEx("ShowInParentLegend", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ShowMarkerInLegend
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether the series Marker is shown in the Legend.
 | |
|         /// </summary>
 | |
|         [DefaultValue(true), Category("Legend")]
 | |
|         [Description("Indicates whether the series Marker is shown in the Legend.")]
 | |
|         public bool ShowMarkerInLegend
 | |
|         {
 | |
|             get { return (TestState(States.ShowMarkerInLegend)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != ShowMarkerInLegend)
 | |
|                 {
 | |
|                     SetState(States.ShowMarkerInLegend, value);
 | |
| 
 | |
|                     OnPropertyChangedEx("ShowMarkerInLegend", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region LegendItem
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets the item's parent LegendItem.
 | |
|         ///</summary>
 | |
|         [Browsable(false)]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | |
|         [Description("Indicates the item's parent LegendItem.")]
 | |
|         public ChartLegendItem LegendItem
 | |
|         {
 | |
|             get { return (_LegendItem); }
 | |
| 
 | |
|             internal set
 | |
|             {
 | |
|                 if (_LegendItem != null)
 | |
|                     _LegendItem.Dispose();
 | |
| 
 | |
|                 _LegendItem = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region LegendText
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the text to display in the legend.
 | |
|         ///</summary>
 | |
|         [DefaultValue(null), Category("Legend")]
 | |
|         [Description("Indicates the text to display in the legend.")]
 | |
|         public string LegendText
 | |
|         {
 | |
|             get { return (_LegendText); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _LegendText)
 | |
|                 {
 | |
|                     _LegendText = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("LegendText", Style.VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetLegendItem
 | |
| 
 | |
|         public ChartLegendItem GetLegendItem()
 | |
|         {
 | |
|             LegendItem = null;
 | |
| 
 | |
|             if (ShowInLegend == true)
 | |
|             {
 | |
|                 ChartXy chartXy = Parent as ChartXy;
 | |
| 
 | |
|                 LegendItem = new ChartLegendItem();
 | |
| 
 | |
|                 if (CheckedInLegend == true)
 | |
|                     _LegendItem.CheckState = CheckState.Checked;
 | |
| 
 | |
|                 _LegendItem.Parent = chartXy.Legend;
 | |
| 
 | |
|                 _LegendItem.Name = Name;
 | |
|                 _LegendItem.ItemText = LegendText;
 | |
| 
 | |
|                 if (string.IsNullOrEmpty(_LegendItem.Name) == true)
 | |
|                     _LegendItem.Name = "(Series)";
 | |
| 
 | |
|                 _LegendItem.ChartItems.Add(this);
 | |
|             }
 | |
| 
 | |
|             return (_LegendItem);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetLegendItems
 | |
| 
 | |
|         public List<ChartLegendItem> GetLegendItems()
 | |
|         {
 | |
|             List<ChartLegendItem> list = new List<ChartLegendItem>();
 | |
| 
 | |
|             ChartLegendItem item = GetLegendItem();
 | |
| 
 | |
|             if (item != null)
 | |
|                 list.Add(item);
 | |
| 
 | |
|             foreach (ChartIndicator ci in ChartIndicators)
 | |
|             {
 | |
|                 if (ci.Visible == true)
 | |
|                 {
 | |
|                     ChartLegendItem li = ci.GetLegendItem();
 | |
| 
 | |
|                     if (li != null)
 | |
|                         list.Add(li);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (list);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetLegendItemColor
 | |
| 
 | |
|         public Color GetLegendItemColor()
 | |
|         {
 | |
|             ChartXy chartXy = Parent as ChartXy;
 | |
| 
 | |
|             ChartLegendItemVisualStyle lstyle = ChartLegendItemVisualStyles[StyleType.Default];
 | |
| 
 | |
|             if (lstyle.TextColor.IsEmpty == false)
 | |
|                 return (lstyle.TextColor);
 | |
| 
 | |
|             Color color = Color.Empty;
 | |
| 
 | |
|             ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle;
 | |
| 
 | |
|             if (sstyle.ItemColor.IsEmpty == false)
 | |
|                 return (sstyle.ItemColor);
 | |
| 
 | |
|             PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle;
 | |
| 
 | |
|             switch (SeriesType)
 | |
|             {
 | |
|                 case SeriesType.Bubble:
 | |
|                 case SeriesType.Point:
 | |
|                 case SeriesType.HorizontalDot:
 | |
|                 case SeriesType.VerticalDot:
 | |
|                     color = pstyle.Background.Color1;
 | |
|                     break;
 | |
| 
 | |
|                 case SeriesType.Line:
 | |
|                     ChartLineDisplayMode mode = GetLineDisplayMode(chartXy);
 | |
| 
 | |
|                     if ((mode & ChartLineDisplayMode.DisplayLine) == ChartLineDisplayMode.DisplayLine)
 | |
|                         color = sstyle.LineStyle.LineColor;
 | |
| 
 | |
|                     else if ((mode & ChartLineDisplayMode.DisplaySpline) == ChartLineDisplayMode.DisplaySpline)
 | |
|                         color = sstyle.SplineStyle.LineColor;
 | |
| 
 | |
|                     else if ((mode & ChartLineDisplayMode.DisplayStepLine) == ChartLineDisplayMode.DisplayStepLine)
 | |
|                         color = sstyle.StepLineStyle.LineColor;
 | |
| 
 | |
|                     if (color.IsEmpty == true)
 | |
|                         color = pstyle.Background.Color1;
 | |
|                     break;
 | |
| 
 | |
|                 case SeriesType.HorizontalBar:
 | |
|                 case SeriesType.VerticalBar:
 | |
|                     ChartBarVisualStyle bstyle = sstyle.BarVisualStyle;
 | |
|                     color = bstyle.Background.Color1;
 | |
|                     break;
 | |
| 
 | |
|                 case SeriesType.HorizontalHiLoBar:
 | |
|                 case SeriesType.VerticalHiLoBar:
 | |
|                     HiLoBarSegmentStyle hstyle = sstyle.HiLoBarVisualStyle.DefaultSegmentStyle;
 | |
| 
 | |
|                     if (HiLoBarType == HiLoBarType.Line)
 | |
|                     {
 | |
|                         color = hstyle.Default.LineColor;
 | |
| 
 | |
|                         if (color.IsEmpty == true)
 | |
|                             color = hstyle.CenterLine.LineColor;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         color = hstyle.BoxBackground.Color1;
 | |
|                     }
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             if (color.IsEmpty == true)
 | |
|                 color = _DefaultPaletteColor;
 | |
| 
 | |
|             return (color);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderLegendItemMarker
 | |
| 
 | |
|         public void RenderLegendItemMarker(Graphics g,
 | |
|             ChartLegendItem litem, ChartLegendItemVisualStyle style)
 | |
|         {
 | |
|             ChartXy chartXy = Parent as ChartXy;
 | |
|             ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle;
 | |
| 
 | |
|             Rectangle bounds = litem.MarkerBounds;
 | |
| 
 | |
|             SmoothingMode sm = g.SmoothingMode;
 | |
|             g.SmoothingMode = SmoothingMode.AntiAlias;
 | |
| 
 | |
|             switch (SeriesType)
 | |
|             {
 | |
|                 case SeriesType.HorizontalHiLoBar:
 | |
|                 case SeriesType.VerticalHiLoBar:
 | |
|                     RenderHiLoBarMarker(g, bounds, chartXy, sstyle);
 | |
|                     break;
 | |
| 
 | |
|                 case SeriesType.VerticalBar:
 | |
|                 case SeriesType.HorizontalBar:
 | |
|                     RenderBarMarker(g, bounds, chartXy, sstyle);
 | |
|                     break;
 | |
| 
 | |
|                 case SeriesType.Bubble:
 | |
|                     RenderBubbleMarker(g, bounds, chartXy, sstyle);
 | |
|                     break;;
 | |
| 
 | |
|                 case SeriesType.VerticalDot:
 | |
|                 case SeriesType.HorizontalDot:
 | |
|                 case SeriesType.Point:
 | |
|                     RenderDotMarker(g, bounds, chartXy, sstyle);
 | |
|                     break;
 | |
| 
 | |
|                 case SeriesType.Line:
 | |
|                     RenderLineMarker(g, bounds, chartXy, sstyle);
 | |
|                     break;
 | |
| 
 | |
|                 default:
 | |
|                     RenderDefaultMarker(g, bounds, sstyle);
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             g.SmoothingMode = sm;
 | |
|         }
 | |
| 
 | |
|         #region RenderHiLoBarMarker
 | |
| 
 | |
|         private void RenderHiLoBarMarker(Graphics g,
 | |
|             Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             Rectangle r = bounds;
 | |
|             r.Inflate(-1, -1);
 | |
| 
 | |
|             if (r.Width > 0 && r.Height > 0)
 | |
|             {
 | |
|                 SmoothingMode sm = g.SmoothingMode;
 | |
|                 g.SmoothingMode = SmoothingMode.None;
 | |
| 
 | |
|                 HiLoBarSegmentStyle hstyle = sstyle.HiLoBarVisualStyle.DefaultSegmentStyle;
 | |
| 
 | |
|                 if (HiLoBarType == HiLoBarType.Line)
 | |
|                 {
 | |
|                     Color color = hstyle.Default.LineColor;
 | |
| 
 | |
|                     if (color.IsEmpty == true)
 | |
|                         color = hstyle.CenterLine.LineColor;
 | |
| 
 | |
|                     if (color.IsEmpty == true)
 | |
|                         color = _DefaultPaletteColor;
 | |
| 
 | |
|                     if (color.IsEmpty == true)
 | |
|                         color = Color.Black;
 | |
| 
 | |
|                     if (IsRotated == true || r.Width > r.Height)
 | |
|                         RenderHiLoHBarMarker(g, r, color);
 | |
|                     else
 | |
|                         RenderHiLoVBarMarker(g, r, color);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     Background bk = hstyle.BoxBackground;
 | |
|                     ChartLineVisualStyle lstyle = hstyle.BoxBorder;
 | |
| 
 | |
|                     if (IsRotated == true || r.Width > r.Height)
 | |
|                         RenderHBoxMarker(g, r, bk, hstyle, lstyle);
 | |
|                     else
 | |
|                         RenderVBoxMarker(g, r, bk, hstyle, lstyle);
 | |
|                 }
 | |
| 
 | |
|                 g.SmoothingMode = sm;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderHBoxMarker
 | |
| 
 | |
|         private void RenderHBoxMarker(Graphics g, Rectangle r,
 | |
|             Background bk, HiLoBarSegmentStyle hstyle, ChartLineVisualStyle lstyle)
 | |
|         {
 | |
|             int n = r.Height / 4;
 | |
| 
 | |
|             Rectangle t = r;
 | |
|             t.Inflate(-n, -n);
 | |
| 
 | |
|             if (t.Height % 2 != 0)
 | |
|             {
 | |
|                 t.Y--;
 | |
|                 t.Height++;
 | |
|             }
 | |
| 
 | |
|             using (Brush br = bk.GetBrush(t))
 | |
|                 g.FillRectangle(br, t);
 | |
| 
 | |
|             Color lineColor = lstyle.LineColor;
 | |
| 
 | |
|             if (lineColor.IsEmpty == true)
 | |
|                 lineColor = hstyle.Default.LineColor;
 | |
| 
 | |
|             if (lineColor.IsEmpty == true)
 | |
|                 lineColor = Color.Black;
 | |
| 
 | |
|             using (Pen pen = new Pen(lineColor))
 | |
|             {
 | |
|                 Point pt1 = new Point(r.X, (r.Y + r.Bottom) / 2);
 | |
|                 Point pt2 = new Point(t.X, pt1.Y);
 | |
| 
 | |
|                 g.DrawLine(pen, pt1, pt2);
 | |
| 
 | |
|                 pt1.X = t.Right;
 | |
|                 pt2.X = r.Right;
 | |
| 
 | |
|                 g.DrawLine(pen, pt1, pt2);
 | |
|             }
 | |
| 
 | |
|             using (Pen pen = new Pen(lineColor))
 | |
|                 g.DrawRectangle(pen, t);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderVBoxMarker
 | |
| 
 | |
|         private void RenderVBoxMarker(Graphics g, Rectangle r,
 | |
|             Background bk, HiLoBarSegmentStyle hstyle, ChartLineVisualStyle lstyle)
 | |
|         {
 | |
|             int n = r.Width / 4;
 | |
| 
 | |
|             Rectangle t = r;
 | |
|             t.Inflate(-n, -n);
 | |
| 
 | |
|             if (t.Width % 2 != 0)
 | |
|             {
 | |
|                 t.X--;
 | |
|                 t.Width++;
 | |
|             }
 | |
| 
 | |
|             using (Brush br = bk.GetBrush(t))
 | |
|                 g.FillRectangle(br, t);
 | |
| 
 | |
|             Color lineColor = lstyle.LineColor;
 | |
| 
 | |
|             if (lineColor.IsEmpty == true)
 | |
|                 lineColor = hstyle.Default.LineColor;
 | |
| 
 | |
|             if (lineColor.IsEmpty == true)
 | |
|                 lineColor = Color.Black;
 | |
| 
 | |
|             using (Pen pen = new Pen(lineColor))
 | |
|             {
 | |
|                 Point pt1 = new Point((r.X + r.Right) / 2, r.Y);
 | |
|                 Point pt2 = new Point(pt1.X, t.Y);
 | |
| 
 | |
|                 g.DrawLine(pen, pt1, pt2);
 | |
| 
 | |
|                 pt1.Y = t.Bottom;
 | |
|                 pt2.Y = r.Bottom;
 | |
| 
 | |
|                 g.DrawLine(pen, pt1, pt2);
 | |
|             }
 | |
| 
 | |
|             using (Pen pen = new Pen(lineColor))
 | |
|                 g.DrawRectangle(pen, t);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderHiLoHBarMarker
 | |
| 
 | |
|         private void RenderHiLoHBarMarker(Graphics g, Rectangle r, Color color)
 | |
|         {
 | |
|             Point pt1 = new Point(r.X, (r.Y + r.Bottom) / 2);
 | |
|             Point pt2 = new Point(r.Right, pt1.Y);
 | |
| 
 | |
|             using (Pen pen = new Pen(color))
 | |
|             {
 | |
|                 g.DrawLine(pen, pt1, pt2);
 | |
| 
 | |
|                 int n = (r.Bottom - r.Top) / 3;
 | |
| 
 | |
|                 pt1.X = r.X + (r.Width / 4);
 | |
|                 pt1.Y -= n;
 | |
| 
 | |
|                 pt2.X = pt1.X;
 | |
| 
 | |
|                 g.DrawLine(pen, pt1, pt2);
 | |
| 
 | |
|                 pt1.X = r.X + (r.Width / 4) * 3;
 | |
|                 pt1.Y += (2 * n);
 | |
|                 pt2.X = pt1.X;
 | |
| 
 | |
|                 g.DrawLine(pen, pt1, pt2);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderHiLoVBarMarker
 | |
| 
 | |
|         private void RenderHiLoVBarMarker(Graphics g, Rectangle r, Color color)
 | |
|         {
 | |
|             Point pt1 = new Point((r.X + r.Right) / 2, r.Y);
 | |
|             Point pt2 = new Point(pt1.X, r.Bottom);
 | |
| 
 | |
|             using (Pen pen = new Pen(color))
 | |
|             {
 | |
|                 g.DrawLine(pen, pt1, pt2);
 | |
| 
 | |
|                 int n = (r.Right - r.Left) / 3;
 | |
| 
 | |
|                 pt1.X -= n;
 | |
|                 pt1.Y = r.Y + (r.Height / 4);
 | |
|                 pt2.Y = pt1.Y;
 | |
| 
 | |
|                 g.DrawLine(pen, pt1, pt2);
 | |
| 
 | |
|                 pt1.X += (2 * n);
 | |
|                 pt1.Y = r.Y + (r.Height / 4) * 3;
 | |
|                 pt2.Y = pt1.Y;
 | |
| 
 | |
|                 g.DrawLine(pen, pt1, pt2);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderBarMarker
 | |
| 
 | |
|         private void RenderBarMarker(Graphics g, Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             ChartLineVisualStyle cstyle = sstyle.BarVisualStyle.Border;
 | |
|             Background bk = sstyle.BarVisualStyle.Background;
 | |
| 
 | |
|             Rectangle r = bounds;
 | |
|             r.Inflate(-1, -1);
 | |
| 
 | |
|             using (Brush br = bk.GetBrush(r))
 | |
|             {
 | |
|                 g.FillRectangle(br, r);
 | |
| 
 | |
|                 if (cstyle.LineColor.IsEmpty == false && cstyle.LinePattern != LinePattern.None)
 | |
|                 {
 | |
|                     using (Pen pen = new Pen(cstyle.LineColor, cstyle.LineWidth))
 | |
|                     {
 | |
|                         if (cstyle.LinePattern != LinePattern.NotSet)
 | |
|                             pen.DashStyle = (DashStyle)cstyle.LinePattern;
 | |
| 
 | |
|                         g.DrawRectangle(pen, r);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderBubbleMarker
 | |
| 
 | |
|         private void RenderBubbleMarker(Graphics g,
 | |
|             Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle;
 | |
| 
 | |
|             Background bk = pstyle.Background;
 | |
| 
 | |
|             Rectangle r = bounds;
 | |
|             r.Inflate(-1, -1);
 | |
| 
 | |
|             using (Brush br = pstyle.Background.GetBrush(r))
 | |
|             {
 | |
|                 g.FillEllipse(br, r);
 | |
| 
 | |
|                 if (pstyle.BorderColor.IsEmpty == false && pstyle.BorderWidth > 0)
 | |
|                 {
 | |
|                     using (Pen pen = new Pen(pstyle.BorderColor, pstyle.BorderWidth))
 | |
|                         g.DrawEllipse(pen, r);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderDotMarker
 | |
| 
 | |
|         private void RenderDotMarker(Graphics g,
 | |
|             Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle;
 | |
| 
 | |
|             Image marker = pstyle.GetPointMarkerImage();
 | |
| 
 | |
|             if (marker != null)
 | |
|             {
 | |
|                 g.DrawImage(marker, bounds);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 marker = chartXy.GetPointMarker(g, pstyle.Type, pstyle.PointCount,
 | |
|                     bounds.Size, pstyle.Rotation, pstyle.Background,
 | |
|                     pstyle.BorderColor, pstyle.BorderWidth);
 | |
| 
 | |
|                 if (marker != null)
 | |
|                 {
 | |
|                     // Make allowances for the fact that GetPointMarker() adjusts the
 | |
|                     // size and pos of the image to allow for better anti-aliasing
 | |
| 
 | |
|                     bounds.X--;
 | |
|                     bounds.Y--;
 | |
| 
 | |
|                     g.DrawImageUnscaled(marker, bounds);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     RenderDefaultMarker(g, bounds, sstyle);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderLineMarker
 | |
| 
 | |
|         private void RenderLineMarker(Graphics g, 
 | |
|             Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             ChartLineDisplayMode mode = GetLineDisplayMode(chartXy);
 | |
| 
 | |
|            int n = bounds.Height / 2;
 | |
| 
 | |
|             using (Pen pen = new Pen(GetLegendItemColor()))
 | |
|             {
 | |
|                 g.DrawLine(pen,
 | |
|                     new Point(bounds.X, bounds.Y + n),
 | |
|                     new Point(bounds.Right - 1, bounds.Y + n));
 | |
|             }
 | |
| 
 | |
|             if ((mode & ChartLineDisplayMode.DisplayPoints) == ChartLineDisplayMode.DisplayPoints)
 | |
|             {
 | |
|                 n = Math.Min(bounds.Height, bounds.Width);
 | |
|                 n = (int)Math.Ceiling((double)n / 2);
 | |
| 
 | |
|                 if (n % 2 == 0)
 | |
|                     n++;
 | |
| 
 | |
|                 Rectangle r = bounds;
 | |
| 
 | |
|                 r.X += ((r.Width - n) / 2);
 | |
|                 r.Y += ((r.Height - n) / 2);
 | |
| 
 | |
|                 r.Width = n;
 | |
|                 r.Height = n;
 | |
| 
 | |
|                 PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle;
 | |
| 
 | |
|                 Image marker2 = chartXy.GetPointMarker(g, pstyle.Type, pstyle.PointCount,
 | |
|                     r.Size, 0, pstyle.Background, pstyle.BorderColor, pstyle.BorderWidth > 0 ? 1 : 0);
 | |
| 
 | |
|                 if (marker2 != null)
 | |
|                 {
 | |
|                     // Make allowances for the fact that GetPointMarker() adjusts the
 | |
|                     // size and pos of the image to allow for better anti-aliasing
 | |
| 
 | |
|                     r.X--;
 | |
|                     r.Y--;
 | |
| 
 | |
|                     g.DrawImageUnscaled(marker2, r);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     RenderDefaultMarker(g, bounds, sstyle);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|         
 | |
|         #region RenderDefaultMarker
 | |
| 
 | |
|         private void RenderDefaultMarker(Graphics g,
 | |
|             Rectangle bounds, ChartSeriesVisualStyle sstyle)
 | |
|         {
 | |
|             bounds.Width++;
 | |
|             bounds.Height++;
 | |
| 
 | |
|             Background background = sstyle.MarkerVisualStyle.Background;
 | |
| 
 | |
|             if (background.IsEmpty == true)
 | |
|             {
 | |
|                 g.FillRectangle(Brushes.DimGray, bounds);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 using (Brush br = background.GetBrush(bounds))
 | |
|                     g.FillRectangle(br, bounds);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Copy/CopyTo
 | |
| 
 | |
|         public override ChartVisualElement Copy()
 | |
|         {
 | |
|             ChartSeries copy = new ChartSeries();
 | |
| 
 | |
|             CopyTo(copy);
 | |
| 
 | |
|             return (copy);
 | |
|         }
 | |
| 
 | |
|         public override void CopyTo(ChartVisualElement copy)
 | |
|         {
 | |
|             ChartSeries c = copy as ChartSeries;
 | |
| 
 | |
|             if (c != null)
 | |
|             {
 | |
|                 base.CopyTo(c);
 | |
| 
 | |
|                 c.AxisX = AxisX;
 | |
|                 c.AxisY = AxisY;
 | |
| 
 | |
|                 c.AreaBaseValue = AreaBaseValue;
 | |
| 
 | |
|                 c.BarFillRange = BarFillRange;
 | |
|                 c.BarLabelPosition = BarLabelPosition;
 | |
|                 c.BarShadingEnabled = BarShadingEnabled;
 | |
|                 c.BarWidthRatio = BarWidthRatio;
 | |
| 
 | |
|                 c.BubbleIntensityMode = BubbleIntensityMode;
 | |
|                 c.BubbleScaleFactor = BubbleScaleFactor;
 | |
|                 c.BubbleSizeMode = BubbleSizeMode;
 | |
| 
 | |
|                 foreach (ChartIndicator ci in ChartIndicators)
 | |
|                     c.ChartIndicators.Add((ChartIndicator)ci.Copy());
 | |
| 
 | |
|                 c.ChartLegendItemVisualStyles =
 | |
|                     (_ChartLegendItemVisualStyles != null) ? ChartLegendItemVisualStyles.Copy() : null;
 | |
| 
 | |
|                 c.ChartLineAreaDisplayMode = ChartLineAreaDisplayMode;
 | |
|                 c.ChartLineDisplayMode = ChartLineDisplayMode;
 | |
| 
 | |
|                 c.ChartSeriesVisualStyle =
 | |
|                     (_ChartSeriesVisualStyle != null) ? ChartSeriesVisualStyle.Copy() : null;
 | |
| 
 | |
|                 c.ConvexHullDisplayMode = ConvexHullDisplayMode;
 | |
| 
 | |
|                 c.CrosshairEnabled = CrosshairEnabled;
 | |
|                 c.CrosshairHighlightPoints = CrosshairHighlightPoints;
 | |
|                 c.CrosshairShowLabels = CrosshairShowLabels;
 | |
| 
 | |
|                 foreach (DataLabel dl in DataLabels)
 | |
|                     c.DataLabels.Add((DataLabel)dl.Copy());
 | |
| 
 | |
|                 c.DataLabelVisualStyle =
 | |
|                     (_DataLabelVisualStyle != null) ? DataLabelVisualStyle.Copy() : null;
 | |
| 
 | |
|                 c.DataPropertyNameSeries = DataPropertyNameSeries;
 | |
|                 c.DataPropertyNameX = DataPropertyNameX;
 | |
|                 c.DataPropertyNamesY = DataPropertyNamesY;
 | |
| 
 | |
|                 c.DataMember = DataMember;
 | |
|                 c.DataSource = DataSource;
 | |
| 
 | |
|                 c.DefaultPaletteColor = DefaultPaletteColor;
 | |
|                 c.DisplayLinePointsOnTop = DisplayLinePointsOnTop;
 | |
|                 c.DotPlotIndexValue = DotPlotIndexValue;
 | |
|                 c.EmptyValues = EmptyValues;
 | |
|                 c.EnableEmptyValues = EnableEmptyValues;
 | |
|                 c.GroupId = GroupId;
 | |
| 
 | |
|                 c.PointLabelDisplayMode = PointLabelDisplayMode;
 | |
|                 c.PointLabelMinDistance = PointLabelMinDistance;
 | |
|                 c.PointLabelSkip = PointLabelSkip;
 | |
| 
 | |
|                 c.ScaleTypeX = ScaleTypeX;
 | |
|                 c.ScaleTypeY = ScaleTypeY;
 | |
| 
 | |
|                 foreach (SeriesPoint sp in SeriesPoints)
 | |
|                     c.SeriesPoints.Add(sp.Copy());
 | |
| 
 | |
|                 c.SeriesType = SeriesType;
 | |
| 
 | |
|                 c.ShowEmptyLines = ShowEmptyLines;
 | |
|                 c.ShowEmptyPoints = ShowEmptyPoints;
 | |
|                 c.ShowHiLoBarMedianLines = ShowHiLoBarMedianLines;
 | |
|                 c.ShowOriginValueLabels = ShowOriginValueLabels;
 | |
|                 c.StackQualitativePoints = StackQualitativePoints;
 | |
| 
 | |
|                 c.StepLines = StepLines;
 | |
|                 c.StepLineMode = StepLineMode;
 | |
| 
 | |
|                 c.CheckedInLegend = CheckedInLegend;
 | |
|                 c.LegendText = LegendText;
 | |
|                 c.ShowCheckBoxInLegend = ShowCheckBoxInLegend;
 | |
|                 c.ShowInLegend = ShowInLegend;
 | |
|                 c.ShowInParentLegend = ShowInParentLegend;
 | |
|                 c.ShowMarkerInLegend = ShowMarkerInLegend;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetSerialData
 | |
| 
 | |
|         internal override SerialElementCollection GetSerialData(string serialName)
 | |
|         {
 | |
|             SerialElementCollection sec = new SerialElementCollection();
 | |
| 
 | |
|             if (serialName != null)
 | |
|             {
 | |
|                 if (serialName.Equals("") == true)
 | |
|                     serialName = "ChartSeries";
 | |
| 
 | |
|                 sec.AddStartElement(serialName);
 | |
|             }
 | |
| 
 | |
|             if (AxisX != null && string.IsNullOrEmpty(AxisX.Name) == false)
 | |
|                 sec.AddValue("AxisX", AxisX.Name);
 | |
| 
 | |
|             if (AxisY != null && string.IsNullOrEmpty(AxisY.Name) == false)
 | |
|                 sec.AddValue("AxisY", AxisY.Name);
 | |
| 
 | |
|             sec.AddDataValue("AreaBaseValue", AreaBaseValue, null);
 | |
| 
 | |
|             sec.AddValue("BarFillRange", BarFillRange, BarFillRange.NotSet);
 | |
|             sec.AddValue("BarLabelPosition", BarLabelPosition, BarLabelPosition.NotSet);
 | |
|             sec.AddValue("BarShadingEnabled", BarShadingEnabled, Tbool.NotSet);
 | |
|             sec.AddValue("BarWidthRatio", BarWidthRatio, 0d);
 | |
| 
 | |
|             sec.AddValue("BubbleIntensityMode", BubbleIntensityMode, BubbleIntensityMode.NotSet);
 | |
|             sec.AddValue("BubbleScaleFactor", BubbleScaleFactor, 1.0d);
 | |
|             sec.AddValue("BubbleSizeMode", BubbleSizeMode, BubbleSizeMode.NotSet);
 | |
| 
 | |
|             if (_ChartIndicators != null && _ChartIndicators.Count > 0)
 | |
|             {
 | |
|                 sec.AddStartElement("ChartIndicators count=\"" + _ChartIndicators.Count + "\"");
 | |
| 
 | |
|                 foreach (ChartIndicator ci in _ChartIndicators)
 | |
|                     sec.AddElement(ci.GetSerialData(""));
 | |
| 
 | |
|                 sec.AddEndElement("ChartIndicators");
 | |
|             }
 | |
| 
 | |
|             if (_ChartLegendItemVisualStyles != null)
 | |
|                 sec.AddElement(_ChartLegendItemVisualStyles.GetSerialData("ChartLegendItemVisualStyles"));
 | |
| 
 | |
|             sec.AddValue("ChartLineAreaDisplayMode", ChartLineAreaDisplayMode, ChartLineAreaDisplayMode.NotSet);
 | |
|             sec.AddValue("ChartLineDisplayMode", ChartLineDisplayMode, ChartLineDisplayMode.NotSet);
 | |
| 
 | |
|             if (_ChartSeriesVisualStyle != null)
 | |
|                 sec.AddElement(_ChartSeriesVisualStyle.GetSerialData("ChartSeriesVisualStyle"));
 | |
| 
 | |
|             sec.AddValue("ConvexHullDisplayMode", ConvexHullDisplayMode, ConvexHullDisplayMode.NotSet);
 | |
|             sec.AddValue("CrosshairEnabled", CrosshairEnabled, Tbool.NotSet);
 | |
|             sec.AddValue("CrosshairHighlightPoints", CrosshairHighlightPoints, Tbool.NotSet);
 | |
|             sec.AddValue("CrosshairShowLabels", CrosshairShowLabels, Tbool.NotSet);
 | |
| 
 | |
|             if (_DataLabels != null && _DataLabels.Count > 0)
 | |
|             {
 | |
|                 sec.AddStartElement("DataLabels count=\"" + _DataLabels.Count + "\"");
 | |
| 
 | |
|                 foreach (DataLabel dl in _DataLabels)
 | |
|                     sec.AddElement(dl.GetSerialData(""));
 | |
| 
 | |
|                 sec.AddEndElement("DataLabels");
 | |
|             }
 | |
| 
 | |
|             if (_DataLabelVisualStyle != null)
 | |
|                 sec.AddElement(_DataLabelVisualStyle.GetSerialData("DataLabelVisualStyle"));
 | |
| 
 | |
|             //sec.AddDataValue("DataSource", DataSource, null);
 | |
|             sec.AddValue("DataMember", DataMember, null);
 | |
| 
 | |
|             sec.AddValue("DataPropertyNameSeries", DataPropertyNameSeries, null);
 | |
|             sec.AddValue("DataPropertyNameX", DataPropertyNameX, null);
 | |
| 
 | |
|             if (_DataPropertyNamesY != null && _DataPropertyNamesY.Count > 0)
 | |
|             {
 | |
|                 sec.AddStartElement("DataPropertyNamesYs count=\"" + _DataPropertyNamesY.Count + "\"");
 | |
| 
 | |
|                 foreach (string s in _DataPropertyNamesY)
 | |
|                     sec.AddValue("DataPropertyNamesY", s);
 | |
| 
 | |
|                 sec.AddEndElement("DataPropertyNamesYs");
 | |
|             }
 | |
| 
 | |
|             sec.AddValue("DefaultPaletteColor", DefaultPaletteColor, Color.Empty);
 | |
|             sec.AddValue("DisplayLinePointsOnTop", DisplayLinePointsOnTop, true);
 | |
|             sec.AddValue("DotPlotIndexValue", DotPlotIndexValue, 1.0d);
 | |
| 
 | |
|             if (_EmptyValues != null && _EmptyValues.Length > 0)
 | |
|             {
 | |
|                 sec.AddStartElement("EmptyValues count=\"" + _EmptyValues.Length + "\"");
 | |
| 
 | |
|                 foreach (object value in _EmptyValues)
 | |
|                     sec.AddValue("EmptyValue", value);
 | |
| 
 | |
|                 sec.AddEndElement("EmptyValues");
 | |
|             }
 | |
| 
 | |
|             sec.AddValue("EnableEmptyValues", EnableEmptyValues, false);
 | |
|             sec.AddValue("GroupId", GroupId, 0);
 | |
|             sec.AddValue("HiLoBarType", HiLoBarType, HiLoBarType.Box);
 | |
|             sec.AddValue("PointLabelDisplayMode", PointLabelDisplayMode, PointLabelDisplayMode.NotSet);
 | |
|             sec.AddValue("PointLabelMinDistance", PointLabelMinDistance, 0);
 | |
|             sec.AddValue("PointLabelSkip", PointLabelSkip, 0);
 | |
|             sec.AddValue("ScaleTypeX", ScaleTypeX, ScaleType.NotSet);
 | |
|             sec.AddValue("ScaleTypeY", ScaleTypeY, ScaleType.NotSet);
 | |
| 
 | |
|             if (_SeriesPoints != null && _SeriesPoints.Count > 0)
 | |
|             {
 | |
|                 sec.AddStartElement("SeriesPoints count=\"" + _SeriesPoints.Count + "\"");
 | |
| 
 | |
|                 foreach (SeriesPoint sp in _SeriesPoints)
 | |
|                     sec.AddElement(sp.GetSerialData());
 | |
| 
 | |
|                 sec.AddEndElement("SeriesPoints");
 | |
|             }
 | |
| 
 | |
|             sec.AddValue("SeriesType", SeriesType, SeriesType.Point);
 | |
| 
 | |
|             sec.AddValue("ShowEmptyLines", ShowEmptyLines, false);
 | |
|             sec.AddValue("ShowEmptyPoints", ShowEmptyPoints, false);
 | |
|             sec.AddValue("ShowHiLoBarMedianLines", ShowHiLoBarMedianLines, false);
 | |
|             sec.AddValue("ShowOriginValueLabels", ShowOriginValueLabels, true);
 | |
| 
 | |
|             sec.AddValue("StackQualitativePoints", StackQualitativePoints, true);
 | |
| 
 | |
|             sec.AddValue("StepLines", StepLines, StepLines.NotSet);
 | |
|             sec.AddValue("StepLineMode", StepLineMode, StepLineMode.NotSet);
 | |
| 
 | |
|             sec.AddValue("CheckedInLegend", CheckedInLegend, true);
 | |
|             sec.AddValue("LegendText", LegendText, null);
 | |
|             sec.AddValue("ShowCheckBoxInLegend", ShowCheckBoxInLegend, true);
 | |
|             sec.AddValue("ShowInLegend", ShowInLegend, true);
 | |
|             sec.AddValue("ShowInParentLegend", ShowInParentLegend, true);
 | |
|             sec.AddValue("ShowMarkerInLegend", ShowMarkerInLegend, true);
 | |
| 
 | |
|             sec.AddElement(base.GetSerialData(null));
 | |
| 
 | |
|             if (serialName != null)
 | |
|                 sec.AddEndElement(serialName);
 | |
| 
 | |
|             return (sec);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PutSerialData
 | |
| 
 | |
|         #region ProcessValue
 | |
| 
 | |
|         internal override void ProcessValue(SerialElement se)
 | |
|         {
 | |
|             ChartXy chartXy = Parent as ChartXy;
 | |
| 
 | |
|             switch (se.Name)
 | |
|             {
 | |
|                 case "AreaBaseValue":
 | |
|                     AreaBaseValue = se.DataValue;
 | |
|                     break;
 | |
| 
 | |
|                 case "AxisX":
 | |
|                     if (chartXy != null)
 | |
|                         AxisX = GetAncillaryAxis(chartXy.AncillaryAxesX, se.GetValueString());
 | |
|                     break;
 | |
| 
 | |
|                 case "AxisY":
 | |
|                     if (chartXy != null)
 | |
|                         AxisY = GetAncillaryAxis(chartXy.AncillaryAxesY, se.GetValueString());
 | |
|                     break;
 | |
| 
 | |
|                 case "BarFillRange":
 | |
|                     BarFillRange = (BarFillRange)se.GetValueEnum(typeof(BarFillRange));
 | |
|                     break;
 | |
| 
 | |
|                 case "BarLabelPosition":
 | |
|                     BarLabelPosition = (BarLabelPosition)se.GetValueEnum(typeof(BarLabelPosition));
 | |
|                     break;
 | |
| 
 | |
|                 case "BarShadingEnabled":
 | |
|                     BarShadingEnabled = (Tbool)se.GetValueEnum(typeof(Tbool));
 | |
|                     break;
 | |
| 
 | |
|                 case "BarWidthRatio":
 | |
|                     BarWidthRatio = double.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "BubbleIntensityMode":
 | |
|                     BubbleIntensityMode = (BubbleIntensityMode)se.GetValueEnum(typeof(BubbleIntensityMode));
 | |
|                     break;
 | |
| 
 | |
|                 case "BubbleScaleFactor":
 | |
|                     BubbleScaleFactor = double.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "BubbleSizeMode":
 | |
|                     BubbleSizeMode = (BubbleSizeMode)se.GetValueEnum(typeof(BubbleSizeMode));
 | |
|                     break;
 | |
| 
 | |
|                 case "ChartLineAreaDisplayMode":
 | |
|                     ChartLineAreaDisplayMode = (ChartLineAreaDisplayMode)se.GetValueEnum(typeof(ChartLineAreaDisplayMode));
 | |
|                     break;
 | |
| 
 | |
|                 case "ChartLineDisplayMode":
 | |
|                     ChartLineDisplayMode = (ChartLineDisplayMode)se.GetValueEnum(typeof(ChartLineDisplayMode));
 | |
|                     break;
 | |
| 
 | |
|                 case "CheckedInLegend":
 | |
|                     CheckedInLegend = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "ConvexHullDisplayMode":
 | |
|                     ConvexHullDisplayMode = (ConvexHullDisplayMode)se.GetValueEnum(typeof(ConvexHullDisplayMode));
 | |
|                     break;
 | |
| 
 | |
|                 case "CrosshairEnabled":
 | |
|                     CrosshairEnabled = (Tbool)se.GetValueEnum(typeof(Tbool));
 | |
|                     break;
 | |
| 
 | |
|                 case "CrosshairHighlightPoints":
 | |
|                     CrosshairHighlightPoints = (Tbool)se.GetValueEnum(typeof(Tbool));
 | |
|                     break;
 | |
| 
 | |
|                 case "CrosshairShowLabels":
 | |
|                     CrosshairShowLabels = (Tbool)se.GetValueEnum(typeof(Tbool));
 | |
|                     break;
 | |
| 
 | |
|                 case "DataMember":
 | |
|                     DataMember = se.StringValue;
 | |
|                     break;
 | |
| 
 | |
|                 case "DataPropertyNameSeries":
 | |
|                     DataPropertyNameSeries = se.StringValue;
 | |
|                     break;
 | |
| 
 | |
|                 case "DataPropertyNameX":
 | |
|                     DataPropertyNameX = se.StringValue;
 | |
|                     break;
 | |
| 
 | |
|                 case "DataPropertyNamesY":
 | |
|                     DataPropertyNamesY.Add(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "DataSource":
 | |
|                     DataSource = se.DataValue;
 | |
|                     break;
 | |
| 
 | |
|                 case "DefaultPaletteColor":
 | |
|                     DefaultPaletteColor = se.GetValueColor();
 | |
|                     break;
 | |
| 
 | |
|                 case "DisplayLinePointsOnTop":
 | |
|                     DisplayLinePointsOnTop = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "DotPlotIndexValue":
 | |
|                     DotPlotIndexValue = double.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "EmptyValues":
 | |
|                     EmptyValues[se.ValueIndex] = se.DataValue;
 | |
|                     break;
 | |
| 
 | |
|                 case "EnableEmptyValues":
 | |
|                     EnableEmptyValues = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "GroupId":
 | |
|                     GroupId = int.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "HiLoBarType":
 | |
|                     HiLoBarType = (HiLoBarType)se.GetValueEnum(typeof(HiLoBarType));
 | |
|                     break;
 | |
| 
 | |
|                 case "LegendText":
 | |
|                     LegendText = se.StringValue;
 | |
|                     break;
 | |
| 
 | |
|                 case "PointLabelDisplayMode":
 | |
|                     PointLabelDisplayMode = (PointLabelDisplayMode)se.GetValueEnum(typeof(PointLabelDisplayMode));
 | |
|                     break;
 | |
| 
 | |
|                 case "PointLabelMinDistance":
 | |
|                     PointLabelMinDistance = int.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "PointLabelSkip":
 | |
|                     PointLabelSkip = int.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "ScaleTypeX":
 | |
|                     ScaleTypeX = (ScaleType)se.GetValueEnum(typeof(ScaleType));
 | |
|                     break;
 | |
| 
 | |
|                 case "ScaleTypeY":
 | |
|                     ScaleTypeY = (ScaleType)se.GetValueEnum(typeof(ScaleType));
 | |
|                     break;
 | |
| 
 | |
|                 case "SeriesType":
 | |
|                     SeriesType = (SeriesType)se.GetValueEnum(typeof(SeriesType));
 | |
|                     break;
 | |
| 
 | |
|                 case "ShowCheckBoxInLegend":
 | |
|                     ShowCheckBoxInLegend = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "ShowEmptyLines":
 | |
|                     ShowEmptyLines = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "ShowEmptyPoints":
 | |
|                     ShowEmptyPoints = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "ShowHiLoBarMedianLines":
 | |
|                     ShowHiLoBarMedianLines = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "ShowInLegend":
 | |
|                     ShowInLegend = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "ShowInParentLegend":
 | |
|                     ShowInParentLegend = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "ShowMarkerInLegend":
 | |
|                     ShowMarkerInLegend = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "ShowOriginValueLabels":
 | |
|                     ShowOriginValueLabels = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "StackQualitativePoints":
 | |
|                     StackQualitativePoints = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "StepLines":
 | |
|                     StepLines = (StepLines)se.GetValueEnum(typeof(StepLines));
 | |
|                     break;
 | |
| 
 | |
|                 case "StepLineMode":
 | |
|                     StepLineMode = (StepLineMode)se.GetValueEnum(typeof(StepLineMode));
 | |
|                     break;
 | |
| 
 | |
|                 default:
 | |
|                     base.ProcessValue(se);
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetAncillaryAxis
 | |
| 
 | |
|         private ChartAxis GetAncillaryAxis(ChartAxesCollection axes, string name)
 | |
|         {
 | |
|             foreach (ChartAxis axis in axes)
 | |
|             {
 | |
|                 if (name.Equals(axis.Name) == true)
 | |
|                     return (axis);
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ProcessCollection
 | |
| 
 | |
|         internal override void ProcessCollection(SerialElement se)
 | |
|         {
 | |
|             SerialElementCollection sec = se.Sec;
 | |
| 
 | |
|             switch (se.Name)
 | |
|             {
 | |
|                 case "ChartIndicators":
 | |
|                     sec.PutSerialData(this);
 | |
|                     break;
 | |
| 
 | |
|                 case "ChartLegendItemVisualStyles":
 | |
|                     sec.PutSerialData(ChartLegendItemVisualStyles);
 | |
|                     break;
 | |
| 
 | |
|                 case "ChartSeriesVisualStyle":
 | |
|                     sec.PutSerialData(ChartSeriesVisualStyle);
 | |
|                     break;
 | |
| 
 | |
|                 case "DataLabel":
 | |
|                     sec.PutSerialData(DataLabels[se.ValueIndex]);
 | |
|                     break;
 | |
| 
 | |
|                 case "DataLabels":
 | |
|                     sec.PutSerialData(this);
 | |
|                     break;
 | |
| 
 | |
|                 case "DataLabelVisualStyle":
 | |
|                     sec.PutSerialData(DataLabelVisualStyle);
 | |
|                     break;
 | |
| 
 | |
|                 case "DataPropertyNamesYs":
 | |
|                     if (se.ArrayCount > 0)
 | |
|                     {
 | |
|                         DataPropertyNamesY = new CustomCollection<string>(se.ArrayCount);
 | |
| 
 | |
|                         sec.PutSerialData(this);
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case "EmptyValues":
 | |
|                     if (se.ArrayCount > 0)
 | |
|                     {
 | |
|                         EmptyValues = new object[se.ArrayCount];
 | |
| 
 | |
|                         sec.PutSerialData(this);
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case "RegressionLine":
 | |
|                     string rname = se.Sec.GetItemValue("Name");
 | |
| 
 | |
|                     RegressionLine reg = ChartIndicators[rname] as RegressionLine;
 | |
| 
 | |
|                     if (reg != null)
 | |
|                         ChartIndicators.Remove(reg);
 | |
| 
 | |
|                     reg = new RegressionLine(rname);
 | |
| 
 | |
|                     if (reg != null)
 | |
|                     {
 | |
|                         sec.PutSerialData(reg);
 | |
| 
 | |
|                         ChartIndicators.Add(reg);
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case "SeriesPoints":
 | |
|                     if (se.ArrayCount > 0)
 | |
|                     {
 | |
|                         SeriesPoints = new SeriesPointCollection();
 | |
| 
 | |
|                         sec.PutSerialData(this);
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case "SeriesPoint":
 | |
|                     SeriesPoint sp = new SeriesPoint();
 | |
| 
 | |
|                     sec.PutSerialData(sp);
 | |
| 
 | |
|                     SeriesPoints.Add(sp);
 | |
|                     break;
 | |
| 
 | |
|                 case "TrendLine":
 | |
|                     string tname = se.Sec.GetItemValue("Name");
 | |
| 
 | |
|                     TrendLine trend = ChartIndicators[tname] as TrendLine;
 | |
| 
 | |
|                     if (trend != null)
 | |
|                         ChartIndicators.Remove(trend);
 | |
| 
 | |
|                     trend = new TrendLine(tname);
 | |
| 
 | |
|                     if (trend != null)
 | |
|                     {
 | |
|                         sec.PutSerialData(trend);
 | |
| 
 | |
|                         ChartIndicators.Add(trend);
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 default:
 | |
|                     base.ProcessCollection(se);
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Series States
 | |
| 
 | |
|         [Flags]
 | |
|         private enum States : uint
 | |
|         {
 | |
|             FilterIgnoreMatchCase = (1U << 0),
 | |
| 
 | |
|             CheckedInLegend = (1U << 1),
 | |
|             ShowInLegend = (1U << 2),
 | |
|             ShowInParentLegend = (1U << 3),
 | |
|             ShowCheckBoxInLegend = (1U << 4),
 | |
|             ShowMarkerInLegend = (1U << 5),
 | |
| 
 | |
|             IsSorted = (1U << 6),
 | |
|             IsRotated = (1U << 7),
 | |
| 
 | |
|             StackQualitativePoints = (1U << 8),
 | |
|             DisplayLinePointsOnTop = (1U << 9),
 | |
| 
 | |
|             EnableEmptyValues = (1U << 10),
 | |
|             ShowEmptyLines = (1U << 11),
 | |
|             ShowEmptyPoints = (1U << 12),
 | |
|             ShowOriginValueLabels = (1U << 13),
 | |
|             ShowHiLoBarMedianLines = (1U << 14),
 | |
| 
 | |
|             NeedToUpdateBindings = (1U << 15),
 | |
|         }
 | |
| 
 | |
|         #region TestState
 | |
| 
 | |
|         private bool TestState(States state)
 | |
|         {
 | |
|             return ((_States & state) == state);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region SetState
 | |
| 
 | |
|         private void SetState(States state, bool value)
 | |
|         {
 | |
|             if (value == true)
 | |
|                 _States |= state;
 | |
|             else
 | |
|                 _States &= ~state;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IDisposable
 | |
| 
 | |
|         public override void Dispose()
 | |
|         {
 | |
|             AxisX = null;
 | |
|             AxisY = null;
 | |
|             ChartIndicators = null;
 | |
|             ChartLegendItemVisualStyles = null;
 | |
|             ChartSeriesVisualStyle = null;
 | |
|             DataLabels = null;
 | |
|             DataLabelVisualStyle = null;
 | |
|             SeriesPoints = null;
 | |
| 
 | |
|             base.Dispose();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|     }
 | |
| 
 | |
|     #region SortedSeriesPoints
 | |
| 
 | |
|     public class SortedSeriesPoints
 | |
|     {
 | |
|         #region Private variables
 | |
| 
 | |
|         private ChartSeries _ChartSeries;
 | |
|         private SeriesPointCollection _Spc;
 | |
| 
 | |
|         private int[] _IndexArray;
 | |
|         private int[] _CountArray;
 | |
| 
 | |
|         private int _SeriesLayoutCount;
 | |
| 
 | |
|         private int _FirstDisplayIndex = -1;
 | |
|         private int _LastDisplayIndex = -1;
 | |
| 
 | |
|         private double _Slope = double.NaN;
 | |
|         private double _Intercept = double.NaN;
 | |
| 
 | |
|         private bool _SlopeCalculated;
 | |
|         private int _SlopeIndex;
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         public SortedSeriesPoints(ChartSeries series, bool sortPoints)
 | |
|         {
 | |
|             _ChartSeries = series;
 | |
|             _Spc = series.SeriesPoints;
 | |
| 
 | |
|             if (sortPoints == true)
 | |
|                 _IndexArray = CreateIndexArray(_Spc);
 | |
|         }
 | |
| 
 | |
|         #region Public properties
 | |
| 
 | |
|         #region Count
 | |
| 
 | |
|         public int Count
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_IndexArray != null)
 | |
|                     return (_IndexArray.Length);
 | |
| 
 | |
|                 return (_Spc.Count);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Indexer[int]
 | |
| 
 | |
|         public SeriesPoint this[int index]
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_IndexArray != null)
 | |
|                     index = _IndexArray[index];
 | |
| 
 | |
|                 return (_Spc[index]);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IsSorted
 | |
| 
 | |
|         public bool IsSorted
 | |
|         {
 | |
|             get { return (_ChartSeries.IsSorted); }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region SeriesLayoutCount
 | |
| 
 | |
|         public int SeriesLayoutCount
 | |
|         {
 | |
|             get { return (_SeriesLayoutCount); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _SeriesLayoutCount)
 | |
|                 {
 | |
|                     _SeriesLayoutCount = value;
 | |
| 
 | |
|                     _FirstDisplayIndex = -1;
 | |
|                     _LastDisplayIndex = -1;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Internal properties
 | |
| 
 | |
|         #region CountArray
 | |
| 
 | |
|         internal int[] CountArray
 | |
|         {
 | |
|             get { return (_CountArray); }
 | |
|             set { _CountArray = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IndexArray
 | |
| 
 | |
|         internal int[] IndexArray
 | |
|         {
 | |
|             get { return (_IndexArray); }
 | |
|             set { _IndexArray = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Intercept
 | |
| 
 | |
|         internal double Intercept
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_SlopeCalculated == false)
 | |
|                     CalcSeriesSlope();
 | |
| 
 | |
|                 return (_Intercept);
 | |
|             }
 | |
| 
 | |
|             set { _Intercept = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Slope
 | |
| 
 | |
|         internal double Slope
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_SlopeCalculated == false)
 | |
|                     CalcSeriesSlope();
 | |
| 
 | |
|                 return (_Slope);
 | |
|             }
 | |
| 
 | |
|             set { _Slope = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region SlopeIndex
 | |
| 
 | |
|         internal int SlopeIndex
 | |
|         {
 | |
|             get { return (_SlopeIndex); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_SlopeIndex != value)
 | |
|                 {
 | |
|                     _SlopeIndex = value;
 | |
|                     _SlopeCalculated = false;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CreateIndexArray
 | |
| 
 | |
|         private int[] CreateIndexArray(SeriesPointCollection spc)
 | |
|         {
 | |
|             int[] indexArray = new int[_Spc.Count];
 | |
|             object[] keyArray = new object[_Spc.Count];
 | |
| 
 | |
|             for (int i = 0; i < _Spc.Count; i++)
 | |
|             {
 | |
|                 indexArray[i] = i;
 | |
|                 keyArray[i] = _Spc[i].ValueX;
 | |
|             }
 | |
| 
 | |
|             Array.Sort(keyArray, indexArray);
 | |
| 
 | |
|             return (indexArray);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region SearchX
 | |
| 
 | |
|         public int SearchX(object okey)
 | |
|         {
 | |
|             ChartXy chartXy = _ChartSeries.Parent as ChartXy;
 | |
| 
 | |
|             if (IsSorted == true)
 | |
|             {
 | |
|                 int min = 0;
 | |
|                 int max = Count - 1;
 | |
| 
 | |
|                 while (min <= max)
 | |
|                 {
 | |
|                     int mid = (min + max) / 2;
 | |
| 
 | |
|                     int cmp = chartXy.DataCompare(okey, this[mid].ValueX);
 | |
| 
 | |
|                     if (cmp > 0)
 | |
|                         min = mid + 1;
 | |
| 
 | |
|                     else if (cmp < 0)
 | |
|                         max = mid - 1;
 | |
| 
 | |
|                     else
 | |
|                         return (mid);
 | |
|                 }
 | |
| 
 | |
|                 return (-((min > 0) ? min - 1 : 0));
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 for (int i = 0; i < Count; i++)
 | |
|                 {
 | |
|                     if (chartXy.DataCompare(okey, this[i].ValueX) == 0)
 | |
|                         return (i);
 | |
|                 }
 | |
| 
 | |
|                 return (-1);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region SearchY
 | |
| 
 | |
|         public int SearchY(object okey)
 | |
|         {
 | |
|             ChartXy chartXy = _ChartSeries.Parent as ChartXy;
 | |
| 
 | |
|             for (int i = 0; i < _Spc.Count; i++)
 | |
|             {
 | |
|                 if (_Spc[i].ValueY[0].Equals(okey))
 | |
|                     return (i);
 | |
|             }
 | |
| 
 | |
|             return (0);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetQualitativeXIndex
 | |
| 
 | |
|         internal int GetQualitativeXIndex(object okey)
 | |
|         {
 | |
|             int index;
 | |
| 
 | |
|             if (okey is string)
 | |
|                 index = _ChartSeries.QualitativeXValues.IndexOf((string)okey);
 | |
|             else
 | |
|                 index = Convert.ToInt32(okey);
 | |
| 
 | |
|             return (index);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetQualitativeYIndex
 | |
| 
 | |
|         internal int GetQualitativeYIndex(object okey)
 | |
|         {
 | |
|             int index;
 | |
| 
 | |
|             if (okey is string)
 | |
|                 index = _ChartSeries.QualitativeYValues.IndexOf((string)okey);
 | |
|             else
 | |
|                 index = Convert.ToInt32(okey);
 | |
| 
 | |
|             return (index);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CalcSeriesSlope
 | |
| 
 | |
|         private void CalcSeriesSlope()
 | |
|         {
 | |
|             ChartXy chartXy = _ChartSeries.Parent as ChartXy;
 | |
| 
 | |
|             if (chartXy != null)
 | |
|             {
 | |
|                 ChartAxis axisX = _ChartSeries.AxisX ?? chartXy.AxisX;
 | |
|                 ChartAxis axisY = _ChartSeries.AxisY ?? chartXy.AxisY;
 | |
| 
 | |
|                 if (_ChartSeries.ActualScaleTypeX != ScaleType.NotSet)
 | |
|                 {
 | |
|                     int n = Count;
 | |
| 
 | |
|                     double sumX = 0;
 | |
|                     double sumY = 0;
 | |
|                     double sumXx = 0;
 | |
|                     double sumXy = 0;
 | |
| 
 | |
|                     int nn = 0;
 | |
| 
 | |
|                     for (int i = 0; i < n; i++)
 | |
|                     {
 | |
|                         SeriesPoint sp = this[i];
 | |
| 
 | |
|                         if (sp.IsEmpty == false && (sp.ValueY.Length > _SlopeIndex))
 | |
|                         {
 | |
|                             nn++;
 | |
| 
 | |
|                             double x;
 | |
| 
 | |
|                             switch (_ChartSeries.ActualScaleTypeX)
 | |
|                             {
 | |
|                                 case ScaleType.DateTime:
 | |
|                                     x = chartXy.GetDateTimePointValue(axisX,
 | |
|                                         axisX.TickmarkLayout, (DateTime)sp.ValueX, (DateTime)_ChartSeries.MinValueX);
 | |
|                                     break;
 | |
| 
 | |
|                                 case ScaleType.Qualitative:
 | |
|                                     x = _ChartSeries.QualitativeXValues.IndexOf(sp.ValueX);
 | |
|                                     break;
 | |
| 
 | |
|                                 default:
 | |
|                                     x = Convert.ToDouble(sp.ValueX);
 | |
|                                     break;
 | |
|                             }
 | |
| 
 | |
|                             double y;
 | |
| 
 | |
|                             switch (_ChartSeries.ActualScaleTypeY)
 | |
|                             {
 | |
|                                 case ScaleType.DateTime:
 | |
|                                     y = chartXy.GetDateTimePointValue(axisY, axisY.TickmarkLayout, (DateTime)sp.ValueY[_SlopeIndex]);
 | |
|                                     break;
 | |
| 
 | |
|                                 case ScaleType.Qualitative:
 | |
|                                     y = _ChartSeries.QualitativeYValues.IndexOf(sp.ValueY[_SlopeIndex]);
 | |
|                                     break;
 | |
| 
 | |
|                                 default:
 | |
|                                     y = Convert.ToDouble(sp.ValueY[_SlopeIndex]);
 | |
|                                     break;
 | |
|                             }
 | |
| 
 | |
|                             sumX += x;
 | |
|                             sumY += y;
 | |
| 
 | |
|                             sumXx += (x * x);
 | |
|                             sumXy += (x * y);
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     double a = nn * sumXy;
 | |
|                     double b = sumX * sumY;
 | |
|                     double c = nn * sumXx;
 | |
|                     double d = sumX * sumX;
 | |
| 
 | |
|                     double m = (a - b) / (c - d);
 | |
|                     double yi = (sumY - (m * sumX)) / nn;
 | |
| 
 | |
|                     Slope = m;
 | |
|                     Intercept = yi;
 | |
| 
 | |
|                     _SlopeCalculated = true;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetSeriesPoint
 | |
| 
 | |
|         internal SeriesPoint GetSeriesPoint(object key)
 | |
|         {
 | |
|             if (Count > 0)
 | |
|             {
 | |
|                 int index;
 | |
| 
 | |
|                 if (this[0].IsQuantitativeXValue == true)
 | |
|                     index = SearchX(key);
 | |
|                 else
 | |
|                     index = GetQualitativeXIndex(key) - 1;
 | |
| 
 | |
|                 if (index < 0 && IsSorted == true)
 | |
|                     index = -index;
 | |
| 
 | |
|                 if ((uint)index < Count)
 | |
|                     return (this[index]);
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region PointData
 | |
| 
 | |
|     public class PointData
 | |
|     {
 | |
|         public List<Point[]> Points;
 | |
|         public List<SeriesPoint[]> SeriesPoints;
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region BubblePlotData
 | |
| 
 | |
|     internal class BubblePlotData
 | |
|     {
 | |
|         public double MinSize;
 | |
|         public double MaxSize;
 | |
| 
 | |
|         public double TotalSize;
 | |
| 
 | |
|         public double MinIntensity;
 | |
|         public double MaxIntensity;
 | |
| 
 | |
|         public void Clear()
 | |
|         {
 | |
|             MinSize = double.MaxValue;
 | |
|             MaxSize = double.MinValue;
 | |
| 
 | |
|             MinIntensity = double.MaxValue;
 | |
|             MaxIntensity = double.MinValue;
 | |
| 
 | |
|             TotalSize = 0;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region BarRenderData
 | |
| 
 | |
|     internal class BarRenderData
 | |
|     {
 | |
|         public ChartAxis Axis;
 | |
|         public ChartXy ChartXy;
 | |
| 
 | |
|         public BarFillRange FillRange;
 | |
|         public bool BarShading;
 | |
| 
 | |
|         public Point Spt;
 | |
|         public SeriesPoint Sp;
 | |
| 
 | |
|         public ChartSeriesVisualStyle SeriesStyle;
 | |
| 
 | |
|         public BarRenderData(ChartXy chartXy, ChartAxis axis)
 | |
|         {
 | |
|             ChartXy = chartXy;
 | |
|             Axis = axis;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region HiLoRenderData
 | |
| 
 | |
|     public class HiLoRenderData
 | |
|     {
 | |
|         #region Private variables
 | |
| 
 | |
|         private ChartAxis _Axis;
 | |
|         private ChartXy _ChartXy;
 | |
| 
 | |
|         private Point _Spt;
 | |
|         private SeriesPoint _Sp;
 | |
|         private int _Index;
 | |
| 
 | |
|         private ChartSeriesVisualStyle _SeriesStyle;
 | |
| 
 | |
|         private int[] _Value;
 | |
| 
 | |
|         private bool _IsAlternate;
 | |
|         private int _EndDelta;
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         public HiLoRenderData(ChartXy chartXy, ChartAxis axis)
 | |
|         {
 | |
|             _ChartXy = chartXy;
 | |
|             _Axis = axis;
 | |
|         }
 | |
| 
 | |
|         #region Public properties
 | |
| 
 | |
|         #region AlternateStyle
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the alternate segment style used when Open/Close values are reversed.
 | |
|         /// </summary>
 | |
|         public HiLoBarSegmentStyle AlternateStyle
 | |
|         {
 | |
|             get { return (SeriesStyle.HiLoBarVisualStyle.AlternateSegmentStyle); }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region DefaultStyle
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the default segment style used when Open/Close values are not reversed.
 | |
|         /// </summary>
 | |
|         public HiLoBarSegmentStyle DefaultStyle
 | |
|         {
 | |
|             get { return (SeriesStyle.HiLoBarVisualStyle.DefaultSegmentStyle); }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IsAlternate
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets whether the segment is to be render as 'Alternate'.
 | |
|         /// </summary>
 | |
|         public bool IsAlternate
 | |
|         {
 | |
|             get { return (_IsAlternate); }
 | |
|             internal set { _IsAlternate = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region SeriesStyle
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the associated series visual style.
 | |
|         /// </summary>
 | |
|         public ChartSeriesVisualStyle SeriesStyle
 | |
|         {
 | |
|             get { return (_SeriesStyle); }
 | |
|             internal set { _SeriesStyle = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Value
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets an array of specified HiLo coordinate data values (x or y,
 | |
|         /// depending upon the bar orientation). The values are specified
 | |
|         /// in [High=0, Low=1, Close=2, Open=3, Median=4] order, followed
 | |
|         /// by any 'extra' user supplied bar values.
 | |
|         /// </summary>
 | |
|         public int[] Value
 | |
|         {
 | |
|             get { return (_Value); }
 | |
|             internal set { _Value = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Internal properties
 | |
| 
 | |
|         #region Axis
 | |
| 
 | |
|         internal ChartAxis Axis
 | |
|         {
 | |
|             get { return (_Axis); }
 | |
|             set { _Axis = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ChartXy
 | |
| 
 | |
|         internal ChartXy ChartXy
 | |
|         {
 | |
|             get { return (_ChartXy); }
 | |
|             set { _ChartXy = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region EndDelta
 | |
| 
 | |
|         public int EndDelta
 | |
|         {
 | |
|             get { return (_EndDelta); }
 | |
|             set { _EndDelta = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Index
 | |
| 
 | |
|         internal int Index
 | |
|         {
 | |
|             get { return (_Index); }
 | |
|             set { _Index = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Sp
 | |
| 
 | |
|         internal SeriesPoint Sp
 | |
|         {
 | |
|             get { return (_Sp); }
 | |
|             set { _Sp = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Spt
 | |
| 
 | |
|         internal Point Spt
 | |
|         {
 | |
|             get { return (_Spt); }
 | |
|             set { _Spt = value; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region AMath (approximate math)
 | |
| 
 | |
|     internal class AMath
 | |
|     {
 | |
|         public static double ToScalar(double x)
 | |
|         {
 | |
|             return (AMath.Sqrt((float)(x / Math.PI)) * 2);
 | |
|         }
 | |
| 
 | |
|         public static float Sqrt(float x)
 | |
|         {
 | |
|             if (x != 0)
 | |
|             {
 | |
|                 FloatIntUnion u;
 | |
| 
 | |
|                 u.tmp = 0;
 | |
|                 u.f = x;
 | |
| 
 | |
|                 u.tmp -= 1 << 23;   // Subtract 2^m
 | |
|                 u.tmp >>= 1;        // Divide by 2
 | |
|                 u.tmp += 1 << 29;   // Add ((b + 1) / 2) * 2^m
 | |
| 
 | |
|                 return (u.f);
 | |
|             }
 | |
| 
 | |
|             return (0);
 | |
|         }
 | |
| 
 | |
|         [StructLayout(LayoutKind.Explicit)]
 | |
|         private struct FloatIntUnion
 | |
|         {
 | |
|             [FieldOffset(0)]
 | |
|             public float f;
 | |
| 
 | |
|             [FieldOffset(0)]
 | |
|             public int tmp;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region enums
 | |
| 
 | |
|     #region BarLabelPosition
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Specifies the position for Bar series labels.
 | |
|     /// </summary>
 | |
|     public enum BarLabelPosition
 | |
|     {
 | |
|         /// <summary>
 | |
|         /// Not set (default is Center). 
 | |
|         /// </summary>
 | |
|         NotSet = -1,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Labels will be positioned in the center of the bar. 
 | |
|         /// </summary>
 | |
|         Center,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Labels will be positioned outside the bar, relative to its origin. 
 | |
|         /// </summary>
 | |
|         Near,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Labels will be positioned inside the bar, relative to its origin. 
 | |
|         /// </summary>
 | |
|         NearInside,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Labels will be positioned outside the bar, opposite to its origin. 
 | |
|         /// </summary>
 | |
|         Far,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Labels will be positioned inside the bar, opposite to its origin. 
 | |
|         /// </summary>
 | |
|         FarInside,
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region BarSegment
 | |
| 
 | |
|     public enum BarSegment
 | |
|     {
 | |
|         /// <summary>
 | |
|         /// Top portion of Vertical bar (full area).
 | |
|         /// </summary>
 | |
|         Top,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Partial Top area of Vertical bar.
 | |
|         /// </summary>
 | |
|         TopPartial,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Bottom portion of Vertical bar (full area).
 | |
|         /// </summary>
 | |
|         Bottom,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Partial Bottom area of Vertical bar.
 | |
|         /// </summary>
 | |
|         BottomPartial,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Left portion of Horizontal bar (full area).
 | |
|         /// </summary>
 | |
|         Left,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Partial Left area of Horizontal bar.
 | |
|         /// </summary>
 | |
|         LeftPartial,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Right portion of Horizontal bar (full area).
 | |
|         /// </summary>
 | |
|         Right,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Partial Right area of Horizontal bar.
 | |
|         /// </summary>
 | |
|         RightPartial,
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region SeriesType
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Defines available Series types
 | |
|     /// </summary>
 | |
|     public enum SeriesType
 | |
|     {
 | |
|         Bubble,
 | |
| 
 | |
|         HorizontalBar,
 | |
|         VerticalBar,
 | |
| 
 | |
|         Line,
 | |
|         Point,
 | |
| 
 | |
|         HorizontalDot,          // Wilkinson dotplot
 | |
|         VerticalDot,
 | |
| 
 | |
|         HorizontalHiLoBar,      // Box, Candle, HiLo
 | |
|         VerticalHiLoBar,
 | |
| 
 | |
|         //Bullet,
 | |
| 
 | |
|         //Pie,
 | |
|         //Polar,
 | |
|         //Radar,
 | |
| 
 | |
|         //TreeMap,
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region ConvexHullDisplayMode
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Specifies the ConvexHull display mode
 | |
|     /// </summary>
 | |
|     [Flags]
 | |
|     public enum ConvexHullDisplayMode
 | |
|     {
 | |
|         /// <summary>
 | |
|         /// Not set (default is None). 
 | |
|         /// </summary>
 | |
|         NotSet = 0,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// No Convex Hull processing will take place. 
 | |
|         /// </summary>
 | |
|         None = (1 << 0),
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Convex Hull border will be displayed.
 | |
|         /// </summary>
 | |
|         DisplayBorder = (1 << 1),
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Convex Hull background area will be displayed.
 | |
|         /// </summary>
 | |
|         DisplayBackground = (1 << 2),
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region PointLabelDisplayMode
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Specifies which PointLabels are to be displayed
 | |
|     /// </summary>
 | |
|     [Flags]
 | |
|     public enum PointLabelDisplayMode
 | |
|     {
 | |
|         /// <summary>
 | |
|         /// Not set (default is None). 
 | |
|         /// </summary>
 | |
|         NotSet,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// No labels will be displayed. 
 | |
|         /// </summary>
 | |
|         None = (1 << 0),
 | |
| 
 | |
|         /// <summary>
 | |
|         /// All series points will display a label. 
 | |
|         /// </summary>
 | |
|         AllSeriesPoints = (1 << 1),
 | |
| 
 | |
|         /// <summary>
 | |
|         /// User defined DataLabels will be displayed.
 | |
|         /// </summary>
 | |
|         DataLabels = (1 << 2),
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Minimum 'X' Value label will be displayed.
 | |
|         /// </summary>
 | |
|         MinValueX = (1 << 3),
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Minimum 'Y' Value label will be displayed.
 | |
|         /// </summary>
 | |
|         MinValueY = (1 << 4),
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Maximum 'X' Value label will be displayed.
 | |
|         /// </summary>
 | |
|         MaxValueX = (1 << 5),
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Maximum 'Y' Value label will be displayed.
 | |
|         /// </summary>
 | |
|         MaxValueY = (1 << 6),
 | |
| 
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region StepLineMode
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Specifies the mode used to render "Step Lines" in
 | |
|     /// a given Line series.
 | |
|     /// </summary>
 | |
|     public enum StepLineMode
 | |
|     {
 | |
|         /// <summary>
 | |
|         /// Not set (default is HorizontalThenVertical). 
 | |
|         /// </summary>
 | |
|         NotSet = -1,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// No Step Lines will be rendered. 
 | |
|         /// </summary>
 | |
|         None,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Step lines will be displayed between consecutive
 | |
|         /// series points, by first displaying the horizontal step
 | |
|         /// line, followed by the connecting vertical step line. 
 | |
|         /// </summary>
 | |
|         HorizontalThenVertical,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Step lines will be displayed between consecutive
 | |
|         /// series points, by first displaying the vertical step
 | |
|         /// line, followed by the connecting horizontal step line. 
 | |
|         /// </summary>
 | |
|         VerticalThenHorizontal,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Step lines will be displayed between consecutive
 | |
|         /// series points, by first displaying the midPoint horizontal
 | |
|         /// step line, followed by the connecting vertical step line. 
 | |
|         /// </summary>
 | |
|         MidPoint,
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region StepLines
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Specifies the mode used to render "Stepped Lines" in
 | |
|     /// a given Line series.
 | |
|     /// </summary>
 | |
|     public enum StepLines
 | |
|     {
 | |
|         /// <summary>
 | |
|         /// Not set (default is StepHv). 
 | |
|         /// </summary>
 | |
|         NotSet = -1,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// No step lines will be displayed. 
 | |
|         /// </summary>
 | |
|         None,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Horizontal step lines will be displayed. 
 | |
|         /// </summary>
 | |
|         Horizontal,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Vertical step lines will be displayed. 
 | |
|         /// </summary>
 | |
|         Vertical,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Both horizontal and vertical step lines will be displayed. 
 | |
|         /// </summary>
 | |
|         Both,
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region ScaleType
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Specifies the scale type for the series points
 | |
|     /// </summary>
 | |
|     public enum ScaleType
 | |
|     {
 | |
|         /// <summary>
 | |
|         /// ScaleType is NotSet (default is 'Auto').
 | |
|         /// </summary>
 | |
|         NotSet,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// ScaleType is Automatic.  Scale type will be determined
 | |
|         /// by the underlying, assigned data.
 | |
|         /// </summary>
 | |
|         Auto,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// DateTime data scale. Points will be treated as
 | |
|         /// DateTime values and will be shown as such on the axis. 
 | |
|         /// </summary>
 | |
|         DateTime,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Numerical data scale. Points will be treated as
 | |
|         /// numerical values and will be shown on the axis as numbers.
 | |
|         /// </summary>
 | |
|         Quantitative,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Qualitative data scale. Points will be treated as 
 | |
|         /// qualitative values and will be shown on the axis as text.
 | |
|         /// </summary>
 | |
|         Qualitative,
 | |
| 
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region HiLoBarType
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Specifies the HiloBar series display type.
 | |
|     /// </summary>
 | |
|     public enum HiLoBarType
 | |
|     {
 | |
|         /// <summary>
 | |
|         /// Box Plot display. Display is identical to 'Candle' except:
 | |
|         /// 1. Median separated segments are separately rendered using both
 | |
|         /// default and alternate box backgrounds.
 | |
|         /// 2. UseAlternateSegmentStyle defaults to false.
 | |
|         /// </summary>
 | |
|         Box,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Candle Plot display. Display is identical to 'Box' except:
 | |
|         /// 1. Mmedian separated segments are both rendered using either
 | |
|         /// the default or alternate box background.
 | |
|         /// 2. UseAlternateSegmentStyle defaults to true.
 | |
|         /// </summary>
 | |
|         Candle,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Line plot display.
 | |
|         /// </summary>
 | |
|         Line,
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region HiLoBarSegment
 | |
| 
 | |
|     public enum HiLoBarSegment
 | |
|     {
 | |
|         /// <summary>
 | |
|         /// Box (Box plot).
 | |
|         /// </summary>
 | |
|         Box,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// High whisker (Box, Candle, Line).
 | |
|         /// </summary>
 | |
|         HighWhisker,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// High whisker cap (Box, Candle, Line).
 | |
|         /// </summary>
 | |
|         HighWhiskerCap,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Low whisker (Box, Candle, Line).
 | |
|         /// </summary>
 | |
|         LowWhisker,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Low whisker cap (Box, Candle, Line).
 | |
|         /// </summary>
 | |
|         LowWhiskerCap,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Open whisker (Line plot).
 | |
|         /// </summary>
 | |
|         OpenWhisker,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Close whisker (Line Plot).
 | |
|         /// </summary>
 | |
|         CloseWhisker,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Center line (Line plot).
 | |
|         /// </summary>
 | |
|         CenterLine,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Full range (Line plot).
 | |
|         /// </summary>
 | |
|         FullRange,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Median line (Box, Candle, Line).
 | |
|         /// </summary>
 | |
|         MedianLine,
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Bar shading (Box, Candle).
 | |
|         /// </summary>
 | |
|         BarShading,
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region AxisTypeConverter
 | |
| 
 | |
|     ///<summary>
 | |
|     /// AxisTypeConverter
 | |
|     ///</summary>
 | |
|     public class AxisTypeConverter : TypeConverter
 | |
|     {
 | |
|         ///<summary>
 | |
|         /// ConvertTo
 | |
|         ///</summary>
 | |
|         ///<param name="context"></param>
 | |
|         ///<param name="culture"></param>
 | |
|         ///<param name="value"></param>
 | |
|         ///<param name="destinationType"></param>
 | |
|         ///<returns></returns>
 | |
|         public override object ConvertTo(
 | |
|             ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
 | |
|         {
 | |
|             if (destinationType == typeof(string))
 | |
|             {
 | |
|                 ChartAxis axis = value as ChartAxis;
 | |
| 
 | |
|                 if (axis != null)
 | |
|                 {
 | |
|                     if (string.IsNullOrEmpty(axis.Name) == false)
 | |
|                         return (axis.Name);
 | |
| 
 | |
|                     return ("No Axis Name");
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (base.ConvertTo(context, culture, value, destinationType));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| }
 |