896 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			896 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.ComponentModel;
 | 
						|
using System.Drawing;
 | 
						|
using DevComponents.DotNetBar.Charts.Style;
 | 
						|
 | 
						|
namespace DevComponents.DotNetBar.Charts
 | 
						|
{
 | 
						|
    /// <summary>
 | 
						|
    /// Represents a Crosshair element.
 | 
						|
    /// </summary>
 | 
						|
    [TypeConverter(typeof(BlankExpandableObjectConverter))]
 | 
						|
    public class ChartCrosshair : ChartVisualElement
 | 
						|
    {
 | 
						|
        #region Private variables
 | 
						|
 | 
						|
        private States _States;
 | 
						|
 | 
						|
        private PointIntersectMode _PointIntersectMode = PointIntersectMode.Edge;
 | 
						|
        private int _PointIntersectMargin = 2;
 | 
						|
 | 
						|
        private AxisOrientation _AxisOrientation = AxisOrientation.X;
 | 
						|
        private CrosshairLabelMode _CrosshairLabelMode = CrosshairLabelMode.Common;
 | 
						|
 | 
						|
        private CrosshairVisualStyle _CrosshairVisualStyle;
 | 
						|
        private EffectiveStyle<CrosshairVisualStyle> _EffectiveCrosshairStyle;
 | 
						|
 | 
						|
        private CrosshairValueVisualStyle _CrosshairLabelVisualStyle;
 | 
						|
        private EffectiveStyle<CrosshairValueVisualStyle> _EffectiveCrosshairLabelStyle;
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        public ChartCrosshair()
 | 
						|
        {
 | 
						|
            InitDefaultStates();
 | 
						|
 | 
						|
            _EffectiveCrosshairStyle = new EffectiveStyle<CrosshairVisualStyle>(this);
 | 
						|
            _EffectiveCrosshairLabelStyle = new EffectiveStyle<CrosshairValueVisualStyle>(this);
 | 
						|
        }
 | 
						|
 | 
						|
        #region InitDefaultStates
 | 
						|
 | 
						|
        private void InitDefaultStates()
 | 
						|
        {
 | 
						|
            SetState(States.ShowCrosshairLabelMarkers, true);
 | 
						|
            SetState(States.ShowGroupHeader, true);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Public properties
 | 
						|
 | 
						|
        #region AxisOrientation
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the axis orientation driving the crosshair display.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(AxisOrientation.X), Category("Appearance")]
 | 
						|
        [Description("Indicates the axis orientation driving the crosshair display.")]
 | 
						|
        public AxisOrientation AxisOrientation
 | 
						|
        {
 | 
						|
            get { return (_AxisOrientation); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _AxisOrientation)
 | 
						|
                {
 | 
						|
                    _AxisOrientation = value;
 | 
						|
 | 
						|
                    OnPropertyChanged("AxisOrientation");
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CrosshairLabelMode
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the mode used to display the Crosshair label.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(CrosshairLabelMode.Common), Category("Behavior")]
 | 
						|
        [Description("Indicates the mode used to display the Crosshair label.")]
 | 
						|
        public CrosshairLabelMode CrosshairLabelMode
 | 
						|
        {
 | 
						|
            get { return (_CrosshairLabelMode); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _CrosshairLabelMode)
 | 
						|
                {
 | 
						|
                    _CrosshairLabelMode = value;
 | 
						|
 | 
						|
                    OnPropertyChangedEx("CrosshairLabelMode", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region PointIntersectMode
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the the Crosshair point intersection mode.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(PointIntersectMode.Edge), Category("Behavior")]
 | 
						|
        [Description("Indicates the Crosshair point intersection mode.")]
 | 
						|
        public PointIntersectMode PointIntersectMode
 | 
						|
        {
 | 
						|
            get { return (_PointIntersectMode); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _PointIntersectMode)
 | 
						|
                {
 | 
						|
                    _PointIntersectMode = value;
 | 
						|
 | 
						|
                    OnPropertyChangedEx("PointIntersectMode", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region PointIntersectMargin
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the the Crosshair point intersection margin.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(2), Category("Layout")]
 | 
						|
        [Description("Indicates the Crosshair point intersection margin.")]
 | 
						|
        public int PointIntersectMargin
 | 
						|
        {
 | 
						|
            get { return (_PointIntersectMargin); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _PointIntersectMargin)
 | 
						|
                {
 | 
						|
                    _PointIntersectMargin = value;
 | 
						|
 | 
						|
                    OnPropertyChangedEx("PointIntersectMargin", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CrosshairLabelVisualStyle
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the default visual style to be used for Crosshair 
 | 
						|
        /// values rendered on the X and Y axes.
 | 
						|
        /// </summary>
 | 
						|
        [Category("Style")]
 | 
						|
        [Description("Indicates visual style to be used for Crosshair values rendered on the X and Y axes")]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | 
						|
        public CrosshairValueVisualStyle CrosshairLabelVisualStyle
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                if (_CrosshairLabelVisualStyle == null)
 | 
						|
                {
 | 
						|
                    _CrosshairLabelVisualStyle = new CrosshairValueVisualStyle();
 | 
						|
 | 
						|
                    StyleVisualChangeHandler(null, _CrosshairLabelVisualStyle);
 | 
						|
                }
 | 
						|
 | 
						|
                return (_CrosshairLabelVisualStyle);
 | 
						|
            }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (_CrosshairLabelVisualStyle != value)
 | 
						|
                {
 | 
						|
                    CrosshairValueVisualStyle oldValue = _CrosshairLabelVisualStyle;
 | 
						|
                    _CrosshairLabelVisualStyle = value;
 | 
						|
 | 
						|
                    OnVisualStyleChanged("CrosshairLabelVisualStyle", oldValue, value);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CrosshairVisualStyle
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the visual style for the Crosshair.
 | 
						|
        /// </summary>
 | 
						|
        [Category("Style")]
 | 
						|
        [Description("Indicates the visual style for the Crosshair.")]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | 
						|
        public CrosshairVisualStyle CrosshairVisualStyle
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                if (_CrosshairVisualStyle == null)
 | 
						|
                {
 | 
						|
                    _CrosshairVisualStyle = new CrosshairVisualStyle();
 | 
						|
 | 
						|
                    StyleVisualChangeHandler(null, _CrosshairVisualStyle);
 | 
						|
                }
 | 
						|
 | 
						|
                return (_CrosshairVisualStyle);
 | 
						|
            }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (_CrosshairVisualStyle != value)
 | 
						|
                {
 | 
						|
                    CrosshairVisualStyle oldValue = _CrosshairVisualStyle;
 | 
						|
 | 
						|
                    _CrosshairVisualStyle = value;
 | 
						|
 | 
						|
                    OnVisualStyleChanged("CrosshairVisualStyle", oldValue, value);
 | 
						|
 | 
						|
                    if (oldValue != null)
 | 
						|
                        oldValue.Dispose();
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region EffectiveCrosshairLabelStyle
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets a reference to the Crosshair label's Effective (cached, composite) style.
 | 
						|
        /// </summary>
 | 
						|
        [Browsable(false)]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | 
						|
        public CrosshairValueVisualStyle EffectiveCrosshairLabelStyle
 | 
						|
        {
 | 
						|
            get { return (_EffectiveCrosshairLabelStyle.Style); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region EffectiveCrosshairStyle
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets a reference to the Crosshair's Effective (cached, composite) style.
 | 
						|
        /// </summary>
 | 
						|
        [Browsable(false)]
 | 
						|
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | 
						|
        public CrosshairVisualStyle EffectiveCrosshairStyle
 | 
						|
        {
 | 
						|
            get { return (_EffectiveCrosshairStyle.Style); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region HighlightPoints
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets whether series points are highlighted
 | 
						|
        /// when the Crosshair cursor intersects with them.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(false), Category("Appearance")]
 | 
						|
        [Description("Indicates whether series points are highlighted when the Crosshair cursor intersects with them.")]
 | 
						|
        public bool HighlightPoints
 | 
						|
        {
 | 
						|
            get { return (TestState(States.HighlightPoints)); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != HighlightPoints)
 | 
						|
                {
 | 
						|
                    SetState(States.HighlightPoints, value);
 | 
						|
 | 
						|
                    OnPropertyChangedEx("HighlightPoints", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region HighlightSinglePoint
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets whether only single series points are highlighted
 | 
						|
        /// when the Crosshair cursor intersects with them.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(false), Category("Appearance")]
 | 
						|
        [Description("Indicates whether only single series points are highlighted when the Crosshair cursor intersects with them.")]
 | 
						|
        public bool HighlightSinglePoint
 | 
						|
        {
 | 
						|
            get { return (TestState(States.HighlightSinglePoint)); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != HighlightSinglePoint)
 | 
						|
                {
 | 
						|
                    SetState(States.HighlightSinglePoint, value);
 | 
						|
 | 
						|
                    OnPropertyChangedEx("HighlightSinglePoint", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ShowValueXLabels
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets whether ValueX Labels are shown.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(false), Category("Appearance")]
 | 
						|
        [Description("Indicates whether ValueX Labels are shown.")]
 | 
						|
        public bool ShowValueXLabels
 | 
						|
        {
 | 
						|
            get { return (TestState(States.ShowValueXLabels)); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != ShowValueXLabels)
 | 
						|
                {
 | 
						|
                    SetState(States.ShowValueXLabels, value);
 | 
						|
 | 
						|
                    OnPropertyChangedEx("ShowValueXLabels", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ShowValueXLine
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets whether a ValueX line is shown.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(false), Category("Appearance")]
 | 
						|
        [Description("Indicates whether a ValueX line is shown.")]
 | 
						|
        public bool ShowValueXLine
 | 
						|
        {
 | 
						|
            get { return (TestState(States.ShowValueXLine)); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != ShowValueXLine)
 | 
						|
                {
 | 
						|
                    SetState(States.ShowValueXLine, value);
 | 
						|
 | 
						|
                    OnPropertyChangedEx("ShowValueXLine", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ShowCrosshairLabelMarkers
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets whether Crosshair label markers are shown.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(true), Category("Appearance")]
 | 
						|
        [Description("Indicates whether Crosshair label markers are shown.")]
 | 
						|
        public bool ShowCrosshairLabelMarkers
 | 
						|
        {
 | 
						|
            get { return (TestState(States.ShowCrosshairLabelMarkers)); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != ShowCrosshairLabelMarkers)
 | 
						|
                {
 | 
						|
                    SetState(States.ShowCrosshairLabelMarkers, value);
 | 
						|
 | 
						|
                    OnPropertyChangedEx("ShowCrosshairLabelMarkers", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ShowCrosshairLabels
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets whether Crosshair labels are shown.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(false), Category("Appearance")]
 | 
						|
        [Description("Indicates whether Crosshair labels are shown.")]
 | 
						|
        public bool ShowCrosshairLabels
 | 
						|
        {
 | 
						|
            get { return (TestState(States.ShowCrosshairLabels)); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != ShowCrosshairLabels)
 | 
						|
                {
 | 
						|
                    SetState(States.ShowCrosshairLabels, value);
 | 
						|
 | 
						|
                    OnPropertyChangedEx("ShowCrosshairLabels", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ShowGroupHeaders
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets whether Group Headers are shown for each series.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(true), Category("Appearance")]
 | 
						|
        [Description("Indicates whether Group Headers are shown for each series.")]
 | 
						|
        public bool ShowGroupHeaders
 | 
						|
        {
 | 
						|
            get { return (TestState(States.ShowGroupHeader)); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != ShowGroupHeaders)
 | 
						|
                {
 | 
						|
                    SetState(States.ShowGroupHeader, value);
 | 
						|
 | 
						|
                    OnPropertyChangedEx("ShowGroupHeaders", VisualChangeType.Layout);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ShowValueYLabels
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets whether a ValueY label is shown.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(false), Category("Appearance")]
 | 
						|
        [Description("Indicates whether a ValueY label is shown.")]
 | 
						|
        public bool ShowValueYLabels
 | 
						|
        {
 | 
						|
            get { return (TestState(States.ShowValueYLabels)); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != ShowValueYLabels)
 | 
						|
                {
 | 
						|
                    SetState(States.ShowValueYLabels, value);
 | 
						|
 | 
						|
                    OnPropertyChangedEx("ShowValueYLabels", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ShowValueYLine
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets whether a ValueY line is shown.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(false), Category("Appearance")]
 | 
						|
        [Description("Indicates whether a ValueY line is shown.")]
 | 
						|
        public bool ShowValueYLine
 | 
						|
        {
 | 
						|
            get { return (TestState(States.ShowValueYLine)); }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != ShowValueYLine)
 | 
						|
                {
 | 
						|
                    SetState(States.ShowValueYLine, value);
 | 
						|
 | 
						|
                    OnPropertyChangedEx("ShowValueYLine", VisualChangeType.Render);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MeasureOverride
 | 
						|
 | 
						|
        protected override void MeasureOverride(ChartLayoutInfo layoutInfo)
 | 
						|
        {
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ArrangeOverride
 | 
						|
 | 
						|
        protected override void ArrangeOverride(ChartLayoutInfo layoutInfo)
 | 
						|
        {
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderOverride
 | 
						|
 | 
						|
        protected override void RenderOverride(ChartRenderInfo renderInfo)
 | 
						|
        {
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Style support
 | 
						|
 | 
						|
        #region ApplyStyles
 | 
						|
 | 
						|
        public override void ApplyStyles(BaseVisualStyle style)
 | 
						|
        {
 | 
						|
            base.ApplyStyles(style);
 | 
						|
 | 
						|
            CrosshairVisualStyle cstyle = style as CrosshairVisualStyle;
 | 
						|
 | 
						|
            if (cstyle != null)
 | 
						|
            {
 | 
						|
                ApplyParentStyles(cstyle, Parent as ChartContainer);
 | 
						|
 | 
						|
                cstyle.ApplyStyle(CrosshairVisualStyle);
 | 
						|
 | 
						|
                ApplyDefaultLineStyles(cstyle.ValueXLineStyle);
 | 
						|
                ApplyDefaultLineStyles(cstyle.ValueYLineStyle);
 | 
						|
 | 
						|
                if (cstyle.GroupHeaderFont == null)
 | 
						|
                    cstyle.GroupHeaderFont = SystemFonts.CaptionFont;
 | 
						|
 | 
						|
                if (cstyle.GroupHeaderTextColor.IsEmpty)
 | 
						|
                    cstyle.GroupHeaderTextColor = Color.Black;
 | 
						|
 | 
						|
                if (cstyle.Padding.IsEmpty == true)
 | 
						|
                    cstyle.Padding = new Style.Padding(4);
 | 
						|
 | 
						|
                if (cstyle.BorderThickness <= 0)
 | 
						|
                    cstyle.BorderThickness = 1;
 | 
						|
 | 
						|
                if (cstyle.BorderPattern == LinePattern.NotSet)
 | 
						|
                    cstyle.BorderPattern = LinePattern.Solid;
 | 
						|
 | 
						|
                if (cstyle.BorderColor.IsEmpty == true)
 | 
						|
                    cstyle.BorderColor = Color.Black;
 | 
						|
 | 
						|
                if (cstyle.Background.IsEmpty == true)
 | 
						|
                    cstyle.Background = new Background(Color.White);
 | 
						|
 | 
						|
                if (cstyle.Font == null)
 | 
						|
                    cstyle.Font = SystemFonts.DefaultFont;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region ApplyParentStyles
 | 
						|
 | 
						|
        private void ApplyParentStyles(
 | 
						|
            CrosshairVisualStyle pstyle, ChartContainer item)
 | 
						|
        {
 | 
						|
            if (item != null)
 | 
						|
            {
 | 
						|
                ApplyParentStyles(pstyle, item.Parent as ChartContainer);
 | 
						|
 | 
						|
                if (item is ChartPanel)
 | 
						|
                    pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.CrosshairVisualStyle);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                pstyle.ApplyStyle(ChartControl.BaseVisualStyles.CrosshairVisualStyle);
 | 
						|
                pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.CrosshairVisualStyle);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ApplyDefaultLineStyles
 | 
						|
 | 
						|
        private void ApplyDefaultLineStyles(ChartLineVisualStyle style)
 | 
						|
        {
 | 
						|
            if (style.LineColor.IsEmpty == true)
 | 
						|
                style.LineColor = Color.Fuchsia;
 | 
						|
 | 
						|
            if (style.LinePattern == LinePattern.NotSet)
 | 
						|
                style.LinePattern = LinePattern.Solid;
 | 
						|
 | 
						|
            if (style.LineWidth < 0)
 | 
						|
                style.LineWidth = 1;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region InvalidateStyle
 | 
						|
 | 
						|
        ///<summary>
 | 
						|
        ///Invalidate the cached Styles
 | 
						|
        ///</summary>
 | 
						|
        public void InvalidateStyle()
 | 
						|
        {
 | 
						|
            ClearEffectiveStyles();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ClearEffectiveStyles
 | 
						|
 | 
						|
        protected override void ClearEffectiveStyles()
 | 
						|
        {
 | 
						|
            _EffectiveCrosshairStyle.InvalidateStyle();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Crosshair States
 | 
						|
 | 
						|
        [Flags]
 | 
						|
        private enum States : uint
 | 
						|
        {
 | 
						|
            HighlightPoints = (1U << 0),
 | 
						|
            HighlightSinglePoint = (1U << 1),
 | 
						|
 | 
						|
            ShowValueXLabels = (1U << 2),
 | 
						|
            ShowValueXLine = (1U << 3),
 | 
						|
 | 
						|
            ShowCrosshairLabels = (1U << 4),
 | 
						|
            ShowGroupHeader = (1U << 5),
 | 
						|
            ShowCrosshairLabelMarkers = (1U << 6),
 | 
						|
 | 
						|
            ShowValueYLabels = (1U << 7),
 | 
						|
            ShowValueYLine = (1U << 8),
 | 
						|
        }
 | 
						|
 | 
						|
        #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 Copy/CopyTo
 | 
						|
 | 
						|
        public override ChartVisualElement Copy()
 | 
						|
        {
 | 
						|
            ChartCrosshair copy = new ChartCrosshair();
 | 
						|
 | 
						|
            CopyTo(copy);
 | 
						|
 | 
						|
            return (copy);
 | 
						|
        }
 | 
						|
 | 
						|
        public override void CopyTo(ChartVisualElement copy)
 | 
						|
        {
 | 
						|
            ChartCrosshair c = copy as ChartCrosshair;
 | 
						|
 | 
						|
            if (c != null)
 | 
						|
            {
 | 
						|
                base.CopyTo(c);
 | 
						|
 | 
						|
                c.AxisOrientation = AxisOrientation;
 | 
						|
                c.CrosshairLabelMode = CrosshairLabelMode;
 | 
						|
                c.PointIntersectMode = PointIntersectMode;
 | 
						|
                c.PointIntersectMargin = PointIntersectMargin;
 | 
						|
 | 
						|
                c.CrosshairLabelVisualStyle =  (_CrosshairLabelVisualStyle != null) ? CrosshairLabelVisualStyle.Copy() : null;
 | 
						|
                c.CrosshairVisualStyle = (_CrosshairVisualStyle != null) ? CrosshairVisualStyle.Copy() : null;
 | 
						|
 | 
						|
                c.HighlightPoints = HighlightPoints;
 | 
						|
                c.HighlightSinglePoint = HighlightSinglePoint;
 | 
						|
 | 
						|
                c.ShowValueXLabels = ShowValueXLabels;
 | 
						|
                c.ShowValueXLine = ShowValueXLine;
 | 
						|
                c.ShowCrosshairLabels = ShowCrosshairLabels;
 | 
						|
                c.ShowGroupHeaders = ShowGroupHeaders;
 | 
						|
                c.ShowValueYLabels = ShowValueYLabels;
 | 
						|
                c.ShowValueYLine = ShowValueYLine;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetSerialData
 | 
						|
 | 
						|
        internal override SerialElementCollection GetSerialData(string serialName)
 | 
						|
        {
 | 
						|
            SerialElementCollection sec = new SerialElementCollection();
 | 
						|
 | 
						|
            if (serialName != null)
 | 
						|
            {
 | 
						|
                if (serialName.Equals("") == true)
 | 
						|
                    serialName = "ChartCrosshair";
 | 
						|
 | 
						|
                sec.AddStartElement(serialName);
 | 
						|
            }
 | 
						|
 | 
						|
            sec.AddValue("AxisOrientation", AxisOrientation, AxisOrientation.X);
 | 
						|
            sec.AddValue("CrosshairLabelMode", CrosshairLabelMode, CrosshairLabelMode.Common);
 | 
						|
            sec.AddValue("PointIntersectMode", PointIntersectMode, PointIntersectMode.Edge);
 | 
						|
            sec.AddValue("PointIntersectMargin", PointIntersectMargin, 2);
 | 
						|
 | 
						|
            if (_CrosshairLabelVisualStyle != null && _CrosshairLabelVisualStyle.IsEmpty == false)
 | 
						|
                sec.AddElement(_CrosshairLabelVisualStyle.GetSerialData("CrosshairLabelVisualStyle"));
 | 
						|
 | 
						|
            if (_CrosshairVisualStyle != null && _CrosshairVisualStyle.IsEmpty == false)
 | 
						|
                sec.AddElement(_CrosshairVisualStyle.GetSerialData("CrosshairVisualStyle"));
 | 
						|
 | 
						|
            sec.AddValue("HighlightPoints", HighlightPoints, false);
 | 
						|
            sec.AddValue("HighlightSinglePoint", HighlightSinglePoint, false);
 | 
						|
 | 
						|
            sec.AddValue("ShowValueXLabels", ShowValueXLabels, false);
 | 
						|
            sec.AddValue("ShowValueXLine", ShowValueXLine, false);
 | 
						|
            sec.AddValue("ShowCrosshairLabels", ShowCrosshairLabels, false);
 | 
						|
            sec.AddValue("ShowGroupHeaders", ShowGroupHeaders, true);
 | 
						|
            sec.AddValue("ShowValueYLabels", ShowValueYLabels, false);
 | 
						|
            sec.AddValue("ShowValueYLine", ShowValueYLine, false);
 | 
						|
 | 
						|
            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 "AxisOrientation":
 | 
						|
                    AxisOrientation = (AxisOrientation)se.GetValueEnum(typeof(AxisOrientation));
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "CrosshairLabelMode":
 | 
						|
                    CrosshairLabelMode = (CrosshairLabelMode)se.GetValueEnum(typeof(CrosshairLabelMode));
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "PointIntersectMode":
 | 
						|
                    PointIntersectMode = (PointIntersectMode)se.GetValueEnum(typeof(PointIntersectMode));
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "PointIntersectMargin":
 | 
						|
                    PointIntersectMargin = int.Parse(se.StringValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "HighlightPoints":
 | 
						|
                    HighlightPoints = bool.Parse(se.StringValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "HighlightSinglePoint":
 | 
						|
                    HighlightSinglePoint = bool.Parse(se.StringValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "ShowValueXLabels":
 | 
						|
                    ShowValueXLabels = bool.Parse(se.StringValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "ShowValueXLine":
 | 
						|
                    ShowValueXLine = bool.Parse(se.StringValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "ShowCrosshairLabels":
 | 
						|
                    ShowCrosshairLabels = bool.Parse(se.StringValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "ShowGroupHeaders":
 | 
						|
                    ShowGroupHeaders = bool.Parse(se.StringValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "ShowValueYLabels":
 | 
						|
                    ShowValueYLabels = bool.Parse(se.StringValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "ShowValueYLine":
 | 
						|
                    ShowValueYLine = bool.Parse(se.StringValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                default:
 | 
						|
                    base.ProcessValue(se);
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessCollection
 | 
						|
 | 
						|
        internal override void ProcessCollection(SerialElement se)
 | 
						|
        {
 | 
						|
            SerialElementCollection sec = se.Sec;
 | 
						|
 | 
						|
            switch (se.Name)
 | 
						|
            {
 | 
						|
                case "CrosshairLabelVisualStyle":
 | 
						|
                    sec.PutSerialData(CrosshairLabelVisualStyle);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case "CrosshairVisualStyle":
 | 
						|
                    sec.PutSerialData(CrosshairVisualStyle);
 | 
						|
                    break;
 | 
						|
 | 
						|
                default:
 | 
						|
                    base.ProcessCollection(se);
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region IDisposable
 | 
						|
 | 
						|
        public override void Dispose()
 | 
						|
        {
 | 
						|
            CrosshairLabelVisualStyle = null;
 | 
						|
            CrosshairVisualStyle = null;
 | 
						|
 | 
						|
            base.Dispose();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
    }
 | 
						|
 | 
						|
    #region enums
 | 
						|
 | 
						|
    #region CrosshairLabelMode
 | 
						|
 | 
						|
    public enum CrosshairLabelMode
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// A common Crosshair label is shown for all series
 | 
						|
        /// </summary>
 | 
						|
        Common,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// A crosshair label is shown for the nearest series
 | 
						|
        /// </summary>
 | 
						|
        NearestSeries,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// A crosshair label is shown for each series
 | 
						|
        /// </summary>
 | 
						|
        EachSeries,
 | 
						|
    }
 | 
						|
 | 
						|
    #endregion
 | 
						|
 | 
						|
    #region CrosshairLabelPosition
 | 
						|
 | 
						|
    public enum CrosshairLabelPosition
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// Crosshair labels positioned relative to the Chart
 | 
						|
        /// </summary>
 | 
						|
        ChartRelative,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Crosshair labels positioned relative to the Mouse
 | 
						|
        /// </summary>
 | 
						|
        MouseRelative,
 | 
						|
    }
 | 
						|
 | 
						|
    #endregion
 | 
						|
 | 
						|
    #region PointIntersectMode
 | 
						|
 | 
						|
    public enum PointIntersectMode
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// From center.
 | 
						|
        /// </summary>
 | 
						|
        Center,
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// From edge.
 | 
						|
        /// </summary>
 | 
						|
        Edge,
 | 
						|
    }
 | 
						|
 | 
						|
    #endregion
 | 
						|
 | 
						|
    #endregion
 | 
						|
}
 |