1 //-------------------------------------------------------------
2 // <copyright company=
\92Microsoft Corporation
\92>
3 // Copyright © Microsoft Corporation. All Rights Reserved.
5 //-------------------------------------------------------------
6 // @owner=alexgor, deliant
7 //=================================================================
10 // Namespace: DataVisualization.Charting
12 // Classes: TitleCollection, Title, Docking
14 // Purpose: Titles can be added to the chart by simply including
15 // those titles into the Titles collection, which is
16 // found in the root Chart object. The Title object
17 // incorporates several properties that can be used to
18 // position, dock, and control the appearance of any
19 // Title. Title positioning can be explicitly set, or
20 // you can specify that your title be docked. The
21 // charting control gives you full control over all of
22 // the appearance properties of your Titles, so you have
23 // the ability to set specific properties for such things
24 // as fonts, or colors, and even text effects.
26 // NOTE: In early versions of the Chart control only 1 title was
27 // exposed through the Title, TitleFont and TitleFontColor properties
28 // in the root chart object. Due to the customer requests, support for
29 // unlimited number of titles was added through the TitleCollection
30 // exposed as a Titles property of the root chart object. Old
31 // properties were deprecated and marked as non-browsable.
33 // Reviewed: AG - Microsoft 13, 2007
35 //===================================================================
37 #region Used namespaces
40 using System.Collections;
41 using System.Collections.Specialized;
42 using System.ComponentModel;
43 using System.ComponentModel.Design;
46 using System.Drawing.Design;
47 using System.Drawing.Drawing2D;
48 using System.Diagnostics.CodeAnalysis;
49 using System.Globalization;
52 using System.Windows.Forms.DataVisualization.Charting;
53 using System.Windows.Forms.DataVisualization.Charting.Data;
54 using System.Windows.Forms.DataVisualization.Charting.ChartTypes;
55 using System.Windows.Forms.DataVisualization.Charting.Utilities;
56 using System.Windows.Forms.DataVisualization.Charting.Borders3D;
57 using System.ComponentModel.Design.Serialization;
58 using System.Reflection;
59 using System.Windows.Forms.Design;
63 using System.Web.UI.DataVisualization.Charting;
64 using System.Web.UI.DataVisualization.Charting.Data;
65 using System.Web.UI.DataVisualization.Charting.Utilities;
72 namespace System.Windows.Forms.DataVisualization.Charting
74 namespace System.Web.UI.DataVisualization.Charting
78 #region Title enumerations
81 /// An enumeration of chart element docking styles.
86 /// Docked to the top.
91 /// Docked to the right.
96 /// Docked to the bottom.
101 /// Docked to the left.
107 /// Text drawing styles.
109 public enum TextStyle
112 /// Default text drawing style.
139 /// An enumeration of chart text orientation.
141 public enum TextOrientation
144 /// Orientation is automatically determined based on the type of the
145 /// chart element it is used in.
155 /// Text rotated 90 degrees and oriented from top to bottom.
160 /// Text rotated 270 degrees and oriented from bottom to top.
165 /// Text characters are not rotated and position one below the other.
173 /// The Title class provides properties which define content, visual
174 /// appearance and position of the single chart title. It also
175 /// contains methods responsible for calculating title position,
176 /// drawing and hit testing.
179 SRDescription("DescriptionAttributeTitle5"),
181 #if Microsoft_CONTROL
182 public class Title : ChartNamedElement, IDisposable
185 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
186 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
188 public class Title : ChartNamedElement, IDisposable, IChartMapArea
193 // Spacing between title text and the border in pixels
194 internal int titleBorderSpacing = 4;
197 //***********************************************************
198 //** Private data members, which store properties values
199 //***********************************************************
202 private string _text = String.Empty;
204 // Title drawing style
205 private TextStyle _style = TextStyle.Default;
208 private ElementPosition _position = null;
210 // Background properties
211 private bool _visible = true;
212 private Color _backColor = Color.Empty;
213 private ChartHatchStyle _backHatchStyle = ChartHatchStyle.None;
214 private string _backImage = "";
215 private ChartImageWrapMode _backImageWrapMode = ChartImageWrapMode.Tile;
216 private Color _backImageTransparentColor = Color.Empty;
217 private ChartImageAlignmentStyle _backImageAlignment = ChartImageAlignmentStyle.TopLeft;
218 private GradientStyle _backGradientStyle = GradientStyle.None;
219 private Color _backSecondaryColor = Color.Empty;
220 private int _shadowOffset = 0;
221 private Color _shadowColor = Color.FromArgb(128, 0, 0, 0);
224 private Color _borderColor = Color.Empty;
225 private int _borderWidth = 1;
226 private ChartDashStyle _borderDashStyle = ChartDashStyle.Solid;
229 private FontCache _fontCache = new FontCache();
231 private Color _foreColor = Color.Black;
233 // Docking and Alignment properties
234 private ContentAlignment _alignment = ContentAlignment.MiddleCenter;
235 private Docking _docking = Docking.Top;
236 private string _dockedToChartArea = Constants.NotSetValue;
237 private bool _isDockedInsideChartArea = true;
238 private int _dockingOffset = 0;
240 // Interactive properties
241 private string _toolTip = String.Empty;
243 #if !Microsoft_CONTROL
244 private string _url = String.Empty;
245 private string _mapAreaAttributes = String.Empty;
246 private string _postbackValue = String.Empty;
249 // Default text orientation
250 private TextOrientation _textOrientation = TextOrientation.Auto;
254 #region Constructors and Initialization
257 /// Title constructor.
261 Initialize(string.Empty, Docking.Top, null, Color.Black);
265 /// Public constructor.
267 /// <param name="text">Title text.</param>
268 public Title(string text)
270 Initialize(text, Docking.Top, null, Color.Black);
274 /// Title constructor.
276 /// <param name="text">Title text.</param>
277 /// <param name="docking">Title docking.</param>
278 public Title(string text, Docking docking)
280 Initialize(text, docking, null, Color.Black);
284 /// Title constructor.
286 /// <param name="text">Title text.</param>
287 /// <param name="docking">Title docking.</param>
288 /// <param name="font">Title font.</param>
289 /// <param name="color">Title color.</param>
290 public Title(string text, Docking docking, Font font, Color color)
292 Initialize(text, docking, font, color);
296 /// Initialize title object.
298 /// <param name="text">Title text.</param>
299 /// <param name="docking">Title docking.</param>
300 /// <param name="font">Title font.</param>
301 /// <param name="color">Title color.</param>
302 private void Initialize(string text, Docking docking, Font font, Color color)
305 this._position = new ElementPosition(this);
306 this._font = _fontCache.DefaultFont;
308 this._docking = docking;
309 this._foreColor = color;
321 /// Gets or sets the unique name of a ChartArea object.
325 SRCategory("CategoryAttributeMisc"),
327 SRDescription("DescriptionAttributeTitle_Name"),
328 NotifyParentPropertyAttribute(true),
329 #if !Microsoft_CONTROL
330 PersistenceMode(PersistenceMode.Attribute)
333 public override string Name
346 /// Gets or sets the text orientation.
349 SRCategory("CategoryAttributeAppearance"),
351 DefaultValue(TextOrientation.Auto),
352 SRDescription("DescriptionAttribute_TextOrientation"),
353 NotifyParentPropertyAttribute(true),
354 #if !Microsoft_CONTROL
355 PersistenceMode(PersistenceMode.Attribute)
358 public TextOrientation TextOrientation
362 return this._textOrientation;
366 this._textOrientation = value;
367 this.Invalidate(true);
372 /// Gets or sets a flag that specifies whether the title is visible.
375 /// <b>True</b> if the title is visible; <b>false</b> otherwise.
378 SRCategory("CategoryAttributeAppearance"),
380 SRDescription("DescriptionAttributeTitle_Visible"),
381 ParenthesizePropertyNameAttribute(true),
383 virtual public bool Visible
392 this.Invalidate(false);
397 /// Gets or sets the chart area name which the title is docked to inside or outside.
400 SRCategory("CategoryAttributeDocking"),
402 DefaultValue(Constants.NotSetValue),
403 SRDescription("DescriptionAttributeTitle_DockToChartArea"),
404 TypeConverter(typeof(LegendAreaNameConverter)),
405 NotifyParentPropertyAttribute(true),
406 #if !Microsoft_CONTROL
407 PersistenceMode(PersistenceMode.Attribute),
410 public string DockedToChartArea
414 return _dockedToChartArea;
418 if(value != _dockedToChartArea)
420 if(value.Length == 0)
422 _dockedToChartArea = Constants.NotSetValue;
426 if (Chart != null && Chart.ChartAreas != null)
428 Chart.ChartAreas.VerifyNameReference(value);
430 _dockedToChartArea = value;
432 this.Invalidate(false);
438 /// Gets or sets a property which indicates whether the title is docked inside chart area.
439 /// DockedToChartArea property must be set first.
442 SRCategory("CategoryAttributeDocking"),
445 SRDescription("DescriptionAttributeTitle_DockInsideChartArea"),
446 NotifyParentPropertyAttribute(true),
447 #if !Microsoft_CONTROL
448 PersistenceMode(PersistenceMode.Attribute),
451 public bool IsDockedInsideChartArea
455 return _isDockedInsideChartArea;
459 if(value != _isDockedInsideChartArea)
461 _isDockedInsideChartArea = value;
462 this.Invalidate(false);
468 /// Gets or sets the positive or negative offset of the docked title position.
471 SRCategory("CategoryAttributeDocking"),
474 SRDescription("DescriptionAttributeTitle_DockOffset"),
475 NotifyParentPropertyAttribute(true),
476 #if !Microsoft_CONTROL
477 PersistenceMode(PersistenceMode.Attribute),
480 public int DockingOffset
484 return _dockingOffset;
488 if(value != _dockingOffset)
490 if (value < -100 || value > 100)
492 throw (new ArgumentOutOfRangeException("value", SR.ExceptionValueMustBeInRange("DockingOffset", (-100).ToString(CultureInfo.CurrentCulture), (100).ToString(CultureInfo.CurrentCulture))));
494 _dockingOffset = value;
495 this.Invalidate(false);
502 /// Gets or sets the position of the title.
505 SRCategory("CategoryAttributeAppearance"),
507 SRDescription("DescriptionAttributeTitle_Position"),
508 #if Microsoft_CONTROL
509 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
511 PersistenceMode(PersistenceMode.InnerProperty),
513 NotifyParentPropertyAttribute(true),
514 TypeConverter(typeof(ElementPositionConverter)),
515 SerializationVisibilityAttribute(SerializationVisibility.Element)
517 public ElementPosition Position
521 // Serialize only position values if Auto set to false
522 if (Chart != null && Chart.serializationStatus == SerializationStatus.Saving)
526 return new ElementPosition();
530 ElementPosition newPosition = new ElementPosition();
531 #if Microsoft_CONTROL
532 newPosition.Auto = false;
534 newPosition.Auto = true;
536 newPosition.SetPositionNoAuto(_position.X, _position.Y, _position.Width, _position.Height);
545 _position.Parent = this;
546 this.Invalidate(false);
551 /// Determoines if this position should be serialized.
553 /// <returns></returns>
554 internal bool ShouldSerializePosition()
556 return !this.Position.Auto;
561 /// Gets or sets the text of the title.
564 SRCategory("CategoryAttributeAppearance"),
567 SRDescription("DescriptionAttributeTitle_Text"),
568 NotifyParentPropertyAttribute(true),
569 ParenthesizePropertyNameAttribute(true),
570 #if !Microsoft_CONTROL
571 PersistenceMode(PersistenceMode.Attribute)
582 _text = (value == null) ? string.Empty : value;
583 this.Invalidate(false);
589 /// Title drawing style.
592 SRCategory("CategoryAttributeAppearance"),
594 DefaultValue(TextStyle.Default),
595 SRDescription("DescriptionAttributeTextStyle"),
596 NotifyParentPropertyAttribute(true),
597 #if !Microsoft_CONTROL
598 PersistenceMode(PersistenceMode.Attribute)
601 public TextStyle TextStyle
610 this.Invalidate(true);
616 /// Gets or sets the background color of the title.
619 SRCategory("CategoryAttributeAppearance"),
621 DefaultValue(typeof(Color), ""),
622 SRDescription("DescriptionAttributeBackColor"),
623 NotifyParentPropertyAttribute(true),
624 TypeConverter(typeof(ColorConverter)),
625 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
626 #if !Microsoft_CONTROL
627 PersistenceMode(PersistenceMode.Attribute)
630 public Color BackColor
639 this.Invalidate(true);
644 /// Gets or sets the border color of the title.
647 SRCategory("CategoryAttributeAppearance"),
649 DefaultValue(typeof(Color), ""),
650 SRDescription("DescriptionAttributeBorderColor"),
651 NotifyParentPropertyAttribute(true),
652 TypeConverter(typeof(ColorConverter)),
653 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
654 #if !Microsoft_CONTROL
655 PersistenceMode(PersistenceMode.Attribute)
658 public Color BorderColor
666 _borderColor = value;
667 this.Invalidate(true);
672 /// Gets or sets the border style of the title.
675 SRCategory("CategoryAttributeAppearance"),
677 DefaultValue(ChartDashStyle.Solid),
678 SRDescription("DescriptionAttributeBorderDashStyle"),
679 NotifyParentPropertyAttribute(true),
680 #if !Microsoft_CONTROL
681 PersistenceMode(PersistenceMode.Attribute)
684 public ChartDashStyle BorderDashStyle
688 return _borderDashStyle;
692 _borderDashStyle = value;
693 this.Invalidate(true);
698 /// Gets or sets the border width of the title.
701 SRCategory("CategoryAttributeAppearance"),
704 SRDescription("DescriptionAttributeBorderWidth"),
705 NotifyParentPropertyAttribute(true),
706 #if !Microsoft_CONTROL
707 PersistenceMode(PersistenceMode.Attribute)
710 public int BorderWidth
720 throw (new ArgumentOutOfRangeException("value", SR.ExceptionTitleBorderWidthIsNegative));
722 _borderWidth = value;
723 this.Invalidate(false);
728 /// Gets or sets the background image.
731 SRCategory("CategoryAttributeAppearance"),
734 SRDescription("DescriptionAttributeBackImage"),
735 Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base),
736 #if !Microsoft_CONTROL
737 PersistenceMode(PersistenceMode.Attribute),
739 NotifyParentPropertyAttribute(true),
741 public string BackImage
750 this.Invalidate(true);
755 /// Gets or sets the background image drawing mode.
758 SRCategory("CategoryAttributeAppearance"),
760 DefaultValue(ChartImageWrapMode.Tile),
761 NotifyParentPropertyAttribute(true),
762 SRDescription("DescriptionAttributeImageWrapMode"),
763 #if !Microsoft_CONTROL
764 PersistenceMode(PersistenceMode.Attribute)
767 public ChartImageWrapMode BackImageWrapMode
771 return _backImageWrapMode;
775 _backImageWrapMode = value;
776 this.Invalidate(true);
781 /// Gets or sets a color which will be replaced with a transparent color while drawing the background image.
784 SRCategory("CategoryAttributeAppearance"),
786 DefaultValue(typeof(Color), ""),
787 NotifyParentPropertyAttribute(true),
788 SRDescription("DescriptionAttributeImageTransparentColor"),
789 TypeConverter(typeof(ColorConverter)),
790 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
791 #if !Microsoft_CONTROL
792 PersistenceMode(PersistenceMode.Attribute)
795 public Color BackImageTransparentColor
799 return _backImageTransparentColor;
803 _backImageTransparentColor = value;
804 this.Invalidate(true);
809 /// Gets or sets the background image alignment used by unscale drawing mode.
812 SRCategory("CategoryAttributeAppearance"),
814 DefaultValue(ChartImageAlignmentStyle.TopLeft),
815 NotifyParentPropertyAttribute(true),
816 SRDescription("DescriptionAttributeBackImageAlign"),
817 #if !Microsoft_CONTROL
818 PersistenceMode(PersistenceMode.Attribute)
821 public ChartImageAlignmentStyle BackImageAlignment
825 return _backImageAlignment;
829 _backImageAlignment = value;
830 this.Invalidate(true);
835 /// Gets or sets the background gradient style.
836 /// <seealso cref="BackSecondaryColor"/>
837 /// <seealso cref="BackColor"/>
838 /// <seealso cref="BackHatchStyle"/>
841 /// A <see cref="GradientStyle"/> value used for the background.
844 /// Two colors are used to draw the gradient, <see cref="BackColor"/> and <see cref="BackSecondaryColor"/>.
847 SRCategory("CategoryAttributeAppearance"),
849 DefaultValue(GradientStyle.None),
850 NotifyParentPropertyAttribute(true),
851 SRDescription("DescriptionAttributeBackGradientStyle"),
852 #if !Microsoft_CONTROL
853 PersistenceMode(PersistenceMode.Attribute),
855 Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base)
857 public GradientStyle BackGradientStyle
861 return _backGradientStyle;
865 _backGradientStyle = value;
866 this.Invalidate(true);
871 /// Gets or sets the secondary background color.
872 /// <seealso cref="BackColor"/>
873 /// <seealso cref="BackHatchStyle"/>
874 /// <seealso cref="BackGradientStyle"/>
877 /// A <see cref="Color"/> value used for the secondary color of a background with
878 /// hatching or gradient fill.
881 /// This color is used with <see cref="BackColor"/> when <see cref="BackHatchStyle"/> or
882 /// <see cref="BackGradientStyle"/> are used.
885 SRCategory("CategoryAttributeAppearance"),
887 DefaultValue(typeof(Color), ""),
888 NotifyParentPropertyAttribute(true),
889 SRDescription("DescriptionAttributeBackSecondaryColor"),
890 TypeConverter(typeof(ColorConverter)),
891 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
892 #if !Microsoft_CONTROL
893 PersistenceMode(PersistenceMode.Attribute)
896 public Color BackSecondaryColor
900 return _backSecondaryColor;
904 _backSecondaryColor = value;
905 this.Invalidate(true);
910 /// Gets or sets the background hatch style.
911 /// <seealso cref="BackSecondaryColor"/>
912 /// <seealso cref="BackColor"/>
913 /// <seealso cref="BackGradientStyle"/>
916 /// A <see cref="ChartHatchStyle"/> value used for the background.
919 /// Two colors are used to draw the hatching, <see cref="BackColor"/> and <see cref="BackSecondaryColor"/>.
922 SRCategory("CategoryAttributeAppearance"),
924 DefaultValue(ChartHatchStyle.None),
925 NotifyParentPropertyAttribute(true),
926 SRDescription("DescriptionAttributeBackHatchStyle"),
927 #if !Microsoft_CONTROL
928 PersistenceMode(PersistenceMode.Attribute),
930 Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base)
932 public ChartHatchStyle BackHatchStyle
936 return _backHatchStyle;
940 _backHatchStyle = value;
941 this.Invalidate(true);
946 /// Gets or sets the title font.
949 SRCategory("CategoryAttributeAppearance"),
951 DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"),
952 SRDescription("DescriptionAttributeTitle_Font"),
953 NotifyParentPropertyAttribute(true),
954 #if !Microsoft_CONTROL
955 PersistenceMode(PersistenceMode.Attribute)
967 this.Invalidate(false);
972 /// Gets or sets the title fore color.
975 SRCategory("CategoryAttributeAppearance"),
977 DefaultValue(typeof(Color), "Black"),
978 SRDescription("DescriptionAttributeTitle_Color"),
979 NotifyParentPropertyAttribute(true),
980 TypeConverter(typeof(ColorConverter)),
981 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
982 #if !Microsoft_CONTROL
983 PersistenceMode(PersistenceMode.Attribute)
986 public Color ForeColor
995 this.Invalidate(true);
1000 /// Gets or sets title alignment.
1003 SRCategory("CategoryAttributeDocking"),
1005 DefaultValue(ContentAlignment.MiddleCenter),
1006 SRDescription("DescriptionAttributeTitle_Alignment"),
1007 NotifyParentPropertyAttribute(true),
1008 #if !Microsoft_CONTROL
1009 PersistenceMode(PersistenceMode.Attribute)
1012 public ContentAlignment Alignment
1021 this.Invalidate(false);
1026 /// Gets or sets the title docking style.
1029 SRCategory("CategoryAttributeDocking"),
1031 DefaultValue(Docking.Top),
1032 SRDescription("DescriptionAttributeTitle_Docking"),
1033 NotifyParentPropertyAttribute(true),
1034 #if !Microsoft_CONTROL
1035 PersistenceMode(PersistenceMode.Attribute)
1038 public Docking Docking
1047 this.Invalidate(false);
1052 /// Gets or sets the title shadow offset.
1055 SRCategory("CategoryAttributeAppearance"),
1058 SRDescription("DescriptionAttributeShadowOffset"),
1059 NotifyParentPropertyAttribute(true),
1060 #if !Microsoft_CONTROL
1061 PersistenceMode(PersistenceMode.Attribute)
1064 public int ShadowOffset
1068 return _shadowOffset;
1072 _shadowOffset = value;
1073 this.Invalidate(false);
1078 /// Gets or sets the title shadow color.
1081 SRCategory("CategoryAttributeAppearance"),
1083 DefaultValue(typeof(Color), "128, 0, 0, 0"),
1084 SRDescription("DescriptionAttributeShadowColor"),
1085 NotifyParentPropertyAttribute(true),
1086 TypeConverter(typeof(ColorConverter)),
1087 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
1088 #if !Microsoft_CONTROL
1089 PersistenceMode(PersistenceMode.Attribute)
1092 public Color ShadowColor
1096 return _shadowColor;
1100 _shadowColor = value;
1101 this.Invalidate(false);
1106 /// Gets or sets the tooltip.
1109 #if !Microsoft_CONTROL
1110 SRCategory("CategoryAttributeMapArea"),
1112 SRCategory("CategoryAttributeToolTip"),
1115 SRDescription("DescriptionAttributeToolTip"),
1117 #if !Microsoft_CONTROL
1118 PersistenceMode(PersistenceMode.Attribute)
1121 public string ToolTip
1134 #if !Microsoft_CONTROL
1137 /// Gets or sets the URL target of the title.
1140 SRCategory("CategoryAttributeMapArea"),
1142 SRDescription("DescriptionAttributeUrl"),
1144 #if !Microsoft_CONTROL
1145 PersistenceMode(PersistenceMode.Attribute),
1146 Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base)
1161 /// Gets or sets the other attributes of the title map area.
1164 SRCategory("CategoryAttributeMapArea"),
1166 SRDescription("DescriptionAttributeMapAreaAttributes"),
1168 PersistenceMode(PersistenceMode.Attribute)
1170 public string MapAreaAttributes
1174 _mapAreaAttributes = value;
1178 return _mapAreaAttributes;
1183 /// Gets or sets the postback value which can be processed on a click event.
1185 /// <value>The value which is passed to a click event as an argument.</value>
1187 [SRCategory(SR.Keys.CategoryAttributeMapArea)]
1188 [SRDescription(SR.Keys.DescriptionAttributePostBackValue)]
1189 public string PostBackValue
1193 return this._postbackValue;
1197 this._postbackValue = value;
1205 /// True if title background or border is visible
1207 internal bool BackGroundIsVisible
1211 if(!this.BackColor.IsEmpty ||
1212 this.BackImage.Length > 0 ||
1213 (!this.BorderColor.IsEmpty && this.BorderDashStyle != ChartDashStyle.NotSet) )
1224 #region Helper Methods
1227 /// Checks if chart title is drawn vertically.
1228 /// Note: From the drawing perspective stacked text orientation is not vertical.
1230 /// <returns>True if text is vertical.</returns>
1231 private bool IsTextVertical
1235 TextOrientation currentTextOrientation = this.GetTextOrientation();
1236 return currentTextOrientation == TextOrientation.Rotated90 || currentTextOrientation == TextOrientation.Rotated270;
1241 /// Returns title text orientation. If set to Auto automatically determines the
1242 /// orientation based on title docking.
1244 /// <returns>Current text orientation.</returns>
1245 private TextOrientation GetTextOrientation()
1247 if (this.TextOrientation == TextOrientation.Auto)
1249 // When chart title is docked to the left or right we automatically
1250 // set vertical text with different rotation angles.
1251 if (this.Position.Auto)
1253 if (this.Docking == Docking.Left)
1255 return TextOrientation.Rotated270;
1257 else if (this.Docking == Docking.Right)
1259 return TextOrientation.Rotated90;
1262 return TextOrientation.Horizontal;
1264 return this.TextOrientation;
1268 /// Helper method that checks if title is visible.
1270 /// <returns>True if title is visible.</returns>
1271 internal bool IsVisible()
1276 // Check if title is docked to the chart area
1277 if(this.DockedToChartArea.Length > 0 &&
1280 if(this.Chart.ChartAreas.IndexOf(this.DockedToChartArea) >= 0)
1282 // Do not show title when it is docked to invisible chart area
1283 ChartArea area = this.Chart.ChartAreas[this.DockedToChartArea];
1298 /// Invalidate chart title when one of the properties is changed.
1300 /// <param name="invalidateTitleOnly">Indicates that only title area should be invalidated.</param>
1301 [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "This parameter is used when compiling for the Microsoft version of Chart")]
1302 internal void Invalidate(bool invalidateTitleOnly)
1304 #if Microsoft_CONTROL
1308 Chart.dirtyFlag = true;
1311 if(invalidateTitleOnly)
1313 // Calculate the position of the title
1314 Rectangle invalRect = Chart.ClientRectangle;
1315 if(this.Position.Width != 0 && this.Position.Height != 0 )
1317 // Convert relative coordinates to absolute coordinates
1318 invalRect.X = (int)(this.Position.X * (Common.ChartPicture.Width - 1) / 100F);
1319 invalRect.Y = (int)(this.Position.Y * (Common.ChartPicture.Height - 1) / 100F);
1320 invalRect.Width = (int)(this.Position.Width * (Common.ChartPicture.Width - 1) / 100F);
1321 invalRect.Height = (int)(this.Position.Height * (Common.ChartPicture.Height - 1) / 100F);
1323 // Inflate rectangle size using border size and shadow size
1324 invalRect.Inflate(this.BorderWidth + this.ShadowOffset + 1, this.BorderWidth + this.ShadowOffset + 1);
1327 // Invalidate title rectangle only
1328 Chart.Invalidate(invalRect);
1335 #endif // #if Microsoft_CONTROL
1340 #region Painting and Selection Methods
1343 /// Paints title using chart graphics object.
1345 /// <param name="chartGraph">The graph provides drawing object to the display device. A Graphics object is associated with a specific device context.</param>
1346 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
1347 internal void Paint(ChartGraphics chartGraph )
1349 // check if title is visible
1350 if(!this.IsVisible())
1356 string titleText = this.Text;
1358 //***************************************************************
1359 //** Calculate title relative position
1360 //***************************************************************
1361 RectangleF titlePosition = this.Position.ToRectangleF();
1363 // Auto set the title position if width or height is not set for custom position
1364 if(!this.Position.Auto && Common != null && Common.ChartPicture != null)
1366 if(titlePosition.Width == 0 || titlePosition.Height == 0)
1368 // Calculate text layout area
1369 SizeF layoutArea = new SizeF(
1370 (titlePosition.Width == 0) ? Common.ChartPicture.Width : titlePosition.Width,
1371 (titlePosition.Height == 0) ? Common.ChartPicture.Height : titlePosition.Height);
1372 if (this.IsTextVertical)
1374 float tempValue = layoutArea.Width;
1375 layoutArea.Width = layoutArea.Height;
1376 layoutArea.Height = tempValue;
1379 // Measure text size
1380 layoutArea = chartGraph.GetAbsoluteSize(layoutArea);
1381 SizeF titleSize = chartGraph.MeasureString(
1382 "W" + titleText.Replace("\\n", "\n"),
1385 StringFormat.GenericDefault,
1386 this.GetTextOrientation());
1388 // Increase text size by 4 pixels
1389 if(this.BackGroundIsVisible)
1391 titleSize.Width += titleBorderSpacing;
1392 titleSize.Height += titleBorderSpacing;
1395 // Switch width and height for vertical text
1396 if (this.IsTextVertical)
1398 float tempValue = titleSize.Width;
1399 titleSize.Width = titleSize.Height;
1400 titleSize.Height = tempValue;
1403 // Convert text size to relative coordinates
1404 titleSize = chartGraph.GetRelativeSize(titleSize);
1406 // Update custom position
1407 if(titlePosition.Width == 0)
1409 titlePosition.Width = titleSize.Width;
1410 if(this.Alignment == ContentAlignment.BottomRight ||
1411 this.Alignment == ContentAlignment.MiddleRight ||
1412 this.Alignment == ContentAlignment.TopRight)
1414 titlePosition.X = titlePosition.X - titlePosition.Width;
1416 else if(this.Alignment == ContentAlignment.BottomCenter ||
1417 this.Alignment == ContentAlignment.MiddleCenter ||
1418 this.Alignment == ContentAlignment.TopCenter)
1420 titlePosition.X = titlePosition.X - titlePosition.Width/2f;
1423 if(titlePosition.Height == 0)
1425 titlePosition.Height = titleSize.Height;
1426 if(this.Alignment == ContentAlignment.BottomRight ||
1427 this.Alignment == ContentAlignment.BottomCenter ||
1428 this.Alignment == ContentAlignment.BottomLeft)
1430 titlePosition.Y = titlePosition.Y - titlePosition.Height;
1432 else if(this.Alignment == ContentAlignment.MiddleCenter ||
1433 this.Alignment == ContentAlignment.MiddleLeft ||
1434 this.Alignment == ContentAlignment.MiddleRight)
1436 titlePosition.Y = titlePosition.Y - titlePosition.Height/2f;
1443 //***************************************************************
1444 //** Convert title position to absolute coordinates
1445 //***************************************************************
1446 RectangleF absPosition = new RectangleF(titlePosition.Location, titlePosition.Size);
1447 absPosition = chartGraph.GetAbsoluteRectangle(absPosition);
1449 //***************************************************************
1450 //** Draw title background, border and shadow
1451 //***************************************************************
1452 if(this.BackGroundIsVisible && Common.ProcessModePaint )
1454 chartGraph.FillRectangleRel( titlePosition,
1459 BackImageTransparentColor,
1468 PenAlignment.Inset);
1472 // Adjust text position to be only around the text itself
1473 SizeF titleArea = chartGraph.GetAbsoluteSize(titlePosition.Size);
1474 SizeF titleSize = chartGraph.MeasureString(
1475 "W" + titleText.Replace("\\n", "\n"),
1478 StringFormat.GenericDefault,
1479 this.GetTextOrientation());
1481 // Convert text size to relative coordinates
1482 titleSize = chartGraph.GetRelativeSize(titleSize);
1484 // Adjust position depending on alignment
1485 RectangleF exactTitleRect = new RectangleF(
1490 if(this.Alignment == ContentAlignment.BottomCenter ||
1491 this.Alignment == ContentAlignment.BottomLeft ||
1492 this.Alignment == ContentAlignment.BottomRight )
1494 exactTitleRect.Y = titlePosition.Bottom - exactTitleRect.Height;
1496 else if(this.Alignment == ContentAlignment.MiddleCenter ||
1497 this.Alignment == ContentAlignment.MiddleLeft ||
1498 this.Alignment == ContentAlignment.MiddleRight )
1500 exactTitleRect.Y = titlePosition.Y +
1501 titlePosition.Height / 2f -
1502 exactTitleRect.Height / 2f;
1505 if(this.Alignment == ContentAlignment.BottomRight ||
1506 this.Alignment == ContentAlignment.MiddleRight ||
1507 this.Alignment == ContentAlignment.TopRight )
1509 exactTitleRect.X = titlePosition.Right - exactTitleRect.Width;
1511 else if(this.Alignment == ContentAlignment.BottomCenter ||
1512 this.Alignment == ContentAlignment.MiddleCenter ||
1513 this.Alignment == ContentAlignment.TopCenter )
1515 exactTitleRect.X = titlePosition.X +
1516 titlePosition.Width / 2f -
1517 exactTitleRect.Width / 2f;
1520 // NOTE: This approach for text selection can not be used with
1521 // Flash animations because of the bug in Flash viewer. When the
1522 // button shape is placed in the last frame the Alpha value of the
1523 // color is ignored.
1525 // NOTE: Feature tested again with Flash Player 7 and it seems to be
1526 // working fine. Code below is commented to enable selection in flash
1527 // through transparent rectangle.
1528 // Fixes issue #4172.
1530 bool drawRect = true;
1532 // Draw transparent rectangle in the text position
1535 chartGraph.FillRectangleRel(
1537 Color.FromArgb(0, Color.White),
1538 ChartHatchStyle.None,
1540 ChartImageWrapMode.Tile,
1541 BackImageTransparentColor,
1550 PenAlignment.Inset);
1553 // End Selection mode
1554 chartGraph.EndHotRegion( );
1557 if( Common.ProcessModePaint)
1558 Common.Chart.CallOnPrePaint(new ChartPaintEventArgs(this, chartGraph, Common, Position));
1560 //***************************************************************
1561 //** Add spacing between text and border
1562 //***************************************************************
1563 if(this.BackGroundIsVisible)
1565 absPosition.Width -= this.titleBorderSpacing;
1566 absPosition.Height -= this.titleBorderSpacing;
1567 absPosition.X += this.titleBorderSpacing / 2f;
1568 absPosition.Y += this.titleBorderSpacing / 2f;
1571 //***************************************************************
1572 //** Create string format
1573 //***************************************************************
1574 using (StringFormat format = new StringFormat())
1576 format.Alignment = StringAlignment.Center;
1577 format.LineAlignment = StringAlignment.Center;
1579 if (this.Alignment == ContentAlignment.BottomCenter ||
1580 this.Alignment == ContentAlignment.BottomLeft ||
1581 this.Alignment == ContentAlignment.BottomRight)
1583 format.LineAlignment = StringAlignment.Far;
1585 else if (this.Alignment == ContentAlignment.TopCenter ||
1586 this.Alignment == ContentAlignment.TopLeft ||
1587 this.Alignment == ContentAlignment.TopRight)
1589 format.LineAlignment = StringAlignment.Near;
1592 if (this.Alignment == ContentAlignment.BottomLeft ||
1593 this.Alignment == ContentAlignment.MiddleLeft ||
1594 this.Alignment == ContentAlignment.TopLeft)
1596 format.Alignment = StringAlignment.Near;
1598 else if (this.Alignment == ContentAlignment.BottomRight ||
1599 this.Alignment == ContentAlignment.MiddleRight ||
1600 this.Alignment == ContentAlignment.TopRight)
1602 format.Alignment = StringAlignment.Far;
1605 //***************************************************************
1606 //** Draw text shadow for the default style when background is not drawn anf ShadowOffset is not null
1607 //***************************************************************
1608 Color textShadowColor = ChartGraphics.GetGradientColor(this.ForeColor, Color.Black, 0.8);
1609 int textShadowOffset = 1;
1610 TextStyle textStyle = this.TextStyle;
1611 if ((textStyle == TextStyle.Default || textStyle == TextStyle.Shadow) &&
1612 !this.BackGroundIsVisible &&
1615 // Draw shadowed text
1616 textStyle = TextStyle.Shadow;
1617 textShadowColor = ShadowColor;
1618 textShadowOffset = ShadowOffset;
1621 if (textStyle == TextStyle.Shadow)
1623 textShadowColor = (textShadowColor.A != 255) ? textShadowColor : Color.FromArgb(textShadowColor.A / 2, textShadowColor);
1626 //***************************************************************
1627 //** Replace new line characters
1628 //***************************************************************
1629 titleText = titleText.Replace("\\n", "\n");
1631 //***************************************************************
1632 //** Define text angle depending on the docking
1633 //***************************************************************
1634 Matrix oldTransform = null;
1635 if (this.IsTextVertical)
1637 if (this.GetTextOrientation() == TextOrientation.Rotated270)
1640 // 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.
1641 format.FormatFlags |= StringFormatFlags.DirectionVertical | StringFormatFlags.DirectionRightToLeft;
1643 // Save old graphics transformation
1644 oldTransform = chartGraph.Transform.Clone();
1646 // Rotate tile 180 degrees at center
1647 PointF center = PointF.Empty;
1649 center.X = absPosition.X + absPosition.Width / 2F;
1650 center.Y = absPosition.Y + absPosition.Height / 2F;
1652 // Create and set new transformation matrix
1653 Matrix newMatrix = chartGraph.Transform.Clone();
1654 newMatrix.RotateAt(180, center);
1655 chartGraph.Transform = newMatrix;
1657 else if (this.GetTextOrientation() == TextOrientation.Rotated90)
1660 // 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.
1661 format.FormatFlags |= StringFormatFlags.DirectionVertical | StringFormatFlags.DirectionRightToLeft;
1666 chartGraph.IsTextClipped = !Position.Auto;
1667 Title.DrawStringWithStyle(chartGraph, titleText, textStyle, this.Font, absPosition, this.ForeColor, textShadowColor, textShadowOffset, format, this.GetTextOrientation());
1671 chartGraph.IsTextClipped = false;
1674 if (Common.ProcessModePaint)
1675 Common.Chart.CallOnPostPaint(new ChartPaintEventArgs(this, chartGraph, Common, Position));
1677 //***************************************************************
1678 //** Restore old transformation
1679 //***************************************************************
1680 if(oldTransform != null)
1682 chartGraph.Transform = oldTransform;
1685 if( Common.ProcessModeRegions )
1687 #if !Microsoft_CONTROL
1688 Common.HotRegionsList.AddHotRegion( titlePosition, this.ToolTip, this.Url, this.MapAreaAttributes, this.PostBackValue, this, ChartElementType.Title, string.Empty );
1690 Common.HotRegionsList.AddHotRegion( titlePosition, this.ToolTip, null, null, null, this, ChartElementType.Title, null );
1691 #endif // !Microsoft_CONTROL
1697 /// Draws the string with style.
1699 /// <param name="chartGraph">The chart graph.</param>
1700 /// <param name="titleText">The title text.</param>
1701 /// <param name="textStyle">The text style.</param>
1702 /// <param name="font">The font.</param>
1703 /// <param name="absPosition">The abs position.</param>
1704 /// <param name="foreColor">Color of the fore.</param>
1705 /// <param name="shadowColor">Color of the shadow.</param>
1706 /// <param name="shadowOffset">The shadow offset.</param>
1707 /// <param name="format">The format.</param>
1708 /// <param name="orientation">The orientation.</param>
1709 internal static void DrawStringWithStyle(
1710 ChartGraphics chartGraph,
1712 TextStyle textStyle,
1714 RectangleF absPosition,
1718 StringFormat format,
1719 TextOrientation orientation
1722 //***************************************************************
1723 //** Draw title text
1724 //***************************************************************
1725 if (titleText.Length > 0)
1727 if (textStyle == TextStyle.Default)
1729 using (SolidBrush brush = new SolidBrush(foreColor))
1731 chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation);
1734 else if (textStyle == TextStyle.Frame)
1736 using (GraphicsPath graphicsPath = new GraphicsPath())
1738 graphicsPath.AddString(
1745 graphicsPath.CloseAllFigures();
1748 using (Pen pen = new Pen(foreColor, 1))
1750 chartGraph.DrawPath(pen, graphicsPath);
1754 else if (textStyle == TextStyle.Embed)
1757 RectangleF shadowPosition = new RectangleF(absPosition.Location, absPosition.Size);
1758 shadowPosition.X -= 1;
1759 shadowPosition.Y -= 1;
1760 using (SolidBrush brush = new SolidBrush(shadowColor))
1762 chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
1764 // Draw highlighting
1765 shadowPosition.X += 2;
1766 shadowPosition.Y += 2;
1767 Color texthighlightColor = ChartGraphics.GetGradientColor(Color.White, foreColor, 0.3);
1768 using (SolidBrush brush = new SolidBrush(texthighlightColor))
1770 chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
1772 using (SolidBrush brush = new SolidBrush(foreColor))
1775 chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation);
1778 else if (textStyle == TextStyle.Emboss)
1781 RectangleF shadowPosition = new RectangleF(absPosition.Location, absPosition.Size);
1782 shadowPosition.X += 1;
1783 shadowPosition.Y += 1;
1784 using (SolidBrush brush = new SolidBrush(shadowColor))
1786 chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
1788 // Draw highlighting
1789 shadowPosition.X -= 2;
1790 shadowPosition.Y -= 2;
1791 Color texthighlightColor = ChartGraphics.GetGradientColor(Color.White, foreColor, 0.3);
1792 using (SolidBrush brush = new SolidBrush(texthighlightColor))
1794 chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
1797 using (SolidBrush brush = new SolidBrush(foreColor))
1799 chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation);
1803 else if (textStyle == TextStyle.Shadow)
1806 RectangleF shadowPosition = new RectangleF(absPosition.Location, absPosition.Size);
1807 shadowPosition.X += shadowOffset;
1808 shadowPosition.Y += shadowOffset;
1809 using (SolidBrush brush = new SolidBrush(shadowColor))
1811 chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
1814 using (SolidBrush brush = new SolidBrush(foreColor))
1816 chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation);
1825 #region Position Calculation Methods
1828 /// Recalculates title position.
1830 /// <param name="chartGraph">Chart graphics used.</param>
1831 /// <param name="chartAreasRectangle">Area where the title should be docked.</param>
1832 /// <param name="frameTitlePosition">Position of the title in the frame.</param>
1833 /// <param name="elementSpacing">Spacing size in percentage of the area.</param>
1834 internal void CalcTitlePosition(
1835 ChartGraphics chartGraph,
1836 ref RectangleF chartAreasRectangle,
1837 ref RectangleF frameTitlePosition,
1838 float elementSpacing)
1840 // Special case for the first title docked to the top when the title frame is used
1841 if(!frameTitlePosition.IsEmpty &&
1842 this.Position.Auto &&
1843 this.Docking == Docking.Top &&
1844 this.DockedToChartArea == Constants.NotSetValue)
1846 this.Position.SetPositionNoAuto(
1847 frameTitlePosition.X + elementSpacing,
1848 frameTitlePosition.Y,
1849 frameTitlePosition.Width - 2f * elementSpacing,
1850 frameTitlePosition.Height);
1851 frameTitlePosition = RectangleF.Empty;
1856 RectangleF titlePosition = new RectangleF();
1857 SizeF layoutArea = new SizeF(chartAreasRectangle.Width, chartAreasRectangle.Height);
1859 // Switch width and height for vertical text
1860 if (this.IsTextVertical)
1862 float tempValue = layoutArea.Width;
1863 layoutArea.Width = layoutArea.Height;
1864 layoutArea.Height = tempValue;
1867 // Meausure text size
1868 layoutArea.Width -= 2f * elementSpacing;
1869 layoutArea.Height -= 2f * elementSpacing;
1870 layoutArea = chartGraph.GetAbsoluteSize(layoutArea);
1871 SizeF titleSize = chartGraph.MeasureString(
1872 "W" + this.Text.Replace("\\n", "\n"),
1875 StringFormat.GenericDefault,
1876 this.GetTextOrientation());
1878 // Increase text size by 4 pixels
1879 if(this.BackGroundIsVisible)
1881 titleSize.Width += titleBorderSpacing;
1882 titleSize.Height += titleBorderSpacing;
1885 // Switch width and height for vertical text
1886 if (this.IsTextVertical)
1888 float tempValue = titleSize.Width;
1889 titleSize.Width = titleSize.Height;
1890 titleSize.Height = tempValue;
1893 // Convert text size to relative coordinates
1894 titleSize = chartGraph.GetRelativeSize(titleSize);
1895 titlePosition.Height = titleSize.Height;
1896 titlePosition.Width = titleSize.Width;
1897 if(float.IsNaN(titleSize.Height) || float.IsNaN(titleSize.Width))
1902 // Calculate title position
1903 if(this.Docking == Docking.Top)
1905 titlePosition.Y = chartAreasRectangle.Y + elementSpacing;
1906 titlePosition.X = chartAreasRectangle.X + elementSpacing;
1907 titlePosition.Width = chartAreasRectangle.Right - titlePosition.X - elementSpacing;
1908 if(titlePosition.Width < 0)
1910 titlePosition.Width = 0;
1913 // Adjust position of the chart area(s)
1914 chartAreasRectangle.Height -= titlePosition.Height + elementSpacing;
1915 chartAreasRectangle.Y = titlePosition.Bottom;
1917 else if(this.Docking == Docking.Bottom)
1919 titlePosition.Y = chartAreasRectangle.Bottom - titleSize.Height - elementSpacing;
1920 titlePosition.X = chartAreasRectangle.X + elementSpacing;
1921 titlePosition.Width = chartAreasRectangle.Right - titlePosition.X - elementSpacing;
1922 if(titlePosition.Width < 0)
1924 titlePosition.Width = 0;
1927 // Adjust position of the chart area(s)
1928 chartAreasRectangle.Height -= titlePosition.Height + elementSpacing;
1930 if(this.Docking == Docking.Left)
1932 titlePosition.X = chartAreasRectangle.X + elementSpacing;
1933 titlePosition.Y = chartAreasRectangle.Y + elementSpacing;
1934 titlePosition.Height = chartAreasRectangle.Bottom - titlePosition.Y - elementSpacing;
1935 if(titlePosition.Height < 0)
1937 titlePosition.Height = 0;
1940 // Adjust position of the chart area(s)
1941 chartAreasRectangle.Width -= titlePosition.Width + elementSpacing;
1942 chartAreasRectangle.X = titlePosition.Right;
1944 if(this.Docking == Docking.Right)
1946 titlePosition.X = chartAreasRectangle.Right - titleSize.Width - elementSpacing;
1947 titlePosition.Y = chartAreasRectangle.Y + elementSpacing;
1948 titlePosition.Height = chartAreasRectangle.Bottom - titlePosition.Y - elementSpacing;
1949 if(titlePosition.Height < 0)
1951 titlePosition.Height = 0;
1954 // Adjust position of the chart area(s)
1955 chartAreasRectangle.Width -= titlePosition.Width + elementSpacing;
1959 // Offset calculated docking position
1960 if(this.DockingOffset != 0)
1962 if(this.Docking == Docking.Top || this.Docking == Docking.Bottom)
1964 titlePosition.Y += this.DockingOffset;
1968 titlePosition.X += this.DockingOffset;
1972 this.Position.SetPositionNoAuto(titlePosition.X, titlePosition.Y, titlePosition.Width, titlePosition.Height);
1977 #region IDisposable Members
1980 /// Releases unmanaged and - optionally - managed resources
1982 /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
1983 protected override void Dispose(bool disposing)
1987 if (_fontCache != null)
1989 _fontCache.Dispose();
1992 if (_position != null)
1994 _position.Dispose();
2005 /// The TitleCollection class is a strongly typed collection of Title classes.
2006 /// Indexer of this collection can take the title index (integer) or unique
2007 /// title name (string) as a parameter.
2010 SRDescription("DescriptionAttributeTitles"),
2013 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
2014 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
2016 public class TitleCollection : ChartNamedElementCollection<Title>
2019 #region Constructors
2022 /// TitleCollection constructor.
2024 /// <param name="parent">Parent chart element.</param>
2025 internal TitleCollection(IChartElement parent)
2035 /// Creates a new Title with the specified name and adds it to the collection.
2037 /// <param name="name">The new chart area name.</param>
2038 /// <returns>New title</returns>
2039 public Title Add(string name)
2041 Title title = new Title(name);
2048 /// Recalculates title position in the collection for titles docked outside of chart area.
2050 /// <param name="chartPicture">Chart picture object.</param>
2051 /// <param name="chartGraph">Chart graphics used.</param>
2052 /// <param name="area">Area the title is docked to.</param>
2053 /// <param name="chartAreasRectangle">Area where the title should be positioned.</param>
2054 /// <param name="elementSpacing">Spacing size in percentage of the area.</param>
2055 internal static void CalcOutsideTitlePosition(
2056 ChartPicture chartPicture,
2057 ChartGraphics chartGraph,
2059 ref RectangleF chartAreasRectangle,
2060 float elementSpacing)
2062 if(chartPicture != null)
2064 // Get elemets spacing
2065 float areaSpacing = Math.Min((chartAreasRectangle.Height/100F) * elementSpacing, (chartAreasRectangle.Width/100F) * elementSpacing);
2067 // Loop through all titles
2068 foreach(Title title in chartPicture.Titles)
2070 // Check if title visible
2071 if(!title.IsVisible())
2076 // Check if all chart area names are valid
2077 if (title.DockedToChartArea != Constants.NotSetValue && chartPicture.ChartAreas.IndexOf(title.DockedToChartArea)<0)
2079 throw (new ArgumentException(SR.ExceptionChartTitleDockedChartAreaIsMissing((string)title.DockedToChartArea)));
2082 // Process only titles docked to specified area
2083 if(title.IsDockedInsideChartArea == false &&
2084 title.DockedToChartArea == area.Name &&
2085 title.Position.Auto)
2087 // Calculate title position
2088 RectangleF frameRect = RectangleF.Empty;
2089 RectangleF prevChartAreasRectangle = chartAreasRectangle;
2090 title.CalcTitlePosition(chartGraph,
2091 ref chartAreasRectangle,
2095 // Adjust title position
2096 RectangleF titlePosition = title.Position.ToRectangleF();
2097 if(title.Docking == Docking.Top)
2099 titlePosition.Y -= areaSpacing;
2100 if(!area.Position.Auto)
2102 titlePosition.Y -= titlePosition.Height;
2103 prevChartAreasRectangle.Y -= titlePosition.Height + areaSpacing;
2104 prevChartAreasRectangle.Height += titlePosition.Height + areaSpacing;
2107 else if(title.Docking == Docking.Bottom)
2109 titlePosition.Y += areaSpacing;
2110 if(!area.Position.Auto)
2112 titlePosition.Y = prevChartAreasRectangle.Bottom + areaSpacing;
2113 prevChartAreasRectangle.Height += titlePosition.Height +areaSpacing;
2116 if(title.Docking == Docking.Left)
2118 titlePosition.X -= areaSpacing;
2119 if(!area.Position.Auto)
2121 titlePosition.X -= titlePosition.Width;
2122 prevChartAreasRectangle.X -= titlePosition.Width + areaSpacing;
2123 prevChartAreasRectangle.Width += titlePosition.Width + areaSpacing;
2126 if(title.Docking == Docking.Right)
2128 titlePosition.X += areaSpacing;
2129 if(!area.Position.Auto)
2131 titlePosition.X = prevChartAreasRectangle.Right + areaSpacing;
2132 prevChartAreasRectangle.Width += titlePosition.Width + areaSpacing;
2136 // Set title position without changing the 'Auto' flag
2137 title.Position.SetPositionNoAuto(titlePosition.X, titlePosition.Y, titlePosition.Width, titlePosition.Height);
2139 // If custom position is used in the chart area reset the curent adjusted position
2140 if (!area.Position.Auto)
2142 chartAreasRectangle = prevChartAreasRectangle;
2152 /// Recalculates all titles position inside chart area in the collection.
2154 /// <param name="chartPicture">Chart picture object.</param>
2155 /// <param name="chartGraph">Chart graphics used.</param>
2156 /// <param name="elementSpacing">Spacing size in percentage of the area.</param>
2157 internal static void CalcInsideTitlePosition(
2158 ChartPicture chartPicture,
2159 ChartGraphics chartGraph,
2160 float elementSpacing)
2162 if(chartPicture != null)
2164 // Check if all chart area names are valid
2165 foreach(Title title in chartPicture.Titles)
2167 // Check if title visible
2168 if(!title.IsVisible())
2173 if (title.DockedToChartArea != Constants.NotSetValue)
2177 ChartArea area = chartPicture.ChartAreas[title.DockedToChartArea];
2181 throw(new ArgumentException( SR.ExceptionChartTitleDockedChartAreaIsMissing( (string)title.DockedToChartArea ) ) );
2186 // Loop through all chart areas
2187 foreach(ChartArea area in chartPicture.ChartAreas)
2190 // Check if chart area is visible
2194 // Get area position
2195 RectangleF titlePlottingRectangle = area.PlotAreaPosition.ToRectangleF();
2197 // Get elemets spacing
2198 float areaSpacing = Math.Min((titlePlottingRectangle.Height/100F) * elementSpacing, (titlePlottingRectangle.Width/100F) * elementSpacing);
2200 // Loop through all titles
2201 foreach(Title title in chartPicture.Titles)
2203 if(title.IsDockedInsideChartArea == true &&
2204 title.DockedToChartArea == area.Name &&
2205 title.Position.Auto)
2207 // Calculate title position
2208 RectangleF frameRect = RectangleF.Empty;
2209 title.CalcTitlePosition(chartGraph,
2210 ref titlePlottingRectangle,
2222 #region Event handlers
2223 internal void ChartAreaNameReferenceChanged(object sender, NameReferenceChangedEventArgs e)
2225 //If all the chart areas are removed and then the first one is added we don't want to dock the titles
2226 if (e.OldElement == null)
2229 foreach (Title title in this)
2230 if (title.DockedToChartArea == e.OldName)
2231 title.DockedToChartArea = e.NewName;