1 //-------------------------------------------------------------
2 // <copyright company=
\92Microsoft Corporation
\92>
3 // Copyright © Microsoft Corporation. All Rights Reserved.
5 //-------------------------------------------------------------
6 // @owner=alexgor, deliant
7 //=================================================================
8 // File: RectangleAnnotation.cs
10 // Namespace: System.Web.UI.WebControls[Windows.Forms].Charting
12 // Classes: PolylineAnnotation, PolygonAnnotation
14 // Purpose: Polyline and polygon annotation classes.
18 //===================================================================
20 #region Used namespace
22 using System.Collections;
23 using System.Collections.Specialized;
24 using System.ComponentModel;
25 using System.ComponentModel.Design;
28 using System.Drawing.Design;
29 using System.Drawing.Text;
30 using System.Drawing.Drawing2D;
31 using System.Diagnostics.CodeAnalysis;
33 using System.Windows.Forms;
34 using System.Globalization;
35 using System.Reflection;
36 using System.ComponentModel.Design.Serialization;
37 using System.Windows.Forms.DataVisualization.Charting;
38 using System.Windows.Forms.DataVisualization.Charting.Data;
39 using System.Windows.Forms.DataVisualization.Charting.ChartTypes;
40 using System.Windows.Forms.DataVisualization.Charting.Utilities;
41 using System.Windows.Forms.DataVisualization.Charting.Borders3D;
42 using System.Collections.ObjectModel;
47 using System.Web.UI.DataVisualization.Charting;
48 using System.Web.UI.DataVisualization.Charting.Data;
49 using System.Web.UI.DataVisualization.Charting.Utilities;
50 using System.Web.UI.DataVisualization.Charting.Borders3D;
51 using System.Collections.ObjectModel;
57 namespace System.Windows.Forms.DataVisualization.Charting
60 namespace System.Web.UI.DataVisualization.Charting
65 /// <b>PolylineAnnotation</b> is a class that represents a polyline annotation.
68 SRDescription("DescriptionAttributePolylineAnnotation_PolylineAnnotation"),
70 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Polyline")]
72 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
73 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
75 public class PolylineAnnotation : Annotation
79 // Path with polygon points.
80 private GraphicsPath _defaultGraphicsPath = new GraphicsPath();
81 private GraphicsPath _graphicsPath;
83 // Indicates that path was changed
84 internal bool pathChanged = false;
86 // Collection of path points exposed at design-time
87 private AnnotationPathPointCollection _pathPoints;
89 // Indicate that filled polygon must be drawn
90 internal bool isPolygon = false;
92 // Indicates that annotation will be placed using free-draw style
93 internal bool isFreeDrawPlacement = false;
95 // Line start/end caps
96 private LineAnchorCapStyle _startCap = LineAnchorCapStyle.None;
97 private LineAnchorCapStyle _endCap = LineAnchorCapStyle.None;
101 #region Construction and Initialization
104 /// Default public constructor.
106 public PolylineAnnotation()
109 _pathPoints = new AnnotationPathPointCollection(this);
111 _graphicsPath = _defaultGraphicsPath;
118 #region Polyline Visual Attributes
121 /// Gets or sets a cap style used at the start of an annotation line.
122 /// <seealso cref="EndCap"/>
125 /// A <see cref="LineAnchorCapStyle"/> value used for a cap style used at the start of an annotation line.
128 SRCategory("CategoryAttributeAppearance"),
129 DefaultValue(LineAnchorCapStyle.None),
130 SRDescription("DescriptionAttributeStartCap3"),
132 virtual public LineAnchorCapStyle StartCap
146 /// Gets or sets a cap style used at the end of an annotation line.
147 /// <seealso cref="StartCap"/>
150 /// A <see cref="LineAnchorCapStyle"/> value used for a cap style used at the end of an annotation line.
153 SRCategory("CategoryAttributeAppearance"),
154 DefaultValue(LineAnchorCapStyle.None),
155 SRDescription("DescriptionAttributeStartCap3"),
157 virtual public LineAnchorCapStyle EndCap
172 #region Non Applicable Annotation Appearance Attributes (set as Non-Browsable)
175 /// Not applicable to this annotation type.
178 /// A <see cref="ContentAlignment"/> value.
181 SRCategory("CategoryAttributeAppearance"),
183 DefaultValue(typeof(ContentAlignment), "MiddleCenter"),
185 override public ContentAlignment Alignment
189 return base.Alignment;
193 base.Alignment = value;
198 /// Gets or sets an annotation's text style.
199 /// <seealso cref="Font"/>
200 /// <seealso cref="ForeColor"/>
203 /// A <see cref="TextStyle"/> value used to draw an annotation's text.
206 [EditorBrowsable(EditorBrowsableState.Never)]
207 public override TextStyle TextStyle
211 return base.TextStyle;
215 base.TextStyle = value;
220 /// Not applicable to this annotation type.
221 /// <seealso cref="Font"/>
224 /// A <see cref="Color"/> value.
227 SRCategory("CategoryAttributeAppearance"),
229 DefaultValue(typeof(Color), "Black"),
230 SRDescription("DescriptionAttributeForeColor"),
231 TypeConverter(typeof(ColorConverter)),
232 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base)
234 override public Color ForeColor
238 return base.ForeColor;
242 base.ForeColor = value;
247 /// Not applicable to this annotation type.
248 /// <seealso cref="ForeColor"/>
251 /// A <see cref="Font"/> object.
254 SRCategory("CategoryAttributeAppearance"),
256 DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"),
258 override public Font Font
271 /// Not applicable to this annotation type.
274 SRCategory("CategoryAttributeAppearance"),
276 DefaultValue(typeof(Color), ""),
277 NotifyParentPropertyAttribute(true),
278 TypeConverter(typeof(ColorConverter)),
279 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base)
281 override public Color BackColor
285 return base.BackColor;
289 base.BackColor = value;
294 /// Not applicable to this annotation type.
297 SRCategory("CategoryAttributeAppearance"),
299 DefaultValue(ChartHatchStyle.None),
300 NotifyParentPropertyAttribute(true),
301 Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base)
303 override public ChartHatchStyle BackHatchStyle
307 return base.BackHatchStyle;
311 base.BackHatchStyle = value;
316 /// Not applicable to this annotation type.
319 SRCategory("CategoryAttributeAppearance"),
321 DefaultValue(GradientStyle.None),
322 NotifyParentPropertyAttribute(true),
323 Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base)
325 override public GradientStyle BackGradientStyle
329 return base.BackGradientStyle;
333 base.BackGradientStyle = value;
338 /// Not applicable to this annotation type.
341 SRCategory("CategoryAttributeAppearance"),
343 DefaultValue(typeof(Color), ""),
344 NotifyParentPropertyAttribute(true),
345 TypeConverter(typeof(ColorConverter)),
346 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base)
348 override public Color BackSecondaryColor
352 return base.BackSecondaryColor;
356 base.BackSecondaryColor = value;
365 /// Gets or sets an annotation's type name.
368 /// This property is used to get the name of each annotation type
369 /// (e.g. Line, Rectangle, Ellipse).
371 /// This property is for internal use and is hidden at design and run time.
375 SRCategory("CategoryAttributeMisc"),
378 EditorBrowsableAttribute(EditorBrowsableState.Never),
379 DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
380 SerializationVisibilityAttribute(SerializationVisibility.Hidden),
381 SRDescription("DescriptionAttributeAnnotationType"),
383 public override string AnnotationType
392 /// Gets or sets an annotation selection points style.
395 /// A <see cref="SelectionPointsStyle"/> value that represents the annotation
399 /// This property is for internal use and is hidden at design and run time.
402 SRCategory("CategoryAttributeAppearance"),
403 DefaultValue(SelectionPointsStyle.Rectangle),
404 ParenthesizePropertyNameAttribute(true),
406 EditorBrowsableAttribute(EditorBrowsableState.Never),
407 DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
408 SerializationVisibilityAttribute(SerializationVisibility.Hidden),
409 SRDescription("DescriptionAttributeSelectionPointsStyle"),
411 override internal SelectionPointsStyle SelectionPointsStyle
415 return SelectionPointsStyle.Rectangle;
420 /// Gets or sets a flag that determines whether an annotation should be placed using the free-draw mode.
423 /// <b>True</b> if an annotation should be placed using free-draw mode,
424 /// <b>false</b> otherwise. Defaults to <b>false</b>.
427 /// Two different placement modes are supported when the Annotation.BeginPlacement
428 /// method is called. Set this property to <b>true</b> to switch from the default
429 /// mode to free-draw mode, which allows the caller to free-draw while moving the mouse cursor.
432 SRCategory("CategoryAttributeMisc"),
434 SRDescription("DescriptionAttributeFreeDrawPlacement"),
435 #if !Microsoft_CONTROL
437 EditorBrowsable(EditorBrowsableState.Never),
438 #endif // !Microsoft_CONTROL
440 virtual public bool IsFreeDrawPlacement
444 return isFreeDrawPlacement;
448 isFreeDrawPlacement = value;
453 /// Gets or sets the path points of a polyline at run-time.
456 /// A <see cref="GraphicsPath"/> object with the polyline shape.
459 /// A polyline must use coordinates relative to an annotation object, where (0,0) is
460 /// the top-left coordinates and (100,100) is the bottom-right coordinates of the annotation.
462 /// This property is not accessible at design time (at design-time, use the
463 /// <see cref="GraphicsPathPoints"/> property instead).
467 SRCategory("CategoryAttributePosition"),
469 SRDescription("DescriptionAttributePath"),
471 DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
472 SerializationVisibilityAttribute(SerializationVisibility.Hidden),
474 virtual public GraphicsPath GraphicsPath
478 return _graphicsPath;
482 _graphicsPath = value;
483 this.pathChanged = true;
488 /// Gets or sets the path points of the polyline at design-time.
491 /// An <see cref="AnnotationPathPointCollection"/> object with the polyline shape.
494 /// A polyline must use coordinates relative to an annotation object, where (0,0) is
495 /// the top-left coordinates and (100,100) is the bottom-right coordinates of the annotation.
497 /// This property is not accessible at runtime (at runtime, use the <see cref="GraphicsPath"/>
498 /// property instead).
502 SRCategory("CategoryAttributePosition"),
503 SRDescription("DescriptionAttributePathPoints"),
504 EditorBrowsableAttribute(EditorBrowsableState.Never),
505 Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base),
506 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
507 #if !Microsoft_CONTROL
508 PersistenceMode(PersistenceMode.InnerProperty)
511 public AnnotationPathPointCollection GraphicsPathPoints
515 if(this.pathChanged ||
516 _graphicsPath.PointCount != _pathPoints.Count)
518 // Recreate collection from graphics path
519 _pathPoints.annotation = null;
521 if (_graphicsPath.PointCount > 0 )
523 PointF[] points = _graphicsPath.PathPoints;
524 byte[] types = _graphicsPath.PathTypes;
525 for (int index = 0; index < points.Length; index++)
527 _pathPoints.Add(new AnnotationPathPoint(points[index].X, points[index].Y, types[index]));
530 _pathPoints.annotation = this;
545 /// Paints an annotation object on the specified graphics.
547 /// <param name="graphics">
548 /// A <see cref="ChartGraphics"/> object, used to paint an annotation object.
550 /// <param name="chart">
551 /// Reference to the <see cref="Chart"/> owner control.
553 override internal void Paint(Chart chart, ChartGraphics graphics)
555 // Check for empty path
556 if(_graphicsPath.PointCount == 0)
561 // Get annotation position in relative coordinates
562 PointF firstPoint = PointF.Empty;
563 PointF anchorPoint = PointF.Empty;
564 SizeF size = SizeF.Empty;
565 GetRelativePosition(out firstPoint, out size, out anchorPoint);
566 PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height);
568 // Create selection rectangle
569 RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y));
572 RectangleF rectanglePosition = new RectangleF(selectionRect.Location, selectionRect.Size);
573 if(rectanglePosition.Width < 0)
575 rectanglePosition.X = rectanglePosition.Right;
576 rectanglePosition.Width = -rectanglePosition.Width;
578 if(rectanglePosition.Height < 0)
580 rectanglePosition.Y = rectanglePosition.Bottom;
581 rectanglePosition.Height = -rectanglePosition.Height;
584 // Check if position is valid
585 if( float.IsNaN(rectanglePosition.X) ||
586 float.IsNaN(rectanglePosition.Y) ||
587 float.IsNaN(rectanglePosition.Right) ||
588 float.IsNaN(rectanglePosition.Bottom) )
593 // Get annotation absolute position
594 RectangleF rectanglePositionAbs = graphics.GetAbsoluteRectangle(rectanglePosition);
597 float groupScaleX = rectanglePositionAbs.Width / 100.0f;
598 float groupScaleY = rectanglePositionAbs.Height / 100.0f;
600 // Convert path to pixel coordinates
601 PointF[] pathPoints = _graphicsPath.PathPoints;
602 byte[] pathTypes = _graphicsPath.PathTypes;
603 for(int pointIndex = 0; pointIndex < pathPoints.Length; pointIndex++)
605 pathPoints[pointIndex].X = rectanglePositionAbs.X + pathPoints[pointIndex].X * groupScaleX;
606 pathPoints[pointIndex].Y = rectanglePositionAbs.Y + pathPoints[pointIndex].Y * groupScaleY;
609 using (GraphicsPath pathAbs = new GraphicsPath(pathPoints, pathTypes))
613 bool capChanged = false;
614 LineCap oldStartCap = LineCap.Flat;
615 LineCap oldEndCap = LineCap.Flat;
618 if (this._startCap != LineAnchorCapStyle.None ||
619 this._endCap != LineAnchorCapStyle.None)
622 oldStartCap = graphics.Pen.StartCap;
623 oldEndCap = graphics.Pen.EndCap;
625 // Apply anchor cap settings
626 if (this._startCap == LineAnchorCapStyle.Arrow)
628 // Adjust arrow size for small line width
629 if (this.LineWidth < 4)
631 int adjustment = 3 - this.LineWidth;
632 graphics.Pen.StartCap = LineCap.Custom;
633 graphics.Pen.CustomStartCap = new AdjustableArrowCap(
634 this.LineWidth + adjustment,
635 this.LineWidth + adjustment,
640 graphics.Pen.StartCap = LineCap.ArrowAnchor;
643 else if (this._startCap == LineAnchorCapStyle.Diamond)
645 graphics.Pen.StartCap = LineCap.DiamondAnchor;
647 else if (this._startCap == LineAnchorCapStyle.Round)
649 graphics.Pen.StartCap = LineCap.RoundAnchor;
651 else if (this._startCap == LineAnchorCapStyle.Square)
653 graphics.Pen.StartCap = LineCap.SquareAnchor;
655 if (this._endCap == LineAnchorCapStyle.Arrow)
657 // Adjust arrow size for small line width
658 if (this.LineWidth < 4)
660 int adjustment = 3 - this.LineWidth;
661 graphics.Pen.EndCap = LineCap.Custom;
662 graphics.Pen.CustomEndCap = new AdjustableArrowCap(
663 this.LineWidth + adjustment,
664 this.LineWidth + adjustment,
669 graphics.Pen.EndCap = LineCap.ArrowAnchor;
672 else if (this._endCap == LineAnchorCapStyle.Diamond)
674 graphics.Pen.EndCap = LineCap.DiamondAnchor;
676 else if (this._endCap == LineAnchorCapStyle.Round)
678 graphics.Pen.EndCap = LineCap.RoundAnchor;
680 else if (this._endCap == LineAnchorCapStyle.Square)
682 graphics.Pen.EndCap = LineCap.SquareAnchor;
688 if (this.Common.ProcessModePaint)
693 pathAbs.CloseAllFigures();
694 graphics.DrawPathAbs(
699 ChartImageWrapMode.Scaled,
701 ChartImageAlignmentStyle.Center,
702 this.BackGradientStyle,
703 this.BackSecondaryColor,
714 graphics.DrawPathAbs(
717 ChartHatchStyle.None,
719 ChartImageWrapMode.Scaled,
721 ChartImageAlignmentStyle.Center,
733 if (this.Common.ProcessModeRegions)
735 // Create line graphics path
736 GraphicsPath selectionPath = null;
737 GraphicsPath newPath = null;
741 selectionPath = pathAbs;
745 newPath = new GraphicsPath();
746 selectionPath = newPath;
747 selectionPath.AddPath(pathAbs, false);
748 using (Pen pen = (Pen)graphics.Pen.Clone())
750 // Increase pen size by 2 pixels
751 pen.DashStyle = DashStyle.Solid;
755 selectionPath.Widen(pen);
757 catch (OutOfMemoryException)
759 // GraphicsPath.Widen incorrectly throws OutOfMemoryException
760 // catching here and reacting by not widening
762 catch (ArgumentException)
769 this.Common.HotRegionsList.AddHotRegion(
773 ReplaceKeywords(this.ToolTip),
774 #if Microsoft_CONTROL
778 #else // Microsoft_CONTROL
779 ReplaceKeywords(this.Url),
780 ReplaceKeywords(this.MapAreaAttributes),
781 ReplaceKeywords(this.PostBackValue),
782 #endif // Microsoft_CONTROL
784 ChartElementType.Annotation);
794 graphics.Pen.StartCap = oldStartCap;
795 graphics.Pen.EndCap = oldEndCap;
798 // Paint selection handles
799 PaintSelectionHandles(graphics, rectanglePosition, pathAbs);
803 #endregion // Painting
805 #region Position Changing
806 #if Microsoft_CONTROL
808 /// Changes annotation position, so it exactly matches the bounary of the
811 private void ResizeToPathBoundary()
813 if(_graphicsPath.PointCount > 0)
815 // Get current annotation position in relative coordinates
816 PointF firstPoint = PointF.Empty;
817 PointF anchorPoint = PointF.Empty;
818 SizeF size = SizeF.Empty;
819 GetRelativePosition(out firstPoint, out size, out anchorPoint);
821 // Get path boundary and convert it to relative coordinates
822 RectangleF pathBoundary = _graphicsPath.GetBounds();
823 pathBoundary.X *= size.Width / 100f;
824 pathBoundary.Y *= size.Height / 100f;
825 pathBoundary.X += firstPoint.X;
826 pathBoundary.Y += firstPoint.Y;
827 pathBoundary.Width *= size.Width / 100f;
828 pathBoundary.Height *= size.Height / 100f;
830 // Scale all current points
831 using( Matrix matrix = new Matrix() )
833 matrix.Scale(size.Width/pathBoundary.Width, size.Height/pathBoundary.Height);
834 matrix.Translate(-pathBoundary.X, -pathBoundary.Y);
835 _graphicsPath.Transform(matrix);
838 // Set new position for annotation
839 this.SetPositionRelative(pathBoundary, anchorPoint);
842 #endif //Microsoft_CONTROL
844 /// Adjust annotation location and\or size as a result of user action.
846 /// <param name="movingDistance">Distance to resize/move the annotation.</param>
847 /// <param name="resizeMode">Resizing mode.</param>
848 /// <param name="pixelCoord">Distance is in pixels, otherwise relative.</param>
849 /// <param name="userInput">Indicates if position changing was a result of the user input.</param>
850 override internal void AdjustLocationSize(SizeF movingDistance, ResizingMode resizeMode, bool pixelCoord, bool userInput)
852 // Call base class when not resizing the path points
853 if(resizeMode != ResizingMode.MovingPathPoints)
855 base.AdjustLocationSize(movingDistance, resizeMode, pixelCoord, userInput);
859 // Get annotation position in relative coordinates
860 PointF firstPoint = PointF.Empty;
861 PointF anchorPoint = PointF.Empty;
862 SizeF size = SizeF.Empty;
863 GetRelativePosition(out firstPoint, out size, out anchorPoint);
865 // Remember path before moving operation
866 if(userInput == true && startMovePathRel == null)
868 #if Microsoft_CONTROL
869 this.startMovePathRel = (GraphicsPath)_graphicsPath.Clone();
870 this.startMovePositionRel = new RectangleF(firstPoint, size);
871 this.startMoveAnchorLocationRel = new PointF(anchorPoint.X, anchorPoint.Y);
873 #endif // Microsoft_CONTROL
876 // Convert moving distance to coordinates relative to the anotation
879 movingDistance = this.GetGraphics().GetRelativeSize(movingDistance);
881 movingDistance.Width /= startMovePositionRel.Width / 100.0f;
882 movingDistance.Height /= startMovePositionRel.Height / 100.0f;
884 // Get path points and adjust position of one of them
885 if(_graphicsPath.PointCount > 0)
887 GraphicsPath pathToMove = (userInput) ? startMovePathRel : _graphicsPath;
888 PointF[] pathPoints = pathToMove.PathPoints;
889 byte[] pathTypes = pathToMove.PathTypes;
891 for(int pointIndex = 0; pointIndex < pathPoints.Length; pointIndex++)
894 if( currentPathPointIndex == pointIndex ||
895 currentPathPointIndex < 0 ||
896 currentPathPointIndex >= pathPoints.Length )
898 pathPoints[pointIndex].X -= movingDistance.Width;
899 pathPoints[pointIndex].Y -= movingDistance.Height;
903 #if Microsoft_CONTROL
905 // Adjust annotation position to the boundary of the path
906 if(userInput && this.AllowResizing)
908 // Get path bounds in relative coordinates
909 _defaultGraphicsPath.Dispose();
910 _defaultGraphicsPath = new GraphicsPath(pathPoints, pathTypes);
911 _graphicsPath = _defaultGraphicsPath;
913 RectangleF pathBounds = _graphicsPath.GetBounds();
914 pathBounds.X *= startMovePositionRel.Width / 100f;
915 pathBounds.Y *= startMovePositionRel.Height / 100f;
916 pathBounds.X += startMovePositionRel.X;
917 pathBounds.Y += startMovePositionRel.Y;
918 pathBounds.Width *= startMovePositionRel.Width / 100f;
919 pathBounds.Height *= startMovePositionRel.Height / 100f;
921 // Set new annotation position
922 this.SetPositionRelative(pathBounds, anchorPoint);
924 // Adjust path point position
925 for(int pointIndex = 0; pointIndex < pathPoints.Length; pointIndex++)
928 pathPoints[pointIndex].X = startMovePositionRel.X + pathPoints[pointIndex].X * (startMovePositionRel.Width / 100f);
929 pathPoints[pointIndex].Y = startMovePositionRel.Y + pathPoints[pointIndex].Y * (startMovePositionRel.Height / 100f);
931 pathPoints[pointIndex].X = (pathPoints[pointIndex].X - pathBounds.X) / (pathBounds.Width / 100f);
932 pathPoints[pointIndex].Y = (pathPoints[pointIndex].Y - pathBounds.Y) / (pathBounds.Height / 100f);
936 #endif // Microsoft_CONTROL
938 #if Microsoft_CONTROL
940 this.positionChanged = true;
941 #endif // Microsoft_CONTROL
943 // Recreate path with new points
944 _defaultGraphicsPath.Dispose();
945 _defaultGraphicsPath = new GraphicsPath(pathPoints, pathTypes);
946 _graphicsPath = _defaultGraphicsPath;
947 this.pathChanged = true;
949 // Invalidate annotation
954 #endregion // Position Changing
956 #region Placement Methods
958 #if Microsoft_CONTROL
961 /// Ends user placement of an annotation.
964 /// Ends an annotation placement operation previously started by a
965 /// <see cref="Annotation.BeginPlacement"/> method call.
967 /// Calling this method is not required, since placement will automatically
968 /// end when an end user enters all required points. However, it is useful when an annotation
969 /// placement operation needs to be aborted for some reason.
972 override public void EndPlacement()
977 // Position was changed
978 if(this.Chart != null)
980 this.Chart.OnAnnotationPositionChanged(this);
983 // Reset last placement position
984 this.lastPlacementPosition = PointF.Empty;
986 // Resize annotation to the boundary of the polygon
987 ResizeToPathBoundary();
990 this.positionChanged = true;
994 /// Handles mouse down event during annotation placement.
996 /// <param name="point">Mouse cursor position in pixels.</param>
997 /// <param name="buttons">Mouse button down.</param>
998 internal override void PlacementMouseDown(PointF point, MouseButtons buttons)
1000 // Call base class method if path editing is not allowed
1001 if(!this.AllowPathEditing)
1003 base.PlacementMouseDown(point, buttons);
1007 if(buttons == MouseButtons.Right)
1010 this.EndPlacement();
1012 if(buttons == MouseButtons.Left &&
1013 IsValidPlacementPosition(point.X, point.Y))
1015 // Convert coordinate to relative
1016 PointF newPoint = this.GetGraphics().GetRelativePoint(point);
1018 if(this.lastPlacementPosition.IsEmpty)
1020 // Set annotation coordinates to full chart
1026 // Remeber position where mouse was clicked
1027 this.lastPlacementPosition = newPoint;
1031 if(this.lastPlacementPosition.X == newPoint.X &&
1032 this.lastPlacementPosition.Y == newPoint.Y)
1035 this.EndPlacement();
1039 // Add a line from prev. position to current into the path
1040 using( GraphicsPath tmpPath = new GraphicsPath() )
1042 PointF firstPoint = this.lastPlacementPosition;
1043 if(_graphicsPath.PointCount > 1)
1045 firstPoint = _graphicsPath.GetLastPoint();
1047 tmpPath.AddLine(firstPoint, newPoint);
1048 _graphicsPath.AddPath(tmpPath, true);
1051 // Remember last position
1052 this.lastPlacementPosition = newPoint;
1054 // Invalidate and update the chart
1058 Chart.UpdateAnnotations();
1064 /// Handles mouse up event during annotation placement.
1066 /// <param name="point">Mouse cursor position in pixels.</param>
1067 /// <param name="buttons">Mouse button Up.</param>
1068 /// <returns>Return true when placing finished.</returns>
1069 internal override bool PlacementMouseUp(PointF point, MouseButtons buttons)
1071 // Call base class method if path editing is not allowed
1072 if(!this.AllowPathEditing)
1074 return base.PlacementMouseUp(point, buttons);
1077 if(buttons == MouseButtons.Left &&
1078 isFreeDrawPlacement)
1081 this.EndPlacement();
1089 /// Handles mouse move event during annotation placement.
1091 /// <param name="point">Mouse cursor position in pixels.</param>
1092 internal override void PlacementMouseMove(PointF point)
1094 // Call base class method if path editing is not allowed
1095 if(!this.AllowPathEditing)
1097 base.PlacementMouseMove(point);
1101 // Check if annotation was moved
1102 if( this.GetGraphics() != null &&
1103 _graphicsPath.PointCount > 0 &&
1104 !this.lastPlacementPosition.IsEmpty)
1106 // Convert coordinate to relative
1107 PointF newPoint = this.GetGraphics().GetRelativePoint(point);
1108 if(this.isFreeDrawPlacement)
1111 using( GraphicsPath tmpPath = new GraphicsPath() )
1113 PointF firstPoint = this.lastPlacementPosition;
1114 if(_graphicsPath.PointCount > 1)
1116 firstPoint = _graphicsPath.GetLastPoint();
1118 tmpPath.AddLine(firstPoint, newPoint);
1119 _graphicsPath.AddPath(tmpPath, true);
1124 // Adjust last point position
1125 PointF[] pathPoints = _graphicsPath.PathPoints;
1126 byte[] pathTypes = _graphicsPath.PathTypes;
1127 pathPoints[pathPoints.Length - 1] = newPoint;
1129 _defaultGraphicsPath.Dispose();
1130 _defaultGraphicsPath = new GraphicsPath(pathPoints, pathTypes);
1131 _graphicsPath = _defaultGraphicsPath;
1136 this.positionChanged = true;
1138 // Invalidate and update the chart
1139 if(this.Chart != null)
1142 this.Chart.UpdateAnnotations();
1147 #endif // Microsoft_CONTROL
1149 #endregion // Placement Methods
1153 #region IDisposable override
1155 /// Releases unmanaged and - optionally - managed resources
1157 /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
1158 protected override void Dispose(bool disposing)
1162 if (_defaultGraphicsPath != null)
1164 _defaultGraphicsPath.Dispose();
1165 _defaultGraphicsPath = null;
1167 if (_pathPoints != null)
1169 _pathPoints.Dispose();
1174 base.Dispose(disposing);
1181 /// <b>PolygonAnnotation</b> is a class that represents a polygon annotation.
1184 SRDescription("DescriptionAttributePolygonAnnotation_PolygonAnnotation"),
1187 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1188 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1190 public class PolygonAnnotation : PolylineAnnotation
1192 #region Construction and Initialization
1195 /// Default public constructor.
1197 public PolygonAnnotation()
1200 this.isPolygon = true;
1207 #region Non Applicable Annotation Appearance Attributes (set as Non-Browsable)
1210 /// Not applicable to this annotation type.
1211 /// <seealso cref="EndCap"/>
1214 /// A <see cref="LineAnchorCapStyle"/> value.
1217 SRCategory("CategoryAttributeAppearance"),
1219 DefaultValue(LineAnchorCapStyle.None),
1221 override public LineAnchorCapStyle StartCap
1225 return base.StartCap;
1229 base.StartCap = value;
1234 /// Not applicable to this annotation type.
1235 /// <seealso cref="StartCap"/>
1238 /// A <see cref="LineAnchorCapStyle"/> value.
1241 SRCategory("CategoryAttributeAppearance"),
1243 DefaultValue(LineAnchorCapStyle.None),
1245 override public LineAnchorCapStyle EndCap
1253 base.EndCap = value;
1259 #region Applicable Annotation Appearance Attributes (set as Browsable)
1262 /// Gets or sets the background color of an annotation.
1263 /// <seealso cref="BackSecondaryColor"/>
1264 /// <seealso cref="BackHatchStyle"/>
1265 /// <seealso cref="BackGradientStyle"/>
1268 /// A <see cref="Color"/> value used for the background of an annotation.
1271 SRCategory("CategoryAttributeAppearance"),
1273 DefaultValue(typeof(Color), ""),
1274 SRDescription("DescriptionAttributeBackColor"),
1275 NotifyParentPropertyAttribute(true),
1276 TypeConverter(typeof(ColorConverter)),
1277 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base)
1279 override public Color BackColor
1283 return base.BackColor;
1287 base.BackColor = value;
1292 /// Gets or sets the background hatch style of an annotation.
1293 /// <seealso cref="BackSecondaryColor"/>
1294 /// <seealso cref="BackColor"/>
1295 /// <seealso cref="BackGradientStyle"/>
1298 /// A <see cref="ChartHatchStyle"/> value used for the background of an annotation.
1301 /// Two colors are used to draw the hatching, <see cref="BackColor"/> and <see cref="BackSecondaryColor"/>.
1304 SRCategory("CategoryAttributeAppearance"),
1306 DefaultValue(ChartHatchStyle.None),
1307 NotifyParentPropertyAttribute(true),
1308 SRDescription("DescriptionAttributeBackHatchStyle"),
1309 Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base)
1311 override public ChartHatchStyle BackHatchStyle
1315 return base.BackHatchStyle;
1319 base.BackHatchStyle = value;
1324 /// Gets or sets the background gradient style of an annotation.
1325 /// <seealso cref="BackSecondaryColor"/>
1326 /// <seealso cref="BackColor"/>
1327 /// <seealso cref="BackHatchStyle"/>
1330 /// A <see cref="GradientStyle"/> value used for the background of an annotation.
1333 /// Two colors are used to draw the gradient, <see cref="BackColor"/> and <see cref="BackSecondaryColor"/>.
1336 SRCategory("CategoryAttributeAppearance"),
1338 DefaultValue(GradientStyle.None),
1339 NotifyParentPropertyAttribute(true),
1340 SRDescription("DescriptionAttributeBackGradientStyle"),
1341 Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base)
1343 override public GradientStyle BackGradientStyle
1347 return base.BackGradientStyle;
1351 base.BackGradientStyle = value;
1356 /// Gets or sets the secondary background color of an annotation.
1357 /// <seealso cref="BackColor"/>
1358 /// <seealso cref="BackHatchStyle"/>
1359 /// <seealso cref="BackGradientStyle"/>
1362 /// A <see cref="Color"/> value used for the secondary color of an annotation background with
1363 /// hatching or gradient fill.
1366 /// This color is used with <see cref="BackColor"/> when <see cref="BackHatchStyle"/> or
1367 /// <see cref="BackGradientStyle"/> are used.
1370 SRCategory("CategoryAttributeAppearance"),
1372 DefaultValue(typeof(Color), ""),
1373 NotifyParentPropertyAttribute(true),
1374 SRDescription("DescriptionAttributeBackSecondaryColor"),
1375 TypeConverter(typeof(ColorConverter)),
1376 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base)
1378 override public Color BackSecondaryColor
1382 return base.BackSecondaryColor;
1386 base.BackSecondaryColor = value;
1395 /// Gets or sets an annotation's type name.
1398 /// This property is used to get the name of each annotation type
1399 /// (e.g. Line, Rectangle, Ellipse).
1401 /// This property is for internal use and is hidden at design and run time.
1405 SRCategory("CategoryAttributeMisc"),
1408 EditorBrowsableAttribute(EditorBrowsableState.Never),
1409 DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
1410 SerializationVisibilityAttribute(SerializationVisibility.Hidden),
1411 SRDescription("DescriptionAttributeAnnotationType"),
1413 public override string AnnotationType
1422 /// Gets or sets an annotation's selection points style.
1425 /// A <see cref="SelectionPointsStyle"/> value that represents an annotation's
1426 /// selection style.
1429 /// This property is for internal use and is hidden at design and run time.
1432 SRCategory("CategoryAttributeAppearance"),
1433 DefaultValue(SelectionPointsStyle.Rectangle),
1434 ParenthesizePropertyNameAttribute(true),
1436 EditorBrowsableAttribute(EditorBrowsableState.Never),
1437 DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
1438 SerializationVisibilityAttribute(SerializationVisibility.Hidden),
1439 SRDescription("DescriptionAttributeSelectionPointsStyle"),
1441 override internal SelectionPointsStyle SelectionPointsStyle
1445 return SelectionPointsStyle.Rectangle;
1454 /// <summary><b>AnnotationPathPointCollection</b> is a collection of polyline
1455 /// annotation path points, and is only available via the <b>GraphicsPathPoints</b>
1456 /// property at design-time.
1457 /// <seealso cref="PolylineAnnotation.GraphicsPathPoints"/></summary>
1459 /// This collection is used at design-time only, and uses serialization to expose the
1460 /// shape of the polyline and polygon via their GraphicsPathPoints collection property.
1461 /// At run-time, use Path property to set the path of a polyline or polygon
1464 SRDescription("DescriptionAttributeAnnotationPathPointCollection_AnnotationPathPointCollection"),
1467 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1468 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1470 public class AnnotationPathPointCollection : ChartElementCollection<AnnotationPathPoint>
1474 internal PolylineAnnotation annotation = null;
1475 private GraphicsPath _graphicsPath = null;
1477 #endregion // Fields
1479 #region Constructors
1482 /// Default public constructor.
1484 public AnnotationPathPointCollection(PolylineAnnotation annotation)
1487 this.annotation = annotation;
1490 #endregion // Constructors
1495 /// Forces the invalidation of the chart element
1497 public override void Invalidate()
1499 if (this.annotation != null)
1501 //Dispose previously instantiated graphics path
1502 if (this._graphicsPath != null)
1504 this._graphicsPath.Dispose();
1505 this._graphicsPath = null;
1508 // Recreate polyline annotation path
1511 PointF[] points = new PointF[this.Count];
1512 byte[] types = new byte[this.Count];
1513 for (int index = 0; index < this.Count; index++)
1515 points[index] = new PointF(this[index].X, this[index].Y);
1516 types[index] = this[index].PointType;
1518 this._graphicsPath = new GraphicsPath(points, types);
1522 this._graphicsPath = new GraphicsPath();
1525 // Invalidate annotation
1526 this.annotation.GraphicsPath = this._graphicsPath;
1527 this.annotation.Invalidate();
1532 #endregion // Methods
1534 #region IDisposable Members
1536 /// Releases unmanaged and - optionally - managed resources
1538 /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
1539 protected override void Dispose(bool disposing)
1543 // Free up managed resources
1544 if (this._graphicsPath != null)
1546 this._graphicsPath.Dispose();
1547 this._graphicsPath = null;
1550 base.Dispose(disposing);
1557 /// The <b>AnnotationPathPoint</b> class represents a path point of a polyline or polygon,
1558 /// and is stored in their <b>GraphicsPathPoints</b> property, which is only available at design-time.
1561 /// At run-time, use <b>Path</b> property to set the path of a polyline or polygon.
1564 SRDescription("DescriptionAttributeAnnotationPathPoint_AnnotationPathPoint"),
1567 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1568 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1570 public class AnnotationPathPoint: ChartElement
1575 private float _x = 0f;
1578 private float _y = 0f;
1581 private byte _pointType = 1;
1583 #endregion // Fields
1585 #region Constructors
1588 /// Default public constructor.
1590 public AnnotationPathPoint()
1595 /// Constructor that takes X and Y parameters.
1597 /// <param name="x">Point's X value.</param>
1598 /// <param name="y">Point's Y value.</param>
1599 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
1600 Justification="X and Y are cartesian coordinates and well understood")]
1601 public AnnotationPathPoint(float x, float y)
1608 /// Constructor that takes X, Y and point type parameters.
1610 /// <param name="x">Point's X value.</param>
1611 /// <param name="y">Point's Y value.</param>
1612 /// <param name="type">Point type.</param>
1613 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
1614 Justification = "X and Y are cartesian coordinates and well understood")]
1615 public AnnotationPathPoint(float x, float y, byte type)
1619 this._pointType = type;
1622 #endregion // Constructors
1627 /// Gets or sets an annotation path point's X coordinate.
1630 /// A float value for the point's X coordinate.
1633 SRCategory("CategoryAttributePosition"),
1636 SRDescription("DescriptionAttributeAnnotationPathPoint_X"),
1637 #if !Microsoft_CONTROL
1638 PersistenceMode(PersistenceMode.Attribute),
1641 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "X")]
1655 /// Gets or sets an annotation path point's Y coordinate.
1658 /// A float value for the point's Y coordinate.
1661 SRCategory("CategoryAttributePosition"),
1664 SRDescription("DescriptionAttributeAnnotationPathPoint_Y"),
1665 #if !Microsoft_CONTROL
1666 PersistenceMode(PersistenceMode.Attribute),
1669 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Y")]
1683 /// Gets or sets an annotation path point's type.
1689 /// See the <see cref="PathPointType"/> enumeration for more details.
1692 SRCategory("CategoryAttributePosition"),
1693 DefaultValue(typeof(byte), "1"),
1695 EditorBrowsableAttribute(EditorBrowsableState.Never),
1696 SRDescription("DescriptionAttributeAnnotationPathPoint_Name"),
1697 #if !Microsoft_CONTROL
1698 PersistenceMode(PersistenceMode.Attribute),
1701 public byte PointType
1714 /// Gets or sets an annotation path point's name.
1717 /// This property is for internal use and is hidden at design and run time.
1720 SRCategory("CategoryAttributeMisc"),
1721 DefaultValue("PathPoint"),
1723 EditorBrowsableAttribute(EditorBrowsableState.Never),
1724 SRDescription("DescriptionAttributeAnnotationPathPoint_Name"),
1725 DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
1726 SerializationVisibilityAttribute(SerializationVisibility.Hidden),
1736 #endregion // Properties