Title.cs 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056
  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: Titles can be added to the chart by simply including
  6. // those titles into the Titles collection, which is
  7. // found in the root Chart object. The Title object
  8. // incorporates several properties that can be used to
  9. // position, dock, and control the appearance of any
  10. // Title. Title positioning can be explicitly set, or
  11. // you can specify that your title be docked. The
  12. // charting control gives you full control over all of
  13. // the appearance properties of your Titles, so you have
  14. // the ability to set specific properties for such things
  15. // as fonts, or colors, and even text effects.
  16. // :
  17. // NOTE: In early versions of the Chart control only 1 title was
  18. // exposed through the Title, TitleFont and TitleFontColor properties
  19. // in the root chart object. Due to the customer requests, support for
  20. // unlimited number of titles was added through the TitleCollection
  21. // exposed as a Titles property of the root chart object. Old
  22. // properties were deprecated and marked as non-browsable.
  23. //
  24. using System;
  25. using System.ComponentModel;
  26. using System.Diagnostics.CodeAnalysis;
  27. using System.Drawing;
  28. using System.Drawing.Design;
  29. using System.Drawing.Drawing2D;
  30. using System.Globalization;
  31. using FastReport.DataVisualization.Charting.Utilities;
  32. namespace FastReport.DataVisualization.Charting
  33. {
  34. #region Title enumerations
  35. /// <summary>
  36. /// An enumeration of chart element docking styles.
  37. /// </summary>
  38. public enum Docking
  39. {
  40. /// <summary>
  41. /// Docked to the top.
  42. /// </summary>
  43. Top,
  44. /// <summary>
  45. /// Docked to the right.
  46. /// </summary>
  47. Right,
  48. /// <summary>
  49. /// Docked to the bottom.
  50. /// </summary>
  51. Bottom,
  52. /// <summary>
  53. /// Docked to the left.
  54. /// </summary>
  55. Left,
  56. };
  57. /// <summary>
  58. /// Text drawing styles.
  59. /// </summary>
  60. public enum TextStyle
  61. {
  62. /// <summary>
  63. /// Default text drawing style.
  64. /// </summary>
  65. Default,
  66. /// <summary>
  67. /// Shadow text.
  68. /// </summary>
  69. Shadow,
  70. /// <summary>
  71. /// Emboss text.
  72. /// </summary>
  73. Emboss,
  74. /// <summary>
  75. /// Embed text.
  76. /// </summary>
  77. Embed,
  78. /// <summary>
  79. /// Frame text.
  80. /// </summary>
  81. Frame
  82. }
  83. /// <summary>
  84. /// An enumeration of chart text orientation.
  85. /// </summary>
  86. public enum TextOrientation
  87. {
  88. /// <summary>
  89. /// Orientation is automatically determined based on the type of the
  90. /// chart element it is used in.
  91. /// </summary>
  92. Auto,
  93. /// <summary>
  94. /// Horizontal text.
  95. /// </summary>
  96. Horizontal,
  97. /// <summary>
  98. /// Text rotated 90 degrees and oriented from top to bottom.
  99. /// </summary>
  100. Rotated90,
  101. /// <summary>
  102. /// Text rotated 270 degrees and oriented from bottom to top.
  103. /// </summary>
  104. Rotated270,
  105. /// <summary>
  106. /// Text characters are not rotated and position one below the other.
  107. /// </summary>
  108. Stacked
  109. }
  110. #endregion
  111. /// <summary>
  112. /// The Title class provides properties which define content, visual
  113. /// appearance and position of the single chart title. It also
  114. /// contains methods responsible for calculating title position,
  115. /// drawing and hit testing.
  116. /// </summary>
  117. [
  118. SRDescription("DescriptionAttributeTitle5"),
  119. ]
  120. public class Title : ChartNamedElement, IDisposable
  121. {
  122. #region Fields
  123. // Spacing between title text and the border in pixels
  124. internal int titleBorderSpacing = 4;
  125. //***********************************************************
  126. //** Private data members, which store properties values
  127. //***********************************************************
  128. // Title text
  129. private string _text = String.Empty;
  130. // Title drawing style
  131. private TextStyle _style = TextStyle.Default;
  132. // Title position
  133. private ElementPosition _position = null;
  134. // Background properties
  135. private bool _visible = true;
  136. private Color _backColor = Color.Empty;
  137. private ChartHatchStyle _backHatchStyle = ChartHatchStyle.None;
  138. private string _backImage = "";
  139. private ChartImageWrapMode _backImageWrapMode = ChartImageWrapMode.Tile;
  140. private Color _backImageTransparentColor = Color.Empty;
  141. private ChartImageAlignmentStyle _backImageAlignment = ChartImageAlignmentStyle.TopLeft;
  142. private GradientStyle _backGradientStyle = GradientStyle.None;
  143. private Color _backSecondaryColor = Color.Empty;
  144. private int _shadowOffset = 0;
  145. private Color _shadowColor = Color.FromArgb(128, 0, 0, 0);
  146. // Border properties
  147. private Color _borderColor = Color.Empty;
  148. private int _borderWidth = 1;
  149. private ChartDashStyle _borderDashStyle = ChartDashStyle.Solid;
  150. // Font properties
  151. private FontCache _fontCache = new FontCache();
  152. private Font _font;
  153. private Color _foreColor = Color.Black;
  154. // Docking and Alignment properties
  155. private ContentAlignment _alignment = ContentAlignment.MiddleCenter;
  156. private Docking _docking = Docking.Top;
  157. private string _dockedToChartArea = Constants.NotSetValue;
  158. private bool _isDockedInsideChartArea = true;
  159. private int _dockingOffset = 0;
  160. // Interactive properties
  161. private string _toolTip = String.Empty;
  162. // Default text orientation
  163. private TextOrientation _textOrientation = TextOrientation.Auto;
  164. #endregion
  165. #region Constructors and Initialization
  166. /// <summary>
  167. /// Title constructor.
  168. /// </summary>
  169. public Title()
  170. {
  171. Initialize(string.Empty, Docking.Top, null, Color.Black);
  172. }
  173. /// <summary>
  174. /// Public constructor.
  175. /// </summary>
  176. /// <param name="text">Title text.</param>
  177. public Title(string text)
  178. {
  179. Initialize(text, Docking.Top, null, Color.Black);
  180. }
  181. /// <summary>
  182. /// Title constructor.
  183. /// </summary>
  184. /// <param name="text">Title text.</param>
  185. /// <param name="docking">Title docking.</param>
  186. public Title(string text, Docking docking)
  187. {
  188. Initialize(text, docking, null, Color.Black);
  189. }
  190. /// <summary>
  191. /// Title constructor.
  192. /// </summary>
  193. /// <param name="text">Title text.</param>
  194. /// <param name="docking">Title docking.</param>
  195. /// <param name="font">Title font.</param>
  196. /// <param name="color">Title color.</param>
  197. public Title(string text, Docking docking, Font font, Color color)
  198. {
  199. Initialize(text, docking, font, color);
  200. }
  201. /// <summary>
  202. /// Initialize title object.
  203. /// </summary>
  204. /// <param name="text">Title text.</param>
  205. /// <param name="docking">Title docking.</param>
  206. /// <param name="font">Title font.</param>
  207. /// <param name="color">Title color.</param>
  208. private void Initialize(string text, Docking docking, Font font, Color color)
  209. {
  210. // Initialize fields
  211. this._position = new ElementPosition(this);
  212. this._font = _fontCache.DefaultFont;
  213. this._text = text;
  214. this._docking = docking;
  215. this._foreColor = color;
  216. if(font != null)
  217. {
  218. this._font = font;
  219. }
  220. }
  221. #endregion
  222. #region Properties
  223. /// <summary>
  224. /// Gets or sets the unique name of a ChartArea object.
  225. /// </summary>
  226. [
  227. SRCategory("CategoryAttributeMisc"),
  228. Bindable(true),
  229. SRDescription("DescriptionAttributeTitle_Name"),
  230. NotifyParentPropertyAttribute(true),
  231. ]
  232. public override string Name
  233. {
  234. get
  235. {
  236. return base.Name;
  237. }
  238. set
  239. {
  240. base.Name = value;
  241. CallOnModifing();
  242. }
  243. }
  244. /// <summary>
  245. /// Gets or sets the text orientation.
  246. /// </summary>
  247. [
  248. SRCategory("CategoryAttributeAppearance"),
  249. Bindable(true),
  250. DefaultValue(TextOrientation.Auto),
  251. SRDescription("DescriptionAttribute_TextOrientation"),
  252. NotifyParentPropertyAttribute(true)
  253. ]
  254. public TextOrientation TextOrientation
  255. {
  256. get
  257. {
  258. return this._textOrientation;
  259. }
  260. set
  261. {
  262. this._textOrientation = value;
  263. this.Invalidate(true);
  264. CallOnModifing();
  265. }
  266. }
  267. /// <summary>
  268. /// Gets or sets a flag that specifies whether the title is visible.
  269. /// </summary>
  270. /// <value>
  271. /// <b>True</b> if the title is visible; <b>false</b> otherwise.
  272. /// </value>
  273. [
  274. SRCategory("CategoryAttributeAppearance"),
  275. DefaultValue(true),
  276. SRDescription("DescriptionAttributeTitle_Visible"),
  277. ParenthesizePropertyNameAttribute(true),
  278. ]
  279. virtual public bool Visible
  280. {
  281. get
  282. {
  283. return _visible;
  284. }
  285. set
  286. {
  287. _visible = value;
  288. this.Invalidate(false);
  289. CallOnModifing();
  290. }
  291. }
  292. /// <summary>
  293. /// Gets or sets the chart area name which the title is docked to inside or outside.
  294. /// </summary>
  295. [
  296. SRCategory("CategoryAttributeDocking"),
  297. Bindable(true),
  298. DefaultValue(Constants.NotSetValue),
  299. SRDescription("DescriptionAttributeTitle_DockToChartArea"),
  300. TypeConverter(typeof(LegendAreaNameConverter)),
  301. NotifyParentPropertyAttribute(true)
  302. ]
  303. public string DockedToChartArea
  304. {
  305. get
  306. {
  307. return _dockedToChartArea;
  308. }
  309. set
  310. {
  311. if(value != _dockedToChartArea)
  312. {
  313. if(value.Length == 0)
  314. {
  315. _dockedToChartArea = Constants.NotSetValue;
  316. }
  317. else
  318. {
  319. if (Chart != null && Chart.ChartAreas != null)
  320. {
  321. Chart.ChartAreas.VerifyNameReference(value);
  322. }
  323. _dockedToChartArea = value;
  324. }
  325. this.Invalidate(false);
  326. CallOnModifing();
  327. }
  328. }
  329. }
  330. /// <summary>
  331. /// Gets or sets a property which indicates whether the title is docked inside chart area.
  332. /// DockedToChartArea property must be set first.
  333. /// </summary>
  334. [
  335. SRCategory("CategoryAttributeDocking"),
  336. Bindable(true),
  337. DefaultValue(true),
  338. SRDescription("DescriptionAttributeTitle_DockInsideChartArea"),
  339. NotifyParentPropertyAttribute(true)
  340. ]
  341. public bool IsDockedInsideChartArea
  342. {
  343. get
  344. {
  345. return _isDockedInsideChartArea;
  346. }
  347. set
  348. {
  349. if(value != _isDockedInsideChartArea)
  350. {
  351. _isDockedInsideChartArea = value;
  352. this.Invalidate(false);
  353. CallOnModifing();
  354. }
  355. }
  356. }
  357. /// <summary>
  358. /// Gets or sets the positive or negative offset of the docked title position.
  359. /// </summary>
  360. [
  361. SRCategory("CategoryAttributeDocking"),
  362. Bindable(true),
  363. DefaultValue(0),
  364. SRDescription("DescriptionAttributeTitle_DockOffset"),
  365. NotifyParentPropertyAttribute(true)
  366. ]
  367. public int DockingOffset
  368. {
  369. get
  370. {
  371. return _dockingOffset;
  372. }
  373. set
  374. {
  375. if(value != _dockingOffset)
  376. {
  377. if (value < -100 || value > 100)
  378. {
  379. throw (new ArgumentOutOfRangeException("value", SR.ExceptionValueMustBeInRange("DockingOffset", (-100).ToString(CultureInfo.CurrentCulture), (100).ToString(CultureInfo.CurrentCulture))));
  380. }
  381. _dockingOffset = value;
  382. this.Invalidate(false);
  383. CallOnModifing();
  384. }
  385. }
  386. }
  387. /// <summary>
  388. /// Gets or sets the position of the title.
  389. /// </summary>
  390. [
  391. SRCategory("CategoryAttributeAppearance"),
  392. Bindable(true),
  393. SRDescription("DescriptionAttributeTitle_Position"),
  394. DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
  395. NotifyParentPropertyAttribute(true),
  396. TypeConverter(typeof(ElementPositionConverter)),
  397. SerializationVisibilityAttribute(SerializationVisibility.Element)
  398. ]
  399. public ElementPosition Position
  400. {
  401. get
  402. {
  403. // Serialize only position values if Auto set to false
  404. if (Chart != null && Chart.serializationStatus == SerializationStatus.Saving)
  405. {
  406. if(_position.Auto)
  407. {
  408. return new ElementPosition();
  409. }
  410. else
  411. {
  412. ElementPosition newPosition = new ElementPosition();
  413. newPosition.Auto = false;
  414. newPosition.SetPositionNoAuto(_position.X, _position.Y, _position.Width, _position.Height);
  415. return newPosition;
  416. }
  417. }
  418. return _position;
  419. }
  420. set
  421. {
  422. _position = value;
  423. _position.Parent = this;
  424. this.Invalidate(false);
  425. CallOnModifing();
  426. }
  427. }
  428. /// <summary>
  429. /// Determoines if this position should be serialized.
  430. /// </summary>
  431. /// <returns></returns>
  432. internal bool ShouldSerializePosition()
  433. {
  434. return !this.Position.Auto;
  435. }
  436. /// <summary>
  437. /// Gets or sets the text of the title.
  438. /// </summary>
  439. [
  440. SRCategory("CategoryAttributeAppearance"),
  441. Bindable(true),
  442. DefaultValue(""),
  443. SRDescription("DescriptionAttributeTitle_Text"),
  444. NotifyParentPropertyAttribute(true),
  445. ParenthesizePropertyNameAttribute(true)
  446. ]
  447. public string Text
  448. {
  449. get
  450. {
  451. return _text;
  452. }
  453. set
  454. {
  455. _text = (value == null) ? string.Empty : value;
  456. this.Invalidate(false);
  457. CallOnModifing();
  458. }
  459. }
  460. /// <summary>
  461. /// Title drawing style.
  462. /// </summary>
  463. [
  464. SRCategory("CategoryAttributeAppearance"),
  465. Bindable(true),
  466. DefaultValue(TextStyle.Default),
  467. SRDescription("DescriptionAttributeTextStyle"),
  468. NotifyParentPropertyAttribute(true)
  469. ]
  470. public TextStyle TextStyle
  471. {
  472. get
  473. {
  474. return _style;
  475. }
  476. set
  477. {
  478. _style = value;
  479. this.Invalidate(true);
  480. CallOnModifing();
  481. }
  482. }
  483. /// <summary>
  484. /// Gets or sets the background color of the title.
  485. /// </summary>
  486. [
  487. SRCategory("CategoryAttributeAppearance"),
  488. Bindable(true),
  489. DefaultValue(typeof(Color), ""),
  490. SRDescription("DescriptionAttributeBackColor"),
  491. NotifyParentPropertyAttribute(true),
  492. TypeConverter(typeof(ColorConverter)),
  493. #if DESIGNER
  494. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  495. #endif
  496. ]
  497. public Color BackColor
  498. {
  499. get
  500. {
  501. return _backColor;
  502. }
  503. set
  504. {
  505. _backColor = value;
  506. this.Invalidate(true);
  507. CallOnModifing();
  508. }
  509. }
  510. /// <summary>
  511. /// Gets or sets the border color of the title.
  512. /// </summary>
  513. [
  514. SRCategory("CategoryAttributeAppearance"),
  515. Bindable(true),
  516. DefaultValue(typeof(Color), ""),
  517. SRDescription("DescriptionAttributeBorderColor"),
  518. NotifyParentPropertyAttribute(true),
  519. TypeConverter(typeof(ColorConverter)),
  520. #if DESIGNER
  521. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  522. #endif
  523. ]
  524. public Color BorderColor
  525. {
  526. get
  527. {
  528. return _borderColor;
  529. }
  530. set
  531. {
  532. _borderColor = value;
  533. this.Invalidate(true);
  534. }
  535. }
  536. /// <summary>
  537. /// Gets or sets the border style of the title.
  538. /// </summary>
  539. [
  540. SRCategory("CategoryAttributeAppearance"),
  541. Bindable(true),
  542. DefaultValue(ChartDashStyle.Solid),
  543. SRDescription("DescriptionAttributeBorderDashStyle"),
  544. NotifyParentPropertyAttribute(true),
  545. ]
  546. public ChartDashStyle BorderDashStyle
  547. {
  548. get
  549. {
  550. return _borderDashStyle;
  551. }
  552. set
  553. {
  554. _borderDashStyle = value;
  555. this.Invalidate(true);
  556. CallOnModifing();
  557. }
  558. }
  559. /// <summary>
  560. /// Gets or sets the border width of the title.
  561. /// </summary>
  562. [
  563. SRCategory("CategoryAttributeAppearance"),
  564. Bindable(true),
  565. DefaultValue(1),
  566. SRDescription("DescriptionAttributeBorderWidth"),
  567. NotifyParentPropertyAttribute(true),
  568. ]
  569. public int BorderWidth
  570. {
  571. get
  572. {
  573. return _borderWidth;
  574. }
  575. set
  576. {
  577. if(value < 0)
  578. {
  579. throw (new ArgumentOutOfRangeException("value", SR.ExceptionTitleBorderWidthIsNegative));
  580. }
  581. _borderWidth = value;
  582. this.Invalidate(false);
  583. CallOnModifing();
  584. }
  585. }
  586. /// <summary>
  587. /// Gets or sets the background image.
  588. /// </summary>
  589. [
  590. SRCategory("CategoryAttributeAppearance"),
  591. Bindable(true),
  592. DefaultValue(""),
  593. SRDescription("DescriptionAttributeBackImage"),
  594. #if DESIGNER
  595. Editor(typeof(ImageValueEditor), typeof(UITypeEditor)),
  596. #endif
  597. NotifyParentPropertyAttribute(true),
  598. ]
  599. public string BackImage
  600. {
  601. get
  602. {
  603. return _backImage;
  604. }
  605. set
  606. {
  607. _backImage = value;
  608. this.Invalidate(true);
  609. CallOnModifing();
  610. }
  611. }
  612. /// <summary>
  613. /// Gets or sets the background image drawing mode.
  614. /// </summary>
  615. [
  616. SRCategory("CategoryAttributeAppearance"),
  617. Bindable(true),
  618. DefaultValue(ChartImageWrapMode.Tile),
  619. NotifyParentPropertyAttribute(true),
  620. SRDescription("DescriptionAttributeImageWrapMode"),
  621. ]
  622. public ChartImageWrapMode BackImageWrapMode
  623. {
  624. get
  625. {
  626. return _backImageWrapMode;
  627. }
  628. set
  629. {
  630. _backImageWrapMode = value;
  631. this.Invalidate(true);
  632. CallOnModifing();
  633. }
  634. }
  635. /// <summary>
  636. /// Gets or sets a color which will be replaced with a transparent color while drawing the background image.
  637. /// </summary>
  638. [
  639. SRCategory("CategoryAttributeAppearance"),
  640. Bindable(true),
  641. DefaultValue(typeof(Color), ""),
  642. NotifyParentPropertyAttribute(true),
  643. SRDescription("DescriptionAttributeImageTransparentColor"),
  644. TypeConverter(typeof(ColorConverter)),
  645. #if DESIGNER
  646. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  647. #endif
  648. ]
  649. public Color BackImageTransparentColor
  650. {
  651. get
  652. {
  653. return _backImageTransparentColor;
  654. }
  655. set
  656. {
  657. _backImageTransparentColor = value;
  658. this.Invalidate(true);
  659. CallOnModifing();
  660. }
  661. }
  662. /// <summary>
  663. /// Gets or sets the background image alignment used by unscale drawing mode.
  664. /// </summary>
  665. [
  666. SRCategory("CategoryAttributeAppearance"),
  667. Bindable(true),
  668. DefaultValue(ChartImageAlignmentStyle.TopLeft),
  669. NotifyParentPropertyAttribute(true),
  670. SRDescription("DescriptionAttributeBackImageAlign"),
  671. ]
  672. public ChartImageAlignmentStyle BackImageAlignment
  673. {
  674. get
  675. {
  676. return _backImageAlignment;
  677. }
  678. set
  679. {
  680. _backImageAlignment = value;
  681. this.Invalidate(true);
  682. }
  683. }
  684. /// <summary>
  685. /// Gets or sets the background gradient style.
  686. /// <seealso cref="BackSecondaryColor"/>
  687. /// <seealso cref="BackColor"/>
  688. /// <seealso cref="BackHatchStyle"/>
  689. /// </summary>
  690. /// <value>
  691. /// A <see cref="GradientStyle"/> value used for the background.
  692. /// </value>
  693. /// <remarks>
  694. /// Two colors are used to draw the gradient, <see cref="BackColor"/> and <see cref="BackSecondaryColor"/>.
  695. /// </remarks>
  696. [
  697. SRCategory("CategoryAttributeAppearance"),
  698. Bindable(true),
  699. DefaultValue(GradientStyle.None),
  700. NotifyParentPropertyAttribute(true),
  701. SRDescription("DescriptionAttributeBackGradientStyle"),
  702. #if DESIGNER
  703. Editor(typeof(GradientEditor), typeof(UITypeEditor))
  704. #endif
  705. ]
  706. public GradientStyle BackGradientStyle
  707. {
  708. get
  709. {
  710. return _backGradientStyle;
  711. }
  712. set
  713. {
  714. _backGradientStyle = value;
  715. this.Invalidate(true);
  716. CallOnModifing();
  717. }
  718. }
  719. /// <summary>
  720. /// Gets or sets the secondary background color.
  721. /// <seealso cref="BackColor"/>
  722. /// <seealso cref="BackHatchStyle"/>
  723. /// <seealso cref="BackGradientStyle"/>
  724. /// </summary>
  725. /// <value>
  726. /// A <see cref="Color"/> value used for the secondary color of a background with
  727. /// hatching or gradient fill.
  728. /// </value>
  729. /// <remarks>
  730. /// This color is used with <see cref="BackColor"/> when <see cref="BackHatchStyle"/> or
  731. /// <see cref="BackGradientStyle"/> are used.
  732. /// </remarks>
  733. [
  734. SRCategory("CategoryAttributeAppearance"),
  735. Bindable(true),
  736. DefaultValue(typeof(Color), ""),
  737. NotifyParentPropertyAttribute(true),
  738. SRDescription("DescriptionAttributeBackSecondaryColor"),
  739. TypeConverter(typeof(ColorConverter)),
  740. #if DESIGNER
  741. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  742. #endif
  743. ]
  744. public Color BackSecondaryColor
  745. {
  746. get
  747. {
  748. return _backSecondaryColor;
  749. }
  750. set
  751. {
  752. _backSecondaryColor = value;
  753. this.Invalidate(true);
  754. CallOnModifing();
  755. }
  756. }
  757. /// <summary>
  758. /// Gets or sets the background hatch style.
  759. /// <seealso cref="BackSecondaryColor"/>
  760. /// <seealso cref="BackColor"/>
  761. /// <seealso cref="BackGradientStyle"/>
  762. /// </summary>
  763. /// <value>
  764. /// A <see cref="ChartHatchStyle"/> value used for the background.
  765. /// </value>
  766. /// <remarks>
  767. /// Two colors are used to draw the hatching, <see cref="BackColor"/> and <see cref="BackSecondaryColor"/>.
  768. /// </remarks>
  769. [
  770. SRCategory("CategoryAttributeAppearance"),
  771. Bindable(true),
  772. DefaultValue(ChartHatchStyle.None),
  773. NotifyParentPropertyAttribute(true),
  774. SRDescription("DescriptionAttributeBackHatchStyle"),
  775. #if DESIGNER
  776. Editor(typeof(HatchStyleEditor), typeof(UITypeEditor))
  777. #endif
  778. ]
  779. public ChartHatchStyle BackHatchStyle
  780. {
  781. get
  782. {
  783. return _backHatchStyle;
  784. }
  785. set
  786. {
  787. _backHatchStyle = value;
  788. this.Invalidate(true);
  789. CallOnModifing();
  790. }
  791. }
  792. /// <summary>
  793. /// Gets or sets the title font.
  794. /// </summary>
  795. [
  796. SRCategory("CategoryAttributeAppearance"),
  797. Bindable(true),
  798. DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"),
  799. SRDescription("DescriptionAttributeTitle_Font"),
  800. NotifyParentPropertyAttribute(true),
  801. ]
  802. public Font Font
  803. {
  804. get
  805. {
  806. return _font;
  807. }
  808. set
  809. {
  810. _font = value;
  811. this.Invalidate(false);
  812. CallOnModifing();
  813. }
  814. }
  815. /// <summary>
  816. /// Gets or sets the title fore color.
  817. /// </summary>
  818. [
  819. SRCategory("CategoryAttributeAppearance"),
  820. Bindable(true),
  821. DefaultValue(typeof(Color), "Black"),
  822. SRDescription("DescriptionAttributeTitle_Color"),
  823. NotifyParentPropertyAttribute(true),
  824. TypeConverter(typeof(ColorConverter)),
  825. #if DESIGNER
  826. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  827. #endif
  828. ]
  829. public Color ForeColor
  830. {
  831. get
  832. {
  833. return _foreColor;
  834. }
  835. set
  836. {
  837. _foreColor = value;
  838. this.Invalidate(true);
  839. CallOnModifing();
  840. }
  841. }
  842. /// <summary>
  843. /// Gets or sets title alignment.
  844. /// </summary>
  845. [
  846. SRCategory("CategoryAttributeDocking"),
  847. Bindable(true),
  848. DefaultValue(ContentAlignment.MiddleCenter),
  849. SRDescription("DescriptionAttributeTitle_Alignment"),
  850. NotifyParentPropertyAttribute(true)
  851. ]
  852. public ContentAlignment Alignment
  853. {
  854. get
  855. {
  856. return _alignment;
  857. }
  858. set
  859. {
  860. _alignment = value;
  861. this.Invalidate(false);
  862. CallOnModifing();
  863. }
  864. }
  865. /// <summary>
  866. /// Gets or sets the title docking style.
  867. /// </summary>
  868. [
  869. SRCategory("CategoryAttributeDocking"),
  870. Bindable(true),
  871. DefaultValue(Docking.Top),
  872. SRDescription("DescriptionAttributeTitle_Docking"),
  873. NotifyParentPropertyAttribute(true)
  874. ]
  875. public Docking Docking
  876. {
  877. get
  878. {
  879. return _docking;
  880. }
  881. set
  882. {
  883. _docking = value;
  884. this.Invalidate(false);
  885. CallOnModifing();
  886. }
  887. }
  888. /// <summary>
  889. /// Gets or sets the title shadow offset.
  890. /// </summary>
  891. [
  892. SRCategory("CategoryAttributeAppearance"),
  893. Bindable(true),
  894. DefaultValue(0),
  895. SRDescription("DescriptionAttributeShadowOffset"),
  896. NotifyParentPropertyAttribute(true)
  897. ]
  898. public int ShadowOffset
  899. {
  900. get
  901. {
  902. return _shadowOffset;
  903. }
  904. set
  905. {
  906. _shadowOffset = value;
  907. this.Invalidate(false);
  908. CallOnModifing();
  909. }
  910. }
  911. /// <summary>
  912. /// Gets or sets the title shadow color.
  913. /// </summary>
  914. [
  915. SRCategory("CategoryAttributeAppearance"),
  916. Bindable(true),
  917. DefaultValue(typeof(Color), "128, 0, 0, 0"),
  918. SRDescription("DescriptionAttributeShadowColor"),
  919. NotifyParentPropertyAttribute(true),
  920. TypeConverter(typeof(ColorConverter)),
  921. #if DESIGNER
  922. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  923. #endif
  924. ]
  925. public Color ShadowColor
  926. {
  927. get
  928. {
  929. return _shadowColor;
  930. }
  931. set
  932. {
  933. _shadowColor = value;
  934. this.Invalidate(false);
  935. CallOnModifing();
  936. }
  937. }
  938. /// <summary>
  939. /// Gets or sets the tooltip.
  940. /// </summary>
  941. [
  942. SRCategory("CategoryAttributeToolTip"),
  943. Bindable(true),
  944. SRDescription("DescriptionAttributeToolTip"),
  945. DefaultValue("")
  946. ]
  947. public string ToolTip
  948. {
  949. set
  950. {
  951. _toolTip = value;
  952. CallOnModifing();
  953. }
  954. get
  955. {
  956. return _toolTip;
  957. }
  958. }
  959. /// <summary>
  960. /// True if title background or border is visible
  961. /// </summary>
  962. internal bool BackGroundIsVisible
  963. {
  964. get
  965. {
  966. if(!this.BackColor.IsEmpty ||
  967. this.BackImage.Length > 0 ||
  968. (!this.BorderColor.IsEmpty && this.BorderDashStyle != ChartDashStyle.NotSet) )
  969. {
  970. return true;
  971. }
  972. return false;
  973. }
  974. }
  975. #endregion
  976. #region Helper Methods
  977. /// <summary>
  978. /// Checks if chart title is drawn vertically.
  979. /// Note: From the drawing perspective stacked text orientation is not vertical.
  980. /// </summary>
  981. /// <returns>True if text is vertical.</returns>
  982. private bool IsTextVertical
  983. {
  984. get
  985. {
  986. TextOrientation currentTextOrientation = this.GetTextOrientation();
  987. return currentTextOrientation == TextOrientation.Rotated90 || currentTextOrientation == TextOrientation.Rotated270;
  988. }
  989. }
  990. /// <summary>
  991. /// Returns title text orientation. If set to Auto automatically determines the
  992. /// orientation based on title docking.
  993. /// </summary>
  994. /// <returns>Current text orientation.</returns>
  995. private TextOrientation GetTextOrientation()
  996. {
  997. if (this.TextOrientation == TextOrientation.Auto)
  998. {
  999. // When chart title is docked to the left or right we automatically
  1000. // set vertical text with different rotation angles.
  1001. if (this.Position.Auto)
  1002. {
  1003. if (this.Docking == Docking.Left)
  1004. {
  1005. return TextOrientation.Rotated270;
  1006. }
  1007. else if (this.Docking == Docking.Right)
  1008. {
  1009. return TextOrientation.Rotated90;
  1010. }
  1011. }
  1012. return TextOrientation.Horizontal;
  1013. }
  1014. return this.TextOrientation;
  1015. }
  1016. /// <summary>
  1017. /// Helper method that checks if title is visible.
  1018. /// </summary>
  1019. /// <returns>True if title is visible.</returns>
  1020. internal bool IsVisible()
  1021. {
  1022. if(this.Visible)
  1023. {
  1024. // Check if title is docked to the chart area
  1025. if(this.DockedToChartArea.Length > 0 &&
  1026. this.Chart != null)
  1027. {
  1028. if(this.Chart.ChartAreas.IndexOf(this.DockedToChartArea) >= 0)
  1029. {
  1030. // Do not show title when it is docked to invisible chart area
  1031. ChartArea area = this.Chart.ChartAreas[this.DockedToChartArea];
  1032. if(!area.Visible)
  1033. {
  1034. return false;
  1035. }
  1036. }
  1037. }
  1038. return true;
  1039. }
  1040. return false;
  1041. }
  1042. /// <summary>
  1043. /// Invalidate chart title when one of the properties is changed.
  1044. /// </summary>
  1045. /// <param name="invalidateTitleOnly">Indicates that only title area should be invalidated.</param>
  1046. [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "This parameter is used when compiling for the WinForms version of Chart")]
  1047. internal void Invalidate(bool invalidateTitleOnly)
  1048. {
  1049. if(Chart != null)
  1050. {
  1051. // Set dirty flag
  1052. Chart.dirtyFlag = true;
  1053. // Invalidate chart
  1054. if(invalidateTitleOnly)
  1055. {
  1056. // Calculate the position of the title
  1057. Rectangle invalRect = Chart.ClientRectangle;
  1058. if(this.Position.Width != 0 && this.Position.Height != 0 )
  1059. {
  1060. // Convert relative coordinates to absolute coordinates
  1061. invalRect.X = (int)(this.Position.X * (Common.ChartPicture.Width - 1) / 100F);
  1062. invalRect.Y = (int)(this.Position.Y * (Common.ChartPicture.Height - 1) / 100F);
  1063. invalRect.Width = (int)(this.Position.Width * (Common.ChartPicture.Width - 1) / 100F);
  1064. invalRect.Height = (int)(this.Position.Height * (Common.ChartPicture.Height - 1) / 100F);
  1065. // Inflate rectangle size using border size and shadow size
  1066. invalRect.Inflate(this.BorderWidth + this.ShadowOffset + 1, this.BorderWidth + this.ShadowOffset + 1);
  1067. }
  1068. // Invalidate title rectangle only
  1069. Chart.Invalidate(invalRect);
  1070. }
  1071. else
  1072. {
  1073. Invalidate();
  1074. }
  1075. }
  1076. }
  1077. #endregion
  1078. #region Painting and Selection Methods
  1079. /// <summary>
  1080. /// Paints title using chart graphics object.
  1081. /// </summary>
  1082. /// <param name="chartGraph">The graph provides drawing object to the display device. A Graphics object is associated with a specific device context.</param>
  1083. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
  1084. internal void Paint(ChartGraphics chartGraph )
  1085. {
  1086. // check if title is visible
  1087. if(!this.IsVisible())
  1088. {
  1089. return;
  1090. }
  1091. // Title text
  1092. string titleText = this.Text;
  1093. //***************************************************************
  1094. //** Calculate title relative position
  1095. //***************************************************************
  1096. RectangleF titlePosition = this.Position.ToRectangleF();
  1097. // Auto set the title position if width or height is not set for custom position
  1098. if(!this.Position.Auto && Common != null && Common.ChartPicture != null)
  1099. {
  1100. if(titlePosition.Width == 0 || titlePosition.Height == 0)
  1101. {
  1102. // Calculate text layout area
  1103. SizeF layoutArea = new SizeF(
  1104. (titlePosition.Width == 0) ? Common.ChartPicture.Width : titlePosition.Width,
  1105. (titlePosition.Height == 0) ? Common.ChartPicture.Height : titlePosition.Height);
  1106. if (this.IsTextVertical)
  1107. {
  1108. float tempValue = layoutArea.Width;
  1109. layoutArea.Width = layoutArea.Height;
  1110. layoutArea.Height = tempValue;
  1111. }
  1112. // Measure text size
  1113. layoutArea = chartGraph.GetAbsoluteSize(layoutArea);
  1114. SizeF titleSize = chartGraph.MeasureString(
  1115. "W" + titleText.Replace("\\n", "\n"),
  1116. this.Font,
  1117. layoutArea,
  1118. StringFormat.GenericDefault,
  1119. this.GetTextOrientation());
  1120. // Increase text size by 4 pixels
  1121. if(this.BackGroundIsVisible)
  1122. {
  1123. titleSize.Width += titleBorderSpacing;
  1124. titleSize.Height += titleBorderSpacing;
  1125. }
  1126. // Switch width and height for vertical text
  1127. if (this.IsTextVertical)
  1128. {
  1129. float tempValue = titleSize.Width;
  1130. titleSize.Width = titleSize.Height;
  1131. titleSize.Height = tempValue;
  1132. }
  1133. // Convert text size to relative coordinates
  1134. titleSize = chartGraph.GetRelativeSize(titleSize);
  1135. // Update custom position
  1136. if(titlePosition.Width == 0)
  1137. {
  1138. titlePosition.Width = titleSize.Width;
  1139. if(this.Alignment == ContentAlignment.BottomRight ||
  1140. this.Alignment == ContentAlignment.MiddleRight ||
  1141. this.Alignment == ContentAlignment.TopRight)
  1142. {
  1143. titlePosition.X = titlePosition.X - titlePosition.Width;
  1144. }
  1145. else if(this.Alignment == ContentAlignment.BottomCenter ||
  1146. this.Alignment == ContentAlignment.MiddleCenter ||
  1147. this.Alignment == ContentAlignment.TopCenter)
  1148. {
  1149. titlePosition.X = titlePosition.X - titlePosition.Width/2f;
  1150. }
  1151. }
  1152. if(titlePosition.Height == 0)
  1153. {
  1154. titlePosition.Height = titleSize.Height;
  1155. if(this.Alignment == ContentAlignment.BottomRight ||
  1156. this.Alignment == ContentAlignment.BottomCenter ||
  1157. this.Alignment == ContentAlignment.BottomLeft)
  1158. {
  1159. titlePosition.Y = titlePosition.Y - titlePosition.Height;
  1160. }
  1161. else if(this.Alignment == ContentAlignment.MiddleCenter ||
  1162. this.Alignment == ContentAlignment.MiddleLeft ||
  1163. this.Alignment == ContentAlignment.MiddleRight)
  1164. {
  1165. titlePosition.Y = titlePosition.Y - titlePosition.Height/2f;
  1166. }
  1167. }
  1168. }
  1169. }
  1170. //***************************************************************
  1171. //** Convert title position to absolute coordinates
  1172. //***************************************************************
  1173. RectangleF absPosition = new RectangleF(titlePosition.Location, titlePosition.Size);
  1174. absPosition = chartGraph.GetAbsoluteRectangle(absPosition);
  1175. //***************************************************************
  1176. //** Draw title background, border and shadow
  1177. //***************************************************************
  1178. if(this.BackGroundIsVisible && Common.ProcessModePaint )
  1179. {
  1180. chartGraph.FillRectangleRel( titlePosition,
  1181. BackColor,
  1182. BackHatchStyle,
  1183. BackImage,
  1184. BackImageWrapMode,
  1185. BackImageTransparentColor,
  1186. BackImageAlignment,
  1187. BackGradientStyle,
  1188. BackSecondaryColor,
  1189. BorderColor,
  1190. BorderWidth,
  1191. BorderDashStyle,
  1192. ShadowColor,
  1193. ShadowOffset,
  1194. PenAlignment.Inset);
  1195. }
  1196. else
  1197. {
  1198. // Adjust text position to be only around the text itself
  1199. SizeF titleArea = chartGraph.GetAbsoluteSize(titlePosition.Size);
  1200. SizeF titleSize = chartGraph.MeasureString(
  1201. "W" + titleText.Replace("\\n", "\n"),
  1202. this.Font,
  1203. titleArea,
  1204. StringFormat.GenericDefault,
  1205. this.GetTextOrientation());
  1206. // Convert text size to relative coordinates
  1207. titleSize = chartGraph.GetRelativeSize(titleSize);
  1208. // Adjust position depending on alignment
  1209. RectangleF exactTitleRect = new RectangleF(
  1210. titlePosition.X,
  1211. titlePosition.Y,
  1212. titleSize.Width,
  1213. titleSize.Height);
  1214. if(this.Alignment == ContentAlignment.BottomCenter ||
  1215. this.Alignment == ContentAlignment.BottomLeft ||
  1216. this.Alignment == ContentAlignment.BottomRight )
  1217. {
  1218. exactTitleRect.Y = titlePosition.Bottom - exactTitleRect.Height;
  1219. }
  1220. else if(this.Alignment == ContentAlignment.MiddleCenter ||
  1221. this.Alignment == ContentAlignment.MiddleLeft ||
  1222. this.Alignment == ContentAlignment.MiddleRight )
  1223. {
  1224. exactTitleRect.Y = titlePosition.Y +
  1225. titlePosition.Height / 2f -
  1226. exactTitleRect.Height / 2f;
  1227. }
  1228. if(this.Alignment == ContentAlignment.BottomRight ||
  1229. this.Alignment == ContentAlignment.MiddleRight ||
  1230. this.Alignment == ContentAlignment.TopRight )
  1231. {
  1232. exactTitleRect.X = titlePosition.Right - exactTitleRect.Width;
  1233. }
  1234. else if(this.Alignment == ContentAlignment.BottomCenter ||
  1235. this.Alignment == ContentAlignment.MiddleCenter ||
  1236. this.Alignment == ContentAlignment.TopCenter )
  1237. {
  1238. exactTitleRect.X = titlePosition.X +
  1239. titlePosition.Width / 2f -
  1240. exactTitleRect.Width / 2f;
  1241. }
  1242. // NOTE: This approach for text selection can not be used with
  1243. // Flash animations because of the bug in Flash viewer. When the
  1244. // button shape is placed in the last frame the Alpha value of the
  1245. // color is ignored.
  1246. // NOTE: Feature tested again with Flash Player 7 and it seems to be
  1247. // working fine. Code below is commented to enable selection in flash
  1248. // through transparent rectangle.
  1249. // Fixes issue #4172.
  1250. bool drawRect = true;
  1251. // Draw transparent rectangle in the text position
  1252. if(drawRect)
  1253. {
  1254. chartGraph.FillRectangleRel(
  1255. exactTitleRect,
  1256. Color.FromArgb(0, Color.White),
  1257. ChartHatchStyle.None,
  1258. String.Empty,
  1259. ChartImageWrapMode.Tile,
  1260. BackImageTransparentColor,
  1261. BackImageAlignment,
  1262. GradientStyle.None,
  1263. BackSecondaryColor,
  1264. Color.Transparent,
  1265. 0,
  1266. BorderDashStyle,
  1267. Color.Transparent,
  1268. 0,
  1269. PenAlignment.Inset);
  1270. }
  1271. // End Selection mode
  1272. chartGraph.EndHotRegion( );
  1273. }
  1274. if( Common.ProcessModePaint)
  1275. Common.Chart.CallOnPrePaint(new ChartPaintEventArgs(this, chartGraph, Common, Position));
  1276. //***************************************************************
  1277. //** Add spacing between text and border
  1278. //***************************************************************
  1279. if(this.BackGroundIsVisible)
  1280. {
  1281. absPosition.Width -= this.titleBorderSpacing;
  1282. absPosition.Height -= this.titleBorderSpacing;
  1283. absPosition.X += this.titleBorderSpacing / 2f;
  1284. absPosition.Y += this.titleBorderSpacing / 2f;
  1285. }
  1286. //***************************************************************
  1287. //** Create string format
  1288. //***************************************************************
  1289. using (StringFormat format = new StringFormat())
  1290. {
  1291. format.Alignment = StringAlignment.Center;
  1292. format.LineAlignment = StringAlignment.Center;
  1293. if (this.Alignment == ContentAlignment.BottomCenter ||
  1294. this.Alignment == ContentAlignment.BottomLeft ||
  1295. this.Alignment == ContentAlignment.BottomRight)
  1296. {
  1297. format.LineAlignment = StringAlignment.Far;
  1298. }
  1299. else if (this.Alignment == ContentAlignment.TopCenter ||
  1300. this.Alignment == ContentAlignment.TopLeft ||
  1301. this.Alignment == ContentAlignment.TopRight)
  1302. {
  1303. format.LineAlignment = StringAlignment.Near;
  1304. }
  1305. if (this.Alignment == ContentAlignment.BottomLeft ||
  1306. this.Alignment == ContentAlignment.MiddleLeft ||
  1307. this.Alignment == ContentAlignment.TopLeft)
  1308. {
  1309. format.Alignment = StringAlignment.Near;
  1310. }
  1311. else if (this.Alignment == ContentAlignment.BottomRight ||
  1312. this.Alignment == ContentAlignment.MiddleRight ||
  1313. this.Alignment == ContentAlignment.TopRight)
  1314. {
  1315. format.Alignment = StringAlignment.Far;
  1316. }
  1317. //***************************************************************
  1318. //** Draw text shadow for the default style when background is not drawn anf ShadowOffset is not null
  1319. //***************************************************************
  1320. Color textShadowColor = ChartGraphics.GetGradientColor(this.ForeColor, Color.Black, 0.8);
  1321. int textShadowOffset = 1;
  1322. TextStyle textStyle = this.TextStyle;
  1323. if ((textStyle == TextStyle.Default || textStyle == TextStyle.Shadow) &&
  1324. !this.BackGroundIsVisible &&
  1325. ShadowOffset != 0)
  1326. {
  1327. // Draw shadowed text
  1328. textStyle = TextStyle.Shadow;
  1329. textShadowColor = ShadowColor;
  1330. textShadowOffset = ShadowOffset;
  1331. }
  1332. if (textStyle == TextStyle.Shadow)
  1333. {
  1334. textShadowColor = (textShadowColor.A != 255) ? textShadowColor : Color.FromArgb(textShadowColor.A / 2, textShadowColor);
  1335. }
  1336. //***************************************************************
  1337. //** Replace new line characters
  1338. //***************************************************************
  1339. titleText = titleText.Replace("\\n", "\n");
  1340. //***************************************************************
  1341. //** Define text angle depending on the docking
  1342. //***************************************************************
  1343. Matrix oldTransform = null;
  1344. if (this.IsTextVertical)
  1345. {
  1346. if (this.GetTextOrientation() == TextOrientation.Rotated270)
  1347. {
  1348. // IMPORTANT !
  1349. // Right to Left flag has to be used because of bug with .net with multi line vertical text. As soon as .net bug is fixed this flag HAS TO be removed. Bug number 1870.
  1350. format.FormatFlags |= StringFormatFlags.DirectionVertical | StringFormatFlags.DirectionRightToLeft;
  1351. // Save old graphics transformation
  1352. oldTransform = chartGraph.Transform.Clone();
  1353. // Rotate tile 180 degrees at center
  1354. PointF center = PointF.Empty;
  1355. center.X = absPosition.X + absPosition.Width / 2F;
  1356. center.Y = absPosition.Y + absPosition.Height / 2F;
  1357. // Create and set new transformation matrix
  1358. Matrix newMatrix = chartGraph.Transform.Clone();
  1359. newMatrix.RotateAt(180, center);
  1360. chartGraph.Transform = newMatrix;
  1361. }
  1362. else if (this.GetTextOrientation() == TextOrientation.Rotated90)
  1363. {
  1364. // IMPORTANT !
  1365. // Right to Left flag has to be used because of bug with .net with multi line vertical text. As soon as .net bug is fixed this flag HAS TO be removed. Bug number 1870.
  1366. format.FormatFlags |= StringFormatFlags.DirectionVertical | StringFormatFlags.DirectionRightToLeft;
  1367. }
  1368. }
  1369. try
  1370. {
  1371. chartGraph.IsTextClipped = !Position.Auto;
  1372. Title.DrawStringWithStyle(chartGraph, titleText, textStyle, this.Font, absPosition, this.ForeColor, textShadowColor, textShadowOffset, format, this.GetTextOrientation());
  1373. }
  1374. finally
  1375. {
  1376. chartGraph.IsTextClipped = false;
  1377. }
  1378. // Call Paint event
  1379. if (Common.ProcessModePaint)
  1380. Common.Chart.CallOnPostPaint(new ChartPaintEventArgs(this, chartGraph, Common, Position));
  1381. //***************************************************************
  1382. //** Restore old transformation
  1383. //***************************************************************
  1384. if(oldTransform != null)
  1385. {
  1386. chartGraph.Transform = oldTransform;
  1387. }
  1388. if (Common.ProcessModeRegions)
  1389. {
  1390. Common.HotRegionsList.AddHotRegion(titlePosition, this.ToolTip, null, null, null, this, ChartElementType.Title, null);
  1391. }
  1392. }
  1393. }
  1394. /// <summary>
  1395. /// Draws the string with style.
  1396. /// </summary>
  1397. /// <param name="chartGraph">The chart graph.</param>
  1398. /// <param name="titleText">The title text.</param>
  1399. /// <param name="textStyle">The text style.</param>
  1400. /// <param name="font">The font.</param>
  1401. /// <param name="absPosition">The abs position.</param>
  1402. /// <param name="foreColor">Color of the fore.</param>
  1403. /// <param name="shadowColor">Color of the shadow.</param>
  1404. /// <param name="shadowOffset">The shadow offset.</param>
  1405. /// <param name="format">The format.</param>
  1406. /// <param name="orientation">The orientation.</param>
  1407. internal static void DrawStringWithStyle(
  1408. ChartGraphics chartGraph,
  1409. string titleText,
  1410. TextStyle textStyle,
  1411. Font font,
  1412. RectangleF absPosition,
  1413. Color foreColor,
  1414. Color shadowColor,
  1415. int shadowOffset,
  1416. StringFormat format,
  1417. TextOrientation orientation
  1418. )
  1419. {
  1420. //***************************************************************
  1421. //** Draw title text
  1422. //***************************************************************
  1423. if (titleText.Length > 0)
  1424. {
  1425. if (textStyle == TextStyle.Default)
  1426. {
  1427. using (SolidBrush brush = new SolidBrush(foreColor))
  1428. {
  1429. chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation);
  1430. }
  1431. }
  1432. else if (textStyle == TextStyle.Frame)
  1433. {
  1434. using (GraphicsPath graphicsPath = new GraphicsPath())
  1435. {
  1436. graphicsPath.AddString(
  1437. titleText,
  1438. font.FontFamily,
  1439. (int)font.Style,
  1440. font.Size * 1.3f,
  1441. absPosition,
  1442. format);
  1443. graphicsPath.CloseAllFigures();
  1444. using (Pen pen = new Pen(foreColor, 1))
  1445. {
  1446. chartGraph.DrawPath(pen, graphicsPath);
  1447. }
  1448. }
  1449. }
  1450. else if (textStyle == TextStyle.Embed)
  1451. {
  1452. // Draw shadow
  1453. RectangleF shadowPosition = new RectangleF(absPosition.Location, absPosition.Size);
  1454. shadowPosition.X -= 1;
  1455. shadowPosition.Y -= 1;
  1456. using (SolidBrush brush = new SolidBrush(shadowColor))
  1457. {
  1458. chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
  1459. }
  1460. // Draw highlighting
  1461. shadowPosition.X += 2;
  1462. shadowPosition.Y += 2;
  1463. Color texthighlightColor = ChartGraphics.GetGradientColor(Color.White, foreColor, 0.3);
  1464. using (SolidBrush brush = new SolidBrush(texthighlightColor))
  1465. {
  1466. chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
  1467. }
  1468. using (SolidBrush brush = new SolidBrush(foreColor))
  1469. {
  1470. // Draw text
  1471. chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation);
  1472. }
  1473. }
  1474. else if (textStyle == TextStyle.Emboss)
  1475. {
  1476. // Draw shadow
  1477. RectangleF shadowPosition = new RectangleF(absPosition.Location, absPosition.Size);
  1478. shadowPosition.X += 1;
  1479. shadowPosition.Y += 1;
  1480. using (SolidBrush brush = new SolidBrush(shadowColor))
  1481. {
  1482. chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
  1483. }
  1484. // Draw highlighting
  1485. shadowPosition.X -= 2;
  1486. shadowPosition.Y -= 2;
  1487. Color texthighlightColor = ChartGraphics.GetGradientColor(Color.White, foreColor, 0.3);
  1488. using (SolidBrush brush = new SolidBrush(texthighlightColor))
  1489. {
  1490. chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
  1491. }
  1492. // Draw text
  1493. using (SolidBrush brush = new SolidBrush(foreColor))
  1494. {
  1495. chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation);
  1496. }
  1497. }
  1498. else if (textStyle == TextStyle.Shadow)
  1499. {
  1500. // Draw shadow
  1501. RectangleF shadowPosition = new RectangleF(absPosition.Location, absPosition.Size);
  1502. shadowPosition.X += shadowOffset;
  1503. shadowPosition.Y += shadowOffset;
  1504. using (SolidBrush brush = new SolidBrush(shadowColor))
  1505. {
  1506. chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
  1507. }
  1508. // Draw text
  1509. using (SolidBrush brush = new SolidBrush(foreColor))
  1510. {
  1511. chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation);
  1512. }
  1513. }
  1514. }
  1515. }
  1516. #endregion
  1517. #region Position Calculation Methods
  1518. /// <summary>
  1519. /// Recalculates title position.
  1520. /// </summary>
  1521. /// <param name="chartGraph">Chart graphics used.</param>
  1522. /// <param name="chartAreasRectangle">Area where the title should be docked.</param>
  1523. /// <param name="frameTitlePosition">Position of the title in the frame.</param>
  1524. /// <param name="elementSpacing">Spacing size in percentage of the area.</param>
  1525. internal void CalcTitlePosition(
  1526. ChartGraphics chartGraph,
  1527. ref RectangleF chartAreasRectangle,
  1528. ref RectangleF frameTitlePosition,
  1529. float elementSpacing)
  1530. {
  1531. // Special case for the first title docked to the top when the title frame is used
  1532. if(!frameTitlePosition.IsEmpty &&
  1533. this.Position.Auto &&
  1534. this.Docking == Docking.Top &&
  1535. this.DockedToChartArea == Constants.NotSetValue)
  1536. {
  1537. this.Position.SetPositionNoAuto(
  1538. frameTitlePosition.X + elementSpacing,
  1539. frameTitlePosition.Y,
  1540. frameTitlePosition.Width - 2f * elementSpacing,
  1541. frameTitlePosition.Height);
  1542. frameTitlePosition = RectangleF.Empty;
  1543. return;
  1544. }
  1545. // Get title size
  1546. RectangleF titlePosition = new RectangleF();
  1547. SizeF layoutArea = new SizeF(chartAreasRectangle.Width, chartAreasRectangle.Height);
  1548. // Switch width and height for vertical text
  1549. if (this.IsTextVertical)
  1550. {
  1551. float tempValue = layoutArea.Width;
  1552. layoutArea.Width = layoutArea.Height;
  1553. layoutArea.Height = tempValue;
  1554. }
  1555. // Meausure text size
  1556. layoutArea.Width -= 2f * elementSpacing;
  1557. layoutArea.Height -= 2f * elementSpacing;
  1558. layoutArea = chartGraph.GetAbsoluteSize(layoutArea);
  1559. SizeF titleSize = chartGraph.MeasureString(
  1560. "W" + this.Text.Replace("\\n", "\n"),
  1561. this.Font,
  1562. layoutArea,
  1563. StringFormat.GenericDefault,
  1564. this.GetTextOrientation());
  1565. // Increase text size by 4 pixels
  1566. if(this.BackGroundIsVisible)
  1567. {
  1568. titleSize.Width += titleBorderSpacing;
  1569. titleSize.Height += titleBorderSpacing;
  1570. }
  1571. // Switch width and height for vertical text
  1572. if (this.IsTextVertical)
  1573. {
  1574. float tempValue = titleSize.Width;
  1575. titleSize.Width = titleSize.Height;
  1576. titleSize.Height = tempValue;
  1577. }
  1578. // Convert text size to relative coordinates
  1579. titleSize = chartGraph.GetRelativeSize(titleSize);
  1580. titlePosition.Height = titleSize.Height;
  1581. titlePosition.Width = titleSize.Width;
  1582. if(float.IsNaN(titleSize.Height) || float.IsNaN(titleSize.Width))
  1583. {
  1584. return;
  1585. }
  1586. // Calculate title position
  1587. if(this.Docking == Docking.Top)
  1588. {
  1589. titlePosition.Y = chartAreasRectangle.Y + elementSpacing;
  1590. titlePosition.X = chartAreasRectangle.X + elementSpacing;
  1591. titlePosition.Width = chartAreasRectangle.Right - titlePosition.X - elementSpacing;
  1592. if(titlePosition.Width < 0)
  1593. {
  1594. titlePosition.Width = 0;
  1595. }
  1596. // Adjust position of the chart area(s)
  1597. chartAreasRectangle.Height -= titlePosition.Height + elementSpacing;
  1598. chartAreasRectangle.Y = titlePosition.Bottom;
  1599. }
  1600. else if(this.Docking == Docking.Bottom)
  1601. {
  1602. titlePosition.Y = chartAreasRectangle.Bottom - titleSize.Height - elementSpacing;
  1603. titlePosition.X = chartAreasRectangle.X + elementSpacing;
  1604. titlePosition.Width = chartAreasRectangle.Right - titlePosition.X - elementSpacing;
  1605. if(titlePosition.Width < 0)
  1606. {
  1607. titlePosition.Width = 0;
  1608. }
  1609. // Adjust position of the chart area(s)
  1610. chartAreasRectangle.Height -= titlePosition.Height + elementSpacing;
  1611. }
  1612. if(this.Docking == Docking.Left)
  1613. {
  1614. titlePosition.X = chartAreasRectangle.X + elementSpacing;
  1615. titlePosition.Y = chartAreasRectangle.Y + elementSpacing;
  1616. titlePosition.Height = chartAreasRectangle.Bottom - titlePosition.Y - elementSpacing;
  1617. if(titlePosition.Height < 0)
  1618. {
  1619. titlePosition.Height = 0;
  1620. }
  1621. // Adjust position of the chart area(s)
  1622. chartAreasRectangle.Width -= titlePosition.Width + elementSpacing;
  1623. chartAreasRectangle.X = titlePosition.Right;
  1624. }
  1625. if(this.Docking == Docking.Right)
  1626. {
  1627. titlePosition.X = chartAreasRectangle.Right - titleSize.Width - elementSpacing;
  1628. titlePosition.Y = chartAreasRectangle.Y + elementSpacing;
  1629. titlePosition.Height = chartAreasRectangle.Bottom - titlePosition.Y - elementSpacing;
  1630. if(titlePosition.Height < 0)
  1631. {
  1632. titlePosition.Height = 0;
  1633. }
  1634. // Adjust position of the chart area(s)
  1635. chartAreasRectangle.Width -= titlePosition.Width + elementSpacing;
  1636. }
  1637. // Offset calculated docking position
  1638. if(this.DockingOffset != 0)
  1639. {
  1640. if(this.Docking == Docking.Top || this.Docking == Docking.Bottom)
  1641. {
  1642. titlePosition.Y += this.DockingOffset;
  1643. }
  1644. else
  1645. {
  1646. titlePosition.X += this.DockingOffset;
  1647. }
  1648. }
  1649. this.Position.SetPositionNoAuto(titlePosition.X, titlePosition.Y, titlePosition.Width, titlePosition.Height);
  1650. }
  1651. #endregion
  1652. #region IDisposable Members
  1653. /// <summary>
  1654. /// Releases unmanaged and - optionally - managed resources
  1655. /// </summary>
  1656. /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
  1657. protected override void Dispose(bool disposing)
  1658. {
  1659. if (disposing)
  1660. {
  1661. if (_fontCache != null)
  1662. {
  1663. _fontCache.Dispose();
  1664. _fontCache = null;
  1665. }
  1666. if (_position != null)
  1667. {
  1668. _position.Dispose();
  1669. _position = null;
  1670. }
  1671. }
  1672. }
  1673. #endregion
  1674. }
  1675. /// <summary>
  1676. /// The TitleCollection class is a strongly typed collection of Title classes.
  1677. /// Indexer of this collection can take the title index (integer) or unique
  1678. /// title name (string) as a parameter.
  1679. /// </summary>
  1680. [
  1681. SRDescription("DescriptionAttributeTitles"),
  1682. ]
  1683. public class TitleCollection : ChartNamedElementCollection<Title>
  1684. {
  1685. #region Constructors
  1686. /// <summary>
  1687. /// TitleCollection constructor.
  1688. /// </summary>
  1689. /// <param name="parent">Parent chart element.</param>
  1690. internal TitleCollection(IChartElement parent)
  1691. : base(parent)
  1692. {
  1693. }
  1694. #endregion
  1695. #region Methods
  1696. /// <summary>
  1697. /// Creates a new Title with the specified name and adds it to the collection.
  1698. /// </summary>
  1699. /// <param name="name">The new chart area name.</param>
  1700. /// <returns>New title</returns>
  1701. public Title Add(string name)
  1702. {
  1703. Title title = new Title(name);
  1704. this.Add(title);
  1705. return title;
  1706. }
  1707. /// <summary>
  1708. /// Recalculates title position in the collection for titles docked outside of chart area.
  1709. /// </summary>
  1710. /// <param name="chartPicture">Chart picture object.</param>
  1711. /// <param name="chartGraph">Chart graphics used.</param>
  1712. /// <param name="area">Area the title is docked to.</param>
  1713. /// <param name="chartAreasRectangle">Area where the title should be positioned.</param>
  1714. /// <param name="elementSpacing">Spacing size in percentage of the area.</param>
  1715. internal static void CalcOutsideTitlePosition(
  1716. ChartPicture chartPicture,
  1717. ChartGraphics chartGraph,
  1718. ChartArea area,
  1719. ref RectangleF chartAreasRectangle,
  1720. float elementSpacing)
  1721. {
  1722. if(chartPicture != null)
  1723. {
  1724. // Get elemets spacing
  1725. float areaSpacing = Math.Min((chartAreasRectangle.Height/100F) * elementSpacing, (chartAreasRectangle.Width/100F) * elementSpacing);
  1726. // Loop through all titles
  1727. foreach(Title title in chartPicture.Titles)
  1728. {
  1729. // Check if title visible
  1730. if(!title.IsVisible())
  1731. {
  1732. continue;
  1733. }
  1734. // Check if all chart area names are valid
  1735. if (title.DockedToChartArea != Constants.NotSetValue && chartPicture.ChartAreas.IndexOf(title.DockedToChartArea)<0)
  1736. {
  1737. throw (new ArgumentException(SR.ExceptionChartTitleDockedChartAreaIsMissing((string)title.DockedToChartArea)));
  1738. }
  1739. // Process only titles docked to specified area
  1740. if(title.IsDockedInsideChartArea == false &&
  1741. title.DockedToChartArea == area.Name &&
  1742. title.Position.Auto)
  1743. {
  1744. // Calculate title position
  1745. RectangleF frameRect = RectangleF.Empty;
  1746. RectangleF prevChartAreasRectangle = chartAreasRectangle;
  1747. title.CalcTitlePosition(chartGraph,
  1748. ref chartAreasRectangle,
  1749. ref frameRect,
  1750. areaSpacing);
  1751. // Adjust title position
  1752. RectangleF titlePosition = title.Position.ToRectangleF();
  1753. if(title.Docking == Docking.Top)
  1754. {
  1755. titlePosition.Y -= areaSpacing;
  1756. if(!area.Position.Auto)
  1757. {
  1758. titlePosition.Y -= titlePosition.Height;
  1759. prevChartAreasRectangle.Y -= titlePosition.Height + areaSpacing;
  1760. prevChartAreasRectangle.Height += titlePosition.Height + areaSpacing;
  1761. }
  1762. }
  1763. else if(title.Docking == Docking.Bottom)
  1764. {
  1765. titlePosition.Y += areaSpacing;
  1766. if(!area.Position.Auto)
  1767. {
  1768. titlePosition.Y = prevChartAreasRectangle.Bottom + areaSpacing;
  1769. prevChartAreasRectangle.Height += titlePosition.Height +areaSpacing;
  1770. }
  1771. }
  1772. if(title.Docking == Docking.Left)
  1773. {
  1774. titlePosition.X -= areaSpacing;
  1775. if(!area.Position.Auto)
  1776. {
  1777. titlePosition.X -= titlePosition.Width;
  1778. prevChartAreasRectangle.X -= titlePosition.Width + areaSpacing;
  1779. prevChartAreasRectangle.Width += titlePosition.Width + areaSpacing;
  1780. }
  1781. }
  1782. if(title.Docking == Docking.Right)
  1783. {
  1784. titlePosition.X += areaSpacing;
  1785. if(!area.Position.Auto)
  1786. {
  1787. titlePosition.X = prevChartAreasRectangle.Right + areaSpacing;
  1788. prevChartAreasRectangle.Width += titlePosition.Width + areaSpacing;
  1789. }
  1790. }
  1791. // Set title position without changing the 'Auto' flag
  1792. title.Position.SetPositionNoAuto(titlePosition.X, titlePosition.Y, titlePosition.Width, titlePosition.Height);
  1793. // If custom position is used in the chart area reset the curent adjusted position
  1794. if (!area.Position.Auto)
  1795. {
  1796. chartAreasRectangle = prevChartAreasRectangle;
  1797. }
  1798. }
  1799. }
  1800. }
  1801. }
  1802. /// <summary>
  1803. /// Recalculates all titles position inside chart area in the collection.
  1804. /// </summary>
  1805. /// <param name="chartPicture">Chart picture object.</param>
  1806. /// <param name="chartGraph">Chart graphics used.</param>
  1807. /// <param name="elementSpacing">Spacing size in percentage of the area.</param>
  1808. internal static void CalcInsideTitlePosition(
  1809. ChartPicture chartPicture,
  1810. ChartGraphics chartGraph,
  1811. float elementSpacing)
  1812. {
  1813. if(chartPicture != null)
  1814. {
  1815. // Check if all chart area names are valid
  1816. foreach(Title title in chartPicture.Titles)
  1817. {
  1818. // Check if title visible
  1819. if(!title.IsVisible())
  1820. {
  1821. continue;
  1822. }
  1823. if (title.DockedToChartArea != Constants.NotSetValue)
  1824. {
  1825. try
  1826. {
  1827. ChartArea area = chartPicture.ChartAreas[title.DockedToChartArea];
  1828. }
  1829. catch
  1830. {
  1831. throw(new ArgumentException( SR.ExceptionChartTitleDockedChartAreaIsMissing( (string)title.DockedToChartArea ) ) );
  1832. }
  1833. }
  1834. }
  1835. // Loop through all chart areas
  1836. foreach(ChartArea area in chartPicture.ChartAreas)
  1837. {
  1838. // Check if chart area is visible
  1839. if(area.Visible)
  1840. {
  1841. // Get area position
  1842. RectangleF titlePlottingRectangle = area.PlotAreaPosition.ToRectangleF();
  1843. // Get elemets spacing
  1844. float areaSpacing = Math.Min((titlePlottingRectangle.Height/100F) * elementSpacing, (titlePlottingRectangle.Width/100F) * elementSpacing);
  1845. // Loop through all titles
  1846. foreach(Title title in chartPicture.Titles)
  1847. {
  1848. if(title.IsDockedInsideChartArea == true &&
  1849. title.DockedToChartArea == area.Name &&
  1850. title.Position.Auto)
  1851. {
  1852. // Calculate title position
  1853. RectangleF frameRect = RectangleF.Empty;
  1854. title.CalcTitlePosition(chartGraph,
  1855. ref titlePlottingRectangle,
  1856. ref frameRect,
  1857. areaSpacing);
  1858. }
  1859. }
  1860. }
  1861. }
  1862. }
  1863. }
  1864. #endregion
  1865. #region Event handlers
  1866. internal void ChartAreaNameReferenceChanged(object sender, NameReferenceChangedEventArgs e)
  1867. {
  1868. //If all the chart areas are removed and then the first one is added we don't want to dock the titles
  1869. if (e.OldElement == null)
  1870. return;
  1871. foreach (Title title in this)
  1872. if (title.DockedToChartArea == e.OldName)
  1873. title.DockedToChartArea = e.NewName;
  1874. }
  1875. #endregion
  1876. }
  1877. }