StripLine.cs 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417
  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: StripLinesCollection class is used to expose stripes
  6. // or lines on the plotting area and is exposed through
  7. // StripLines property of each Axis.
  8. // Each StripLine class presents one or series of
  9. // repeated axis horizontal or vertical strips within
  10. // the plotting are.
  11. // When multiple strip lines are defined for an axis,
  12. // there is a possibility of overlap. The z-order of
  13. // StripLine objects is determined by their order of
  14. // occurrence in the StripLinesCollection object. The
  15. // z-order follows this convention, the first occurrence
  16. // is drawn first, the second occurrence is drawn second,
  17. // and so on.
  18. // Highlighting weekends on date axis is a good example
  19. // of using strip lines with interval.
  20. //
  21. using System;
  22. using System.Collections.Generic;
  23. using System.ComponentModel;
  24. using System.Drawing;
  25. using System.Drawing.Design;
  26. using System.Drawing.Drawing2D;
  27. using FastReport.DataVisualization.Charting.Utilities;
  28. namespace FastReport.DataVisualization.Charting
  29. {
  30. /// <summary>
  31. /// The StripLinesCollection class is a strongly typed collection of
  32. /// StripLine classes.
  33. /// </summary>
  34. [
  35. SRDescription("DescriptionAttributeStripLinesCollection_StripLinesCollection"),
  36. ]
  37. public class StripLinesCollection : ChartElementCollection<StripLine>
  38. {
  39. #region Constructor
  40. /// <summary>
  41. /// Legend item collection object constructor
  42. /// </summary>
  43. /// <param name="axis">Axis object reference.</param>
  44. internal StripLinesCollection(Axis axis)
  45. : base(axis)
  46. {
  47. }
  48. #endregion
  49. }
  50. /// <summary>
  51. /// The StripLine class contains properties which define visual appearance
  52. /// of the stripe or line, its position according to the axis. It
  53. /// may optionally contain the repeat interval. Text may associate
  54. /// with a strip or a line. It also contains methods of drawing and hit
  55. /// testing.
  56. /// </summary>
  57. [
  58. SRDescription("DescriptionAttributeStripLine_StripLine"),
  59. DefaultProperty("IntervalOffset"),
  60. ]
  61. public class StripLine : ChartElement
  62. {
  63. #region Fields
  64. // Private data members, which store properties values
  65. private double _intervalOffset = 0;
  66. private double _interval = 0;
  67. private DateTimeIntervalType _intervalType = DateTimeIntervalType.Auto;
  68. internal DateTimeIntervalType intervalOffsetType = DateTimeIntervalType.Auto;
  69. internal bool interlaced = false;
  70. private double _stripWidth = 0;
  71. private DateTimeIntervalType _stripWidthType = DateTimeIntervalType.Auto;
  72. private Color _backColor = Color.Empty;
  73. private ChartHatchStyle _backHatchStyle = ChartHatchStyle.None;
  74. private string _backImage = "";
  75. private ChartImageWrapMode _backImageWrapMode = ChartImageWrapMode.Tile;
  76. private Color _backImageTransparentColor = Color.Empty;
  77. private ChartImageAlignmentStyle _backImageAlignment = ChartImageAlignmentStyle.TopLeft;
  78. private GradientStyle _backGradientStyle = GradientStyle.None;
  79. private Color _backSecondaryColor = Color.Empty;
  80. private Color _borderColor = Color.Empty;
  81. private int _borderWidth = 1;
  82. private ChartDashStyle _borderDashStyle = ChartDashStyle.Solid;
  83. // Strip/Line title properties
  84. private string _text = "";
  85. private Color _foreColor = Color.Black;
  86. private FontCache _fontCache = new FontCache();
  87. private Font _font = null;
  88. private StringAlignment _textAlignment = StringAlignment.Far;
  89. private StringAlignment _textLineAlignment = StringAlignment.Near;
  90. // Chart image map properties
  91. private string _toolTip = "";
  92. // Default text orientation
  93. private TextOrientation _textOrientation = TextOrientation.Auto;
  94. #endregion
  95. #region Properties
  96. /// <summary>
  97. /// Gets axes to which this object attached to.
  98. /// </summary>
  99. /// <returns>Axis object reference.</returns>
  100. internal Axis Axis
  101. {
  102. get
  103. {
  104. if (Parent != null)
  105. return Parent.Parent as Axis;
  106. else
  107. return null;
  108. }
  109. }
  110. #endregion
  111. #region Constructors
  112. /// <summary>
  113. /// Strip line object constructor.
  114. /// </summary>
  115. public StripLine()
  116. : base()
  117. {
  118. _font = _fontCache.DefaultFont;
  119. }
  120. #endregion
  121. #region Painting methods
  122. /// <summary>
  123. /// Checks if chart title is drawn vertically.
  124. /// Note: From the drawing perspective stacked text orientation is not vertical.
  125. /// </summary>
  126. /// <returns>True if text is vertical.</returns>
  127. private bool IsTextVertical
  128. {
  129. get
  130. {
  131. TextOrientation currentTextOrientation = this.GetTextOrientation();
  132. return currentTextOrientation == TextOrientation.Rotated90 || currentTextOrientation == TextOrientation.Rotated270;
  133. }
  134. }
  135. /// <summary>
  136. /// Returns stripline text orientation. If set to Auto automatically determines the
  137. /// orientation based on the orientation of the stripline.
  138. /// </summary>
  139. /// <returns>Current text orientation.</returns>
  140. private TextOrientation GetTextOrientation()
  141. {
  142. if (this.TextOrientation == TextOrientation.Auto && this.Axis != null)
  143. {
  144. if (this.Axis.AxisPosition == AxisPosition.Bottom || this.Axis.AxisPosition == AxisPosition.Top)
  145. {
  146. return TextOrientation.Rotated270;
  147. }
  148. return TextOrientation.Horizontal;
  149. }
  150. return this.TextOrientation;
  151. }
  152. /// <summary>
  153. /// Draw strip(s) or line(s).
  154. /// </summary>
  155. /// <param name="graph">Reference to the Chart Graphics object.</param>
  156. /// <param name="common">Common objects.</param>
  157. /// <param name="drawLinesOnly">Indicates if Lines or Stripes should be drawn.</param>
  158. internal void Paint(
  159. ChartGraphics graph,
  160. CommonElements common,
  161. bool drawLinesOnly)
  162. {
  163. // Strip lines are not supported in circular chart area
  164. if(this.Axis.ChartArea.chartAreaIsCurcular)
  165. {
  166. return;
  167. }
  168. // Get plot area position
  169. RectangleF plotAreaPosition = this.Axis.ChartArea.PlotAreaPosition.ToRectangleF();
  170. // Detect if strip/line is horizontal or vertical
  171. bool horizontal = true;
  172. if(this.Axis.AxisPosition == AxisPosition.Bottom || this.Axis.AxisPosition == AxisPosition.Top)
  173. {
  174. horizontal = false;
  175. }
  176. // Get first series attached to this axis
  177. Series axisSeries = null;
  178. if(Axis.axisType == AxisName.X || Axis.axisType == AxisName.X2)
  179. {
  180. List<string> seriesArray = Axis.ChartArea.GetXAxesSeries((Axis.axisType == AxisName.X) ? AxisType.Primary : AxisType.Secondary, Axis.SubAxisName);
  181. if(seriesArray.Count > 0)
  182. {
  183. axisSeries = Axis.Common.DataManager.Series[seriesArray[0]];
  184. if(axisSeries != null && !axisSeries.IsXValueIndexed)
  185. {
  186. axisSeries = null;
  187. }
  188. }
  189. }
  190. // Get starting position from axis
  191. // NOTE: Starting position was changed from "this.Axis.minimum" to
  192. // fix the minimum scaleView location to fix issue #5962 -- AG
  193. double currentPosition = this.Axis.ViewMinimum;
  194. // Adjust start position depending on the interval type
  195. if(!Axis.ChartArea.chartAreaIsCurcular ||
  196. Axis.axisType == AxisName.Y ||
  197. Axis.axisType == AxisName.Y2 )
  198. {
  199. double intervalToUse = this.Interval;
  200. // NOTE: fix for issue #5962
  201. // Always use original grid interval for isInterlaced strip lines.
  202. if (this.interlaced)
  203. {
  204. // Automaticly generated isInterlaced strips have interval twice as big as major grids
  205. intervalToUse /= 2.0;
  206. }
  207. currentPosition = ChartHelper.AlignIntervalStart(currentPosition, intervalToUse, this.IntervalType, axisSeries);
  208. }
  209. // Too many tick marks
  210. if(this.Interval != 0)
  211. {
  212. if( ( Axis.ViewMaximum - Axis.ViewMinimum ) / ChartHelper.GetIntervalSize(currentPosition, this._interval, this._intervalType, axisSeries, 0, DateTimeIntervalType.Number, false) > ChartHelper.MaxNumOfGridlines)
  213. return;
  214. }
  215. DateTimeIntervalType offsetType = (IntervalOffsetType == DateTimeIntervalType.Auto) ? IntervalType : IntervalOffsetType;
  216. if(this.Interval == 0)
  217. {
  218. currentPosition = this.IntervalOffset;
  219. }
  220. /******************************************************************
  221. * Removed by AG. Causing issues with interalced strip lines.
  222. /******************************************************************
  223. else if(axisSeries != null && axisSeries.IsXValueIndexed)
  224. {
  225. // Align first position for indexed series
  226. currentPosition += this.Axis.AlignIndexedIntervalStart(
  227. currentPosition,
  228. this.Interval,
  229. this.IntervalType,
  230. axisSeries,
  231. this.IntervalOffset,
  232. offsetType,
  233. false);
  234. }
  235. */
  236. else
  237. {
  238. if(this.IntervalOffset > 0)
  239. {
  240. currentPosition += ChartHelper.GetIntervalSize(currentPosition, this.IntervalOffset,
  241. offsetType, axisSeries, 0, DateTimeIntervalType.Number, false);
  242. }
  243. else if(this.IntervalOffset < 0)
  244. {
  245. currentPosition -= ChartHelper.GetIntervalSize(currentPosition, -this.IntervalOffset,
  246. offsetType, axisSeries, 0, DateTimeIntervalType.Number, false);
  247. }
  248. }
  249. // Draw several lines or strips if Interval property is set
  250. int counter = 0;
  251. do
  252. {
  253. // Check if we do not exceed max number of elements
  254. if(counter++ > ChartHelper.MaxNumOfGridlines)
  255. {
  256. break;
  257. }
  258. // Draw strip
  259. if (this.StripWidth > 0 && !drawLinesOnly)
  260. {
  261. double stripRightPosition = currentPosition + ChartHelper.GetIntervalSize(currentPosition, this.StripWidth, this.StripWidthType, axisSeries, this.IntervalOffset, offsetType, false);
  262. if (stripRightPosition > this.Axis.ViewMinimum && currentPosition < this.Axis.ViewMaximum)
  263. {
  264. // Calculate strip rectangle
  265. RectangleF rect = RectangleF.Empty;
  266. double pos1 = (float)this.Axis.GetLinearPosition(currentPosition);
  267. double pos2 = (float)this.Axis.GetLinearPosition(stripRightPosition);
  268. if (horizontal)
  269. {
  270. rect.X = plotAreaPosition.X;
  271. rect.Width = plotAreaPosition.Width;
  272. rect.Y = (float)Math.Min(pos1, pos2);
  273. rect.Height = (float)Math.Max(pos1, pos2) - rect.Y;
  274. // Check rectangle boundaries
  275. rect.Intersect(plotAreaPosition);
  276. }
  277. else
  278. {
  279. rect.Y = plotAreaPosition.Y;
  280. rect.Height = plotAreaPosition.Height;
  281. rect.X = (float)Math.Min(pos1, pos2);
  282. rect.Width = (float)Math.Max(pos1, pos2) - rect.X;
  283. // Check rectangle boundaries
  284. rect.Intersect(plotAreaPosition);
  285. }
  286. if (rect.Width > 0 && rect.Height > 0)
  287. {
  288. // Start Svg Selection mode
  289. graph.StartHotRegion("", this._toolTip);
  290. if (!this.Axis.ChartArea.Area3DStyle.Enable3D)
  291. {
  292. // Draw strip
  293. graph.FillRectangleRel(rect,
  294. this.BackColor, this.BackHatchStyle, this.BackImage,
  295. this.BackImageWrapMode, this.BackImageTransparentColor, this.BackImageAlignment,
  296. this.BackGradientStyle, this.BackSecondaryColor, this.BorderColor,
  297. this.BorderWidth, this.BorderDashStyle, Color.Empty,
  298. 0, PenAlignment.Inset);
  299. }
  300. else
  301. {
  302. Draw3DStrip(graph, rect, horizontal);
  303. }
  304. // End Svg Selection mode
  305. graph.EndHotRegion();
  306. // Draw strip line title
  307. PaintTitle(graph, rect);
  308. if (common.ProcessModeRegions)
  309. {
  310. if (!this.Axis.ChartArea.Area3DStyle.Enable3D)
  311. {
  312. common.HotRegionsList.AddHotRegion(rect, this.ToolTip, string.Empty, string.Empty, string.Empty, this, ChartElementType.StripLines, null);
  313. }
  314. }
  315. }
  316. }
  317. }
  318. // Draw line
  319. else if (this.StripWidth == 0 && drawLinesOnly)
  320. {
  321. if (currentPosition > this.Axis.ViewMinimum && currentPosition < this.Axis.ViewMaximum)
  322. {
  323. // Calculate line position
  324. PointF point1 = PointF.Empty;
  325. PointF point2 = PointF.Empty;
  326. if (horizontal)
  327. {
  328. point1.X = plotAreaPosition.X;
  329. point1.Y = (float)this.Axis.GetLinearPosition(currentPosition);
  330. point2.X = plotAreaPosition.Right;
  331. point2.Y = point1.Y;
  332. }
  333. else
  334. {
  335. point1.X = (float)this.Axis.GetLinearPosition(currentPosition);
  336. point1.Y = plotAreaPosition.Y;
  337. point2.X = point1.X;
  338. point2.Y = plotAreaPosition.Bottom;
  339. }
  340. // Start Svg Selection mode
  341. graph.StartHotRegion("", this._toolTip);
  342. // Draw Line
  343. if (!this.Axis.ChartArea.Area3DStyle.Enable3D)
  344. {
  345. graph.DrawLineRel(this.BorderColor, this.BorderWidth, this.BorderDashStyle, point1, point2);
  346. }
  347. else
  348. {
  349. graph.Draw3DGridLine(this.Axis.ChartArea, _borderColor, _borderWidth, _borderDashStyle, point1, point2, horizontal, Axis.Common, this);
  350. }
  351. // End Svg Selection mode
  352. graph.EndHotRegion();
  353. // Draw strip line title
  354. PaintTitle(graph, point1, point2);
  355. if (common.ProcessModeRegions)
  356. {
  357. SizeF relBorderWidth = new SizeF(this.BorderWidth + 1, this.BorderWidth + 1);
  358. relBorderWidth = graph.GetRelativeSize(relBorderWidth);
  359. RectangleF lineRect = RectangleF.Empty;
  360. if (horizontal)
  361. {
  362. lineRect.X = point1.X;
  363. lineRect.Y = point1.Y - relBorderWidth.Height / 2f;
  364. lineRect.Width = point2.X - point1.X;
  365. lineRect.Height = relBorderWidth.Height;
  366. }
  367. else
  368. {
  369. lineRect.X = point1.X - relBorderWidth.Width / 2f;
  370. lineRect.Y = point1.Y;
  371. lineRect.Width = relBorderWidth.Width;
  372. lineRect.Height = point2.Y - point1.Y;
  373. }
  374. common.HotRegionsList.AddHotRegion(lineRect, this.ToolTip, null, null, null, this, ChartElementType.StripLines, null);
  375. }
  376. }
  377. }
  378. // Go to the next line/strip
  379. if(this.Interval > 0)
  380. {
  381. currentPosition += ChartHelper.GetIntervalSize(currentPosition, this.Interval, this.IntervalType, axisSeries, this.IntervalOffset, offsetType, false);
  382. }
  383. } while(this.Interval > 0 && currentPosition <= this.Axis.ViewMaximum);
  384. }
  385. /// <summary>
  386. /// Draws strip line in 3d.
  387. /// </summary>
  388. /// <param name="graph">Chart graphics.</param>
  389. /// <param name="rect">Strip rectangle.</param>
  390. /// <param name="horizontal">Indicates that strip is horizontal</param>
  391. private void Draw3DStrip(ChartGraphics graph, RectangleF rect, bool horizontal )
  392. {
  393. ChartArea area = this.Axis.ChartArea;
  394. GraphicsPath path = null;
  395. DrawingOperationTypes operationType = DrawingOperationTypes.DrawElement;
  396. if( this.Axis.Common.ProcessModeRegions )
  397. {
  398. operationType |= DrawingOperationTypes.CalcElementPath;
  399. }
  400. // Draw strip on the back/front wall
  401. path = graph.Fill3DRectangle(
  402. rect,
  403. area.IsMainSceneWallOnFront() ? area.areaSceneDepth : 0f,
  404. 0,
  405. area.matrix3D,
  406. area.Area3DStyle.LightStyle,
  407. this.BackColor,
  408. this.BorderColor,
  409. this.BorderWidth,
  410. this.BorderDashStyle,
  411. operationType );
  412. if( this.Axis.Common.ProcessModeRegions )
  413. {
  414. this.Axis.Common.HotRegionsList.AddHotRegion( graph, path, false, this.ToolTip, null, null, null, this, ChartElementType.StripLines );
  415. }
  416. if(horizontal)
  417. {
  418. // Draw strip on the side wall (left or right)
  419. if(!area.IsSideSceneWallOnLeft())
  420. {
  421. rect.X = rect.Right;
  422. }
  423. rect.Width = 0f;
  424. path = graph.Fill3DRectangle(
  425. rect,
  426. 0f,
  427. area.areaSceneDepth,
  428. area.matrix3D,
  429. area.Area3DStyle.LightStyle,
  430. this.BackColor,
  431. this.BorderColor,
  432. this.BorderWidth,
  433. this.BorderDashStyle,
  434. operationType );
  435. }
  436. else if(area.IsBottomSceneWallVisible())
  437. {
  438. // Draw strip on the bottom wall (if visible)
  439. rect.Y = rect.Bottom;
  440. rect.Height = 0f;
  441. path = graph.Fill3DRectangle(
  442. rect,
  443. 0f,
  444. area.areaSceneDepth,
  445. area.matrix3D,
  446. area.Area3DStyle.LightStyle,
  447. this.BackColor,
  448. this.BorderColor,
  449. this.BorderWidth,
  450. this.BorderDashStyle,
  451. operationType );
  452. }
  453. if( this.Axis.Common.ProcessModeRegions )
  454. {
  455. this.Axis.Common.HotRegionsList.AddHotRegion( graph, path, false, this.ToolTip, null, null, null, this, ChartElementType.StripLines );
  456. }
  457. if (path != null)
  458. {
  459. path.Dispose();
  460. }
  461. }
  462. /// <summary>
  463. /// Draw strip/line title text
  464. /// </summary>
  465. /// <param name="graph">Chart graphics object.</param>
  466. /// <param name="point1">First line point.</param>
  467. /// <param name="point2">Second line point.</param>
  468. private void PaintTitle(ChartGraphics graph, PointF point1, PointF point2)
  469. {
  470. if(this.Text.Length > 0)
  471. {
  472. // Define a rectangle to draw the title
  473. RectangleF rect = RectangleF.Empty;
  474. rect.X = point1.X;
  475. rect.Y = point1.Y;
  476. rect.Height = point2.Y - rect.Y;
  477. rect.Width = point2.X - rect.X;
  478. // Paint title using a rect
  479. PaintTitle(graph, rect);
  480. }
  481. }
  482. /// <summary>
  483. /// Draw strip/line title text
  484. /// </summary>
  485. /// <param name="graph">Chart graphics object.</param>
  486. /// <param name="rect">Rectangle to draw in.</param>
  487. private void PaintTitle(ChartGraphics graph, RectangleF rect)
  488. {
  489. if(this.Text.Length > 0)
  490. {
  491. // Get title text
  492. string titleText = this.Text;
  493. // Prepare string format
  494. using (StringFormat format = new StringFormat())
  495. {
  496. format.Alignment = this.TextAlignment;
  497. if (graph.IsRightToLeft)
  498. {
  499. if (format.Alignment == StringAlignment.Far)
  500. {
  501. format.Alignment = StringAlignment.Near;
  502. }
  503. else if (format.Alignment == StringAlignment.Near)
  504. {
  505. format.Alignment = StringAlignment.Far;
  506. }
  507. }
  508. format.LineAlignment = this.TextLineAlignment;
  509. // Adjust default title angle for horizontal lines
  510. int angle = 0;
  511. switch (this.TextOrientation)
  512. {
  513. case (TextOrientation.Rotated90):
  514. angle = 90;
  515. break;
  516. case (TextOrientation.Rotated270):
  517. angle = 270;
  518. break;
  519. case (TextOrientation.Auto):
  520. if (this.Axis.AxisPosition == AxisPosition.Bottom || this.Axis.AxisPosition == AxisPosition.Top)
  521. {
  522. angle = 270;
  523. }
  524. break;
  525. }
  526. // Set vertical text for horizontal lines
  527. if (angle == 90)
  528. {
  529. format.FormatFlags = StringFormatFlags.DirectionVertical;
  530. angle = 0;
  531. }
  532. else if (angle == 270)
  533. {
  534. format.FormatFlags = StringFormatFlags.DirectionVertical;
  535. angle = 180;
  536. }
  537. // Measure string size
  538. SizeF size = graph.MeasureStringRel(titleText.Replace("\\n", "\n"), this.Font, new SizeF(100, 100), format, this.GetTextOrientation());
  539. // Adjust text size
  540. float zPositon = 0f;
  541. if (this.Axis.ChartArea.Area3DStyle.Enable3D)
  542. {
  543. // Get projection coordinates
  544. Point3D[] textSizeProjection = new Point3D[3];
  545. zPositon = this.Axis.ChartArea.IsMainSceneWallOnFront() ? this.Axis.ChartArea.areaSceneDepth : 0f;
  546. textSizeProjection[0] = new Point3D(0f, 0f, zPositon);
  547. textSizeProjection[1] = new Point3D(size.Width, 0f, zPositon);
  548. textSizeProjection[2] = new Point3D(0f, size.Height, zPositon);
  549. // Transform coordinates of text size
  550. this.Axis.ChartArea.matrix3D.TransformPoints(textSizeProjection);
  551. // Adjust text size
  552. int index = this.Axis.ChartArea.IsMainSceneWallOnFront() ? 0 : 1;
  553. size.Width *= size.Width / (textSizeProjection[index].X - textSizeProjection[(index == 0) ? 1 : 0].X);
  554. size.Height *= size.Height / (textSizeProjection[2].Y - textSizeProjection[0].Y);
  555. }
  556. // Get relative size of the border width
  557. SizeF sizeBorder = graph.GetRelativeSize(new SizeF(this.BorderWidth, this.BorderWidth));
  558. // Find the center of rotation
  559. PointF rotationCenter = PointF.Empty;
  560. if (format.Alignment == StringAlignment.Near)
  561. { // Near
  562. rotationCenter.X = rect.X + size.Width / 2 + sizeBorder.Width;
  563. }
  564. else if (format.Alignment == StringAlignment.Far)
  565. { // Far
  566. rotationCenter.X = rect.Right - size.Width / 2 - sizeBorder.Width;
  567. }
  568. else
  569. { // Center
  570. rotationCenter.X = (rect.Left + rect.Right) / 2;
  571. }
  572. if (format.LineAlignment == StringAlignment.Near)
  573. { // Near
  574. rotationCenter.Y = rect.Top + size.Height / 2 + sizeBorder.Height;
  575. }
  576. else if (format.LineAlignment == StringAlignment.Far)
  577. { // Far
  578. rotationCenter.Y = rect.Bottom - size.Height / 2 - sizeBorder.Height;
  579. }
  580. else
  581. { // Center
  582. rotationCenter.Y = (rect.Bottom + rect.Top) / 2;
  583. }
  584. // Reset string alignment to center point
  585. format.Alignment = StringAlignment.Center;
  586. format.LineAlignment = StringAlignment.Center;
  587. if (this.Axis.ChartArea.Area3DStyle.Enable3D)
  588. {
  589. // Get projection coordinates
  590. Point3D[] rotationCenterProjection = new Point3D[2];
  591. rotationCenterProjection[0] = new Point3D(rotationCenter.X, rotationCenter.Y, zPositon);
  592. if (format.FormatFlags == StringFormatFlags.DirectionVertical)
  593. {
  594. rotationCenterProjection[1] = new Point3D(rotationCenter.X, rotationCenter.Y - 20f, zPositon);
  595. }
  596. else
  597. {
  598. rotationCenterProjection[1] = new Point3D(rotationCenter.X - 20f, rotationCenter.Y, zPositon);
  599. }
  600. // Transform coordinates of text rotation point
  601. this.Axis.ChartArea.matrix3D.TransformPoints(rotationCenterProjection);
  602. // Adjust rotation point
  603. rotationCenter = rotationCenterProjection[0].PointF;
  604. // Adjust angle of the text
  605. if (angle == 0 || angle == 180 || angle == 90 || angle == 270)
  606. {
  607. if (format.FormatFlags == StringFormatFlags.DirectionVertical)
  608. {
  609. angle += 90;
  610. }
  611. // Convert coordinates to absolute
  612. rotationCenterProjection[0].PointF = graph.GetAbsolutePoint(rotationCenterProjection[0].PointF);
  613. rotationCenterProjection[1].PointF = graph.GetAbsolutePoint(rotationCenterProjection[1].PointF);
  614. // Calcuate axis angle
  615. float angleXAxis = (float)Math.Atan(
  616. (rotationCenterProjection[1].Y - rotationCenterProjection[0].Y) /
  617. (rotationCenterProjection[1].X - rotationCenterProjection[0].X));
  618. angleXAxis = (float)Math.Round(angleXAxis * 180f / (float)Math.PI);
  619. angle += (int)angleXAxis;
  620. }
  621. }
  622. // Draw string
  623. using (Brush brush = new SolidBrush(this.ForeColor))
  624. {
  625. graph.DrawStringRel(
  626. titleText.Replace("\\n", "\n"),
  627. this.Font,
  628. brush,
  629. rotationCenter,
  630. format,
  631. angle,
  632. this.GetTextOrientation());
  633. }
  634. }
  635. }
  636. }
  637. #endregion
  638. #region Strip line properties
  639. /// <summary>
  640. /// Gets or sets the text orientation.
  641. /// </summary>
  642. [
  643. SRCategory("CategoryAttributeAppearance"),
  644. Bindable(true),
  645. DefaultValue(TextOrientation.Auto),
  646. SRDescription("DescriptionAttribute_TextOrientation"),
  647. NotifyParentPropertyAttribute(true)
  648. ]
  649. public TextOrientation TextOrientation
  650. {
  651. get
  652. {
  653. return this._textOrientation;
  654. }
  655. set
  656. {
  657. this._textOrientation = value;
  658. this.Invalidate();
  659. CallOnModifing();
  660. }
  661. }
  662. /// <summary>
  663. /// Gets or sets the strip or line starting position offset.
  664. /// </summary>
  665. [
  666. SRCategory("CategoryAttributeData"),
  667. Bindable(true),
  668. DefaultValue(0.0),
  669. SRDescription("DescriptionAttributeStripLine_IntervalOffset"),
  670. TypeConverter(typeof(AxisLabelDateValueConverter))
  671. ]
  672. public double IntervalOffset
  673. {
  674. get
  675. {
  676. return _intervalOffset;
  677. }
  678. set
  679. {
  680. _intervalOffset = value;
  681. this.Invalidate();
  682. CallOnModifing();
  683. }
  684. }
  685. /// <summary>
  686. /// Gets or sets the unit of measurement of the strip or line offset.
  687. /// </summary>
  688. [
  689. SRCategory("CategoryAttributeData"),
  690. Bindable(true),
  691. DefaultValue(DateTimeIntervalType.Auto),
  692. SRDescription("DescriptionAttributeStripLine_IntervalOffsetType"),
  693. RefreshPropertiesAttribute(RefreshProperties.All)
  694. ]
  695. public DateTimeIntervalType IntervalOffsetType
  696. {
  697. get
  698. {
  699. return intervalOffsetType;
  700. }
  701. set
  702. {
  703. intervalOffsetType = (value != DateTimeIntervalType.NotSet) ? value : DateTimeIntervalType.Auto;
  704. this.Invalidate();
  705. CallOnModifing();
  706. }
  707. }
  708. /// <summary>
  709. /// Gets or sets the strip or line step size.
  710. /// </summary>
  711. [
  712. SRCategory("CategoryAttributeData"),
  713. Bindable(true),
  714. DefaultValue(0.0),
  715. RefreshPropertiesAttribute(RefreshProperties.All),
  716. SRDescription("DescriptionAttributeStripLine_Interval")
  717. ]
  718. public double Interval
  719. {
  720. get
  721. {
  722. return _interval;
  723. }
  724. set
  725. {
  726. _interval = value;
  727. this.Invalidate();
  728. CallOnModifing();
  729. }
  730. }
  731. /// <summary>
  732. /// Gets or sets the unit of measurement of the strip or line step.
  733. /// </summary>
  734. [
  735. SRCategory("CategoryAttributeData"),
  736. Bindable(true),
  737. DefaultValue(DateTimeIntervalType.Auto),
  738. SRDescription("DescriptionAttributeStripLine_IntervalType"),
  739. RefreshPropertiesAttribute(RefreshProperties.All)
  740. ]
  741. public DateTimeIntervalType IntervalType
  742. {
  743. get
  744. {
  745. return _intervalType;
  746. }
  747. set
  748. {
  749. _intervalType = (value != DateTimeIntervalType.NotSet) ? value : DateTimeIntervalType.Auto;
  750. this.Invalidate();
  751. CallOnModifing();
  752. }
  753. }
  754. /// <summary>
  755. /// Gets or sets the strip width.
  756. /// </summary>
  757. [
  758. SRCategory("CategoryAttributeData"),
  759. Bindable(true),
  760. DefaultValue(0.0),
  761. SRDescription("DescriptionAttributeStripLine_StripWidth")
  762. ]
  763. public double StripWidth
  764. {
  765. get
  766. {
  767. return _stripWidth;
  768. }
  769. set
  770. {
  771. if(value < 0)
  772. {
  773. throw (new ArgumentException(SR.ExceptionStripLineWidthIsNegative, "value"));
  774. }
  775. _stripWidth = value;
  776. this.Invalidate();
  777. CallOnModifing();
  778. }
  779. }
  780. /// <summary>
  781. /// Gets or sets the unit of measurement of the strip width.
  782. /// </summary>
  783. [
  784. SRCategory("CategoryAttributeData"),
  785. Bindable(true),
  786. DefaultValue(DateTimeIntervalType.Auto),
  787. SRDescription("DescriptionAttributeStripLine_StripWidthType"),
  788. RefreshPropertiesAttribute(RefreshProperties.All)
  789. ]
  790. public DateTimeIntervalType StripWidthType
  791. {
  792. get
  793. {
  794. return _stripWidthType;
  795. }
  796. set
  797. {
  798. _stripWidthType = (value != DateTimeIntervalType.NotSet) ? value : DateTimeIntervalType.Auto;
  799. this.Invalidate();
  800. CallOnModifing();
  801. }
  802. }
  803. /// <summary>
  804. /// Gets or sets the background color.
  805. /// </summary>
  806. [
  807. SRCategory("CategoryAttributeAppearance"),
  808. Bindable(true),
  809. DefaultValue(typeof(Color), ""),
  810. SRDescription("DescriptionAttributeBackColor"),
  811. TypeConverter(typeof(ColorConverter)),
  812. #if DESIGNER
  813. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  814. #endif
  815. ]
  816. public Color BackColor
  817. {
  818. get
  819. {
  820. return _backColor;
  821. }
  822. set
  823. {
  824. _backColor = value;
  825. this.Invalidate();
  826. CallOnModifing();
  827. }
  828. }
  829. /// <summary>
  830. /// Gets or sets the border color.
  831. /// </summary>
  832. [
  833. SRCategory("CategoryAttributeAppearance"),
  834. Bindable(true),
  835. DefaultValue(typeof(Color), ""),
  836. SRDescription("DescriptionAttributeBorderColor"),
  837. TypeConverter(typeof(ColorConverter)),
  838. #if DESIGNER
  839. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  840. #endif
  841. ]
  842. public Color BorderColor
  843. {
  844. get
  845. {
  846. return _borderColor;
  847. }
  848. set
  849. {
  850. _borderColor = value;
  851. this.Invalidate();
  852. CallOnModifing();
  853. }
  854. }
  855. /// <summary>
  856. /// Gets or sets the border style.
  857. /// </summary>
  858. [
  859. SRCategory("CategoryAttributeAppearance"),
  860. Bindable(true),
  861. DefaultValue(ChartDashStyle.Solid),
  862. SRDescription("DescriptionAttributeBorderDashStyle")
  863. ]
  864. public ChartDashStyle BorderDashStyle
  865. {
  866. get
  867. {
  868. return _borderDashStyle;
  869. }
  870. set
  871. {
  872. _borderDashStyle = value;
  873. this.Invalidate();
  874. CallOnModifing();
  875. }
  876. }
  877. /// <summary>
  878. /// Gets or sets the border width.
  879. /// </summary>
  880. [
  881. SRCategory("CategoryAttributeAppearance"),
  882. Bindable(true),
  883. DefaultValue(1),
  884. SRDescription("DescriptionAttributeBorderWidth")
  885. ]
  886. public int BorderWidth
  887. {
  888. get
  889. {
  890. return _borderWidth;
  891. }
  892. set
  893. {
  894. _borderWidth = value;
  895. this.Invalidate();
  896. CallOnModifing();
  897. }
  898. }
  899. /// <summary>
  900. /// Gets or sets the background image.
  901. /// </summary>
  902. [
  903. SRCategory("CategoryAttributeAppearance"),
  904. Bindable(true),
  905. DefaultValue(""),
  906. SRDescription("DescriptionAttributeBackImage"),
  907. #if DESIGNER
  908. Editor(typeof(ImageValueEditor), typeof(UITypeEditor)),
  909. #endif
  910. NotifyParentPropertyAttribute(true)
  911. ]
  912. public string BackImage
  913. {
  914. get
  915. {
  916. return _backImage;
  917. }
  918. set
  919. {
  920. _backImage = value;
  921. this.Invalidate();
  922. CallOnModifing();
  923. }
  924. }
  925. /// <summary>
  926. /// Gets or sets the background image drawing mode.
  927. /// </summary>
  928. [
  929. SRCategory("CategoryAttributeAppearance"),
  930. Bindable(true),
  931. DefaultValue(ChartImageWrapMode.Tile),
  932. NotifyParentPropertyAttribute(true),
  933. SRDescription("DescriptionAttributeImageWrapMode")
  934. ]
  935. public ChartImageWrapMode BackImageWrapMode
  936. {
  937. get
  938. {
  939. return _backImageWrapMode;
  940. }
  941. set
  942. {
  943. _backImageWrapMode = value;
  944. this.Invalidate();
  945. CallOnModifing();
  946. }
  947. }
  948. /// <summary>
  949. /// Gets or sets a color which will be replaced with a transparent color while drawing the background image.
  950. /// </summary>
  951. [
  952. SRCategory("CategoryAttributeAppearance"),
  953. Bindable(true),
  954. DefaultValue(typeof(Color), ""),
  955. NotifyParentPropertyAttribute(true),
  956. SRDescription("DescriptionAttributeImageTransparentColor"),
  957. TypeConverter(typeof(ColorConverter)),
  958. #if DESIGNER
  959. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  960. #endif
  961. ]
  962. public Color BackImageTransparentColor
  963. {
  964. get
  965. {
  966. return _backImageTransparentColor;
  967. }
  968. set
  969. {
  970. _backImageTransparentColor = value;
  971. this.Invalidate();
  972. CallOnModifing();
  973. }
  974. }
  975. /// <summary>
  976. /// Gets or sets the background image alignment used by unscale drawing mode.
  977. /// </summary>
  978. [
  979. SRCategory("CategoryAttributeAppearance"),
  980. Bindable(true),
  981. DefaultValue(ChartImageAlignmentStyle.TopLeft),
  982. NotifyParentPropertyAttribute(true),
  983. SRDescription("DescriptionAttributeBackImageAlign")
  984. ]
  985. public ChartImageAlignmentStyle BackImageAlignment
  986. {
  987. get
  988. {
  989. return _backImageAlignment;
  990. }
  991. set
  992. {
  993. _backImageAlignment = value;
  994. this.Invalidate();
  995. CallOnModifing();
  996. }
  997. }
  998. /// <summary>
  999. /// Gets or sets the background gradient style.
  1000. /// <seealso cref="BackSecondaryColor"/>
  1001. /// <seealso cref="BackColor"/>
  1002. /// <seealso cref="BackHatchStyle"/>
  1003. /// </summary>
  1004. /// <value>
  1005. /// A <see cref="GradientStyle"/> value used for the background.
  1006. /// </value>
  1007. /// <remarks>
  1008. /// Two colors are used to draw the gradient, <see cref="BackColor"/> and <see cref="BackSecondaryColor"/>.
  1009. /// </remarks>
  1010. [
  1011. SRCategory("CategoryAttributeAppearance"),
  1012. Bindable(true),
  1013. DefaultValue(GradientStyle.None),
  1014. SRDescription("DescriptionAttributeBackGradientStyle"),
  1015. #if DESIGNER
  1016. Editor(typeof(GradientEditor), typeof(UITypeEditor))
  1017. #endif
  1018. ]
  1019. public GradientStyle BackGradientStyle
  1020. {
  1021. get
  1022. {
  1023. return _backGradientStyle;
  1024. }
  1025. set
  1026. {
  1027. _backGradientStyle = value;
  1028. this.Invalidate();
  1029. CallOnModifing();
  1030. }
  1031. }
  1032. /// <summary>
  1033. /// Gets or sets the secondary background color.
  1034. /// <seealso cref="BackColor"/>
  1035. /// <seealso cref="BackHatchStyle"/>
  1036. /// <seealso cref="BackGradientStyle"/>
  1037. /// </summary>
  1038. /// <value>
  1039. /// A <see cref="Color"/> value used for the secondary color of a background with
  1040. /// hatching or gradient fill.
  1041. /// </value>
  1042. /// <remarks>
  1043. /// This color is used with <see cref="BackColor"/> when <see cref="BackHatchStyle"/> or
  1044. /// <see cref="BackGradientStyle"/> are used.
  1045. /// </remarks>
  1046. [
  1047. SRCategory("CategoryAttributeAppearance"),
  1048. Bindable(true),
  1049. DefaultValue(typeof(Color), ""),
  1050. SRDescription("DescriptionAttributeBackSecondaryColor"),
  1051. TypeConverter(typeof(ColorConverter)),
  1052. #if DESIGNER
  1053. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  1054. #endif
  1055. ]
  1056. public Color BackSecondaryColor
  1057. {
  1058. get
  1059. {
  1060. return _backSecondaryColor;
  1061. }
  1062. set
  1063. {
  1064. _backSecondaryColor = value;
  1065. this.Invalidate();
  1066. CallOnModifing();
  1067. }
  1068. }
  1069. /// <summary>
  1070. /// Gets or sets the background hatch style.
  1071. /// <seealso cref="BackSecondaryColor"/>
  1072. /// <seealso cref="BackColor"/>
  1073. /// <seealso cref="BackGradientStyle"/>
  1074. /// </summary>
  1075. /// <value>
  1076. /// A <see cref="ChartHatchStyle"/> value used for the background.
  1077. /// </value>
  1078. /// <remarks>
  1079. /// Two colors are used to draw the hatching, <see cref="BackColor"/> and <see cref="BackSecondaryColor"/>.
  1080. /// </remarks>
  1081. [
  1082. SRCategory("CategoryAttributeAppearance"),
  1083. Bindable(true),
  1084. DefaultValue(ChartHatchStyle.None),
  1085. SRDescription("DescriptionAttributeBackHatchStyle"),
  1086. #if DESIGNER
  1087. Editor(typeof(HatchStyleEditor), typeof(UITypeEditor))
  1088. #endif
  1089. ]
  1090. public ChartHatchStyle BackHatchStyle
  1091. {
  1092. get
  1093. {
  1094. return _backHatchStyle;
  1095. }
  1096. set
  1097. {
  1098. _backHatchStyle = value;
  1099. this.Invalidate();
  1100. CallOnModifing();
  1101. }
  1102. }
  1103. /// <summary>
  1104. /// Gets or sets the name of the strip line.
  1105. /// </summary>
  1106. [
  1107. SRCategory("CategoryAttributeAppearance"),
  1108. Bindable(false),
  1109. Browsable(false),
  1110. DefaultValue("StripLine"),
  1111. SRDescription("DescriptionAttributeStripLine_Name"),
  1112. DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
  1113. SerializationVisibilityAttribute(SerializationVisibility.Hidden)
  1114. ]
  1115. public string Name
  1116. {
  1117. get
  1118. {
  1119. return "StripLine";
  1120. }
  1121. }
  1122. /// <summary>
  1123. /// Gets or sets the title text of the strip line.
  1124. /// </summary>
  1125. [
  1126. SRCategory("CategoryAttributeTitle"),
  1127. Bindable(true),
  1128. DefaultValue(""),
  1129. SRDescription("DescriptionAttributeStripLine_Title"),
  1130. NotifyParentPropertyAttribute(true)
  1131. ]
  1132. public string Text
  1133. {
  1134. get
  1135. {
  1136. return _text;
  1137. }
  1138. set
  1139. {
  1140. _text = value;
  1141. this.Invalidate();
  1142. CallOnModifing();
  1143. }
  1144. }
  1145. /// <summary>
  1146. /// Gets or sets the fore color of the strip line.
  1147. /// </summary>
  1148. [
  1149. SRCategory("CategoryAttributeTitle"),
  1150. Bindable(true),
  1151. DefaultValue(typeof(Color), "Black"),
  1152. SRDescription("DescriptionAttributeStripLine_TitleColor"),
  1153. NotifyParentPropertyAttribute(true),
  1154. TypeConverter(typeof(ColorConverter)),
  1155. #if DESIGNER
  1156. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  1157. #endif
  1158. ]
  1159. public Color ForeColor
  1160. {
  1161. get
  1162. {
  1163. return _foreColor;
  1164. }
  1165. set
  1166. {
  1167. _foreColor = value;
  1168. this.Invalidate();
  1169. CallOnModifing();
  1170. }
  1171. }
  1172. /// <summary>
  1173. /// Gets or sets the text alignment of the strip line.
  1174. /// </summary>
  1175. [
  1176. SRCategory("CategoryAttributeTitle"),
  1177. Bindable(true),
  1178. DefaultValue(typeof(StringAlignment), "Far"),
  1179. SRDescription("DescriptionAttributeStripLine_TitleAlignment"),
  1180. NotifyParentPropertyAttribute(true)
  1181. ]
  1182. public StringAlignment TextAlignment
  1183. {
  1184. get
  1185. {
  1186. return _textAlignment;
  1187. }
  1188. set
  1189. {
  1190. _textAlignment = value;
  1191. this.Invalidate();
  1192. CallOnModifing();
  1193. }
  1194. }
  1195. /// <summary>
  1196. /// Gets or sets the text line alignment of the strip line.
  1197. /// </summary>
  1198. [
  1199. SRCategory("CategoryAttributeTitle"),
  1200. Bindable(true),
  1201. DefaultValue(typeof(StringAlignment), "Near"),
  1202. SRDescription("DescriptionAttributeStripLine_TitleLineAlignment"),
  1203. NotifyParentPropertyAttribute(true)
  1204. ]
  1205. public StringAlignment TextLineAlignment
  1206. {
  1207. get
  1208. {
  1209. return _textLineAlignment;
  1210. }
  1211. set
  1212. {
  1213. _textLineAlignment = value;
  1214. this.Invalidate();
  1215. CallOnModifing();
  1216. }
  1217. }
  1218. /// <summary>
  1219. /// Gets or sets the title font.
  1220. /// </summary>
  1221. [
  1222. SRCategory("CategoryAttributeTitle"),
  1223. Bindable(true),
  1224. DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"),
  1225. SRDescription("DescriptionAttributeTitleFont"),
  1226. NotifyParentPropertyAttribute(true)
  1227. ]
  1228. public Font Font
  1229. {
  1230. get
  1231. {
  1232. return _font;
  1233. }
  1234. set
  1235. {
  1236. _font = value;
  1237. this.Invalidate();
  1238. CallOnModifing();
  1239. }
  1240. }
  1241. /// <summary>
  1242. /// Gets or sets the tooltip.
  1243. /// </summary>
  1244. [
  1245. SRCategory("CategoryAttributeMapArea"),
  1246. Bindable(true),
  1247. SRDescription("DescriptionAttributeToolTip"),
  1248. DefaultValue("")
  1249. ]
  1250. public string ToolTip
  1251. {
  1252. set
  1253. {
  1254. this.Invalidate();
  1255. _toolTip = value;
  1256. CallOnModifing();
  1257. }
  1258. get
  1259. {
  1260. return _toolTip;
  1261. }
  1262. }
  1263. #endregion
  1264. #region Invalidation methods
  1265. /// <summary>
  1266. /// Invalidate chart area
  1267. /// </summary>
  1268. private new void Invalidate()
  1269. {
  1270. if(this.Axis != null)
  1271. {
  1272. Axis.Invalidate();
  1273. }
  1274. }
  1275. #endregion
  1276. #region IDisposable Members
  1277. /// <summary>
  1278. /// Releases unmanaged and - optionally - managed resources
  1279. /// </summary>
  1280. /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
  1281. protected override void Dispose(bool disposing)
  1282. {
  1283. if (disposing)
  1284. {
  1285. if (_fontCache != null)
  1286. {
  1287. _fontCache.Dispose();
  1288. _fontCache = null;
  1289. }
  1290. }
  1291. base.Dispose(disposing);
  1292. }
  1293. #endregion
  1294. }
  1295. }