PolygonAnnotation.cs 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. //
  5. // Purpose: Polyline and polygon annotation classes.
  6. //
  7. using System;
  8. using System.Windows.Forms;
  9. using System.ComponentModel;
  10. using System.Diagnostics.CodeAnalysis;
  11. using System.Drawing;
  12. using System.Drawing.Design;
  13. using System.Drawing.Drawing2D;
  14. using FastReport.DataVisualization.Charting.Utilities;
  15. namespace FastReport.DataVisualization.Charting
  16. {
  17. /// <summary>
  18. /// <b>PolylineAnnotation</b> is a class that represents a polyline annotation.
  19. /// </summary>
  20. [
  21. SRDescription("DescriptionAttributePolylineAnnotation_PolylineAnnotation"),
  22. ]
  23. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Polyline")]
  24. public class PolylineAnnotation : Annotation
  25. {
  26. #region Fields
  27. // Path with polygon points.
  28. private GraphicsPath _defaultGraphicsPath = new GraphicsPath();
  29. private GraphicsPath _graphicsPath;
  30. // Indicates that path was changed
  31. internal bool pathChanged = false;
  32. // Collection of path points exposed at design-time
  33. private AnnotationPathPointCollection _pathPoints;
  34. // Indicate that filled polygon must be drawn
  35. internal bool isPolygon = false;
  36. // Indicates that annotation will be placed using free-draw style
  37. internal bool isFreeDrawPlacement = false;
  38. // Line start/end caps
  39. private LineAnchorCapStyle _startCap = LineAnchorCapStyle.None;
  40. private LineAnchorCapStyle _endCap = LineAnchorCapStyle.None;
  41. #endregion
  42. #region Construction and Initialization
  43. /// <summary>
  44. /// Default public constructor.
  45. /// </summary>
  46. public PolylineAnnotation()
  47. : base()
  48. {
  49. _pathPoints = new AnnotationPathPointCollection(this);
  50. _graphicsPath = _defaultGraphicsPath;
  51. }
  52. #endregion
  53. #region Properties
  54. #region Polyline Visual Attributes
  55. /// <summary>
  56. /// Gets or sets a cap style used at the start of an annotation line.
  57. /// <seealso cref="EndCap"/>
  58. /// </summary>
  59. /// <value>
  60. /// A <see cref="LineAnchorCapStyle"/> value used for a cap style used at the start of an annotation line.
  61. /// </value>
  62. [
  63. SRCategory("CategoryAttributeAppearance"),
  64. DefaultValue(LineAnchorCapStyle.None),
  65. SRDescription("DescriptionAttributeStartCap3"),
  66. ]
  67. virtual public LineAnchorCapStyle StartCap
  68. {
  69. get
  70. {
  71. return _startCap;
  72. }
  73. set
  74. {
  75. _startCap = value;
  76. Invalidate();
  77. }
  78. }
  79. /// <summary>
  80. /// Gets or sets a cap style used at the end of an annotation line.
  81. /// <seealso cref="StartCap"/>
  82. /// </summary>
  83. /// <value>
  84. /// A <see cref="LineAnchorCapStyle"/> value used for a cap style used at the end of an annotation line.
  85. /// </value>
  86. [
  87. SRCategory("CategoryAttributeAppearance"),
  88. DefaultValue(LineAnchorCapStyle.None),
  89. SRDescription("DescriptionAttributeStartCap3"),
  90. ]
  91. virtual public LineAnchorCapStyle EndCap
  92. {
  93. get
  94. {
  95. return _endCap;
  96. }
  97. set
  98. {
  99. _endCap = value;
  100. Invalidate();
  101. }
  102. }
  103. #endregion
  104. #region Non Applicable Annotation Appearance Attributes (set as Non-Browsable)
  105. /// <summary>
  106. /// Not applicable to this annotation type.
  107. /// </summary>
  108. /// <value>
  109. /// A <see cref="ContentAlignment"/> value.
  110. /// </value>
  111. [
  112. SRCategory("CategoryAttributeAppearance"),
  113. Browsable(false),
  114. DefaultValue(typeof(ContentAlignment), "MiddleCenter"),
  115. ]
  116. override public ContentAlignment Alignment
  117. {
  118. get
  119. {
  120. return base.Alignment;
  121. }
  122. set
  123. {
  124. base.Alignment = value;
  125. }
  126. }
  127. /// <summary>
  128. /// Gets or sets an annotation's text style.
  129. /// <seealso cref="Font"/>
  130. /// <seealso cref="ForeColor"/>
  131. /// </summary>
  132. /// <value>
  133. /// A <see cref="TextStyle"/> value used to draw an annotation's text.
  134. /// </value>
  135. [Browsable(false)]
  136. [EditorBrowsable(EditorBrowsableState.Never)]
  137. public override TextStyle TextStyle
  138. {
  139. get
  140. {
  141. return base.TextStyle;
  142. }
  143. set
  144. {
  145. base.TextStyle = value;
  146. }
  147. }
  148. /// <summary>
  149. /// Not applicable to this annotation type.
  150. /// <seealso cref="Font"/>
  151. /// </summary>
  152. /// <value>
  153. /// A <see cref="Color"/> value.
  154. /// </value>
  155. [
  156. SRCategory("CategoryAttributeAppearance"),
  157. Browsable(false),
  158. DefaultValue(typeof(Color), "Black"),
  159. SRDescription("DescriptionAttributeForeColor"),
  160. TypeConverter(typeof(ColorConverter)),
  161. #if DESIGNER
  162. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  163. #endif
  164. ]
  165. override public Color ForeColor
  166. {
  167. get
  168. {
  169. return base.ForeColor;
  170. }
  171. set
  172. {
  173. base.ForeColor = value;
  174. }
  175. }
  176. /// <summary>
  177. /// Not applicable to this annotation type.
  178. /// <seealso cref="ForeColor"/>
  179. /// </summary>
  180. /// <value>
  181. /// A <see cref="Font"/> object.
  182. /// </value>
  183. [
  184. SRCategory("CategoryAttributeAppearance"),
  185. Browsable(false),
  186. DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"),
  187. ]
  188. override public Font Font
  189. {
  190. get
  191. {
  192. return base.Font;
  193. }
  194. set
  195. {
  196. base.Font = value;
  197. }
  198. }
  199. /// <summary>
  200. /// Not applicable to this annotation type.
  201. /// </summary>
  202. [
  203. SRCategory("CategoryAttributeAppearance"),
  204. Browsable(false),
  205. DefaultValue(typeof(Color), ""),
  206. NotifyParentPropertyAttribute(true),
  207. TypeConverter(typeof(ColorConverter)),
  208. #if DESIGNER
  209. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  210. #endif
  211. ]
  212. override public Color BackColor
  213. {
  214. get
  215. {
  216. return base.BackColor;
  217. }
  218. set
  219. {
  220. base.BackColor = value;
  221. }
  222. }
  223. /// <summary>
  224. /// Not applicable to this annotation type.
  225. /// </summary>
  226. [
  227. SRCategory("CategoryAttributeAppearance"),
  228. Browsable(false),
  229. DefaultValue(ChartHatchStyle.None),
  230. NotifyParentPropertyAttribute(true),
  231. #if DESIGNER
  232. Editor(typeof(HatchStyleEditor), typeof(UITypeEditor))
  233. #endif
  234. ]
  235. override public ChartHatchStyle BackHatchStyle
  236. {
  237. get
  238. {
  239. return base.BackHatchStyle;
  240. }
  241. set
  242. {
  243. base.BackHatchStyle = value;
  244. }
  245. }
  246. /// <summary>
  247. /// Not applicable to this annotation type.
  248. /// </summary>
  249. [
  250. SRCategory("CategoryAttributeAppearance"),
  251. Browsable(false),
  252. DefaultValue(GradientStyle.None),
  253. NotifyParentPropertyAttribute(true),
  254. #if DESIGNER
  255. Editor(typeof(GradientEditor), typeof(UITypeEditor))
  256. #endif
  257. ]
  258. override public GradientStyle BackGradientStyle
  259. {
  260. get
  261. {
  262. return base.BackGradientStyle;
  263. }
  264. set
  265. {
  266. base.BackGradientStyle = value;
  267. }
  268. }
  269. /// <summary>
  270. /// Not applicable to this annotation type.
  271. /// </summary>
  272. [
  273. SRCategory("CategoryAttributeAppearance"),
  274. Browsable(false),
  275. DefaultValue(typeof(Color), ""),
  276. NotifyParentPropertyAttribute(true),
  277. TypeConverter(typeof(ColorConverter)),
  278. #if DESIGNER
  279. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  280. #endif
  281. ]
  282. override public Color BackSecondaryColor
  283. {
  284. get
  285. {
  286. return base.BackSecondaryColor;
  287. }
  288. set
  289. {
  290. base.BackSecondaryColor = value;
  291. }
  292. }
  293. #endregion
  294. #region Other
  295. /// <summary>
  296. /// Gets or sets an annotation's type name.
  297. /// </summary>
  298. /// <remarks>
  299. /// This property is used to get the name of each annotation type
  300. /// (e.g. Line, Rectangle, Ellipse).
  301. /// <para>
  302. /// This property is for internal use and is hidden at design and run time.
  303. /// </para>
  304. /// </remarks>
  305. [
  306. SRCategory("CategoryAttributeMisc"),
  307. Bindable(true),
  308. Browsable(false),
  309. EditorBrowsableAttribute(EditorBrowsableState.Never),
  310. DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
  311. SerializationVisibilityAttribute(SerializationVisibility.Hidden),
  312. SRDescription("DescriptionAttributeAnnotationType"),
  313. ]
  314. public override string AnnotationType
  315. {
  316. get
  317. {
  318. return "Polyline";
  319. }
  320. }
  321. /// <summary>
  322. /// Gets or sets an annotation selection points style.
  323. /// </summary>
  324. /// <value>
  325. /// A <see cref="SelectionPointsStyle"/> value that represents the annotation
  326. /// selection style.
  327. /// </value>
  328. /// <remarks>
  329. /// This property is for internal use and is hidden at design and run time.
  330. /// </remarks>
  331. [
  332. SRCategory("CategoryAttributeAppearance"),
  333. DefaultValue(SelectionPointsStyle.Rectangle),
  334. ParenthesizePropertyNameAttribute(true),
  335. Browsable(false),
  336. EditorBrowsableAttribute(EditorBrowsableState.Never),
  337. DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
  338. SerializationVisibilityAttribute(SerializationVisibility.Hidden),
  339. SRDescription("DescriptionAttributeSelectionPointsStyle"),
  340. ]
  341. override internal SelectionPointsStyle SelectionPointsStyle
  342. {
  343. get
  344. {
  345. return SelectionPointsStyle.Rectangle;
  346. }
  347. }
  348. /// <summary>
  349. /// Gets or sets a flag that determines whether an annotation should be placed using the free-draw mode.
  350. /// </summary>
  351. /// <value>
  352. /// <b>True</b> if an annotation should be placed using free-draw mode,
  353. /// <b>false</b> otherwise. Defaults to <b>false</b>.
  354. /// </value>
  355. /// <remarks>
  356. /// Two different placement modes are supported when the Annotation.BeginPlacement
  357. /// method is called. Set this property to <b>true</b> to switch from the default
  358. /// mode to free-draw mode, which allows the caller to free-draw while moving the mouse cursor.
  359. /// </remarks>
  360. [
  361. SRCategory("CategoryAttributeMisc"),
  362. DefaultValue(false),
  363. SRDescription("DescriptionAttributeFreeDrawPlacement"),
  364. ]
  365. virtual public bool IsFreeDrawPlacement
  366. {
  367. get
  368. {
  369. return isFreeDrawPlacement;
  370. }
  371. set
  372. {
  373. isFreeDrawPlacement = value;
  374. }
  375. }
  376. /// <summary>
  377. /// Gets or sets the path points of a polyline at run-time.
  378. /// </summary>
  379. /// <value>
  380. /// A <see cref="GraphicsPath"/> object with the polyline shape.
  381. /// </value>
  382. /// <remarks>
  383. /// A polyline must use coordinates relative to an annotation object, where (0,0) is
  384. /// the top-left coordinates and (100,100) is the bottom-right coordinates of the annotation.
  385. /// <para>
  386. /// This property is not accessible at design time (at design-time, use the
  387. /// <see cref="GraphicsPathPoints"/> property instead).
  388. /// </para>
  389. /// </remarks>
  390. [
  391. SRCategory("CategoryAttributePosition"),
  392. DefaultValue(null),
  393. SRDescription("DescriptionAttributePath"),
  394. Browsable(false),
  395. DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
  396. SerializationVisibilityAttribute(SerializationVisibility.Hidden),
  397. ]
  398. virtual public GraphicsPath GraphicsPath
  399. {
  400. get
  401. {
  402. return _graphicsPath;
  403. }
  404. set
  405. {
  406. _graphicsPath = value;
  407. this.pathChanged = true;
  408. }
  409. }
  410. /// <summary>
  411. /// Gets or sets the path points of the polyline at design-time.
  412. /// </summary>
  413. /// <value>
  414. /// An <see cref="AnnotationPathPointCollection"/> object with the polyline shape.
  415. /// </value>
  416. /// <remarks>
  417. /// A polyline must use coordinates relative to an annotation object, where (0,0) is
  418. /// the top-left coordinates and (100,100) is the bottom-right coordinates of the annotation.
  419. /// <para>
  420. /// This property is not accessible at runtime (at runtime, use the <see cref="GraphicsPath"/>
  421. /// property instead).
  422. /// </para>
  423. /// </remarks>
  424. [
  425. SRCategory("CategoryAttributePosition"),
  426. SRDescription("DescriptionAttributePathPoints"),
  427. EditorBrowsableAttribute(EditorBrowsableState.Never),
  428. #if DESIGNER
  429. Editor(typeof(ChartCollectionEditor), typeof(UITypeEditor)),
  430. #endif
  431. DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
  432. ]
  433. public AnnotationPathPointCollection GraphicsPathPoints
  434. {
  435. get
  436. {
  437. if(this.pathChanged ||
  438. _graphicsPath.PointCount != _pathPoints.Count)
  439. {
  440. // Recreate collection from graphics path
  441. _pathPoints.annotation = null;
  442. _pathPoints.Clear();
  443. if (_graphicsPath.PointCount > 0 )
  444. {
  445. PointF[] points = _graphicsPath.PathPoints;
  446. byte[] types = _graphicsPath.PathTypes;
  447. for (int index = 0; index < points.Length; index++)
  448. {
  449. _pathPoints.Add(new AnnotationPathPoint(points[index].X, points[index].Y, types[index]));
  450. }
  451. }
  452. _pathPoints.annotation = this;
  453. }
  454. return _pathPoints;
  455. }
  456. }
  457. #endregion
  458. #endregion
  459. #region Methods
  460. #region Painting
  461. /// <summary>
  462. /// Paints an annotation object on the specified graphics.
  463. /// </summary>
  464. /// <param name="graphics">
  465. /// A <see cref="ChartGraphics"/> object, used to paint an annotation object.
  466. /// </param>
  467. /// <param name="chart">
  468. /// Reference to the <see cref="Chart"/> owner control.
  469. /// </param>
  470. override internal void Paint(Chart chart, ChartGraphics graphics)
  471. {
  472. // Check for empty path
  473. if(_graphicsPath.PointCount == 0)
  474. {
  475. return;
  476. }
  477. // Get annotation position in relative coordinates
  478. PointF firstPoint = PointF.Empty;
  479. PointF anchorPoint = PointF.Empty;
  480. SizeF size = SizeF.Empty;
  481. GetRelativePosition(out firstPoint, out size, out anchorPoint);
  482. PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height);
  483. // Create selection rectangle
  484. RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y));
  485. // Get position
  486. RectangleF rectanglePosition = new RectangleF(selectionRect.Location, selectionRect.Size);
  487. if(rectanglePosition.Width < 0)
  488. {
  489. rectanglePosition.X = rectanglePosition.Right;
  490. rectanglePosition.Width = -rectanglePosition.Width;
  491. }
  492. if(rectanglePosition.Height < 0)
  493. {
  494. rectanglePosition.Y = rectanglePosition.Bottom;
  495. rectanglePosition.Height = -rectanglePosition.Height;
  496. }
  497. // Check if position is valid
  498. if( float.IsNaN(rectanglePosition.X) ||
  499. float.IsNaN(rectanglePosition.Y) ||
  500. float.IsNaN(rectanglePosition.Right) ||
  501. float.IsNaN(rectanglePosition.Bottom) )
  502. {
  503. return;
  504. }
  505. // Get annotation absolute position
  506. RectangleF rectanglePositionAbs = graphics.GetAbsoluteRectangle(rectanglePosition);
  507. // Calculate scaling
  508. float groupScaleX = rectanglePositionAbs.Width / 100.0f;
  509. float groupScaleY = rectanglePositionAbs.Height / 100.0f;
  510. // Convert path to pixel coordinates
  511. PointF[] pathPoints = _graphicsPath.PathPoints;
  512. byte[] pathTypes = _graphicsPath.PathTypes;
  513. for(int pointIndex = 0; pointIndex < pathPoints.Length; pointIndex++)
  514. {
  515. pathPoints[pointIndex].X = rectanglePositionAbs.X + pathPoints[pointIndex].X * groupScaleX;
  516. pathPoints[pointIndex].Y = rectanglePositionAbs.Y + pathPoints[pointIndex].Y * groupScaleY;
  517. }
  518. using (GraphicsPath pathAbs = new GraphicsPath(pathPoints, pathTypes))
  519. {
  520. // Set line caps
  521. bool capChanged = false;
  522. LineCap oldStartCap = LineCap.Flat;
  523. LineCap oldEndCap = LineCap.Flat;
  524. if (!this.isPolygon)
  525. {
  526. if (this._startCap != LineAnchorCapStyle.None ||
  527. this._endCap != LineAnchorCapStyle.None)
  528. {
  529. capChanged = true;
  530. oldStartCap = graphics.Pen.StartCap;
  531. oldEndCap = graphics.Pen.EndCap;
  532. // Apply anchor cap settings
  533. if (this._startCap == LineAnchorCapStyle.Arrow)
  534. {
  535. // Adjust arrow size for small line width
  536. if (this.LineWidth < 4)
  537. {
  538. int adjustment = 3 - this.LineWidth;
  539. graphics.Pen.StartCap = LineCap.Custom;
  540. graphics.Pen.CustomStartCap = new AdjustableArrowCap(
  541. this.LineWidth + adjustment,
  542. this.LineWidth + adjustment,
  543. true);
  544. }
  545. else
  546. {
  547. graphics.Pen.StartCap = LineCap.ArrowAnchor;
  548. }
  549. }
  550. else if (this._startCap == LineAnchorCapStyle.Diamond)
  551. {
  552. graphics.Pen.StartCap = LineCap.DiamondAnchor;
  553. }
  554. else if (this._startCap == LineAnchorCapStyle.Round)
  555. {
  556. graphics.Pen.StartCap = LineCap.RoundAnchor;
  557. }
  558. else if (this._startCap == LineAnchorCapStyle.Square)
  559. {
  560. graphics.Pen.StartCap = LineCap.SquareAnchor;
  561. }
  562. if (this._endCap == LineAnchorCapStyle.Arrow)
  563. {
  564. // Adjust arrow size for small line width
  565. if (this.LineWidth < 4)
  566. {
  567. int adjustment = 3 - this.LineWidth;
  568. graphics.Pen.EndCap = LineCap.Custom;
  569. graphics.Pen.CustomEndCap = new AdjustableArrowCap(
  570. this.LineWidth + adjustment,
  571. this.LineWidth + adjustment,
  572. true);
  573. }
  574. else
  575. {
  576. graphics.Pen.EndCap = LineCap.ArrowAnchor;
  577. }
  578. }
  579. else if (this._endCap == LineAnchorCapStyle.Diamond)
  580. {
  581. graphics.Pen.EndCap = LineCap.DiamondAnchor;
  582. }
  583. else if (this._endCap == LineAnchorCapStyle.Round)
  584. {
  585. graphics.Pen.EndCap = LineCap.RoundAnchor;
  586. }
  587. else if (this._endCap == LineAnchorCapStyle.Square)
  588. {
  589. graphics.Pen.EndCap = LineCap.SquareAnchor;
  590. }
  591. }
  592. }
  593. // Painting mode
  594. if (this.Common.ProcessModePaint)
  595. {
  596. if (this.isPolygon)
  597. {
  598. // Draw polygon
  599. pathAbs.CloseAllFigures();
  600. graphics.DrawPathAbs(
  601. pathAbs,
  602. this.BackColor,
  603. this.BackHatchStyle,
  604. String.Empty,
  605. ChartImageWrapMode.Scaled,
  606. Color.Empty,
  607. ChartImageAlignmentStyle.Center,
  608. this.BackGradientStyle,
  609. this.BackSecondaryColor,
  610. this.LineColor,
  611. this.LineWidth,
  612. this.LineDashStyle,
  613. PenAlignment.Center,
  614. this.ShadowOffset,
  615. this.ShadowColor);
  616. }
  617. else
  618. {
  619. // Draw polyline
  620. graphics.DrawPathAbs(
  621. pathAbs,
  622. Color.Transparent,
  623. ChartHatchStyle.None,
  624. String.Empty,
  625. ChartImageWrapMode.Scaled,
  626. Color.Empty,
  627. ChartImageAlignmentStyle.Center,
  628. GradientStyle.None,
  629. Color.Empty,
  630. this.LineColor,
  631. this.LineWidth,
  632. this.LineDashStyle,
  633. PenAlignment.Center,
  634. this.ShadowOffset,
  635. this.ShadowColor);
  636. }
  637. }
  638. if (this.Common.ProcessModeRegions)
  639. {
  640. // Create line graphics path
  641. GraphicsPath selectionPath = null;
  642. GraphicsPath newPath = null;
  643. if (this.isPolygon)
  644. {
  645. selectionPath = pathAbs;
  646. }
  647. else
  648. {
  649. newPath = new GraphicsPath();
  650. selectionPath = newPath;
  651. selectionPath.AddPath(pathAbs, false);
  652. using (Pen pen = (Pen)graphics.Pen.Clone())
  653. {
  654. // Increase pen size by 2 pixels
  655. pen.DashStyle = DashStyle.Solid;
  656. pen.Width += 2;
  657. try
  658. {
  659. selectionPath.Widen(pen);
  660. }
  661. catch (OutOfMemoryException)
  662. {
  663. // GraphicsPath.Widen incorrectly throws OutOfMemoryException
  664. // catching here and reacting by not widening
  665. }
  666. catch (ArgumentException)
  667. {
  668. }
  669. }
  670. }
  671. // Add hot region
  672. this.Common.HotRegionsList.AddHotRegion(
  673. graphics,
  674. selectionPath,
  675. false,
  676. ReplaceKeywords(this.ToolTip),
  677. String.Empty,
  678. String.Empty,
  679. String.Empty,
  680. this,
  681. ChartElementType.Annotation);
  682. //Clean up
  683. if (newPath != null)
  684. newPath.Dispose();
  685. }
  686. // Restore line caps
  687. if (capChanged)
  688. {
  689. graphics.Pen.StartCap = oldStartCap;
  690. graphics.Pen.EndCap = oldEndCap;
  691. }
  692. // Paint selection handles
  693. PaintSelectionHandles(graphics, rectanglePosition, pathAbs);
  694. }
  695. }
  696. #endregion // Painting
  697. #region Position Changing
  698. /// <summary>
  699. /// Changes annotation position, so it exactly matches the bounary of the
  700. /// polyline path.
  701. /// </summary>
  702. private void ResizeToPathBoundary()
  703. {
  704. if(_graphicsPath.PointCount > 0)
  705. {
  706. // Get current annotation position in relative coordinates
  707. PointF firstPoint = PointF.Empty;
  708. PointF anchorPoint = PointF.Empty;
  709. SizeF size = SizeF.Empty;
  710. GetRelativePosition(out firstPoint, out size, out anchorPoint);
  711. // Get path boundary and convert it to relative coordinates
  712. RectangleF pathBoundary = _graphicsPath.GetBounds();
  713. pathBoundary.X *= size.Width / 100f;
  714. pathBoundary.Y *= size.Height / 100f;
  715. pathBoundary.X += firstPoint.X;
  716. pathBoundary.Y += firstPoint.Y;
  717. pathBoundary.Width *= size.Width / 100f;
  718. pathBoundary.Height *= size.Height / 100f;
  719. // Scale all current points
  720. using( Matrix matrix = new Matrix() )
  721. {
  722. matrix.Scale(size.Width/pathBoundary.Width, size.Height/pathBoundary.Height);
  723. matrix.Translate(-pathBoundary.X, -pathBoundary.Y);
  724. _graphicsPath.Transform(matrix);
  725. }
  726. // Set new position for annotation
  727. this.SetPositionRelative(pathBoundary, anchorPoint);
  728. }
  729. }
  730. /// <summary>
  731. /// Adjust annotation location and\or size as a result of user action.
  732. /// </summary>
  733. /// <param name="movingDistance">Distance to resize/move the annotation.</param>
  734. /// <param name="resizeMode">Resizing mode.</param>
  735. /// <param name="pixelCoord">Distance is in pixels, otherwise relative.</param>
  736. /// <param name="userInput">Indicates if position changing was a result of the user input.</param>
  737. override internal void AdjustLocationSize(SizeF movingDistance, ResizingMode resizeMode, bool pixelCoord, bool userInput)
  738. {
  739. // Call base class when not resizing the path points
  740. if(resizeMode != ResizingMode.MovingPathPoints)
  741. {
  742. base.AdjustLocationSize(movingDistance, resizeMode, pixelCoord, userInput);
  743. return;
  744. }
  745. // Get annotation position in relative coordinates
  746. PointF firstPoint = PointF.Empty;
  747. PointF anchorPoint = PointF.Empty;
  748. SizeF size = SizeF.Empty;
  749. GetRelativePosition(out firstPoint, out size, out anchorPoint);
  750. // Remember path before moving operation
  751. if(userInput == true && startMovePathRel == null)
  752. {
  753. this.startMovePathRel = (GraphicsPath)_graphicsPath.Clone();
  754. this.startMovePositionRel = new RectangleF(firstPoint, size);
  755. this.startMoveAnchorLocationRel = new PointF(anchorPoint.X, anchorPoint.Y);
  756. }
  757. // Convert moving distance to coordinates relative to the anotation
  758. if(pixelCoord)
  759. {
  760. movingDistance = this.GetGraphics().GetRelativeSize(movingDistance);
  761. }
  762. movingDistance.Width /= startMovePositionRel.Width / 100.0f;
  763. movingDistance.Height /= startMovePositionRel.Height / 100.0f;
  764. // Get path points and adjust position of one of them
  765. if(_graphicsPath.PointCount > 0)
  766. {
  767. GraphicsPath pathToMove = (userInput) ? startMovePathRel : _graphicsPath;
  768. PointF[] pathPoints = pathToMove.PathPoints;
  769. byte[] pathTypes = pathToMove.PathTypes;
  770. for(int pointIndex = 0; pointIndex < pathPoints.Length; pointIndex++)
  771. {
  772. // Adjust position
  773. if( currentPathPointIndex == pointIndex ||
  774. currentPathPointIndex < 0 ||
  775. currentPathPointIndex >= pathPoints.Length )
  776. {
  777. pathPoints[pointIndex].X -= movingDistance.Width;
  778. pathPoints[pointIndex].Y -= movingDistance.Height;
  779. }
  780. }
  781. // Adjust annotation position to the boundary of the path
  782. if(userInput && this.AllowResizing)
  783. {
  784. // Get path bounds in relative coordinates
  785. _defaultGraphicsPath.Dispose();
  786. _defaultGraphicsPath = new GraphicsPath(pathPoints, pathTypes);
  787. _graphicsPath = _defaultGraphicsPath;
  788. RectangleF pathBounds = _graphicsPath.GetBounds();
  789. pathBounds.X *= startMovePositionRel.Width / 100f;
  790. pathBounds.Y *= startMovePositionRel.Height / 100f;
  791. pathBounds.X += startMovePositionRel.X;
  792. pathBounds.Y += startMovePositionRel.Y;
  793. pathBounds.Width *= startMovePositionRel.Width / 100f;
  794. pathBounds.Height *= startMovePositionRel.Height / 100f;
  795. // Set new annotation position
  796. this.SetPositionRelative(pathBounds, anchorPoint);
  797. // Adjust path point position
  798. for(int pointIndex = 0; pointIndex < pathPoints.Length; pointIndex++)
  799. {
  800. pathPoints[pointIndex].X = startMovePositionRel.X + pathPoints[pointIndex].X * (startMovePositionRel.Width / 100f);
  801. pathPoints[pointIndex].Y = startMovePositionRel.Y + pathPoints[pointIndex].Y * (startMovePositionRel.Height / 100f);
  802. pathPoints[pointIndex].X = (pathPoints[pointIndex].X - pathBounds.X) / (pathBounds.Width / 100f);
  803. pathPoints[pointIndex].Y = (pathPoints[pointIndex].Y - pathBounds.Y) / (pathBounds.Height / 100f);
  804. }
  805. }
  806. // Position changed
  807. this.positionChanged = true;
  808. // Recreate path with new points
  809. _defaultGraphicsPath.Dispose();
  810. _defaultGraphicsPath = new GraphicsPath(pathPoints, pathTypes);
  811. _graphicsPath = _defaultGraphicsPath;
  812. this.pathChanged = true;
  813. // Invalidate annotation
  814. this.Invalidate();
  815. }
  816. }
  817. #endregion // Position Changing
  818. #region Placement Methods
  819. /// <summary>
  820. /// Ends user placement of an annotation.
  821. /// </summary>
  822. /// <remarks>
  823. /// Ends an annotation placement operation previously started by a
  824. /// <see cref="Annotation.BeginPlacement"/> method call.
  825. /// <para>
  826. /// Calling this method is not required, since placement will automatically
  827. /// end when an end user enters all required points. However, it is useful when an annotation
  828. /// placement operation needs to be aborted for some reason.
  829. /// </para>
  830. /// </remarks>
  831. override public void EndPlacement()
  832. {
  833. // Call base method
  834. base.EndPlacement();
  835. // Position was changed
  836. if(this.Chart != null)
  837. {
  838. this.Chart.OnAnnotationPositionChanged(this);
  839. }
  840. // Reset last placement position
  841. this.lastPlacementPosition = PointF.Empty;
  842. // Resize annotation to the boundary of the polygon
  843. ResizeToPathBoundary();
  844. // Position changed
  845. this.positionChanged = true;
  846. }
  847. /// <summary>
  848. /// Handles mouse down event during annotation placement.
  849. /// </summary>
  850. /// <param name="point">Mouse cursor position in pixels.</param>
  851. /// <param name="buttons">Mouse button down.</param>
  852. internal override void PlacementMouseDown(PointF point, MouseButtons buttons)
  853. {
  854. // Call base class method if path editing is not allowed
  855. if(!this.AllowPathEditing)
  856. {
  857. base.PlacementMouseDown(point, buttons);
  858. return;
  859. }
  860. if(buttons == MouseButtons.Right)
  861. {
  862. // Stop pacement
  863. this.EndPlacement();
  864. }
  865. if(buttons == MouseButtons.Left &&
  866. IsValidPlacementPosition(point.X, point.Y))
  867. {
  868. // Convert coordinate to relative
  869. PointF newPoint = this.GetGraphics().GetRelativePoint(point);
  870. if(this.lastPlacementPosition.IsEmpty)
  871. {
  872. // Set annotation coordinates to full chart
  873. this.X = 0f;
  874. this.Y = 0f;
  875. this.Width = 100f;
  876. this.Height = 100f;
  877. // Remeber position where mouse was clicked
  878. this.lastPlacementPosition = newPoint;
  879. }
  880. else
  881. {
  882. if(this.lastPlacementPosition.X == newPoint.X &&
  883. this.lastPlacementPosition.Y == newPoint.Y)
  884. {
  885. // Stop pacement
  886. this.EndPlacement();
  887. }
  888. }
  889. // Add a line from prev. position to current into the path
  890. using( GraphicsPath tmpPath = new GraphicsPath() )
  891. {
  892. PointF firstPoint = this.lastPlacementPosition;
  893. if(_graphicsPath.PointCount > 1)
  894. {
  895. firstPoint = _graphicsPath.GetLastPoint();
  896. }
  897. tmpPath.AddLine(firstPoint, newPoint);
  898. _graphicsPath.AddPath(tmpPath, true);
  899. }
  900. // Remember last position
  901. this.lastPlacementPosition = newPoint;
  902. // Invalidate and update the chart
  903. if(Chart != null)
  904. {
  905. Invalidate();
  906. Chart.UpdateAnnotations();
  907. }
  908. }
  909. }
  910. /// <summary>
  911. /// Handles mouse up event during annotation placement.
  912. /// </summary>
  913. /// <param name="point">Mouse cursor position in pixels.</param>
  914. /// <param name="buttons">Mouse button Up.</param>
  915. /// <returns>Return true when placing finished.</returns>
  916. internal override bool PlacementMouseUp(PointF point, MouseButtons buttons)
  917. {
  918. // Call base class method if path editing is not allowed
  919. if(!this.AllowPathEditing)
  920. {
  921. return base.PlacementMouseUp(point, buttons);
  922. }
  923. if(buttons == MouseButtons.Left &&
  924. isFreeDrawPlacement)
  925. {
  926. // Stop pacement
  927. this.EndPlacement();
  928. }
  929. return false;
  930. }
  931. /// <summary>
  932. /// Handles mouse move event during annotation placement.
  933. /// </summary>
  934. /// <param name="point">Mouse cursor position in pixels.</param>
  935. internal override void PlacementMouseMove(PointF point)
  936. {
  937. // Call base class method if path editing is not allowed
  938. if(!this.AllowPathEditing)
  939. {
  940. base.PlacementMouseMove(point);
  941. return;
  942. }
  943. // Check if annotation was moved
  944. if( this.GetGraphics() != null &&
  945. _graphicsPath.PointCount > 0 &&
  946. !this.lastPlacementPosition.IsEmpty)
  947. {
  948. // Convert coordinate to relative
  949. PointF newPoint = this.GetGraphics().GetRelativePoint(point);
  950. if(this.isFreeDrawPlacement)
  951. {
  952. // Add new point
  953. using( GraphicsPath tmpPath = new GraphicsPath() )
  954. {
  955. PointF firstPoint = this.lastPlacementPosition;
  956. if(_graphicsPath.PointCount > 1)
  957. {
  958. firstPoint = _graphicsPath.GetLastPoint();
  959. }
  960. tmpPath.AddLine(firstPoint, newPoint);
  961. _graphicsPath.AddPath(tmpPath, true);
  962. }
  963. }
  964. else
  965. {
  966. // Adjust last point position
  967. PointF[] pathPoints = _graphicsPath.PathPoints;
  968. byte[] pathTypes = _graphicsPath.PathTypes;
  969. pathPoints[pathPoints.Length - 1] = newPoint;
  970. _defaultGraphicsPath.Dispose();
  971. _defaultGraphicsPath = new GraphicsPath(pathPoints, pathTypes);
  972. _graphicsPath = _defaultGraphicsPath;
  973. }
  974. // Position changed
  975. this.positionChanged = true;
  976. // Invalidate and update the chart
  977. if(this.Chart != null)
  978. {
  979. Invalidate();
  980. this.Chart.UpdateAnnotations();
  981. }
  982. }
  983. }
  984. #endregion // Placement Methods
  985. #endregion
  986. #region IDisposable override
  987. /// <summary>
  988. /// Releases unmanaged and - optionally - managed resources
  989. /// </summary>
  990. /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
  991. protected override void Dispose(bool disposing)
  992. {
  993. if (disposing)
  994. {
  995. if (_defaultGraphicsPath != null)
  996. {
  997. _defaultGraphicsPath.Dispose();
  998. _defaultGraphicsPath = null;
  999. }
  1000. if (_pathPoints != null)
  1001. {
  1002. _pathPoints.Dispose();
  1003. _pathPoints = null;
  1004. }
  1005. }
  1006. base.Dispose(disposing);
  1007. }
  1008. #endregion
  1009. }
  1010. /// <summary>
  1011. /// <b>PolygonAnnotation</b> is a class that represents a polygon annotation.
  1012. /// </summary>
  1013. [
  1014. SRDescription("DescriptionAttributePolygonAnnotation_PolygonAnnotation"),
  1015. ]
  1016. public class PolygonAnnotation : PolylineAnnotation
  1017. {
  1018. #region Construction and Initialization
  1019. /// <summary>
  1020. /// Default public constructor.
  1021. /// </summary>
  1022. public PolygonAnnotation()
  1023. : base()
  1024. {
  1025. this.isPolygon = true;
  1026. }
  1027. #endregion
  1028. #region Properties
  1029. #region Non Applicable Annotation Appearance Attributes (set as Non-Browsable)
  1030. /// <summary>
  1031. /// Not applicable to this annotation type.
  1032. /// <seealso cref="EndCap"/>
  1033. /// </summary>
  1034. /// <value>
  1035. /// A <see cref="LineAnchorCapStyle"/> value.
  1036. /// </value>
  1037. [
  1038. SRCategory("CategoryAttributeAppearance"),
  1039. Browsable(false),
  1040. DefaultValue(LineAnchorCapStyle.None),
  1041. ]
  1042. override public LineAnchorCapStyle StartCap
  1043. {
  1044. get
  1045. {
  1046. return base.StartCap;
  1047. }
  1048. set
  1049. {
  1050. base.StartCap = value;
  1051. }
  1052. }
  1053. /// <summary>
  1054. /// Not applicable to this annotation type.
  1055. /// <seealso cref="StartCap"/>
  1056. /// </summary>
  1057. /// <value>
  1058. /// A <see cref="LineAnchorCapStyle"/> value.
  1059. /// </value>
  1060. [
  1061. SRCategory("CategoryAttributeAppearance"),
  1062. Browsable(false),
  1063. DefaultValue(LineAnchorCapStyle.None),
  1064. ]
  1065. override public LineAnchorCapStyle EndCap
  1066. {
  1067. get
  1068. {
  1069. return base.EndCap;
  1070. }
  1071. set
  1072. {
  1073. base.EndCap = value;
  1074. }
  1075. }
  1076. #endregion
  1077. #region Applicable Annotation Appearance Attributes (set as Browsable)
  1078. /// <summary>
  1079. /// Gets or sets the background color of an annotation.
  1080. /// <seealso cref="BackSecondaryColor"/>
  1081. /// <seealso cref="BackHatchStyle"/>
  1082. /// <seealso cref="BackGradientStyle"/>
  1083. /// </summary>
  1084. /// <value>
  1085. /// A <see cref="Color"/> value used for the background of an annotation.
  1086. /// </value>
  1087. [
  1088. SRCategory("CategoryAttributeAppearance"),
  1089. Browsable(true),
  1090. DefaultValue(typeof(Color), ""),
  1091. SRDescription("DescriptionAttributeBackColor"),
  1092. NotifyParentPropertyAttribute(true),
  1093. TypeConverter(typeof(ColorConverter)),
  1094. #if DESIGNER
  1095. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  1096. #endif
  1097. ]
  1098. override public Color BackColor
  1099. {
  1100. get
  1101. {
  1102. return base.BackColor;
  1103. }
  1104. set
  1105. {
  1106. base.BackColor = value;
  1107. }
  1108. }
  1109. /// <summary>
  1110. /// Gets or sets the background hatch style of an annotation.
  1111. /// <seealso cref="BackSecondaryColor"/>
  1112. /// <seealso cref="BackColor"/>
  1113. /// <seealso cref="BackGradientStyle"/>
  1114. /// </summary>
  1115. /// <value>
  1116. /// A <see cref="ChartHatchStyle"/> value used for the background of an annotation.
  1117. /// </value>
  1118. /// <remarks>
  1119. /// Two colors are used to draw the hatching, <see cref="BackColor"/> and <see cref="BackSecondaryColor"/>.
  1120. /// </remarks>
  1121. [
  1122. SRCategory("CategoryAttributeAppearance"),
  1123. Browsable(true),
  1124. DefaultValue(ChartHatchStyle.None),
  1125. NotifyParentPropertyAttribute(true),
  1126. SRDescription("DescriptionAttributeBackHatchStyle"),
  1127. #if DESIGNER
  1128. Editor(typeof(HatchStyleEditor), typeof(UITypeEditor))
  1129. #endif
  1130. ]
  1131. override public ChartHatchStyle BackHatchStyle
  1132. {
  1133. get
  1134. {
  1135. return base.BackHatchStyle;
  1136. }
  1137. set
  1138. {
  1139. base.BackHatchStyle = value;
  1140. }
  1141. }
  1142. /// <summary>
  1143. /// Gets or sets the background gradient style of an annotation.
  1144. /// <seealso cref="BackSecondaryColor"/>
  1145. /// <seealso cref="BackColor"/>
  1146. /// <seealso cref="BackHatchStyle"/>
  1147. /// </summary>
  1148. /// <value>
  1149. /// A <see cref="GradientStyle"/> value used for the background of an annotation.
  1150. /// </value>
  1151. /// <remarks>
  1152. /// Two colors are used to draw the gradient, <see cref="BackColor"/> and <see cref="BackSecondaryColor"/>.
  1153. /// </remarks>
  1154. [
  1155. SRCategory("CategoryAttributeAppearance"),
  1156. Browsable(true),
  1157. DefaultValue(GradientStyle.None),
  1158. NotifyParentPropertyAttribute(true),
  1159. SRDescription("DescriptionAttributeBackGradientStyle"),
  1160. #if DESIGNER
  1161. Editor(typeof(GradientEditor), typeof(UITypeEditor))
  1162. #endif
  1163. ]
  1164. override public GradientStyle BackGradientStyle
  1165. {
  1166. get
  1167. {
  1168. return base.BackGradientStyle;
  1169. }
  1170. set
  1171. {
  1172. base.BackGradientStyle = value;
  1173. }
  1174. }
  1175. /// <summary>
  1176. /// Gets or sets the secondary background color of an annotation.
  1177. /// <seealso cref="BackColor"/>
  1178. /// <seealso cref="BackHatchStyle"/>
  1179. /// <seealso cref="BackGradientStyle"/>
  1180. /// </summary>
  1181. /// <value>
  1182. /// A <see cref="Color"/> value used for the secondary color of an annotation background with
  1183. /// hatching or gradient fill.
  1184. /// </value>
  1185. /// <remarks>
  1186. /// This color is used with <see cref="BackColor"/> when <see cref="BackHatchStyle"/> or
  1187. /// <see cref="BackGradientStyle"/> are used.
  1188. /// </remarks>
  1189. [
  1190. SRCategory("CategoryAttributeAppearance"),
  1191. Browsable(true),
  1192. DefaultValue(typeof(Color), ""),
  1193. NotifyParentPropertyAttribute(true),
  1194. SRDescription("DescriptionAttributeBackSecondaryColor"),
  1195. TypeConverter(typeof(ColorConverter)),
  1196. #if DESIGNER
  1197. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  1198. #endif
  1199. ]
  1200. override public Color BackSecondaryColor
  1201. {
  1202. get
  1203. {
  1204. return base.BackSecondaryColor;
  1205. }
  1206. set
  1207. {
  1208. base.BackSecondaryColor = value;
  1209. }
  1210. }
  1211. #endregion
  1212. #region Other
  1213. /// <summary>
  1214. /// Gets or sets an annotation's type name.
  1215. /// </summary>
  1216. /// <remarks>
  1217. /// This property is used to get the name of each annotation type
  1218. /// (e.g. Line, Rectangle, Ellipse).
  1219. /// <para>
  1220. /// This property is for internal use and is hidden at design and run time.
  1221. /// </para>
  1222. /// </remarks>
  1223. [
  1224. SRCategory("CategoryAttributeMisc"),
  1225. Bindable(true),
  1226. Browsable(false),
  1227. EditorBrowsableAttribute(EditorBrowsableState.Never),
  1228. DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
  1229. SerializationVisibilityAttribute(SerializationVisibility.Hidden),
  1230. SRDescription("DescriptionAttributeAnnotationType"),
  1231. ]
  1232. public override string AnnotationType
  1233. {
  1234. get
  1235. {
  1236. return "Polygon";
  1237. }
  1238. }
  1239. /// <summary>
  1240. /// Gets or sets an annotation's selection points style.
  1241. /// </summary>
  1242. /// <value>
  1243. /// A <see cref="SelectionPointsStyle"/> value that represents an annotation's
  1244. /// selection style.
  1245. /// </value>
  1246. /// <remarks>
  1247. /// This property is for internal use and is hidden at design and run time.
  1248. /// </remarks>
  1249. [
  1250. SRCategory("CategoryAttributeAppearance"),
  1251. DefaultValue(SelectionPointsStyle.Rectangle),
  1252. ParenthesizePropertyNameAttribute(true),
  1253. Browsable(false),
  1254. EditorBrowsableAttribute(EditorBrowsableState.Never),
  1255. DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
  1256. SerializationVisibilityAttribute(SerializationVisibility.Hidden),
  1257. SRDescription("DescriptionAttributeSelectionPointsStyle"),
  1258. ]
  1259. override internal SelectionPointsStyle SelectionPointsStyle
  1260. {
  1261. get
  1262. {
  1263. return SelectionPointsStyle.Rectangle;
  1264. }
  1265. }
  1266. #endregion
  1267. #endregion
  1268. }
  1269. /// <summary><b>AnnotationPathPointCollection</b> is a collection of polyline
  1270. /// annotation path points, and is only available via the <b>GraphicsPathPoints</b>
  1271. /// property at design-time.
  1272. /// <seealso cref="PolylineAnnotation.GraphicsPathPoints"/></summary>
  1273. /// <remarks>
  1274. /// This collection is used at design-time only, and uses serialization to expose the
  1275. /// shape of the polyline and polygon via their GraphicsPathPoints collection property.
  1276. /// At run-time, use Path property to set the path of a polyline or polygon
  1277. /// </remarks>
  1278. [
  1279. SRDescription("DescriptionAttributeAnnotationPathPointCollection_AnnotationPathPointCollection"),
  1280. ]
  1281. public class AnnotationPathPointCollection : ChartElementCollection<AnnotationPathPoint>
  1282. {
  1283. #region Fields
  1284. internal PolylineAnnotation annotation = null;
  1285. private GraphicsPath _graphicsPath = null;
  1286. #endregion // Fields
  1287. #region Constructors
  1288. /// <summary>
  1289. /// Default public constructor.
  1290. /// </summary>
  1291. public AnnotationPathPointCollection(PolylineAnnotation annotation)
  1292. : base(annotation)
  1293. {
  1294. this.annotation = annotation;
  1295. }
  1296. #endregion // Constructors
  1297. #region Methods
  1298. /// <summary>
  1299. /// Forces the invalidation of the chart element
  1300. /// </summary>
  1301. public override void Invalidate()
  1302. {
  1303. if (this.annotation != null)
  1304. {
  1305. //Dispose previously instantiated graphics path
  1306. if (this._graphicsPath != null)
  1307. {
  1308. this._graphicsPath.Dispose();
  1309. this._graphicsPath = null;
  1310. }
  1311. // Recreate polyline annotation path
  1312. if (this.Count > 0)
  1313. {
  1314. PointF[] points = new PointF[this.Count];
  1315. byte[] types = new byte[this.Count];
  1316. for (int index = 0; index < this.Count; index++)
  1317. {
  1318. points[index] = new PointF(this[index].X, this[index].Y);
  1319. types[index] = this[index].PointType;
  1320. }
  1321. this._graphicsPath = new GraphicsPath(points, types);
  1322. }
  1323. else
  1324. {
  1325. this._graphicsPath = new GraphicsPath();
  1326. }
  1327. // Invalidate annotation
  1328. this.annotation.GraphicsPath = this._graphicsPath;
  1329. this.annotation.Invalidate();
  1330. }
  1331. base.Invalidate();
  1332. }
  1333. #endregion // Methods
  1334. #region IDisposable Members
  1335. /// <summary>
  1336. /// Releases unmanaged and - optionally - managed resources
  1337. /// </summary>
  1338. /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
  1339. protected override void Dispose(bool disposing)
  1340. {
  1341. if (disposing)
  1342. {
  1343. // Free up managed resources
  1344. if (this._graphicsPath != null)
  1345. {
  1346. this._graphicsPath.Dispose();
  1347. this._graphicsPath = null;
  1348. }
  1349. }
  1350. base.Dispose(disposing);
  1351. }
  1352. #endregion
  1353. }
  1354. /// <summary>
  1355. /// The <b>AnnotationPathPoint</b> class represents a path point of a polyline or polygon,
  1356. /// and is stored in their <b>GraphicsPathPoints</b> property, which is only available at design-time.
  1357. /// </summary>
  1358. /// <remarks>
  1359. /// At run-time, use <b>Path</b> property to set the path of a polyline or polygon.
  1360. /// </remarks>
  1361. [
  1362. SRDescription("DescriptionAttributeAnnotationPathPoint_AnnotationPathPoint"),
  1363. ]
  1364. public class AnnotationPathPoint: ChartElement
  1365. {
  1366. #region Fields
  1367. // Point X value
  1368. private float _x = 0f;
  1369. // Point Y value
  1370. private float _y = 0f;
  1371. // Point type
  1372. private byte _pointType = 1;
  1373. #endregion // Fields
  1374. #region Constructors
  1375. /// <summary>
  1376. /// Default public constructor.
  1377. /// </summary>
  1378. public AnnotationPathPoint()
  1379. {
  1380. }
  1381. /// <summary>
  1382. /// Constructor that takes X and Y parameters.
  1383. /// </summary>
  1384. /// <param name="x">Point's X value.</param>
  1385. /// <param name="y">Point's Y value.</param>
  1386. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
  1387. Justification="X and Y are cartesian coordinates and well understood")]
  1388. public AnnotationPathPoint(float x, float y)
  1389. {
  1390. this._x = x;
  1391. this._y = y;
  1392. }
  1393. /// <summary>
  1394. /// Constructor that takes X, Y and point type parameters.
  1395. /// </summary>
  1396. /// <param name="x">Point's X value.</param>
  1397. /// <param name="y">Point's Y value.</param>
  1398. /// <param name="type">Point type.</param>
  1399. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
  1400. Justification = "X and Y are cartesian coordinates and well understood")]
  1401. public AnnotationPathPoint(float x, float y, byte type)
  1402. {
  1403. this._x = x;
  1404. this._y = y;
  1405. this._pointType = type;
  1406. }
  1407. #endregion // Constructors
  1408. #region Properties
  1409. /// <summary>
  1410. /// Gets or sets an annotation path point's X coordinate.
  1411. /// </summary>
  1412. /// <value>
  1413. /// A float value for the point's X coordinate.
  1414. /// </value>
  1415. [
  1416. SRCategory("CategoryAttributePosition"),
  1417. DefaultValue(0f),
  1418. Browsable(true),
  1419. SRDescription("DescriptionAttributeAnnotationPathPoint_X"),
  1420. ]
  1421. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "X")]
  1422. public float X
  1423. {
  1424. get
  1425. {
  1426. return _x;
  1427. }
  1428. set
  1429. {
  1430. _x = value;
  1431. }
  1432. }
  1433. /// <summary>
  1434. /// Gets or sets an annotation path point's Y coordinate.
  1435. /// </summary>
  1436. /// <value>
  1437. /// A float value for the point's Y coordinate.
  1438. /// </value>
  1439. [
  1440. SRCategory("CategoryAttributePosition"),
  1441. DefaultValue(0f),
  1442. Browsable(true),
  1443. SRDescription("DescriptionAttributeAnnotationPathPoint_Y"),
  1444. ]
  1445. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Y")]
  1446. public float Y
  1447. {
  1448. get
  1449. {
  1450. return _y;
  1451. }
  1452. set
  1453. {
  1454. _y = value;
  1455. }
  1456. }
  1457. /// <summary>
  1458. /// Gets or sets an annotation path point's type.
  1459. /// </summary>
  1460. /// <value>
  1461. /// A byte value.
  1462. /// </value>
  1463. /// <remarks>
  1464. /// See the <see cref="PathPointType"/> enumeration for more details.
  1465. /// </remarks>
  1466. [
  1467. SRCategory("CategoryAttributePosition"),
  1468. DefaultValue(typeof(byte), "1"),
  1469. Browsable(false),
  1470. EditorBrowsableAttribute(EditorBrowsableState.Never),
  1471. SRDescription("DescriptionAttributeAnnotationPathPoint_Name"),
  1472. ]
  1473. public byte PointType
  1474. {
  1475. get
  1476. {
  1477. return _pointType;
  1478. }
  1479. set
  1480. {
  1481. _pointType = value;
  1482. }
  1483. }
  1484. /// <summary>
  1485. /// Gets or sets an annotation path point's name.
  1486. /// </summary>
  1487. /// <para>
  1488. /// This property is for internal use and is hidden at design and run time.
  1489. /// </para>
  1490. [
  1491. SRCategory("CategoryAttributeMisc"),
  1492. DefaultValue("PathPoint"),
  1493. Browsable(false),
  1494. EditorBrowsableAttribute(EditorBrowsableState.Never),
  1495. SRDescription("DescriptionAttributeAnnotationPathPoint_Name"),
  1496. DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
  1497. SerializationVisibilityAttribute(SerializationVisibility.Hidden),
  1498. ]
  1499. public string Name
  1500. {
  1501. get
  1502. {
  1503. return "PathPoint";
  1504. }
  1505. }
  1506. #endregion // Properties
  1507. }
  1508. }