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