6453 lines
		
	
	
		
			191 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			6453 lines
		
	
	
		
			191 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Collections;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.ComponentModel;
 | 
						|
using System.Drawing;
 | 
						|
using System.Drawing.Design;
 | 
						|
using System.Drawing.Drawing2D;
 | 
						|
using System.Windows.Forms;
 | 
						|
using DevComponents.DotNetBar.Charts.Style;
 | 
						|
 | 
						|
namespace DevComponents.DotNetBar.Charts
 | 
						|
{
 | 
						|
    /// <summary>
 | 
						|
    /// Represents an X/Y oriented chart.
 | 
						|
    /// </summary>pi
 | 
						|
    public class ChartXy : BaseChart
 | 
						|
    {
 | 
						|
        #region Private variables
 | 
						|
 | 
						|
        private States _States;
 | 
						|
 | 
						|
        private ChartAxisX _AxisX;
 | 
						|
        private ChartAxisY _AxisY;
 | 
						|
 | 
						|
        private ChartAxesXCollection _AncillaryAxesX;
 | 
						|
        private ChartAxesYCollection _AncillaryAxesY;
 | 
						|
 | 
						|
        private ChartSeriesCollection _ChartSeries;
 | 
						|
 | 
						|
        private SeriesType _AutoGenSeriesChartType = SeriesType.Point;
 | 
						|
 | 
						|
        private int _BarSpacing;
 | 
						|
        private double _BarSpacingRatio = 0.2d;
 | 
						|
        private double _BarWidthRatio;
 | 
						|
        private object _BarOrigin;
 | 
						|
        private Tbool _BarShadingEnabled = Tbool.NotSet;
 | 
						|
        private Tbool _BarShowAsHistogram = Tbool.NotSet;
 | 
						|
 | 
						|
        private BarFillRange _BarFillRange = BarFillRange.NotSet;
 | 
						|
        private BarLabelPosition _BarLabelPosition = BarLabelPosition.NotSet;
 | 
						|
 | 
						|
        private DataLabelOverlapMode _DataLabelOverlapMode = DataLabelOverlapMode.NotSet;
 | 
						|
 | 
						|
        private DataLabelVisualStyle _DataLabelVisualStyle;
 | 
						|
        private EffectiveStyle<DataLabelVisualStyle> _EffectiveDataLabelStyle;
 | 
						|
 | 
						|
        private ChartXyVisualStyle _ChartVisualStyle;
 | 
						|
        private EffectiveStyle<ChartXyVisualStyle> _EffectiveChartStyle;
 | 
						|
 | 
						|
        private ChartSeriesVisualStyle _ChartSeriesVisualStyle;
 | 
						|
        private EffectiveStyle<ChartSeriesVisualStyle> _EffectiveChartSeriesStyle;
 | 
						|
 | 
						|
        private ChartCrosshair _ChartCrosshair;
 | 
						|
        private List<CrosshairPoint> _CrosshairSeriesPoints;
 | 
						|
        private CrosshairPoint _NearestCrosshairPoint;
 | 
						|
        private bool _CanShowCrosshairLabel;
 | 
						|
 | 
						|
        private object _MinValueX;
 | 
						|
        private object _MaxValueX;
 | 
						|
 | 
						|
        private object _MinValueY;
 | 
						|
        private object _MaxValueY;
 | 
						|
 | 
						|
        private Size _MinQualitativeSize;
 | 
						|
 | 
						|
        private PointMarker _PointMarker;
 | 
						|
 | 
						|
        private ChartLineDisplayMode _ChartLineDisplayMode = ChartLineDisplayMode.NotSet;
 | 
						|
        private ChartLineAreaDisplayMode _ChartLineAreaDisplayMode = ChartLineAreaDisplayMode.NotSet;
 | 
						|
 | 
						|
        private BubbleSizeMode _BubbleSizeMode = BubbleSizeMode.NotSet;
 | 
						|
        private BubbleIntensityMode _BubbleIntensityMode = BubbleIntensityMode.NotSet;
 | 
						|
        private ConvexHullDisplayMode _ConvexHullDisplayMode = ConvexHullDisplayMode.NotSet;
 | 
						|
        private PointLabelDisplayMode _PointLabelDisplayType = PointLabelDisplayMode.NotSet;
 | 
						|
 | 
						|
        private StepLines _StepLines = StepLines.NotSet;
 | 
						|
        private StepLineMode _StepLineMode = StepLineMode.NotSet;
 | 
						|
 | 
						|
        private List<PointLabelGroup> _PointLabels;
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        public ChartXy(string name)
 | 
						|
            : this()
 | 
						|
        {
 | 
						|
            Name = name;
 | 
						|
        }
 | 
						|
 | 
						|
        public ChartXy()
 | 
						|
        {
 | 
						|
            InitDefaultStates();
 | 
						|
 | 
						|
            _EffectiveChartStyle = new EffectiveStyle<ChartXyVisualStyle>(this);
 | 
						|
            _EffectiveChartSeriesStyle = new EffectiveStyle<ChartSeriesVisualStyle>(this);
 | 
						|
 | 
						|
            _EffectiveDataLabelStyle = new EffectiveStyle<DataLabelVisualStyle>(this);
 | 
						|
        }
 | 
						|
 | 
						|
        #region InitDefaultStates
 | 
						|
 | 
						|
        private void InitDefaultStates()
 | 
						|
        {
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Public properties
 | 
						|
 | 
						|
        #region AncillaryAxesX
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets a reference to the collection of Ancillary X Axes (Axes that
 | 
						|
        /// can be presented in addition to the default X Axis)
 | 
						|
        /// </summary>
 | 
						|
        [Category("Axis")]
 | 
						|
        [Description("Indicates the collection of Ancillary X Axes (Axes that can be presented in addition to the default X Axis.")]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | 
						|
        public ChartAxesXCollection AncillaryAxesX
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                if (_AncillaryAxesX == null)
 | 
						|
                {
 | 
						|
                    _AncillaryAxesX = new ChartAxesXCollection();
 | 
						|
                    _AncillaryAxesX.CollectionChanged += AncillaryAxesCollectionChanged;
 | 
						|
                }
 | 
						|
 | 
						|
                return (_AncillaryAxesX);
 | 
						|
            }
 | 
						|
 | 
						|
            internal set
 | 
						|
            {
 | 
						|
                if (_AncillaryAxesX != null)
 | 
						|
                    _AncillaryAxesX.CollectionChanged -= AncillaryAxesCollectionChanged;
 | 
						|
 | 
						|
                _AncillaryAxesX = value;
 | 
						|
 | 
						|
                if (_AncillaryAxesX != null)
 | 
						|
                    _AncillaryAxesX.CollectionChanged += AncillaryAxesCollectionChanged;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region AncillaryAxesCollectionChanged
 | 
						|
 | 
						|
        private void AncillaryAxesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
 | 
						|
        {
 | 
						|
            ChartAxesCollection cac = sender as ChartAxesCollection;
 | 
						|
 | 
						|
            switch (e.Action)
 | 
						|
            {
 | 
						|
                case NotifyCollectionChangedAction.Add:
 | 
						|
                    AddAxisItems(e, cac.AxisOrientation);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case NotifyCollectionChangedAction.Replace:
 | 
						|
                    RemoveAxisItems(e);
 | 
						|
                    AddAxisItems(e, cac.AxisOrientation);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case NotifyCollectionChangedAction.Remove:
 | 
						|
                    RemoveAxisItems(e);
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
 | 
						|
            InvalidateLayout();
 | 
						|
        }
 | 
						|
 | 
						|
        #region AddAxisItems
 | 
						|
 | 
						|
        private void AddAxisItems(
 | 
						|
            NotifyCollectionChangedEventArgs e, AxisOrientation axisOrientation)
 | 
						|
        {
 | 
						|
            foreach (ChartAxis axis in e.NewItems)
 | 
						|
            {
 | 
						|
                if (axis.AxisOrientation != axisOrientation)
 | 
						|
                {
 | 
						|
                    if (axisOrientation == AxisOrientation.X)
 | 
						|
                        throw new Exception("Cannot add Y-Axis element to X-Axis collection.");
 | 
						|
                    else
 | 
						|
                        throw new Exception("Cannot add X-Axis element to Y-Axis collection.");
 | 
						|
                }
 | 
						|
 | 
						|
                axis.Parent = this;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RemoveAxisItems
 | 
						|
 | 
						|
        private void RemoveAxisItems(NotifyCollectionChangedEventArgs e)
 | 
						|
        {
 | 
						|
            foreach (ChartAxis axis in e.OldItems)
 | 
						|
                axis.Parent = null;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region AncillaryAxesY
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets a reference to the collection of Ancillary Y Axes (Axes that
 | 
						|
        /// can be presented in addition to the default Y Axis)
 | 
						|
        /// </summary>
 | 
						|
        [Category("Axis")]
 | 
						|
        [Description("Indicates the collection of Ancillary Y Axes (Axes that can be presented in addition to the default Y Axis.")]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | 
						|
        public ChartAxesYCollection AncillaryAxesY
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                if (_AncillaryAxesY == null)
 | 
						|
                {
 | 
						|
                    _AncillaryAxesY = new ChartAxesYCollection();
 | 
						|
                    _AncillaryAxesY.CollectionChanged += AncillaryAxesCollectionChanged;
 | 
						|
                }
 | 
						|
 | 
						|
                return (_AncillaryAxesY);
 | 
						|
            }
 | 
						|
 | 
						|
            internal set
 | 
						|
            {
 | 
						|
                if (_AncillaryAxesY != null)
 | 
						|
                    _AncillaryAxesY.CollectionChanged -= AncillaryAxesCollectionChanged;
 | 
						|
 | 
						|
                _AncillaryAxesY = value;
 | 
						|
 | 
						|
                if (_AncillaryAxesY != null)
 | 
						|
                    _AncillaryAxesY.CollectionChanged += AncillaryAxesCollectionChanged;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region AutoGenSeriesType
 | 
						|
 | 
						|
        ///<summary>
 | 
						|
        /// Gets or sets the default SeriesType assigned to auto-generated Series.
 | 
						|
        ///</summary>
 | 
						|
        [DefaultValue(SeriesType.Point), Category("Behavior")]
 | 
						|
        [Description("Indicates the default SeriesType assigned to auto-generated Series.")]
 | 
						|
        public SeriesType AutoGenSeriesType
 | 
						|
        {
 | 
						|
            get { return (_AutoGenSeriesChartType); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _AutoGenSeriesChartType)
 | 
						|
                {
 | 
						|
                    _AutoGenSeriesChartType = value;
 | 
						|
 | 
						|
                    OnPropertyChanged("AutoGenSeriesType");
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region AxisX
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets a reference to the default, primary X Axis.
 | 
						|
        /// </summary>
 | 
						|
        [Category("Axis")]
 | 
						|
        [Description("Indicates the reference to the default, primary X Axis.")]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | 
						|
        public ChartAxisX AxisX
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                if (_AxisX == null)
 | 
						|
                {
 | 
						|
                    _AxisX = new ChartAxisX();
 | 
						|
 | 
						|
                    _AxisX.Parent = this;
 | 
						|
                    _AxisX.IsPrimaryAxis = true;
 | 
						|
                }
 | 
						|
 | 
						|
                return (_AxisX);
 | 
						|
            }
 | 
						|
 | 
						|
            internal set
 | 
						|
            {
 | 
						|
                if (_AxisX != null)
 | 
						|
                    _AxisX.Parent = null;
 | 
						|
 | 
						|
                _AxisX = value;
 | 
						|
 | 
						|
                if (_AxisX != null)
 | 
						|
                {
 | 
						|
                    _AxisX.Parent = this;
 | 
						|
                    _AxisX.IsPrimaryAxis = true;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region AxisY
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets a reference to the default, primary Y Axis.
 | 
						|
        /// </summary>
 | 
						|
        [Category("Axis")]
 | 
						|
        [Description("Indicates the reference to the default, primary Y Axis.")]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | 
						|
        public ChartAxisY AxisY
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                if (_AxisY == null)
 | 
						|
                {
 | 
						|
                    _AxisY = new ChartAxisY();
 | 
						|
 | 
						|
                    _AxisY.Parent = this;
 | 
						|
                    _AxisY.IsPrimaryAxis = true;
 | 
						|
                }
 | 
						|
 | 
						|
                return (_AxisY);
 | 
						|
            }
 | 
						|
 | 
						|
            internal set
 | 
						|
            {
 | 
						|
                if (_AxisY != null)
 | 
						|
                    _AxisY.Parent = null;
 | 
						|
 | 
						|
                _AxisY = value;
 | 
						|
 | 
						|
                if (_AxisY != null)
 | 
						|
                {
 | 
						|
                    _AxisY.Parent = this;
 | 
						|
                    _AxisY.IsPrimaryAxis = true;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region BarFillRange
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets how series bars are filled by default (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 by default(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 default position of bar series labels (default is Center).
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(BarLabelPosition.NotSet), Category("Bar Display")]
 | 
						|
        [Description("Indicates the default 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 BarOrigin
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the bar 'origin'.  This value is used as the base, or 
 | 
						|
        /// starting Value, from which each bar originates.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(null), Category("Bar Display")]
 | 
						|
        [Description("Indicates the bar 'origin'.  This value is used as the base, or starting Value, from which each bar originates.")]
 | 
						|
        [TypeConverter("DevComponents.Charts.Design.PointValueConverter, DevComponents.Charts.Design," +
 | 
						|
            "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")]
 | 
						|
        public object BarOrigin
 | 
						|
        {
 | 
						|
            get { return (_BarOrigin); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _BarOrigin)
 | 
						|
                {
 | 
						|
                    _BarOrigin = value;
 | 
						|
 | 
						|
                    OnPropertyChangedEx("BarOrigin", VisualChangeType.Layout);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region BarOverlayEnabled
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets whether the intra-bar (or bar grouping) overlay
 | 
						|
        /// is enabled (bars within a group are positoned overlayed on top of each other).
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(false), Category("Bar Display")]
 | 
						|
        [Description("Indicates whether the intra-bar (or bar grouping) overlay is enabled (bars within a group are positoned overlayed on top of each other).")]
 | 
						|
        public bool BarOverlayEnabled
 | 
						|
        {
 | 
						|
            get { return (TestState(States.BarOverlayEnabled)); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != BarOverlayEnabled)
 | 
						|
                {
 | 
						|
                    SetState(States.BarOverlayEnabled, value);
 | 
						|
 | 
						|
                    OnPropertyChangedEx("BarOverlayEnabled", VisualChangeType.Layout);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region BarShadingEnabled
 | 
						|
 | 
						|
        ///<summary>
 | 
						|
        /// Gets or sets whether Bar shading is enabled by
 | 
						|
        /// default for Horizontal and Vertical Bar series.
 | 
						|
        ///</summary>
 | 
						|
        [DefaultValue(Tbool.NotSet), Category("Bar Display")]
 | 
						|
        [Description("Indicates whether Bar shading is enabled by default for Horizontal and Vertical Bar series.")]
 | 
						|
        public Tbool BarShadingEnabled
 | 
						|
        {
 | 
						|
            get { return (_BarShadingEnabled); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _BarShadingEnabled)
 | 
						|
                {
 | 
						|
                    _BarShadingEnabled = value;
 | 
						|
 | 
						|
                    OnPropertyChangedEx("BarShadingEnabled", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region BarShowAsHistogram
 | 
						|
 | 
						|
        ///<summary>
 | 
						|
        /// Gets or sets whether the bars will be shown as a Histogram.
 | 
						|
        /// Note that this will only be honored for single series bar displays.
 | 
						|
        ///</summary>
 | 
						|
        [DefaultValue(Tbool.NotSet), Category("Bar Display")]
 | 
						|
        [Description("Indicates whether the bars will be shown as a Histogram. Note that this will only be honored for single series bar displays.")]
 | 
						|
        public Tbool BarShowAsHistogram
 | 
						|
        {
 | 
						|
            get { return (_BarShowAsHistogram); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _BarShowAsHistogram)
 | 
						|
                {
 | 
						|
                    _BarShowAsHistogram = value;
 | 
						|
 | 
						|
                    OnPropertyChangedEx("BarShowAsHistogram", VisualChangeType.Layout);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region BarSpacing
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the intra-bar spacing (or spacing between bars
 | 
						|
        /// within the same group). Value is taken as a fixed pixel size.
 | 
						|
        /// Setting BarSpacing to 0 (zero) will disable the use of this
 | 
						|
        /// property, and will enable the use of the set BarSpacingRatio value.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(0), Category("Bar Display")]
 | 
						|
        [Description("Indicates the intra-bar spacing (or spacing between bars within the same group). Value is taken as a fixed pixel size. Setting BarSpacing to 0 (zero) will disable the use of this property, and will enable the use of the set BarSpacingRatio value.")]
 | 
						|
        public int BarSpacing
 | 
						|
        {
 | 
						|
            get { return (_BarSpacing); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _BarSpacing)
 | 
						|
                {
 | 
						|
                    _BarSpacing = value;
 | 
						|
 | 
						|
                    OnPropertyChangedEx("BarSpacing", VisualChangeType.Layout);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region BarSpacingRatio
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the intra-bar spacing ratio (bar spacing between
 | 
						|
        /// multiple series bars associated with the same value. Default is .2).
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(0.2d), Category("Bar Display")]
 | 
						|
        [Description("Indicates the intra-bar spacing ratio (bar spacing between multiple series bars associated with the same value. Default is .2).")]
 | 
						|
        public double BarSpacingRatio
 | 
						|
        {
 | 
						|
            get { return (_BarSpacingRatio); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _BarSpacingRatio)
 | 
						|
                {
 | 
						|
                    if (value < 0)
 | 
						|
                        throw new ArgumentException("Value must be >= 0");
 | 
						|
 | 
						|
                    _BarSpacingRatio = value;
 | 
						|
 | 
						|
                    OnPropertyChangedEx("BarSpacingRatio", VisualChangeType.Layout);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region BarWidthRatio
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the default ratio of bar width to bar 
 | 
						|
        /// group spacing (defaults to 1 - bar width matches spacing).
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(0d), Category("Bar Display")]
 | 
						|
        [Description("Indicates the default ratio of bar width to bar group spacing (defaults to 1 - bar width matches 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 default mode used to determine series bubble intensities.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(BubbleIntensityMode.NotSet), Category("Display")]
 | 
						|
        [Description("Indicates the default mode used to determine series bubble intensities.")]
 | 
						|
        public BubbleIntensityMode BubbleIntensityMode
 | 
						|
        {
 | 
						|
            get { return (_BubbleIntensityMode); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _BubbleIntensityMode)
 | 
						|
                {
 | 
						|
                    _BubbleIntensityMode = value;
 | 
						|
 | 
						|
                    OnPropertyChangedEx("BubbleIntensityMode", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region BubbleSizeMode
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the default mode used to calculate series bubble sizes.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(BubbleSizeMode.NotSet), Category("Display")]
 | 
						|
        [Description("Indicates the default mode used to calculate series bubble sizes.")]
 | 
						|
        public BubbleSizeMode BubbleSizeMode
 | 
						|
        {
 | 
						|
            get { return (_BubbleSizeMode); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _BubbleSizeMode)
 | 
						|
                {
 | 
						|
                    _BubbleSizeMode = value;
 | 
						|
 | 
						|
                    OnPropertyChangedEx("BubbleSizeMode", VisualChangeType.Layout);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ChartLineAreaDisplayMode
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the default Line 'Area' display mode.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(ChartLineAreaDisplayMode.NotSet), Category("Display")]
 | 
						|
        [Description("Indicates the default Line 'Area' 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 default display mode for SeriesType.Line series.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(ChartLineDisplayMode.NotSet), Category("Display")]
 | 
						|
        [Description("Indicates the default display mode for SeriesType.Line series.")]
 | 
						|
        [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)
 | 
						|
                {
 | 
						|
                    if ((_ChartLineDisplayMode & ChartLineDisplayMode.DisplayUnsorted) !=
 | 
						|
                        (value & ChartLineDisplayMode.DisplayUnsorted))
 | 
						|
                    {
 | 
						|
                        foreach (ChartSeries series in ChartSeries)
 | 
						|
                            series.ResetSortedPoints();
 | 
						|
                    }
 | 
						|
 | 
						|
                    _ChartLineDisplayMode = value;
 | 
						|
 | 
						|
                    OnPropertyChangedEx("ChartLineDisplayMode", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ChartSeries
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets a reference to the collection of Chart Series
 | 
						|
        /// </summary>
 | 
						|
        [Category("Data")]
 | 
						|
        [Description("Indicates the collection of Chart Series.")]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | 
						|
        public ChartSeriesCollection ChartSeries
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                if (_ChartSeries == null)
 | 
						|
                {
 | 
						|
                    _ChartSeries = new ChartSeriesCollection();
 | 
						|
 | 
						|
                    _ChartSeries.CollectionChanged += ChartSeriesCollectionChanged;
 | 
						|
                }
 | 
						|
 | 
						|
                return (_ChartSeries);
 | 
						|
            }
 | 
						|
 | 
						|
            internal set
 | 
						|
            {
 | 
						|
                BaseSeries = null;
 | 
						|
 | 
						|
                if (_ChartSeries != null)
 | 
						|
                    _ChartSeries.CollectionChanged -= ChartSeriesCollectionChanged;
 | 
						|
 | 
						|
                _ChartSeries = value;
 | 
						|
 | 
						|
                if (_ChartSeries != null)
 | 
						|
                    _ChartSeries.CollectionChanged += ChartSeriesCollectionChanged;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region ChartSeriesCollectionChanged
 | 
						|
 | 
						|
        void ChartSeriesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
 | 
						|
        {
 | 
						|
            BaseSeries = null;
 | 
						|
 | 
						|
            switch (e.Action)
 | 
						|
            {
 | 
						|
                case NotifyCollectionChangedAction.Add:
 | 
						|
                    foreach (ChartSeries item in e.NewItems)
 | 
						|
                        item.Parent = this;
 | 
						|
                    break;
 | 
						|
 | 
						|
                case NotifyCollectionChangedAction.Replace:
 | 
						|
                    foreach (ChartSeries item in e.OldItems)
 | 
						|
                        item.Parent = null;
 | 
						|
 | 
						|
                    foreach (ChartSeries item in e.NewItems)
 | 
						|
                        item.Parent = this;
 | 
						|
                    break;
 | 
						|
 | 
						|
                case NotifyCollectionChangedAction.Remove:
 | 
						|
                    foreach (ChartSeries item in e.OldItems)
 | 
						|
                        item.Parent = null;
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
 | 
						|
            ValidateSeriesCollection();
 | 
						|
 | 
						|
            InvalidateLayout();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ValidateSeriesCollection
 | 
						|
 | 
						|
        private void ValidateSeriesCollection()
 | 
						|
        {
 | 
						|
            SeriesRangeChanged = true;
 | 
						|
 | 
						|
            foreach (ChartSeries series in ChartSeries)
 | 
						|
            {
 | 
						|
                ChartAxis axis = series.AxisX;
 | 
						|
 | 
						|
                if (axis != null && axis.IsPrimaryAxis == false)
 | 
						|
                {
 | 
						|
                    if (AncillaryAxesX.Contains(axis) == false)
 | 
						|
                    {
 | 
						|
                        throw new Exception("Cannot set the series YAxis. The axis is not primary " +
 | 
						|
                            "or a member of the chart's AncillaryAxesY collection.");
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                axis = series.AxisY;
 | 
						|
 | 
						|
                if (axis != null && axis.IsPrimaryAxis == false)
 | 
						|
                {
 | 
						|
                    if (AncillaryAxesY.Contains(axis) == false)
 | 
						|
                    {
 | 
						|
                        throw new Exception("Cannot set the series YAxis. The axis is not primary " +
 | 
						|
                            "or a member of the chart's AncillaryAxesY collection.");
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ChartSeriesVisualStyle
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the default visual style for each chart series.
 | 
						|
        /// </summary>
 | 
						|
        [Category("Style")]
 | 
						|
        [Description("Indicates the default visual style for each chart 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 ChartVisualStyle
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the visual style for the Chart.
 | 
						|
        /// </summary>
 | 
						|
        [Category("Style")]
 | 
						|
        [Description("Indicates the visual style for the Chart.")]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | 
						|
        public ChartXyVisualStyle ChartVisualStyle
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                if (_ChartVisualStyle == null)
 | 
						|
                {
 | 
						|
                    _ChartVisualStyle = new ChartXyVisualStyle();
 | 
						|
 | 
						|
                    StyleVisualChangeHandler(null, _ChartVisualStyle);
 | 
						|
                }
 | 
						|
 | 
						|
                return (_ChartVisualStyle);
 | 
						|
            }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (_ChartVisualStyle != value)
 | 
						|
                {
 | 
						|
                    ChartXyVisualStyle oldValue = _ChartVisualStyle;
 | 
						|
 | 
						|
                    _ChartVisualStyle = value;
 | 
						|
 | 
						|
                    OnStyleChanged("ChartVisualStyle", oldValue, value);
 | 
						|
 | 
						|
                    if (oldValue != null)
 | 
						|
                        oldValue.Dispose();
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ChartCrosshair
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets a reference to the Crosshair element for the chart.
 | 
						|
        /// </summary>
 | 
						|
        [Category("Appearance")]
 | 
						|
        [Description("Indicates a reference to the Crosshair element for the chart.")]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | 
						|
        public ChartCrosshair ChartCrosshair
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                if (_ChartCrosshair == null)
 | 
						|
                {
 | 
						|
                    _ChartCrosshair = new ChartCrosshair();
 | 
						|
 | 
						|
                    _ChartCrosshair.Parent = this;
 | 
						|
                    _ChartCrosshair.PropertyChanged += ChartCrosshair_PropertyChanged;
 | 
						|
                }
 | 
						|
 | 
						|
                return (_ChartCrosshair);
 | 
						|
            }
 | 
						|
 | 
						|
            internal set
 | 
						|
            {
 | 
						|
                if (_ChartCrosshair != null)
 | 
						|
                {
 | 
						|
                    _ChartCrosshair.Parent = null;
 | 
						|
                    _ChartCrosshair.PropertyChanged -= ChartCrosshair_PropertyChanged;
 | 
						|
                }
 | 
						|
 | 
						|
                _ChartCrosshair = value;
 | 
						|
 | 
						|
                if (_ChartCrosshair != null)
 | 
						|
                {
 | 
						|
                    _ChartCrosshair.Parent = this;
 | 
						|
                    _ChartCrosshair.PropertyChanged += ChartCrosshair_PropertyChanged;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region ChartCrosshair_PropertyChanged
 | 
						|
 | 
						|
        void ChartCrosshair_PropertyChanged(object sender, PropertyChangedEventArgs e)
 | 
						|
        {
 | 
						|
            InvalidateRender();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ConvexHullDisplayMode
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the default ConvexHull display mode.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(ConvexHullDisplayMode.NotSet), Category("Display")]
 | 
						|
        [Description("Indicates the default 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 DataLabelOverlapMode
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the mode for resolving overlapping series data labels.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(DataLabelOverlapMode.NotSet), Category("Display")]
 | 
						|
        [Description("Indicates the mode for resolving overlapping series data labels.")]
 | 
						|
        public DataLabelOverlapMode DataLabelOverlapMode
 | 
						|
        {
 | 
						|
            get { return (_DataLabelOverlapMode); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _DataLabelOverlapMode)
 | 
						|
                {
 | 
						|
                    _DataLabelOverlapMode = value;
 | 
						|
 | 
						|
                    OnPropertyChangedEx("DataLabelOverlapMode", VisualChangeType.Layout);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DataLabelVisualStyle
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the default visual style for the chart DataLabel's.
 | 
						|
        /// </summary>
 | 
						|
        [Category("Style")]
 | 
						|
        [Description("Indicates the default visual style for the chart DataLabel's.")]
 | 
						|
        [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 EffectiveChartSeriesStyle
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets a reference to the ChartSeries effective (cached, composite) style.
 | 
						|
        /// </summary>
 | 
						|
        [Browsable(false)]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | 
						|
        public ChartSeriesVisualStyle EffectiveChartSeriesStyle
 | 
						|
        {
 | 
						|
            get { return (_EffectiveChartSeriesStyle.Style); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region EffectiveChartStyle
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets a reference to the Chart's Effective (cached, composite) style.
 | 
						|
        /// </summary>
 | 
						|
        [Browsable(false)]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | 
						|
        public ChartXyVisualStyle EffectiveChartStyle
 | 
						|
        {
 | 
						|
            get { return (_EffectiveChartStyle.Style); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region EffectiveDataLabelStyle
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets a reference to the DataLabel Effective (cached, composite) style.
 | 
						|
        /// </summary>
 | 
						|
        [Browsable(false)]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | 
						|
        [Description("Indicates a reference to the DataLabel Effective (cached, composite) style.")]
 | 
						|
        public DataLabelVisualStyle EffectiveDataLabelStyle
 | 
						|
        {
 | 
						|
            get { return (_EffectiveDataLabelStyle.Style); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MaxValueX
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the calculated maximum X value (composite value of all associated series).
 | 
						|
        /// </summary>
 | 
						|
        [Browsable(false)]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | 
						|
        public object MaxValueX
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                UpdateRangeValues();
 | 
						|
 | 
						|
                return (_MaxValueX);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MaxValueY
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the calculated maximum Y value (composite value of all associated series).
 | 
						|
        /// </summary>
 | 
						|
        [Browsable(false)]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | 
						|
        public object MaxValueY
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                UpdateRangeValues();
 | 
						|
 | 
						|
                return (_MaxValueY);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MinValueX
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the calculated minimum X value (composite value of all associated series).
 | 
						|
        /// </summary>
 | 
						|
        [Browsable(false)]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | 
						|
        public object MinValueX
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                UpdateRangeValues();
 | 
						|
 | 
						|
                return (_MinValueX);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MinValueY
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the calculated minimum Y value (composite value of all associated series).
 | 
						|
        /// </summary>
 | 
						|
        [Browsable(false)]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | 
						|
        public object MinValueY
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                UpdateRangeValues();
 | 
						|
 | 
						|
                return (_MinValueY);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region NearestCrosshairPoint
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the last calculated CrosshairPoint nearest to the mouse cursor.
 | 
						|
        /// </summary>
 | 
						|
        [Browsable(false)]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | 
						|
        public CrosshairPoint NearestCrosshairPoint
 | 
						|
        {
 | 
						|
            get { return (_NearestCrosshairPoint); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region PointLabelDisplayMode
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the default display mode for the chart PointLabels.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(PointLabelDisplayMode.NotSet), Category("Display")]
 | 
						|
        [Description("Indicates the default 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 (_PointLabelDisplayType); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _PointLabelDisplayType)
 | 
						|
                {
 | 
						|
                    _PointLabelDisplayType = value;
 | 
						|
 | 
						|
                    InvalidatePointLabels();
 | 
						|
 | 
						|
                    OnPropertyChangedEx("PointLabelDisplayMode", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ScrollBounds
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the Scrollable bounds of the chart.
 | 
						|
        /// </summary>
 | 
						|
        [Browsable(false)]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | 
						|
        public override Rectangle ScrollBounds
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                ChartXyVisualStyle xyStyle = EffectiveChartStyle;
 | 
						|
 | 
						|
                Rectangle cbounds = ContentBounds;
 | 
						|
 | 
						|
                cbounds.X += xyStyle.BorderThickness.Left;
 | 
						|
                cbounds.Width -= xyStyle.BorderThickness.Horizontal;
 | 
						|
 | 
						|
                cbounds.Y += xyStyle.BorderThickness.Top;
 | 
						|
                cbounds.Height -= xyStyle.BorderThickness.Vertical;
 | 
						|
 | 
						|
                return (cbounds);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ScrollBoundsEx
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the Scrollable, extended bounds of the chart.
 | 
						|
        /// </summary>
 | 
						|
        [Browsable(false)]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | 
						|
        public override Rectangle ScrollBoundsEx
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                ChartXyVisualStyle xyStyle = EffectiveChartStyle;
 | 
						|
 | 
						|
                Rectangle cbounds = ContentBoundsEx;
 | 
						|
 | 
						|
                cbounds.X += xyStyle.BorderThickness.Left;
 | 
						|
                cbounds.Width -= xyStyle.BorderThickness.Horizontal;
 | 
						|
 | 
						|
                cbounds.Y += xyStyle.BorderThickness.Top;
 | 
						|
                cbounds.Height -= xyStyle.BorderThickness.Vertical;
 | 
						|
 | 
						|
                return (cbounds);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region StepLines
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets which 'Step lines' are displayed by default.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(StepLines.NotSet), Category("Display")]
 | 
						|
        [Description("Indicates which 'Step lines' are displayed by default.")]
 | 
						|
        public StepLines StepLines
 | 
						|
        {
 | 
						|
            get { return (_StepLines); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _StepLines)
 | 
						|
                {
 | 
						|
                    _StepLines = value;
 | 
						|
 | 
						|
                    OnPropertyChangedEx("StepLines", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region StepLineMode
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the default mode (or order of rendered Step Lines)
 | 
						|
        /// used to display "Step Lines" in the defined Line series.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(StepLineMode.NotSet), Category("Display")]
 | 
						|
        [Description("Indicates the default mode (or order of rendered Step Lines) used to display '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 CrosshairSeriesPoints
 | 
						|
 | 
						|
        internal List<CrosshairPoint> CrosshairSeriesPoints
 | 
						|
        {
 | 
						|
            get { return (_CrosshairSeriesPoints); }
 | 
						|
            set { _CrosshairSeriesPoints = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DisplayCrosshair
 | 
						|
 | 
						|
        internal bool DisplayCrosshair
 | 
						|
        {
 | 
						|
            get { return (TestState(States.DisplayCrosshair)); }
 | 
						|
            set { SetState(States.DisplayCrosshair, value); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DropShadowDisplayed
 | 
						|
 | 
						|
        internal bool DropShadowDisplayed
 | 
						|
        {
 | 
						|
            get { return (TestState(States.DropShadowDisplayed)); }
 | 
						|
            set { SetState(States.DropShadowDisplayed, value); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MinQualitativeSize
 | 
						|
 | 
						|
        internal Size MinQualitativeSize
 | 
						|
        {
 | 
						|
            get { return (_MinQualitativeSize); }
 | 
						|
            set { _MinQualitativeSize = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region PointLabels
 | 
						|
 | 
						|
        internal List<PointLabelGroup> PointLabels
 | 
						|
        {
 | 
						|
            get { return (_PointLabels); }
 | 
						|
            set { _PointLabels = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MeasureOverride
 | 
						|
 | 
						|
        protected override void MeasureOverride(ChartLayoutInfo layoutInfo)
 | 
						|
        {
 | 
						|
            ContainerVisualStyle cstyle = GetEffectiveContainerStyle();
 | 
						|
            ChartXyVisualStyle xystyle = EffectiveChartStyle;
 | 
						|
 | 
						|
            BoundsRelative = layoutInfo.LayoutBounds;
 | 
						|
 | 
						|
            MinQualitativeSize = Size.Empty;
 | 
						|
 | 
						|
            UpdateDataBindings();
 | 
						|
            UpdateRangeValues();
 | 
						|
 | 
						|
            Rectangle oldFrameBounds = FrameBounds;
 | 
						|
 | 
						|
            FrameBounds = GetAdjustedBounds(BoundsRelative, cstyle.Margin);
 | 
						|
            FrameBounds = GetAdjustedBounds(FrameBounds, cstyle.Padding);
 | 
						|
            FrameBounds = GetAdjustedBounds(FrameBounds, xystyle.Margin);
 | 
						|
 | 
						|
            if (FrameBounds != oldFrameBounds)
 | 
						|
                SeriesPointCount++;
 | 
						|
 | 
						|
            ContentBounds = GetAdjustedBounds(FrameBounds, cstyle.BorderThickness);
 | 
						|
            ContentBounds = GetAdjustedBounds(ContentBounds, xystyle.BorderThickness);
 | 
						|
            ContentBounds = GetAdjustedBounds(ContentBounds, xystyle.Padding);
 | 
						|
 | 
						|
            layoutInfo.LayoutBounds = ContentBounds;
 | 
						|
 | 
						|
            foreach (ChartTitle title in Titles)
 | 
						|
            {
 | 
						|
                if (title.Visible == true)
 | 
						|
                    title.Measure(layoutInfo);
 | 
						|
            }
 | 
						|
 | 
						|
            if (Legend.Visible == true && Legend.Placement != Placement.Inside)
 | 
						|
                Legend.Measure(layoutInfo);
 | 
						|
 | 
						|
            DropShadowDisplayed = (xystyle.DropShadow.Enabled == Tbool.True);
 | 
						|
 | 
						|
            MeasureSeries(layoutInfo);
 | 
						|
            MeasureXyAxes(layoutInfo);
 | 
						|
 | 
						|
            if (DropShadowDisplayed == true)
 | 
						|
                layoutInfo.LayoutBounds = GetShadowBounds(layoutInfo.LayoutBounds);
 | 
						|
 | 
						|
            if (Legend.Visible == true && Legend.Placement == Placement.Inside)
 | 
						|
            {
 | 
						|
                Rectangle t = layoutInfo.LayoutBounds;
 | 
						|
 | 
						|
                if (VScrollBar.Visible == true)
 | 
						|
                {
 | 
						|
                    t.Width -= (VScrollBar.Width - 1);
 | 
						|
                    layoutInfo.LayoutBounds = t;
 | 
						|
                }
 | 
						|
 | 
						|
                if (HScrollBar.Visible == true)
 | 
						|
                {
 | 
						|
                    t.Height -= (HScrollBar.Height - 1);
 | 
						|
                    layoutInfo.LayoutBounds = t;
 | 
						|
                }
 | 
						|
 | 
						|
                Legend.Measure(layoutInfo);
 | 
						|
 | 
						|
                if (VScrollBar.Visible == true)
 | 
						|
                {
 | 
						|
                    t.Width += VScrollBar.Width;
 | 
						|
                    layoutInfo.LayoutBounds = t;
 | 
						|
                }
 | 
						|
 | 
						|
                if (HScrollBar.Visible == true)
 | 
						|
                {
 | 
						|
                    t.Height += HScrollBar.Height;
 | 
						|
                    layoutInfo.LayoutBounds = t;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            Rectangle oldContentBoundsEx = ContentBoundsEx;
 | 
						|
 | 
						|
            ContentBounds = layoutInfo.LayoutBounds;
 | 
						|
            ContentBoundsEx = ContentBounds;
 | 
						|
 | 
						|
            Rectangle r = ContentBounds;
 | 
						|
 | 
						|
            r.Size = new Size(
 | 
						|
                Math.Max(r.Size.Width, Dpi.Width(MinContentSize.Width)),
 | 
						|
                Math.Max(r.Size.Height, Dpi.Height(MinContentSize.Height)));
 | 
						|
 | 
						|
            if (MinQualitativeSize.Width > r.Width)
 | 
						|
                r.Width = MinQualitativeSize.Width;
 | 
						|
 | 
						|
            if (MinQualitativeSize.Height > r.Height)
 | 
						|
                r.Height = MinQualitativeSize.Height;
 | 
						|
 | 
						|
            // Since our vertical scrollbar is reversed, we
 | 
						|
            // need to adjust the extended content area accordingly
 | 
						|
 | 
						|
            if (r.Height > ContentBounds.Height)
 | 
						|
                r.Y -= (r.Height - ContentBounds.Height);
 | 
						|
 | 
						|
            ContentBoundsEx = r;
 | 
						|
 | 
						|
            if (ContentBoundsEx.Equals(oldContentBoundsEx) == false)
 | 
						|
                _PointLabels = null;
 | 
						|
 | 
						|
            FinalizeDataBindings();
 | 
						|
        }
 | 
						|
 | 
						|
        #region MeasureSeries
 | 
						|
 | 
						|
        private void MeasureSeries(ChartLayoutInfo layoutInfo)
 | 
						|
        {
 | 
						|
            ChartSeries[] aseries = new ChartSeries[ChartSeries.Count];
 | 
						|
 | 
						|
            ChartSeries.CopyTo(aseries, 0);
 | 
						|
 | 
						|
            foreach (ChartSeries series in aseries)
 | 
						|
            {
 | 
						|
                if (series.Visible == true)
 | 
						|
                    series.Measure(layoutInfo);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MeasureXyAxes
 | 
						|
 | 
						|
        private void MeasureXyAxes(ChartLayoutInfo layoutInfo)
 | 
						|
        {
 | 
						|
            Rectangle obounds = layoutInfo.LayoutBounds;
 | 
						|
 | 
						|
            SetEdgeAxes(AncillaryAxesX, AxisX);
 | 
						|
            SetEdgeAxes(AncillaryAxesY, AxisY);
 | 
						|
 | 
						|
            MeasureAxes(layoutInfo, AncillaryAxesX, AxisX);
 | 
						|
 | 
						|
            Rectangle nbounds = layoutInfo.LayoutBounds;
 | 
						|
 | 
						|
            MeasureAxes(layoutInfo, AncillaryAxesY, AxisY);
 | 
						|
 | 
						|
            for (int i = 0; i < 10; i++)
 | 
						|
            {
 | 
						|
                if (layoutInfo.LayoutBounds.Width == nbounds.Width)
 | 
						|
                    break;
 | 
						|
 | 
						|
                nbounds = layoutInfo.LayoutBounds;
 | 
						|
 | 
						|
                layoutInfo.LayoutBoundsAdjusted = true;
 | 
						|
                layoutInfo.LayoutBounds.Y = obounds.Y;
 | 
						|
                layoutInfo.LayoutBounds.Height = obounds.Height;
 | 
						|
 | 
						|
                MeasureAxes(layoutInfo, AncillaryAxesX, AxisX);
 | 
						|
 | 
						|
                if (layoutInfo.LayoutBounds.Height == nbounds.Height)
 | 
						|
                    break;
 | 
						|
 | 
						|
                layoutInfo.LayoutBounds.X = obounds.X;
 | 
						|
                layoutInfo.LayoutBounds.Width = obounds.Width;
 | 
						|
 | 
						|
                MeasureAxes(layoutInfo, AncillaryAxesY, AxisY);
 | 
						|
            }
 | 
						|
 | 
						|
            ValidateAxes();
 | 
						|
        }
 | 
						|
 | 
						|
        #region MeasureAxes
 | 
						|
 | 
						|
        private void MeasureAxes(
 | 
						|
            ChartLayoutInfo layoutInfo, ChartAxesCollection axes, ChartAxis axis)
 | 
						|
        {
 | 
						|
            for (int i = axes.Count - 1; i >= 0; i--)
 | 
						|
            {
 | 
						|
                ChartAxis ca = axes[i];
 | 
						|
 | 
						|
                if (ca != null)
 | 
						|
                    ca.Measure(layoutInfo);
 | 
						|
            }
 | 
						|
 | 
						|
            axis.Measure(layoutInfo);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ValidateAxes
 | 
						|
 | 
						|
        private void ValidateAxes()
 | 
						|
        {
 | 
						|
            if (ValidateAxes(AncillaryAxesX, AxisX) |
 | 
						|
                ValidateAxes(AncillaryAxesY, AxisY))
 | 
						|
            {
 | 
						|
                InvalidateSeriesPoints();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region ValidateAxes
 | 
						|
 | 
						|
        private bool ValidateAxes(ChartAxesCollection axes, ChartAxis axis)
 | 
						|
        {
 | 
						|
            int visCount = 0;
 | 
						|
            bool altered = false;
 | 
						|
 | 
						|
            for (int i = axes.Count - 1; i >= 0; i--)
 | 
						|
            {
 | 
						|
                ChartAxis ca = axes[i];
 | 
						|
 | 
						|
                if (ca.Visible == true)
 | 
						|
                {
 | 
						|
                    visCount++;
 | 
						|
                    altered |= ca.ValidateAxis();
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            if (axis.Visible == true)
 | 
						|
            {
 | 
						|
                visCount++;
 | 
						|
                altered |= axis.ValidateAxis();
 | 
						|
            }
 | 
						|
 | 
						|
            return (altered || (visCount == 0));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SetEdgeAxes
 | 
						|
 | 
						|
        private void SetEdgeAxes(ChartAxesCollection axes, ChartAxis axis)
 | 
						|
        {
 | 
						|
            ChartAxis farEdgeAxis = null;
 | 
						|
            ChartAxis nearEdgeAxis = null;
 | 
						|
 | 
						|
            for (int i = axes.Count - 1; i >= 0; i--)
 | 
						|
            {
 | 
						|
                ChartAxis ca = axes[i];
 | 
						|
 | 
						|
                if (ca.Visible == true)
 | 
						|
                {
 | 
						|
                    AxisAlignment axisAlignment = ca.GetAxisAlignment();
 | 
						|
 | 
						|
                    ca.EdgeAxis = false;
 | 
						|
 | 
						|
                    if (axisAlignment == AxisAlignment.Near)
 | 
						|
                        nearEdgeAxis = ca;
 | 
						|
 | 
						|
                    else if (axisAlignment == AxisAlignment.Far)
 | 
						|
                        farEdgeAxis = ca;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            if (axis.Visible == true)
 | 
						|
            {
 | 
						|
                AxisAlignment axisAlignment = axis.GetAxisAlignment();
 | 
						|
 | 
						|
                if (axisAlignment == AxisAlignment.Near)
 | 
						|
                    nearEdgeAxis = axis;
 | 
						|
 | 
						|
                else if (axisAlignment == AxisAlignment.Far)
 | 
						|
                    farEdgeAxis = axis;
 | 
						|
            }
 | 
						|
 | 
						|
            if (nearEdgeAxis != null)
 | 
						|
                nearEdgeAxis.EdgeAxis = true;
 | 
						|
 | 
						|
            if (farEdgeAxis != null)
 | 
						|
                farEdgeAxis.EdgeAxis = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ArrangeOverride
 | 
						|
 | 
						|
        protected override void ArrangeOverride(ChartLayoutInfo layoutInfo)
 | 
						|
        {
 | 
						|
            int vmax = VScrollBar.LargeChange;
 | 
						|
 | 
						|
            UpdatePaletteColor();
 | 
						|
 | 
						|
            base.ArrangeOverride(layoutInfo);
 | 
						|
 | 
						|
            if (VScrollBar.LargeChange != vmax)
 | 
						|
                SeriesPointCount++;
 | 
						|
 | 
						|
            ArrangeAxes(layoutInfo, AncillaryAxesX, AxisX);
 | 
						|
            ArrangeAxes(layoutInfo, AncillaryAxesY, AxisY);
 | 
						|
 | 
						|
            ArrangeSeries(layoutInfo);
 | 
						|
 | 
						|
            SeriesLayoutCount++;
 | 
						|
        }
 | 
						|
 | 
						|
        #region UpdatePaletteColor
 | 
						|
 | 
						|
        private void UpdatePaletteColor()
 | 
						|
        {
 | 
						|
            ChartBaseSeriesCollection baseSeries = BaseSeries;
 | 
						|
 | 
						|
            for (int i = 0; i < baseSeries.Count; i++)
 | 
						|
            {
 | 
						|
                BaseSeries series = baseSeries[i];
 | 
						|
 | 
						|
                series.DefaultPaletteColor = GetPaletteColor(i);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ArrangeAxes
 | 
						|
 | 
						|
        private void ArrangeAxes(
 | 
						|
            ChartLayoutInfo layoutInfo, ChartAxesCollection axes, ChartAxis axis)
 | 
						|
        {
 | 
						|
            foreach (ChartAxis ca in axes)
 | 
						|
            {
 | 
						|
                if (ca.Visible == true)
 | 
						|
                    ca.Arrange(layoutInfo);
 | 
						|
            }
 | 
						|
 | 
						|
            axis.Arrange(layoutInfo);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ArrangeSeries
 | 
						|
 | 
						|
        private void ArrangeSeries(ChartLayoutInfo layoutInfo)
 | 
						|
        {
 | 
						|
            if (ChartSeries.Count > 0)
 | 
						|
            {
 | 
						|
                for (int i = 0; i < ChartSeries.Count; i++)
 | 
						|
                {
 | 
						|
                    ChartSeries series = ChartSeries[i];
 | 
						|
 | 
						|
                    series.Arrange(layoutInfo);
 | 
						|
 | 
						|
                    if (series.IsBarSeries == true)
 | 
						|
                    {
 | 
						|
                        ChartAxis axis = (series.IsRotated == false)
 | 
						|
                            ? (series.AxisX ?? AxisX) : (series.AxisY ?? AxisY);
 | 
						|
 | 
						|
                        for (int j = 0; j < axis.AxisBars.Length; j++)
 | 
						|
                            axis.AxisBars[j].Reset();
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                for (int i = ChartSeries.Count - 1; i >= 0; i--)
 | 
						|
                    SetBarTotals(i);
 | 
						|
 | 
						|
                for (int i = ChartSeries.Count - 1; i >= 0; i--)
 | 
						|
                    SetBarWidth(i);
 | 
						|
 | 
						|
                if (SeriesDisplayOrder == SeriesDisplayOrder.Reverse)
 | 
						|
                {
 | 
						|
                    for (int i = ChartSeries.Count - 1; i >= 0; i--)
 | 
						|
                        ArrangeBarSeries(i);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    for (int i = 0; i < ChartSeries.Count; i++)
 | 
						|
                        ArrangeBarSeries(i);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region SetBarTotals
 | 
						|
 | 
						|
        private void SetBarTotals(int i)
 | 
						|
        {
 | 
						|
            ChartSeries series = ChartSeries[i];
 | 
						|
 | 
						|
            if (series.IsDisplayed == true)
 | 
						|
            {
 | 
						|
                ChartAxis axis = (series.IsRotated == false)
 | 
						|
                    ? series.AxisX ?? AxisX : series.AxisY ?? AxisY;
 | 
						|
 | 
						|
                switch (series.SeriesType)
 | 
						|
                {
 | 
						|
                    case SeriesType.HorizontalBar:
 | 
						|
                    case SeriesType.VerticalBar:
 | 
						|
                        axis.AxisBars[(int)AxisBarType.Bar].BarCount++;
 | 
						|
                        axis.AxisBars[(int)AxisBarType.Bar].BarTotal += series.GetBarWidthRatio(this);
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case SeriesType.HorizontalHiLoBar:
 | 
						|
                    case SeriesType.VerticalHiLoBar:
 | 
						|
                        axis.AxisBars[(int)AxisBarType.HiLoBar].BarCount++;
 | 
						|
                        axis.AxisBars[(int)AxisBarType.HiLoBar].BarTotal += series.GetBarWidthRatio(this);
 | 
						|
                        break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SetBarWidth
 | 
						|
 | 
						|
        private void SetBarWidth(int i)
 | 
						|
        {
 | 
						|
            ChartSeries series = ChartSeries[i];
 | 
						|
 | 
						|
            if (series.IsDisplayed == true)
 | 
						|
            {
 | 
						|
                switch (series.SeriesType)
 | 
						|
                {
 | 
						|
                    case SeriesType.HorizontalBar:
 | 
						|
                    case SeriesType.VerticalBar:
 | 
						|
                        SetBarWidthEx(series, (int)AxisBarType.Bar);
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case SeriesType.HorizontalHiLoBar:
 | 
						|
                    case SeriesType.VerticalHiLoBar:
 | 
						|
                        SetBarWidthEx(series, (int)AxisBarType.HiLoBar);
 | 
						|
                        break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region SetBarWidthEx
 | 
						|
 | 
						|
        private void SetBarWidthEx(ChartSeries series, int barType)
 | 
						|
        {
 | 
						|
            ChartAxis axis = (series.IsRotated == false)
 | 
						|
                ? series.AxisX ?? AxisX : series.AxisY ?? AxisY;
 | 
						|
 | 
						|
            AxisBar axisBar = axis.AxisBars[barType];
 | 
						|
 | 
						|
            double interval = axis.MajorTickmarks.TickmarkLayout.MajorInterval;
 | 
						|
 | 
						|
            double dwidth = interval / axis.MajorTickmarks.TickmarkLayout.MajorSpacing;
 | 
						|
            double ratio = series.GetBarWidthRatio(this);
 | 
						|
 | 
						|
            if (BarOverlayEnabled == true || axisBar.BarCount == 1)
 | 
						|
            {
 | 
						|
                int width = (int)(dwidth * (ratio / (ratio + 1)));
 | 
						|
 | 
						|
                if (ratio > 100)
 | 
						|
                {
 | 
						|
                    ratio = (ratio - 1) / 100;
 | 
						|
                    width = (int)(dwidth * ratio);
 | 
						|
                }
 | 
						|
                
 | 
						|
                width = (width < 0) ? 0 : ((width - 1) | 1);
 | 
						|
 | 
						|
                series.BarWidth = (int)(width / axis.MajorTickmarks.TickmarkLayout.GridSpacing);
 | 
						|
 | 
						|
                axisBar.BarTotalWidth += series.BarWidth;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                int spacing = BarSpacing;
 | 
						|
 | 
						|
                if (BarSpacing == 0)
 | 
						|
                {
 | 
						|
                    double abt = (axisBar.BarTotal + 1) + (axisBar.BarCount - 1) * BarSpacingRatio;
 | 
						|
                    double sr = BarSpacingRatio / abt;
 | 
						|
 | 
						|
                    spacing = (int)(Math.Ceiling(dwidth * sr));
 | 
						|
                }
 | 
						|
 | 
						|
                dwidth -= ((axisBar.BarCount - 1) * spacing);
 | 
						|
 | 
						|
                int width = (int)(dwidth * (ratio / (axisBar.BarTotal + 1)));
 | 
						|
 | 
						|
                if (ratio > 100)
 | 
						|
                {
 | 
						|
                    ratio = (ratio - 1) / 100;
 | 
						|
                    width = (int)(dwidth * ratio);
 | 
						|
                }
 | 
						|
 | 
						|
                width = (int)(width / axis.MajorTickmarks.TickmarkLayout.GridSpacing);
 | 
						|
                width = (width < 0) ? 0 : ((width - 1) | 1);                
 | 
						|
 | 
						|
                series.BarWidth = width;
 | 
						|
 | 
						|
                axisBar.BarTotalWidth += (series.BarWidth + spacing);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ArrangeBarSeries
 | 
						|
 | 
						|
        private void ArrangeBarSeries(int i)
 | 
						|
        {
 | 
						|
            ChartSeries series = ChartSeries[i];
 | 
						|
 | 
						|
            if (series.IsDisplayed == true)
 | 
						|
            {
 | 
						|
                switch (series.SeriesType)
 | 
						|
                {
 | 
						|
                    case SeriesType.HorizontalBar:
 | 
						|
                    case SeriesType.VerticalBar:
 | 
						|
                        ArrangeBarSeriesEx(series, (int)AxisBarType.Bar);
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case SeriesType.HorizontalHiLoBar:
 | 
						|
                    case SeriesType.VerticalHiLoBar:
 | 
						|
                        ArrangeBarSeriesEx(series, (int)AxisBarType.HiLoBar);
 | 
						|
                        break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region ArrangeBarSeriesEx
 | 
						|
 | 
						|
        private void ArrangeBarSeriesEx(ChartSeries series, int barType)
 | 
						|
        {
 | 
						|
            ChartAxis axis = (series.IsRotated == false)
 | 
						|
                ? (series.AxisX ?? AxisX) : (series.AxisY ?? AxisY);
 | 
						|
 | 
						|
            AxisBar axisBar = axis.AxisBars[barType];
 | 
						|
 | 
						|
            if (BarOverlayEnabled == true || axisBar.BarCount == 1)
 | 
						|
            {
 | 
						|
                series.BarOffset = 0;
 | 
						|
 | 
						|
                axisBar.BarOffset = series.BarWidth;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                int spacing = BarSpacing;
 | 
						|
 | 
						|
                if (BarSpacing == 0)
 | 
						|
                {
 | 
						|
                    double dwidth = axis.MajorTickmarks.TickmarkLayout.MajorInterval;
 | 
						|
                    double abt = (axisBar.BarTotal + 1) + (axisBar.BarCount - 1) * BarSpacingRatio;
 | 
						|
 | 
						|
                    spacing = (int)(Math.Ceiling(dwidth * BarSpacingRatio / abt));
 | 
						|
                }
 | 
						|
 | 
						|
                if (axisBar.BarOffset == int.MinValue)
 | 
						|
                    axisBar.BarOffset = (int)((-axisBar.BarTotalWidth + spacing) / 2);
 | 
						|
 | 
						|
                series.BarOffset = axisBar.BarOffset + series.BarWidth / 2;
 | 
						|
 | 
						|
                axisBar.BarOffset += (series.BarWidth + spacing);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderOverride
 | 
						|
 | 
						|
        private bool _LastDisplayCrosshair;
 | 
						|
 | 
						|
        protected override void RenderOverride(ChartRenderInfo renderInfo)
 | 
						|
        {
 | 
						|
            Graphics g = renderInfo.Graphics;
 | 
						|
 | 
						|
            ChartXyVisualStyle xystyle = EffectiveChartStyle;
 | 
						|
            ContainerVisualStyle cstyle = GetEffectiveContainerStyle();
 | 
						|
 | 
						|
            Rectangle scFrameBounds = GetScrollBounds(FrameBounds);
 | 
						|
            Rectangle scContentBounds = GetScrollBounds(ContentBounds);
 | 
						|
 | 
						|
            Rectangle scFigureBounds = GetFigureBounds(scFrameBounds, cstyle);
 | 
						|
 | 
						|
            RenderFrameBackground(g, scFrameBounds, cstyle);
 | 
						|
 | 
						|
            cstyle.RenderBackgroundFigure(g, scFigureBounds);
 | 
						|
            cstyle.RenderBorder(g, scFrameBounds);
 | 
						|
 | 
						|
            Region clip = g.Clip;
 | 
						|
            g.SetClip(scContentBounds, CombineMode.Intersect);
 | 
						|
 | 
						|
            RenderContentBackground(renderInfo, scContentBounds, xystyle);
 | 
						|
 | 
						|
            Rectangle imageBounds = GetXyImageBounds(xystyle);
 | 
						|
 | 
						|
            if (xystyle.ImageOverlay != ImageOverlay.Top && xystyle.ImageOverlay != ImageOverlay.Middle)
 | 
						|
                xystyle.RenderBackgroundFigure(g, scContentBounds, imageBounds);
 | 
						|
 | 
						|
            Point cpt = Point.Empty;
 | 
						|
            Rectangle cbounds = Rectangle.Empty;
 | 
						|
 | 
						|
            _NearestCrosshairPoint = null;
 | 
						|
 | 
						|
            if (DisplayCrosshair == true)
 | 
						|
            {
 | 
						|
                cpt = ChartControl.PointToClient(Control.MousePosition);
 | 
						|
                cbounds = GetCrosshairBounds(cstyle);
 | 
						|
 | 
						|
                _CrosshairSeriesPoints = GetCrosshairPoints(cbounds, cpt);
 | 
						|
            }
 | 
						|
 | 
						|
            UpdatePointLabels(g);
 | 
						|
 | 
						|
            RenderGrid(renderInfo, false);
 | 
						|
            RenderReferences(renderInfo, false);
 | 
						|
 | 
						|
            if (xystyle.ImageOverlay == ImageOverlay.Middle)
 | 
						|
                xystyle.RenderBackgroundFigure(g, scContentBounds, imageBounds);
 | 
						|
 | 
						|
            RenderChartContent(renderInfo, xystyle);
 | 
						|
 | 
						|
            RenderGrid(renderInfo, true);
 | 
						|
            RenderReferences(renderInfo, true);
 | 
						|
 | 
						|
            RenderPointLabels(g);
 | 
						|
 | 
						|
            g.Clip = clip;
 | 
						|
 | 
						|
            xystyle.RenderBorder(g, scContentBounds);
 | 
						|
 | 
						|
            if (xystyle.ImageOverlay == ImageOverlay.Top)
 | 
						|
                xystyle.RenderBackgroundFigure(g, scContentBounds, imageBounds);
 | 
						|
 | 
						|
            RenderAxes(renderInfo, AncillaryAxesX, AxisX);
 | 
						|
            RenderAxes(renderInfo, AncillaryAxesY, AxisY);
 | 
						|
 | 
						|
            RenderScrollbars(renderInfo);
 | 
						|
 | 
						|
            if (DropShadowDisplayed == true)
 | 
						|
                xystyle.DropShadow.RenderDropShadow(g, scContentBounds, true, true);
 | 
						|
 | 
						|
            if (cstyle.DropShadow.Enabled == Tbool.True)
 | 
						|
                cstyle.DropShadow.RenderDropShadow(g, scFrameBounds, true, true);
 | 
						|
 | 
						|
            if (DisplayCrosshair == true)
 | 
						|
            {
 | 
						|
                CrosshairVisualStyle chstyle = ChartCrosshair.EffectiveCrosshairStyle;
 | 
						|
 | 
						|
                RenderCrosshairLines(g, cbounds, cpt, chstyle);
 | 
						|
                base.RenderOverride(renderInfo);
 | 
						|
 | 
						|
                if (_CanShowCrosshairLabel == true)
 | 
						|
                    RenderCrosshairLabels(g, cbounds, cpt, chstyle);
 | 
						|
 | 
						|
                _LastDisplayCrosshair = DisplayCrosshair;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                if (_CanShowCrosshairLabel == true)
 | 
						|
                {
 | 
						|
                    if (DisplayCrosshair != _LastDisplayCrosshair)
 | 
						|
                        RenderCrosshairLabels(g, cbounds, cpt, ChartCrosshair.EffectiveCrosshairStyle);
 | 
						|
                }
 | 
						|
 | 
						|
                base.RenderOverride(renderInfo);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region RenderContentBackground
 | 
						|
 | 
						|
        private void RenderContentBackground(
 | 
						|
            ChartRenderInfo renderInfo, Rectangle bounds, ChartXyVisualStyle xyStyle)
 | 
						|
        {
 | 
						|
            Graphics g = renderInfo.Graphics;
 | 
						|
            ChartControl chartControl = ChartControl;
 | 
						|
 | 
						|
            if (chartControl.DoPreRenderContentBackgroundEvent(g, this, bounds) == false)
 | 
						|
            {
 | 
						|
                xyStyle.RenderBackground(g, bounds);
 | 
						|
 | 
						|
                RenderAxesBackground(renderInfo, bounds, AncillaryAxesX, AxisX);
 | 
						|
                RenderAxesBackground(renderInfo, bounds, AncillaryAxesY, AxisY);
 | 
						|
 | 
						|
                chartControl.DoPostRenderContentBackgroundEvent(g, this, bounds);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region RenderAxesBackground
 | 
						|
 | 
						|
        private void RenderAxesBackground(ChartRenderInfo renderInfo,
 | 
						|
            Rectangle scContentBounds, ChartAxesCollection axes, ChartAxis axis)
 | 
						|
        {
 | 
						|
            foreach (ChartAxis ca in axes)
 | 
						|
            {
 | 
						|
                if (ca.Visible == true)
 | 
						|
                    ca.RenderBackground(renderInfo, scContentBounds);
 | 
						|
            }
 | 
						|
 | 
						|
            axis.RenderBackground(renderInfo, scContentBounds);
 | 
						|
 | 
						|
            foreach (ChartAxis ca in axes)
 | 
						|
            {
 | 
						|
                if (ca.Visible == true)
 | 
						|
                    ca.RenderStripes(renderInfo, scContentBounds);
 | 
						|
            }
 | 
						|
 | 
						|
            axis.RenderStripes(renderInfo, scContentBounds);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderChartContent
 | 
						|
 | 
						|
        protected virtual void RenderChartContent(
 | 
						|
            ChartRenderInfo renderInfo, ChartXyVisualStyle xyStyle)
 | 
						|
        {
 | 
						|
            Graphics g = renderInfo.Graphics;
 | 
						|
 | 
						|
            if (ChartSeries.Count > 0)
 | 
						|
            {
 | 
						|
                SmoothingMode sm = g.SmoothingMode;
 | 
						|
                g.SmoothingMode = SmoothingMode.AntiAlias;
 | 
						|
 | 
						|
                Point pt = GetLocalAdjustedPoint(Point.Empty);
 | 
						|
 | 
						|
                if (pt.IsEmpty == false)
 | 
						|
                    g.TranslateTransform(pt.X, pt.Y);
 | 
						|
 | 
						|
                // Indicators on bottom
 | 
						|
 | 
						|
                if (SeriesDisplayOrder == SeriesDisplayOrder.Reverse)
 | 
						|
                {
 | 
						|
                    for (int i = ChartSeries.Count - 1; i >= 0; i--)
 | 
						|
                        RenderIndicators(renderInfo, ChartSeries[i], false);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    foreach (ChartSeries series in ChartSeries)
 | 
						|
                        RenderIndicators(renderInfo, series, false);
 | 
						|
                }
 | 
						|
 | 
						|
                // Series data
 | 
						|
 | 
						|
                if (SeriesDisplayOrder == SeriesDisplayOrder.Reverse)
 | 
						|
                {
 | 
						|
                    for (int i = ChartSeries.Count - 1; i >= 0; i--)
 | 
						|
                        RenderSeries(renderInfo, ChartSeries[i]);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    foreach (ChartSeries series in ChartSeries)
 | 
						|
                        RenderSeries(renderInfo, series);
 | 
						|
                }
 | 
						|
 | 
						|
                // Indicators on top
 | 
						|
 | 
						|
                if (SeriesDisplayOrder == SeriesDisplayOrder.Reverse)
 | 
						|
                {
 | 
						|
                    for (int i = ChartSeries.Count - 1; i >= 0; i--)
 | 
						|
                        RenderIndicators(renderInfo, ChartSeries[i], true);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    foreach (ChartSeries series in ChartSeries)
 | 
						|
                        RenderIndicators(renderInfo, series, true);
 | 
						|
                }
 | 
						|
 | 
						|
                if (pt.IsEmpty == false)
 | 
						|
                    g.ResetTransform();
 | 
						|
 | 
						|
                g.SmoothingMode = sm;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                Rectangle scContentBounds = GetScrollBounds(ContentBounds);
 | 
						|
                Rectangle scDisplayBounds = GetDisplayBounds(scContentBounds);
 | 
						|
 | 
						|
                RenderEmptyText(g, xyStyle, scDisplayBounds);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region RenderIndicators
 | 
						|
 | 
						|
        private void RenderIndicators(
 | 
						|
            ChartRenderInfo renderInfo, ChartSeries series, bool onTop)
 | 
						|
        {
 | 
						|
            if (Visible == true)
 | 
						|
            {
 | 
						|
                if (Legend.ItemCheckAction != ItemCheckAction.ShowItem || series.IsDisplayed == true)
 | 
						|
                    series.RenderIndicators(renderInfo, onTop);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderSeries
 | 
						|
 | 
						|
        private void RenderSeries(ChartRenderInfo renderInfo, ChartSeries series)
 | 
						|
        {
 | 
						|
            if (Visible == true)
 | 
						|
            {
 | 
						|
                if (Legend.ItemCheckAction != ItemCheckAction.ShowItem || series.IsDisplayed == true)
 | 
						|
                    series.Render(renderInfo);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetFigureBounds
 | 
						|
 | 
						|
        private Rectangle GetFigureBounds(Rectangle bounds, ContainerVisualStyle cStyle)
 | 
						|
        {
 | 
						|
            bounds = GetAdjustedBounds(bounds, cStyle.BorderThickness);
 | 
						|
 | 
						|
            Rectangle scBounds = GetScrollBounds(bounds);
 | 
						|
 | 
						|
            return (scBounds);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetXyImageBounds
 | 
						|
 | 
						|
        private Rectangle GetXyImageBounds(ChartXyVisualStyle xyStyle)
 | 
						|
        {
 | 
						|
            Rectangle scBbounds = GetScrollBounds(ScrollBounds);
 | 
						|
 | 
						|
            scBbounds = GetAdjustedBounds(scBbounds, xyStyle.BorderThickness);
 | 
						|
 | 
						|
            if (xyStyle.EnableImageScroll != Tbool.False)
 | 
						|
            {
 | 
						|
                scBbounds = GetScrollBounds(ScrollBoundsEx);
 | 
						|
                scBbounds = GetDisplayBounds(scBbounds);
 | 
						|
            }
 | 
						|
 | 
						|
            if (HScrollBar.Visible == true)
 | 
						|
                scBbounds.Height -= HScrollBar.Height;
 | 
						|
 | 
						|
            if (VScrollBar.Visible == true)
 | 
						|
                scBbounds.Width -= VScrollBar.Width;
 | 
						|
 | 
						|
            return (scBbounds);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderGrid
 | 
						|
 | 
						|
        private void RenderGrid(ChartRenderInfo renderInfo, bool displayOnTop)
 | 
						|
        {
 | 
						|
            Rectangle scContentBounds = GetScrollBounds(ContentBounds);
 | 
						|
 | 
						|
            if (scContentBounds.Width > 0 && scContentBounds.Height > 0)
 | 
						|
            {
 | 
						|
                RenderGridLines(renderInfo, displayOnTop, AncillaryAxesX, AxisX);
 | 
						|
                RenderGridLines(renderInfo, displayOnTop, AncillaryAxesY, AxisY);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region RenderGridLines
 | 
						|
 | 
						|
        private void RenderGridLines(ChartRenderInfo renderInfo,
 | 
						|
            bool displayOnTop, ChartAxesCollection axes, ChartAxis axis)
 | 
						|
        {
 | 
						|
            foreach (ChartAxis ca in axes)
 | 
						|
            {
 | 
						|
                if (ca.Visible == true)
 | 
						|
                {
 | 
						|
                    if (ca.MajorGridLines.DisplayOnTop == displayOnTop)
 | 
						|
                        ca.MajorGridLines.Render(renderInfo);
 | 
						|
 | 
						|
                    if (ca.MinorGridLines.DisplayOnTop == displayOnTop)
 | 
						|
                        ca.MinorGridLines.Render(renderInfo);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            if (axis.MajorGridLines.DisplayOnTop == displayOnTop)
 | 
						|
                axis.MajorGridLines.Render(renderInfo);
 | 
						|
 | 
						|
            if (axis.MinorGridLines.DisplayOnTop == displayOnTop)
 | 
						|
                axis.MinorGridLines.Render(renderInfo);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderReferences
 | 
						|
 | 
						|
        private void RenderReferences(ChartRenderInfo renderInfo, bool displayOnTop)
 | 
						|
        {
 | 
						|
            Rectangle scContentBounds = GetScrollBounds(ContentBounds);
 | 
						|
 | 
						|
            if (scContentBounds.Width > 0 && scContentBounds.Height > 0)
 | 
						|
            {
 | 
						|
                RenderReferenceLines(renderInfo, displayOnTop, AncillaryAxesX, AxisX);
 | 
						|
                RenderReferenceLines(renderInfo, displayOnTop, AncillaryAxesY, AxisY);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region RenderReferenceLines
 | 
						|
 | 
						|
        private void RenderReferenceLines(ChartRenderInfo renderInfo,
 | 
						|
            bool displayOnTop, ChartAxesCollection axes, ChartAxis axis)
 | 
						|
        {
 | 
						|
            foreach (ChartAxis ca in axes)
 | 
						|
            {
 | 
						|
                foreach (ReferenceLine line in ca.ReferenceLines)
 | 
						|
                    RenderReferenceLine(renderInfo, line, displayOnTop);
 | 
						|
            }
 | 
						|
 | 
						|
            if (axis.Visible == true)
 | 
						|
            {
 | 
						|
                foreach (ReferenceLine line in axis.ReferenceLines)
 | 
						|
                    RenderReferenceLine(renderInfo, line, displayOnTop);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region RenderReferenceLine
 | 
						|
 | 
						|
        private void RenderReferenceLine(
 | 
						|
            ChartRenderInfo renderInfo, ReferenceLine line, bool displayOnTop)
 | 
						|
        {
 | 
						|
            if (line.Visible == true)
 | 
						|
            {
 | 
						|
                if (line.ShowCheckBoxInLegend == false || line.CheckedInLegend == true)
 | 
						|
                {
 | 
						|
                    if (line.DisplayLineOnTop == displayOnTop)
 | 
						|
                        line.RenderLine(renderInfo);
 | 
						|
 | 
						|
                    if (line.DisplayTextOnTop == displayOnTop)
 | 
						|
                        line.RenderLineText(renderInfo);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderPointLabels
 | 
						|
 | 
						|
        private void RenderPointLabels(Graphics g)
 | 
						|
        {
 | 
						|
            Point pt = GetLocalAdjustedPoint(Point.Empty);
 | 
						|
 | 
						|
            List<PointLabelGroup> pointLabels = UpdatePointLabels(g);
 | 
						|
 | 
						|
            if (pointLabels.Count > 0)
 | 
						|
            {
 | 
						|
                SmoothingMode sm = g.SmoothingMode;
 | 
						|
                g.SmoothingMode = SmoothingMode.AntiAlias;
 | 
						|
 | 
						|
                RenderPointConnector(g, pt, pointLabels);
 | 
						|
                RenderPointLabel(g, pt, pointLabels);
 | 
						|
 | 
						|
                g.SmoothingMode = sm;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region UpdatePointLabels
 | 
						|
 | 
						|
        private List<PointLabelGroup> UpdatePointLabels(Graphics g)
 | 
						|
        {
 | 
						|
            if (_PointLabels == null)
 | 
						|
            {
 | 
						|
                List<PointLabelGroup> labelGroups = new List<PointLabelGroup>();
 | 
						|
 | 
						|
                foreach (ChartSeries series in ChartSeries)
 | 
						|
                {
 | 
						|
                    if (series.IsDisplayed == true)
 | 
						|
                    {
 | 
						|
                        List<PointLabel> list = series.GetPointLabels(g);
 | 
						|
 | 
						|
                        if (list != null)
 | 
						|
                        {
 | 
						|
                            PointLabelGroup plg = new PointLabelGroup(series, list);
 | 
						|
 | 
						|
                            labelGroups.Add(plg);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                UpdatePointLabelsEx(g, labelGroups);
 | 
						|
 | 
						|
                FlockAlign falign = new FlockAlign(labelGroups);
 | 
						|
 | 
						|
                ContainerVisualStyle cstyle = GetEffectiveContainerStyle();
 | 
						|
 | 
						|
                Rectangle r = GetAdjustedBounds(ContentBoundsEx, cstyle.BorderThickness);
 | 
						|
 | 
						|
                falign.Iterate(r, DataLabelOverlapMode);
 | 
						|
 | 
						|
                _PointLabels = labelGroups;
 | 
						|
            }
 | 
						|
 | 
						|
            return (_PointLabels);
 | 
						|
        }
 | 
						|
 | 
						|
        #region UpdatePointLabelsEx
 | 
						|
 | 
						|
        private void UpdatePointLabelsEx(Graphics g, List<PointLabelGroup> labelGroups)
 | 
						|
        {
 | 
						|
            ChartControl control = ChartControl;
 | 
						|
 | 
						|
            if (control.IsPointLabelUpdateHooked == true)
 | 
						|
            {
 | 
						|
                for (int i = 0; i < labelGroups.Count; i++)
 | 
						|
                {
 | 
						|
                    PointLabelGroup lg = labelGroups[i];
 | 
						|
                    List<PointLabel> lps = lg.PointLabels;
 | 
						|
 | 
						|
                    control.DoPointLabelUpdateEvent(this, lg.ChartSeries, lps);
 | 
						|
 | 
						|
                    for (int j = 0; j < lps.Count; j++)
 | 
						|
                    {
 | 
						|
                        PointLabel pl = lps[j];
 | 
						|
 | 
						|
                        if (pl.IsFixedSize == false && pl.NeedsMeasured == true)
 | 
						|
                            pl.LabelSize = lg.ChartSeries.MeasurePointLabel(g, pl);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderPointConnector
 | 
						|
 | 
						|
        private void RenderPointConnector(
 | 
						|
            Graphics g, Point pt, List<PointLabelGroup> labelGroups)
 | 
						|
        {
 | 
						|
            ChartControl chartControl = ChartControl;
 | 
						|
 | 
						|
            foreach (PointLabelGroup lg in labelGroups)
 | 
						|
            {
 | 
						|
                ChartSeries series = lg.ChartSeries;
 | 
						|
 | 
						|
                foreach (PointLabel pl in lg.PointLabels)
 | 
						|
                {
 | 
						|
                    if (pl.Visible == true &&
 | 
						|
                        pl.SeriesPoint.IsEmpty == false && pl.EdgePoint.IsEmpty == false)
 | 
						|
                    {
 | 
						|
                        DataLabelVisualStyle dstyle = series.GetPointLabelVisualStyle(pl);
 | 
						|
                        ConnectorLineVisualStyle cstyle = dstyle.ConnectorLineStyle;
 | 
						|
 | 
						|
                        if (dstyle.DrawConnector == Tbool.True && cstyle.LinePattern != LinePattern.None)
 | 
						|
                        {
 | 
						|
                            if (pl.Bounds.IsEmpty == false)
 | 
						|
                            {
 | 
						|
                                Rectangle r = pl.Bounds;
 | 
						|
                                r.Offset(pt);
 | 
						|
 | 
						|
                                Point pt1 = pl.Point;
 | 
						|
                                pt1.Offset(pt);
 | 
						|
 | 
						|
                                Point pt2 = pl.EdgePoint;
 | 
						|
                                pt2.Offset(pt);
 | 
						|
 | 
						|
                                bool isChpt = IsCrosshairSeriesPoint(null, pt1);
 | 
						|
 | 
						|
                                if (cstyle.Origin == ConnectorOrigin.Edge)
 | 
						|
                                {
 | 
						|
                                    int offset = Math.Max(
 | 
						|
                                        pl.SeriesPoint.PointSize.Width,
 | 
						|
                                        pl.SeriesPoint.PointSize.Height) / 2 + 1;
 | 
						|
 | 
						|
                                    double radians = MathHelper.ToRadians(pl.Angle);
 | 
						|
 | 
						|
                                    int x = (int)(Math.Cos(radians) * offset);
 | 
						|
                                    int y = (int)(Math.Sin(radians) * offset);
 | 
						|
 | 
						|
                                    pt1.X += (int)(Math.Cos(radians) * offset);
 | 
						|
                                    pt1.Y += (int)(Math.Sin(radians) * offset);
 | 
						|
                                }
 | 
						|
 | 
						|
                                if (r.Contains(pt1) == false)
 | 
						|
                                {
 | 
						|
                                    if (chartControl.DoPreRenderPointConnectorEvent(g, this, series, pl, isChpt, pt1, pt2) == false)
 | 
						|
                                    {
 | 
						|
                                        using (Pen pen = new Pen(cstyle.LineColor, Dpi.Width(cstyle.LineWidth)))
 | 
						|
                                        {
 | 
						|
                                            if (cstyle.LinePattern != LinePattern.NotSet)
 | 
						|
                                                pen.DashStyle = (DashStyle)cstyle.LinePattern;
 | 
						|
 | 
						|
                                            g.DrawLine(pen, pt1, pt2);
 | 
						|
                                        }
 | 
						|
 | 
						|
                                        chartControl.DoPostRenderPointConnectorEvent(g, this, series, pl, isChpt, pt1, pt2);
 | 
						|
                                    }
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderPointLabel
 | 
						|
 | 
						|
        private void RenderPointLabel(
 | 
						|
            Graphics g, Point pt, List<PointLabelGroup> labelGroups)
 | 
						|
        {
 | 
						|
            ChartControl chartControl = ChartControl;
 | 
						|
 | 
						|
            foreach (PointLabelGroup lg in labelGroups)
 | 
						|
            {
 | 
						|
                ChartSeries series = lg.ChartSeries;
 | 
						|
 | 
						|
                foreach (PointLabel pl in lg.PointLabels)
 | 
						|
                {
 | 
						|
                    if (pl.Visible == true && pl.SeriesPoint.IsEmpty == false)
 | 
						|
                    {
 | 
						|
                        Rectangle r = pl.Bounds;
 | 
						|
 | 
						|
                        if (r.IsEmpty == false)
 | 
						|
                        {
 | 
						|
                            DataLabelVisualStyle dstyle = series.GetPointLabelVisualStyle(pl);
 | 
						|
 | 
						|
                            Point pt1 = r.Location;
 | 
						|
                            pt1.Offset(pt);
 | 
						|
                            r.Location = pt1;
 | 
						|
 | 
						|
                            Point pt2 = pl.Point;
 | 
						|
                            pt2.Offset(pt);
 | 
						|
 | 
						|
                            bool isChpt = IsCrosshairSeriesPoint(null, pt2);
 | 
						|
 | 
						|
                            if (chartControl.DoPreRenderPointLabelEvent(g, this, series, pl, isChpt, r) == false)
 | 
						|
                            {
 | 
						|
                                using (StringFormat sf = new StringFormat())
 | 
						|
                                {
 | 
						|
                                    dstyle.GetStringFormatFlags(sf);
 | 
						|
 | 
						|
                                    Color textColor = dstyle.TextColor;
 | 
						|
                                    Color borderColor = dstyle.BorderColor;
 | 
						|
                                    Background background = dstyle.Background;
 | 
						|
                                    LinePattern borderPattern = dstyle.BorderPattern;
 | 
						|
 | 
						|
                                    if (isChpt == true)
 | 
						|
                                    {
 | 
						|
                                        if (dstyle.HighlightTextColor.IsEmpty == false)
 | 
						|
                                            textColor = dstyle.HighlightTextColor;
 | 
						|
 | 
						|
                                        if (dstyle.HighlightBorderColor.IsEmpty == false)
 | 
						|
                                            borderColor = dstyle.HighlightBorderColor;
 | 
						|
 | 
						|
                                        if (dstyle.HighlightBackground.IsEmpty == false)
 | 
						|
                                            background = dstyle.HighlightBackground;
 | 
						|
 | 
						|
                                        if (dstyle.HighlightBorderPattern != LinePattern.NotSet)
 | 
						|
                                            borderPattern = dstyle.HighlightBorderPattern;
 | 
						|
                                    }
 | 
						|
 | 
						|
                                    RenderPointLabelEx(g, lg, pl, r, textColor,
 | 
						|
                                        background, borderColor, dstyle.BorderThickness, borderPattern, dstyle, sf);
 | 
						|
                                }
 | 
						|
 | 
						|
                                chartControl.DoPostRenderPointLabelEvent(g, this, series, pl, isChpt, r);
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region RenderPointLabelEx
 | 
						|
 | 
						|
        private void RenderPointLabelEx(Graphics g, PointLabelGroup lg, PointLabel pl,
 | 
						|
            Rectangle r, Color tcolor, Background background, Color bcolor,
 | 
						|
            int thickness, LinePattern pattern, DataLabelVisualStyle dstyle, StringFormat sf)
 | 
						|
        {
 | 
						|
            if (background.IsEmpty == false)
 | 
						|
            {
 | 
						|
                using (Brush hbr = background.GetBrush(r))
 | 
						|
                    g.FillRectangle(hbr, r);
 | 
						|
            }
 | 
						|
 | 
						|
            g.SmoothingMode = SmoothingMode.None;
 | 
						|
 | 
						|
            using (Pen hBorderPen = GetBorderPen(bcolor, thickness, pattern))
 | 
						|
            {
 | 
						|
                if (hBorderPen != null)
 | 
						|
                    g.DrawRectangle(hBorderPen, r);
 | 
						|
            }
 | 
						|
 | 
						|
            if (dstyle.DropShadow.Enabled == Tbool.True)
 | 
						|
                dstyle.DropShadow.RenderDropShadow(g, r, true, true);
 | 
						|
 | 
						|
            RotateDegrees rotateDegrees = lg.ChartSeries.GetRotateDegrees(dstyle);
 | 
						|
            float angle = GetRotateAngle(rotateDegrees);
 | 
						|
 | 
						|
            r.Size = pl.LabelSize;
 | 
						|
 | 
						|
            Point ptc = new Point(
 | 
						|
                r.X + pl.Bounds.Width / 2,
 | 
						|
                r.Y + pl.Bounds.Height / 2);
 | 
						|
 | 
						|
            if (angle != 0)
 | 
						|
            {
 | 
						|
                g.TranslateTransform(ptc.X, ptc.Y);
 | 
						|
                g.RotateTransform(angle);
 | 
						|
 | 
						|
                r.X = -((r.Width + dstyle.Padding.Horizontal) / 2);
 | 
						|
                r.Y = -((r.Height + dstyle.Padding.Vertical) / 2);
 | 
						|
 | 
						|
                if (angle == 90)
 | 
						|
                    r.Y--;
 | 
						|
 | 
						|
                else if (angle == 270)
 | 
						|
                    r.X--;
 | 
						|
 | 
						|
                r.X += dstyle.Padding.Left;
 | 
						|
                r.Y += dstyle.Padding.Top;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                if (dstyle.HasBorder == true)
 | 
						|
                {
 | 
						|
                    r.X += dstyle.BorderThickness;
 | 
						|
                    r.Y += dstyle.BorderThickness;
 | 
						|
                }
 | 
						|
 | 
						|
                r.X += dstyle.Padding.Left;
 | 
						|
                r.Y += dstyle.Padding.Top;
 | 
						|
            }
 | 
						|
 | 
						|
            using (Brush htbr = new SolidBrush(tcolor))
 | 
						|
                g.DrawString(pl.Label, dstyle.Font, htbr, r, sf);
 | 
						|
 | 
						|
            if (angle != 0)
 | 
						|
                g.ResetTransform();
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetRotateAngle
 | 
						|
 | 
						|
        private float GetRotateAngle(RotateDegrees rotateDegrees)
 | 
						|
        {
 | 
						|
            switch (rotateDegrees)
 | 
						|
            {
 | 
						|
                case RotateDegrees.Rotate90:
 | 
						|
                    return (90);
 | 
						|
 | 
						|
                case RotateDegrees.Rotate180:
 | 
						|
                    return (180);
 | 
						|
 | 
						|
                case RotateDegrees.Rotate270:
 | 
						|
                    return (270);
 | 
						|
 | 
						|
                default:
 | 
						|
                    return (0);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetBorderPen
 | 
						|
 | 
						|
        private Pen GetBorderPen(Color color, int thickness, LinePattern pattern)
 | 
						|
        {
 | 
						|
            Pen pen = null;
 | 
						|
 | 
						|
            if (pattern != LinePattern.None && pattern != LinePattern.NotSet && 
 | 
						|
                color.IsEmpty == false && thickness > 0)
 | 
						|
            {
 | 
						|
                pen = new Pen(color, Dpi.Width(thickness));
 | 
						|
 | 
						|
                pen.Alignment = PenAlignment.Inset;
 | 
						|
 | 
						|
                if (pattern != LinePattern.NotSet)
 | 
						|
                    pen.DashStyle = (DashStyle)pattern;
 | 
						|
            }
 | 
						|
 | 
						|
            return (pen);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderAxes
 | 
						|
 | 
						|
        private void RenderAxes(ChartRenderInfo renderInfo,
 | 
						|
            ChartAxesCollection axes, ChartAxis axis)
 | 
						|
        {
 | 
						|
            foreach (ChartAxis ca in axes)
 | 
						|
            {
 | 
						|
                if (ca.Visible == true)
 | 
						|
                    ca.Render(renderInfo);
 | 
						|
            }
 | 
						|
 | 
						|
            if (axis.Visible == true)
 | 
						|
                axis.Render(renderInfo);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderCrosshair
 | 
						|
 | 
						|
        #region GetCrosshairBounds
 | 
						|
 | 
						|
        private Rectangle GetCrosshairBounds(ContainerVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            ChartCrosshair crosshair = ChartCrosshair;
 | 
						|
 | 
						|
            Rectangle bounds = GetScrollBounds(ContentBounds);
 | 
						|
 | 
						|
            if (cstyle.BorderThickness.IsEmpty == false)
 | 
						|
            {
 | 
						|
                bounds.X += Dpi.Width(cstyle.BorderThickness.Left);
 | 
						|
                bounds.Width -= Dpi.Width(cstyle.BorderThickness.Horizontal);
 | 
						|
 | 
						|
                bounds.Y += Dpi.Height(cstyle.BorderThickness.Top);
 | 
						|
                bounds.Height -= Dpi.Height(cstyle.BorderThickness.Vertical);
 | 
						|
            }
 | 
						|
 | 
						|
            if (HScrollBar.Visible == true)
 | 
						|
                bounds.Height -= (HScrollBar.Height + 1);
 | 
						|
 | 
						|
            if (VScrollBar.Visible == true)
 | 
						|
                bounds.Width -= (VScrollBar.Width + 1);
 | 
						|
 | 
						|
            return (bounds);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetCrosshairPoints
 | 
						|
 | 
						|
        private List<CrosshairPoint> GetCrosshairPoints(Rectangle bounds, Point pt)
 | 
						|
        {
 | 
						|
            List<CrosshairPoint> cps;
 | 
						|
 | 
						|
            if (ChartCrosshair.AxisOrientation == AxisOrientation.X)
 | 
						|
                cps = GetCrosshairPointsX(pt, bounds);
 | 
						|
            else
 | 
						|
                cps = GetCrosshairPointsY(pt, bounds);
 | 
						|
 | 
						|
            _NearestCrosshairPoint = null;
 | 
						|
 | 
						|
            if (cps != null && cps.Count > 0)
 | 
						|
            {
 | 
						|
                if (ChartCrosshair.CrosshairLabelMode == CrosshairLabelMode.NearestSeries)
 | 
						|
                    _NearestCrosshairPoint = GetNearestPoint(cps, pt, ChartCrosshair.AxisOrientation);
 | 
						|
            }
 | 
						|
 | 
						|
            return (cps);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderCrosshair
 | 
						|
 | 
						|
        internal void RenderCrosshairLines(Graphics g,
 | 
						|
            Rectangle bounds, Point pt, CrosshairVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            if (ChartCrosshair.AxisOrientation == AxisOrientation.X)
 | 
						|
                RenderCrosshairX(g, bounds, pt, cstyle);
 | 
						|
            else
 | 
						|
                RenderCrosshairY(g, bounds, pt, cstyle);
 | 
						|
        }
 | 
						|
 | 
						|
        #region RenderCrosshairX
 | 
						|
 | 
						|
        private void RenderCrosshairX(Graphics g,
 | 
						|
            Rectangle bounds, Point pt, CrosshairVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            ChartCrosshair crosshair = ChartCrosshair;
 | 
						|
 | 
						|
            List<CrosshairPoint> cps = _CrosshairSeriesPoints;
 | 
						|
 | 
						|
            if (crosshair.ShowValueXLine == true)
 | 
						|
                RenderCrosshairLineX(g, pt, bounds, cstyle);
 | 
						|
 | 
						|
            if (crosshair.ShowValueXLabels == true)
 | 
						|
                RenderCrosshairLabelX(g, pt);
 | 
						|
 | 
						|
            if (crosshair.ShowValueYLine == true || crosshair.ShowValueYLabels == true)
 | 
						|
            {
 | 
						|
                if (crosshair.CrosshairLabelMode == CrosshairLabelMode.NearestSeries)
 | 
						|
                {
 | 
						|
                    CrosshairPoint mcp = _NearestCrosshairPoint;
 | 
						|
 | 
						|
                    if (mcp != null)
 | 
						|
                    {
 | 
						|
                        if (crosshair.ShowValueYLine == true)
 | 
						|
                            RenderCrosshairLineY(g, mcp.Point, bounds, cstyle);
 | 
						|
 | 
						|
                        if (crosshair.ShowValueYLabels == true)
 | 
						|
                            RenderCrosshairLabelY(g, mcp);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    foreach (CrosshairPoint cp in cps)
 | 
						|
                    {
 | 
						|
                        if (crosshair.ShowValueYLine == true)
 | 
						|
                            RenderCrosshairLineY(g, cp.Point, bounds, cstyle);
 | 
						|
 | 
						|
                        if (crosshair.ShowValueYLabels == true)
 | 
						|
                            RenderCrosshairLabelY(g, cp);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetCrosshairPointsX
 | 
						|
 | 
						|
        private List<CrosshairPoint> GetCrosshairPointsX(Point pt, Rectangle bounds)
 | 
						|
        {
 | 
						|
            List<CrosshairPoint> cps = new List<CrosshairPoint>();
 | 
						|
 | 
						|
            for (int i = 0; i < ChartSeries.Count; i++)
 | 
						|
            {
 | 
						|
                ChartSeries series = ChartSeries[i];
 | 
						|
 | 
						|
                if (series.IsDisplayed == true && series.CrosshairEnabled != Tbool.False)
 | 
						|
                {
 | 
						|
                    if (series.SeriesPoints.Count > 0)
 | 
						|
                    {
 | 
						|
                        SortedSeriesPoints ssp = series.GetSortedSeriesPoints(this);
 | 
						|
 | 
						|
                        ChartAxis axis = (series.IsRotated == true)
 | 
						|
                            ? series.AxisY ?? AxisY : series.AxisX ?? AxisX;
 | 
						|
 | 
						|
                        TickmarkLayout layout = axis.TickmarkLayout;
 | 
						|
 | 
						|
                        if (layout.Ticks != null && layout.Ticks.Length > 0)
 | 
						|
                        {
 | 
						|
                            Size msize = GetCrosshairMarkerSize(series);
 | 
						|
 | 
						|
                            for (int j = 0; j < ssp.Count; j++)
 | 
						|
                                SetCrosshairPointX(cps, series, ssp, j, msize, pt, bounds);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (cps);
 | 
						|
        }
 | 
						|
 | 
						|
        #region SetCrosshairPointX
 | 
						|
 | 
						|
        private void SetCrosshairPointX(List<CrosshairPoint> cps, ChartSeries series,
 | 
						|
            SortedSeriesPoints ssp, int index, Size msize, Point pt, Rectangle bounds)
 | 
						|
        {
 | 
						|
            SeriesPoint sp = ssp[index];
 | 
						|
 | 
						|
            if (sp.IsEmpty == false)
 | 
						|
            {
 | 
						|
                int vindex = 0;
 | 
						|
                bool descending = false;
 | 
						|
 | 
						|
                Point spt = Point.Empty;
 | 
						|
                Point lpt = GetLocalAdjustedPoint(spt);
 | 
						|
 | 
						|
                switch (series.SeriesType)
 | 
						|
                {
 | 
						|
                    case SeriesType.VerticalDot:
 | 
						|
                        spt = GetDataPointEx(series, sp, -1);
 | 
						|
                        spt.Offset(lpt);
 | 
						|
 | 
						|
                        spt.Y -= (msize.Height * ssp.CountArray[index]);
 | 
						|
                        spt.Y += (msize.Height / 2);
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case SeriesType.HorizontalDot:
 | 
						|
                        object x1 = GetDataPointValueX(series, sp);
 | 
						|
 | 
						|
                        spt = GetPointFromValue(series, 0, x1);
 | 
						|
                        spt.Offset(lpt);
 | 
						|
 | 
						|
                        spt.X += (msize.Width * ssp.CountArray[index]);
 | 
						|
                        spt.X -= (msize.Width / 2);
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case SeriesType.VerticalBar:
 | 
						|
                        spt = GetDataPointEx(series, sp, 0);
 | 
						|
                        spt.Offset(lpt);
 | 
						|
 | 
						|
                        spt.X += series.BarOffset;
 | 
						|
 | 
						|
                        int yStart = series.GetVBarStart(this, sp) + lpt.Y;
 | 
						|
 | 
						|
                        descending = (spt.Y > yStart);
 | 
						|
 | 
						|
                        if (sp.ValueY.Length > 1)
 | 
						|
                        {
 | 
						|
                            AddCrosshairPointX(cps, series,
 | 
						|
                                ssp, index, sp, 0, spt, msize, pt, bounds, descending);
 | 
						|
 | 
						|
                            spt.Y = yStart;
 | 
						|
 | 
						|
                            vindex = 1;
 | 
						|
                            descending = !descending;
 | 
						|
                        }
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case SeriesType.HorizontalBar:
 | 
						|
                        spt = GetDataPointEx(series, sp, 0);
 | 
						|
                        spt.Offset(lpt);
 | 
						|
 | 
						|
                        spt.Y += series.BarOffset;
 | 
						|
 | 
						|
                        int xStart = series.GetHBarStart(this, sp) + lpt.X;
 | 
						|
 | 
						|
                        descending = (spt.X < xStart);
 | 
						|
 | 
						|
                        if (sp.ValueY.Length > 1)
 | 
						|
                        {
 | 
						|
                            AddCrosshairPointX(cps, series,
 | 
						|
                                ssp, index, sp, 0, spt, msize, pt, bounds, descending);
 | 
						|
 | 
						|
                            spt.X = xStart;
 | 
						|
 | 
						|
                            vindex = 1;
 | 
						|
                            descending = !descending;
 | 
						|
                        }
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case SeriesType.VerticalHiLoBar:
 | 
						|
                        SetCrosshairPointVHiLoX(cps, series, ssp, index, msize, pt, bounds);
 | 
						|
                        return;
 | 
						|
 | 
						|
                    case SeriesType.HorizontalHiLoBar:
 | 
						|
                        SetCrosshairPointHHiLoX(cps, series, ssp, index, msize, pt, bounds);
 | 
						|
                        return;
 | 
						|
 | 
						|
                    case SeriesType.Point:
 | 
						|
                        for (int i = 0; i < sp.ValueY.Length; i++)
 | 
						|
                        {
 | 
						|
                            spt = GetDataPointEx(series, sp, i);
 | 
						|
                            spt.Offset(lpt);
 | 
						|
 | 
						|
                            AddCrosshairPointX(cps, series,
 | 
						|
                                ssp, index, sp, i, spt, msize, pt, bounds, descending);
 | 
						|
                        }
 | 
						|
                        return;
 | 
						|
 | 
						|
                    default:
 | 
						|
                        spt = GetDataPoint(series, sp, 0);
 | 
						|
                        break;
 | 
						|
                }
 | 
						|
 | 
						|
                AddCrosshairPointX(cps, series,
 | 
						|
                    ssp, index, sp, vindex, spt, msize, pt, bounds, descending);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region SetCrosshairPointVHiLoX
 | 
						|
 | 
						|
        private void SetCrosshairPointVHiLoX(List<CrosshairPoint> cps,
 | 
						|
            ChartSeries series, SortedSeriesPoints ssp, int index, Size msize, Point pt, Rectangle bounds)
 | 
						|
        {
 | 
						|
            Point spt = Point.Empty;
 | 
						|
            Point lpt = GetLocalAdjustedPoint(spt);
 | 
						|
 | 
						|
            SeriesPoint sp = ssp[index];
 | 
						|
 | 
						|
            spt = GetDataPointEx(series, sp, 0);
 | 
						|
            spt.X += (series.BarOffset + lpt.X);
 | 
						|
 | 
						|
            int[] values = GetVStockValues(series, sp);
 | 
						|
 | 
						|
            int v0, v1, v2, v3;
 | 
						|
            NormalizeStockValues(values, out v0, out v1, out v2, out v3);
 | 
						|
 | 
						|
            if (values[v2] != int.MinValue)
 | 
						|
            {
 | 
						|
                spt.Y = values[v2] + lpt.Y;
 | 
						|
 | 
						|
                AddCrosshairPointX(cps, series,
 | 
						|
                    ssp, index, sp, v2, spt, msize, pt, bounds, false);
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v3] != int.MinValue)
 | 
						|
            {
 | 
						|
                spt.Y = values[v3] + lpt.Y;
 | 
						|
 | 
						|
                AddCrosshairPointX(cps, series,
 | 
						|
                    ssp, index, sp, v3, spt, msize, pt, bounds, true);
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v2] == int.MinValue || values[v0] < values[v2])
 | 
						|
            {
 | 
						|
                spt.Y = values[v0] + lpt.Y;
 | 
						|
 | 
						|
                AddCrosshairPointX(cps, series,
 | 
						|
                    ssp, index, sp, v0, spt, msize, pt, bounds, false);
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v3] == int.MinValue || values[v1] > values[v3])
 | 
						|
            {
 | 
						|
                spt.Y = values[v1] + lpt.Y;
 | 
						|
 | 
						|
                AddCrosshairPointX(cps, series,
 | 
						|
                    ssp, index, sp, v1, spt, msize, pt, bounds, true);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetVStockValues
 | 
						|
 | 
						|
        private int[] GetVStockValues(ChartSeries series, SeriesPoint sp)
 | 
						|
        {
 | 
						|
            ChartAxis axis = series.AxisY ?? AxisY;
 | 
						|
 | 
						|
            int[] values = new int[4];
 | 
						|
 | 
						|
            for (int i = 0; i < values.Length; i++)
 | 
						|
            {
 | 
						|
                if (i < sp.ValueY.Length)
 | 
						|
                    values[i] = GetDataPointY(axis, sp.ValueY[i]);
 | 
						|
                else
 | 
						|
                    values[i] = int.MinValue;
 | 
						|
            }
 | 
						|
 | 
						|
            return (values);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SetCrosshairPointHHiLoX
 | 
						|
 | 
						|
        private void SetCrosshairPointHHiLoX(List<CrosshairPoint> cps,
 | 
						|
        ChartSeries series, SortedSeriesPoints ssp, int index, Size msize, Point pt, Rectangle bounds)
 | 
						|
        {
 | 
						|
            Point spt = Point.Empty;
 | 
						|
            Point lpt = GetLocalAdjustedPoint(spt);
 | 
						|
 | 
						|
            SeriesPoint sp = ssp[index];
 | 
						|
 | 
						|
            spt = GetDataPointEx(series, sp, 0);
 | 
						|
            spt.Y += (series.BarOffset + lpt.Y);
 | 
						|
 | 
						|
            int[] values = GetHStockValues(series, sp);
 | 
						|
 | 
						|
            int v0, v1, v2, v3;
 | 
						|
            NormalizeStockValues(values, out v0, out v1, out v2, out v3);
 | 
						|
 | 
						|
            if (values[v2] != int.MinValue)
 | 
						|
            {
 | 
						|
                spt.X = values[v2] + lpt.X;
 | 
						|
 | 
						|
                AddCrosshairPointX(cps, series,
 | 
						|
                    ssp, index, sp, v2, spt, msize, pt, bounds, true);
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v3] != int.MinValue)
 | 
						|
            {
 | 
						|
                spt.X = values[v3] + lpt.X;
 | 
						|
 | 
						|
                AddCrosshairPointX(cps, series,
 | 
						|
                    ssp, index, sp, v3, spt, msize, pt, bounds, false);
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v2] == int.MinValue || values[v0] < values[v2])
 | 
						|
            {
 | 
						|
                spt.X = values[v0] + lpt.X;
 | 
						|
 | 
						|
                AddCrosshairPointX(cps, series,
 | 
						|
                    ssp, index, sp, v0, spt, msize, pt, bounds, true);
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v3] == int.MinValue || values[v1] > values[v3])
 | 
						|
            {
 | 
						|
                spt.X = values[v1] + lpt.X;
 | 
						|
 | 
						|
                AddCrosshairPointX(cps, series,
 | 
						|
                    ssp, index, sp, v1, spt, msize, pt, bounds, false);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetHStockValues
 | 
						|
 | 
						|
        private int[] GetHStockValues(ChartSeries series, SeriesPoint sp)
 | 
						|
        {
 | 
						|
            ChartAxis axis = series.AxisX ?? AxisX;
 | 
						|
 | 
						|
            int[] values = new int[4];
 | 
						|
 | 
						|
            for (int i = 0; i < values.Length; i++)
 | 
						|
            {
 | 
						|
                if (i < sp.ValueY.Length)
 | 
						|
                    values[i] = GetDataPointX(axis, sp.ValueY[i]);
 | 
						|
                else
 | 
						|
                    values[i] = int.MinValue;
 | 
						|
            }
 | 
						|
 | 
						|
            return (values);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region NormalizeStockValues
 | 
						|
 | 
						|
        private void NormalizeStockValues(int[] values,
 | 
						|
            out int v0, out int v1, out int v2, out int v3)
 | 
						|
        {
 | 
						|
            v0 = 0;
 | 
						|
            v1 = 1;
 | 
						|
            v2 = 2;
 | 
						|
            v3 = 3;
 | 
						|
 | 
						|
            if (values[1] < values[0])
 | 
						|
            {
 | 
						|
                v0 = 1;
 | 
						|
                v1 = 0;
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v3] != int.MinValue && values[v3] < values[v2])
 | 
						|
            {
 | 
						|
                v2 = 3;
 | 
						|
                v3 = 2;
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v2] != int.MinValue)
 | 
						|
            {
 | 
						|
                if (values[v2] < values[v0])
 | 
						|
                    v0 = v2;
 | 
						|
 | 
						|
                if (values[v2] > values[v1])
 | 
						|
                    v1 = v2;
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v3] != int.MinValue)
 | 
						|
            {
 | 
						|
                if (values[v3] > values[v1])
 | 
						|
                    v1 = v3;
 | 
						|
 | 
						|
                if (values[v3] < values[v0])
 | 
						|
                    v0 = v3;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region AddCrosshairPointX
 | 
						|
 | 
						|
        private void AddCrosshairPointX(List<CrosshairPoint> cps, ChartSeries series,
 | 
						|
            SortedSeriesPoints ssp, int index, SeriesPoint sp, int vindex, Point spt,
 | 
						|
            Size msize, Point pt, Rectangle bounds, bool descending)
 | 
						|
        {
 | 
						|
            if (spt != Point.Empty && bounds.Contains(spt))
 | 
						|
            {
 | 
						|
                int dx = ChartCrosshair.PointIntersectMargin;
 | 
						|
 | 
						|
                if (ChartCrosshair.PointIntersectMode == PointIntersectMode.Edge)
 | 
						|
                {
 | 
						|
                    if (sp.PointSize.Width > 0)
 | 
						|
                        dx += (sp.PointSize.Width / 2);
 | 
						|
                    else
 | 
						|
                        dx += (msize.Height / 2);
 | 
						|
                }
 | 
						|
 | 
						|
                if (spt.X >= pt.X - dx && spt.X <= pt.X + dx)
 | 
						|
                    cps.Add(new CrosshairPoint(series, ssp, index, sp, vindex, spt, descending));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderCrosshairY
 | 
						|
 | 
						|
        private void RenderCrosshairY(Graphics g,
 | 
						|
            Rectangle bounds, Point pt, CrosshairVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            ChartCrosshair crosshair = ChartCrosshair;
 | 
						|
 | 
						|
            List<CrosshairPoint> cps = _CrosshairSeriesPoints;
 | 
						|
 | 
						|
            if (crosshair.ShowValueYLine == true)
 | 
						|
                RenderCrosshairLineY(g, pt, bounds, cstyle);
 | 
						|
 | 
						|
            if (crosshair.ShowValueYLabels == true)
 | 
						|
                RenderCrosshairLabelY(g, pt);
 | 
						|
 | 
						|
            if (crosshair.ShowValueXLine == true || crosshair.ShowValueXLabels == true)
 | 
						|
            {
 | 
						|
                if (crosshair.CrosshairLabelMode == CrosshairLabelMode.NearestSeries)
 | 
						|
                {
 | 
						|
                    CrosshairPoint mcp = _NearestCrosshairPoint;
 | 
						|
 | 
						|
                    if (mcp != null)
 | 
						|
                    {
 | 
						|
                        if (crosshair.ShowValueXLine == true)
 | 
						|
                            RenderCrosshairLineX(g, mcp.Point, bounds, cstyle);
 | 
						|
 | 
						|
                        if (crosshair.ShowValueXLabels == true)
 | 
						|
                            RenderCrosshairLabelX(g, mcp);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    foreach (CrosshairPoint cp in cps)
 | 
						|
                    {
 | 
						|
                        if (crosshair.ShowValueXLine == true)
 | 
						|
                            RenderCrosshairLineX(g, cp.Point, bounds, cstyle);
 | 
						|
 | 
						|
                        if (crosshair.ShowValueXLabels == true)
 | 
						|
                            RenderCrosshairLabelX(g, cp);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetCrosshairPointsY
 | 
						|
 | 
						|
        private List<CrosshairPoint> GetCrosshairPointsY(Point pt, Rectangle bounds)
 | 
						|
        {
 | 
						|
            List<CrosshairPoint> cps = new List<CrosshairPoint>();
 | 
						|
 | 
						|
            for (int i = 0; i < ChartSeries.Count; i++)
 | 
						|
            {
 | 
						|
                ChartSeries series = ChartSeries[i];
 | 
						|
 | 
						|
                if (series.IsDisplayed == true && series.CrosshairEnabled != Tbool.False)
 | 
						|
                {
 | 
						|
                    if (series.SeriesPoints.Count > 0)
 | 
						|
                    {
 | 
						|
                        SortedSeriesPoints ssp = series.GetSortedSeriesPoints(this);
 | 
						|
 | 
						|
                        ChartAxis axis = series.AxisX ?? AxisX;
 | 
						|
                        TickmarkLayout layout = axis.TickmarkLayout;
 | 
						|
 | 
						|
                        if (layout.Ticks != null && layout.Ticks.Length > 0)
 | 
						|
                        {
 | 
						|
                            Size msize = GetCrosshairMarkerSize(series);
 | 
						|
 | 
						|
                            for (int j = 0; j < ssp.Count; j++)
 | 
						|
                                SetCrosshairPointY(cps, series, ssp, j, msize, pt, bounds);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (cps);
 | 
						|
        }
 | 
						|
 | 
						|
        #region SetCrosshairPointY
 | 
						|
 | 
						|
        private void SetCrosshairPointY(List<CrosshairPoint> cps, ChartSeries series,
 | 
						|
            SortedSeriesPoints ssp, int index, Size msize, Point pt, Rectangle bounds)
 | 
						|
        {
 | 
						|
            SeriesPoint sp = ssp[index];
 | 
						|
 | 
						|
            if (sp.IsEmpty == false)
 | 
						|
            {
 | 
						|
                int vindex = 0;
 | 
						|
                bool descending = false;
 | 
						|
 | 
						|
                Point spt = Point.Empty;
 | 
						|
                Point lpt = GetLocalAdjustedPoint(spt);
 | 
						|
 | 
						|
                switch (series.SeriesType)
 | 
						|
                {
 | 
						|
                    case SeriesType.VerticalDot:
 | 
						|
                        spt = GetDataPointEx(series, sp, -1);
 | 
						|
                        spt.Offset(lpt);
 | 
						|
 | 
						|
                        spt.Y -= (msize.Height * ssp.CountArray[index] - msize.Height / 2);
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case SeriesType.HorizontalDot:
 | 
						|
                        object x1 = GetDataPointValueX(series, sp);
 | 
						|
 | 
						|
                        spt = GetPointFromValue(series, 0, x1);
 | 
						|
                        spt.Offset(lpt);
 | 
						|
 | 
						|
                        spt.X += (msize.Width * ssp.CountArray[index] - msize.Width / 2);
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case SeriesType.VerticalBar:
 | 
						|
                        spt = GetDataPointEx(series, sp, 0);
 | 
						|
                        spt.Offset(lpt);
 | 
						|
 | 
						|
                        spt.X += series.BarOffset;
 | 
						|
 | 
						|
                        int yStart = series.GetVBarStart(this, sp) + lpt.Y;
 | 
						|
 | 
						|
                        descending = (spt.Y > yStart);
 | 
						|
 | 
						|
                        if (sp.ValueY.Length > 1)
 | 
						|
                        {
 | 
						|
                            AddCrosshairPointY(cps, series,
 | 
						|
                                ssp, index, sp, 0, spt, msize, pt, bounds, descending);
 | 
						|
 | 
						|
                            spt.Y = yStart;
 | 
						|
 | 
						|
                            vindex = 1;
 | 
						|
                            descending = !descending;
 | 
						|
                        }
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case SeriesType.HorizontalBar:
 | 
						|
                        spt = GetDataPointEx(series, sp, 0);
 | 
						|
                        spt.Offset(lpt);
 | 
						|
 | 
						|
                        spt.Y += series.BarOffset;
 | 
						|
 | 
						|
                        int xStart = series.GetHBarStart(this, sp) + lpt.X;
 | 
						|
 | 
						|
                        descending = (spt.X < xStart);
 | 
						|
 | 
						|
                        if (sp.ValueY.Length > 1)
 | 
						|
                        {
 | 
						|
                            AddCrosshairPointX(cps, series,
 | 
						|
                                ssp, index, sp, 0, spt, msize, pt, bounds, descending);
 | 
						|
 | 
						|
                            spt.X = xStart;
 | 
						|
 | 
						|
                            vindex = 1;
 | 
						|
                            descending = !descending;
 | 
						|
                        }
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case SeriesType.VerticalHiLoBar:
 | 
						|
                        SetCrosshairPointVHiLoY(cps, series, ssp, index, msize, pt, bounds);
 | 
						|
                        return;
 | 
						|
 | 
						|
                    case SeriesType.HorizontalHiLoBar:
 | 
						|
                        SetCrosshairPointHHiLoY(cps, series, ssp, index, msize, pt, bounds);
 | 
						|
                        return;
 | 
						|
 | 
						|
                    case SeriesType.Point:
 | 
						|
                        for (int i = 0; i < sp.ValueY.Length; i++)
 | 
						|
                        {
 | 
						|
                            spt = GetDataPointEx(series, sp, i);
 | 
						|
                            spt.Offset(lpt);
 | 
						|
 | 
						|
                            AddCrosshairPointY(cps, series,
 | 
						|
                                ssp, index, sp, i, spt, msize, pt, bounds, descending);
 | 
						|
                        }
 | 
						|
                        return;
 | 
						|
 | 
						|
                    default:
 | 
						|
                        spt = GetDataPoint(series, sp, 0);
 | 
						|
                        break;
 | 
						|
                }
 | 
						|
 | 
						|
                AddCrosshairPointY(cps, series,
 | 
						|
                    ssp, index, sp, vindex, spt, msize, pt, bounds, descending);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region SetCrosshairPointVHiLoY
 | 
						|
 | 
						|
        private void SetCrosshairPointVHiLoY(List<CrosshairPoint> cps,
 | 
						|
            ChartSeries series, SortedSeriesPoints ssp, int index, Size msize, Point pt, Rectangle bounds)
 | 
						|
        {
 | 
						|
            Point spt = Point.Empty;
 | 
						|
            Point lpt = GetLocalAdjustedPoint(spt);
 | 
						|
 | 
						|
            SeriesPoint sp = ssp[index];
 | 
						|
 | 
						|
            spt = GetDataPointEx(series, sp, 0);
 | 
						|
            spt.X += (series.BarOffset + lpt.X);
 | 
						|
 | 
						|
            int[] values = GetVStockValues(series, sp);
 | 
						|
 | 
						|
            int v0, v1, v2, v3;
 | 
						|
            NormalizeStockValues(values, out v0, out v1, out v2, out v3);
 | 
						|
 | 
						|
            if (values[v2] != int.MinValue)
 | 
						|
            {
 | 
						|
                spt.Y = values[v2] + lpt.Y;
 | 
						|
 | 
						|
                AddCrosshairPointY(cps, series,
 | 
						|
                    ssp, index, sp, v2, spt, msize, pt, bounds, false);
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v3] != int.MinValue)
 | 
						|
            {
 | 
						|
                spt.Y = values[v3] + lpt.Y;
 | 
						|
 | 
						|
                AddCrosshairPointY(cps, series,
 | 
						|
                    ssp, index, sp, v3, spt, msize, pt, bounds, true);
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v2] == int.MinValue || values[v0] < values[v2])
 | 
						|
            {
 | 
						|
                spt.Y = values[v0] + lpt.Y;
 | 
						|
 | 
						|
                AddCrosshairPointY(cps, series,
 | 
						|
                    ssp, index, sp, v0, spt, msize, pt, bounds, false);
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v3] == int.MinValue || values[v1] > values[v3])
 | 
						|
            {
 | 
						|
                spt.Y = values[v1] + lpt.Y;
 | 
						|
 | 
						|
                AddCrosshairPointY(cps, series,
 | 
						|
                    ssp, index, sp, v1, spt, msize, pt, bounds, true);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SetCrosshairPointHHiLoY
 | 
						|
 | 
						|
        private void SetCrosshairPointHHiLoY(List<CrosshairPoint> cps,
 | 
						|
        ChartSeries series, SortedSeriesPoints ssp, int index, Size msize, Point pt, Rectangle bounds)
 | 
						|
        {
 | 
						|
            Point spt = Point.Empty;
 | 
						|
            Point lpt = GetLocalAdjustedPoint(spt);
 | 
						|
 | 
						|
            SeriesPoint sp = ssp[index];
 | 
						|
 | 
						|
            spt = GetDataPointEx(series, sp, 0);
 | 
						|
            spt.Y += (series.BarOffset + lpt.Y);
 | 
						|
 | 
						|
            int[] values = GetHStockValues(series, sp);
 | 
						|
 | 
						|
            int v0, v1, v2, v3;
 | 
						|
            NormalizeStockValues(values, out v0, out v1, out v2, out v3);
 | 
						|
 | 
						|
            if (values[v2] != int.MinValue)
 | 
						|
            {
 | 
						|
                spt.X = values[v2] + lpt.X;
 | 
						|
 | 
						|
                AddCrosshairPointY(cps, series,
 | 
						|
                    ssp, index, sp, v2, spt, msize, pt, bounds, true);
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v3] != int.MinValue)
 | 
						|
            {
 | 
						|
                spt.X = values[v3] + lpt.X;
 | 
						|
 | 
						|
                AddCrosshairPointY(cps, series,
 | 
						|
                    ssp, index, sp, v3, spt, msize, pt, bounds, false);
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v2] == int.MinValue || values[v0] < values[v2])
 | 
						|
            {
 | 
						|
                spt.X = values[v0] + lpt.X;
 | 
						|
 | 
						|
                AddCrosshairPointY(cps, series,
 | 
						|
                    ssp, index, sp, v0, spt, msize, pt, bounds, true);
 | 
						|
            }
 | 
						|
 | 
						|
            if (values[v3] == int.MinValue || values[v1] > values[v3])
 | 
						|
            {
 | 
						|
                spt.X = values[v1] + lpt.X;
 | 
						|
 | 
						|
                AddCrosshairPointY(cps, series,
 | 
						|
                    ssp, index, sp, v1, spt, msize, pt, bounds, false);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region AddCrosshairPointY
 | 
						|
 | 
						|
        private void AddCrosshairPointY(List<CrosshairPoint> cps, ChartSeries series,
 | 
						|
            SortedSeriesPoints ssp, int index, SeriesPoint sp, int vindex, Point spt,
 | 
						|
            Size msize, Point pt, Rectangle bounds, bool descending)
 | 
						|
        {
 | 
						|
            if (spt != Point.Empty && bounds.Contains(spt))
 | 
						|
            {
 | 
						|
                int dy = ChartCrosshair.PointIntersectMargin;
 | 
						|
 | 
						|
                if (ChartCrosshair.PointIntersectMode == PointIntersectMode.Edge)
 | 
						|
                {
 | 
						|
                    if (sp.PointSize.Height > 0)
 | 
						|
                        dy += (sp.PointSize.Height / 2);
 | 
						|
                    else
 | 
						|
                        dy += (msize.Height / 2);
 | 
						|
                }
 | 
						|
 | 
						|
                if (spt.Y >= pt.Y - dy && spt.Y <= pt.Y + dy)
 | 
						|
                    cps.Add(new CrosshairPoint(series, ssp, index, sp, vindex, spt, descending));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetCrosshairMarkerSize
 | 
						|
 | 
						|
        private Size GetCrosshairMarkerSize(ChartSeries series)
 | 
						|
        {
 | 
						|
            Size msize = Size.Empty;
 | 
						|
 | 
						|
            if (series.SeriesType == SeriesType.VerticalDot ||
 | 
						|
                series.SeriesType == SeriesType.HorizontalDot)
 | 
						|
            {
 | 
						|
                msize = GetMaxDotPlotMarkerSize();
 | 
						|
            }
 | 
						|
            else if (series.IsBarSeries == true)
 | 
						|
            {
 | 
						|
                msize = new Size(series.BarWidth, Dpi.Height5);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                Image marker = series.PointMarkerImage;
 | 
						|
 | 
						|
                if (marker != null)
 | 
						|
                    msize = marker.Size;
 | 
						|
            }
 | 
						|
 | 
						|
            return (msize);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderCrosshairLineX
 | 
						|
 | 
						|
        private void RenderCrosshairLineX(Graphics g,
 | 
						|
            Point pt, Rectangle bounds, CrosshairVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            Point pt1 = new Point(pt.X, bounds.Y);
 | 
						|
            Point pt2 = new Point(pt.X, bounds.Bottom - 1);
 | 
						|
 | 
						|
            ChartLineVisualStyle lstyle = cstyle.ValueXLineStyle;
 | 
						|
 | 
						|
            using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth)))
 | 
						|
            {
 | 
						|
                pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | 
						|
 | 
						|
                g.DrawLine(pen, pt1, pt2);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderCrosshairLineY
 | 
						|
 | 
						|
        private void RenderCrosshairLineY(Graphics g,
 | 
						|
            Point pt, Rectangle bounds, CrosshairVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            Point pt1 = new Point(bounds.X, pt.Y);
 | 
						|
            Point pt2 = new Point(bounds.Right - 1, pt.Y);
 | 
						|
 | 
						|
            ChartLineVisualStyle lstyle = cstyle.ValueYLineStyle;
 | 
						|
 | 
						|
            using (Pen pen = new Pen(lstyle.LineColor, Dpi.Height(lstyle.LineWidth)))
 | 
						|
            {
 | 
						|
                pen.DashStyle = (DashStyle)lstyle.LinePattern;
 | 
						|
 | 
						|
                g.DrawLine(pen, pt1, pt2);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderCrosshairLabelX
 | 
						|
 | 
						|
        private void RenderCrosshairLabelX(Graphics g, Point pt)
 | 
						|
        {
 | 
						|
            RenderAxesCrosshairLabelXy(g, pt, AncillaryAxesX, AxisX);
 | 
						|
        }
 | 
						|
 | 
						|
        private void RenderCrosshairLabelX(Graphics g, CrosshairPoint cp)
 | 
						|
        {
 | 
						|
            ChartAxis axis = cp.ChartSeries.AxisX ?? AxisX;
 | 
						|
 | 
						|
            if (axis != null)
 | 
						|
                axis.RenderCrosshairLabel(g, cp);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderCrosshairLabelY
 | 
						|
 | 
						|
        private void RenderCrosshairLabelY(Graphics g, Point pt)
 | 
						|
        {
 | 
						|
            RenderAxesCrosshairLabelXy(g, pt, AncillaryAxesY, AxisY);
 | 
						|
        }
 | 
						|
 | 
						|
        private void RenderCrosshairLabelY(Graphics g, CrosshairPoint cp)
 | 
						|
        {
 | 
						|
            ChartAxis axis = cp.ChartSeries.AxisY ?? AxisY;
 | 
						|
 | 
						|
            if (axis != null)
 | 
						|
                axis.RenderCrosshairLabel(g, cp);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderAxesCrosshairLabelXy
 | 
						|
 | 
						|
        private void RenderAxesCrosshairLabelXy(Graphics g,
 | 
						|
            Point pt, ChartAxesCollection axes, ChartAxis axis)
 | 
						|
        {
 | 
						|
            foreach (ChartAxis ca in axes)
 | 
						|
            {
 | 
						|
                if (ca.Visible == true)
 | 
						|
                    ca.RenderCrosshairLabel(g, pt);
 | 
						|
            }
 | 
						|
 | 
						|
            if (axis.Visible == true)
 | 
						|
                axis.RenderCrosshairLabel(g, pt);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetNearestPoint
 | 
						|
 | 
						|
        private CrosshairPoint GetNearestPoint(
 | 
						|
            List<CrosshairPoint> cps, Point pt, AxisOrientation orientation)
 | 
						|
        {
 | 
						|
            CrosshairPoint minPoint = null;
 | 
						|
 | 
						|
            int minValue = int.MaxValue;
 | 
						|
            int minValue2 = int.MaxValue;
 | 
						|
 | 
						|
            bool comp = (orientation == AxisOrientation.Y);
 | 
						|
 | 
						|
            foreach (CrosshairPoint cp in cps)
 | 
						|
            {
 | 
						|
                Point cpt = cp.Point;
 | 
						|
 | 
						|
                int dv = Math.Abs((comp == false) ? (cpt.Y - pt.Y) : (cpt.X - pt.X));
 | 
						|
                int dv2 = Math.Abs((comp == true) ? (cpt.Y - pt.Y) : (cpt.X - pt.X));
 | 
						|
 | 
						|
                if (dv < minValue)
 | 
						|
                {
 | 
						|
                    minValue = dv;
 | 
						|
                    minValue2 = dv2;
 | 
						|
 | 
						|
                    minPoint = cp;
 | 
						|
                }
 | 
						|
                else if (dv == minValue)
 | 
						|
                {
 | 
						|
                    if (dv2 < minValue2)
 | 
						|
                    {
 | 
						|
                        minValue2 = dv2;
 | 
						|
                        minPoint = cp;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (minPoint);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetFirstValue
 | 
						|
 | 
						|
        private object GetFirstValue(TickmarkLayout layout)
 | 
						|
        {
 | 
						|
            for (int i = 0; i < layout.Ticks.Length; i++)
 | 
						|
            {
 | 
						|
                TickmarkTick tick = layout.Ticks[i];
 | 
						|
 | 
						|
                if (tick.LabelIndex >= 0)
 | 
						|
                    return (tick.Value);
 | 
						|
            }
 | 
						|
 | 
						|
            return (null);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetLastValue
 | 
						|
 | 
						|
        private object GetLastValue(TickmarkLayout layout)
 | 
						|
        {
 | 
						|
            for (int i = layout.Ticks.Length - 1; i >= 0; i--)
 | 
						|
            {
 | 
						|
                TickmarkTick tick = layout.Ticks[i];
 | 
						|
 | 
						|
                if (tick.LabelIndex >= 0)
 | 
						|
                    return (tick.Value);
 | 
						|
            }
 | 
						|
 | 
						|
            return (null);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderCrosshairLabels
 | 
						|
 | 
						|
        #region RenderCrosshairLabels
 | 
						|
 | 
						|
        private void RenderCrosshairLabels(Graphics g,
 | 
						|
            Rectangle bounds, Point pt, CrosshairVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            if (ChartCrosshair.ShowCrosshairLabels == true)
 | 
						|
            {
 | 
						|
                if (ChartControl.DoRenderCrosshairLabelEvent(g, this, _CrosshairSeriesPoints, bounds, pt) == false)
 | 
						|
                {
 | 
						|
                    if (_CrosshairSeriesPoints != null && _CrosshairSeriesPoints.Count > 0)
 | 
						|
                    {
 | 
						|
                        switch (ChartCrosshair.CrosshairLabelMode)
 | 
						|
                        {
 | 
						|
                            case CrosshairLabelMode.Common:
 | 
						|
                                RenderCrosshairLabelCommon(g, bounds, pt, cstyle);
 | 
						|
                                break;
 | 
						|
 | 
						|
                            case CrosshairLabelMode.EachSeries:
 | 
						|
                                RenderCrosshairLabelEach(g, bounds, pt, cstyle);
 | 
						|
                                break;
 | 
						|
 | 
						|
                            case CrosshairLabelMode.NearestSeries:
 | 
						|
                                if (_NearestCrosshairPoint != null)
 | 
						|
                                    RenderCrosshairLabel(g, bounds, cstyle, _NearestCrosshairPoint);
 | 
						|
                                break;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region RenderCrosshairLabelCommon
 | 
						|
 | 
						|
        private void RenderCrosshairLabelCommon(Graphics g,
 | 
						|
            Rectangle bounds, Point pt, CrosshairVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            Hashtable gps = GetCrosshairLabelGroups(_CrosshairSeriesPoints);
 | 
						|
 | 
						|
            MeasureCrosshairLabelGroups(g, gps, bounds, cstyle);
 | 
						|
 | 
						|
            int markerWidth;
 | 
						|
            Rectangle cbounds = GetCrosshairCommonBounds(gps, bounds, pt, cstyle, out markerWidth);
 | 
						|
 | 
						|
            cbounds = GetAdjustedBounds(cbounds, cstyle.Margin);
 | 
						|
 | 
						|
            if (ChartControl.DoRenderCrosshairCalloutEvent(g, this, cbounds, pt, cstyle) == false)
 | 
						|
                DrawRoundRectangle(g, cbounds, cstyle);
 | 
						|
 | 
						|
            cbounds = GetAdjustedBounds(cbounds, cstyle.Padding);
 | 
						|
 | 
						|
            RenderCrosshairLabelGroups(g, gps, cbounds, cstyle);
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetCrosshairLabelGroups
 | 
						|
 | 
						|
        private Hashtable GetCrosshairLabelGroups(List<CrosshairPoint> cps)
 | 
						|
        {
 | 
						|
            Hashtable gps = new Hashtable();
 | 
						|
 | 
						|
            foreach (CrosshairPoint cp in cps)
 | 
						|
            {
 | 
						|
                ChartAxis axis;
 | 
						|
 | 
						|
                if (ChartCrosshair.AxisOrientation == AxisOrientation.X)
 | 
						|
                    axis = cp.ChartSeries.AxisX ?? AxisX;
 | 
						|
                else
 | 
						|
                    axis = cp.ChartSeries.AxisY ?? AxisY;
 | 
						|
 | 
						|
                CrosshairGroup group = gps[axis] as CrosshairGroup;
 | 
						|
 | 
						|
                if (group == null)
 | 
						|
                {
 | 
						|
                    group = new CrosshairGroup();
 | 
						|
 | 
						|
                    group.Cps = new List<CrosshairPoint>();
 | 
						|
                    group.Text = GetCrosshairHeader(cp, cps);
 | 
						|
 | 
						|
                    gps[axis] = group;
 | 
						|
                }
 | 
						|
 | 
						|
                group.Cps.Add(cp);
 | 
						|
            }
 | 
						|
 | 
						|
            return (gps);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MeasureCrosshairLabelGroups
 | 
						|
 | 
						|
        private void MeasureCrosshairLabelGroups(Graphics g,
 | 
						|
            Hashtable gps, Rectangle bounds, CrosshairVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            bool groupHeader = ChartCrosshair.ShowGroupHeaders;
 | 
						|
 | 
						|
            foreach (DictionaryEntry pair in gps)
 | 
						|
            {
 | 
						|
                CrosshairGroup group = (CrosshairGroup)pair.Value;
 | 
						|
 | 
						|
                if (groupHeader == true)
 | 
						|
                    MeasureCrosshairGroupHeader(g, group, bounds, cstyle);
 | 
						|
 | 
						|
                MeasureCrosshairCommonLabels(g, group, bounds, cstyle, groupHeader ? null : group.Text);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region MeasureCrosshairGroupHeader
 | 
						|
 | 
						|
        private void MeasureCrosshairGroupHeader(Graphics g,
 | 
						|
            CrosshairGroup group, Rectangle bounds, CrosshairVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            if (string.IsNullOrEmpty(group.Text) == false)
 | 
						|
            {
 | 
						|
                SizeF sizef = g.MeasureString(group.Text, cstyle.GroupHeaderFont, bounds.Width);
 | 
						|
 | 
						|
                group.TextSize = new Size((int)sizef.Width + 1, (int)sizef.Height + 1);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MeasureCrosshairCommonLabels
 | 
						|
 | 
						|
        private void MeasureCrosshairCommonLabels(Graphics g,
 | 
						|
            CrosshairGroup group, Rectangle bounds, CrosshairVisualStyle cstyle, string header)
 | 
						|
        {
 | 
						|
            group.LabelSize = Size.Empty;
 | 
						|
            group.MarkerWidth = 0;
 | 
						|
 | 
						|
            foreach (CrosshairPoint cp in group.Cps)
 | 
						|
            {
 | 
						|
                Size markerSize = Size.Empty;
 | 
						|
 | 
						|
                Image marker = cp.ChartSeries.PointMarkerImage;
 | 
						|
 | 
						|
                if (marker != null)
 | 
						|
                {
 | 
						|
                    markerSize = marker.Size;
 | 
						|
 | 
						|
                    if (marker.Width > group.MarkerWidth)
 | 
						|
                        group.MarkerWidth = marker.Width;
 | 
						|
                }
 | 
						|
 | 
						|
                MeasureCrosshairLabel(g, bounds, cp, cstyle, header, false);
 | 
						|
 | 
						|
                if (cp.TextSize.IsEmpty == false)
 | 
						|
                {
 | 
						|
                    group.LabelSize.Height += Math.Max(markerSize.Height, cp.TextSize.Height);
 | 
						|
 | 
						|
                    if (markerSize.Width + cp.TextSize.Width > group.LabelSize.Width)
 | 
						|
                        group.LabelSize.Width = markerSize.Width + cp.TextSize.Width;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetCrosshairCommonBounds
 | 
						|
 | 
						|
        private Rectangle GetCrosshairCommonBounds(Hashtable gps,
 | 
						|
            Rectangle bounds, Point pt, CrosshairVisualStyle cstyle, out int markerWidth)
 | 
						|
        {
 | 
						|
            markerWidth = 0;
 | 
						|
 | 
						|
            Size totalSize = Size.Empty;
 | 
						|
 | 
						|
            foreach (DictionaryEntry pair in gps)
 | 
						|
            {
 | 
						|
                CrosshairGroup group = (CrosshairGroup)pair.Value;
 | 
						|
 | 
						|
                totalSize.Width = Math.Max(totalSize.Width, group.TextSize.Width);
 | 
						|
                totalSize.Height += (group.TextSize.Height + Dpi.Width4);
 | 
						|
 | 
						|
                foreach (CrosshairPoint cp in group.Cps)
 | 
						|
                {
 | 
						|
                    Size markerSize = Size.Empty;
 | 
						|
 | 
						|
                    Image marker = cp.ChartSeries.PointMarkerImage;
 | 
						|
 | 
						|
                    if (marker != null)
 | 
						|
                        markerSize = Dpi.Size(marker.Size);
 | 
						|
 | 
						|
                    markerWidth = Math.Max(markerWidth, markerSize.Width);
 | 
						|
 | 
						|
                    totalSize.Width = Math.Max(totalSize.Width, cp.TextSize.Width);
 | 
						|
                    totalSize.Height += (Math.Max(markerSize.Height, cp.TextSize.Height) + Dpi.Width4);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            totalSize.Width += markerWidth;
 | 
						|
 | 
						|
            totalSize.Width += (cstyle.Margin.Horizontal + cstyle.Padding.Horizontal + Dpi.Width4);
 | 
						|
            totalSize.Height += (cstyle.Margin.Horizontal + cstyle.Padding.Horizontal - Dpi.Width4);
 | 
						|
 | 
						|
            return (GetCrosshairLabelBounds(bounds, pt, totalSize));
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetCrosshairLabelBounds
 | 
						|
 | 
						|
        private Rectangle GetCrosshairLabelBounds(
 | 
						|
            Rectangle bounds, Point pt, Size size)
 | 
						|
        {
 | 
						|
            Rectangle r;
 | 
						|
 | 
						|
            int left = pt.X - bounds.X - Dpi.Width10;
 | 
						|
            int right = bounds.Right - pt.X - Dpi.Width10;
 | 
						|
 | 
						|
            if ((right >= size.Width) || (right > left))
 | 
						|
            {
 | 
						|
                r = new Rectangle(pt.X + 10, pt.Y - size.Height,
 | 
						|
                    size.Width, size.Height);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                r = new Rectangle(pt.X - (size.Width + Dpi.Width10),
 | 
						|
                    pt.Y - size.Height, size.Width, size.Height);
 | 
						|
            }
 | 
						|
 | 
						|
            r.Y -= Dpi.Height10;
 | 
						|
 | 
						|
            if (r.Y < ContentBounds.Y + Dpi.Height2)
 | 
						|
                r.Y = ContentBounds.Y + Dpi.Height2;
 | 
						|
 | 
						|
            return (r);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderCrosshairLabelGroups
 | 
						|
 | 
						|
        private void RenderCrosshairLabelGroups(Graphics g,
 | 
						|
            Hashtable gps, Rectangle bounds, CrosshairVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            using (Brush br = new SolidBrush(cstyle.GroupHeaderTextColor))
 | 
						|
            {
 | 
						|
                foreach (DictionaryEntry pair in gps)
 | 
						|
                {
 | 
						|
                    CrosshairGroup group = (CrosshairGroup)pair.Value;
 | 
						|
 | 
						|
                    Rectangle r = bounds;
 | 
						|
                    r.Height = group.TextSize.Height;
 | 
						|
 | 
						|
                    if (string.IsNullOrEmpty(group.Text) == false)
 | 
						|
                    {
 | 
						|
                        g.DrawString(group.Text, cstyle.GroupHeaderFont, br, r);
 | 
						|
 | 
						|
                        bounds.Y += (group.TextSize.Height + Dpi.Height4);
 | 
						|
                        bounds.Height -= (group.TextSize.Height + Dpi.Height4);
 | 
						|
                    }
 | 
						|
 | 
						|
                    foreach (CrosshairPoint cp in group.Cps)
 | 
						|
                    {
 | 
						|
                        if (cp.TextSize.IsEmpty == false)
 | 
						|
                        {
 | 
						|
                            RenderCrosshairLabelItem(g, bounds, cp, cstyle);
 | 
						|
 | 
						|
                            bounds.Y += (cp.TextSize.Height + Dpi.Height4);
 | 
						|
                            bounds.Height -= (cp.TextSize.Height + Dpi.Height4);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderCrosshairLabelEach
 | 
						|
 | 
						|
        private void RenderCrosshairLabelEach(Graphics g,
 | 
						|
            Rectangle bounds, Point pt, CrosshairVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            List<CrosshairPoint> cps = _CrosshairSeriesPoints;
 | 
						|
 | 
						|
            foreach (CrosshairPoint cp in cps)
 | 
						|
                RenderCrosshairLabel(g, bounds, cstyle, cp);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderCrosshairLabel
 | 
						|
 | 
						|
        private void RenderCrosshairLabel(Graphics g,
 | 
						|
            Rectangle bounds, CrosshairVisualStyle cstyle, CrosshairPoint cp)
 | 
						|
        {
 | 
						|
            string arg = GetCrosshairArgument(cp);
 | 
						|
 | 
						|
            MeasureCrosshairLabel(g, bounds, cp, cstyle, arg, true);
 | 
						|
 | 
						|
            if (cp.TextSize.IsEmpty == false)
 | 
						|
            {
 | 
						|
                Size markerSize = Size.Empty;
 | 
						|
 | 
						|
                if (ChartCrosshair.ShowCrosshairLabelMarkers == true)
 | 
						|
                {
 | 
						|
                    Image marker = cp.ChartSeries.PointMarkerImage;
 | 
						|
 | 
						|
                    if (marker != null)
 | 
						|
                        markerSize = marker.Size;
 | 
						|
                }
 | 
						|
 | 
						|
                Size totalSize = new Size((markerSize.Width + cp.TextSize.Width),
 | 
						|
                    Math.Max(markerSize.Height, cp.TextSize.Height) + Dpi.Height4);
 | 
						|
 | 
						|
                totalSize.Width += Dpi.Width(cstyle.Padding.Horizontal + 4);
 | 
						|
                totalSize.Height += Dpi.Height(cstyle.Padding.Vertical - 4);
 | 
						|
 | 
						|
                Point pt = cp.Point;
 | 
						|
 | 
						|
                if (ChartCrosshair.PointIntersectMode == PointIntersectMode.Edge)
 | 
						|
                {
 | 
						|
                    if (cp.ChartSeries.SeriesType == SeriesType.VerticalDot)
 | 
						|
                        pt.Y -= (cp.SeriesPoint.PointSize.Height / 2);
 | 
						|
 | 
						|
                    else if (cp.ChartSeries.SeriesType == SeriesType.HorizontalDot)
 | 
						|
                        pt.X += (cp.SeriesPoint.PointSize.Width / 2);
 | 
						|
                }
 | 
						|
 | 
						|
                Rectangle cbounds = GetCrosshairPointBounds(bounds, cp, pt, totalSize);
 | 
						|
 | 
						|
                DrawCrosshairCallout(g, cbounds, pt, cstyle);
 | 
						|
 | 
						|
                cbounds = GetAdjustedBounds(cbounds, cstyle.Padding);
 | 
						|
 | 
						|
                RenderCrosshairLabelItem(g, cbounds, cp, cstyle);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetCrosshairPointBounds
 | 
						|
 | 
						|
        private Rectangle GetCrosshairPointBounds(
 | 
						|
            Rectangle bounds, CrosshairPoint cp, Point pt, Size size)
 | 
						|
        {
 | 
						|
            Rectangle r;
 | 
						|
 | 
						|
            int n = size.Width / 5;
 | 
						|
 | 
						|
            int left = pt.X - bounds.X + n;
 | 
						|
            int right = bounds.Right - pt.X + n;
 | 
						|
 | 
						|
            if ((right >= size.Width) || (right > left))
 | 
						|
            {
 | 
						|
                r = new Rectangle(pt.X - n, pt.Y - size.Height,
 | 
						|
                    size.Width, size.Height);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                r = new Rectangle(pt.X - (size.Width - n),
 | 
						|
                    pt.Y - size.Height, size.Width, size.Height);
 | 
						|
            }
 | 
						|
 | 
						|
            r.Y -= Dpi.Height20;
 | 
						|
 | 
						|
            if (cp.ChartSeries.SeriesType == SeriesType.VerticalBar ||
 | 
						|
                cp.ChartSeries.SeriesType == SeriesType.VerticalHiLoBar)
 | 
						|
            {
 | 
						|
                if (cp.IsDescending == true)
 | 
						|
                {
 | 
						|
                    if (pt.Y + 20 + r.Height < Bounds.Bottom)
 | 
						|
                        r.Y = pt.Y + Dpi.Height20;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                if (r.Y < Bounds.Y + 2)
 | 
						|
                    r.Y = pt.Y + Dpi.Height20;
 | 
						|
            }
 | 
						|
 | 
						|
            if (cp.ChartSeries.SeriesType == SeriesType.HorizontalBar ||
 | 
						|
                cp.ChartSeries.SeriesType == SeriesType.HorizontalHiLoBar)
 | 
						|
            {
 | 
						|
                if (cp.IsDescending == true)
 | 
						|
                    r.X = pt.X - (size.Width - n);
 | 
						|
            }
 | 
						|
 | 
						|
            if (r.Right > Bounds.Right - Dpi.Width2)
 | 
						|
                r.X = Bounds.Right - r.Width - Dpi.Width2;
 | 
						|
 | 
						|
            if (r.Left < Bounds.X + Dpi.Width2)
 | 
						|
                r.X = Bounds.X + Dpi.Width2;
 | 
						|
 | 
						|
            return (r);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetCrosshairHeader
 | 
						|
 | 
						|
        private string GetCrosshairHeader(CrosshairPoint cp, List<CrosshairPoint> cps)
 | 
						|
        {
 | 
						|
            string text = GetCrosshairArgument(cp);
 | 
						|
 | 
						|
            ChartControl.DoGetCrosshairLabelHeaderEvent(this, cp, cps, ref text);
 | 
						|
 | 
						|
            return (text);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetCrosshairArgument
 | 
						|
 | 
						|
        private string GetCrosshairArgument(CrosshairPoint cp)
 | 
						|
        {
 | 
						|
            AxisOrientation ao = ChartCrosshair.AxisOrientation;
 | 
						|
 | 
						|
            if (cp.ChartSeries.IsRotated == true)
 | 
						|
            {
 | 
						|
                ao = (ChartCrosshair.AxisOrientation == AxisOrientation.X)
 | 
						|
                    ? AxisOrientation.Y : AxisOrientation.X;
 | 
						|
            }
 | 
						|
 | 
						|
            if (ao == AxisOrientation.X)
 | 
						|
                return (GetValueXText(cp.ChartSeries, cp.ValueX));
 | 
						|
 | 
						|
            return (GetValueYText(cp.ChartSeries, cp.ValueY));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetValueXText
 | 
						|
 | 
						|
        private string GetValueXText(ChartSeries series, object value)
 | 
						|
        {
 | 
						|
            ChartAxis axis = (series.IsRotated)
 | 
						|
                ? series.AxisY ?? AxisY : series.AxisX ?? AxisX;
 | 
						|
 | 
						|
            return (axis.GetCrosshairLabel(
 | 
						|
                value, axis.EffectiveCrosshairLabelStyle));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetValueYText
 | 
						|
 | 
						|
        private string GetValueYText(ChartSeries series, object value)
 | 
						|
        {
 | 
						|
            ChartAxis axis = (series.IsRotated)
 | 
						|
                ? series.AxisX ?? AxisX : series.AxisY ?? AxisY;
 | 
						|
 | 
						|
            return (axis.GetCrosshairLabel(
 | 
						|
                value, axis.EffectiveCrosshairLabelStyle));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MeasureCrosshairLabel
 | 
						|
 | 
						|
        private void MeasureCrosshairLabel(Graphics g,
 | 
						|
            Rectangle bounds, CrosshairPoint cp, CrosshairVisualStyle cstyle, string arg, bool multiLine)
 | 
						|
        {
 | 
						|
            cp.Text = GetCrosshairItemText(cp, arg, multiLine);
 | 
						|
 | 
						|
            if (string.IsNullOrEmpty(cp.Text) == false)
 | 
						|
            {
 | 
						|
                SizeF sizef = g.MeasureString(cp.Text, cstyle.Font, bounds.Width);
 | 
						|
 | 
						|
                cp.TextSize = new Size((int)sizef.Width + 1, (int)sizef.Height + 1);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                cp.TextSize = Size.Empty;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetCrosshairItemText
 | 
						|
 | 
						|
        private string GetCrosshairItemText(CrosshairPoint cp, string arg, bool multiLine)
 | 
						|
        {
 | 
						|
            string text = cp.ChartSeries.LegendText ?? cp.ChartSeries.Name ?? "";
 | 
						|
 | 
						|
            if (String.IsNullOrEmpty(text) == false)
 | 
						|
                text += "  ";
 | 
						|
 | 
						|
            if (arg != null)
 | 
						|
            {
 | 
						|
                if (multiLine == true && text.Length > 0)
 | 
						|
                    text += "\n";
 | 
						|
 | 
						|
                text += (arg + " : ");
 | 
						|
            }
 | 
						|
 | 
						|
            text += GetItemText(cp);
 | 
						|
 | 
						|
            ChartControl.DoGetCrosshairLabelItemEvent(this, cp, ref text);
 | 
						|
 | 
						|
            return (text);
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetItemText
 | 
						|
 | 
						|
        private string GetItemText(CrosshairPoint cp)
 | 
						|
        {
 | 
						|
            AxisOrientation ao = ChartCrosshair.AxisOrientation;
 | 
						|
 | 
						|
            if (cp.ChartSeries.IsRotated == true)
 | 
						|
            {
 | 
						|
                ao = (ChartCrosshair.AxisOrientation == AxisOrientation.X)
 | 
						|
                    ? AxisOrientation.Y : AxisOrientation.X;
 | 
						|
            }
 | 
						|
 | 
						|
            string text = (ao == AxisOrientation.X)
 | 
						|
                ? GetValueYText(cp.ChartSeries, cp.ValueY)
 | 
						|
                : GetValueXText(cp.ChartSeries, cp.ValueX);
 | 
						|
 | 
						|
            switch (cp.ChartSeries.SeriesType)
 | 
						|
            {
 | 
						|
                case SeriesType.HorizontalBar:
 | 
						|
                case SeriesType.VerticalBar:
 | 
						|
                    return (GetBarText(cp, text));
 | 
						|
 | 
						|
                case SeriesType.HorizontalHiLoBar:
 | 
						|
                case SeriesType.VerticalHiLoBar:
 | 
						|
                    return (GetHiLoBarText(cp, text));
 | 
						|
 | 
						|
                default:
 | 
						|
                    return (text);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetBarText
 | 
						|
 | 
						|
        private string GetBarText(CrosshairPoint cp, string s1)
 | 
						|
        {
 | 
						|
            if (cp.ChartSeries.IsRotated == (ChartCrosshair.AxisOrientation == AxisOrientation.Y))
 | 
						|
            {
 | 
						|
                if (cp.SeriesPoint.ValueY.Length > 1)
 | 
						|
                {
 | 
						|
                    object v1 = cp.ValueY;
 | 
						|
 | 
						|
                    ChartAxis axis = (cp.ChartSeries.IsRotated)
 | 
						|
                        ? cp.ChartSeries.AxisX ?? AxisX : cp.ChartSeries.AxisY ?? AxisY;
 | 
						|
 | 
						|
                    CrosshairValueVisualStyle lstyle = axis.EffectiveCrosshairLabelStyle;
 | 
						|
 | 
						|
                    object v2 = cp.SeriesPoint.ValueY[1];
 | 
						|
 | 
						|
                    if (v2 != null)
 | 
						|
                    {
 | 
						|
                        string s2 = axis.GetCrosshairLabel(v2, lstyle);
 | 
						|
 | 
						|
                        int y1 = GetDataPointX(axis, v1);
 | 
						|
                        int y2 = GetDataPointX(axis, v2);
 | 
						|
 | 
						|
                        if (y1 < y2)
 | 
						|
                            return (s1 + " — " + s2);
 | 
						|
 | 
						|
                        return (s2 + " — " + s1);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (s1);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetHiLoVBarText
 | 
						|
 | 
						|
        private string GetHiLoBarText(CrosshairPoint cp, string s1)
 | 
						|
        {
 | 
						|
            if (cp.ChartSeries.IsRotated == (ChartCrosshair.AxisOrientation == AxisOrientation.Y))
 | 
						|
            {
 | 
						|
                if (cp.SeriesPoint.ValueY.Length > 1)
 | 
						|
                {
 | 
						|
                    ChartAxis axis = (cp.ChartSeries.IsRotated)
 | 
						|
                        ? cp.ChartSeries.AxisX ?? AxisX : cp.ChartSeries.AxisY ?? AxisY;
 | 
						|
 | 
						|
                    CrosshairValueVisualStyle lstyle = axis.EffectiveCrosshairLabelStyle;
 | 
						|
 | 
						|
                    s1 = axis.GetCrosshairLabel(cp.ValueY, lstyle);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            s1 = s1 + " (" + "HLCO"[cp.ValueIndex] + ")";
 | 
						|
 | 
						|
            return (s1);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderCrosshairLabelItem
 | 
						|
 | 
						|
        private void RenderCrosshairLabelItem(Graphics g,
 | 
						|
            Rectangle bounds, CrosshairPoint cp, CrosshairVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            if (ChartControl.DoRenderCrosshairLabelItemEvent(g, this, cp, bounds, cstyle) == false)
 | 
						|
            {
 | 
						|
                Rectangle r = RenderCrosshairLabelMarker(g, bounds, cp);
 | 
						|
 | 
						|
                Color color = cstyle.TextColor;
 | 
						|
 | 
						|
                if (color.IsEmpty == true)
 | 
						|
                {
 | 
						|
                    color = cp.ChartSeries.GetLegendItemColor();
 | 
						|
 | 
						|
                    color = Color.FromArgb(255, color);
 | 
						|
                }
 | 
						|
 | 
						|
                using (Brush lbr = new SolidBrush(color))
 | 
						|
                    g.DrawString(cp.Text, cstyle.Font, lbr, r);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region RenderCrosshairLabelMarker
 | 
						|
 | 
						|
        private Rectangle RenderCrosshairLabelMarker(
 | 
						|
            Graphics g, Rectangle r, CrosshairPoint cp)
 | 
						|
        {
 | 
						|
            if (ChartCrosshair.ShowCrosshairLabelMarkers == true)
 | 
						|
            {
 | 
						|
                Image image = cp.ChartSeries.PointMarkerImage;
 | 
						|
 | 
						|
                if (image != null)
 | 
						|
                {
 | 
						|
                    Rectangle t = r;
 | 
						|
 | 
						|
                    Size isize = image.Size;
 | 
						|
 | 
						|
                    if (cp.TextSize.Height > isize.Height)
 | 
						|
                        t.Y += (cp.TextSize.Height - isize.Height) / 2;
 | 
						|
 | 
						|
                    g.DrawImageUnscaled(image, t);
 | 
						|
 | 
						|
                    r.X += (isize.Width + Dpi.Width4);
 | 
						|
                    r.Width -= (isize.Width + Dpi.Width4);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (r);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawRoundRectangle
 | 
						|
 | 
						|
        private void DrawRoundRectangle(Graphics g,
 | 
						|
            Rectangle t, CrosshairVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            SmoothingMode sm = g.SmoothingMode;
 | 
						|
            g.SmoothingMode = SmoothingMode.AntiAlias;
 | 
						|
 | 
						|
            using (GraphicsPath path = new GraphicsPath())
 | 
						|
            {
 | 
						|
                int dia = Dpi.Width14;
 | 
						|
                Rectangle r = t;
 | 
						|
 | 
						|
                r.Width = dia;
 | 
						|
                r.Height = dia;
 | 
						|
                path.AddArc(r, 180, 90);
 | 
						|
 | 
						|
                r.X += (t.Width - dia);
 | 
						|
                path.AddArc(r, 270, 90);
 | 
						|
 | 
						|
                r.Y += (t.Height - dia);
 | 
						|
                path.AddArc(r, 0, 90);
 | 
						|
 | 
						|
                r.X = t.X;
 | 
						|
                path.AddArc(r, 90, 90);
 | 
						|
 | 
						|
                path.CloseFigure();
 | 
						|
 | 
						|
                using (Brush br = cstyle.Background.GetBrush(r))
 | 
						|
                    g.FillPath(br, path);
 | 
						|
 | 
						|
                using (Pen pen = new Pen(cstyle.BorderColor, cstyle.BorderThickness))
 | 
						|
                {
 | 
						|
                    pen.DashStyle = (DashStyle)cstyle.BorderPattern;
 | 
						|
 | 
						|
                    g.DrawPath(pen, path);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            g.SmoothingMode = sm;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawCrosshairCallout
 | 
						|
 | 
						|
        private void DrawCrosshairCallout(Graphics g,
 | 
						|
            Rectangle t, Point pt, CrosshairVisualStyle cstyle)
 | 
						|
        {
 | 
						|
            SmoothingMode sm = g.SmoothingMode;
 | 
						|
            g.SmoothingMode = SmoothingMode.AntiAlias;
 | 
						|
 | 
						|
            using (GraphicsPath path = new GraphicsPath())
 | 
						|
            {
 | 
						|
                AddCalloutToPath(path, t, pt);
 | 
						|
 | 
						|
                Rectangle rp = Rectangle.Round(path.GetBounds());
 | 
						|
 | 
						|
                if (pt.Y > t.Y)
 | 
						|
                    rp.Y -= Dpi.Height10;
 | 
						|
 | 
						|
                rp.Height += Dpi.Height10;
 | 
						|
 | 
						|
                using (Brush br = cstyle.Background.GetBrush(rp))
 | 
						|
                    g.FillPath(br, path);
 | 
						|
 | 
						|
                using (Pen pen = new Pen(cstyle.BorderColor, cstyle.BorderThickness))
 | 
						|
                {
 | 
						|
                    pen.DashStyle = (DashStyle)cstyle.BorderPattern;
 | 
						|
 | 
						|
                    g.DrawPath(pen, path);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            g.SmoothingMode = sm;
 | 
						|
        }
 | 
						|
 | 
						|
        #region AddCalloutToPath
 | 
						|
 | 
						|
        private void AddCalloutToPath(GraphicsPath path, Rectangle t, Point pt)
 | 
						|
        {
 | 
						|
            int dia = Dpi.Width10;
 | 
						|
            Rectangle r = t;
 | 
						|
 | 
						|
            int n = Dpi.Width20;
 | 
						|
 | 
						|
            r.Width = dia;
 | 
						|
            r.Height = dia;
 | 
						|
 | 
						|
            if (pt.Y > t.Y)
 | 
						|
            {
 | 
						|
                if (pt.X < (t.X + t.Width / 2))
 | 
						|
                {
 | 
						|
                    path.AddLine(new Point(pt.X + n, pt.Y - Dpi.Width20), pt);
 | 
						|
                    path.AddLine(pt, new Point(pt.X + Dpi.Width5, pt.Y - Dpi.Width20));
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    path.AddLine(new Point(pt.X - Dpi.Width5, pt.Y - Dpi.Width20), pt);
 | 
						|
                    path.AddLine(pt, new Point(pt.X - n, pt.Y - Dpi.Width20));
 | 
						|
                }
 | 
						|
 | 
						|
 | 
						|
                r.Y += (t.Height - dia);
 | 
						|
                path.AddArc(r, 90, 90);
 | 
						|
 | 
						|
                r.Y = t.Y;
 | 
						|
                path.AddArc(r, 180, 90);
 | 
						|
 | 
						|
                r.X += (t.Width - dia);
 | 
						|
                path.AddArc(r, 270, 90);
 | 
						|
 | 
						|
                r.Y += (t.Height - dia);
 | 
						|
                path.AddArc(r, 0, 90);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                if (pt.X < (t.X + t.Width / 2))
 | 
						|
                {
 | 
						|
                    path.AddLine(new Point(pt.X + Dpi.Width5, pt.Y + Dpi.Width20), pt);
 | 
						|
                    path.AddLine(pt, new Point(pt.X + n, pt.Y + Dpi.Width20));
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    path.AddLine(new Point(pt.X - n, pt.Y + Dpi.Width20), pt);
 | 
						|
                    path.AddLine(pt, new Point(pt.X - Dpi.Width5, pt.Y + Dpi.Width20));
 | 
						|
                }
 | 
						|
 | 
						|
                r.X += (t.Width - dia);
 | 
						|
                path.AddArc(r, 270, 90);
 | 
						|
 | 
						|
                r.Y += (t.Height - dia);
 | 
						|
                path.AddArc(r, 0, 90);
 | 
						|
 | 
						|
                r.X = t.X;
 | 
						|
                path.AddArc(r, 90, 90);
 | 
						|
 | 
						|
                r.Y = t.Y;
 | 
						|
                path.AddArc(r, 180, 90);
 | 
						|
            }
 | 
						|
 | 
						|
            path.CloseFigure();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Mouse Support
 | 
						|
 | 
						|
        #region OnMouseMove
 | 
						|
 | 
						|
        protected override bool OnMouseMove(MouseEventArgs e)
 | 
						|
        {
 | 
						|
            OnMouseMoveEx(e);
 | 
						|
 | 
						|
            if (Legend.Visible == false ||
 | 
						|
                Legend.ContentBounds.Contains(e.Location) == false)
 | 
						|
            {
 | 
						|
                _CanShowCrosshairLabel = true;
 | 
						|
            }
 | 
						|
 | 
						|
            return (base.OnMouseMove(e));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region OnMouseMoveEx
 | 
						|
 | 
						|
        protected override void OnMouseMoveEx(MouseEventArgs e)
 | 
						|
        {
 | 
						|
            ChartCrosshair crosshair = ChartCrosshair;
 | 
						|
 | 
						|
            bool displayCrosshair = DisplayCrosshair;
 | 
						|
 | 
						|
            _CanShowCrosshairLabel = false;
 | 
						|
 | 
						|
            if (crosshair.Visible == false ||
 | 
						|
                (crosshair.ShowCrosshairLabels == false &&
 | 
						|
                crosshair.ShowValueXLine == false && crosshair.ShowValueYLine == false &&
 | 
						|
                crosshair.ShowValueXLabels == false && crosshair.ShowValueYLabels == false))
 | 
						|
            {
 | 
						|
                DisplayCrosshair = false;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                Rectangle bounds = GetScrollBounds(ContentBounds);
 | 
						|
 | 
						|
                if (VScrollBar.Enabled == true)
 | 
						|
                    bounds.Width -= (VScrollBar.Width + 1);
 | 
						|
 | 
						|
                if (HScrollBar.Enabled == true)
 | 
						|
                    bounds.Height -= (HScrollBar.Height + 1);
 | 
						|
 | 
						|
                DisplayCrosshair = bounds.Contains(e.Location);
 | 
						|
            }
 | 
						|
 | 
						|
            if (DisplayCrosshair == true || displayCrosshair != DisplayCrosshair)
 | 
						|
            {
 | 
						|
                if (DisplayCrosshair == false)
 | 
						|
                    _CrosshairSeriesPoints = null;
 | 
						|
 | 
						|
                InvalidateRender();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region OnMouseLeave
 | 
						|
 | 
						|
        protected override bool OnMouseLeave(EventArgs e)
 | 
						|
        {
 | 
						|
            if (DisplayCrosshair == true)
 | 
						|
            {
 | 
						|
                DisplayCrosshair = false;
 | 
						|
 | 
						|
                _CrosshairSeriesPoints = null;
 | 
						|
 | 
						|
                InvalidateRender();
 | 
						|
            }
 | 
						|
 | 
						|
            return (base.OnMouseLeave(e));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetLocalAdjustedPoint
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the local, scroll adjusted point.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pt"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        public Point GetLocalAdjustedPoint(Point pt)
 | 
						|
        {
 | 
						|
            pt.X -= ScrollOffset.X;
 | 
						|
            pt.X += (HScrollBar.Inverted == true ? HScrollOffset : -HScrollOffset);
 | 
						|
 | 
						|
            pt.Y -= ScrollOffset.Y;
 | 
						|
            pt.Y += (VScrollBar.Inverted == true ? VScrollOffset : -VScrollOffset);
 | 
						|
 | 
						|
            return (pt);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetGlobalAdjustedPoint
 | 
						|
 | 
						|
        internal Point GetGlobalAdjustedPoint(Point pt)
 | 
						|
        {
 | 
						|
            pt.X -= (HScrollBar.Inverted == true ? HScrollOffset : -HScrollOffset);
 | 
						|
            pt.Y -= (VScrollBar.Inverted == true ? VScrollOffset : -VScrollOffset);
 | 
						|
 | 
						|
            return (pt);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetScBorderThickness
 | 
						|
 | 
						|
        internal int GetScBorderThickness(XyAlignment side)
 | 
						|
        {
 | 
						|
            ChartXyVisualStyle xyStyle = EffectiveChartStyle;
 | 
						|
 | 
						|
            int n = 0;
 | 
						|
 | 
						|
            switch (side)
 | 
						|
            {
 | 
						|
                case XyAlignment.Top:
 | 
						|
                    n = (xyStyle.BorderThickness.Top);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case XyAlignment.Left:
 | 
						|
                    n = (xyStyle.BorderThickness.Left);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case XyAlignment.Bottom:
 | 
						|
                    n = (xyStyle.BorderThickness.Bottom +
 | 
						|
                        ((HScrollBar.Visible == true) ? HScrollBar.Height + 1 : 0));
 | 
						|
                    break;
 | 
						|
 | 
						|
                case XyAlignment.Right:
 | 
						|
                    n = (xyStyle.BorderThickness.Right +
 | 
						|
                        ((VScrollBar.Visible == true) ? VScrollBar.Width + 1 : 0));
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
 | 
						|
            return (Dpi.Width(n));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetPointMarker
 | 
						|
 | 
						|
        internal Image GetPointMarker(Graphics g, PointMarkerVisualStyle style)
 | 
						|
        {
 | 
						|
            Image marker = null;
 | 
						|
 | 
						|
            marker = style.GetPointMarkerImage();
 | 
						|
 | 
						|
            return (marker ?? GetPointMarkerEx(g, style));
 | 
						|
        }
 | 
						|
 | 
						|
        internal Image GetPointMarkerEx(Graphics g, PointMarkerVisualStyle style)
 | 
						|
        {
 | 
						|
            return (GetPointMarker(g, style.Type,
 | 
						|
                style.PointCount, Dpi.Size(style.Size), style.Rotation,
 | 
						|
                style.Background, style.BorderColor, style.BorderWidth));
 | 
						|
        }
 | 
						|
 | 
						|
        internal Image GetPointMarker(Graphics g, PointMarkerType markerType, int markerPoints,
 | 
						|
            Size size, int markerRotation, Background background, Color borderColor, int borderWidth)
 | 
						|
        {
 | 
						|
            if (_PointMarker == null)
 | 
						|
                _PointMarker = new PointMarker();
 | 
						|
 | 
						|
            if (markerType == PointMarkerType.None || markerType == PointMarkerType.NotSet)
 | 
						|
                markerType = PointMarkerType.Rectangle;
 | 
						|
 | 
						|
            return (_PointMarker.GetMarkerBitmap(g, markerType,
 | 
						|
                markerPoints, size, markerRotation, background, borderColor, borderWidth));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region IsCrosshairSeriesPoint
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets whether the given Point is a Crosshair displayed point.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="series"></param>
 | 
						|
        /// <param name="pt"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        public bool IsCrosshairSeriesPoint(ChartSeries series, Point pt)
 | 
						|
        {
 | 
						|
            if (_CrosshairSeriesPoints != null)
 | 
						|
            {
 | 
						|
                Rectangle r = new Rectangle(pt, Size.Empty);
 | 
						|
                r.Inflate(2, 2);
 | 
						|
 | 
						|
                foreach (CrosshairPoint chp in _CrosshairSeriesPoints)
 | 
						|
                {
 | 
						|
                    if (r.Contains(chp.Point) && (series == null || chp.ChartSeries == series))
 | 
						|
                    {
 | 
						|
                        if (chp == _NearestCrosshairPoint)
 | 
						|
                            return (true);
 | 
						|
 | 
						|
                        if (ChartCrosshair.CrosshairLabelMode != CrosshairLabelMode.NearestSeries)
 | 
						|
                            return (true);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (false);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region UpdateRangeValues
 | 
						|
 | 
						|
        private void UpdateRangeValues()
 | 
						|
        {
 | 
						|
            if (SeriesRangeChanged == true)
 | 
						|
            {
 | 
						|
                SeriesRangeChanged = false;
 | 
						|
 | 
						|
                InvalidatePointLabelsEx();
 | 
						|
 | 
						|
                _MinValueX = null;
 | 
						|
                _MaxValueX = null;
 | 
						|
                _MinValueY = null;
 | 
						|
                _MaxValueY = null;
 | 
						|
 | 
						|
                foreach (ChartSeries series in ChartSeries)
 | 
						|
                {
 | 
						|
                    if (_MinValueX == null)
 | 
						|
                    {
 | 
						|
                        _MinValueX = series.MinValueX;
 | 
						|
                        _MaxValueX = series.MaxValueX;
 | 
						|
                        _MinValueY = series.MinValueY;
 | 
						|
                        _MaxValueY = series.MaxValueY;
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        if (series.MinValueX != null)
 | 
						|
                        {
 | 
						|
                            if (DataCompare(series.MinValueX, _MinValueX) < 0)
 | 
						|
                                _MinValueX = series.MinValueX;
 | 
						|
 | 
						|
                            else if (DataCompare(series.MaxValueX, _MaxValueX) > 0)
 | 
						|
                                _MaxValueX = series.MaxValueX;
 | 
						|
 | 
						|
                            if (DataCompare(series.MinValueY, _MinValueY) < 0)
 | 
						|
                                _MinValueY = series.MinValueY;
 | 
						|
 | 
						|
                            else if (DataCompare(series.MaxValueY, _MaxValueY) > 0)
 | 
						|
                                _MaxValueY = series.MaxValueY;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
 | 
						|
                    ChartAxis axis = series.AxisX ?? AxisX;
 | 
						|
 | 
						|
                    if (axis != null)
 | 
						|
                        axis.SeriesRangeChanged = true;
 | 
						|
 | 
						|
                    axis = series.AxisY ?? AxisY;
 | 
						|
 | 
						|
                    if (axis != null)
 | 
						|
                        axis.SeriesRangeChanged = true;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetPointFromValue
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the chart Point, given the provided SeriesPoint.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="series"></param>
 | 
						|
        /// <param name="sp"></param>
 | 
						|
        /// <param name="dy"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        public Point GetPointFromValue(ChartSeries series, SeriesPoint sp)
 | 
						|
        {
 | 
						|
            Point pt = GetDataPointNa(series, sp, 0);
 | 
						|
 | 
						|
            return (GetLocalAdjustedPoint(pt));
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the chart Point, given the X and Y data point values.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="series"></param>
 | 
						|
        /// <param name="pointValueX"></param>
 | 
						|
        /// <param name="pointValueY"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        public Point GetPointFromValue(ChartSeries series, object pointValueX, object pointValueY)
 | 
						|
        {
 | 
						|
            Point pt = Point.Empty;
 | 
						|
 | 
						|
            ChartAxis axisX = series.AxisX ?? AxisX;
 | 
						|
            ChartAxis axisY = series.AxisY ?? AxisY;
 | 
						|
 | 
						|
            pt.X = GetDataPointX(axisX, pointValueX) + series.PointOffset.X;
 | 
						|
            pt.Y = GetDataPointY(axisY, pointValueY);
 | 
						|
 | 
						|
            return (pt);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDataPoint
 | 
						|
 | 
						|
        internal Point GetDataPoint(ChartSeries series, SeriesPoint sp, int dy)
 | 
						|
        {
 | 
						|
            Point pt = GetDataPointNa(series, sp, dy);
 | 
						|
 | 
						|
            return (GetLocalAdjustedPoint(pt));
 | 
						|
        }
 | 
						|
 | 
						|
        internal Point GetDataPointNa(ChartSeries series, SeriesPoint sp, int dy)
 | 
						|
        {
 | 
						|
            if (sp.SeriesValidationCount != SeriesPointCount)
 | 
						|
            {
 | 
						|
                sp.InvalidatePoints();
 | 
						|
 | 
						|
                sp.SeriesValidationCount = SeriesPointCount;
 | 
						|
            }
 | 
						|
 | 
						|
            int n = (dy < 0) ? 0 : dy;
 | 
						|
 | 
						|
            if (sp.Point.Length > n)
 | 
						|
            {
 | 
						|
                if (sp.Point[n].IsEmpty == true)
 | 
						|
                {
 | 
						|
                    sp.Point[n] = GetDataPointEx(series, sp, dy);
 | 
						|
 | 
						|
                    if (sp.Point[n].IsEmpty == true)
 | 
						|
                        return (Point.Empty);
 | 
						|
                }
 | 
						|
 | 
						|
                return (sp.Point[n]);
 | 
						|
            }
 | 
						|
 | 
						|
            return (Point.Empty);
 | 
						|
        }
 | 
						|
 | 
						|
        internal Point GetDataPointEx(ChartSeries series, SeriesPoint sp, int dy)
 | 
						|
        {
 | 
						|
            object pointValueX = sp.ValueX;
 | 
						|
            object pointValueY = 0;
 | 
						|
 | 
						|
            if (dy >= 0)
 | 
						|
            {
 | 
						|
                if (sp.ValueY != null && sp.ValueY.Length > dy)
 | 
						|
                    pointValueY = sp.ValueY[dy];
 | 
						|
            }
 | 
						|
 | 
						|
            if (series.IsRotated == true)
 | 
						|
                return (GetPointFromValue(series, pointValueY, pointValueX));
 | 
						|
 | 
						|
            return (GetPointFromValue(series, pointValueX, pointValueY));
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetDataPointX
 | 
						|
 | 
						|
        internal int GetDataPointX(ChartAxis axis, object pointValueX)
 | 
						|
        {
 | 
						|
            TickmarkLayout layoutX = axis.TickmarkLayout;
 | 
						|
 | 
						|
            if (layoutX.Ticks != null)
 | 
						|
            {
 | 
						|
                Rectangle tmBoundsX = axis.MajorTickmarks.TickmarkBounds;
 | 
						|
 | 
						|
                int minOffset;
 | 
						|
                int majOffset = GetDataOffsetX(axis, layoutX, pointValueX, out minOffset);
 | 
						|
 | 
						|
                return ((tmBoundsX.X + majOffset - layoutX.MarginOffset) + minOffset);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                Rectangle r = ScrollBounds;
 | 
						|
 | 
						|
                return (int)(r.Left);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetDataOffsetX
 | 
						|
 | 
						|
        private int GetDataOffsetX(ChartAxis axis,
 | 
						|
            TickmarkLayout layout, object pointValue, out int minOffset)
 | 
						|
        {
 | 
						|
            double ptValue;
 | 
						|
 | 
						|
            switch (axis.ScaleType)
 | 
						|
            {
 | 
						|
                case ScaleType.Qualitative:
 | 
						|
                    ptValue = axis.QualitativeValues.IndexOf(pointValue) - Convert.ToInt32(layout.BaseValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case ScaleType.DateTime:
 | 
						|
                    ptValue = GetDateTimePointValue(axis, layout, (DateTime)pointValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                default:
 | 
						|
                    try
 | 
						|
                    {
 | 
						|
                        ptValue = Convert.ToDouble(pointValue) - Convert.ToDouble(layout.BaseValue);
 | 
						|
                    }
 | 
						|
                    catch
 | 
						|
                    {
 | 
						|
                        minOffset = 0;
 | 
						|
 | 
						|
                        return (0);
 | 
						|
                    }
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
 | 
						|
            int n = (int)(ptValue / layout.MajorSpacing);
 | 
						|
            int p1 = (int)(n * layout.MajorInterval);
 | 
						|
            int p2 = (int)((n + 1) * layout.MajorInterval);
 | 
						|
 | 
						|
            double minorValue = (ptValue - (n * layout.MajorSpacing));
 | 
						|
            minOffset = (int)(((p2 - p1) * minorValue) / layout.MajorSpacing);
 | 
						|
 | 
						|
            return (p1);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDataPointY
 | 
						|
 | 
						|
        internal int GetDataPointY(ChartAxis axis, object pointValueY)
 | 
						|
        {
 | 
						|
            TickmarkLayout layoutY = axis.TickmarkLayout;
 | 
						|
 | 
						|
            if (layoutY.Ticks != null)
 | 
						|
            {
 | 
						|
                Rectangle tmBoundsY = axis.MajorTickmarks.TickmarkBounds;
 | 
						|
 | 
						|
                int minOffset;
 | 
						|
                int majOffset = GetDataOffsetY(axis, layoutY, pointValueY, out minOffset);
 | 
						|
 | 
						|
                return (((tmBoundsY.Bottom - 1) - majOffset + layoutY.MarginOffset) - minOffset);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                Rectangle r = ScrollBounds;
 | 
						|
 | 
						|
                if (HScrollBar.Enabled == true)
 | 
						|
                    r.Height -= HScrollBar.Height;
 | 
						|
 | 
						|
                return (int)(r.Bottom - 1);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetDataOffsetY
 | 
						|
 | 
						|
        private int GetDataOffsetY(ChartAxis axis,
 | 
						|
            TickmarkLayout layout, object pointValue, out int minOffset)
 | 
						|
        {
 | 
						|
            double ptValue;
 | 
						|
 | 
						|
            switch (axis.ScaleType)
 | 
						|
            {
 | 
						|
                case ScaleType.Qualitative:
 | 
						|
                    ptValue = axis.QualitativeValues.IndexOf(pointValue) - Convert.ToInt32(layout.BaseValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case ScaleType.DateTime:
 | 
						|
                    ptValue = GetDateTimePointValue(axis, layout, (DateTime)pointValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                default:
 | 
						|
                    try
 | 
						|
                    {
 | 
						|
                        ptValue = Convert.ToDouble(pointValue) - Convert.ToDouble(layout.BaseValue);
 | 
						|
                    }
 | 
						|
                    catch
 | 
						|
                    {
 | 
						|
                        minOffset = 0;
 | 
						|
 | 
						|
                        return (0);
 | 
						|
                    }
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
 | 
						|
            int n = (int)(ptValue / layout.MajorSpacing);
 | 
						|
            int p1 = (int)Math.Ceiling(n * layout.MajorInterval);
 | 
						|
            int p2 = (int)Math.Ceiling((n + 1) * layout.MajorInterval);
 | 
						|
 | 
						|
            double minorValue = (ptValue - (n * layout.MajorSpacing));
 | 
						|
            minOffset = (int)Math.Ceiling(((p2 - p1) * minorValue) / layout.MajorSpacing);
 | 
						|
 | 
						|
            return (p1);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDateTimePointValue
 | 
						|
 | 
						|
        internal double GetDateTimePointValue(
 | 
						|
            ChartAxis axis, TickmarkLayout layout, DateTime dt)
 | 
						|
        {
 | 
						|
            return (GetDateTimePointValue(axis, layout, dt, (DateTime)layout.BaseValue));
 | 
						|
        }
 | 
						|
 | 
						|
        internal double GetDateTimePointValue(
 | 
						|
            ChartAxis axis, TickmarkLayout layout, DateTime dt, DateTime baseValue)
 | 
						|
        {
 | 
						|
            TimeSpan ts = dt - baseValue;
 | 
						|
 | 
						|
            DateTimeUnits adtu = axis.ActualDateTimeUnits;
 | 
						|
 | 
						|
            switch (adtu)
 | 
						|
            {
 | 
						|
                case DateTimeUnits.Ticks:
 | 
						|
                    return (ts.Ticks);
 | 
						|
 | 
						|
                case DateTimeUnits.Milliseconds:
 | 
						|
                    return (ts.TotalMilliseconds);
 | 
						|
 | 
						|
                case DateTimeUnits.Seconds:
 | 
						|
                    return (ts.TotalSeconds);
 | 
						|
 | 
						|
                case DateTimeUnits.Minutes:
 | 
						|
                    return (ts.TotalMinutes);
 | 
						|
 | 
						|
                case DateTimeUnits.Hours:
 | 
						|
                    return (ts.TotalHours);
 | 
						|
 | 
						|
                case DateTimeUnits.Days:
 | 
						|
                    return (ts.TotalDays);
 | 
						|
 | 
						|
                case DateTimeUnits.Months:
 | 
						|
                    return (axis.CalcDateTimeMonths(baseValue, dt));
 | 
						|
 | 
						|
                default:
 | 
						|
                    return (axis.CalcDateTimeYears(baseValue, dt));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDataPointValueX
 | 
						|
 | 
						|
        internal object GetDataPointValueX(ChartSeries series, SeriesPoint sp)
 | 
						|
        {
 | 
						|
            ChartAxis axisX = series.AxisX ?? AxisX;
 | 
						|
 | 
						|
            switch (axisX.ScaleType)
 | 
						|
            {
 | 
						|
                case ScaleType.Qualitative:
 | 
						|
                    return (axisX.QualitativeValues.IndexOf(sp.ValueX));
 | 
						|
 | 
						|
                default:
 | 
						|
                    return (sp.ValueX);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDataPointValueY
 | 
						|
 | 
						|
        internal double GetDataPointValueY(ChartSeries series, SeriesPoint sp, int dy)
 | 
						|
        {
 | 
						|
            if (dy >= 0)
 | 
						|
            {
 | 
						|
                if (sp.IsQuantitativeYValue == true)
 | 
						|
                {
 | 
						|
                    if (sp.ValueY != null && sp.ValueY.Length > dy)
 | 
						|
                        return (Convert.ToDouble(sp.ValueY[dy]));
 | 
						|
 | 
						|
                    return (1);
 | 
						|
                }
 | 
						|
 | 
						|
                ChartAxis axisY = series.AxisY ?? AxisY;
 | 
						|
 | 
						|
                return (axisY.QualitativeValues.IndexOf(sp.ValueY[dy]));
 | 
						|
            }
 | 
						|
 | 
						|
            return (0);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetQualitativeColumnWidth
 | 
						|
 | 
						|
        internal int GetQualitativeColumnWidth(ChartAxis axis, int groupId)
 | 
						|
        {
 | 
						|
            ChartXyVisualStyle cstyle = EffectiveChartStyle;
 | 
						|
 | 
						|
            List<ChartSeries> slist = GetQualitativeSeriesList(axis, groupId);
 | 
						|
 | 
						|
            int width = 0;
 | 
						|
            int swidth = 0;
 | 
						|
 | 
						|
            int count = 0;
 | 
						|
 | 
						|
            foreach (ChartSeries series in slist)
 | 
						|
            {
 | 
						|
                Size size;
 | 
						|
 | 
						|
                if (series.PointMarkerImage != null)
 | 
						|
                    size = series.PointMarkerImage.Size;
 | 
						|
                else
 | 
						|
                    size = series.EffectiveChartSeriesStyle.MarkerVisualStyle.Size;
 | 
						|
 | 
						|
                if (series.StackQualitativePoints == false)
 | 
						|
                {
 | 
						|
                    count++;
 | 
						|
                    width += size.Width;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    swidth = Math.Max(swidth, size.Width);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            width += swidth;
 | 
						|
 | 
						|
            if (count > 1)
 | 
						|
                width += ((count - 1) * cstyle.IntraSeriesGap);
 | 
						|
 | 
						|
            int offset = -width / 2;
 | 
						|
 | 
						|
            if (swidth > 0)
 | 
						|
            {
 | 
						|
                Point pt = new Point(offset + swidth / 2, 0);
 | 
						|
 | 
						|
                foreach (ChartSeries series in slist)
 | 
						|
                {
 | 
						|
                    if (series.StackQualitativePoints == true)
 | 
						|
                        series.PointOffset = pt;
 | 
						|
                }
 | 
						|
 | 
						|
                offset += (swidth + cstyle.IntraSeriesGap);
 | 
						|
            }
 | 
						|
 | 
						|
            foreach (ChartSeries series in slist)
 | 
						|
            {
 | 
						|
                if (series.StackQualitativePoints == false)
 | 
						|
                {
 | 
						|
                    Size size;
 | 
						|
 | 
						|
                    if (series.PointMarkerImage != null)
 | 
						|
                        size = series.PointMarkerImage.Size;
 | 
						|
                    else
 | 
						|
                        size = series.EffectiveChartSeriesStyle.MarkerVisualStyle.Size;
 | 
						|
 | 
						|
                    series.PointOffset = new Point(offset + size.Width / 2 + 1, 0);
 | 
						|
 | 
						|
                    offset += (size.Width + cstyle.IntraSeriesGap);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            width += (cstyle.InterSeriesGap * 2);
 | 
						|
 | 
						|
            return (width);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region AdjustQualitativeOffsets
 | 
						|
 | 
						|
        internal void AdjustQualitativeOffsets(ChartAxis axis, int groupId, int colWidth, int interval)
 | 
						|
        {
 | 
						|
            ChartXyVisualStyle cstyle = EffectiveChartStyle;
 | 
						|
 | 
						|
            if (cstyle.AutoExpandIntraSeriesGap == Tbool.True)
 | 
						|
            {
 | 
						|
                List<ChartSeries> slist = GetQualitativeSeriesList(axis, groupId);
 | 
						|
 | 
						|
                interval -= cstyle.InterSeriesGap;
 | 
						|
 | 
						|
                int count = 0;
 | 
						|
 | 
						|
                foreach (ChartSeries series in slist)
 | 
						|
                {
 | 
						|
                    if (series.StackQualitativePoints == false)
 | 
						|
                        count++;
 | 
						|
                }
 | 
						|
 | 
						|
                if (count > 1)
 | 
						|
                {
 | 
						|
                    if (interval > colWidth)
 | 
						|
                    {
 | 
						|
                        int offset = (interval - colWidth);
 | 
						|
                        int dv = offset / count;
 | 
						|
 | 
						|
                        offset = offset / 2 - dv / 2;
 | 
						|
 | 
						|
                        foreach (ChartSeries series in slist)
 | 
						|
                        {
 | 
						|
                            Point pt = series.PointOffset;
 | 
						|
 | 
						|
                            if (axis.AxisOrientation == AxisOrientation.X)
 | 
						|
                                pt.X -= offset;
 | 
						|
                            else
 | 
						|
                                pt.Y -= offset;
 | 
						|
 | 
						|
                            series.PointOffset = pt;
 | 
						|
 | 
						|
                            if (series.StackQualitativePoints == false)
 | 
						|
                                offset -= dv;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetQualitativeSeriesList
 | 
						|
 | 
						|
        private List<ChartSeries> GetQualitativeSeriesList(ChartAxis axis, int groupId)
 | 
						|
        {
 | 
						|
            List<ChartSeries> slist = new List<ChartSeries>();
 | 
						|
 | 
						|
            if (axis.ScaleType == ScaleType.Qualitative)
 | 
						|
            {
 | 
						|
                foreach (ChartSeries series in ChartSeries)
 | 
						|
                {
 | 
						|
                    if (series.Visible == true && series.GroupId == groupId)
 | 
						|
                    {
 | 
						|
                        if (Legend.Visible == false ||
 | 
						|
                            (series.ShowCheckBoxInLegend == false || series.CheckedInLegend == true))
 | 
						|
                        {
 | 
						|
                            if (axis.AxisOrientation == AxisOrientation.X)
 | 
						|
                            {
 | 
						|
                                if (series.AxisX == axis || (series.AxisX == null && axis.IsPrimaryAxis))
 | 
						|
                                    slist.Add(series);
 | 
						|
                            }
 | 
						|
                            else
 | 
						|
                            {
 | 
						|
                                if (series.AxisY == axis || (series.AxisY == null && axis.IsPrimaryAxis))
 | 
						|
                                    slist.Add(series);
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (slist);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetChartBubbleData
 | 
						|
 | 
						|
        internal int GetChartBubbleData(out double min, out double max)
 | 
						|
        {
 | 
						|
            int count = 0;
 | 
						|
 | 
						|
            min = double.MaxValue;
 | 
						|
            max = double.MinValue;
 | 
						|
 | 
						|
            foreach (ChartSeries series in ChartSeries)
 | 
						|
            {
 | 
						|
                if (series.Visible == true)
 | 
						|
                {
 | 
						|
                    BubblePlotData bpd = series.PlotData as BubblePlotData;
 | 
						|
 | 
						|
                    if (bpd != null)
 | 
						|
                    {
 | 
						|
                        int n = series.SeriesPoints.Count;
 | 
						|
                        count += n;
 | 
						|
 | 
						|
                        double size = bpd.MinSize;
 | 
						|
 | 
						|
                        if (size < min)
 | 
						|
                            min = size;
 | 
						|
 | 
						|
                        size = bpd.MaxSize;
 | 
						|
 | 
						|
                        if (size > max)
 | 
						|
                            max = size;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (count);
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetMaxDotPlotMarkerSize
 | 
						|
 | 
						|
        internal Size GetMaxDotPlotMarkerSize()
 | 
						|
        {
 | 
						|
            Size size = Size.Empty;
 | 
						|
 | 
						|
            foreach (ChartSeries series in ChartSeries)
 | 
						|
            {
 | 
						|
                if (series.Visible == true)
 | 
						|
                {
 | 
						|
                    Image marker = series.PointMarkerImage;
 | 
						|
 | 
						|
                    if (marker != null)
 | 
						|
                    {
 | 
						|
                        if (marker.Size.Width > size.Width)
 | 
						|
                            size.Width = marker.Size.Width;
 | 
						|
 | 
						|
                        if (marker.Size.Height > size.Height)
 | 
						|
                            size.Height = marker.Size.Height;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (size);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDotPlotTypes
 | 
						|
 | 
						|
        internal DotPlotType GetDotPlotTypes()
 | 
						|
        {
 | 
						|
            DotPlotType types = DotPlotType.None;
 | 
						|
 | 
						|
            foreach (ChartSeries series in ChartSeries)
 | 
						|
            {
 | 
						|
                if (series.Visible == true)
 | 
						|
                {
 | 
						|
                    if (series.SeriesType == SeriesType.VerticalDot)
 | 
						|
                        types |= DotPlotType.Vertical;
 | 
						|
 | 
						|
                    else if (series.SeriesType == SeriesType.HorizontalDot)
 | 
						|
                        types |= DotPlotType.Horizontal;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (types);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetBaseSeries
 | 
						|
 | 
						|
        internal override ChartBaseSeriesCollection GetBaseSeries()
 | 
						|
        {
 | 
						|
            ChartBaseSeriesCollection baseSeries = new ChartBaseSeriesCollection();
 | 
						|
 | 
						|
            foreach (BaseSeries series in ChartSeries)
 | 
						|
                baseSeries.Add(series);
 | 
						|
 | 
						|
            return (baseSeries);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetSeriesByName
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the chart series with the given Name.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="name"></param>
 | 
						|
        /// <returns>ChartSeries or null.</returns>
 | 
						|
        public ChartSeries GetSeriesByName(string name)
 | 
						|
        {
 | 
						|
            if (String.IsNullOrEmpty(name) == true)
 | 
						|
                return (null);
 | 
						|
 | 
						|
            foreach (ChartSeries series in ChartSeries)
 | 
						|
            {
 | 
						|
                if (name.Equals(series.Name) == true)
 | 
						|
                    return (series);
 | 
						|
            }
 | 
						|
 | 
						|
            return (null);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetAutoGenSeriesType
 | 
						|
 | 
						|
        internal override SeriesType GetAutoGenSeriesType()
 | 
						|
        {
 | 
						|
            return (AutoGenSeriesType);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetAutoGenSeriesNameCount
 | 
						|
 | 
						|
        internal override int GetAutoGenSeriesNameCount()
 | 
						|
        {
 | 
						|
            return (AutoGenSeriesType == SeriesType.Bubble ? 2 : 1);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetNewSeries
 | 
						|
 | 
						|
        internal override BaseSeries GetNewSeries()
 | 
						|
        {
 | 
						|
            return (new ChartSeries(AutoGenSeriesType));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region AddChartSeries
 | 
						|
 | 
						|
        internal override void AddChartSeries(BaseSeries series)
 | 
						|
        {
 | 
						|
            ChartSeries.Add((ChartSeries)series);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Style handling
 | 
						|
 | 
						|
        #region ApplyStyles
 | 
						|
 | 
						|
        public override void ApplyStyles(BaseVisualStyle style)
 | 
						|
        {
 | 
						|
            base.ApplyStyles(style);
 | 
						|
 | 
						|
            ChartXyVisualStyle xyStyle = style as ChartXyVisualStyle;
 | 
						|
 | 
						|
            if (xyStyle != null)
 | 
						|
            {
 | 
						|
                ApplyParentStyles(xyStyle, Parent as ChartContainer);
 | 
						|
 | 
						|
                xyStyle.ApplyStyle(ChartVisualStyle);
 | 
						|
 | 
						|
                xyStyle.ApplyDefaults();
 | 
						|
            }
 | 
						|
            else if (style is ChartSeriesVisualStyle)
 | 
						|
            {
 | 
						|
                ChartSeriesVisualStyle sstyle = (ChartSeriesVisualStyle)style;
 | 
						|
 | 
						|
                ApplyParentStyles(sstyle, Parent as ChartContainer);
 | 
						|
 | 
						|
                sstyle.ApplyStyle(_ChartSeriesVisualStyle);
 | 
						|
 | 
						|
                sstyle.ApplyDefaults();
 | 
						|
            }
 | 
						|
            else if (style is DataLabelVisualStyle)
 | 
						|
            {
 | 
						|
                DataLabelVisualStyle dstyle = style as DataLabelVisualStyle;
 | 
						|
 | 
						|
                if (dstyle != null)
 | 
						|
                {
 | 
						|
                    ApplyParentStyles(dstyle, Parent as ChartContainer);
 | 
						|
 | 
						|
                    dstyle.ApplyStyle(_DataLabelVisualStyle);
 | 
						|
 | 
						|
                    dstyle.ApplyDefaults();
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region ApplyParentStyles
 | 
						|
 | 
						|
        private void ApplyParentStyles(ChartXyVisualStyle pstyle, ChartContainer item)
 | 
						|
        {
 | 
						|
            if (item != null)
 | 
						|
            {
 | 
						|
                ApplyParentStyles(pstyle, item.Parent as ChartContainer);
 | 
						|
 | 
						|
                if (item is ChartPanel)
 | 
						|
                    pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.ChartXyVisualStyle);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                pstyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartXyVisualStyle);
 | 
						|
                pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartXyVisualStyle);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ApplyParentStyles (ChartSeriesVisualStyle)
 | 
						|
 | 
						|
        private void ApplyParentStyles(ChartSeriesVisualStyle pstyle, ChartContainer item)
 | 
						|
        {
 | 
						|
            if (item != null)
 | 
						|
            {
 | 
						|
                ApplyParentStyles(pstyle, item.Parent as ChartContainer);
 | 
						|
 | 
						|
                if (item is ChartPanel)
 | 
						|
                    pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.ChartSeriesVisualStyle);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                pstyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartSeriesVisualStyle);
 | 
						|
                pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartSeriesVisualStyle);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ApplyParentStyles (DataLabelVisualStyle)
 | 
						|
 | 
						|
        private void ApplyParentStyles(DataLabelVisualStyle pstyle, ChartContainer item)
 | 
						|
        {
 | 
						|
            if (item != null)
 | 
						|
            {
 | 
						|
                ApplyParentStyles(pstyle, item.Parent as ChartContainer);
 | 
						|
 | 
						|
                if (item is ChartPanel)
 | 
						|
                    pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.DataLabelVisualStyle);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                pstyle.ApplyStyle(ChartControl.BaseVisualStyles.DataLabelVisualStyle);
 | 
						|
                pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.DataLabelVisualStyle);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ClearEffectiveStyles
 | 
						|
 | 
						|
        protected override void ClearEffectiveStyles()
 | 
						|
        {
 | 
						|
            _EffectiveChartStyle.InvalidateStyle();
 | 
						|
            _EffectiveChartSeriesStyle.InvalidateStyle();
 | 
						|
 | 
						|
            if (_EffectiveDataLabelStyle.InvalidateStyle() == true)
 | 
						|
                InvalidateLayout();
 | 
						|
 | 
						|
            base.ClearEffectiveStyles();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region InvalidateLayoutBounds
 | 
						|
 | 
						|
        public override void InvalidateLayoutBounds(ScrollBarLite sbar)
 | 
						|
        {
 | 
						|
            base.InvalidateLayoutBounds(sbar);
 | 
						|
 | 
						|
            if (sbar != null)
 | 
						|
            {
 | 
						|
                Rectangle contentBounds = GetScrollBounds(ContentBounds);
 | 
						|
                InvalidateRender(contentBounds);
 | 
						|
 | 
						|
                if (sbar.Orientation == Orientation.Horizontal)
 | 
						|
                    InvalidateAxes(AncillaryAxesX, AxisX);
 | 
						|
                else
 | 
						|
                    InvalidateAxes(AncillaryAxesY, AxisY);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region InvalidateAxes
 | 
						|
 | 
						|
        private void InvalidateAxes(ChartAxesCollection axes, ChartAxis axis)
 | 
						|
        {
 | 
						|
            foreach (ChartAxis ca in axes)
 | 
						|
            {
 | 
						|
                if (ca.Visible == true)
 | 
						|
                {
 | 
						|
                    Rectangle bounds = ca.GetScrollBounds(ca.AxisBounds);
 | 
						|
 | 
						|
                    ca.InvalidateRender(bounds);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            if (axis.Visible == true)
 | 
						|
            {
 | 
						|
                Rectangle bounds = axis.GetScrollBounds(axis.AxisBounds);
 | 
						|
 | 
						|
                axis.InvalidateRender(bounds);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region InvalidateSeriesPoints
 | 
						|
 | 
						|
        private void InvalidateSeriesPoints()
 | 
						|
        {
 | 
						|
            SeriesPointCount++;
 | 
						|
 | 
						|
            foreach (ChartSeries series in ChartSeries)
 | 
						|
                series.InvalidatePoints();
 | 
						|
 | 
						|
            InvalidatePointLabelsEx();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region InvalidatePointLabels
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Invalidate the cached PointLabels
 | 
						|
        /// </summary>
 | 
						|
        public void InvalidatePointLabels()
 | 
						|
        {
 | 
						|
            InvalidatePointLabelsEx();
 | 
						|
            InvalidateRender();
 | 
						|
        }
 | 
						|
 | 
						|
        internal void InvalidatePointLabelsEx()
 | 
						|
        {
 | 
						|
            _PointLabels = null;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetLegendData
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the list of chart legend data.
 | 
						|
        /// </summary>
 | 
						|
        /// <returns></returns>
 | 
						|
        public override List<ChartLegendItem> GetLegendData()
 | 
						|
        {
 | 
						|
            base.GetLegendData();
 | 
						|
 | 
						|
            GetAxesLegendData(AncillaryAxesX, AxisX);
 | 
						|
            GetAxesLegendData(AncillaryAxesY, AxisY);
 | 
						|
 | 
						|
            return (LegendData);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetAxesLegendData
 | 
						|
 | 
						|
        private void GetAxesLegendData(ChartAxesCollection axes, ChartAxis axis)
 | 
						|
        {
 | 
						|
            for (int i = axes.Count - 1; i >= 0; i--)
 | 
						|
            {
 | 
						|
                ChartAxis ca = axes[i];
 | 
						|
 | 
						|
                if (ca.Visible == true)
 | 
						|
                    ca.GetLegendData(LegendData);
 | 
						|
            }
 | 
						|
 | 
						|
            if (axis.Visible == true)
 | 
						|
                axis.GetLegendData(LegendData);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetHitArea
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the hit area for the chart.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pt"></param>
 | 
						|
        /// <returns>ItemHitArea</returns>
 | 
						|
        public override ItemHitArea GetHitArea(Point pt)
 | 
						|
        {
 | 
						|
            if (AxisX.Bounds.Contains(pt))
 | 
						|
                return (ItemHitArea.InPrimaryAxisX);
 | 
						|
 | 
						|
            if (AxisY.Bounds.Contains(pt))
 | 
						|
                return (ItemHitArea.InPrimaryAxisY);
 | 
						|
 | 
						|
            foreach (ChartAxis axis in AncillaryAxesX)
 | 
						|
            {
 | 
						|
                if (axis.Bounds.Contains(pt))
 | 
						|
                    return (ItemHitArea.InAncillaryAxisX);
 | 
						|
            }
 | 
						|
 | 
						|
            foreach (ChartAxis axis in AncillaryAxesY)
 | 
						|
            {
 | 
						|
                if (axis.Bounds.Contains(pt))
 | 
						|
                    return (ItemHitArea.InAncillaryAxisY);
 | 
						|
            }
 | 
						|
 | 
						|
            return (base.GetHitArea(pt));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Copy/CopyTo
 | 
						|
 | 
						|
        public override ChartVisualElement Copy()
 | 
						|
        {
 | 
						|
            ChartXy copy = new ChartXy();
 | 
						|
 | 
						|
            CopyTo(copy);
 | 
						|
 | 
						|
            return (copy);
 | 
						|
        }
 | 
						|
 | 
						|
        public override void CopyTo(ChartVisualElement copy)
 | 
						|
        {
 | 
						|
            ChartXy c = copy as ChartXy;
 | 
						|
 | 
						|
            if (c != null)
 | 
						|
            {
 | 
						|
                base.CopyTo(c);
 | 
						|
 | 
						|
                foreach (ChartAxisX axis in AncillaryAxesX)
 | 
						|
                    c.AncillaryAxesX.Add((ChartAxisX)axis.Copy());
 | 
						|
 | 
						|
                foreach (ChartAxisY axis in AncillaryAxesY)
 | 
						|
                    c.AncillaryAxesY.Add((ChartAxisY)axis.Copy());
 | 
						|
 | 
						|
                c.AutoGenSeriesType = AutoGenSeriesType;
 | 
						|
 | 
						|
                AxisX.CopyTo(c.AxisX);
 | 
						|
                AxisY.CopyTo(c.AxisY);
 | 
						|
 | 
						|
                c.BarFillRange = BarFillRange;
 | 
						|
                c.BarLabelPosition = BarLabelPosition;
 | 
						|
                c.BarOrigin = BarOrigin;
 | 
						|
                c.BarOverlayEnabled = BarOverlayEnabled;
 | 
						|
                c.BarShadingEnabled = BarShadingEnabled;
 | 
						|
                c.BarSpacing = BarSpacing;
 | 
						|
                c.BarSpacingRatio = BarSpacingRatio;
 | 
						|
                c.BarWidthRatio = BarWidthRatio;
 | 
						|
 | 
						|
                c.BubbleIntensityMode = BubbleIntensityMode;
 | 
						|
                c.BubbleSizeMode = BubbleSizeMode;
 | 
						|
 | 
						|
                c.ChartLineAreaDisplayMode = ChartLineAreaDisplayMode;
 | 
						|
                c.ChartLineDisplayMode = ChartLineDisplayMode;
 | 
						|
 | 
						|
                foreach (ChartSeries series in ChartSeries)
 | 
						|
                    c.ChartSeries.Add((ChartSeries)series.Copy());
 | 
						|
 | 
						|
                c.ChartSeriesVisualStyle =
 | 
						|
                    (_ChartSeriesVisualStyle != null) ? _ChartSeriesVisualStyle.Copy() : null;
 | 
						|
 | 
						|
                c.ChartVisualStyle = (_ChartVisualStyle != null) ? ChartVisualStyle.Copy() : null;
 | 
						|
 | 
						|
                c.ConvexHullDisplayMode = ConvexHullDisplayMode;
 | 
						|
 | 
						|
                ChartCrosshair.CopyTo(c.ChartCrosshair);
 | 
						|
 | 
						|
                c.DataLabelOverlapMode = DataLabelOverlapMode;
 | 
						|
 | 
						|
                c.DataLabelVisualStyle =
 | 
						|
                    (_DataLabelVisualStyle != null) ? _DataLabelVisualStyle.Copy() : null;
 | 
						|
 | 
						|
                c.PointLabelDisplayMode = PointLabelDisplayMode;
 | 
						|
                c.SeriesDisplayOrder = SeriesDisplayOrder;
 | 
						|
 | 
						|
                c.StepLines = StepLines;
 | 
						|
                c.StepLineMode = StepLineMode;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetSerialData
 | 
						|
 | 
						|
        internal override SerialElementCollection GetSerialData(string serialName)
 | 
						|
        {
 | 
						|
            SerialElementCollection sec = new SerialElementCollection();
 | 
						|
 | 
						|
            if (serialName != null)
 | 
						|
            {
 | 
						|
                if (serialName.Equals("") == true)
 | 
						|
                    serialName = "ChartXy";
 | 
						|
 | 
						|
                sec.AddStartElement(serialName);
 | 
						|
            }
 | 
						|
 | 
						|
            if (_AncillaryAxesX != null && _AncillaryAxesX.Count > 0)
 | 
						|
            {
 | 
						|
                sec.AddStartElement("AncillaryAxesX count=\"" + _AncillaryAxesX.Count + "\"");
 | 
						|
 | 
						|
                foreach (ChartAxisX axis in _AncillaryAxesX)
 | 
						|
                    sec.AddElement(axis.GetSerialData("ChartAxisX"));
 | 
						|
 | 
						|
                sec.AddEndElement("AncillaryAxesX");
 | 
						|
            }
 | 
						|
 | 
						|
            if (_AncillaryAxesY != null && _AncillaryAxesY.Count > 0)
 | 
						|
            {
 | 
						|
                sec.AddStartElement("AncillaryAxesY count=\"" + _AncillaryAxesY.Count + "\"");
 | 
						|
 | 
						|
                foreach (ChartAxisY axis in _AncillaryAxesY)
 | 
						|
                    sec.AddElement(axis.GetSerialData("ChartAxisY"));
 | 
						|
 | 
						|
                sec.AddEndElement("AncillaryAxesY");
 | 
						|
            }
 | 
						|
 | 
						|
            sec.AddValue("AutoGenSeriesType", AutoGenSeriesType, SeriesType.Point);
 | 
						|
 | 
						|
            if (AxisX != null)
 | 
						|
                sec.AddElement(AxisX.GetSerialData("AxisX"));
 | 
						|
 | 
						|
            if (AxisY != null)
 | 
						|
                sec.AddElement(AxisY.GetSerialData("AxisY"));
 | 
						|
 | 
						|
            sec.AddValue("BarFillRange", BarFillRange, BarFillRange.NotSet);
 | 
						|
            sec.AddValue("BarLabelPosition", BarLabelPosition, BarLabelPosition.NotSet);
 | 
						|
 | 
						|
            sec.AddDataValue("BarOrigin", BarOrigin, null);
 | 
						|
 | 
						|
            sec.AddValue("BarOverlayEnabled", BarOverlayEnabled, false);
 | 
						|
            sec.AddValue("BarShadingEnabled", BarShadingEnabled, Tbool.NotSet);
 | 
						|
            sec.AddValue("BarShowAsHistogram", BarShowAsHistogram, Tbool.NotSet);
 | 
						|
            sec.AddValue("BarSpacing", BarSpacing, 0);
 | 
						|
            sec.AddValue("BarSpacingRatio", BarSpacingRatio, 0.2d);
 | 
						|
            sec.AddValue("BarWidthRatio", BarWidthRatio, 0d);
 | 
						|
 | 
						|
            sec.AddValue("BubbleIntensityMode", BubbleIntensityMode, BubbleIntensityMode.NotSet);
 | 
						|
            sec.AddValue("BubbleSizeMode", BubbleSizeMode, BubbleSizeMode.NotSet);
 | 
						|
 | 
						|
            sec.AddValue("ChartLineAreaDisplayMode", ChartLineAreaDisplayMode, ChartLineAreaDisplayMode.NotSet);
 | 
						|
            sec.AddValue("ChartLineDisplayMode", ChartLineDisplayMode, ChartLineDisplayMode.NotSet);
 | 
						|
 | 
						|
            if (ChartSeries.Count > 0)
 | 
						|
            {
 | 
						|
                sec.AddStartElement("ChartSeries count=\"" + ChartSeries.Count + "\"");
 | 
						|
 | 
						|
                foreach (ChartSeries series in ChartSeries)
 | 
						|
                    sec.AddElement(series.GetSerialData("ChartSeries"));
 | 
						|
 | 
						|
                sec.AddEndElement("ChartSeries");
 | 
						|
            }
 | 
						|
 | 
						|
            if (_ChartSeriesVisualStyle != null && _ChartSeriesVisualStyle.IsEmpty == false)
 | 
						|
                sec.AddElement(_ChartSeriesVisualStyle.GetSerialData("ChartSeriesVisualStyle"));
 | 
						|
 | 
						|
            if (_ChartVisualStyle != null && _ChartVisualStyle.IsEmpty == false)
 | 
						|
                sec.AddElement(_ChartVisualStyle.GetSerialData("ChartVisualStyle"));
 | 
						|
 | 
						|
            sec.AddValue("ConvexHullDisplayMode", ConvexHullDisplayMode, ConvexHullDisplayMode.NotSet);
 | 
						|
 | 
						|
            sec.AddElement(ChartCrosshair.GetSerialData("ChartCrosshair"));
 | 
						|
 | 
						|
            sec.AddValue("DataLabelOverlapMode", DataLabelOverlapMode, DataLabelOverlapMode.NotSet);
 | 
						|
 | 
						|
            if (_DataLabelVisualStyle != null && _DataLabelVisualStyle.IsEmpty == false)
 | 
						|
                sec.AddElement(_DataLabelVisualStyle.GetSerialData("DataLabelVisualStyle"));
 | 
						|
 | 
						|
            sec.AddValue("PointLabelDisplayMode", PointLabelDisplayMode, PointLabelDisplayMode.NotSet);
 | 
						|
            sec.AddValue("SeriesDisplayOrder", SeriesDisplayOrder, SeriesDisplayOrder.NotSet);
 | 
						|
            sec.AddValue("StepLines", StepLines, StepLines.NotSet);
 | 
						|
            sec.AddValue("StepLineMode", StepLineMode, StepLineMode.NotSet);
 | 
						|
 | 
						|
            sec.AddElement(base.GetSerialData(null));
 | 
						|
 | 
						|
            if (serialName != null)
 | 
						|
                sec.AddEndElement(serialName);
 | 
						|
 | 
						|
            return (sec);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region PutSerialData
 | 
						|
 | 
						|
        #region ProcessValue
 | 
						|
 | 
						|
        internal override void ProcessValue(SerialElement se)
 | 
						|
        {
 | 
						|
            switch (se.Name)
 | 
						|
            {
 | 
						|
                case "AutoGenSeriesType":
 | 
						|
                    AutoGenSeriesType = (SeriesType)se.GetValueEnum(typeof(SeriesType));
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "BarFillRange":
 | 
						|
                    BarFillRange = (BarFillRange)se.GetValueEnum(typeof(BarFillRange));
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "BarLabelPosition":
 | 
						|
                    BarLabelPosition = (BarLabelPosition)se.GetValueEnum(typeof(BarLabelPosition));
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "BarOrigin":
 | 
						|
                    BarOrigin = se.DataValue;
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "BarOverlayEnabled":
 | 
						|
                    BarOverlayEnabled = bool.Parse(se.StringValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "BarShadingEnabled":
 | 
						|
                    BarShadingEnabled = (Tbool)se.GetValueEnum(typeof(Tbool));
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "BarShowAsHistogram":
 | 
						|
                    BarShowAsHistogram = (Tbool)se.GetValueEnum(typeof(Tbool));
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "BarSpacing":
 | 
						|
                    BarSpacing = int.Parse(se.StringValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "BarSpacingRatio":
 | 
						|
                    BarSpacingRatio = double.Parse(se.StringValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "BarWidthRatio":
 | 
						|
                    BarWidthRatio = double.Parse(se.StringValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "BubbleIntensityMode":
 | 
						|
                    BubbleIntensityMode = (BubbleIntensityMode)se.GetValueEnum(typeof(BubbleIntensityMode));
 | 
						|
                    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 "ConvexHullDisplayMode":
 | 
						|
                    ConvexHullDisplayMode = (ConvexHullDisplayMode)se.GetValueEnum(typeof(ConvexHullDisplayMode));
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "DataLabelOverlapMode":
 | 
						|
                    DataLabelOverlapMode = (DataLabelOverlapMode)se.GetValueEnum(typeof(DataLabelOverlapMode));
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "PointLabelDisplayMode":
 | 
						|
                    PointLabelDisplayMode = (PointLabelDisplayMode)se.GetValueEnum(typeof(PointLabelDisplayMode));
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "SeriesDisplayOrder":
 | 
						|
                    SeriesDisplayOrder = (SeriesDisplayOrder)se.GetValueEnum(typeof(SeriesDisplayOrder));
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "StepLines":
 | 
						|
                    StepLines = (StepLines)se.GetValueEnum(typeof(StepLines));
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "StepLineMode":
 | 
						|
                    StepLineMode = (StepLineMode)se.GetValueEnum(typeof(StepLineMode));
 | 
						|
                    break;
 | 
						|
 | 
						|
                default:
 | 
						|
                    base.ProcessValue(se);
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessCollection
 | 
						|
 | 
						|
        internal override void ProcessCollection(SerialElement se)
 | 
						|
        {
 | 
						|
            SerialElementCollection sec = se.Sec;
 | 
						|
 | 
						|
            switch (se.Name)
 | 
						|
            {
 | 
						|
                case "AncillaryAxesX":
 | 
						|
                case "AncillaryAxesY":
 | 
						|
                    sec.PutSerialData(this);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "AxisX":
 | 
						|
                    sec.PutSerialData(AxisX);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "AxisY":
 | 
						|
                    sec.PutSerialData(AxisY);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "ChartAxisX":
 | 
						|
                    string nameX = sec.GetItemValue("Name");
 | 
						|
 | 
						|
                    ChartAxis axisX = AncillaryAxesX[nameX];
 | 
						|
                        
 | 
						|
                    if (axisX != null)
 | 
						|
                        AncillaryAxesX.Remove(axisX);
 | 
						|
 | 
						|
                    axisX = new ChartAxisX(nameX);
 | 
						|
 | 
						|
                    sec.PutSerialData(axisX);
 | 
						|
 | 
						|
                    AncillaryAxesX.Add(axisX);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "ChartAxisY":
 | 
						|
                    string nameY = sec.GetItemValue("Name");
 | 
						|
 | 
						|
                    ChartAxis axisY = AncillaryAxesY[nameY];
 | 
						|
                        
 | 
						|
                    if (axisY != null)
 | 
						|
                        AncillaryAxesY.Remove(axisY);
 | 
						|
 | 
						|
                    axisY = new ChartAxisY(nameY);
 | 
						|
 | 
						|
                    sec.PutSerialData(axisY);
 | 
						|
 | 
						|
                    AncillaryAxesY.Add(axisY);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "ChartSeries":
 | 
						|
                    if (se.ArrayCount > 0)
 | 
						|
                    {
 | 
						|
                        sec.PutSerialData(this);
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        string name = sec.GetItemValue("Name");
 | 
						|
 | 
						|
                        ChartSeries series = new ChartSeries(name);
 | 
						|
 | 
						|
                        ChartSeries.Add(series);
 | 
						|
 | 
						|
                        sec.PutSerialData(series);
 | 
						|
                    }
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "ChartSeriesVisualStyle":
 | 
						|
                    sec.PutSerialData(ChartSeriesVisualStyle);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "ChartVisualStyle":
 | 
						|
                    sec.PutSerialData(ChartVisualStyle);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "ChartCrosshair":
 | 
						|
                    sec.PutSerialData(ChartCrosshair);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "DataLabelVisualStyle":
 | 
						|
                    sec.PutSerialData(DataLabelVisualStyle);
 | 
						|
                    break;
 | 
						|
 | 
						|
                default:
 | 
						|
                    base.ProcessCollection(se);
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region States
 | 
						|
 | 
						|
        [Flags]
 | 
						|
        private enum States : uint
 | 
						|
        {
 | 
						|
            BarOverlayEnabled = (1U << 0),
 | 
						|
 | 
						|
            DisplayCrosshair = (1U << 1),
 | 
						|
            DropShadowDisplayed = (1U << 2),
 | 
						|
        }
 | 
						|
 | 
						|
        #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()
 | 
						|
        {
 | 
						|
            AncillaryAxesX = null;
 | 
						|
            AncillaryAxesY = null;
 | 
						|
 | 
						|
            AxisX = null;
 | 
						|
            AxisY = null;
 | 
						|
 | 
						|
            ChartSeriesVisualStyle = null;
 | 
						|
            ChartVisualStyle = null;
 | 
						|
            ChartCrosshair = null;
 | 
						|
            DataLabelVisualStyle = null;
 | 
						|
 | 
						|
            base.Dispose();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
    }
 | 
						|
 | 
						|
    #region CrosshairPoint
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Defines a Crosshair Point
 | 
						|
    /// </summary>
 | 
						|
    public class CrosshairPoint
 | 
						|
    {
 | 
						|
        #region Public variables
 | 
						|
 | 
						|
        private ChartSeries _ChartSeries;
 | 
						|
        private SeriesPoint _SeriesPoint;
 | 
						|
 | 
						|
        private int _PointIndex;
 | 
						|
        private int _ValueIndex;
 | 
						|
        private SortedSeriesPoints _SortedSeriesPoints;
 | 
						|
 | 
						|
        private Point _Point;
 | 
						|
        
 | 
						|
        private string _Text;
 | 
						|
        private Size _TextSize;
 | 
						|
 | 
						|
        private bool _IsDescending;
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        public CrosshairPoint(ChartSeries chartSeries, SortedSeriesPoints ssp,
 | 
						|
            int pointIndex, SeriesPoint seriesPoint, int valueIndex, Point point, bool isDescending)
 | 
						|
        {
 | 
						|
            _ChartSeries = chartSeries;
 | 
						|
            _IsDescending = isDescending;
 | 
						|
            _SortedSeriesPoints = ssp;
 | 
						|
            _PointIndex = pointIndex;
 | 
						|
            _SeriesPoint = seriesPoint;
 | 
						|
            _ValueIndex = valueIndex;
 | 
						|
 | 
						|
            _Point = point;
 | 
						|
        }
 | 
						|
 | 
						|
        #region Public properties
 | 
						|
 | 
						|
        #region ChartSeries
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the associated chart series.
 | 
						|
        /// </summary>
 | 
						|
        public ChartSeries ChartSeries
 | 
						|
        {
 | 
						|
            get { return (_ChartSeries); }
 | 
						|
            internal set { _ChartSeries = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SeriesPoint
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the associated SeriesPoint.
 | 
						|
        /// </summary>
 | 
						|
        public SeriesPoint SeriesPoint
 | 
						|
        {
 | 
						|
            get { return (_SeriesPoint); }
 | 
						|
            internal set { _SeriesPoint = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ValueX
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the X-Value
 | 
						|
        /// </summary>
 | 
						|
        public object ValueX
 | 
						|
        {
 | 
						|
            get { return (SeriesPoint.ValueX); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ValueY
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the associated ValueY.
 | 
						|
        /// </summary>
 | 
						|
        public object ValueY
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                if (ChartSeries.SeriesType == SeriesType.VerticalDot ||
 | 
						|
                    ChartSeries.SeriesType == SeriesType.HorizontalDot)
 | 
						|
                {
 | 
						|
                    return (SortedSeriesPoints.CountArray[PointIndex]);
 | 
						|
                }
 | 
						|
 | 
						|
                if (SeriesPoint.ValueY != null && (uint)_ValueIndex < SeriesPoint.ValueY.Length)
 | 
						|
                    return (SeriesPoint.ValueY[_ValueIndex]);
 | 
						|
 | 
						|
                return (string.Empty);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Internal properties
 | 
						|
 | 
						|
        #region IsDescending
 | 
						|
 | 
						|
        internal bool IsDescending
 | 
						|
        {
 | 
						|
            get { return (_IsDescending); }
 | 
						|
            set { _IsDescending = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Point
 | 
						|
 | 
						|
        internal Point Point
 | 
						|
        {
 | 
						|
            get { return (_Point); }
 | 
						|
            set { _Point = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region PointIndex
 | 
						|
 | 
						|
        internal int PointIndex
 | 
						|
        {
 | 
						|
            get { return (_PointIndex); }
 | 
						|
            set { _PointIndex = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SortedSeriesPoints
 | 
						|
 | 
						|
        internal SortedSeriesPoints SortedSeriesPoints
 | 
						|
        {
 | 
						|
            get { return (_SortedSeriesPoints); }
 | 
						|
            set { _SortedSeriesPoints = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Text
 | 
						|
 | 
						|
        internal string Text
 | 
						|
        {
 | 
						|
            get { return (_Text); }
 | 
						|
            set { _Text = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region TextSize
 | 
						|
 | 
						|
        internal Size TextSize
 | 
						|
        {
 | 
						|
            get { return (_TextSize); }
 | 
						|
            set { _TextSize = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ValueIndex
 | 
						|
 | 
						|
        internal int ValueIndex
 | 
						|
        {
 | 
						|
            get { return (_ValueIndex); }
 | 
						|
            set { _ValueIndex = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
    }
 | 
						|
 | 
						|
    #endregion
 | 
						|
 | 
						|
    #region CrosshairGroup
 | 
						|
 | 
						|
    internal class CrosshairGroup
 | 
						|
    {
 | 
						|
        public string Text;
 | 
						|
        public Size TextSize;
 | 
						|
 | 
						|
        public Size LabelSize;
 | 
						|
        public int MarkerWidth;
 | 
						|
 | 
						|
        public List<CrosshairPoint> Cps;
 | 
						|
    }
 | 
						|
 | 
						|
    #endregion
 | 
						|
 | 
						|
    #region enums
 | 
						|
 | 
						|
    #region BarFillRange
 | 
						|
 | 
						|
    public enum BarFillRange
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// Not set (default is ByBar)
 | 
						|
        /// </summary>
 | 
						|
        NotSet = 0,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Bars are filled according to each individual
 | 
						|
        /// bar's defined range.
 | 
						|
        /// </summary>
 | 
						|
        ByBar,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Bars are filled according to the associated series
 | 
						|
        /// minimum and maximum values.
 | 
						|
        /// </summary>
 | 
						|
        BySeries,
 | 
						|
    }
 | 
						|
 | 
						|
    #endregion
 | 
						|
 | 
						|
    #region BubbleIntensityMode
 | 
						|
 | 
						|
    public enum BubbleIntensityMode
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// Not set (default is None)
 | 
						|
        /// </summary>
 | 
						|
        NotSet = 0,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Bubble intensity not used.
 | 
						|
        /// </summary>
 | 
						|
        None,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Bubble intensity is expressed as an alpha value (0 - 255).
 | 
						|
        /// </summary>
 | 
						|
        Alpha,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Bubble intensity is expressed as a data value (as is the size of the bubble).
 | 
						|
        /// </summary>
 | 
						|
        Value,
 | 
						|
    }
 | 
						|
 | 
						|
    #endregion
 | 
						|
 | 
						|
    #region BubbleSizeMode
 | 
						|
 | 
						|
    public enum BubbleSizeMode
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// Not set (default is Area)
 | 
						|
        /// </summary>
 | 
						|
        NotSet = 0,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Bubble size is proportional to the bubble area.
 | 
						|
        /// </summary>
 | 
						|
        Area,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Bubble size is proportional to the bubble diameter.
 | 
						|
        /// </summary>
 | 
						|
        Diameter,
 | 
						|
    }
 | 
						|
 | 
						|
    #endregion
 | 
						|
 | 
						|
    #region ChartLineDisplayMode
 | 
						|
 | 
						|
    [Flags]
 | 
						|
    public enum ChartLineDisplayMode
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// Not set
 | 
						|
        /// </summary>
 | 
						|
        NotSet = 0,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Display defined points on line
 | 
						|
        /// </summary>
 | 
						|
        DisplayPoints = (1 << 0),
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Display a straight line through defined series points
 | 
						|
        /// </summary>
 | 
						|
        DisplayLine = (1 << 1),
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Display a spline through defined series points
 | 
						|
        /// </summary>
 | 
						|
        DisplaySpline = (1 << 2),
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Display a Step Line through defined series points
 | 
						|
        /// </summary>
 | 
						|
        DisplayStepLine = (1 << 3),
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Points are displayed unsorted
 | 
						|
        /// </summary>
 | 
						|
        DisplayUnsorted = (1 << 4),
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Start and end Points are connected.
 | 
						|
        /// </summary>
 | 
						|
        DisplayClosed = (1 << 5),
 | 
						|
    }
 | 
						|
 | 
						|
    #endregion
 | 
						|
 | 
						|
    #region ChartLineAreaDisplayMode
 | 
						|
 | 
						|
    [Flags]
 | 
						|
    public enum ChartLineAreaDisplayMode
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// Not set
 | 
						|
        /// </summary>
 | 
						|
        NotSet = 0,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Not set
 | 
						|
        /// </summary>
 | 
						|
        None = (1 << 0),
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Display background area under series Line.
 | 
						|
        /// </summary>
 | 
						|
        DisplayLine = (1 << 1),
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Display background area under series Spline.
 | 
						|
        /// </summary>
 | 
						|
        DisplaySpline = (1 << 2),
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Display background area under series StepLine.
 | 
						|
        /// </summary>
 | 
						|
        DisplayStepLine = (1 << 3),
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Display background area under series EmptyLines.
 | 
						|
        /// </summary>
 | 
						|
        DisplayEmptyLine = (1 << 4),
 | 
						|
    }
 | 
						|
 | 
						|
    #endregion
 | 
						|
 | 
						|
    #region DotPlotType
 | 
						|
 | 
						|
    [Flags]
 | 
						|
    internal enum DotPlotType
 | 
						|
    {
 | 
						|
        None = 0,
 | 
						|
        Horizontal = (1 << 0),
 | 
						|
        Vertical = (1 << 1),
 | 
						|
    }
 | 
						|
 | 
						|
    #endregion
 | 
						|
 | 
						|
    #region DataLabelOverlapMode
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Specifies how overlapping Series Data Labels are resolved
 | 
						|
    /// </summary>
 | 
						|
    public enum DataLabelOverlapMode
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// Not set (default is None). 
 | 
						|
        /// </summary>
 | 
						|
        NotSet = -1,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Overlapping labels will be shown.
 | 
						|
        /// </summary>
 | 
						|
        ShowOverlapping,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Overlapping labels will be hidden.
 | 
						|
        /// </summary>
 | 
						|
        HideOverlapping,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Overlapping labels will be rotated around point (when applicable).
 | 
						|
        /// </summary>
 | 
						|
        RotateAroundPoint,
 | 
						|
    }
 | 
						|
 | 
						|
    #endregion
 | 
						|
 | 
						|
    #region SeriesDisplayOrder
 | 
						|
 | 
						|
    public enum SeriesDisplayOrder
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// Not set (default is Forward).
 | 
						|
        /// </summary>
 | 
						|
        NotSet,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Series are displayed in the normal collection order.
 | 
						|
        /// </summary>
 | 
						|
        Forward,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Series are displayed in the reverse collection order.
 | 
						|
        /// </summary>
 | 
						|
        Reverse,
 | 
						|
    }
 | 
						|
 | 
						|
    #endregion
 | 
						|
 | 
						|
    #region XyAlignment
 | 
						|
 | 
						|
    public enum XyAlignment
 | 
						|
    {
 | 
						|
        NotSet = -1,
 | 
						|
 | 
						|
        Top,
 | 
						|
        Left,
 | 
						|
        Bottom,
 | 
						|
        Right,
 | 
						|
    }
 | 
						|
 | 
						|
    #endregion
 | 
						|
 | 
						|
    #endregion
 | 
						|
}
 |