1 //-------------------------------------------------------------
2 // <copyright company=�Microsoft Corporation�>
3 //   Copyright � Microsoft Corporation. All Rights Reserved.
4 // </copyright>
5 //-------------------------------------------------------------
6 // @owner=alexgor, deliant
7 //=================================================================
8 //  File:		WebCustomControl1.cs
9 //
10 //  Namespace:	System.Web.UI.DataVisualization.Charting
11 //
12 //	Classes:	Chart, TraceManager
13 //				CustomizeMapAreasEventArgs
14 //
15 //  Purpose:	Chart web control main class.
16 //
17 //	Reviewed:
18 //
19 //===================================================================
20 
21 #region Used namespaces
22 
23 using System;
24 using System.Web.UI;
25 using System.Web.UI.WebControls;
26 using System.ComponentModel;
27 using System.ComponentModel.Design;
28 using System.Drawing.Design;
29 using System.Drawing;
30 using System.Drawing.Drawing2D;
31 using System.Drawing.Imaging;
32 using System.Data;
33 using System.Web;
34 using System.Net;
35 using System.IO;
36 using System.Text;
37 using System.Reflection;
38 using System.Diagnostics.CodeAnalysis;
39 
40 using System.Collections;
41 using System.Diagnostics;
42 using System.Xml;
43 using System.Web.UI.DataVisualization.Charting;
44 using System.Globalization;
45 
46 using System.Web.UI.DataVisualization.Charting.Data;
47 using System.Web.UI.DataVisualization.Charting.Utilities;
48 using System.Web.UI.DataVisualization.Charting.ChartTypes;
49 using System.Web.UI.DataVisualization.Charting.Borders3D;
50 
51 using System.Web.UI.DataVisualization.Charting.Formulas;
52 using System.Security;
53 using System.Security.Permissions;
54 
55 
56 
57 #endregion
58 
59 namespace System.Web.UI.DataVisualization.Charting
60 {
61 
62 	#region Chart enumerations
63 
64     /// <summary>
65     /// Chart image storage mode.
66     /// </summary>
67     public enum ImageStorageMode
68     {
69 
70         /// <summary>
71         /// Images are stored using HTTP Handler.
72         /// </summary>
73         UseHttpHandler,
74 
75         /// <summary>
76         /// Images is saved in temp. file using ImageLocation specified.
77         /// </summary>
78         UseImageLocation
79     }
80 
81 	/// <summary>
82 	/// Specifies the format of the image
83 	/// </summary>
84 	public enum ChartImageFormat
85 	{
86 		/// <summary>
87 		/// Gets the Joint Photographic Experts Group (JPEG) image format.
88 		/// </summary>
89 		Jpeg,
90 
91 		/// <summary>
92 		/// Gets the W3C Portable Network Graphics (PNG) image format.
93 		/// </summary>
94         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Png")]
95         Png,
96 
97 		/// <summary>
98 		/// Gets the bitmap image format (BMP).
99 		/// </summary>
100 		Bmp,
101 
102 		/// <summary>
103 		/// Gets the Tag Image File Format (TIFF) image format.
104 		/// </summary>
105 		Tiff,
106 
107 		/// <summary>
108 		/// Gets the Graphics Interchange Format (GIF) image format.
109 		/// </summary>
110 		Gif,
111 
112         /// <summary>
113 		/// Gets the Enhanced Meta File (Emf) image format.
114 		/// </summary>
115 		Emf,
116 
117 		/// <summary>
118 		/// Gets the Enhanced Meta File (Emf+) image format.
119 		/// </summary>
120 		EmfPlus,
121 
122 		/// <summary>
123 		/// Gets the Enhanced Meta File (EmfDual) image format.
124 		/// </summary>
125 		EmfDual,
126 	}
127 
128 	/// <summary>
129 	/// Chart image rendering type
130 	/// </summary>
131  	public enum RenderType
132 	{
133         /// <summary>
134 		/// Chart image is rendered as image tag.
135 		/// </summary>
136 		ImageTag,
137 
138 		/// <summary>
139 		/// Chart image is streamed back directly.
140 		/// </summary>
141 		BinaryStreaming,
142 
143 		/// <summary>
144 		/// Chart image map is rendered.
145 		/// </summary>
146 		ImageMap
147 	}
148 
149 	#endregion
150 
151 	/// <summary>
152 	/// Summary description for enterprize chart control.
153 	/// </summary>
154 	[
155 	ToolboxData("<{0}:Chart runat=server>" +
156         "<Series><{0}:Series Name=\"Series1\"></{0}:Series></Series>" +
157         "<ChartAreas><{0}:ChartArea Name=\"ChartArea1\"></{0}:ChartArea></ChartAreas>" +
158 		"</{0}:Chart>"),
159 	ToolboxBitmap(typeof(Chart), "ChartControl.ico"),
160     Designer(Editors.ChartWebDesigner)
161 	]
162     [SuppressMessage("Microsoft.Naming", "CA1724:TypeNamesShouldNotMatchNamespaces")]
163 	[DisplayNameAttribute("Chart")]
164     [SupportsEventValidation]
165     [DefaultEvent("Load")]
166 #if ASPPERM_35
167     [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
168     [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
169 #endif
170     public class Chart : System.Web.UI.WebControls.DataBoundControl, IPostBackEventHandler
171 	{
172 
173         #region Control fields
174 
175         /// <summary>
176         /// True if smart labels debug markings should be drawn.
177         /// This field is for SmartLabels related issues debugging only.
178         /// </summary>
179         internal bool ShowDebugMarkings = false;
180 
181         // Chart services components
182 		private ChartTypeRegistry				_chartTypeRegistry = null;
183 		private BorderTypeRegistry				_borderTypeRegistry = null;
184         private CustomPropertyRegistry          _customPropertyRegistry = null;
185 		private DataManager						_dataManager = null;
186 		internal ChartImage						chartPicture = null;
187 		private ImageLoader						_imageLoader = null;
188 		internal static ITypeDescriptorContext	controlCurrentContext = null;
189 		internal string							webFormDocumentURL = "";
190 		internal ServiceContainer				serviceContainer = null;
191 
192 		// Named images collection
193 		private NamedImagesCollection			_namedImages = null;
194 
195 
196 		private FormulaRegistry					_formulaRegistry = null;
197 
198 
199 		// Product ID
200 
201 		internal static string					productID = "MSC-WCE-10";
202 
203 		// Control license
204 		private	License							_license = null;
205 
206 		// Private data members, which store properties values
207 		private	RenderType						_renderType = RenderType.ImageTag;
208 		private string							_chartImageLocation = "ChartPic_#SEQ(300,3)";
209 
210 		// Indicates that chart is serializing the data
211 		internal bool							serializing = false;
212 
213         // Detailed serialization status which allows not only to determine if serialization
214         // is curently in process but also check if we are saving, loading or resetting the chart.
215         internal SerializationStatus            serializationStatus = SerializationStatus.None;
216 
217 		// Chart serializer
218 		private ChartSerializer					_chartSerializer = null;
219 
220 		// Chart content saved in the view state
221 		private	SerializationContents 			_viewStateContent = SerializationContents .Default;
222 
223 		// Image URL the chart will be renderd to
224 		private string							_currentChartImageLocation = String.Empty;
225 
226         // Image Handler URL the chart will be renderd to
227         private string                          _currentChartHandlerImageLocation = String.Empty;
228 
229 		// Indicates if unique GUID should be added to image file name to solve cashing issues
230 		private bool							_addGuidParam = true;
231 
232 		private KeywordsRegistry				_keywordsRegistry = null;
233 
234     	// Indicates image storage mode.
235     	private ImageStorageMode _imageStorageMode = ImageStorageMode.UseHttpHandler;
236 
237 
238         // Selection class
239         internal Selection                      selection = null;
240 
241 		#endregion
242 
243 		#region Constructors and initialization
244 
245 		/// <summary>
246 		/// Chart control constructor.
247 		/// </summary>
Chart()248 		public Chart() : base()
249 		{
250 			base.EnableViewState = false;
251 
252 			//*********************************************************
253 			//** Create services
254 			//*********************************************************
255 			serviceContainer = new ServiceContainer();
256 			_chartTypeRegistry = new ChartTypeRegistry();
257 			_borderTypeRegistry = new BorderTypeRegistry();
258 			_customPropertyRegistry = new CustomPropertyRegistry();
259 
260 			_keywordsRegistry = new KeywordsRegistry();
261 
262 			_dataManager = new DataManager(serviceContainer);
263 			_imageLoader = new ImageLoader(serviceContainer);
264 			chartPicture = new ChartImage(serviceContainer);
265 			_chartSerializer = new ChartSerializer(serviceContainer);
266 
267 
268 			_formulaRegistry = new FormulaRegistry();
269 
270 			// Add services to the service container
271 			serviceContainer.AddService(typeof(Chart), this);							// Chart Control
272 			serviceContainer.AddService(_chartTypeRegistry.GetType(), _chartTypeRegistry);// Chart types registry
273 			serviceContainer.AddService(_borderTypeRegistry.GetType(), _borderTypeRegistry);// Border types registry
274 			serviceContainer.AddService(_customPropertyRegistry.GetType(), _customPropertyRegistry);// Custom attribute registry
275 			serviceContainer.AddService(_dataManager.GetType(), _dataManager);			// Data Manager service
276 			serviceContainer.AddService(_imageLoader.GetType(), _imageLoader);			// Image Loader service
277 			serviceContainer.AddService(chartPicture.GetType(), chartPicture);			// Chart image service
278 			serviceContainer.AddService(_chartSerializer.GetType(), _chartSerializer);	// Chart serializer service
279 
280 
281 			serviceContainer.AddService(_formulaRegistry.GetType(), _formulaRegistry);			// Formula modules service
282 
283 
284 
285 			serviceContainer.AddService(_keywordsRegistry.GetType(), _keywordsRegistry);	// Keywords registry
286 
287 
288 
289 			// Initialize objects
290 			_dataManager.Initialize();
291 
292 			// Register known chart types
293 			_chartTypeRegistry.Register(ChartTypeNames.Bar, typeof(BarChart));
294 			_chartTypeRegistry.Register(ChartTypeNames.Column, typeof(ColumnChart));
295 			_chartTypeRegistry.Register(ChartTypeNames.Point, typeof(PointChart));
296 			_chartTypeRegistry.Register(ChartTypeNames.Bubble, typeof(BubbleChart));
297 			_chartTypeRegistry.Register(ChartTypeNames.Line, typeof(LineChart));
298 			_chartTypeRegistry.Register(ChartTypeNames.Spline, typeof(SplineChart));
299 			_chartTypeRegistry.Register(ChartTypeNames.StepLine, typeof(StepLineChart));
300 			_chartTypeRegistry.Register(ChartTypeNames.Area, typeof(AreaChart));
301 			_chartTypeRegistry.Register(ChartTypeNames.SplineArea, typeof(SplineAreaChart));
302 			_chartTypeRegistry.Register(ChartTypeNames.StackedArea, typeof(StackedAreaChart));
303 			_chartTypeRegistry.Register(ChartTypeNames.Pie, typeof(PieChart));
304 			_chartTypeRegistry.Register(ChartTypeNames.Stock, typeof(StockChart));
305 			_chartTypeRegistry.Register(ChartTypeNames.Candlestick, typeof(CandleStickChart));
306 			_chartTypeRegistry.Register(ChartTypeNames.Doughnut, typeof(DoughnutChart));
307 			_chartTypeRegistry.Register(ChartTypeNames.StackedBar, typeof(StackedBarChart));
308 			_chartTypeRegistry.Register(ChartTypeNames.StackedColumn, typeof(StackedColumnChart));
309 			_chartTypeRegistry.Register(ChartTypeNames.OneHundredPercentStackedColumn, typeof(HundredPercentStackedColumnChart));
310 			_chartTypeRegistry.Register(ChartTypeNames.OneHundredPercentStackedBar, typeof(HundredPercentStackedBarChart));
311 			_chartTypeRegistry.Register(ChartTypeNames.OneHundredPercentStackedArea, typeof(HundredPercentStackedAreaChart));
312 
313 
314 
315 			_chartTypeRegistry.Register(ChartTypeNames.Range, typeof(RangeChart));
316 			_chartTypeRegistry.Register(ChartTypeNames.SplineRange, typeof(SplineRangeChart));
317 			_chartTypeRegistry.Register(ChartTypeNames.RangeBar, typeof(RangeBarChart));
318 			_chartTypeRegistry.Register(ChartTypeNames.RangeColumn, typeof(RangeColumnChart));
319 			_chartTypeRegistry.Register(ChartTypeNames.ErrorBar, typeof(ErrorBarChart));
320 			_chartTypeRegistry.Register(ChartTypeNames.BoxPlot, typeof(BoxPlotChart));
321 			_chartTypeRegistry.Register(ChartTypeNames.Radar, typeof(RadarChart));
322 
323 
324 
325 			_chartTypeRegistry.Register(ChartTypeNames.Renko, typeof(RenkoChart));
326 			_chartTypeRegistry.Register(ChartTypeNames.ThreeLineBreak, typeof(ThreeLineBreakChart));
327 			_chartTypeRegistry.Register(ChartTypeNames.Kagi, typeof(KagiChart));
328 			_chartTypeRegistry.Register(ChartTypeNames.PointAndFigure, typeof(PointAndFigureChart));
329 
330 
331 
332 
333 
334 			_chartTypeRegistry.Register(ChartTypeNames.Polar, typeof(PolarChart));
335 			_chartTypeRegistry.Register(ChartTypeNames.FastLine, typeof(FastLineChart));
336 			_chartTypeRegistry.Register(ChartTypeNames.Funnel, typeof(FunnelChart));
337 			_chartTypeRegistry.Register(ChartTypeNames.Pyramid, typeof(PyramidChart));
338 
339 
340 
341 
342 
343 			_chartTypeRegistry.Register(ChartTypeNames.FastPoint, typeof(FastPointChart));
344 
345 
346 
347 
348 			// Register known formula modules
349             _formulaRegistry.Register(SR.FormulaNamePriceIndicators, typeof(PriceIndicators));
350             _formulaRegistry.Register(SR.FormulaNameGeneralTechnicalIndicators, typeof(GeneralTechnicalIndicators));
351             _formulaRegistry.Register(SR.FormulaNameTechnicalVolumeIndicators, typeof(VolumeIndicators));
352             _formulaRegistry.Register(SR.FormulaNameOscillator, typeof(Oscillators));
353             _formulaRegistry.Register(SR.FormulaNameGeneralFormulas, typeof(GeneralFormulas));
354             _formulaRegistry.Register(SR.FormulaNameTimeSeriesAndForecasting, typeof(TimeSeriesAndForecasting));
355             _formulaRegistry.Register(SR.FormulaNameStatisticalAnalysis, typeof(StatisticalAnalysis));
356 
357 			// Register known 3D border types
358 			_borderTypeRegistry.Register("Emboss", typeof(EmbossBorder));
359 			_borderTypeRegistry.Register("Raised", typeof(RaisedBorder));
360 			_borderTypeRegistry.Register("Sunken", typeof(SunkenBorder));
361 			_borderTypeRegistry.Register("FrameThin1", typeof(FrameThin1Border));
362 			_borderTypeRegistry.Register("FrameThin2", typeof(FrameThin2Border));
363 			_borderTypeRegistry.Register("FrameThin3", typeof(FrameThin3Border));
364 			_borderTypeRegistry.Register("FrameThin4", typeof(FrameThin4Border));
365 			_borderTypeRegistry.Register("FrameThin5", typeof(FrameThin5Border));
366 			_borderTypeRegistry.Register("FrameThin6", typeof(FrameThin6Border));
367 			_borderTypeRegistry.Register("FrameTitle1", typeof(FrameTitle1Border));
368 			_borderTypeRegistry.Register("FrameTitle2", typeof(FrameTitle2Border));
369 			_borderTypeRegistry.Register("FrameTitle3", typeof(FrameTitle3Border));
370 			_borderTypeRegistry.Register("FrameTitle4", typeof(FrameTitle4Border));
371 			_borderTypeRegistry.Register("FrameTitle5", typeof(FrameTitle5Border));
372 			_borderTypeRegistry.Register("FrameTitle6", typeof(FrameTitle6Border));
373 			_borderTypeRegistry.Register("FrameTitle7", typeof(FrameTitle7Border));
374 			_borderTypeRegistry.Register("FrameTitle8", typeof(FrameTitle8Border));
375 
376             // Create selection object
377             this.selection = new Selection(serviceContainer);
378 
379 			// Create named images collection
380             _namedImages = new NamedImagesCollection();
381 
382             // Hook up event handlers
383             ChartAreas.NameReferenceChanged += new EventHandler<NameReferenceChangedEventArgs>(Series.ChartAreaNameReferenceChanged);
384             ChartAreas.NameReferenceChanged += new EventHandler<NameReferenceChangedEventArgs>(Legends.ChartAreaNameReferenceChanged);
385             ChartAreas.NameReferenceChanged += new EventHandler<NameReferenceChangedEventArgs>(Titles.ChartAreaNameReferenceChanged);
386             ChartAreas.NameReferenceChanged += new EventHandler<NameReferenceChangedEventArgs>(Annotations.ChartAreaNameReferenceChanged);
387             Legends.NameReferenceChanged += new EventHandler<NameReferenceChangedEventArgs>(Series.LegendNameReferenceChanged);
388 
389             this.AlternateText = String.Empty;
390             this.DescriptionUrl = String.Empty;
391         }
392 
393 		#endregion
394 
395 		#region Chart rendering methods
396 
397         /// <summary>
398 		/// Gets current image URL the chart control will be rendered into.
399 		/// </summary>
400 		/// <returns>Current chart image URL.</returns>
401         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings")]
402         [
403 		    Bindable(false),
404 		    Browsable(false),
405 		    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
406 		    SerializationVisibility(SerializationVisibility.Hidden),
407         ]
408 		public string CurrentImageLocation
409 		{
410             get
411             {
412 
413                 if (this.RenderType == RenderType.ImageTag && this.GetImageStorageMode() == ImageStorageMode.UseHttpHandler)
414                 {
415                     return _currentChartHandlerImageLocation;
416                 }
417 
418                 // Image name is already created
419                 if (this._currentChartImageLocation.Length > 0)
420                 {
421                     return this._currentChartImageLocation;
422                 }
423 
424                 // Get picture name
425                 this._currentChartImageLocation = this.ImageLocation;
426                 int indexUID = -1;
427                 if (this.RenderType == RenderType.ImageTag)
428                 {
429                     // Make sure image URL is not empty
430                     if (this.ImageLocation.Length == 0)
431                     {
432                         throw (new InvalidOperationException(SR.ExceptionImageUrlIsEmpty));
433                     }
434                     // Add file extension if there is no one
435                     char[] slashesArray = { '\\', '/' };
436                     int pointIndex = _currentChartImageLocation.LastIndexOf('.');
437                     int slashIndex = _currentChartImageLocation.LastIndexOfAny(slashesArray);
438                     if (pointIndex < 0 || pointIndex < slashIndex)
439                     {
440                             switch (chartPicture.ImageType)
441                             {
442                                 case (ChartImageType.Bmp):
443                                     _currentChartImageLocation += ".bmp";
444                                     break;
445                                 case (ChartImageType.Jpeg):
446                                     _currentChartImageLocation += ".jpeg";
447                                     break;
448                                 case (ChartImageType.Png):
449                                     _currentChartImageLocation += ".png";
450                                     break;
451                                 case (ChartImageType.Emf):
452                                     _currentChartImageLocation += ".emf";
453                                     break;
454                             }
455                     }
456 
457                     // Double chech that #UID is not used with #SEQ
458                     // Add GUID to the filename
459                     indexUID = _currentChartImageLocation.IndexOf("#UID", StringComparison.Ordinal);
460                     int indexSEQ = _currentChartImageLocation.IndexOf("#SEQ", StringComparison.Ordinal);
461                     if (indexUID >= 0 && indexSEQ >= 0)
462                     {
463                         throw (new InvalidOperationException(SR.ExceptionImageUrlInvalidFormatters));
464                     }
465 
466                     // Add GUID to the filename
467                     if (indexUID >= 0)
468                     {
469                         // Replace "#UID" with GUID string
470                         _currentChartImageLocation = _currentChartImageLocation.Replace("#UID", Guid.NewGuid().ToString());
471                     }
472 
473                         // Add GUID to the filename
474                     else if (indexSEQ >= 0)
475                     {
476                         // Replace "#SEQ(XXX,XXX)" with the sequence string number
477                         _currentChartImageLocation = GetNewSeqImageUrl(_currentChartImageLocation);
478                     }
479 
480                 }
481 
482                 // Check if GUID parameter should be added to the SRC tag
483                 // Solves issue with image caching in IE
484                 int indexNoGuidParam = _currentChartImageLocation.IndexOf("#NOGUIDPARAM", StringComparison.Ordinal);
485                 if (indexNoGuidParam > 0)
486                 {
487                     _currentChartImageLocation = _currentChartImageLocation.Replace("#NOGUIDPARAM", "");
488                 }
489 
490                 // Check for virtual root character
491                 if (_currentChartImageLocation.StartsWith("~", StringComparison.Ordinal) && HttpContext.Current != null && this.Page.Request != null)
492                 {
493                     // NOTE: Solves issue #4771
494                     _currentChartImageLocation = this.Page.ResolveUrl(_currentChartImageLocation);
495                 }
496 
497                 return _currentChartImageLocation;
498             }
499         }
500 
501 
502 
503         /// <summary>
504         /// Determines if chart should render image maps
505         /// </summary>
506         /// <returns>True if should render image maps</returns>
HasImageMaps()507         private bool HasImageMaps()
508         {
509             // Render chart image map
510             if (this.RenderType != RenderType.BinaryStreaming && this.IsMapEnabled)
511             {
512                 if (this.MapAreas.Count > 0 || this.RenderType == RenderType.ImageMap)
513                 {
514                     // Render image map
515                     return true;
516                 }
517             }
518             return false;
519         }
520 
521         /// <summary>
522         /// Caches the IsImageRendersBorder result.
523         /// </summary>
524         private static int _isImageRendersBorder;
525         /// <summary>
526         /// Checks and returns true if the image renders border. Before Fx 4.0 image control renders border if is not declared.
527         /// After Fx 4.0 this is not by default.
528         /// </summary>
529         /// <returns>True if image control renders border style</returns>
530         private static bool IsImageRendersBorder
531         {
532             get
533             {
534                 if (_isImageRendersBorder == 0)
535                 {
536                     using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
537                     {
538                         using (HtmlTextWriter w = new HtmlTextWriter(sw))
539                         {
540                             System.Web.UI.WebControls.Image img = new System.Web.UI.WebControls.Image();
541                             img.RenderControl(w);
542                         }
543                         _isImageRendersBorder = sw.ToString().IndexOf("border", 0, StringComparison.OrdinalIgnoreCase) != -1 ? 1 : -1;
544                     }
545                 }
546                 return _isImageRendersBorder == 1;
547             }
548         }
549 
550         /// <summary>
551         /// Custom image control for supporting miage maps.
552         /// </summary>
553         private class CustomImageControl : System.Web.UI.WebControls.Image
554         {
555             /// <summary>
556             /// Initializes a new instance of the <see cref="CustomImageControl"/> class.
557             /// </summary>
CustomImageControl()558             internal CustomImageControl() : base()
559             {
560             }
561 
562             /// <summary>
563             /// Gets or sets a value indicating whether this instance has image map.
564             /// </summary>
565             /// <value>
566             /// 	<c>true</c> if this instance has image map; otherwise, <c>false</c>.
567             /// </value>
568             internal bool HasImageMap { get; set; }
569 
570             /// <summary>
571             /// Adds the attributes of an <see cref="T:System.Web.UI.WebControls.Image"/> to the output stream for rendering on the client.
572             /// </summary>
573             /// <param name="writer">A <see cref="T:System.Web.UI.HtmlTextWriter"/> that contains the output stream to render on the client browser.</param>
AddAttributesToRender(HtmlTextWriter writer)574             protected override void AddAttributesToRender(HtmlTextWriter writer)
575             {
576                 base.AddAttributesToRender(writer);
577                 if (this.HasImageMap)
578                 {
579                     writer.AddAttribute(HtmlTextWriterAttribute.Usemap, "#"+this.ClientID+"ImageMap", false);
580                 }
581                 if (!this.Enabled)
582                 {
583                     writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");
584                 }
585             }
586         }
587 
588         /// <summary>
589         /// Builds the image control.
590         /// </summary>
591         /// <param name="chartImageSrc">The chart image SRC.</param>
592         /// <param name="addGuidParameter">if set to <c>true</c> to add GUID parameter.</param>
593         /// <returns>A custom image control with image maps attribute</returns>
BuildImageControl(string chartImageSrc, bool addGuidParameter)594         private CustomImageControl BuildImageControl(string chartImageSrc, bool addGuidParameter)
595         {
596             CustomImageControl htmlImage = new CustomImageControl();
597             htmlImage.ImageUrl = chartImageSrc + (addGuidParameter ? "?" + Guid.NewGuid().ToString() : "");
598             htmlImage.ToolTip = this.ToolTip;
599             htmlImage.CssClass = this.CssClass;
600             htmlImage.AlternateText = this.AlternateText;
601             htmlImage.DescriptionUrl = this.DescriptionUrl;
602             htmlImage.AccessKey = this.AccessKey;
603             htmlImage.TabIndex = this.TabIndex;
604             htmlImage.Enabled = this.IsEnabled;
605             htmlImage.CopyBaseAttributes(this);
606             if (!IsImageRendersBorder)
607             {
608                 // set border 0px only if is not declared yet.
609                 if ( String.IsNullOrEmpty(htmlImage.Style[HtmlTextWriterStyle.BorderWidth]) &&
610                      String.IsNullOrEmpty(htmlImage.Style["border"]) &&
611                      String.IsNullOrEmpty(htmlImage.Style["border-width"]))
612                 {
613                     htmlImage.Style.Value = "border-width:0px;" + htmlImage.Style.Value;
614                 }
615             }
616 
617             htmlImage.ID = this.ClientID;
618 
619             htmlImage.GenerateEmptyAlternateText = true;
620 
621             htmlImage.Width = this.Width;
622             htmlImage.Height = this.Height;
623             htmlImage.HasImageMap = this.HasImageMaps();
624 
625             return htmlImage;
626         }
627 
628         private string _designTimeChart;
629 		/// <summary>
630 		/// Render this control to the output parameter specified.
631 		/// </summary>
632         /// <param name="writer">HTML writer.</param>
Render(HtmlTextWriter writer)633         protected override void Render(HtmlTextWriter writer)
634         {
635             // If by any reason (rudimentary designer host, no designer, embeded in user control, etc)
636             // Render() is called in design mode ( should be handled by control designed )
637             // we render the chart in temp file.
638             if (this.DesignMode)
639             {
640                 if (String.IsNullOrEmpty(_designTimeChart))
641                 {
642                     _designTimeChart = Path.GetTempFileName() + ".bmp";
643                 }
644                 SaveImage(_designTimeChart, ChartImageFormat.Bmp);
645                 using (CustomImageControl imageControl = this.BuildImageControl("file://" + _designTimeChart, false))
646                 {
647                     imageControl.RenderControl(writer);
648                 }
649                 return;
650             }
651 
652             // Check if GUID parameter should be added to the SRC tag
653 			// Solves issue with image caching in IE
654 			_addGuidParam = true;
655 			int		indexNoGuidParam = this.ImageLocation.IndexOf("#NOGUIDPARAM", StringComparison.Ordinal);
656 			if(indexNoGuidParam > 0)
657 			{
658 				_addGuidParam = false;
659 			}
660 
661 			// Get picture name
662 			string	chartImage = this.CurrentImageLocation;
663 
664 
665             if (this.RenderType == RenderType.ImageTag)
666             {
667                 if (this.GetImageStorageMode() == ImageStorageMode.UseHttpHandler)
668                 {
669                     using (MemoryStream stream = new MemoryStream())
670                     {
671                         this.SaveImage(stream);
672                         chartImage = ChartHttpHandler.GetChartImageUrl(stream, this.ImageType.ToString());
673                         _currentChartHandlerImageLocation = chartImage;
674                     }
675                     _addGuidParam = false;
676                 }
677                 else
678                 {
679                     // Save chart into specified image URL
680                     SaveImage(this.Page.MapPath(chartImage));
681                 }
682 
683                 using (CustomImageControl imageControl = this.BuildImageControl(chartImage, _addGuidParam))
684                 {
685                     imageControl.RenderControl(writer);
686                 }
687 
688 			}
689 
690 			// Render chart image as image tag + image map
691 			else if(this.RenderType == RenderType.ImageMap)
692 			{
693 
694 				// Get chart image (do not save it)
695                 chartPicture.PaintOffScreen();
696 
697                 using (CustomImageControl imageControl = this.BuildImageControl(chartImage, _addGuidParam))
698                 {
699                     imageControl.RenderControl(writer);
700                 }
701 
702 	        }
703             // Render chart using binary data streaming
704             else
705             {
706 
707                 // Set response content type
708                 switch (chartPicture.ImageType)
709                 {
710                     case (ChartImageType.Bmp):
711                         this.Page.Response.ContentType = "image/bmp";
712                         break;
713                     case (ChartImageType.Jpeg):
714                         this.Page.Response.ContentType = "image/jpeg";
715                         break;
716                     case (ChartImageType.Png):
717                         this.Page.Response.ContentType = "image/png";
718                         break;
719                 }
720 
721                 this.Page.Response.Charset = "";
722 
723                 // Save image into the memory stream
724                 MemoryStream stream = new MemoryStream();
725                 SaveImage(stream);
726                 this.Page.Response.BinaryWrite(stream.GetBuffer());
727             }
728 
729 
730 			// Render chart image map
731             if (this.HasImageMaps())
732 			{
733 					// Render image map
734 					chartPicture.WriteChartMapTag(writer, this.ClientID + "ImageMap");
735 			}
736 
737             // Reset image Url field
738             this._currentChartImageLocation = String.Empty;
739 
740 		}
741 
742 
743         /// <summary>
744 		/// Checks image URL sequence format.
745 		/// </summary>
746 		/// <param name="imageURL">Image URL to test.</param>
CheckImageURLSeqFormat(string imageURL)747 		void CheckImageURLSeqFormat(string imageURL)
748 		{
749 			// Find the begginning of the "#SEQ" formatting string
750 			int indexSEQ = imageURL.IndexOf("#SEQ", StringComparison.Ordinal);
751 			indexSEQ += 4;
752 
753 			// The "#SEQ" formatter must be followed by (MMM,TTT), where MMM - max sequence number and TTT - time to live
754 			if(imageURL[indexSEQ] != '(')
755 			{
756 				throw( new ArgumentException(SR.ExceptionImageUrlInvalidFormat, "imageURL"));
757 			}
758 			// Find closing bracket
759 			int indexClosing = imageURL.IndexOf(')', 1);
760 			if(indexClosing < 0)
761 			{
762                 throw (new ArgumentException(SR.ExceptionImageUrlInvalidFormat, "imageURL"));
763 			}
764 
765 			// Get max sequence number and time to live
766 			string[] values = imageURL.Substring(indexSEQ + 1, indexClosing - indexSEQ - 1).Split(',');
767 			if(values == null || values.Length != 2)
768 			{
769                 throw (new ArgumentException(SR.ExceptionImageUrlInvalidFormat, "imageURL"));
770 			}
771 
772 			// Make sure all characters are digits
773 			foreach(String str in values)
774 			{
775                 if (String.IsNullOrEmpty(str) || str.Length > 7)
776                 {
777                     throw (new ArgumentException(SR.ExceptionImageUrlInvalidFormat, "imageURL"));
778                 }
779                 foreach (Char c in str)
780 				{
781 					if(!Char.IsDigit(c))
782 					{
783 						throw( new ArgumentException( SR.ExceptionImageUrlInvalidFormat, "imageURL"));
784 					}
785 				}
786 			}
787 		}
788 
789 		/// <summary>
790 		/// Helper function, which returns a new image URL
791 		/// using the sequence numbers
792 		/// </summary>
793 		/// <param name="imageUrl">Image URL format.</param>
794 		/// <returns>New image URL.</returns>
GetNewSeqImageUrl(string imageUrl)795 		private string GetNewSeqImageUrl(string imageUrl)
796 		{
797 			// Initialize image URL max sequence number and image time to live values
798 			int		maxSeqNumber = 0;
799 			int		imageTimeToLive = 0;
800 			string	result = "";
801 
802 			//*********************************************************
803 			//** Check image URL format
804 			//*********************************************************
805 
806 			// Find the begginning of the "#SEQ" formatting string
807 			int indexSEQ = imageUrl.IndexOf("#SEQ", StringComparison.Ordinal);
808 			if(indexSEQ < 0)
809 			{
810 				throw( new ArgumentException( SR.ExceptionImageUrlMissedFormatter, "imageUrl"));
811 			}
812 
813 			// Check format
814 			CheckImageURLSeqFormat(imageUrl);
815 
816 			// Copy everything till the beginning of the format in the result string
817 			result = imageUrl.Substring(0, indexSEQ);
818 			indexSEQ += 4;
819 
820 			// Find closing bracket
821 			int indexClosing = imageUrl.IndexOf(')', 1);
822 
823 			// Add sequence position and everything after closing bracket into the result string
824 			result += "{0:D6}";
825 			result += imageUrl.Substring(indexClosing + 1);
826 
827 			// Get max sequence number and time to live
828 			string[] values = imageUrl.Substring(indexSEQ + 1, indexClosing - indexSEQ - 1).Split(',');
829 			maxSeqNumber = Int32.Parse(values[0], System.Globalization.CultureInfo.InvariantCulture);
830 			imageTimeToLive = Int32.Parse(values[1], System.Globalization.CultureInfo.InvariantCulture);
831 
832 			//*********************************************************
833 			//** Generate new sequence number
834 			//*********************************************************
835 			int		imageSeqNumber = 1;
836 
837 			// Make sure application scope variable "ImageSeqNumber" exist
838 			this.Page.Application.Lock();
839 			if(this.Page.Application[Chart.productID+"_ImageSeqNumber"] != null)
840 			{
841 				imageSeqNumber = (int)this.Page.Application[Chart.productID+"_ImageSeqNumber"] + 1;
842 				if(imageSeqNumber > maxSeqNumber)
843 				{
844 					imageSeqNumber = 1;
845 				}
846 			}
847 			// Save sequence number
848 			this.Page.Application[Chart.productID+"_ImageSeqNumber"] = imageSeqNumber;
849 			this.Page.Application.UnLock();
850 
851 			//*********************************************************
852 			//** Prepare result string
853 			//*********************************************************
854 
855 			result = String.Format(CultureInfo.InvariantCulture, result, imageSeqNumber);
856 
857 			//*********************************************************
858 			//** Check if the image with this name exsists and it's
859 			//** live time is smaller than image time-to-live specified.
860 			//** In this case put a warning into the even log.
861 			//*********************************************************
862 			if(imageTimeToLive > 0)
863 			{
864 				CheckChartFileTime(result, imageTimeToLive);
865 			}
866 
867 			return result;
868 		}
869 
870 		/// <summary>
871 		/// Check if the image with this name exsists and it's
872 		/// live time is smaller than image time-to-live specified.
873 		/// In this case put a warning into the even log.
874 		/// </summary>
875 		/// <param name="fileName">File name.</param>
876 		/// <param name="imageTimeToLive">Time to live.</param>
CheckChartFileTime(string fileName, int imageTimeToLive)877 		private void CheckChartFileTime(string fileName, int imageTimeToLive)
878 		{
879 			//*********************************************************
880 			//** Check if the image with this name exsists and it's
881 			//** live time is smaller than image time-to-live specified.
882 			//** In this case put a warning into the even log.
883 			//*********************************************************
884             try
885             {
886                 if (imageTimeToLive > 0)
887                 {
888                     fileName = this.Page.MapPath(fileName);
889                     if (File.Exists(fileName))
890                     {
891                         DateTime fileTime = File.GetLastWriteTime(fileName);
892                         if (fileTime.AddMinutes(imageTimeToLive) > DateTime.Now)
893                         {
894                             const string eventSource = "ChartComponent";
895 
896                             // Create the source, if it does not already exist.
897                             if (!EventLog.SourceExists(eventSource))
898                             {
899                                 EventLog.CreateEventSource(eventSource, "Application");
900                             }
901 
902                             // Create an EventLog instance and assign its source.
903                             EventLog eventLog = new EventLog();
904                             eventLog.Source = eventSource;
905 
906                             // Write an informational entry to the event log.
907                             TimeSpan timeSpan = DateTime.Now - fileTime;
908                             eventLog.WriteEntry(SR.EvenLogMessageChartImageFileTimeToLive(timeSpan.Minutes.ToString(CultureInfo.InvariantCulture)), EventLogEntryType.Warning);
909                         }
910                     }
911                 }
912             }
913             catch (SecurityException)
914             {
915             }
916             catch (ArgumentException)
917             {
918             }
919             catch (InvalidOperationException)
920             {
921             }
922             catch (Win32Exception)
923             {
924             }
925 		}
926 
927 		#endregion
928 
929 		#region Chart selection methods
930 
931         /// <summary>
932         /// This method performs the hit test and returns a HitTestResult objects.
933         /// </summary>
934         /// <param name="x">X coordinate</param>
935         /// <param name="y">Y coordinate</param>
936         /// <returns>Hit test result object</returns>
937         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
938             Justification = "X and Y are cartesian coordinates and well understood")]
HitTest(int x, int y)939         public HitTestResult HitTest(int x, int y)
940         {
941             return selection.HitTest(x, y);
942         }
943 
944         /// <summary>
945         /// This method performs the hit test and returns a HitTestResult object.
946         /// </summary>
947         /// <param name="x">X coordinate</param>
948         /// <param name="y">Y coordinate</param>
949         /// <param name="ignoreTransparent">Indicates that transparent elements should be ignored.</param>
950         /// <returns>Hit test result object</returns>
951         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
952             Justification = "X and Y are cartesian coordinates and well understood")]
HitTest(int x, int y, bool ignoreTransparent)953         public HitTestResult HitTest(int x, int y, bool ignoreTransparent)
954         {
955             return selection.HitTest(x, y, ignoreTransparent);
956         }
957 
958         /// <summary>
959         /// This method performs the hit test and returns a HitTestResult object.
960         /// </summary>
961         /// <param name="x">X coordinate</param>
962         /// <param name="y">Y coordinate</param>
963         /// <param name="requestedElement">Only this chart element will be hit tested.</param>
964         /// <returns>Hit test result object</returns>
965         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
966             Justification = "X and Y are cartesian coordinates and well understood")]
HitTest(int x, int y, ChartElementType requestedElement)967         public HitTestResult HitTest(int x, int y, ChartElementType requestedElement)
968         {
969             return selection.HitTest(x, y, requestedElement);
970         }
971 
972         /// <summary>
973         /// Call this method to determine the  chart element,
974         /// if any, that is located at a point defined by the given X and Y
975         /// coordinates.
976         /// <seealso cref="HitTestResult"/></summary>
977         /// <param name="x">The X coordinate for the point in question.
978         /// Often obtained from a parameter in an event
979         /// (e.g. the X parameter value in the MouseDown event).</param>
980         /// <param name="y">The Y coordinate for the point in question.
981         /// Often obtained from a parameter in an event
982         /// (e.g. the Y parameter value in the MouseDown event).</param>
983         /// <param name="ignoreTransparent">Indicates that transparent
984         /// elements should be ignored.</param>
985         /// <param name="requestedElement">
986         /// An array of type which specify the types
987         /// to test for, on order to filter the result. If omitted checking for
988         /// elementTypes will be ignored and all kind of elementTypes will be
989         /// valid.
990         ///  </param>
991         /// <returns>
992         /// A array of <see cref="HitTestResult"/> objects,
993         /// which provides information concerning the  chart element
994         /// (if any) that is at the specified location. Result contains at least
995         /// one element, which could be ChartElementType.Nothing.
996         /// The objects in the result are sorted in from top to bottom of
997         /// different layers of control. </returns>
998         /// <remarks>Call this method to determine the  gauge element
999         /// (if any) that is located at a specified point. Often this method is used in
1000         /// some mouse-related event (e.g. MouseDown)
1001         /// to determine what  gauge element the end-user clicked on.
1002         /// The X and Y mouse coordinates obtained from the
1003         /// event parameters are then used for the X and Y parameter
1004         /// values of this method call.   The returned
1005         /// <see cref="HitTestResult"/> object's properties
1006         /// can then be used to determine what  chart element was clicked on,
1007         /// and also provides a reference to the actual object selected (if
1008         /// any).</remarks>
1009         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
1010             Justification = "X and Y are cartesian coordinates and well understood")]
HitTest(int x, int y, bool ignoreTransparent, params ChartElementType[] requestedElement)1011         public HitTestResult[] HitTest(int x, int y, bool ignoreTransparent, params ChartElementType[] requestedElement)
1012         {
1013             return this.selection.HitTest(x, y, ignoreTransparent, requestedElement);
1014         }
1015 
1016         /// <summary>
1017         /// Gets the chart element outline.
1018         /// </summary>
1019         /// <param name="chartElement">The chart element.</param>
1020         /// <param name="elementType">Type of the element.</param>
1021         /// <returns> A <see cref="ChartElementOutline"/> object which contains
1022         /// 1) An array of points in absolute coordinates which can be used as outline markers arround this chart element.
1023         /// 2) A GraphicsPath for drawing aouline around this chart emenent.
1024         /// </returns>
1025         /// <remarks>
1026         /// If the <paramref name="chartElement"/> is not part of the chart or <paramref name="elementType"/> cannot be combined
1027         /// with <paramref name="chartElement"/> then the result will contain empty array of marker points.
1028         /// The marker points are sorted clockwise.
1029         /// </remarks>
GetChartElementOutline(object chartElement, ChartElementType elementType)1030         public ChartElementOutline GetChartElementOutline(object chartElement, ChartElementType elementType)
1031         {
1032             return this.selection.GetChartElementOutline(chartElement, elementType);
1033         }
1034 
1035 		#endregion
1036 
1037 		#region Chart image saving methods
1038 
1039         /// <summary>
1040         /// Draws chart on the graphics.
1041         /// </summary>
1042         /// <param name="graphics">Graphics.</param>
1043         /// <param name="position">Position to draw in the graphics.</param>
Paint(Graphics graphics, Rectangle position)1044         public void Paint(Graphics graphics, Rectangle position)
1045         {
1046                 // Change chart size to fit the new position
1047                 int oldWidth = this.chartPicture.Width;
1048                 int oldHeight = this.chartPicture.Height;
1049                 // Save graphics state.
1050                 GraphicsState transState = graphics.Save();
1051                 try
1052                 {
1053                     this.chartPicture.Width = position.Width;
1054                     this.chartPicture.Height = position.Height;
1055                     // Set required transformation
1056                     graphics.TranslateTransform(position.X, position.Y);
1057                     // Set printing indicator
1058                     this.chartPicture.isPrinting = true;
1059                     // Draw chart
1060                     this.chartPicture.Paint(graphics, false);
1061                     // Clear printing indicator
1062                     this.chartPicture.isPrinting = false;
1063 
1064                 }
1065                 finally
1066                 {
1067                     // Restore graphics state.
1068                     graphics.Restore(transState);
1069                     // Restore old chart position
1070                     this.chartPicture.Width = oldWidth;
1071                     this.chartPicture.Height = oldHeight;
1072 
1073                 }
1074         }
1075 
1076         /// <summary>
1077 		/// Saves chart image into the file.
1078 		/// </summary>
1079 		/// <param name="imageFileName">Image file name</param>
1080 		/// <param name="format">Image format.</param>
SaveImage(string imageFileName, ChartImageFormat format)1081 		public void SaveImage(string imageFileName, ChartImageFormat format)
1082         {
1083             // Check arguments
1084             if (imageFileName == null)
1085                 throw new ArgumentNullException("imageFileName");
1086 
1087 			// Create file stream for the specified file name
1088 			FileStream	fileStream = new FileStream(imageFileName, FileMode.Create);
1089 
1090 			// Save into stream
1091 			try
1092 			{
1093 				SaveImage(fileStream, format);
1094 			}
1095 			finally
1096 			{
1097 				// Close file stream
1098 				fileStream.Close();
1099 			}
1100 		}
1101 
1102 
1103 		/// <summary>
1104 		/// Saves chart image into the stream.
1105 		/// </summary>
1106 		/// <param name="imageStream">Image stream.</param>
1107 		/// <param name="format">Image format.</param>
SaveImage( Stream imageStream, ChartImageFormat format)1108 		public void SaveImage( Stream imageStream, ChartImageFormat format)
1109 		{
1110             // Check arguments
1111             if (imageStream == null)
1112                 throw new ArgumentNullException("imageStream");
1113 
1114             this.chartPicture.isPrinting = true;
1115             try
1116             {
1117                 if (format == ChartImageFormat.Emf ||
1118                     format == ChartImageFormat.EmfDual ||
1119                     format == ChartImageFormat.EmfPlus)
1120                 {
1121                     EmfType emfType = EmfType.EmfOnly;
1122                     if (format == ChartImageFormat.EmfDual)
1123                     {
1124                         emfType = EmfType.EmfPlusDual;
1125                     }
1126                     else if (format == ChartImageFormat.EmfPlus)
1127                     {
1128                         emfType = EmfType.EmfPlusOnly;
1129                     }
1130 
1131                     // Save into the metafile
1132                     this.chartPicture.SaveIntoMetafile(imageStream, emfType);
1133                 }
1134                 else
1135                 {
1136                     // Get chart image
1137                     System.Drawing.Image chartImage = this.chartPicture.GetImage();
1138 
1139                     ImageFormat standardImageFormat = ImageFormat.Png;
1140 
1141                     switch (format)
1142                     {
1143                         case ChartImageFormat.Bmp:
1144                             standardImageFormat = ImageFormat.Bmp;
1145                             break;
1146 
1147                         case ChartImageFormat.Gif:
1148                             standardImageFormat = ImageFormat.Gif;
1149                             break;
1150 
1151                        case ChartImageFormat.Tiff:
1152                             standardImageFormat = ImageFormat.Tiff;
1153                             break;
1154 
1155 
1156                         case ChartImageFormat.Jpeg:
1157                             standardImageFormat = ImageFormat.Jpeg;
1158                             break;
1159                         case ChartImageFormat.Png:
1160                             standardImageFormat = ImageFormat.Png;
1161                             break;
1162 
1163 
1164                         case ChartImageFormat.Emf:
1165                             standardImageFormat = ImageFormat.Emf;
1166                             break;
1167                     }
1168 
1169                     // Save image into the file
1170                     chartImage.Save(imageStream, standardImageFormat);
1171 
1172                     // Dispose image
1173                     chartImage.Dispose();
1174                 }
1175             }
1176             finally
1177             {
1178                 this.chartPicture.isPrinting = false;
1179             }
1180 		}
1181 
1182 
1183 		/// <summary>
1184 		/// Saves image into the stream. ImageType, Compression and other control properties are used.
1185 		/// </summary>
1186 		/// <param name="imageStream">Image stream.</param>
SaveImage(Stream imageStream)1187         public void SaveImage(Stream imageStream)
1188 		{
1189             // Check arguments
1190             if (imageStream == null)
1191                 throw new ArgumentNullException("imageStream");
1192 
1193 			//*****************************************************
1194 			//** Disable validating the license for now....
1195 			//*****************************************************
1196 			// ValidateLicense();
1197 
1198             this.chartPicture.isPrinting = true;
1199             try
1200             {
1201 
1202 			// Save into the metafile
1203 			if( ImageType == ChartImageType.Emf)
1204 			{
1205 				this.chartPicture.SaveIntoMetafile(imageStream, EmfType.EmfOnly);
1206 				return;
1207 			}
1208 
1209             System.Drawing.Image image = chartPicture.GetImage();
1210             // Set image settings
1211 			ImageCodecInfo imageCodecInfo = null;
1212 			EncoderParameter encoderParameter = null;
1213 			EncoderParameters encoderParameters = new EncoderParameters(1);
1214 
1215 			// Get image codec information
1216 			if(ImageType == ChartImageType.Bmp)
1217 			{
1218 				imageCodecInfo = GetEncoderInfo("image/bmp");
1219 			}
1220 			else if(ImageType == ChartImageType.Jpeg)
1221 			{
1222 				imageCodecInfo = GetEncoderInfo("image/jpeg");
1223 			}
1224 			else if(ImageType == ChartImageType.Png)
1225 			{
1226 				imageCodecInfo = GetEncoderInfo("image/png");
1227 			}
1228 
1229 			// Set image quality
1230 			encoderParameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100-Compression);
1231 			encoderParameters.Param[0] = encoderParameter;
1232 
1233 			// Save image into the file
1234 			if(imageCodecInfo == null)
1235 			{
1236 				ImageFormat	format = (ImageFormat)new ImageFormatConverter().ConvertFromString(ImageType.ToString());
1237 				image.Save(imageStream, format);
1238 			}
1239 			else
1240 			{
1241 				image.Save(imageStream, imageCodecInfo, encoderParameters);
1242 			}
1243 
1244 			image.Dispose();
1245         }
1246         finally
1247         {
1248             this.chartPicture.isPrinting = false;
1249         }
1250     }
1251 
1252 
1253 		/// <summary>
1254 		/// Saves image into the file. ImageType, Compression and other control properties are used.
1255 		/// </summary>
1256 		/// <param name="imageFileName">Image file name</param>
SaveImage(string imageFileName)1257 		public void SaveImage(string imageFileName)
1258 		{
1259             // Check arguments
1260             if (imageFileName == null)
1261                 throw new ArgumentNullException("imageFileName");
1262 
1263 			// Create file stream for the specified file name
1264 			FileStream	fileStream = new FileStream(imageFileName, FileMode.Create);
1265 
1266 			// Save into stream
1267 			try
1268 			{
1269 				SaveImage(fileStream);
1270 			}
1271 			finally
1272 			{
1273 				// Close file stream
1274 				fileStream.Close();
1275 			}
1276 		}
1277 
1278 
1279 
1280 
1281 
1282 		/// <summary>
1283 		/// Helper function. Returns image encoder using Mime image type
1284 		/// </summary>
1285 		/// <param name="mimeType">Mime image type</param>
1286 		/// <returns>Image codec</returns>
GetEncoderInfo(String mimeType)1287 		private static ImageCodecInfo GetEncoderInfo(String mimeType)
1288 		{
1289 			int j;
1290 			ImageCodecInfo[] encoders;
1291 			encoders = ImageCodecInfo.GetImageEncoders();
1292 			for(j = 0; j < encoders.Length; ++j)
1293 			{
1294 				if(encoders[j].MimeType == mimeType)
1295 				{
1296 					return encoders[j];
1297 				}
1298 			}
1299 			return null;
1300 		}
1301 
1302 #endregion
1303 
1304 		#region Control events
1305 
1306 
1307         // Defines a key for storing the delegate for the PrePaint event
1308         // in the Events list.
1309         private static readonly object _prePaintEvent = new object();
1310 
1311 		/// <summary>
1312 		/// Fires after the chart element backround was drawn.
1313 		/// This event is fired for elements like: ChartPicture, ChartArea and Legend
1314 		/// </summary>
1315 		[
1316 		SRDescription("DescriptionAttributeChartEvent_PrePaint")
1317 		]
1318         public event EventHandler<ChartPaintEventArgs> PrePaint
1319         {
1320             add { Events.AddHandler(_prePaintEvent, value); }
1321             remove { Events.RemoveHandler(_prePaintEvent, value); }
1322         }
1323 
1324         // Defines a key for storing the delegate for the PrePaint event
1325         // in the Events list.
1326         private static readonly object _postPaintEvent = new object();
1327 
1328 		/// <summary>
1329 		/// Fires after chart element was drawn.
1330 		/// This event is fired for elements like: ChartPicture, ChartArea and Legend
1331 		/// </summary>
1332         [
1333         SRDescription("DescriptionAttributeChartEvent_PostPaint")
1334         ]
1335         public event EventHandler<ChartPaintEventArgs> PostPaint
1336         {
1337             add { Events.AddHandler(_postPaintEvent, value); }
1338             remove { Events.RemoveHandler(_postPaintEvent, value); }
1339         }
1340 
1341         // Defines a key for storing the delegate for the CustomizeMapAreas event
1342         // in the Events list.
1343         private static readonly object _customizeMapAreasEvent = new object();
1344 
1345 		/// <summary>
1346 		/// Fires just before the chart image map is rendered. Use this event to customize the map areas items.
1347 		/// </summary>
1348 		[
1349 		SRDescription("DescriptionAttributeChartEvent_CustomizeMapAreas")
1350 		]
1351         public event EventHandler<CustomizeMapAreasEventArgs> CustomizeMapAreas
1352         {
1353             add { Events.AddHandler(_customizeMapAreasEvent, value); }
1354             remove { Events.RemoveHandler(_customizeMapAreasEvent, value); }
1355         }
1356 
1357 
1358 
1359         // Defines a key for storing the delegate for the CustomizeMapAreas event
1360         // in the Events list.
1361         private static readonly object _customizeEvent = new object();
1362         /// <summary>
1363 		/// Fires just before the chart image is drawn. Use this event to customize the chart picture.
1364 		/// </summary>
1365 		[
1366 		SRDescription("DescriptionAttributeChartEvent_Customize")
1367 		]
1368 		public event EventHandler Customize
1369         {
1370             add { Events.AddHandler(_customizeEvent, value); }
1371             remove { Events.RemoveHandler(_customizeEvent, value); }
1372         }
1373 
1374         // Defines a key for storing the delegate for the CustomizeMapAreas event
1375         // in the Events list.
1376         private static readonly object _customizeLegendEvent = new object();
1377         /// <summary>
1378 		/// Fires just before the chart legend is drawn. Use this event to customize the chart legend items.
1379 		/// </summary>
1380         [
1381         SRDescription("DescriptionAttributeChartEvent_CustomizeLegend")
1382         ]
1383         public event EventHandler<CustomizeLegendEventArgs> CustomizeLegend
1384         {
1385             add { Events.AddHandler(_customizeLegendEvent, value); }
1386             remove { Events.RemoveHandler(_customizeLegendEvent, value); }
1387         }
1388 
1389         // Defines a key for storing the delegate for the Click event
1390         // in the Events list.
1391         private static readonly object _clickEvent = new object();
1392         /// <summary>
1393         /// Occurs when active image map area defined by PostBackValue on Chart control is clicked.
1394         /// </summary>
1395         [
1396         SRCategory("CategoryAttributeAction"),
1397         SRDescription(SR.Keys.DescriptionAttributeChartEvent_Click)
1398         ]
1399         public event ImageMapEventHandler Click
1400         {
1401             add { Events.AddHandler(_clickEvent, value); }
1402             remove { Events.RemoveHandler(_clickEvent, value); }
1403         }
1404 
1405 
1406 		#endregion
1407 
1408 		#region Event Handling
1409 
1410 
1411 		/// <summary>
1412 		/// Invokes delegates registered with the Click event.
1413 		/// </summary>
1414 		/// <param name="e"></param>
1415         [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
OnClick(ImageMapEventArgs e)1416         protected virtual void OnClick(ImageMapEventArgs e)
1417 		{
1418             ImageMapEventHandler clickEventDelegate = (ImageMapEventHandler)Events[_clickEvent];
1419 			if (clickEventDelegate != null)
1420 			{
1421 				clickEventDelegate(this, e);
1422 			}
1423 		}
1424 
1425 
1426 		/// <summary>
1427         /// Raises events for the Chart control when a form is posted back to the server.
1428 		/// </summary>
1429 		/// <param name="eventArgument">Event argument.</param>
1430         [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")]
RaisePostBackEvent(string eventArgument)1431 		protected virtual void RaisePostBackEvent(string eventArgument)
1432 		{
1433             if (!String.IsNullOrEmpty(eventArgument))
1434             {
1435                 this.OnClick(new ImageMapEventArgs(eventArgument));
1436             }
1437 		}
1438 
1439 		/// <summary>
1440 		/// Fires when chart element backround must be drawn.
1441 		/// This event is fired for elements like: ChatPicture, ChartArea and Legend
1442 		/// </summary>
1443 		/// <param name="e">Event arguments.</param>
1444 		[
1445 		SRDescription("DescriptionAttributeChart_OnBackPaint")
1446 		]
1447         [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
OnPrePaint(ChartPaintEventArgs e)1448         protected virtual void OnPrePaint(ChartPaintEventArgs e)
1449 		{
1450             EventHandler<ChartPaintEventArgs> prePaintEventDelegate = (EventHandler<ChartPaintEventArgs>)Events[_prePaintEvent];
1451             if (prePaintEventDelegate != null)
1452             {
1453                 prePaintEventDelegate(this, e);
1454             }
1455 		}
1456 
1457         /// <summary>
1458         /// Fires when chart element backround must be drawn.
1459         /// This event is fired for elements like: ChatPicture, ChartArea and Legend
1460         /// </summary>
1461         /// <param name="e">Event arguments.</param>
CallOnPrePaint(ChartPaintEventArgs e)1462         internal void CallOnPrePaint(ChartPaintEventArgs e)
1463         {
1464             this.OnPrePaint(e);
1465         }
1466 
1467 		/// <summary>
1468 		/// Fires when chart element must be drawn.
1469 		/// This event is fired for elements like: ChatPicture, ChartArea and Legend
1470 		/// </summary>
1471 		/// <param name="e">Event arguments.</param>
1472 		[
1473 		SRDescription("DescriptionAttributeChart_OnPaint")
1474 		]
1475         [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
OnPostPaint(ChartPaintEventArgs e)1476         protected virtual void OnPostPaint(ChartPaintEventArgs e)
1477 		{
1478             EventHandler<ChartPaintEventArgs> postPaintEventDelegate = (EventHandler<ChartPaintEventArgs>)Events[_postPaintEvent];
1479             if (postPaintEventDelegate != null)
1480             {
1481                 postPaintEventDelegate(this, e);
1482             }
1483 		}
1484 
1485         /// <summary>
1486         /// Fires when chart element must be drawn.
1487         /// This event is fired for elements like: ChatPicture, ChartArea and Legend
1488         /// </summary>
1489         /// <param name="e">Event arguments.</param>
CallOnPostPaint(ChartPaintEventArgs e)1490         internal void CallOnPostPaint(ChartPaintEventArgs e)
1491         {
1492             this.OnPostPaint(e);
1493         }
1494 
1495         /// <summary>
1496         /// Fires when chart image map data is prepared to be rendered.
1497         /// </summary>
1498         /// <param name="e">The <see cref="System.Web.UI.DataVisualization.Charting.CustomizeMapAreasEventArgs"/> instance containing the event data.</param>
1499 		[
1500 		SRDescription("DescriptionAttributeChart_OnCustomizeMapAreas")
1501 		]
1502         [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
OnCustomizeMapAreas(CustomizeMapAreasEventArgs e)1503         protected virtual void OnCustomizeMapAreas(CustomizeMapAreasEventArgs e)
1504 		{
1505             EventHandler<CustomizeMapAreasEventArgs> customizeMapAreasEventDelegate = (EventHandler<CustomizeMapAreasEventArgs>)Events[_customizeMapAreasEvent];
1506             if (customizeMapAreasEventDelegate != null)
1507             {
1508                 customizeMapAreasEventDelegate(this, e);
1509             }
1510 		}
1511 
1512         /// <summary>
1513         /// Fires when chart image map data is prepared to be rendered.
1514         /// </summary>
CallOnCustomizeMapAreas(MapAreasCollection areaItems)1515         internal void CallOnCustomizeMapAreas(MapAreasCollection areaItems)
1516         {
1517             this.OnCustomizeMapAreas(new CustomizeMapAreasEventArgs(areaItems));
1518         }
1519 
1520         /// <summary>
1521         /// Fires when all chart data is prepared to be customized before drawing.
1522         /// </summary>
1523         /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
1524 		[
1525 		SRDescription("DescriptionAttributeChart_OnCustomize")
1526 		]
1527         [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
OnCustomize(EventArgs e)1528         protected virtual void OnCustomize(EventArgs e)
1529 		{
1530             EventHandler customizeEventDelegate = (EventHandler)Events[_customizeEvent];
1531             if (customizeEventDelegate != null)
1532             {
1533                 customizeEventDelegate(this, e);
1534             }
1535 		}
1536 
1537 		/// <summary>
1538 		/// Fires when all chart legend data is prepared to be customized before drawing.
1539 		/// </summary>
1540 		[
1541 		SRDescription("DescriptionAttributeChart_OnCustomizeLegend")
1542 		]
1543         [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
OnCustomizeLegend(CustomizeLegendEventArgs e)1544         protected virtual void OnCustomizeLegend(CustomizeLegendEventArgs e)
1545 		{
1546             EventHandler<CustomizeLegendEventArgs> customizeLegendEventDelegate = (EventHandler<CustomizeLegendEventArgs>)Events[_customizeLegendEvent];
1547             if (customizeLegendEventDelegate != null)
1548             {
1549                 customizeLegendEventDelegate(this, e);
1550             }
1551 		}
1552 
1553 		/// <summary>
1554 		/// Event firing helper function.
1555 		/// </summary>
CallOnCustomize()1556 		internal void CallOnCustomize()
1557 		{
1558             OnCustomize(EventArgs.Empty);
1559 		}
1560 
1561 		/// <summary>
1562 		/// Event firing helper function.
1563 		/// </summary>
CallOnCustomizeLegend(LegendItemsCollection legendItems, string legendName)1564 		internal void CallOnCustomizeLegend(LegendItemsCollection legendItems, string legendName)
1565 		{
1566             OnCustomizeLegend(new CustomizeLegendEventArgs(legendItems, legendName));
1567 		}
1568 
1569 		#endregion
1570 
1571 		#region View state properties and methods
1572 
1573 
1574 		/// <summary>
1575 		/// Restores view-state information from a previous page request that was saved by the SaveViewState method.
1576 		/// </summary>
1577 		/// <param name="savedState">An Object that represents the control state to be restored.</param>
LoadViewState(object savedState)1578 		protected override void LoadViewState(object savedState)
1579 		{
1580             // Call the base class
1581             base.LoadViewState(savedState);
1582 
1583 			// Check if view state is enabled
1584 			if(this.EnableViewState)
1585 			{
1586 
1587                 // Load chart's data if custom user state data was not set
1588 				if(this.ViewState["ViewStateData"] != null &&
1589 					(this.ViewState["CustomUserViewStateData"] == null ||
1590 					((string)this.ViewState["CustomUserViewStateData"]) == "false"))
1591 				{
1592 					// Set serializable content
1593 					SerializationContents  oldContent = this.Serializer.Content;
1594 					string oldSerializable = this.Serializer.SerializableContent;
1595 					string oldNonSerializable = this.Serializer.NonSerializableContent;
1596 					SerializationFormat oldFormat = this.Serializer.Format;
1597 					this.Serializer.Content = this.ViewStateContent;
1598 					this.Serializer.Format = SerializationFormat.Xml;
1599 
1600 					// Load data in the chart from the view state
1601 					StringReader stringReader = new StringReader((string)this.ViewState["ViewStateData"]);
1602 
1603 					this.Serializer.Load(stringReader);
1604 
1605 					// Remove chart data from view state
1606 					this.ViewState.Remove("ViewStateData");
1607 
1608 					// Restore serializable content
1609 					this.Serializer.Format = oldFormat;
1610 					this.Serializer.Content = oldContent;
1611 					this.Serializer.SerializableContent = oldSerializable;
1612 					this.Serializer.NonSerializableContent = oldNonSerializable;
1613 				}
1614 			}
1615 		}
1616 
1617 		/// <summary>
1618 		/// Saves any server control view-state changes that have occurred since the time the page was posted back to the server.
1619 		/// </summary>
1620 		/// <returns>Returns the server control's current view state. </returns>
SaveViewState()1621 		protected override object SaveViewState()
1622 		{
1623             // Check if view state is enabled
1624 			if(base.EnableViewState)
1625 			{
1626 				// Save chart's data if custom user state data was not set
1627 				if(this.ViewState["ViewStateData"] == null)
1628 				{
1629 					// Set serializable content
1630 					SerializationContents  oldContent = this.Serializer.Content;
1631 					string oldSerializable = this.Serializer.SerializableContent;
1632 					string oldNonSerializable = this.Serializer.NonSerializableContent;
1633 					this.Serializer.Content = this.ViewStateContent;
1634 
1635 					// Save data from the chart into the view state
1636 					StringBuilder stringBuilder = new StringBuilder();
1637 					StringWriter stringWriter = new StringWriter(stringBuilder, CultureInfo.InvariantCulture);
1638 					this.Serializer.Save(stringWriter);
1639 
1640 					// Put data in view state
1641 					this.ViewState["ViewStateData"] = (string)stringBuilder.ToString();
1642 
1643 					// Remove chart user custom view state flag
1644 					this.ViewState.Remove("CustomUserViewStateData");
1645 
1646 					// Restore serializable content
1647 					this.Serializer.Content = oldContent;
1648 					this.Serializer.SerializableContent = oldSerializable;
1649 					this.Serializer.NonSerializableContent = oldNonSerializable;
1650 				}
1651                 // Call base class
1652             }
1653             return base.SaveViewState();
1654 		}
1655 
1656 
1657 
1658 		/// <summary>
1659 		/// Gets or sets a value indicating whether the control persists its view state.
1660 		/// </summary>
1661 		[
1662 		SRCategory("CategoryAttributeViewState"),
1663 		Bindable(true),
1664 		SRDescription("DescriptionAttributeChart_EnableViewState"),
1665 		PersistenceModeAttribute(PersistenceMode.Attribute),
1666 		DefaultValue(false)
1667 		]
1668 		public override bool EnableViewState
1669 		{
1670 			get
1671 			{
1672                 return base.EnableViewState;
1673 			}
1674 			set
1675 			{
1676 				base.EnableViewState = value;
1677 			}
1678 		}
1679 
1680 
1681 
1682 		/// <summary>
1683 		/// Chart content saved in the view state.
1684 		/// </summary>
1685 		[
1686 		SRCategory("CategoryAttributeBehavior"),
1687 		Bindable(true),
1688 		DefaultValue(typeof(SerializationContents ), "Default"),
1689 		SRDescription("DescriptionAttributeChart_ViewStateContent"),
1690         Editor(Editors.FlagsEnumUITypeEditor.Editor, Editors.FlagsEnumUITypeEditor.Base)
1691 		]
1692 		public SerializationContents  ViewStateContent
1693 		{
1694 			get
1695 			{
1696 				return _viewStateContent;
1697 			}
1698 			set
1699 			{
1700                 int result = 0;
1701                 if (Int32.TryParse(value.ToString(), out result))
1702                 {
1703                     throw new ArgumentException(SR.ExceptionEnumInvalid(value.ToString()));
1704                 }
1705                 _viewStateContent = value;
1706 			}
1707 		}
1708 
1709 		/// <summary>
1710 		/// User defined control state data in XML format.
1711 		/// </summary>
1712 		[
1713 		SRCategory("CategoryAttributeViewState"),
1714         Browsable(false),
1715         Obsolete("ViewStateData has been deprecated. Please investigate Control.ViewState instead."),
1716 		Bindable(true),
1717 		DefaultValue(""),
1718 		SRDescription("DescriptionAttributeChart_ViewStateData"),
1719 		DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
1720 		SerializationVisibilityAttribute(SerializationVisibility.Hidden),
1721         EditorBrowsable(EditorBrowsableState.Never)
1722 		]
1723 		public string ViewStateData
1724 		{
1725 			get
1726 			{
1727 				return (string)this.ViewState["ViewStateData"];
1728 			}
1729 			set
1730 			{
1731 				// Set state data
1732 				this.ViewState["ViewStateData"] = value;
1733 
1734 				// Set custom user state data indicator
1735 				this.ViewState["CustomUserViewStateData"] = "true";
1736 			}
1737 		}
1738 
1739 
1740 		#endregion
1741 
1742 		#region Control properties
1743 
1744 
1745 
1746 		/// <summary>
1747 		/// Indicates that non-critical chart exceptions will be suppressed.
1748 		/// </summary>
1749 		[
1750 		SRCategory("CategoryAttributeMisc"),
1751 		DefaultValue(false),
1752 		SRDescription("DescriptionAttributeSuppressExceptions"),
1753 		]
1754 		public bool SuppressExceptions
1755 		{
1756 			set
1757 			{
1758 				this.chartPicture.SuppressExceptions = value;
1759 			}
1760 			get
1761 			{
1762 				return this.chartPicture.SuppressExceptions;
1763 			}
1764 		}
1765 
1766 
1767 
1768 		/// <summary>
1769 		/// Chart named images collection.
1770 		/// </summary>
1771 		[
1772 		SRCategory("CategoryAttributeChart"),
1773 		Bindable(false),
1774 		SRDescription("DescriptionAttributeChart_Images"),
1775 		Browsable(false),
1776 		DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
1777         , EditorBrowsable(EditorBrowsableState.Never)
1778 		]
1779 		public NamedImagesCollection Images
1780 		{
1781 			get
1782 			{
1783 				return _namedImages;
1784 			}
1785 		}
1786 
1787         /// <summary>
1788 		/// Font property is not used.
1789 		/// </summary>
1790 		[
1791 		Browsable(false),
1792 		DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
1793 		SerializationVisibilityAttribute(SerializationVisibility.Hidden)
1794 		]
1795 		public override FontInfo Font
1796 		{
1797 			get
1798 			{
1799 				return base.Font;
1800 			}
1801 		}
1802 
1803         /// <summary>
1804 		/// Chart rendering type. Image tag, input tag, binary data streaming and image map are the options.
1805 		/// </summary>
1806 		[
1807 		SRCategory("CategoryAttributeImage"),
1808 		Bindable(true),
1809 		SRDescription("DescriptionAttributeChart_RenderType"),
1810 		PersistenceModeAttribute(PersistenceMode.Attribute),
1811 		DefaultValue(RenderType.ImageTag)
1812 		]
1813 		public RenderType RenderType
1814 		{
1815 			get
1816 			{
1817 				return _renderType;
1818 			}
1819 			set
1820 			{
1821 				_renderType = value;
1822 
1823 				if(_renderType == RenderType.ImageMap && this.IsMapEnabled == false)
1824 				{
1825 					this.IsMapEnabled = true;
1826 				}
1827 			}
1828 		}
1829 
1830 
1831 
1832         /// <summary>
1833 		/// Location where chart image is saved, when image tag is used for rendering.
1834 		/// </summary>
1835 		[
1836 		SRCategory("CategoryAttributeImage"),
1837 		Bindable(true),
1838 		SRDescription("DescriptionAttributeChart_ImageUrl"),
1839 		PersistenceModeAttribute(PersistenceMode.Attribute),
1840 		DefaultValue("ChartPic_#SEQ(300,3)"),
1841         Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base)
1842 		]
1843         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")]
1844 		public string ImageLocation
1845 		{
1846 			get
1847 			{
1848 				return _chartImageLocation;
1849 			}
1850 			set
1851 			{
1852 				// Find the begginning of the "#SEQ" formatting string
1853 				int indexSEQ = value.IndexOf("#SEQ", StringComparison.Ordinal);
1854 				if(indexSEQ > 0)
1855 				{
1856 					// Check format
1857 					CheckImageURLSeqFormat(value);
1858 				}
1859 				_chartImageLocation = value;
1860 			}
1861 		}
1862 
1863         // VSTS 96787-Text Direction (RTL/LTR)
1864 
1865         /// <summary>
1866         /// Indicates whether the control should draw right-to-left for RTL languages.
1867         /// <seealso cref="AntiAliasing"/>
1868         /// </summary>
1869         /// <value>
1870         /// One of the <see cref="System.Windows.Forms.RightToLeft"/> values. The default is
1871         /// <b>RightToLeft.No</b>.
1872         /// </value>
1873         /// <remarks>This property affects the direction of legend color keys.</remarks>
1874         [
1875         Category("Appearance"),
1876         SRDescription("DescriptionAttributeRightToLeft"),
1877         PersistenceMode(PersistenceMode.Attribute),
1878         DefaultValue(RightToLeft.No)
1879         ]
1880         public RightToLeft RightToLeft
1881         {
1882             get
1883             {
1884                 return this.chartPicture.RightToLeft;
1885             }
1886             set
1887             {
1888                 this.chartPicture.RightToLeft = value;
1889             }
1890         }
1891 
1892 		#endregion
1893 
1894 		#region Data Manager Properties
1895 
1896 		/// <summary>
1897 		/// Chart series collection.
1898 		/// </summary>
1899 		[
1900         SRCategory("CategoryAttributeChart"),
1901 		SRDescription("DescriptionAttributeChart_Series"),
1902 		PersistenceModeAttribute(PersistenceMode.InnerProperty),
1903         Editor(Editors.SeriesCollectionEditor.Editor, Editors.SeriesCollectionEditor.Base),
1904 #if !Microsoft_CONTROL
1905         Themeable(false)
1906 #endif
1907 		]
1908 		public SeriesCollection Series
1909 		{
1910 			get
1911 			{
1912 				return _dataManager.Series;
1913 			}
1914 		}
1915 
1916 		/// <summary>
1917 		/// Color palette to use
1918 		/// </summary>
1919 		[
1920 		SRCategory("CategoryAttributeAppearance"),
1921 		Bindable(true),
1922 		SRDescription("DescriptionAttributePalette"),
1923 		PersistenceModeAttribute(PersistenceMode.Attribute),
1924         DefaultValue(ChartColorPalette.BrightPastel),
1925         Editor(Editors.ColorPaletteEditor.Editor, Editors.ColorPaletteEditor.Base)
1926 		]
1927 		public ChartColorPalette Palette
1928 		{
1929 			get
1930 			{
1931 				return _dataManager.Palette;
1932 			}
1933 			set
1934 			{
1935 				_dataManager.Palette = value;
1936 			}
1937 		}
1938 
1939 
1940 
1941 		/// <summary>
1942 		/// Array of custom palette colors.
1943 		/// </summary>
1944 		/// <remarks>
1945 		/// When this custom colors array is non-empty the <b>Palette</b> property is ignored.
1946 		/// </remarks>
1947 		[
1948 		SRCategory("CategoryAttributeAppearance"),
1949 		SerializationVisibilityAttribute(SerializationVisibility.Attribute),
1950 		SRDescription("DescriptionAttributeChart_PaletteCustomColors"),
1951 		TypeConverter(typeof(ColorArrayConverter))
1952 		]
1953         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
1954 		public Color[] PaletteCustomColors
1955 		{
1956 			set
1957 			{
1958 				this._dataManager.PaletteCustomColors = value;
1959 			}
1960 			get
1961 			{
1962 				return this._dataManager.PaletteCustomColors;
1963 			}
1964 		}
1965 
1966 		/// <summary>
1967 		/// Method resets custom colors array. Internal use only.
1968 		/// </summary>
1969 		[EditorBrowsable(EditorBrowsableState.Never)]
ResetPaletteCustomColors()1970 		internal void ResetPaletteCustomColors()
1971 		{
1972 			this.PaletteCustomColors = new Color[0];
1973 		}
1974 
1975 		/// <summary>
1976 		/// Method resets custom colors array. Internal use only.
1977 		/// </summary>
1978 		[EditorBrowsable(EditorBrowsableState.Never)]
ShouldSerializePaletteCustomColors()1979         internal bool ShouldSerializePaletteCustomColors()
1980 		{
1981 			if(this.PaletteCustomColors == null ||
1982 				this.PaletteCustomColors.Length == 0)
1983 			{
1984 				return false;
1985 			}
1986 			return true;
1987 		}
1988 
1989 
1990 
1991 		#endregion
1992 
1993 		#region Chart Properties
1994 
1995 
1996 		/// <summary>
1997 		/// "The data source used to populate series data. Series ValueMember properties must be also set."
1998 		/// </summary>
1999 		[
2000 		SRCategory("CategoryAttributeData"),
2001 		Bindable(true),
2002 		SRDescription("DescriptionAttributeDataSource"),
2003 		PersistenceModeAttribute(PersistenceMode.Attribute),
2004 		DefaultValue(null),
2005 		TypeConverter(typeof(ChartDataSourceConverter)),
2006 		DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
2007 		SerializationVisibilityAttribute(SerializationVisibility.Hidden)
2008 		]
2009 		public override object DataSource
2010 		{
2011 			get
2012 			{
2013 				return base.DataSource;
2014 			}
2015 			set
2016 			{
2017                 base.DataSource = value;
2018 				chartPicture.DataSource = value;
2019 			}
2020 		}
2021 
2022 		/// <summary>
2023 		/// Build number of the control
2024 		/// </summary>
2025 		[
2026 		SRDescription("DescriptionAttributeChart_BuildNumber"),
2027 		Browsable(false),
2028 		EditorBrowsable(EditorBrowsableState.Never),
2029 		DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
2030 		DefaultValue("")
2031 		]
2032 		public string BuildNumber
2033 		{
2034 			get
2035 			{
2036 				// Get build number from the assembly
2037 				string	buildNumber = String.Empty;
2038 				Assembly assembly = Assembly.GetExecutingAssembly();
2039 				if(assembly != null)
2040 				{
2041 					buildNumber = assembly.FullName.ToUpper(CultureInfo.InvariantCulture);
2042 					int	versionIndex = buildNumber.IndexOf("VERSION=", StringComparison.Ordinal);
2043 					if(versionIndex >= 0)
2044 					{
2045 						buildNumber = buildNumber.Substring(versionIndex + 8);
2046 					}
2047                     versionIndex = buildNumber.IndexOf(",", StringComparison.Ordinal);
2048 					if(versionIndex >= 0)
2049 					{
2050 						buildNumber = buildNumber.Substring(0, versionIndex);
2051 					}
2052 				}
2053 				return buildNumber;
2054 			}
2055 		}
2056 
2057 		/// <summary>
2058 		/// Chart serializer object.
2059 		/// </summary>
2060 		[
2061 		SRCategory("CategoryAttributeSerializer"),
2062 		SRDescription("DescriptionAttributeChart_Serializer"),
2063 		Browsable(false),
2064 		DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
2065 		SerializationVisibilityAttribute(SerializationVisibility.Hidden)
2066 		]
2067 		public ChartSerializer Serializer
2068 		{
2069 			get
2070 			{
2071 				return _chartSerializer;
2072 			}
2073 		}
2074 
2075 
2076 
2077 		/// <summary>
2078 		/// Image type (Jpeg, BMP, Png, Svg, Flash)
2079 		/// </summary>
2080 		[
2081 		SRCategory("CategoryAttributeImage"),
2082 		Bindable(true),
2083 		DefaultValue(ChartImageType.Png),
2084 		SRDescription("DescriptionAttributeChartImageType"),
2085         PersistenceMode(PersistenceMode.Attribute),
2086 		RefreshProperties(RefreshProperties.All)
2087 		]
2088 		public ChartImageType ImageType
2089 		{
2090 			get
2091 			{
2092 				return chartPicture.ImageType;
2093 			}
2094 			set
2095 			{
2096 				chartPicture.ImageType = value;
2097 			}
2098 		}
2099 
2100 		/// <summary>
2101 		/// Image compression value
2102 		/// </summary>
2103 		[
2104 		SRCategory("CategoryAttributeImage"),
2105 		Bindable(true),
2106 		DefaultValue(0),
2107 		SRDescription("DescriptionAttributeChart_Compression"),
2108 		PersistenceMode(PersistenceMode.Attribute)
2109 		]
2110 		public int Compression
2111 		{
2112 			get
2113 			{
2114 				return chartPicture.Compression;
2115 			}
2116 			set
2117 			{
2118 				chartPicture.Compression = value;
2119 			}
2120 		}
2121 
2122         /*
2123          * Disabled until we get responce from Microsoft
2124          *  --- Alex
2125          *
2126                 /// <summary>
2127                 /// Gif image transparent color
2128                 /// </summary>
2129                 [
2130                 SRCategory("CategoryAttributeImage"),
2131                 Bindable(true),
2132                 DefaultValue(typeof(Color), ""),
2133                 Description("Gif image transparent color."),
2134                 PersistenceMode(PersistenceMode.Attribute),
2135                 TypeConverter(typeof(ColorConverter)),
2136                 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
2137                 ]
2138                 public Color TransparentColor
2139                 {
2140                     get
2141                     {
2142                         return chartPicture.TransparentColor;
2143                     }
2144                     set
2145                     {
2146                         chartPicture.TransparentColor = value;
2147                     }
2148                 }
2149         */
2150         #endregion
2151 
2152         #region Chart Image Properties
2153 
2154         /// <summary>
2155         /// Indicates that chart image map is enabled.
2156         /// </summary>
2157         [
2158         SRCategory("CategoryAttributeMap"),
2159         Bindable(true),
2160         SRDescription(SR.Keys.DescriptionAttributeIsMapAreaAttributesEncoded),
2161         PersistenceModeAttribute(PersistenceMode.Attribute),
2162         DefaultValue(false)
2163         ]
2164         public bool IsMapAreaAttributesEncoded { get; set; }
2165 
2166 
2167         /// <summary>
2168 		/// Indicates that chart image map is enabled.
2169 		/// </summary>
2170 		[
2171 		SRCategory("CategoryAttributeMap"),
2172 		Bindable(true),
2173 		SRDescription("DescriptionAttributeMapEnabled"),
2174 		PersistenceModeAttribute(PersistenceMode.Attribute),
2175 		DefaultValue(true)
2176 		]
2177 		public bool IsMapEnabled
2178 		{
2179 			get
2180 			{
2181 				return chartPicture.IsMapEnabled;
2182 			}
2183 			set
2184 			{
2185 				chartPicture.IsMapEnabled = value;
2186 			}
2187 		}
2188 
2189 		/// <summary>
2190 		/// Chart map areas collection.
2191 		/// </summary>
2192 		[
2193         SRCategory("CategoryAttributeMap"),
2194 		SRDescription("DescriptionAttributeMapAreas"),
2195 		PersistenceModeAttribute(PersistenceMode.InnerProperty),
2196         Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base)
2197 		]
2198 		public MapAreasCollection MapAreas
2199 		{
2200 			get
2201 			{
2202 				return chartPicture.MapAreas;
2203 			}
2204 		}
2205 
2206 		/// <summary>
2207 		/// Specifies whether smoothing (antialiasing) is applied while drawing chart.
2208 		/// </summary>
2209 		[
2210 		SRCategory("CategoryAttributeImage"),
2211 		Bindable(true),
2212         DefaultValue(typeof(AntiAliasingStyles), "All"),
2213 		SRDescription("DescriptionAttributeAntiAlias"),
2214 		PersistenceMode(PersistenceMode.Attribute),
2215 		Editor(Editors.FlagsEnumUITypeEditor.Editor, Editors.FlagsEnumUITypeEditor.Base)
2216 		]
2217         public AntiAliasingStyles AntiAliasing
2218 		{
2219 			get
2220 			{
2221 				return chartPicture.AntiAliasing;
2222 			}
2223 			set
2224 			{
2225 				chartPicture.AntiAliasing = value;
2226 			}
2227 		}
2228 
2229 		/// <summary>
2230 		/// Specifies the quality of text antialiasing.
2231 		/// </summary>
2232 		[
2233 		SRCategory("CategoryAttributeImage"),
2234 		Bindable(true),
2235 		DefaultValue(typeof(TextAntiAliasingQuality), "High"),
2236 		SRDescription("DescriptionAttributeTextAntiAliasingQuality"),
2237 #if !Microsoft_CONTROL
2238 		PersistenceMode(PersistenceMode.Attribute)
2239 #endif
2240 		]
2241 		public TextAntiAliasingQuality TextAntiAliasingQuality
2242 		{
2243 			get
2244 			{
2245 				return chartPicture.TextAntiAliasingQuality;
2246 			}
2247 			set
2248 			{
2249 				chartPicture.TextAntiAliasingQuality = value;
2250 			}
2251 		}
2252 
2253 		/// <summary>
2254 		/// Specifies whether smoothing is applied while drawing shadows.
2255 		/// </summary>
2256 		[
2257 		SRCategory("CategoryAttributeImage"),
2258 		Bindable(true),
2259 		DefaultValue(true),
2260 		SRDescription("DescriptionAttributeChart_SoftShadows"),
2261 		PersistenceMode(PersistenceMode.Attribute)
2262 		]
2263 		public bool IsSoftShadows
2264 		{
2265 			get
2266 			{
2267 				return chartPicture.IsSoftShadows;
2268 			}
2269 			set
2270 			{
2271 				chartPicture.IsSoftShadows = value;
2272 			}
2273 		}
2274 
2275 		/// <summary>
2276 		/// Reference to chart area collection
2277 		/// </summary>
2278 		[
2279 		SRCategory("CategoryAttributeChart"),
2280 		Bindable(true),
2281 		SRDescription("DescriptionAttributeChartAreas"),
2282 		PersistenceMode(PersistenceMode.InnerProperty),
2283 		Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base)
2284 		]
2285 		public ChartAreaCollection ChartAreas
2286 		{
2287 			get
2288 			{
2289 				return chartPicture.ChartAreas;
2290 			}
2291 		}
2292 
2293 		/// <summary>
2294 		/// Back ground color for the Chart
2295 		/// </summary>
2296 		[
2297 		SRCategory("CategoryAttributeAppearance"),
2298 		Bindable(true),
2299 		DefaultValue(typeof(Color), "White"),
2300         SRDescription("DescriptionAttributeBackColor"),
2301 		PersistenceMode(PersistenceMode.Attribute),
2302         TypeConverter(typeof(ColorConverter)),
2303         Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
2304 		]
2305 		public override Color BackColor
2306 		{
2307 			get
2308 			{
2309 				return chartPicture.BackColor;
2310 			}
2311 			set
2312 			{
2313 				chartPicture.BackColor = value;
2314 			}
2315 		}
2316 
2317 		/// <summary>
2318 		/// Fore color propery (not used)
2319 		/// </summary>
2320 		[
2321 		SRCategory("CategoryAttributeAppearance"),
2322 		Bindable(false),
2323 		Browsable(false),
2324 		DefaultValue(typeof(Color), ""),
2325 		SRDescription("DescriptionAttributeChart_ForeColor"),
2326 		PersistenceMode(PersistenceMode.Attribute),
2327         TypeConverter(typeof(ColorConverter)),
2328         Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
2329 		]
2330 		public override Color ForeColor
2331 		{
2332 			get
2333 			{
2334 				return Color.Empty;
2335 			}
2336 			set
2337 			{
2338 			}
2339 		}
2340 
2341 		/// <summary>
2342 		/// Chart width
2343 		/// </summary>
2344 		[
2345 		SRCategory("CategoryAttributeImage"),
2346 		Bindable(true),
2347 		DefaultValue(typeof(Unit), "300"),
2348 		SRDescription("DescriptionAttributeWidth"),
2349 		PersistenceMode(PersistenceMode.Attribute)
2350 		]
2351 		public override Unit Width
2352 		{
2353 			get
2354 			{
2355 				return new Unit(chartPicture.Width);
2356 			}
2357 			set
2358 			{
2359 				if(value.Type != UnitType.Pixel)
2360 				{
2361                     throw (new ArgumentException(SR.ExceptionChartWidthIsNotInPixels));
2362 				}
2363 				chartPicture.Width = (int)value.Value;
2364 			}
2365 		}
2366 
2367 		/// <summary>
2368 		/// Chart legend collection.
2369 		/// </summary>
2370 		[
2371 		SRCategory("CategoryAttributeChart"),
2372 		SRDescription("DescriptionAttributeLegends"),
2373 		PersistenceMode(PersistenceMode.InnerProperty),
2374 		Editor(Editors.LegendCollectionEditor.Editor, Editors.LegendCollectionEditor.Base),
2375 		]
2376 		public LegendCollection Legends
2377 		{
2378 			get
2379 			{
2380 				return chartPicture.Legends;
2381 			}
2382 		}
2383 
2384 		/// <summary>
2385 		/// Chart title collection.
2386 		/// </summary>
2387 		[
2388 		SRCategory("CategoryAttributeChart"),
2389 		SRDescription("DescriptionAttributeTitles"),
2390         Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base),
2391 		PersistenceMode(PersistenceMode.InnerProperty),
2392 		]
2393 		public TitleCollection Titles
2394 		{
2395 			get
2396 			{
2397 				return chartPicture.Titles;
2398 			}
2399 		}
2400 
2401 
2402 		/// <summary>
2403 		/// Chart annotation collection.
2404 		/// </summary>
2405 		[
2406 		SRCategory("CategoryAttributeChart"),
2407 		SRDescription("DescriptionAttributeAnnotations3"),
2408 		Editor(Editors.AnnotationCollectionEditor.Editor, Editors.AnnotationCollectionEditor.Base),
2409 		PersistenceMode(PersistenceMode.InnerProperty),
2410 		]
2411 		public AnnotationCollection Annotations
2412 		{
2413 			get
2414 			{
2415 				return chartPicture.Annotations;
2416 			}
2417 		}
2418 
2419 
2420 		/// <summary>
2421 		/// Series data manipulator
2422 		/// </summary>
2423 		[
2424 		SRCategory("CategoryAttributeData"),
2425 		SRDescription("DescriptionAttributeDataManipulator"),
2426 		Browsable(false),
2427 		DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
2428 		SerializationVisibilityAttribute(SerializationVisibility.Hidden)
2429 		]
2430 		public DataManipulator DataManipulator
2431 		{
2432 			get
2433 			{
2434 				return chartPicture.DataManipulator;
2435 			}
2436 		}
2437 
2438 
2439 		/// <summary>
2440 		/// Chart height
2441 		/// </summary>
2442 		[
2443 		SRCategory("CategoryAttributeImage"),
2444 		Bindable(true),
2445 		DefaultValue(typeof(Unit), "300"),
2446 		SRDescription("DescriptionAttributeHeight3"),
2447 		PersistenceMode(PersistenceMode.Attribute)
2448 		]
2449 		public override Unit Height
2450 		{
2451 			get
2452 			{
2453 				return new Unit(chartPicture.Height);
2454 			}
2455 			set
2456 			{
2457 				if(value.Type != UnitType.Pixel)
2458 				{
2459                     throw (new ArgumentException(SR.ExceptionChartHeightIsNotInPixels));
2460 				}
2461 				chartPicture.Height = (int)value.Value;
2462 			}
2463 		}
2464 
2465 
2466 		/// <summary>
2467 		/// Back Hatch style
2468 		/// </summary>
2469 		[
2470 		SRCategory("CategoryAttributeAppearance"),
2471 		Bindable(true),
2472 		DefaultValue(ChartHatchStyle.None),
2473         SRDescription("DescriptionAttributeBackHatchStyle"),
2474 		PersistenceMode(PersistenceMode.Attribute),
2475 		Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base)
2476 		]
2477 		public ChartHatchStyle BackHatchStyle
2478 		{
2479 			get
2480 			{
2481 				return chartPicture.BackHatchStyle;
2482 			}
2483 			set
2484 			{
2485 				chartPicture.BackHatchStyle = value;
2486 			}
2487 		}
2488 
2489 		/// <summary>
2490 		/// Chart area background image
2491 		/// </summary>
2492 		[
2493 		SRCategory("CategoryAttributeAppearance"),
2494 		Bindable(true),
2495 		DefaultValue(""),
2496         SRDescription("DescriptionAttributeBackImage"),
2497 		PersistenceMode(PersistenceMode.Attribute),
2498 		NotifyParentPropertyAttribute(true),
2499         Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base)
2500 		]
2501 		public string BackImage
2502 		{
2503 			get
2504 			{
2505 				return chartPicture.BackImage;
2506 			}
2507 			set
2508 			{
2509 				chartPicture.BackImage = value;
2510 			}
2511 		}
2512 
2513 		/// <summary>
2514 		/// Chart area background image drawing mode.
2515 		/// </summary>
2516 		[
2517 		SRCategory("CategoryAttributeAppearance"),
2518 		Bindable(true),
2519 		DefaultValue(ChartImageWrapMode.Tile),
2520 		NotifyParentPropertyAttribute(true),
2521         SRDescription("DescriptionAttributeImageWrapMode"),
2522 		PersistenceMode(PersistenceMode.Attribute)
2523 		]
2524 		public ChartImageWrapMode BackImageWrapMode
2525 		{
2526 			get
2527 			{
2528 				return chartPicture.BackImageWrapMode;
2529 			}
2530 			set
2531 			{
2532 				chartPicture.BackImageWrapMode = value;
2533 			}
2534 		}
2535 
2536 		/// <summary>
2537 		/// Background image transparent color.
2538 		/// </summary>
2539 		[
2540 		SRCategory("CategoryAttributeAppearance"),
2541 		Bindable(true),
2542 		DefaultValue(typeof(Color), ""),
2543 		NotifyParentPropertyAttribute(true),
2544         SRDescription("DescriptionAttributeImageTransparentColor"),
2545 		PersistenceMode(PersistenceMode.Attribute),
2546         TypeConverter(typeof(ColorConverter)),
2547         Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
2548 		]
2549 		public Color BackImageTransparentColor
2550 		{
2551 			get
2552 			{
2553 				return chartPicture.BackImageTransparentColor;
2554 			}
2555 			set
2556 			{
2557 				chartPicture.BackImageTransparentColor = value;
2558 			}
2559 		}
2560 
2561 		/// <summary>
2562 		/// Background image alignment used by ClampUnscale drawing mode.
2563 		/// </summary>
2564 		[
2565 		SRCategory("CategoryAttributeAppearance"),
2566 		Bindable(true),
2567 		DefaultValue(ChartImageAlignmentStyle.TopLeft),
2568 		NotifyParentPropertyAttribute(true),
2569         SRDescription("DescriptionAttributeBackImageAlign"),
2570 		PersistenceMode(PersistenceMode.Attribute)
2571 		]
2572 		public ChartImageAlignmentStyle BackImageAlignment
2573 		{
2574 			get
2575 			{
2576 				return chartPicture.BackImageAlignment;
2577 			}
2578 			set
2579 			{
2580 				chartPicture.BackImageAlignment = value;
2581 			}
2582 		}
2583 
2584 		/// <summary>
2585 		/// A type for the background gradient
2586 		/// </summary>
2587 		[
2588 		SRCategory("CategoryAttributeAppearance"),
2589 		Bindable(true),
2590 		DefaultValue(GradientStyle.None),
2591         SRDescription("DescriptionAttributeBackGradientStyle"),
2592 		PersistenceMode(PersistenceMode.Attribute),
2593 		Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base)
2594 		]
2595 		public GradientStyle BackGradientStyle
2596 		{
2597 			get
2598 			{
2599 				return chartPicture.BackGradientStyle;
2600 			}
2601 			set
2602 			{
2603 				chartPicture.BackGradientStyle = value;
2604 			}
2605 		}
2606 
2607 		/// <summary>
2608 		/// The second color which is used for a gradient
2609 		/// </summary>
2610 		[
2611 		SRCategory("CategoryAttributeAppearance"),
2612 		Bindable(true),
2613 		DefaultValue(typeof(Color), ""),
2614         SRDescription("DescriptionAttributeBackSecondaryColor"),
2615 		PersistenceMode(PersistenceMode.Attribute),
2616         TypeConverter(typeof(ColorConverter)),
2617         Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
2618 		]
2619 		public Color BackSecondaryColor
2620 		{
2621 			get
2622 			{
2623 				return chartPicture.BackSecondaryColor;
2624 			}
2625 			set
2626 			{
2627 				chartPicture.BackSecondaryColor = value;
2628 			}
2629 		}
2630 
2631 
2632         /// <summary>
2633         /// Gets or sets the border color of the Chart.
2634         /// </summary>
2635         [
2636         Browsable(false),
2637         EditorBrowsable(EditorBrowsableState.Never)
2638         ]
2639         public override Color BorderColor
2640         {
2641             get { return base.BorderColor; }
2642             set { base.BorderColor = value; }
2643         }
2644 
2645         /// <summary>
2646         /// Gets or sets the border width of the Chart.
2647         /// </summary>
2648         [
2649         Browsable(false),
2650         EditorBrowsable(EditorBrowsableState.Never)
2651         ]
2652         public override Unit  BorderWidth
2653         {
2654           get { return base.BorderWidth;}
2655           set { base.BorderWidth = value;}
2656         }
2657 
2658         /// <summary>
2659         /// Gets or sets the border style of the Chart.
2660         /// </summary>
2661         [
2662         Browsable(false),
2663         EditorBrowsable(EditorBrowsableState.Never)
2664         ]
2665         public override BorderStyle BorderStyle
2666         {
2667             get { return base.BorderStyle; }
2668             set { base.BorderStyle = value; }
2669         }
2670 
2671 
2672 		/// <summary>
2673 		/// Border line color for the Chart
2674 		/// </summary>
2675 		[
2676 		SRCategory("CategoryAttributeAppearance"),
2677 		Bindable(true),
2678 		DefaultValue(typeof(Color), "White"),
2679 		SRDescription("DescriptionAttributeBorderColor"),
2680 		PersistenceMode(PersistenceMode.Attribute),
2681         TypeConverter(typeof(ColorConverter)),
2682         Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
2683 		]
2684 		public Color BorderlineColor
2685 		{
2686 			get
2687 			{
2688 				return chartPicture.BorderColor;
2689 			}
2690 			set
2691 			{
2692 				chartPicture.BorderColor = value;
2693 			}
2694 		}
2695 
2696 		/// <summary>
2697 		/// The width of the border line
2698 		/// </summary>
2699 		[
2700         SRCategory("CategoryAttributeAppearance"),
2701 		Bindable(true),
2702 		DefaultValue(1),
2703 		SRDescription("DescriptionAttributeChart_BorderlineWidth"),
2704 		PersistenceMode(PersistenceMode.Attribute)
2705 		]
2706 		public int BorderlineWidth
2707 		{
2708 			get
2709 			{
2710 				return chartPicture.BorderWidth;
2711 			}
2712 			set
2713 			{
2714 				chartPicture.BorderWidth = value;
2715 			}
2716 		}
2717 
2718 		/// <summary>
2719 		/// The style of the border line
2720 		/// </summary>
2721 		[
2722 		SRCategory("CategoryAttributeAppearance"),
2723 		Bindable(true),
2724 		DefaultValue(ChartDashStyle.NotSet),
2725 		SRDescription("DescriptionAttributeBorderDashStyle"),
2726 		PersistenceMode(PersistenceMode.Attribute)
2727 		]
2728 		public ChartDashStyle BorderlineDashStyle
2729 		{
2730 			get
2731 			{
2732 				return chartPicture.BorderDashStyle;
2733 			}
2734 			set
2735 			{
2736 				chartPicture.BorderDashStyle = value;
2737 			}
2738 		}
2739 
2740         /// <summary>
2741 		/// Chart border skin style.
2742 		/// </summary>
2743 		[
2744 		SRCategory("CategoryAttributeAppearance"),
2745 		Bindable(true),
2746 		DefaultValue(BorderSkinStyle.None),
2747 		SRDescription("DescriptionAttributeBorderSkin"),
2748 		PersistenceMode(PersistenceMode.InnerProperty),
2749 		NotifyParentProperty(true),
2750 		TypeConverterAttribute(typeof(LegendConverter)),
2751         DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
2752 		]
2753 		public BorderSkin BorderSkin
2754 		{
2755 			get
2756 			{
2757 				return chartPicture.BorderSkin;
2758 			}
2759 			set
2760 			{
2761 				chartPicture.BorderSkin = value;
2762 			}
2763 		}
2764 
2765         /// <summary>
2766         /// When overridden in a derived class, gets or sets the alternate text displayed in the Chart control when the chart image is unavailable.
2767         /// </summary>
2768         [
2769         Bindable(true),
2770         SRDescription(SR.Keys.DescriptionAttributeChartImageAlternateText),
2771         Localizable(true),
2772         SRCategory(SR.Keys.CategoryAttributeAppearance),
2773         DefaultValue("")
2774         ]
2775         public string AlternateText { get; set; }
2776 
2777         /// <summary>
2778         /// When overridden in a derived class, gets or sets the location to a detailed description for the chart.
2779         /// </summary>
2780         [
2781         Bindable(true),
2782         SRDescription(SR.Keys.DescriptionAttributeChartImageDescriptionUrl),
2783         Localizable(true),
2784         SRCategory(SR.Keys.CategoryAttributeAccessibility),
2785         DefaultValue(""),
2786         UrlProperty,
2787         Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base),
2788         SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")
2789         ]
2790         public string DescriptionUrl { get; set; }
2791 
2792 		#endregion
2793 
2794 		#region Control public methods
2795 
2796         /// <summary>
2797         /// Creates the HTML text writer.
2798         /// </summary>
2799         /// <param name="tw">The inner text writer.</param>
2800         /// <returns></returns>
CreateHtmlTextWriter(TextWriter tw)2801         private HtmlTextWriter CreateHtmlTextWriter(TextWriter tw)
2802         {
2803             if (((this.Context != null) && (this.Context.Request != null)) && (this.Context.Request.Browser != null))
2804             {
2805                 return this.Context.Request.Browser.CreateHtmlTextWriter(tw);
2806             }
2807             return new Html32TextWriter(tw);
2808         }
2809 
2810 		/// <summary>
2811 		/// Gets HTML image map of the currently rendered chart.
2812 		/// Save(...) method MUST be called before calling this method!
2813 		/// </summary>
2814 		/// <param name="name">Name of the image map tag.</param>
2815 		/// <returns>HTML image map.</returns>
GetHtmlImageMap(string name)2816 		public string GetHtmlImageMap(string name)
2817 		{
2818             // Check arguments
2819             if (name == null)
2820                 throw new ArgumentNullException("name");
2821 
2822             using (StringWriter swriter = new StringWriter(CultureInfo.InvariantCulture))
2823             {
2824                 using (HtmlTextWriter writer = CreateHtmlTextWriter(swriter))
2825                 {
2826                     this.chartPicture.WriteChartMapTag(writer, name);
2827                     return swriter.GetStringBuilder().ToString();
2828                 }
2829             }
2830 		}
2831 
2832 
2833 		/// <summary>
2834 		/// Saves the current state of the chart to an XML file.  This is
2835 		/// mainly used for support purposes.  The executing thread must have
2836 		/// file write permission
2837 		/// </summary>
2838 		/// <param name="name">File path and name to save.</param>
SaveXml(string name)2839 		public void SaveXml(string name)
2840 		{
2841 			try
2842 			{
2843 				this.Serializer.Save(name);
2844 			}
2845 			catch(XmlException)
2846 			{ }
2847 		}
2848 
2849 
2850 		/// <summary>
2851 		/// Loads chart appearance template from file.
2852 		/// </summary>
2853 		/// <param name="name">Template file name to load from.</param>
LoadTemplate(string name)2854 		public void LoadTemplate(string name)
2855 		{
2856 			chartPicture.LoadTemplate(name);
2857 		}
2858 
2859 		/// <summary>
2860 		/// Loads chart appearance template from stream.
2861 		/// </summary>
2862 		/// <param name="stream">Template stream to load from.</param>
LoadTemplate(Stream stream)2863 		public void LoadTemplate(Stream stream)
2864 		{
2865 			chartPicture.LoadTemplate(stream);
2866 		}
2867 
2868 
2869 		/// <summary>
2870 		/// Applies palette colors to series or data points.
2871 		/// </summary>
ApplyPaletteColors()2872 		public void ApplyPaletteColors()
2873 		{
2874 			// Apply palette colors to series
2875 			this._dataManager.ApplyPaletteColors();
2876 
2877 			// Apply palette colors to data Points in series
2878 			foreach(Series series in this.Series)
2879 			{
2880 				// Check if palette colors should be aplied to the points
2881 				bool	applyToPoints = false;
2882 				if(series.Palette != ChartColorPalette.None)
2883 				{
2884 					applyToPoints = true;
2885 				}
2886 				else
2887 				{
2888 					IChartType chartType = this._chartTypeRegistry.GetChartType(series.ChartTypeName);
2889 					applyToPoints = chartType.ApplyPaletteColorsToPoints;
2890 				}
2891 
2892 				// Apply palette colors to the points
2893 				if(applyToPoints)
2894 				{
2895 					series.ApplyPaletteColors();
2896 				}
2897 			}
2898 		}
2899 
2900 		/// <summary>
2901 		/// Checks if control is in design mode.
2902 		/// </summary>
2903 		/// <returns>True if control is in design mode.</returns>
IsDesignMode()2904 		internal bool IsDesignMode()
2905 		{
2906             return this.DesignMode;
2907         }
2908 
2909 		/// <summary>
2910 		/// Reset auto calculated chart properties values to "Auto".
2911 		/// </summary>
ResetAutoValues()2912 		public void ResetAutoValues()
2913 		{
2914 			// Reset auto calculated series properties values
2915 			foreach(Series series in this.Series)
2916 			{
2917 				series.ResetAutoValues();
2918 			}
2919 
2920 			// Reset auto calculated axis properties values
2921 			foreach(ChartArea chartArea in this.ChartAreas)
2922 			{
2923 				chartArea.ResetAutoValues();
2924 			}
2925 
2926 		}
2927 
2928 		#endregion
2929 
2930 		#region Control DataBind method
2931 
2932         /// <summary>
2933         /// Verifies that the object a data-bound control binds to is one it can work with.
2934         /// </summary>
2935         /// <param name="dataSource">The object to verify</param>
ValidateDataSource(object dataSource)2936         protected override void ValidateDataSource(object dataSource)
2937         {
2938             if (!ChartImage.IsValidDataSource(dataSource))
2939             {
2940                 base.ValidateDataSource(dataSource);
2941             }
2942         }
2943 
2944         /// <summary>
2945         /// Binds the specified data source to the Chart control.
2946         /// </summary>
2947         /// <param name="data">An <see cref="IEnumerable"/> that represents the data source.</param>
PerformDataBinding(IEnumerable data)2948         protected override void PerformDataBinding(IEnumerable data)
2949         {
2950             this.chartPicture.DataBind(data, null);
2951             this.chartPicture.boundToDataSource = true;
2952         }
2953 
2954 		/// <summary>
2955 		/// Aligns data points using their axis labels.
2956 		/// </summary>
AlignDataPointsByAxisLabel()2957 		public void AlignDataPointsByAxisLabel()
2958 		{
2959 			this.chartPicture.AlignDataPointsByAxisLabel(false, PointSortOrder.Ascending);
2960 		}
2961 
2962 		/// <summary>
2963 		/// Aligns data points using their axis labels.
2964 		/// </summary>
2965 		/// <param name="series">Comma separated list of series that should be aligned by axis label.</param>
AlignDataPointsByAxisLabel(string series)2966 		public void AlignDataPointsByAxisLabel(string series)
2967 		{
2968 			// Create list of series
2969 			ArrayList seriesList = new ArrayList();
2970 			string[] seriesNames = series.Split(',');
2971 			foreach(string name in seriesNames)
2972 			{
2973 				seriesList.Add(this.Series[name.Trim()]);
2974 			}
2975 
2976 			// Align series
2977 			this.chartPicture.AlignDataPointsByAxisLabel(seriesList, false, PointSortOrder.Ascending);
2978 		}
2979 
2980 		/// <summary>
2981 		/// Aligns data points using their axis labels.
2982 		/// </summary>
2983 		/// <param name="series">Comma separated list of series that should be aligned by axis label.</param>
2984 		/// <param name="sortingOrder">Points sorting order by axis labels.</param>
AlignDataPointsByAxisLabel(string series, PointSortOrder sortingOrder)2985 		public void AlignDataPointsByAxisLabel(string series, PointSortOrder sortingOrder)
2986 		{
2987 			// Create list of series
2988 			ArrayList seriesList = new ArrayList();
2989 			string[] seriesNames = series.Split(',');
2990 			foreach(string name in seriesNames)
2991 			{
2992 				seriesList.Add(this.Series[name.Trim()]);
2993 			}
2994 
2995 			// Align series
2996 			this.chartPicture.AlignDataPointsByAxisLabel(seriesList, true, sortingOrder);
2997 		}
2998 
2999 		/// <summary>
3000 		/// Aligns data points using their axis labels.
3001 		/// </summary>
3002 		/// <param name="sortingOrder">Points sorting order by axis labels.</param>
AlignDataPointsByAxisLabel(PointSortOrder sortingOrder)3003 		public void AlignDataPointsByAxisLabel(PointSortOrder sortingOrder)
3004 		{
3005 			this.chartPicture.AlignDataPointsByAxisLabel(true, sortingOrder);
3006 		}
3007 
3008 
3009 
3010 		/// <summary>
3011 		/// Automatically creates and binds series to specified data table.
3012 		/// Each column of the table becomes a Y value in a separate series.
3013 		/// Series X value field may also be provided.
3014 		/// </summary>
3015 		/// <param name="dataSource">Data source.</param>
3016 		/// <param name="xField">Name of the field for series X values.</param>
3017         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
3018             Justification = "X is a cartesian coordinate and well understood")]
DataBindTable( IEnumerable dataSource, string xField)3019         public void DataBindTable(
3020 			IEnumerable dataSource,
3021 			string xField)
3022 		{
3023 			this.chartPicture.DataBindTable(
3024 				dataSource,
3025 				xField);
3026 		}
3027 
3028 		/// <summary>
3029 		/// Automatically creates and binds series to specified data table.
3030 		/// Each column of the table becomes a Y value in a separate series.
3031 		/// </summary>
3032 		/// <param name="dataSource">Data source.</param>
DataBindTable(IEnumerable dataSource)3033 		public void DataBindTable(IEnumerable dataSource)
3034 		{
3035 			this.chartPicture.DataBindTable(
3036 				dataSource,
3037 				String.Empty);
3038 		}
3039 
3040 		/// <summary>
3041 		/// Data bind chart to the table. Series will be automatically added to the chart depending on
3042 		/// the number of unique values in the seriesGroupByField column of the data source.
3043 		/// Data source can be the Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow.
3044 		/// </summary>
3045 		/// <param name="dataSource">Data source.</param>
3046 		/// <param name="seriesGroupByField">Name of the field used to group data into series.</param>
3047 		/// <param name="xField">Name of the field for X values.</param>
3048 		/// <param name="yFields">Comma separated name(s) of the field(s) for Y value(s).</param>
3049 		/// <param name="otherFields">Other point properties binding rule in format: PointProperty=Field[{Format}] [,PointProperty=Field[{Format}]]. For example: "Tooltip=Price{C1},Url=WebSiteName".</param>
3050         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
3051             Justification = "X and Y are cartesian coordinates and well understood")]
DataBindCrossTable( IEnumerable dataSource, string seriesGroupByField, string xField, string yFields, string otherFields)3052         public void DataBindCrossTable(
3053 			IEnumerable dataSource,
3054 			string seriesGroupByField,
3055 			string xField,
3056 			string yFields,
3057 			string otherFields)
3058 		{
3059 			this.chartPicture.DataBindCrossTab(
3060 				dataSource,
3061 				seriesGroupByField,
3062 				xField,
3063 				yFields,
3064 				otherFields,
3065 				false,
3066 				PointSortOrder.Ascending);
3067 		}
3068 
3069 		/// <summary>
3070 		/// Data bind chart to the table. Series will be automatically added to the chart depending on
3071 		/// the number of unique values in the seriesGroupByField column of the data source.
3072 		/// Data source can be the Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow.
3073 		/// </summary>
3074 		/// <param name="dataSource">Data source.</param>
3075 		/// <param name="seriesGroupByField">Name of the field used to group data into series.</param>
3076 		/// <param name="xField">Name of the field for X values.</param>
3077 		/// <param name="yFields">Comma separated name(s) of the field(s) for Y value(s).</param>
3078 		/// <param name="otherFields">Other point properties binding rule in format: PointProperty=Field[{Format}] [,PointProperty=Field[{Format}]]. For example: "Tooltip=Price{C1},Url=WebSiteName".</param>
3079 		/// <param name="sortingOrder">Series will be sorted by group field values in specified order.</param>
3080         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
3081             Justification = "X and Y are cartesian coordinates and well understood")]
DataBindCrossTable( IEnumerable dataSource, string seriesGroupByField, string xField, string yFields, string otherFields, PointSortOrder sortingOrder)3082         public void DataBindCrossTable(
3083 			IEnumerable dataSource,
3084 			string seriesGroupByField,
3085 			string xField,
3086 			string yFields,
3087 			string otherFields,
3088 			PointSortOrder sortingOrder)
3089 		{
3090 			this.chartPicture.DataBindCrossTab(
3091 				dataSource,
3092 				seriesGroupByField,
3093 				xField,
3094 				yFields,
3095 				otherFields,
3096 				true,
3097 				sortingOrder);
3098 		}
3099 
3100 
3101 		#endregion
3102 
3103 		#region Special Extension Methods and Properties
3104 
3105 		/// <summary>
3106 		/// Gets the requested chart service.
3107 		/// </summary>
3108 		/// <param name="serviceType">Type of requested chart service.</param>
3109 		/// <returns>Instance of the service or null if it can't be found.</returns>
GetService(Type serviceType)3110 		public object GetService(Type serviceType)
3111 		{
3112             // Check arguments
3113             if (serviceType == null)
3114                 throw new ArgumentNullException("serviceType");
3115 
3116 			object service = null;
3117 			if(serviceContainer != null)
3118 			{
3119 				service = serviceContainer.GetService(serviceType);
3120 			}
3121 
3122 			return service;
3123 		}
3124 
3125         /// <summary>
3126         /// Called when a numeric value has to be converted to a string.
3127         /// </summary>
3128         [SRDescription("DescriptionAttributeChartEvent_PrePaint")]
3129         public event EventHandler<FormatNumberEventArgs> FormatNumber;
3130 
3131         /// <summary>
3132         /// Called when a numeric value has to be converted to a string.
3133         /// </summary>
3134         /// <param name="caller">Event caller. Can be ChartPicture, ChartArea or Legend objects.</param>
3135         /// <param name="e">Event arguments.</param>
3136         [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "1#")]
OnFormatNumber(object caller, FormatNumberEventArgs e)3137         protected virtual void OnFormatNumber(object caller, FormatNumberEventArgs e)
3138         {
3139             if (FormatNumber != null)
3140             {
3141                 FormatNumber(caller, e);
3142             }
3143         }
3144 
3145         /// <summary>
3146         /// Called when a numeric value has to be converted to a string.
3147         /// </summary>
3148         /// <param name="caller">Event caller. Can be ChartPicture, ChartArea or Legend objects.</param>
3149         /// <param name="e">Event arguments.</param>
CallOnFormatNumber(object caller, FormatNumberEventArgs e)3150         internal void CallOnFormatNumber(object caller, FormatNumberEventArgs e)
3151         {
3152             this.OnFormatNumber(caller, e);
3153         }
3154 
3155 		#endregion
3156 
3157         #region HttpHandler Support
3158 
3159         /// <summary>
3160         /// Chart rendering type. Image tag, input tag, binary data streaming and image map are the options.
3161         /// </summary>
3162         [
3163         SRCategory("CategoryAttributeImage"),
3164         Bindable(true),
3165         SRDescription("DescriptionAttributeChart_ImageStorageMode"),
3166         PersistenceModeAttribute(PersistenceMode.Attribute),
3167         DefaultValue(ImageStorageMode.UseHttpHandler)
3168         ]
3169         public ImageStorageMode ImageStorageMode
3170         {
3171             get
3172             {
3173                 return this._imageStorageMode;
3174             }
3175             set
3176             {
3177                 this._imageStorageMode = value;
3178             }
3179         }
3180 
3181         /// <summary>
3182         /// Gets the image storage mode.
3183         /// </summary>
3184         /// <returns></returns>
GetImageStorageMode()3185         internal ImageStorageMode GetImageStorageMode()
3186         {
3187             if (this.ImageStorageMode == ImageStorageMode.UseHttpHandler)
3188             {
3189                 ChartHttpHandler.EnsureInstalled();
3190             }
3191             return this.ImageStorageMode;
3192         }
3193 
3194         #endregion //HttpHandler Support
3195 
3196         #region IPostBackEventHandler Members
3197 
IPostBackEventHandler.RaisePostBackEvent(string eventArgument)3198         void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
3199         {
3200             this.RaisePostBackEvent(eventArgument);
3201         }
3202 
3203         #endregion
3204 
3205         #region IDisposable overrides
3206         /// <summary>
3207         /// Releases unmanaged and - optionally - managed resources
3208         /// </summary>
3209         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
Dispose(bool disposing)3210         protected virtual void Dispose(bool disposing)
3211         {
3212             if (disposing)
3213             {
3214                 if (!String.IsNullOrEmpty(_designTimeChart))
3215                 {
3216                     try
3217                     {
3218                         File.Delete(_designTimeChart);
3219                     }
3220                     catch (ArgumentException) { }
3221                     catch (DirectoryNotFoundException) { }
3222                     catch (IOException) { }
3223                     catch (NotSupportedException) { }
3224                     catch (UnauthorizedAccessException) { }
3225                 }
3226 
3227                 // Dispose managed objects here
3228                 if (_imageLoader != null)
3229                 {
3230                     _imageLoader.Dispose();
3231                     _imageLoader = null;
3232                 }
3233                 if (_namedImages != null)
3234                 {
3235                     _namedImages.Dispose();
3236                     _namedImages = null;
3237                 }
3238                 if (_chartTypeRegistry != null)
3239                 {
3240                     _chartTypeRegistry.Dispose();
3241                     _chartTypeRegistry = null;
3242                 }
3243                 if (serviceContainer != null)
3244                 {
3245                     serviceContainer.Dispose();
3246                     serviceContainer = null;
3247                 }
3248                 if (_license != null)
3249                 {
3250                     _license.Dispose();
3251                     _license = null;
3252                 }
3253             }
3254             //Base dispose
3255             base.Dispose();
3256             if (disposing)
3257             {
3258                 if (_dataManager != null)
3259                 {
3260                     _dataManager.Dispose();
3261                     _dataManager = null;
3262                 }
3263                 if (chartPicture != null)
3264                 {
3265                     chartPicture.Dispose();
3266                     chartPicture = null;
3267                 }
3268             }
3269         }
3270 
3271         /// <summary>
3272         /// Disposing control resoursec
3273         /// </summary>
Dispose()3274         public override sealed void Dispose()
3275         {
3276             Dispose(true);
3277             GC.SuppressFinalize(this);
3278         }
3279 
3280         #endregion
3281 
3282     }
3283 
3284 	/// <summary>
3285 	/// Chart map areas customize events arguments
3286 	/// </summary>
3287 #if ASPPERM_35
3288     [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
3289     [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
3290 #endif
3291     public class CustomizeMapAreasEventArgs : EventArgs
3292 	{
3293 		private	MapAreasCollection	_areaItems = null;
3294 
3295 		/// <summary>
3296 		/// Default construvtor is not accessible
3297 		/// </summary>
CustomizeMapAreasEventArgs()3298 		private CustomizeMapAreasEventArgs()
3299 		{
3300 		}
3301 
3302 		/// <summary>
3303 		/// Customize map area event arguments constructor
3304 		/// </summary>
3305 		/// <param name="areaItems">Legend items collection.</param>
CustomizeMapAreasEventArgs(MapAreasCollection areaItems)3306 		public CustomizeMapAreasEventArgs(MapAreasCollection areaItems)
3307 		{
3308 			this._areaItems = areaItems;
3309 		}
3310 
3311 		/// <summary>
3312 		/// Legend items collection.
3313 		/// </summary>
3314 		public MapAreasCollection MapAreaItems
3315 		{
3316 			get
3317 			{
3318 				return _areaItems;
3319 			}
3320 		}
3321 
3322 	}
3323 
3324 
3325 
3326 	/// <summary>
3327 	/// Chart legend customize events arguments
3328 	/// </summary>
3329 #if ASPPERM_35
3330     [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
3331     [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
3332 #endif
3333     public class CustomizeLegendEventArgs : EventArgs
3334 	{
3335 		private	LegendItemsCollection	_legendItems = null;
3336 		private	string					_legendName = "";
3337 
3338 		/// <summary>
3339 		/// Default construvtor is not accessible
3340 		/// </summary>
CustomizeLegendEventArgs()3341 		private CustomizeLegendEventArgs()
3342 		{
3343 		}
3344 
3345 		/// <summary>
3346 		/// Customize legend event arguments constructor
3347 		/// </summary>
3348 		/// <param name="legendItems">Legend items collection.</param>
CustomizeLegendEventArgs(LegendItemsCollection legendItems)3349 		public CustomizeLegendEventArgs(LegendItemsCollection legendItems)
3350 		{
3351 			this._legendItems = legendItems;
3352 		}
3353 
3354 		/// <summary>
3355 		/// Customize legend event arguments constructor
3356 		/// </summary>
3357 		/// <param name="legendItems">Legend items collection.</param>
3358 		/// <param name="legendName">Legend name.</param>
CustomizeLegendEventArgs(LegendItemsCollection legendItems, string legendName)3359 		public CustomizeLegendEventArgs(LegendItemsCollection legendItems, string legendName)
3360 		{
3361 			this._legendItems = legendItems;
3362 			this._legendName = legendName;
3363 		}
3364 
3365 		/// <summary>
3366 		/// Legend name.
3367 		/// </summary>
3368 		public string LegendName
3369 		{
3370 			get
3371 			{
3372 				return _legendName;
3373 			}
3374 		}
3375 
3376 		/// <summary>
3377 		/// Legend items collection.
3378 		/// </summary>
3379 		public LegendItemsCollection LegendItems
3380 		{
3381 			get
3382 			{
3383 				return _legendItems;
3384 			}
3385 		}
3386 
3387 	}
3388 
3389     /// <summary>
3390     /// Specifies a value indicating whether the text appears from right to left, such as when using Hebrew or Arabic fonts
3391     /// </summary>
3392     public enum RightToLeft
3393     {
3394         /// <summary>
3395         /// The text reads from left to right. This is the default.
3396         /// </summary>
3397         No,
3398         /// <summary>
3399         /// The text reads from right to left.
3400         /// </summary>
3401         Yes,
3402         /// <summary>
3403         /// Not used
3404         /// </summary>
3405         [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
3406         Inherit = No
3407     }
3408 }
3409