1 //-------------------------------------------------------------
2 // <copyright company=
\92Microsoft Corporation
\92>
3 // Copyright © Microsoft Corporation. All Rights Reserved.
5 //-------------------------------------------------------------
6 // @owner=alexgor, deliant
7 //=================================================================
8 // File: AxisScrollBar.cs
10 // Namespace: System.Web.UI.WebControls[Windows.Forms].Charting
12 // Classes: AxisScrollBar, ScrollBarEventArgs
14 // Purpose: AxisScrollBar class represent axis scroolbar. There
15 // is a big difference how this UI functionality
16 // implemented for Windows Forms and ASP.NET. For
17 // Windows Forms a custom drawn scrollbar control is
18 // drawn in the chart which reacts to the mouse input and
19 // changes current axis data scaleView.
21 // ASP.NET version uses client-side scripting and partial
22 // loading of data segment by segment. Due to the fact
23 // that scrollbar operates on the client side not all
24 // functionality of WindowsForms scrollbar is supported.
26 // Reviewed: AG - March 16, 2007
28 //===================================================================
32 #region Used namespaces
35 using System.ComponentModel;
37 using System.Drawing.Design;
38 using System.Drawing.Drawing2D;
39 using System.Windows.Forms;
40 using System.Windows.Forms.DataVisualization.Charting;
41 using System.Windows.Forms.DataVisualization.Charting.Data;
42 using System.Windows.Forms.DataVisualization.Charting.ChartTypes;
43 using System.Windows.Forms.DataVisualization.Charting.Utilities;
44 using System.Windows.Forms.DataVisualization.Charting.Borders3D;
45 using System.Diagnostics.CodeAnalysis;
49 namespace System.Windows.Forms.DataVisualization.Charting
51 #region Scroll bar enumerations
54 /// An enumeration of scrollbar button types.
56 public enum ScrollBarButtonType
59 /// Thumb tracker button.
64 /// Scroll by substracting small distance.
69 /// Scroll by adding small distance.
74 /// Scroll by substracting large distance.
79 /// Scroll by adding large distance.
84 /// Zoom reset button.
90 /// An enumeration of scrollbar button style flags.
93 public enum ScrollBarButtonStyles
96 /// No buttons are shown.
101 /// Small increment or decrement buttons are shown.
106 /// Reset zoom buttons are shown.
111 /// All buttons are shown.
113 All = SmallScroll | ResetZoom
119 /// AxisScrollBar class represents the axis scrollbar. It is exposed as the
120 /// ScrollBar property of the Axis class. It contains scrollbar appearance
121 /// properties and drawing methods.
123 public class AxisScrollBar : IDisposable
125 #region Scroll bar fields
127 // Reference to the axis data scaleView class
128 internal Axis axis = null;
130 // Indicates that scollbra will be drawn
131 private bool _enabled = true;
133 // Axis data scaleView scroll bar style
134 private ScrollBarButtonStyles _scrollBarButtonStyle = ScrollBarButtonStyles.All;
136 // Axis data scaleView scroll bar size
137 private double _scrollBarSize = 14.0;
139 // Index of the pressed butoon in the scroll bar
140 private int _pressedButtonType = int.MaxValue;
142 // Axis data scaleView scroll bar buttons color
143 private Color _buttonColor = Color.Empty;
145 // Axis data scaleView scroll bar back color
146 private Color _backColor = Color.Empty;
148 // Axis data scaleView scroll bar lines color
149 private Color _lineColor = Color.Empty;
151 // Current scroll bar drawing colors
152 private Color _buttonCurrentColor = Color.Empty;
153 private Color _backCurrentColor = Color.Empty;
154 private Color _lineCurrentColor = Color.Empty;
156 // Last mouse click mouse and scaleView position
157 private PointF _lastClickMousePosition = PointF.Empty;
158 private double _lastClickViewPosition = double.NaN;
160 // Timer used to scroll the data while selecting
161 private System.Windows.Forms.Timer _scrollTimer = new System.Windows.Forms.Timer();
163 // Scroll size and direction when AutoScroll is set
164 private MouseEventArgs _mouseArguments = null;
166 // Position of the scrollbar (true - edge of PlotArea, false - edge of chart area)
167 private bool _isPositionedInside = true;
171 #region Scroll bar constructors and initialization
174 /// AxisScrollBar constructor.
176 public AxisScrollBar()
181 /// Axis scroll bar constructor.
183 /// <param name="axis">Reference to the axis class.</param>
184 internal AxisScrollBar(Axis axis)
186 // Save reference to the axis data scaleView
191 /// Initialize axis scroll bar class.
193 internal void Initialize()
199 #region Scroll bar properties
202 /// Gets or sets a flag which indicates whether scroll bar is positioned inside or outside of chart area.
205 SRCategory("CategoryAttributeAxisView"),
208 SRDescription("DescriptionAttributeAxisScrollBar_PositionInside")
210 public bool IsPositionedInside
214 return _isPositionedInside;
218 if(_isPositionedInside != value)
220 _isPositionedInside = value;
223 axis.ChartArea.Invalidate();
231 /// Gets or sets a flag which indicates whether the scroll bar is enabled.
234 SRCategory("CategoryAttributeAxisView"),
237 SRDescription("DescriptionAttributeAxisScrollBar_Enabled")
247 if(_enabled != value)
252 axis.ChartArea.Invalidate();
259 /// Gets the ChartArea that contains this scrollbar.
264 DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
265 SerializationVisibilityAttribute(SerializationVisibility.Hidden)
267 public ChartArea ChartArea
271 return this.axis.ChartArea;
276 /// Gets the Axis that contains this scrollbar.
281 DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
282 SerializationVisibilityAttribute(SerializationVisibility.Hidden)
293 /// Gets or sets the style of the scrollbar button.
296 SRCategory("CategoryAttributeAxisView"),
299 DefaultValue(ScrollBarButtonStyle.SmallScroll),
301 DefaultValue(ScrollBarButtonStyles.All),
303 SRDescription("DescriptionAttributeAxisScrollBar_Buttons"),
304 Editor(Editors.FlagsEnumUITypeEditor.Editor, Editors.FlagsEnumUITypeEditor.Base)
306 public ScrollBarButtonStyles ButtonStyle
310 return _scrollBarButtonStyle;
314 if(_scrollBarButtonStyle != value)
316 _scrollBarButtonStyle = value;
319 axis.ChartArea.Invalidate();
326 /// Gets or sets the size of the scrollbar.
329 SRCategory("CategoryAttributeAxisView"),
332 SRDescription("DescriptionAttributeAxisScrollBar_Size"),
338 return _scrollBarSize;
342 if(_scrollBarSize != value)
344 // Check values range
345 if(value < 5.0 || value > 20.0)
347 throw (new ArgumentOutOfRangeException("value", SR.ExceptionScrollBarSizeInvalid));
349 _scrollBarSize = value;
352 axis.ChartArea.Invalidate();
359 /// Gets or sets the button color of the scrollbar.
362 SRCategory("CategoryAttributeAxisView"),
364 DefaultValue(typeof(Color), ""),
365 SRDescription("DescriptionAttributeAxisScrollBar_ButtonColor"),
366 TypeConverter(typeof(ColorConverter)),
367 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base)
369 public Color ButtonColor
377 if(_buttonColor != value)
379 _buttonColor = value;
382 axis.ChartArea.Invalidate();
389 /// Gets or sets the line color of the scrollbar.
392 SRCategory("CategoryAttributeAxisView"),
394 DefaultValue(typeof(Color), ""),
395 SRDescription("DescriptionAttributeLineColor"),
396 TypeConverter(typeof(ColorConverter)),
397 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base)
399 public Color LineColor
407 if(_lineColor != value)
412 axis.ChartArea.Invalidate();
419 /// Gets or sets the background color of the scrollbar.
422 SRCategory("CategoryAttributeAxisView"),
424 DefaultValue(typeof(Color), ""),
425 SRDescription("DescriptionAttributeBackColor"),
426 TypeConverter(typeof(ColorConverter)),
427 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base)
429 public Color BackColor
437 if(_backColor != value)
442 axis.ChartArea.Invalidate();
450 #region Scroll bar public methods
453 /// This method returns true if the scrollbar is visible.
456 [Utilities.SerializationVisibility(Utilities.SerializationVisibility.Hidden)]
457 public bool IsVisible
461 // Check scroll bar enabled flag
467 // Do not show scroll bars while printing
468 if (this.axis == null ||
469 this.axis.ChartArea == null ||
470 this.axis.ChartArea.Common == null ||
471 this.axis.ChartArea.Common.ChartPicture == null ||
472 this.axis.ChartArea.Common.ChartPicture.isPrinting)
478 // Scrollbar is not supported on the sub axis
479 if(this.axis.IsSubAxis)
485 // Check if data scaleView size in percentage is less than 100%
486 return (GetDataViewPercentage() < 100.0) ? true : false;
492 #region Scroll bar painting methods
495 /// Draws axis scroll bar.
497 /// <param name="graph">Reference to the Chart Graphics object.</param>
498 internal void Paint( ChartGraphics graph )
500 // Scroll bar border width
503 // Scroll bar should not be visible
510 // Scrollbar not supported on sub axis
511 if( this.axis != null && this.axis.IsSubAxis)
517 // Set current scroll bar colors
518 _buttonCurrentColor = this._buttonColor;
519 _backCurrentColor = this._backColor;
520 _lineCurrentColor = this._lineColor;
522 // Make sure the current colors are not empty
523 if(_buttonCurrentColor == Color.Empty)
525 _buttonCurrentColor = this.axis.ChartArea.BackColor;
526 if(_buttonCurrentColor == Color.Empty)
528 _buttonCurrentColor = Color.DarkGray;
531 if(_backCurrentColor == Color.Empty)
533 _backCurrentColor = this.axis.ChartArea.BackColor;
534 if(_backCurrentColor == Color.Empty)
536 _backCurrentColor = Color.LightGray;
539 if(_lineCurrentColor == Color.Empty)
541 _lineCurrentColor = this.axis.LineColor;
542 if(_lineCurrentColor == Color.Empty)
544 _lineCurrentColor = Color.Black;
548 // Get scroll bar rectangle
549 RectangleF scrollBarRect = this.GetScrollBarRect();
551 // Fill scroll bar background
552 graph.FillRectangleRel(
555 ChartHatchStyle.None,
557 ChartImageWrapMode.Tile,
559 ChartImageAlignmentStyle.Center,
564 ChartDashStyle.Solid,
567 PenAlignment.Outset );
569 // Fill rectangle between to neighbour scroll bars
570 PaintScrollBarConnectionRect(graph, scrollBarRect, borderWidth);
572 // Get scroll bar client rectangle
573 SizeF borderRelativeSize = new SizeF(borderWidth, borderWidth);
574 borderRelativeSize = graph.GetRelativeSize(borderRelativeSize);
575 RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
576 scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height);
578 // Draw all button types
579 foreach (ScrollBarButtonType buttonType in Enum.GetValues(typeof(ScrollBarButtonType)))
581 // Get button rectangle
582 RectangleF buttonRect = this.GetScrollBarButtonRect(scrollBarClientRect, (ScrollBarButtonType)buttonType);
585 if(!buttonRect.IsEmpty)
587 PaintScrollBar3DButton(
590 ((ScrollBarButtonType)this._pressedButtonType) == (ScrollBarButtonType)buttonType,
591 (ScrollBarButtonType)buttonType);
595 if( this.ChartArea.Common.ProcessModeRegions )
597 SetHotRegionElement( this.ChartArea.Common );
602 /// Fills a connection rectangle between two scoll bars.
604 /// <param name="graph">Chart graphics.</param>
605 /// <param name="scrollBarRect">Scroll bar position.</param>
606 /// <param name="borderWidth">Border width.</param>
607 private void PaintScrollBarConnectionRect(
609 RectangleF scrollBarRect,
612 // Do not draw anything if scroll bar is vertical
613 if(this.axis.AxisPosition == AxisPosition.Left ||
614 this.axis.AxisPosition == AxisPosition.Right)
619 // Check if scoll bar is shown on the left/right sides of
620 // the plotting area and get their sizes in relative coordinates
622 float rightSize = 0f;
624 foreach(Axis a in this.axis.ChartArea.Axes)
626 if(a.AxisPosition == AxisPosition.Left && a.ScrollBar.IsVisible && a.ScrollBar.IsPositionedInside == this.axis.ScrollBar.IsPositionedInside)
628 leftSize = (float)a.ScrollBar.GetScrollBarRelativeSize();
630 if(a.AxisPosition == AxisPosition.Right && a.ScrollBar.IsVisible && a.ScrollBar.IsPositionedInside == this.axis.ScrollBar.IsPositionedInside)
632 rightSize = (float)a.ScrollBar.GetScrollBarRelativeSize();
636 // Prepare generic rectangle coordinates
637 RectangleF connectorRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
639 // Prepare coordinates and fill area to the left
642 connectorRect.X = scrollBarRect.X - leftSize;
643 connectorRect.Width = leftSize;
646 graph.FillRectangleRel(
649 ChartHatchStyle.None,
651 ChartImageWrapMode.Tile,
653 ChartImageAlignmentStyle.Center,
658 ChartDashStyle.Solid,
661 PenAlignment.Outset );
664 // Prepare coordinates and fill area to the right
667 connectorRect.X = scrollBarRect.Right;
668 connectorRect.Width = rightSize;
671 graph.FillRectangleRel(
674 ChartHatchStyle.None,
676 ChartImageWrapMode.Tile,
678 ChartImageAlignmentStyle.Center,
683 ChartDashStyle.Solid,
686 PenAlignment.Outset );
692 /// Draws 3D button in the scroll bar
694 /// <param name="graph">Chart graphics.</param>
695 /// <param name="buttonRect">Button position.</param>
696 /// <param name="pressedState">Indicates that button is pressed.</param>
697 /// <param name="buttonType">Button type to draw.</param>
698 internal void PaintScrollBar3DButton(
700 RectangleF buttonRect,
702 ScrollBarButtonType buttonType)
704 // Page Up/Down buttons do not require drawing
705 if(buttonType == ScrollBarButtonType.LargeIncrement || buttonType == ScrollBarButtonType.LargeDecrement)
710 // Get 3 levels of colors for button drawing
711 Color darkerColor = ChartGraphics.GetGradientColor(_buttonCurrentColor, Color.Black, 0.5);
712 Color darkestColor = ChartGraphics.GetGradientColor(_buttonCurrentColor, Color.Black, 0.8);
713 Color lighterColor = ChartGraphics.GetGradientColor(_buttonCurrentColor, Color.White, 0.5);
715 // Fill button rectangle background
716 graph.FillRectangleRel(
719 ChartHatchStyle.None,
721 ChartImageWrapMode.Tile,
723 ChartImageAlignmentStyle.Center,
727 (pressedState) ? 1 : 0,
728 ChartDashStyle.Solid,
731 PenAlignment.Outset );
733 // Check if 2 or 1 pixel border will be drawn (if size too small)
734 bool singlePixelBorder = this.Size <= 12;
736 // Draw 3D effect around the button when not pressed
739 // Get relative size of 1 pixel
740 SizeF pixelRelativeSize = new SizeF(1, 1);
741 pixelRelativeSize = graph.GetRelativeSize(pixelRelativeSize);
743 // Draw top/left border with button color
745 (singlePixelBorder) ? lighterColor : _buttonCurrentColor, 1, ChartDashStyle.Solid,
746 new PointF(buttonRect.X, buttonRect.Bottom),
747 new PointF(buttonRect.X, buttonRect.Top));
749 (singlePixelBorder) ? lighterColor : _buttonCurrentColor, 1, ChartDashStyle.Solid,
750 new PointF(buttonRect.Left, buttonRect.Y),
751 new PointF(buttonRect.Right, buttonRect.Y));
753 // Draw right/bottom border with the darkest color
755 (singlePixelBorder) ? darkerColor : darkestColor, 1, ChartDashStyle.Solid,
756 new PointF(buttonRect.Right, buttonRect.Bottom),
757 new PointF(buttonRect.Right, buttonRect.Top));
759 (singlePixelBorder) ? darkerColor : darkestColor, 1, ChartDashStyle.Solid,
760 new PointF(buttonRect.Left, buttonRect.Bottom),
761 new PointF(buttonRect.Right, buttonRect.Bottom));
763 if(!singlePixelBorder)
765 // Draw right/bottom border (offset 1) with the dark color
767 darkerColor, 1, ChartDashStyle.Solid,
768 new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height),
769 new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Top+pixelRelativeSize.Height));
771 darkerColor, 1, ChartDashStyle.Solid,
772 new PointF(buttonRect.Left+pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height),
773 new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height));
775 // Draw top/left border (offset 1) with lighter color
777 lighterColor, 1, ChartDashStyle.Solid,
778 new PointF(buttonRect.X+pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height),
779 new PointF(buttonRect.X+pixelRelativeSize.Width, buttonRect.Top+pixelRelativeSize.Height));
781 lighterColor, 1, ChartDashStyle.Solid,
782 new PointF(buttonRect.Left+pixelRelativeSize.Width, buttonRect.Y+pixelRelativeSize.Height),
783 new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Y+pixelRelativeSize.Height));
787 // Check axis orientation
788 bool verticalAxis = (this.axis.AxisPosition == AxisPosition.Left ||
789 this.axis.AxisPosition == AxisPosition.Right) ? true : false;
791 // Set graphics transformation for button pressed mode
792 float pressedShifting = (singlePixelBorder) ? 0.5f : 1f;
795 graph.TranslateTransform(pressedShifting, pressedShifting);
799 RectangleF buttonAbsRect = graph.GetAbsoluteRectangle(buttonRect);
800 float imageOffset = (singlePixelBorder) ? 2 : 3;
803 case(ScrollBarButtonType.SmallDecrement):
805 // Calculate triangal points position
806 PointF[] points = new PointF[3];
809 points[0].X = buttonAbsRect.X + imageOffset;
810 points[0].Y = buttonAbsRect.Y + (imageOffset + 1f);
811 points[1].X = buttonAbsRect.X + buttonAbsRect.Width/2f;
812 points[1].Y = buttonAbsRect.Bottom - imageOffset;
813 points[2].X = buttonAbsRect.Right - imageOffset;
814 points[2].Y = buttonAbsRect.Y + (imageOffset + 1f);
818 points[0].X = buttonAbsRect.X + imageOffset;
819 points[0].Y = buttonAbsRect.Y + buttonAbsRect.Height/2f;
820 points[1].X = buttonAbsRect.Right - (imageOffset + 1f);
821 points[1].Y = buttonAbsRect.Y + imageOffset;
822 points[2].X = buttonAbsRect.Right - (imageOffset + 1f);
823 points[2].Y = buttonAbsRect.Bottom - imageOffset;
826 using (Brush brush = new SolidBrush(this._lineCurrentColor))
828 graph.FillPolygon(brush, points);
832 case(ScrollBarButtonType.SmallIncrement):
834 // Calculate triangal points position
835 PointF[] points = new PointF[3];
838 points[0].X = buttonAbsRect.X + imageOffset;
839 points[0].Y = buttonAbsRect.Bottom - (imageOffset + 1f);
840 points[1].X = buttonAbsRect.X + buttonAbsRect.Width/2f;
841 points[1].Y = buttonAbsRect.Y + imageOffset;
842 points[2].X = buttonAbsRect.Right - imageOffset;
843 points[2].Y = buttonAbsRect.Bottom - (imageOffset + 1f);
847 points[0].X = buttonAbsRect.Right - imageOffset;
848 points[0].Y = buttonAbsRect.Y + buttonAbsRect.Height/2f;
849 points[1].X = buttonAbsRect.X + (imageOffset + 1f);
850 points[1].Y = buttonAbsRect.Y + imageOffset;
851 points[2].X = buttonAbsRect.X + (imageOffset + 1f);
852 points[2].Y = buttonAbsRect.Bottom - imageOffset;
855 using (Brush brush = new SolidBrush(this._lineCurrentColor))
857 graph.FillPolygon(brush, points);
861 case(ScrollBarButtonType.ZoomReset):
863 // Draw circule with a minus sign
864 using (Pen pen = new Pen(this._lineCurrentColor, 1))
866 graph.DrawEllipse(pen, buttonAbsRect.X + imageOffset - 0.5f, buttonAbsRect.Y + imageOffset - 0.5f, buttonAbsRect.Width - 2f * imageOffset, buttonAbsRect.Height - 2f * imageOffset);
867 graph.DrawLine(pen, buttonAbsRect.X + imageOffset + 1.5f, buttonAbsRect.Y + buttonAbsRect.Height / 2f - 0.5f, buttonAbsRect.Right - imageOffset - 2.5f, buttonAbsRect.Y + buttonAbsRect.Height / 2f - 0.5f);
873 // Reset graphics transformation for button pressed mode
876 graph.TranslateTransform(-pressedShifting, -pressedShifting);
882 #region Mouse events handling for the Scroll Bar
885 /// Mouse down event handler.
887 internal void ScrollBar_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
889 // Process left mouse button
890 if(e.Button == MouseButtons.Left && this.IsVisible)
892 // Remember position where mouse was clicked
893 _lastClickMousePosition = new PointF(e.X, e.Y);
894 _lastClickViewPosition = this.axis.ScaleView.Position;
896 // Check if button was pressed inside the scroll bar
897 ScrollBarButtonType buttonType;
898 if(GetElementByPixelPosition(e.X, e.Y, out buttonType))
900 this.ButtonClicked(buttonType, e.X, e.Y);
906 /// Mouse up event handler.
908 internal void ScrollBar_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
910 // If scroll bar button was pressed
911 if(this._pressedButtonType != int.MaxValue)
913 // Check if button was unpressed inside the reset zoom button
914 ScrollBarButtonType buttonType;
915 if(GetElementByPixelPosition(e.X, e.Y, out buttonType))
917 if(buttonType == ScrollBarButtonType.ZoomReset)
919 this.ButtonClicked(buttonType, e.X, e.Y);
923 // Stop scrolling timer
925 _mouseArguments = null;
927 // Clear pressed button state
928 this._pressedButtonType = int.MaxValue;
931 this.axis.Invalidate();
936 /// Mouse move event handler.
938 internal void ScrollBar_MouseMove(System.Windows.Forms.MouseEventArgs e, ref bool handled)
940 // If scroll bar button was pressed
941 if(this._pressedButtonType != int.MaxValue)
943 // Mouse move event should not be handled by any other chart elements
946 // Check if tracking buton was pressed
947 if((ScrollBarButtonType)this._pressedButtonType == ScrollBarButtonType.ThumbTracker)
949 // Proceed if last clicked position is known
950 if(!_lastClickMousePosition.IsEmpty)
952 this.ButtonClicked(ScrollBarButtonType.ThumbTracker, e.X, e.Y);
956 // Non tracking scroll bar button
959 // Check if mouse cursor is still in the pressed button's rectangle
960 bool inPressedButton = false;
961 ScrollBarButtonType buttonType;
962 if(GetElementByPixelPosition(e.X, e.Y, out buttonType))
964 if(buttonType == (ScrollBarButtonType)this._pressedButtonType)
966 inPressedButton = true;
970 // Clear pressed button state
973 // Stop scrolling timer
975 _mouseArguments = null;
977 // Clear pressed button state
978 this._pressedButtonType = int.MaxValue;
981 this.axis.Invalidate();
988 /// Scroll bar button was clicked by the user.
990 /// <param name="buttonType">Button type.</param>
991 /// <param name="x">X click position in pixels.</param>
992 /// <param name="y">Y click position in pixels.</param>
993 [SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Justification = "The timer is used for simulating scrolling behavior")]
994 private void ButtonClicked(ScrollBarButtonType buttonType, int x, int y)
996 // Call zoom reset on the second pass when button is released
997 if(buttonType != ScrollBarButtonType.ZoomReset ||
998 (ScrollBarButtonType)this._pressedButtonType == buttonType)
1001 //**************************************************
1002 //** Fire scroll bar button clicked event
1003 //**************************************************
1004 ScrollBarEventArgs eventArg = new ScrollBarEventArgs(this.axis, x, y, buttonType);
1005 this.axis.ScaleView.GetChartObject().OnAxisScrollBarClicked(eventArg);
1007 // Check if event was handled by user
1008 if(eventArg.IsHandled)
1010 // Save type of the button pressed
1011 this._pressedButtonType = (int)buttonType;
1016 //**************************************************
1017 //** Scroll data scaleView
1018 //**************************************************
1021 case(ScrollBarButtonType.SmallIncrement):
1022 this.axis.ScaleView.Scroll(ScrollType.SmallIncrement, true);
1024 case(ScrollBarButtonType.SmallDecrement):
1025 this.axis.ScaleView.Scroll(ScrollType.SmallDecrement, true);
1027 case(ScrollBarButtonType.LargeIncrement):
1028 this.axis.ScaleView.Scroll(ScrollType.LargeIncrement, true);
1030 case(ScrollBarButtonType.LargeDecrement):
1031 this.axis.ScaleView.Scroll(ScrollType.LargeDecrement, true);
1033 case(ScrollBarButtonType.ZoomReset):
1034 this.axis.ScaleView.ZoomReset(1, true);
1036 case(ScrollBarButtonType.ThumbTracker):
1038 if(!_lastClickMousePosition.IsEmpty &&
1039 !double.IsNaN(this._lastClickViewPosition) &&
1040 (_lastClickMousePosition.X != x || _lastClickMousePosition.Y != y))
1042 // Get scroll bar client rectangle
1043 RectangleF scrollBarRect = this.GetScrollBarRect();
1044 SizeF borderRelativeSize = new SizeF(1, 1);
1045 borderRelativeSize = this.GetRelativeSize(borderRelativeSize);
1046 RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
1047 scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height);
1049 // Check axis orientation
1050 bool verticalAxis = (this.axis.AxisPosition == AxisPosition.Left ||
1051 this.axis.AxisPosition == AxisPosition.Right) ? true : false;
1053 // Get button relative size
1054 SizeF buttonSize = new SizeF(scrollBarClientRect.Width, scrollBarClientRect.Height);
1055 buttonSize = this.GetAbsoluteSize(buttonSize);
1058 buttonSize.Height = buttonSize.Width;
1062 buttonSize.Width = buttonSize.Height;
1064 buttonSize = this.GetRelativeSize(buttonSize);
1066 // Calculate the distance in percentages the mouse was moved
1067 // from it's original (clicked) position.
1068 float distance = 0f;
1069 double trackingAreaSize = 0f;
1072 // Calculate max tracking size
1073 trackingAreaSize = scrollBarClientRect.Height - this.GetButtonsNumberAll() * buttonSize.Height;
1074 distance = _lastClickMousePosition.Y - y;
1076 // Convert to relative coordinates
1077 distance = distance * 100F / ((float)(this.axis.Common.Height - 1));
1081 trackingAreaSize = scrollBarClientRect.Width - this.GetButtonsNumberAll() * buttonSize.Width;
1082 distance = x - _lastClickMousePosition.X;
1084 // Convert to relative coordinates
1085 distance = distance * 100F / ((float)(this.axis.Common.Width - 1));
1088 // Convert to percentages from total tracking area
1089 distance = (float)(distance / (trackingAreaSize / 100f));
1091 // Get axis scale size without margins
1092 double axisScaleSize = Math.Abs(
1093 (this.axis.maximum - this.axis.marginView) -
1094 (this.axis.minimum + this.axis.marginView));
1096 // Calculate the same percentage using axis scale
1097 distance = (float)(distance * (axisScaleSize/100f));
1099 // Round the distance to the minimum scroll line size
1100 if(!double.IsNaN(axis.ScaleView.SmallScrollMinSize) && axis.ScaleView.SmallScrollMinSize != 0.0)
1102 double minSize = ChartHelper.GetIntervalSize(0, axis.ScaleView.SmallScrollMinSize, axis.ScaleView.SmallScrollMinSizeType);
1104 double rounder = (Math.Round(distance / minSize));
1105 distance = (float)(rounder * minSize);
1108 // Scroll scaleView into the new position
1109 this.axis.ScaleView.Scroll(this._lastClickViewPosition + ((this.axis.IsReversed) ? -1 : 1) * distance, true);
1115 //************************************************************
1116 //** Initialize timer for repeating scroll (if mouse is hold)
1117 //************************************************************
1119 // Reset mouse arguments
1120 _mouseArguments = null;
1122 if(buttonType != ScrollBarButtonType.ThumbTracker && buttonType != ScrollBarButtonType.ZoomReset)
1124 // Remember last mouse position
1125 _mouseArguments = new MouseEventArgs(MouseButtons.Left, 1, x, y, 0);
1128 if(!_scrollTimer.Enabled)
1130 _scrollTimer.Tick += new EventHandler(ScrollingTimerEventProcessor);
1131 _scrollTimer.Interval = 400;
1132 _scrollTimer.Start();
1137 //************************************************************
1138 //** Invalidate chart
1139 //************************************************************
1141 // Save type of the button pressed
1142 this._pressedButtonType = (int)buttonType;
1145 this.axis.Invalidate();
1149 /// This is the method to run when the timer is raised.
1150 /// Used to repetedly scroll data scaleView while mouse button is pressed.
1152 /// <param name="myObject">Object.</param>
1153 /// <param name="myEventArgs">Event arguments.</param>
1154 [SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Justification = "The timer is used for simulating scrolling behavior")]
1155 private void ScrollingTimerEventProcessor(Object myObject, EventArgs myEventArgs)
1157 // Simulate mouse move events
1158 if(_mouseArguments != null)
1160 _scrollTimer.Interval = 200;
1161 this.ScrollBar_MouseDown(null, _mouseArguments);
1166 /// This method fills hot region collection with scroll bar elements.
1167 /// Possible elements are all scroll bar buttons and scroll bar background
1168 /// which performs PgUp/PgDn action.
1170 /// <param name="common">Common Elements</param>
1171 private void SetHotRegionElement( CommonElements common )
1173 // Check if mouse button was clicked in the scroll bar
1174 RectangleF scrollBarRect = this.GetScrollBarRect();
1176 // Get scroll bar client rectangle
1177 SizeF borderRelativeSize = new SizeF(1, 1);
1178 borderRelativeSize = this.GetRelativeSize(borderRelativeSize);
1179 RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
1180 scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height);
1182 ChartElementType buttonType = ChartElementType.Nothing;
1184 // Fill collection with scroll buttons rectangles.
1185 foreach(object type in Enum.GetValues(typeof(ScrollBarButtonType)))
1188 // Convert Scroll Bar Button type enum to Chart Element AxisName enum.
1189 switch( (ScrollBarButtonType)type )
1191 case ScrollBarButtonType.SmallIncrement:
1192 buttonType = ChartElementType.ScrollBarSmallIncrement;
1194 case ScrollBarButtonType.LargeIncrement:
1195 buttonType = ChartElementType.ScrollBarLargeIncrement;
1197 case ScrollBarButtonType.LargeDecrement:
1198 buttonType = ChartElementType.ScrollBarLargeDecrement;
1200 case ScrollBarButtonType.ThumbTracker:
1201 buttonType = ChartElementType.ScrollBarThumbTracker;
1203 case ScrollBarButtonType.SmallDecrement:
1204 buttonType = ChartElementType.ScrollBarSmallDecrement;
1206 case ScrollBarButtonType.ZoomReset:
1207 buttonType = ChartElementType.ScrollBarZoomReset;
1211 // Get button rectangle
1212 RectangleF buttonRect = this.GetScrollBarButtonRect(scrollBarClientRect, (ScrollBarButtonType)type);
1214 common.HotRegionsList.AddHotRegion( buttonRect, this, buttonType, true );
1220 /// Detects the scroll bar elements by pixel position.
1221 /// Possible elements are all scroll bar buttons and scroll bar background
1222 /// which performs PgUp/PgDn action.
1224 /// <param name="x">X coordinate in pixels.</param>
1225 /// <param name="y">Y coordinate in pixels.</param>
1226 /// <param name="buttonType">Return button type.</param>
1227 /// <returns>True if position is in the scroll bar.</returns>
1228 private bool GetElementByPixelPosition(float x, float y, out ScrollBarButtonType buttonType)
1230 // Set initial values
1231 buttonType = ScrollBarButtonType.ThumbTracker;
1233 // Convert mouse click coordinates to relative
1234 PointF position = new PointF(x, y);
1235 position.X = x * 100F / ((float)(this.axis.Common.Width - 1));
1236 position.Y = y * 100F / ((float)(this.axis.Common.Height - 1));
1238 // Check if mouse button was clicked in the scroll bar
1239 RectangleF scrollBarRect = this.GetScrollBarRect();
1240 if(scrollBarRect.Contains(position))
1242 // Get scroll bar client rectangle
1243 SizeF borderRelativeSize = new SizeF(1, 1);
1244 borderRelativeSize = this.GetRelativeSize(borderRelativeSize);
1245 RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
1246 scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height);
1248 //******************************************************************
1249 //** Check if scroll bar button was clicked
1250 //******************************************************************
1251 foreach(object type in Enum.GetValues(typeof(ScrollBarButtonType)))
1253 // Get button rectangle
1254 RectangleF buttonRect = this.GetScrollBarButtonRect(scrollBarClientRect, (ScrollBarButtonType)type);
1256 // Check if position is inside the button
1257 if(buttonRect.Contains(position))
1259 buttonType = (ScrollBarButtonType)type;
1265 // Pixel position is outside scroll bar area
1271 #region Scroll bar helper methods
1274 /// Returns scroll bar button rectangle position in relative coordinates.
1276 /// <param name="scrollBarClientRect">Scroll bar client rectangle.</param>
1277 /// <param name="buttonType">Scroll bar button type.</param>
1278 /// <returns>Scroll bar position.</returns>
1279 internal RectangleF GetScrollBarButtonRect(RectangleF scrollBarClientRect, ScrollBarButtonType buttonType)
1281 // Initialize button rectangle
1282 RectangleF buttonRect = new RectangleF(scrollBarClientRect.Location, scrollBarClientRect.Size);
1284 // Check axis orientation
1285 bool verticalAxis = (this.axis.AxisPosition == AxisPosition.Left ||
1286 this.axis.AxisPosition == AxisPosition.Right) ? true : false;
1288 // Get relative size of 1 pixel
1289 SizeF pixelRelativeSize = new SizeF(1, 1);
1290 pixelRelativeSize = this.GetRelativeSize(pixelRelativeSize);
1292 // Get button relative size
1293 SizeF buttonSize = new SizeF(scrollBarClientRect.Width, scrollBarClientRect.Height);
1294 buttonSize = this.GetAbsoluteSize(buttonSize);
1297 buttonSize.Height = buttonSize.Width;
1301 buttonSize.Width = buttonSize.Height;
1303 buttonSize = this.GetRelativeSize(buttonSize);
1305 // Set common position sizes
1306 buttonRect.Width = buttonSize.Width;
1307 buttonRect.Height = buttonSize.Height;
1310 buttonRect.X = scrollBarClientRect.X;
1314 buttonRect.Y = scrollBarClientRect.Y;
1317 // Calculate scroll bar buttons position
1320 case(ScrollBarButtonType.LargeDecrement):
1321 case(ScrollBarButtonType.LargeIncrement):
1322 case(ScrollBarButtonType.ThumbTracker):
1324 // Get tracker button position and size first
1327 // Calculate tracker size
1328 double trackingAreaSize = scrollBarClientRect.Height - this.GetButtonsNumberAll() * buttonSize.Height;
1329 buttonRect.Height = (float)(this.GetDataViewPercentage() * (trackingAreaSize / 100f));
1331 // Check if tracker size is too small
1332 if(buttonRect.Height < pixelRelativeSize.Height * 6f)
1334 buttonRect.Height = pixelRelativeSize.Height * 6f;
1337 // Calculate tracker position
1338 if(!this.axis.IsReversed)
1340 buttonRect.Y = scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height - buttonRect.Height;
1341 buttonRect.Y -= (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f));
1342 if(buttonRect.Y < scrollBarClientRect.Y + this.GetButtonsNumberTop()*buttonSize.Height + ((this.GetButtonsNumberTop() == 0) ? 0 : pixelRelativeSize.Height))
1344 buttonRect.Y = scrollBarClientRect.Y + this.GetButtonsNumberTop()*buttonSize.Height + ((this.GetButtonsNumberTop() == 0) ? 0 : pixelRelativeSize.Height);
1349 buttonRect.Y = scrollBarClientRect.Top + this.GetButtonsNumberTop()*buttonSize.Height;
1350 buttonRect.Y += (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f));
1351 if((buttonRect.Y + buttonRect.Height) > scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Height))
1353 buttonRect.Y = (scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height) - buttonRect.Height - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Height);
1359 // Calculate tracker size
1360 double trackingAreaSize = scrollBarClientRect.Width - this.GetButtonsNumberAll() * buttonSize.Width;
1361 buttonRect.Width = (float)(this.GetDataViewPercentage() * (trackingAreaSize / 100f));
1363 // Check if tracker size is too small
1364 if(buttonRect.Width < pixelRelativeSize.Width * 6f)
1366 buttonRect.Width = pixelRelativeSize.Width * 6f;
1369 // Calculate tracker position
1370 if(!this.axis.IsReversed)
1372 buttonRect.X = scrollBarClientRect.X + this.GetButtonsNumberTop() * buttonSize.Width;
1373 buttonRect.X += (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f));
1374 if((buttonRect.X + buttonRect.Width) > scrollBarClientRect.Right - this.GetButtonsNumberBottom()*buttonSize.Width - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Width))
1376 buttonRect.X = (scrollBarClientRect.Right - buttonRect.Width) - this.GetButtonsNumberBottom()*buttonSize.Width - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Width);
1381 buttonRect.X = scrollBarClientRect.Right - this.GetButtonsNumberBottom()*buttonSize.Width - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Width) - buttonRect.Width;
1382 buttonRect.X -= (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f));
1383 if(buttonRect.X < scrollBarClientRect.X + this.GetButtonsNumberTop()*buttonSize.Width)
1385 buttonRect.X = scrollBarClientRect.X + this.GetButtonsNumberTop()*buttonSize.Width;
1391 // Get page up region rectangle depending on the tracker position
1392 if(buttonType == ScrollBarButtonType.LargeDecrement)
1396 buttonRect.Y = buttonRect.Bottom + pixelRelativeSize.Height;
1397 buttonRect.Height = (scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height - pixelRelativeSize.Height) - buttonRect.Y;
1401 float x = scrollBarClientRect.X +
1402 this.GetButtonsNumberTop() * buttonSize.Width +
1403 pixelRelativeSize.Width;
1405 buttonRect.Width = buttonRect.X - x;
1410 // Get page down region rectangle depending on the tracker position
1411 else if(buttonType == ScrollBarButtonType.LargeIncrement)
1415 float y = scrollBarClientRect.Y +
1416 this.GetButtonsNumberTop() * buttonSize.Height +
1417 pixelRelativeSize.Height;
1419 buttonRect.Height = buttonRect.Y - y;
1424 buttonRect.X = buttonRect.Right + pixelRelativeSize.Width;
1425 buttonRect.Width = (scrollBarClientRect.Right - this.GetButtonsNumberBottom()*buttonSize.Width - pixelRelativeSize.Height) - buttonRect.X;
1432 case(ScrollBarButtonType.SmallDecrement):
1433 if(this._scrollBarButtonStyle == ScrollBarButtonStyles.All ||
1434 this._scrollBarButtonStyle == ScrollBarButtonStyles.SmallScroll)
1438 buttonRect.Y = scrollBarClientRect.Bottom - buttonRect.Height;
1442 buttonRect.X = scrollBarClientRect.X + (this.GetButtonsNumberTop()-1f)*buttonSize.Width;
1443 buttonRect.X += (this.GetButtonsNumberTop() == 1) ? 0 : pixelRelativeSize.Width;
1448 buttonRect = RectangleF.Empty;
1452 case(ScrollBarButtonType.SmallIncrement):
1453 if(this._scrollBarButtonStyle == ScrollBarButtonStyles.All ||
1454 this._scrollBarButtonStyle == ScrollBarButtonStyles.SmallScroll)
1458 buttonRect.Y = scrollBarClientRect.Y + (this.GetButtonsNumberTop()-1f) * buttonSize.Height;
1459 buttonRect.Y += (this.GetButtonsNumberTop() == 1) ? 0 : pixelRelativeSize.Height;
1463 buttonRect.X = scrollBarClientRect.Right - buttonRect.Width;
1468 buttonRect = RectangleF.Empty;
1472 case(ScrollBarButtonType.ZoomReset):
1473 if(this._scrollBarButtonStyle == ScrollBarButtonStyles.All ||
1474 this._scrollBarButtonStyle == ScrollBarButtonStyles.ResetZoom)
1478 buttonRect.Y = scrollBarClientRect.Y;
1482 buttonRect.X = scrollBarClientRect.X;
1487 buttonRect = RectangleF.Empty;
1496 /// Returns scroll bar rectangle position in relative coordinates.
1498 /// <returns>Scroll bar position.</returns>
1499 internal RectangleF GetScrollBarRect()
1501 // Get scroll bar relative size
1502 float scrollBarSize = (float)this.GetScrollBarRelativeSize();
1504 // Get relative size of the axis line (Note: Code removed for now. -- AG)
1505 //SizeF axisLineSize = new SizeF(axis.LineWidth, axis.LineWidth);
1506 //axisLineSize.Width = axisLineSize.Width * 100F / ((float)(this.axis.Common.Width - 1));
1507 //axisLineSize.Height = axisLineSize.Height * 100F / ((float)(this.axis.Common.Height - 1));
1509 // Check if scroll bar is positioned next to PlotArea or ChartArea
1510 RectangleF areaPosition = axis.PlotAreaPosition.ToRectangleF();
1511 if(!this.IsPositionedInside)
1513 areaPosition = axis.ChartArea.Position.ToRectangleF();
1515 // Reduce rectangle size by scroll bar size
1516 foreach(Axis a in this.ChartArea.Axes)
1518 if(a.ScrollBar.IsVisible && !a.ScrollBar.IsPositionedInside)
1520 float size = (float)a.ScrollBar.GetScrollBarRelativeSize();
1521 switch( a.AxisPosition )
1523 case AxisPosition.Left:
1524 areaPosition.X += size;
1525 areaPosition.Width -= size;
1527 case AxisPosition.Right:
1528 areaPosition.Width -= size;
1530 case AxisPosition.Bottom:
1531 areaPosition.Height -= size;
1533 case AxisPosition.Top:
1534 areaPosition.Y += size;
1535 areaPosition.Height -= size;
1542 // Get bar position depending on the axis type
1543 RectangleF barPosition = RectangleF.Empty;
1544 if(this.axis.PlotAreaPosition != null)
1546 switch( axis.AxisPosition )
1548 case AxisPosition.Left:
1549 barPosition.Y = areaPosition.Y;
1550 barPosition.Height = areaPosition.Height;
1552 ( (this.IsPositionedInside) ? (float)(axis.GetAxisPosition(true)) : areaPosition.X) - scrollBarSize;// - axisLineSize.Width / 2f;
1553 barPosition.Width = scrollBarSize;
1555 case AxisPosition.Right:
1556 barPosition.Y = areaPosition.Y;
1557 barPosition.Height = areaPosition.Height;
1559 (this.IsPositionedInside) ? (float)axis.GetAxisPosition(true) : areaPosition.Right;// + axisLineSize.Width / 2f;
1560 barPosition.Width = scrollBarSize;
1562 case AxisPosition.Bottom:
1563 barPosition.X = areaPosition.X;
1564 barPosition.Width = areaPosition.Width;
1566 (this.IsPositionedInside) ? (float)axis.GetAxisPosition(true) : areaPosition.Bottom;// + axisLineSize.Height / 2f;
1567 barPosition.Height = scrollBarSize;
1569 case AxisPosition.Top:
1570 barPosition.X = areaPosition.X;
1571 barPosition.Width = areaPosition.Width;
1573 ( (this.IsPositionedInside) ? (float)axis.GetAxisPosition(true) : areaPosition.Y) - scrollBarSize;// - axisLineSize.Height / 2f;
1574 barPosition.Height = scrollBarSize;
1583 /// Internal helper method which returns the relative scroll bar size.
1585 /// <returns>Relative scroll bar size.</returns>
1586 internal double GetScrollBarRelativeSize()
1588 // Scroll bar is not shown in 3D
1589 if(this.axis.ChartArea.Area3DStyle.Enable3D || this.axis.ChartArea.chartAreaIsCurcular)
1595 // Scrollbar not supported on sub axis
1596 if( this.axis != null && this.axis.IsSubAxis)
1603 // Get scroll bar relative size depending on the axis location
1604 if(this.axis.AxisPosition == AxisPosition.Left || this.axis.AxisPosition == AxisPosition.Right)
1606 return this._scrollBarSize * 100F / ((float)(this.axis.Common.Width - 1));
1610 return this._scrollBarSize * 100F / ((float)(this.axis.Common.Height - 1));
1615 /// Returns the percentage size (0-100%) of the data scaleView comparing to
1616 /// the axis scale minimum and maximum values.
1618 /// <returns>Size of the data scaleView in percentage.</returns>
1619 private double GetDataViewPercentage()
1621 double viewPercentage = 100.0;
1623 // Check if axis data scaleView properties are set
1624 if(this.axis != null &&
1625 !double.IsNaN(this.axis.ScaleView.Position) &&
1626 !double.IsNaN(this.axis.ScaleView.Size))
1628 // Get data scaleView size
1629 double dataViewSize = ChartHelper.GetIntervalSize(
1630 this.axis.ScaleView.Position,
1631 this.axis.ScaleView.Size,
1632 this.axis.ScaleView.SizeType);
1634 // Get axis scale size without margins
1635 double minimum = this.axis.minimum + this.axis.marginView;
1636 double maximum = this.axis.maximum - this.axis.marginView;
1637 if(this.axis.ScaleView.Position < minimum)
1639 minimum = this.axis.ScaleView.Position;
1641 if((this.axis.ScaleView.Position + dataViewSize) > maximum)
1643 maximum = this.axis.ScaleView.Position + dataViewSize;
1645 double axisScaleSize = Math.Abs(minimum - maximum);
1647 // Check if data scaleView is smaller than axis scale and if it is find the pecentage
1648 if(dataViewSize < axisScaleSize)
1650 viewPercentage = dataViewSize / (axisScaleSize / 100.0);
1654 return viewPercentage;
1658 /// Returns the the data scaleView position in percentage (0-100%) using
1659 /// the axis scale minimum and maximum values.
1661 /// <returns>Data scaleView position in percentage.</returns>
1662 private double GetDataViewPositionPercentage()
1664 double viewPosition = 0.0;
1666 // Check if axis data scaleView properties are set
1667 if(this.axis != null &&
1668 !double.IsNaN(this.axis.ScaleView.Position) &&
1669 !double.IsNaN(this.axis.ScaleView.Size))
1671 // Get data scaleView size
1672 double dataViewSize = ChartHelper.GetIntervalSize(
1673 this.axis.ScaleView.Position,
1674 this.axis.ScaleView.Size,
1675 this.axis.ScaleView.SizeType);
1677 // Get axis scale size without margins
1678 double minimum = this.axis.minimum + this.axis.marginView;
1679 double maximum = this.axis.maximum - this.axis.marginView;
1680 if(this.axis.ScaleView.Position < minimum)
1682 minimum = this.axis.ScaleView.Position;
1684 if((this.axis.ScaleView.Position + dataViewSize) > maximum)
1686 maximum = this.axis.ScaleView.Position + dataViewSize;
1688 double axisScaleSize = Math.Abs(minimum - maximum);
1690 // Calculate data scaleView position in percentage
1691 viewPosition = (this.axis.ScaleView.Position - (minimum)) / (axisScaleSize / 100.0);
1694 return viewPosition;
1698 /// Get total number of buttons in the scroll bar (except tracker).
1700 /// <returns>Number of buttons.</returns>
1701 private int GetButtonsNumberAll()
1703 int buttonNumber = 0;
1704 if((this._scrollBarButtonStyle & ScrollBarButtonStyles.ResetZoom) == ScrollBarButtonStyles.ResetZoom)
1708 if((this._scrollBarButtonStyle & ScrollBarButtonStyles.SmallScroll) == ScrollBarButtonStyles.SmallScroll)
1713 return buttonNumber;
1717 /// Get number of buttons in the top (left) part of the scroll bar.
1719 /// <returns>Number of buttons.</returns>
1720 private int GetButtonsNumberTop()
1722 int buttonNumber = 0;
1723 if((this._scrollBarButtonStyle & ScrollBarButtonStyles.ResetZoom) == ScrollBarButtonStyles.ResetZoom)
1727 if((this._scrollBarButtonStyle & ScrollBarButtonStyles.SmallScroll) == ScrollBarButtonStyles.SmallScroll)
1732 return buttonNumber;
1736 /// Get number of buttons in the bottom (right) part of the scroll bar.
1738 /// <returns>Number of buttons.</returns>
1739 private int GetButtonsNumberBottom()
1741 int buttonNumber = 0;
1742 if((this._scrollBarButtonStyle & ScrollBarButtonStyles.SmallScroll) == ScrollBarButtonStyles.SmallScroll)
1747 return buttonNumber;
1752 #region Coordinate convertion methods
1755 /// Converts Relative size to Absolute size
1757 /// <param name="relative">Relative size in %</param>
1758 /// <returns>Absolute size</returns>
1759 internal SizeF GetAbsoluteSize( SizeF relative )
1761 SizeF absolute = SizeF.Empty;
1763 // Convert relative coordinates to absolute coordinates
1764 absolute.Width = relative.Width * (this.axis.Common.Width - 1) / 100F;
1765 absolute.Height = relative.Height * (this.axis.Common.Height - 1) / 100F;
1767 // Return Absolute coordinates
1772 /// Converts Absolute size to Relative size
1774 /// <param name="size">Absolute size</param>
1775 /// <returns>Relative size</returns>
1776 internal SizeF GetRelativeSize( SizeF size )
1778 SizeF relative = SizeF.Empty;
1780 // Convert absolute coordinates to relative coordinates
1781 relative.Width = size.Width * 100F / ((float)(this.axis.Common.Width - 1));
1782 relative.Height = size.Height * 100F / ((float)(this.axis.Common.Height - 1));
1784 // Return relative coordinates
1790 #region IDisposable Members
1793 /// Releases unmanaged and - optionally - managed resources
1795 /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
1796 protected virtual void Dispose(bool disposing)
1800 // Dispose managed resources
1801 if (this._scrollTimer != null)
1803 this._scrollTimer.Dispose();
1804 this._scrollTimer = null;
1810 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
1812 public void Dispose()
1815 GC.SuppressFinalize(this);
1822 /// The arguments for a scrollbar event.
1824 public class ScrollBarEventArgs : EventArgs
1826 #region Private fields
1828 // Private fields for properties values storage
1829 private Axis _axis = null;
1830 private bool _isHandled = false;
1831 private int _mousePositionX = 0;
1832 private int _mousePositionY = 0;
1833 private ScrollBarButtonType _buttonType = ScrollBarButtonType.ThumbTracker;
1837 #region Constructors
1840 /// ScrollBarEventArgs constructor.
1842 /// <param name="axis">Axis containing the scrollbar.</param>
1843 /// <param name="x">X position of mouse cursor.</param>
1844 /// <param name="y">Y position of mouse cursor.</param>
1845 /// <param name="buttonType">Button type of the button clicked.</param>
1846 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
1847 Justification = "X and Y are cartesian coordinates and well understood")]
1848 public ScrollBarEventArgs(Axis axis, int x, int y, ScrollBarButtonType buttonType)
1851 this._mousePositionX = x;
1852 this._mousePositionY = y;
1853 this._buttonType = buttonType;
1861 /// Axis containing the scrollbar of the event.
1864 SRDescription("DescriptionAttributeAxis"),
1875 /// ChartArea containing the scrollbar of the event.
1878 SRDescription("DescriptionAttributeChartArea"),
1880 public ChartArea ChartArea
1884 return _axis.ChartArea;
1889 /// Button type of the scrollbar button clicked.
1892 SRDescription("DescriptionAttributeScrollBarEventArgs_ButtonType"),
1894 public ScrollBarButtonType ButtonType
1903 /// Indicates if the event is handled by the user and no further processing is required.
1906 SRDescription("DescriptionAttributeScrollBarEventArgs_Handled"),
1908 public bool IsHandled
1921 /// X position of mouse cursor.
1924 SRDescription("DescriptionAttributeScrollBarEventArgs_MousePositionX"),
1926 public int MousePositionX
1930 return _mousePositionX;
1935 /// Y position of mouse cursor.
1938 SRDescription("DescriptionAttributeScrollBarEventArgs_MousePositionY"),
1940 public int MousePositionY
1944 return _mousePositionY;
1952 #endif // #if WINFORMS_CONTROL