Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Web.DataVisualization / Common / General / Selection.cs
blob554003cc1a98656400d2ea45d6dc9157d40d4dc0
1 //-------------------------------------------------------------
2 // <copyright company=’Microsoft Corporation’>
3 // Copyright © Microsoft Corporation. All Rights Reserved.
4 // </copyright>
5 //-------------------------------------------------------------
6 // @owner=alexgor, deliant
7 //=================================================================
8 // File: Selection.cs
9 //
10 // Namespace: DataVisualization.Charting
12 // Classes: Selection, HitTestResult, ToolTipEventArgs,
13 // HotRegionElement, Hot Region
15 // Purpose: This file contains methods used for Win Form selection
17 // Reviewed: AG - Oct 21
19 //===================================================================
22 #region Used namespaces
24 using System;
25 using System.Drawing;
26 using System.Drawing.Drawing2D;
27 using System.Collections;
28 using System.Collections.Generic;
29 using System.Globalization;
30 using System.Diagnostics.CodeAnalysis;
31 using System.ComponentModel.Design;
32 using System.ComponentModel;
33 using System.Text;
34 using System.Collections.ObjectModel;
36 #if Microsoft_CONTROL
37 using System.Windows.Forms;
38 #endif
41 #endregion
43 #if Microsoft_CONTROL
44 namespace System.Windows.Forms.DataVisualization.Charting
45 #else
46 namespace System.Web.UI.DataVisualization.Charting
47 #endif
49 #region Enumerations
52 // Plase keep the folowing enumaration in chart layering order - ex. ChartArea is under DataPoint
53 /// <summary>
54 /// An enumeration of types of Chart Element.
55 /// </summary>
56 public enum ChartElementType
58 /// <summary>
59 /// No chart element.
60 /// </summary>
61 Nothing,
63 /// <summary>
64 /// The title of a chart.
65 /// </summary>
66 Title,
68 /// <summary>
69 /// Plotting area (chart area excluding axes, labels, etc.).
70 /// Also excludes the regions that data points may occupy.
71 /// </summary>
72 PlottingArea,
74 /// <summary>
75 /// An Axis object.
76 /// </summary>
77 Axis,
79 /// <summary>
80 /// Any major or minor tick mark.
81 /// </summary>
82 TickMarks,
84 /// <summary>
85 /// Any major or minor grid line (both vertical or horizontal).
86 /// </summary>
87 Gridlines,
89 /// <summary>
90 /// A StripLine object.
91 /// </summary>
92 StripLines,
94 /// <summary>
95 /// Axis label Image.
96 /// </summary>
97 AxisLabelImage,
99 /// <summary>
100 /// Axis labels
101 /// </summary>
102 AxisLabels,
104 /// <summary>
105 /// Axis title
106 /// </summary>
107 AxisTitle,
110 #if Microsoft_CONTROL
112 /// <summary>
113 /// A scrollbar tracking thumb.
114 /// </summary>
115 ScrollBarThumbTracker,
117 /// <summary>
118 /// A scrollbar small decrement button. A "down arrow"
119 /// button for a vertical scrollbar, or a "left arrow"
120 /// button for a horizontal scroll bar.
121 /// </summary>
122 ScrollBarSmallDecrement,
124 /// <summary>
125 /// A scrollbar small increment button. An "up arrow"
126 /// button for a vertical scrollbar, or a "right arrow"
127 /// button for a horizontal scroll bar.
128 /// </summary>
129 ScrollBarSmallIncrement,
131 /// <summary>
132 /// The background of a scrollbar that will result in
133 /// a large decrement in the scale view size when clicked.
134 /// This is the background below the thumb for
135 /// a vertical scrollbar, and to the left of
136 /// the thumb for a horizontal scrollbar.
137 /// </summary>
138 ScrollBarLargeDecrement,
140 /// <summary>
141 /// The background of a scrollbar that will result in
142 /// a large increment in the scale view size when clicked.
143 /// This is the background above the thumb for
144 /// a vertical scrollbar, and to the right of
145 /// the thumb for a horizontal scrollbar.
146 /// </summary>
147 ScrollBarLargeIncrement,
149 /// <summary>
150 /// The zoom reset button of a scrollbar.
151 /// </summary>
152 ScrollBarZoomReset,
154 #endif // Microsoft_CONTROL
156 /// <summary>
157 /// A DataPoint object.
158 /// </summary>
159 DataPoint,
161 /// <summary>
162 /// Series data point label.
163 /// </summary>
164 DataPointLabel,
166 /// <summary>
167 /// The area inside a Legend object. Does not include
168 /// the space occupied by legend items.
169 /// </summary>
170 LegendArea,
172 /// <summary>
173 /// Legend title.
174 /// </summary>
175 LegendTitle,
177 /// <summary>
178 /// Legend header.
179 /// </summary>
180 LegendHeader,
182 /// <summary>
183 /// A LegendItem object.
184 /// </summary>
185 LegendItem,
188 /// <summary>
189 /// Chart annotation object.
190 /// </summary>
191 Annotation,
196 /// <summary>
197 /// Enumeration (Flag) used for processing chart types.
198 /// </summary>
199 [Flags]
200 internal enum ProcessMode
202 /// <summary>
203 /// Paint mode
204 /// </summary>
205 Paint = 1,
207 /// <summary>
208 /// Selection mode. Collection of hot regions has to be created.
209 /// </summary>
210 HotRegions = 2,
212 /// <summary>
213 /// Used for image maps
214 /// </summary>
215 ImageMaps = 4
218 #endregion
220 /// <summary>
221 /// This class presents item in
222 /// the collection of hot regions.
223 /// </summary>
224 internal class HotRegion : IDisposable
226 #region Fields
228 // Private data members, which store properties values
229 private GraphicsPath _path = null;
230 private bool _relativeCoordinates = true;
231 private RectangleF _boundingRectangle = RectangleF.Empty;
232 private object _selectedObject = null;
233 private int _pointIndex = -1;
234 private string _seriesName = "";
235 private ChartElementType _type = ChartElementType.Nothing;
238 private object _selectedSubObject = null;
241 #endregion // Fields
243 #region Properties
245 /// <summary>
246 /// Region is Graphics path
247 /// </summary>
248 internal GraphicsPath Path
252 return _path;
256 _path = value;
260 /// <summary>
261 /// Relative coordinates are used
262 /// to define region
263 /// </summary>
264 internal bool RelativeCoordinates
268 return _relativeCoordinates;
272 _relativeCoordinates = value;
276 /// <summary>
277 /// Bounding Rectangle of an shape
278 /// </summary>
279 internal RectangleF BoundingRectangle
283 return _boundingRectangle;
287 _boundingRectangle = value;
291 /// <summary>
292 /// Object which is presented with this region
293 /// </summary>
294 internal object SelectedObject
298 return _selectedObject;
302 _selectedObject = value;
308 /// <summary>
309 /// Sub-Object which is presented with this region
310 /// </summary>
311 internal object SelectedSubObject
315 return _selectedSubObject;
319 _selectedSubObject = value;
325 /// <summary>
326 /// Index of the data point which is presented with this region
327 /// </summary>
328 internal int PointIndex
332 return _pointIndex;
336 _pointIndex = value;
340 /// <summary>
341 /// Name of the series which is presented with the region
342 /// </summary>
343 internal string SeriesName
347 return _seriesName;
351 _seriesName = value;
355 /// <summary>
356 /// Chart Element AxisName
357 /// </summary>
358 internal ChartElementType Type
362 return _type;
366 _type = value;
370 #endregion // Properties
372 #region IDisposable members
373 /// <summary>
374 /// Releases unmanaged and - optionally - managed resources
375 /// </summary>
376 /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
377 protected virtual void Dispose(bool disposing)
379 if (disposing)
381 if (_path != null)
383 _path.Dispose();
384 _path = null;
389 /// <summary>
390 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
391 /// </summary>
392 public void Dispose()
394 Dispose(true);
395 GC.SuppressFinalize(this);
397 #endregion
399 #region Methods
401 /// <summary>
402 /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
403 /// </summary>
404 /// <returns>
405 /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
406 /// </returns>
407 public override string ToString()
409 string objectType = this.SelectedObject != null ? this.SelectedObject.ToString() : "null";
410 if (this.SelectedObject == null && !String.IsNullOrEmpty(this.SeriesName))
412 objectType = this.SeriesName;
414 return String.Format(CultureInfo.CurrentCulture, "{0} of {1}", this.Type, objectType);
417 #endregion //Methods
420 /// <summary>
421 /// This class is used to fill and
422 /// manage collection with Hot Regions
423 /// </summary>
424 internal class HotRegionsList : IDisposable
426 #region Fields
428 /// <summary>
429 /// Process chart mode Flag
430 /// </summary>
431 private ProcessMode _processChartMode = ProcessMode.Paint;
433 /// <summary>
434 /// Collection with Hor Region Elements
435 /// </summary>
436 private System.Collections.ArrayList _regionList = new ArrayList();
438 /// <summary>
439 /// Reference to the common elements object
440 /// </summary>
441 private CommonElements _common = null;
443 #if Microsoft_CONTROL
445 /// <summary>
446 /// True if hit test function is called
447 /// </summary>
448 internal bool hitTestCalled = false;
450 #endif // Microsoft_CONTROL
452 #endregion // Fields
454 #region Properties
456 /// <summary>
457 /// Flag used for processing chart types. It could
458 /// be Paint, HotRegion or both mode.
459 /// </summary>
460 internal ProcessMode ProcessChartMode
464 return _processChartMode;
468 _processChartMode = value;
469 if(this._common != null)
471 this._common.processModePaint =
472 (_processChartMode & ProcessMode.Paint ) == ProcessMode.Paint;
473 this._common.processModeRegions =
474 ( _processChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions ||
475 ( _processChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps;
480 /// <summary>
481 /// Collection with Hor Region Elements
482 /// </summary>
483 internal ArrayList List
487 return _regionList;
491 #endregion // Properties
493 #region Methods
495 /// <summary>
496 /// Constructor
497 /// </summary>
498 /// <param name="common">Reference to the CommonElements</param>
499 internal HotRegionsList( CommonElements common )
501 this._common = common;
504 /// <summary>
505 /// Add hot region to the collection.
506 /// </summary>
507 /// <param name="rectSize">Rectangle which presents an Hot Region</param>
508 /// <param name="point">Data Point</param>
509 /// <param name="seriesName">Data Series</param>
510 /// <param name="pointIndex">Index of an Data Point in the series</param>
511 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
512 public void AddHotRegion(
513 RectangleF rectSize,
514 DataPoint point,
515 string seriesName,
516 int pointIndex
520 #if !Microsoft_CONTROL
521 if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps )
523 if (_common.ChartPicture.IsMapEnabled == true)
525 if(point.ToolTip.Length > 0 ||
526 point.Url.Length > 0 ||
527 point.MapAreaAttributes.Length > 0 ||
528 point.PostBackValue.Length > 0
531 MapArea area = new MapArea(
532 point.ReplaceKeywords(point.ToolTip),
533 point.ReplaceKeywords(point.Url),
534 point.ReplaceKeywords(point.MapAreaAttributes),
535 point.ReplaceKeywords(point.PostBackValue),
536 rectSize,
537 point.Tag);
538 area.IsCustom = false;
539 _common.ChartPicture.MapAreas.Insert(0, area);
543 #endif // !Microsoft_CONTROL
545 if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions )
547 HotRegion region = new HotRegion();
549 region.BoundingRectangle = rectSize;
550 region.SeriesName = seriesName;
551 region.PointIndex = pointIndex;
552 region.Type = ChartElementType.DataPoint;
553 region.RelativeCoordinates = true;
557 // Use index of the original data point
558 if(point != null && point.IsCustomPropertySet("OriginalPointIndex"))
560 region.PointIndex = int.Parse(point["OriginalPointIndex"], CultureInfo.InvariantCulture);
565 _regionList.Add( region );
570 /// <summary>
571 /// Adds the hot region.
572 /// </summary>
573 /// <param name="path">Bounding GraphicsPath.</param>
574 /// <param name="relativePath">if set to <c>true</c> the is relative path.</param>
575 /// <param name="graph">Chart Graphics Object</param>
576 /// <param name="point">Selected data point</param>
577 /// <param name="seriesName">Name of the series.</param>
578 /// <param name="pointIndex">Index of the point.</param>
579 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "graph")]
580 internal void AddHotRegion(
581 GraphicsPath path,
582 bool relativePath,
583 ChartGraphics graph,
584 DataPoint point,
585 string seriesName,
586 int pointIndex
589 if( path == null )
591 return;
593 #if !Microsoft_CONTROL
594 if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps )
596 if (_common.ChartPicture.IsMapEnabled == true)
598 if(point.ToolTip.Length > 0 ||
599 point.Url.Length > 0 ||
600 point.MapAreaAttributes.Length > 0 ||
601 point.PostBackValue.Length > 0
604 int prevMapAreaCount = _common.ChartPicture.MapAreas.Count;
605 _common.ChartPicture.MapAreas.InsertPath(
607 point.ReplaceKeywords(point.ToolTip),
608 point.ReplaceKeywords(point.Url),
609 point.ReplaceKeywords(point.MapAreaAttributes),
610 point.ReplaceKeywords(point.PostBackValue),
611 path,
612 !relativePath,
613 graph
617 // Set map area type
618 for (int i = 0; i < _common.ChartPicture.MapAreas.Count - prevMapAreaCount; i++)
619 ((IChartMapArea)_common.ChartPicture.MapAreas[i]).Tag = ((IChartMapArea)point).Tag;
623 #endif // !Microsoft_CONTROL
625 if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions )
628 HotRegion region = new HotRegion();
630 region.SeriesName = seriesName;
631 region.PointIndex = pointIndex;
632 region.Type = ChartElementType.DataPoint;
633 region.Path = (GraphicsPath)path.Clone();
634 region.BoundingRectangle = path.GetBounds();
635 region.RelativeCoordinates = relativePath;
639 // Use index of the original data point
640 if(point != null && point.IsCustomPropertySet("OriginalPointIndex"))
642 region.PointIndex = int.Parse(point["OriginalPointIndex"], CultureInfo.InvariantCulture);
647 _regionList.Add( region );
652 /// <summary>
653 /// Adds the hot region.
654 /// </summary>
655 /// <param name="insertIndex">Position where to insert element. Used for image maps only</param>
656 /// <param name="path">Bounding GraphicsPath.</param>
657 /// <param name="relativePath">if set to <c>true</c> the is relative path.</param>
658 /// <param name="graph">Chart Graphics Object</param>
659 /// <param name="point">Selected data point</param>
660 /// <param name="seriesName">Name of the series.</param>
661 /// <param name="pointIndex">Index of the point.</param>
663 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "graph"),
664 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "insertIndex")
666 internal void AddHotRegion(
667 int insertIndex,
668 GraphicsPath path,
669 bool relativePath,
670 ChartGraphics graph,
671 DataPoint point,
672 string seriesName,
673 int pointIndex
676 #if !Microsoft_CONTROL
677 if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps )
679 if (_common.ChartPicture.IsMapEnabled == true)
681 if(point.ToolTip.Length > 0 ||
682 point.Url.Length > 0 ||
683 point.MapAreaAttributes.Length > 0 ||
684 point.PostBackValue.Length > 0)
687 int prevMapAreaCount = _common.ChartPicture.MapAreas.Count;
689 _common.ChartPicture.MapAreas.InsertPath(
690 insertIndex,
691 point.ReplaceKeywords(point.ToolTip),
692 point.ReplaceKeywords(point.Url),
693 point.ReplaceKeywords(point.MapAreaAttributes),
694 point.ReplaceKeywords(point.PostBackValue),
695 path,
696 !relativePath,
697 graph
700 // Set map area type
701 for (int i = insertIndex; i < _common.ChartPicture.MapAreas.Count - prevMapAreaCount; i++)
702 ((IChartMapArea)_common.ChartPicture.MapAreas[i]).Tag = ((IChartMapArea)point).Tag;
706 #endif // !Microsoft_CONTROL
708 if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions )
711 HotRegion region = new HotRegion();
713 region.SeriesName = seriesName;
714 region.PointIndex = pointIndex;
715 region.Type = ChartElementType.DataPoint;
716 region.Path = (GraphicsPath)path.Clone();
717 region.BoundingRectangle = path.GetBounds();
718 region.RelativeCoordinates = relativePath;
722 // Use index of the original data point
723 if(point != null && point.IsCustomPropertySet("OriginalPointIndex"))
725 region.PointIndex = int.Parse(point["OriginalPointIndex"], CultureInfo.InvariantCulture);
730 _regionList.Add( region );
735 /// <summary>
736 /// Add hot region to the collection.
737 /// </summary>
738 /// <param name="path">Graphics path which presents hot region</param>
739 /// <param name="relativePath">Graphics path uses relative or absolute coordinates</param>
740 /// <param name="coord">Coordinates which defines polygon (Graphics Path). Used for image maps</param>
741 /// <param name="point">Selected data point</param>
742 /// <param name="seriesName">Data Series</param>
743 /// <param name="pointIndex">Index of an Data Point in the series</param>
744 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "coord")]
745 internal void AddHotRegion( GraphicsPath path, bool relativePath, float [] coord, DataPoint point, string seriesName, int pointIndex )
748 #if !Microsoft_CONTROL
749 if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps )
751 if (_common.ChartPicture.IsMapEnabled == true)
753 if(point.ToolTip.Length > 0 ||
754 point.Url.Length > 0 ||
755 point.MapAreaAttributes.Length > 0 ||
756 point.PostBackValue.Length > 0)
758 MapArea area = new MapArea(
759 MapAreaShape.Polygon,
760 point.ReplaceKeywords(point.ToolTip),
761 point.ReplaceKeywords(point.Url),
762 point.ReplaceKeywords(point.MapAreaAttributes),
763 point.ReplaceKeywords(point.PostBackValue),
764 coord,
765 point.Tag);
766 area.IsCustom = false;
767 _common.ChartPicture.MapAreas.Insert(0,area);
772 #endif // !Microsoft_CONTROL
774 if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions )
777 HotRegion region = new HotRegion();
779 region.SeriesName = seriesName;
780 region.PointIndex = pointIndex;
781 region.Type = ChartElementType.DataPoint;
782 region.Path = (GraphicsPath)path.Clone();
783 region.BoundingRectangle = path.GetBounds();
784 region.RelativeCoordinates = relativePath;
788 // Use index of the original data point
789 if(point != null && point.IsCustomPropertySet("OriginalPointIndex"))
791 region.PointIndex = int.Parse(point["OriginalPointIndex"], CultureInfo.InvariantCulture);
796 _regionList.Add( region );
802 /// <summary>
803 /// Add Hot region to the collection.
804 /// </summary>
805 /// <param name="insertIndex">Position where to insert element. Used for image maps only</param>
806 /// <param name="graph">Chart Graphics Object</param>
807 /// <param name="x">x coordinate.</param>
808 /// <param name="y">y coordinate.</param>
809 /// <param name="radius">The radius.</param>
810 /// <param name="point">Selected data point</param>
811 /// <param name="seriesName">Data Series</param>
812 /// <param name="pointIndex">Index of an Data Point in the series</param>
813 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "insertIndex")]
814 internal void AddHotRegion( int insertIndex, ChartGraphics graph, float x, float y, float radius, DataPoint point, string seriesName, int pointIndex )
817 #if !Microsoft_CONTROL
818 if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps )
820 if (_common.ChartPicture.IsMapEnabled == true)
822 if(point.ToolTip.Length > 0 ||
823 point.Url.Length > 0 ||
824 point.MapAreaAttributes.Length > 0 ||
825 point.PostBackValue.Length > 0 )
828 float[] circCoord = new float[3];
829 circCoord[0] = x;
830 circCoord[1] = y;
831 circCoord[2] = radius;
833 MapArea area = new MapArea(
834 MapAreaShape.Circle,
835 point.ReplaceKeywords(point.ToolTip),
836 point.ReplaceKeywords(point.Url),
837 point.ReplaceKeywords(point.MapAreaAttributes),
838 point.ReplaceKeywords(point.PostBackValue),
839 circCoord,
840 point.Tag);
841 area.IsCustom = false;
842 // Insert area
843 _common.ChartPicture.MapAreas.Insert(insertIndex,area);
848 #endif // !Microsoft_CONTROL
850 if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions )
852 HotRegion region = new HotRegion();
854 PointF circleCenter = graph.GetAbsolutePoint( new PointF( x, y ) );
855 SizeF circleRadius = graph.GetAbsoluteSize( new SizeF( radius, radius ) );
857 GraphicsPath path = new GraphicsPath();
858 path.AddEllipse(
859 circleCenter.X - circleRadius.Width,
860 circleCenter.Y - circleRadius.Width,
861 2 * circleRadius.Width,
862 2 * circleRadius.Width
864 region.BoundingRectangle = path.GetBounds();
865 region.SeriesName = seriesName;
866 region.Type = ChartElementType.DataPoint;
867 region.PointIndex = pointIndex;
868 region.Path = path;
869 region.RelativeCoordinates = false;
873 // Use index of the original data point
874 if(point != null && point.IsCustomPropertySet("OriginalPointIndex"))
876 region.PointIndex = int.Parse(point["OriginalPointIndex"], CultureInfo.InvariantCulture);
881 _regionList.Add( region );
886 /// <summary>
887 /// Add Hot region to the collection.
888 /// </summary>
889 /// <param name="rectArea">Hot Region rectangle</param>
890 /// <param name="toolTip">Tool Tip Text</param>
891 /// <param name="hRef">HRef string</param>
892 /// <param name="mapAreaAttributes">Map area Attribute string</param>
893 /// <param name="postBackValue">The post back value associated with this item</param>
894 /// <param name="selectedObject">Object which present hot region</param>
895 /// <param name="type">AxisName of the object which present hot region</param>
896 /// <param name="series">Selected series</param>
898 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "hRef"),
899 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "mapAreaAttributes"),
900 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "postBackValue"),
901 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "toolTip")
903 internal void AddHotRegion( RectangleF rectArea, string toolTip, string hRef, string mapAreaAttributes, string postBackValue, object selectedObject, ChartElementType type, string series )
905 #if !Microsoft_CONTROL
906 if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps )
908 // Add items to the image map collection
909 if (_common.ChartPicture.IsMapEnabled == true)
911 if(toolTip.Length > 0 ||
912 hRef.Length > 0 ||
913 mapAreaAttributes.Length > 0 ||
914 postBackValue.Length > 0)
916 MapArea area = new MapArea(
917 toolTip,
918 hRef,
919 mapAreaAttributes,
920 postBackValue,
921 rectArea,
922 ((IChartMapArea)selectedObject).Tag);
923 area.IsCustom = false;
924 _common.ChartPicture.MapAreas.Add( area);
928 #endif // !Microsoft_CONTROL
930 if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions )
932 HotRegion region = new HotRegion();
934 region.BoundingRectangle = rectArea;
935 region.RelativeCoordinates = true;
936 region.Type = type;
937 region.SelectedObject = selectedObject;
938 if(!String.IsNullOrEmpty(series))
940 region.SeriesName = series;
942 _regionList.Add( region );
948 /// <summary>
949 /// Add Hot region to the collection.
950 /// </summary>
951 /// <param name="rectArea">Hot Region rectangle</param>
952 /// <param name="toolTip">Tool Tip Text</param>
953 /// <param name="hRef">HRef string</param>
954 /// <param name="mapAreaAttributes">Map area Attribute string</param>
955 /// <param name="postBackValue">The post back value associated with this item</param>
956 /// <param name="selectedObject">Object which present hot region</param>
957 /// <param name="selectedSubObject">Sub-Object which present hot region</param>
958 /// <param name="type">AxisName of the object which present hot region</param>
959 /// <param name="series">Selected series</param>
961 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "hRef"),
962 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "mapAreaAttributes"),
963 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "postBackValue"),
964 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "toolTip")
966 internal void AddHotRegion(
967 RectangleF rectArea,
968 string toolTip,
969 string hRef,
970 string mapAreaAttributes,
971 string postBackValue,
972 object selectedObject,
973 object selectedSubObject,
974 ChartElementType type,
975 string series )
977 #if !Microsoft_CONTROL
978 if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps )
980 // Add items to the image map collection
981 if (_common.ChartPicture.IsMapEnabled == true)
983 if(toolTip.Length > 0 ||
984 hRef.Length > 0 ||
985 mapAreaAttributes.Length > 0 ||
986 postBackValue.Length > 0)
988 MapArea area = new MapArea(
989 toolTip,
990 hRef,
991 mapAreaAttributes,
992 postBackValue,
993 rectArea,
994 ((IChartMapArea)selectedObject).Tag);
995 area.IsCustom = false;
996 _common.ChartPicture.MapAreas.Add( area);
1000 #endif // !Microsoft_CONTROL
1002 if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions )
1004 HotRegion region = new HotRegion();
1006 region.BoundingRectangle = rectArea;
1007 region.RelativeCoordinates = true;
1008 region.Type = type;
1009 region.SelectedObject = selectedObject;
1010 region.SelectedSubObject = selectedSubObject;
1011 if(!String.IsNullOrEmpty(series))
1013 region.SeriesName = series;
1015 _regionList.Add( region );
1021 /// <summary>
1022 /// Add Hot region to the collection.
1023 /// </summary>
1024 /// <param name="graph">Chart Graphics Object</param>
1025 /// <param name="path">Graphics path</param>
1026 /// <param name="relativePath">Used relative coordinates for graphics path.</param>
1027 /// <param name="toolTip">Tool Tip Text</param>
1028 /// <param name="hRef">HRef string</param>
1029 /// <param name="mapAreaAttributes">Map area Attribute string</param>
1030 /// <param name="postBackValue">The post back value associated with this item</param>
1031 /// <param name="selectedObject">Object which present hot region</param>
1032 /// <param name="type">AxisName of the object which present hot region</param>
1034 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "graph"),
1035 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "hRef"),
1036 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "mapAreaAttributes"),
1037 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "postBackValue"),
1038 System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "toolTip")
1040 internal void AddHotRegion( ChartGraphics graph, GraphicsPath path, bool relativePath, string toolTip, string hRef, string mapAreaAttributes, string postBackValue, object selectedObject, ChartElementType type )
1042 #if !Microsoft_CONTROL
1043 if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps )
1045 if (_common.ChartPicture.IsMapEnabled == true)
1048 if(toolTip.Length > 0 ||
1049 hRef.Length > 0 ||
1050 mapAreaAttributes.Length > 0 ||
1051 postBackValue.Length > 0)
1053 _common.ChartPicture.MapAreas.InsertPath(
1055 toolTip,
1056 hRef,
1057 mapAreaAttributes,
1058 postBackValue,
1059 path,
1060 !relativePath,
1061 graph
1066 #endif // !Microsoft_CONTROL
1068 if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions )
1071 HotRegion region = new HotRegion();
1073 region.Type = type;
1074 region.Path = (GraphicsPath)path.Clone();
1075 region.SelectedObject = selectedObject;
1076 region.BoundingRectangle = path.GetBounds();
1077 region.RelativeCoordinates = relativePath;
1079 _regionList.Add( region );
1084 /// <summary>
1085 /// Add Hot region to the collection.
1086 /// </summary>
1087 /// <param name="rectArea">Hot Region rectangle</param>
1088 /// <param name="selectedObject">Object which present hot region</param>
1089 /// <param name="type">AxisName of the object which present hot region</param>
1090 /// <param name="relativeCoordinates">Coordinates for rectangle are relative</param>
1091 internal void AddHotRegion( RectangleF rectArea, object selectedObject, ChartElementType type, bool relativeCoordinates )
1093 this.AddHotRegion( rectArea, selectedObject, type, relativeCoordinates, false );
1096 /// <summary>
1097 /// Add Hot region to the collection.
1098 /// </summary>
1099 /// <param name="rectArea">Hot Region rectangle</param>
1100 /// <param name="selectedObject">Object which present hot region</param>
1101 /// <param name="type">AxisName of the object which present hot region</param>
1102 /// <param name="relativeCoordinates">Coordinates for rectangle are relative</param>
1103 /// <param name="insertAtBeginning">Insert the hot region at the beginning of the collection</param>
1104 internal void AddHotRegion( RectangleF rectArea, object selectedObject, ChartElementType type, bool relativeCoordinates, bool insertAtBeginning )
1106 if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions )
1108 HotRegion region = new HotRegion();
1110 region.BoundingRectangle = rectArea;
1111 region.RelativeCoordinates = relativeCoordinates;
1112 region.Type = type;
1113 region.SelectedObject = selectedObject;
1115 if( insertAtBeginning )
1117 _regionList.Insert( _regionList.Count - 1, region );
1119 else
1121 _regionList.Add( region );
1126 /// <summary>
1127 /// Add Hot region to the collection.
1128 /// </summary>
1129 /// <param name="path">Graphics path</param>
1130 /// <param name="relativePath">Used relative coordinates for graphics path.</param>
1131 /// <param name="type">Type of the object which present hot region</param>
1132 /// <param name="selectedObject">Object which present hot region</param>
1133 internal void AddHotRegion(
1134 GraphicsPath path,
1135 bool relativePath,
1136 ChartElementType type,
1137 object selectedObject
1140 if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions )
1143 HotRegion region = new HotRegion();
1145 region.SelectedObject = selectedObject;
1146 region.Type = type;
1147 region.Path = (GraphicsPath)path.Clone();
1148 region.BoundingRectangle = path.GetBounds();
1149 region.RelativeCoordinates = relativePath;
1151 _regionList.Add( region );
1156 /// <summary>
1157 /// This method search for position in Map Areas which is the first
1158 /// position after Custom areas.
1159 /// </summary>
1160 /// <returns>Insert Index</returns>
1161 internal int FindInsertIndex()
1163 int insertIndex = 0;
1164 #if !Microsoft_CONTROL
1165 foreach (MapArea mapArea in _common.ChartPicture.MapAreas)
1167 if(!mapArea.IsCustom)
1169 break;
1171 ++insertIndex;
1173 #endif // !Microsoft_CONTROL
1175 return insertIndex;
1178 /// <summary>
1179 /// Clears this instance.
1180 /// </summary>
1181 public void Clear()
1183 foreach (HotRegion hotRegion in this._regionList)
1184 hotRegion.Dispose();
1186 this._regionList.Clear();
1189 #endregion // Methods
1191 #region IDisposable members
1192 /// <summary>
1193 /// Releases unmanaged and - optionally - managed resources
1194 /// </summary>
1195 /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
1196 protected virtual void Dispose(bool disposing)
1198 if (disposing)
1200 if (this._regionList != null)
1202 foreach (HotRegion hotRegion in this._regionList)
1203 hotRegion.Dispose();
1205 this._regionList.Clear();
1210 /// <summary>
1211 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
1212 /// </summary>
1213 public void Dispose()
1215 Dispose(true);
1216 GC.SuppressFinalize(this);
1218 #endregion
1222 /// <summary>
1223 /// The HitTestResult class contains the result of the hit test function.
1224 /// </summary>
1225 #if ASPPERM_35
1226 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1227 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1228 #endif
1229 public class HitTestResult
1231 #region Fields
1233 // Private members
1234 private object _obj = null;
1235 private Series _series = null;
1236 private int _dataPoint = -1;
1237 private ChartArea _chartArea = null;
1238 private Axis _axis = null;
1239 private ChartElementType _type = ChartElementType.Nothing;
1240 private object _subObject = null;
1242 #endregion
1244 #region Properties
1246 /// <summary>
1247 /// Gets or sets the data series object.
1248 /// </summary>
1249 public Series Series
1253 return _series;
1257 _series = value;
1261 /// <summary>
1262 /// Gets or sets the data point index.
1263 /// </summary>
1264 public int PointIndex
1268 return _dataPoint;
1272 _dataPoint = value;
1276 /// <summary>
1277 /// Gets or sets the chart area object.
1278 /// </summary>
1279 public ChartArea ChartArea
1283 return _chartArea;
1287 _chartArea = value;
1291 /// <summary>
1292 /// Gets or sets the axis object.
1293 /// </summary>
1294 public Axis Axis
1298 return _axis;
1302 _axis = value;
1306 /// <summary>
1307 /// Gets or sets the chart element type.
1308 /// </summary>
1309 public ChartElementType ChartElementType
1313 return _type;
1317 _type = value;
1321 /// <summary>
1322 /// Gets or sets the selected object.
1323 /// </summary>
1324 public object Object
1328 return _obj;
1332 _obj = value;
1338 /// <summary>
1339 /// Gets or sets the selected sub object.
1340 /// </summary>
1341 public object SubObject
1345 return _subObject;
1349 _subObject = value;
1353 #endregion
1357 /// <summary>
1358 /// This class represents an array of marker points and
1359 /// the outline path used for visual object selection in the chart.
1360 /// </summary>
1361 /// <remarks>
1362 /// <see cref="OutlinePath"/> may be null for complex objects or objects with two points or fewer.
1363 /// </remarks>
1364 #if ASPPERM_35
1365 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1366 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1367 #endif
1368 public class ChartElementOutline : IDisposable
1370 /// <summary>
1371 /// Initializes a new instance of the <see cref="ChartElementOutline"/> class.
1372 /// </summary>
1373 internal ChartElementOutline()
1375 this.Markers = new ReadOnlyCollection<PointF>( new PointF[] {});
1378 /// <summary>
1379 /// Gets the markers.
1380 /// </summary>
1381 /// <value>The markers.</value>
1382 public ReadOnlyCollection<PointF> Markers { get; internal set; }
1384 /// <summary>
1385 /// Gets or sets the outline path. The result could be null for complex objects and objects with two points or fewer.
1386 /// </summary>
1387 /// <value>The outline path.</value>
1388 public GraphicsPath OutlinePath { get; internal set; }
1391 #region IDisposable Members
1393 /// <summary>
1394 /// Releases unmanaged and - optionally - managed resources
1395 /// </summary>
1396 /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
1397 protected virtual void Dispose(bool disposing)
1399 if (disposing)
1401 if (this.OutlinePath != null)
1403 this.OutlinePath.Dispose();
1404 this.OutlinePath = null;
1406 this.Markers = null;
1410 /// <summary>
1411 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
1412 /// </summary>
1413 [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
1414 public void Dispose()
1416 Dispose(true);
1417 GC.SuppressFinalize(this);
1420 #endregion
1424 /// <summary>
1425 /// This class contains methods used for Windows Forms selection.
1426 /// </summary>
1427 internal class Selection : IServiceProvider
1428 #if Microsoft_CONTROL
1429 , IDisposable
1430 #endif //Microsoft_CONTROL
1432 #region Fields
1434 /// <summary>
1435 /// The chart service container
1436 /// </summary>
1437 private IServiceContainer _service = null;
1439 #if Microsoft_CONTROL
1441 /// <summary>
1442 /// Stores the tooltip of the control.
1443 /// </summary>
1444 private ToolTip _toolTip = new ToolTip();
1446 /// <summary>
1447 /// Used by the tooltip - stores the time when the tooltip is activated.
1448 /// </summary>
1449 private DateTime _toolTipActivationTime = DateTime.Now;
1451 /// <summary>
1452 /// Stores the last mouse move X and Y coordinates, so we can ignore false calls to
1453 /// OnMouseMove generated my the tooltip.
1454 /// </summary>
1455 private Point _lastMouseMove = new Point(int.MinValue, int.MinValue);
1458 // ToolTips enabled or disabled from series or legend
1459 private bool _toolTipsEnabled = false;
1461 // Tool tips enabled flag checked
1462 internal bool enabledChecked = false;
1464 #endif //Microsoft_CONTROL
1465 #endregion
1467 #region Constructors
1469 /// <summary>
1470 /// Initializes a new instance of the <see cref="Selection"/> class.
1471 /// </summary>
1472 /// <param name="service">The service.</param>
1473 internal Selection(IServiceContainer service)
1475 this._service = service;
1476 this._chartControl = this.ChartControl;
1477 #if Microsoft_CONTROL
1479 // Set up the tooltip
1480 this._toolTip.Active = true;
1481 this._toolTip.AutoPopDelay = 30000; // maximum delay possible
1482 this._toolTip.InitialDelay = 500;
1483 this._toolTip.ReshowDelay = 50;
1484 this._toolTip.ShowAlways = true;
1485 this._toolTip.Active = false;
1486 #endif //Microsoft_CONTROL
1490 #if Microsoft_CONTROL
1491 /// <summary>
1492 /// Releases unmanaged and - optionally - managed resources
1493 /// </summary>
1494 /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
1495 private void Dispose(bool disposing)
1497 if (disposing)
1499 if (_toolTip != null)
1501 _toolTip.Dispose();
1502 _toolTip = null;
1507 /// <summary>
1508 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
1509 /// </summary>
1510 public void Dispose()
1512 Dispose(true);
1513 GC.SuppressFinalize(this);
1516 #endif //Microsoft_CONTROL
1518 #endregion //Constructors
1520 #region Properties
1522 private Chart _chartControl = null;
1523 /// <summary>
1524 /// Returns the attached chart control
1525 /// </summary>
1526 internal Chart ChartControl
1530 if (this._chartControl == null)
1532 if (this.ChartPicture != null)
1534 this._chartControl = this.ChartPicture.Chart;
1537 return this._chartControl;
1541 private ChartPicture _chartPicture = null;
1542 /// <summary>
1543 /// Returns the attached ChartPicture
1544 /// </summary>
1545 internal ChartPicture ChartPicture
1549 if (this._chartPicture == null)
1551 this._chartPicture = ((IServiceProvider)this).GetService(typeof(ChartImage)) as ChartPicture;
1552 if (this._chartPicture == null)
1554 this._chartPicture = ((IServiceProvider)this).GetService(typeof(ChartPicture)) as ChartPicture;
1557 return this._chartPicture;
1561 private Data.DataManager _dataManager = null;
1562 /// <summary>
1563 /// Gets the chart data manager ( for series access )
1564 /// </summary>
1565 internal Data.DataManager DataManager
1569 if (this._dataManager == null)
1571 this._dataManager = ((IServiceProvider)this).GetService(typeof(Data.DataManager)) as Data.DataManager;
1573 return this._dataManager;
1577 /// <summary>
1578 /// Gets the chart ChartGraphics
1579 /// </summary>
1580 internal ChartGraphics Graph
1584 if (this.ChartPicture != null)
1586 return this.ChartPicture.Common.graph;
1588 return null;
1592 #endregion //Private Properties
1594 #region Methods
1596 #region Tooltips
1597 #if Microsoft_CONTROL
1598 /// <summary>
1599 /// Checks if tooltips are enabled
1600 /// </summary>
1601 /// <returns>true if tooltips enabled</returns>
1602 private bool IsToolTipsEnabled()
1604 // Enabled checked. Don’t check every time series
1605 // and data points for tooltips.
1606 if( enabledChecked )
1608 return _toolTipsEnabled;
1611 enabledChecked = true;
1616 // Annotations loop
1617 foreach( Annotation annotation in _chartControl.Annotations )
1619 // ToolTip empty
1620 if( annotation.ToolTip.Length > 0 )
1622 // ToolTips enabled
1623 _toolTipsEnabled = true;
1624 return true;
1629 // Data series loop
1630 foreach( Series series in _chartControl.Series )
1632 // Check series tooltips
1633 if( series.ToolTip.Length > 0 ||
1634 series.LegendToolTip.Length > 0 ||
1635 series.LabelToolTip.Length > 0)
1637 // ToolTips enabled
1638 _toolTipsEnabled = true;
1639 return true;
1643 // Check if custom properties (Pie collected slice) that create tooltips are used
1644 if(series.IsCustomPropertySet(Utilities.CustomPropertyName.CollectedToolTip))
1646 // ToolTips enabled
1647 _toolTipsEnabled = true;
1648 return true;
1652 // Check point tooltips only for "non-Fast" chart types
1653 if( !series.IsFastChartType() )
1655 // Data point loop
1656 foreach( DataPoint point in series.Points )
1658 // ToolTip empty
1659 if( point.ToolTip.Length > 0 ||
1660 point.LegendToolTip.Length > 0 ||
1661 point.LabelToolTip.Length > 0)
1663 // ToolTips enabled
1664 _toolTipsEnabled = true;
1665 return true;
1671 // Legend items loop
1672 foreach( Legend legend in _chartControl.Legends )
1674 // Check custom legend items
1675 foreach( LegendItem legendItem in legend.CustomItems )
1677 // ToolTip empty
1678 if( legendItem.ToolTip.Length > 0 )
1680 _toolTipsEnabled = true;
1681 return true;
1685 // Check all custom cells in the legend item
1686 foreach(LegendCell legendCell in legendItem.Cells)
1688 if(legendCell.ToolTip.Length > 0)
1690 _toolTipsEnabled = true;
1691 return true;
1698 // Iterate through legend columns
1699 foreach(LegendCellColumn legendColumn in legend.CellColumns)
1701 if(legendColumn.ToolTip.Length > 0)
1703 _toolTipsEnabled = true;
1704 return true;
1710 // Title items loop
1711 foreach( Title title in _chartControl.Titles )
1713 // ToolTip empty
1714 if( title.ToolTip.Length > 0 )
1716 _toolTipsEnabled = true;
1717 return true;
1721 // Chart areas loop
1722 foreach( ChartArea area in _chartControl.ChartAreas )
1725 // Check if chart area is visible
1726 if(area.Visible)
1729 // Axis loop
1730 foreach(Axis axis in area.Axes)
1733 // Check ToolTip
1734 if( axis.ToolTip.Length > 0 )
1736 _toolTipsEnabled = true;
1737 return true;
1741 // Strip lines loop
1742 foreach(StripLine stripLine in axis.StripLines)
1744 // Check ToolTip
1745 if( stripLine.ToolTip.Length > 0 )
1747 _toolTipsEnabled = true;
1748 return true;
1751 // Check custom labels
1752 foreach(CustomLabel customLabel in axis.CustomLabels)
1754 if( customLabel.ToolTip.Length > 0 )
1756 _toolTipsEnabled = true;
1757 return true;
1764 // ToolTips disabled
1765 _toolTipsEnabled = false;
1766 return false;
1769 [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily",
1770 Justification = "Too large of a code change to justify making this change")]
1771 internal string EvaluateToolTip(System.Windows.Forms.MouseEventArgs e)
1773 object obj;
1774 object subObj;
1775 ChartElementType type;
1776 int dataPointIndex;
1777 string seriesName;
1778 string toolTipText = " ";
1780 HitTestResult hitTest = this.HitTest(e.X, e.Y, true);
1782 type = hitTest.ChartElementType;
1783 dataPointIndex = hitTest.PointIndex;
1784 seriesName = hitTest.Series != null ? hitTest.Series.Name : String.Empty;
1785 obj = hitTest.Object;
1786 subObj = hitTest.SubObject;
1789 // Get tooltips from data points
1790 if (type == ChartElementType.DataPoint)
1792 if (_chartControl.Series.IndexOf(seriesName) >= 0 &&
1793 dataPointIndex >= 0 &&
1794 dataPointIndex < _chartControl.Series[seriesName].Points.Count)
1796 // Take tool tip from data point
1797 toolTipText = _chartControl.Series[seriesName].Points[dataPointIndex].ReplaceKeywords(_chartControl.Series[seriesName].Points[dataPointIndex].ToolTip);
1799 else
1801 DataPoint dataPoint = obj as DataPoint;
1802 if (dataPoint != null)
1804 // Take tool tip from data point
1805 toolTipText = dataPoint.ReplaceKeywords(dataPoint.ToolTip);
1812 // Get tooltips from data points
1813 if (type == ChartElementType.DataPointLabel)
1815 if (_chartControl.Series.IndexOf(seriesName) >= 0 &&
1816 dataPointIndex >= 0 &&
1817 dataPointIndex < _chartControl.Series[seriesName].Points.Count)
1819 // Take tool tip from data point
1820 toolTipText = _chartControl.Series[seriesName].Points[dataPointIndex].ReplaceKeywords(_chartControl.Series[seriesName].Points[dataPointIndex].LabelToolTip);
1825 // Get tooltips from custom label
1826 if (type == ChartElementType.AxisLabels &&
1827 obj is CustomLabel)
1829 toolTipText = ((CustomLabel)obj).ToolTip;
1835 // Get tooltips from data points
1836 else if (type == ChartElementType.Annotation && obj != null && obj is Annotation)
1838 // Take tool tip from data point
1839 toolTipText = ((Annotation)obj).ReplaceKeywords(((Annotation)obj).ToolTip);
1842 // Get tooltips from axis
1843 else if (type == ChartElementType.Axis && obj != null && obj is Axis)
1845 // Take tool tip from strip line
1846 toolTipText = ((Axis)obj).ToolTip;
1849 // Get tooltips from strip lines
1850 else if (type == ChartElementType.StripLines && obj != null && obj is StripLine)
1852 // Take tool tip from strip line
1853 toolTipText = ((StripLine)obj).ToolTip;
1856 // Get tooltips from data points
1857 else if (type == ChartElementType.Title && obj != null && obj is Title)
1859 // Take tool tip from data point
1860 toolTipText = ((Title)obj).ToolTip;
1862 } // Get tooltips for legend items
1864 // Get tooltips for legend items
1865 else if (type == ChartElementType.LegendItem)
1867 // Take tool tip from legend item
1868 toolTipText = ((LegendItem)obj).ToolTip;
1871 // Check if cell has it's own tooltip
1872 LegendCell legendCell = subObj as LegendCell;
1873 if (legendCell != null && legendCell.ToolTip.Length > 0)
1875 toolTipText = legendCell.ToolTip;
1879 // Check if series is associated with legend item
1880 if (toolTipText.Length == 0 &&
1881 seriesName.Length > 0 &&
1882 _chartControl.Series.IndexOf(seriesName) >= 0)
1884 // Take tool tip from data point
1885 if (dataPointIndex == -1)
1887 if (seriesName.Length > 0)
1889 // Take tool tip from series
1890 toolTipText = _chartControl.Series[seriesName].ReplaceKeywords(_chartControl.Series[seriesName].LegendToolTip);
1893 else
1895 if (dataPointIndex >= 0 &&
1896 dataPointIndex < _chartControl.Series[seriesName].Points.Count)
1898 // Take tool tip from data point
1899 toolTipText = _chartControl.Series[seriesName].Points[dataPointIndex].ReplaceKeywords(_chartControl.Series[seriesName].Points[dataPointIndex].LegendToolTip);
1905 // Set event arguments
1906 ToolTipEventArgs args = new ToolTipEventArgs(e.X, e.Y, toolTipText, hitTest);
1908 // Event
1909 _chartControl.OnGetToolTipText(args);
1911 return args.Text.Trim();
1916 /// <summary>
1917 /// Mouse move event handler.
1918 /// </summary>
1919 /// <param name="sender">Sender</param>
1920 /// <param name="e">Arguments</param>
1921 internal void Selection_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
1924 // Ignore false calls to OnMouseMove caused by the tootip control.
1925 if (e.X == this._lastMouseMove.X && e.Y == this._lastMouseMove.Y)
1927 return;
1929 else
1931 this._lastMouseMove.X = e.X;
1932 this._lastMouseMove.Y = e.Y;
1935 // Event is not active and tooltip properties are nor set.
1936 if (!IsToolTipsEnabled() && !_chartControl.IsToolTipEventUsed())
1938 return;
1941 string newToolTipText = this.EvaluateToolTip(e);
1943 if (!String.IsNullOrEmpty(newToolTipText))
1945 string oldToolTipText = this._toolTip.GetToolTip(this._chartControl);
1946 TimeSpan timeSpan = DateTime.Now.Subtract(this._toolTipActivationTime);
1947 if (oldToolTipText != newToolTipText || timeSpan.Milliseconds > 600)
1949 // Activate the tooltip
1950 this._toolTip.Active = false;
1951 this._toolTip.SetToolTip(this._chartControl, newToolTipText);
1952 this._toolTip.Active = true;
1953 this._toolTipActivationTime = DateTime.Now;
1956 else
1958 // We do not have a tooltip, so deactivate it
1959 this._toolTip.Active = false;
1960 this._toolTip.SetToolTip(this._chartControl, string.Empty);
1964 #endif //Microsoft_CONTROL
1966 #endregion //Tooltips
1968 #region HitTest
1971 /// <summary>
1972 /// Call this method to determine the chart element,
1973 /// if any, that is located at a point defined by the given X and Y
1974 /// coordinates.
1975 /// <seealso cref="HitTestResult"/></summary>
1976 /// <param name="x">The X coordinate for the point in question.
1977 /// Often obtained from a parameter in an event
1978 /// (e.g. the X parameter value in the MouseDown event).</param>
1979 /// <param name="y">The Y coordinate for the point in question.
1980 /// Often obtained from a parameter in an event
1981 /// (e.g. the Y parameter value in the MouseDown event).</param>
1982 /// <param name="requestedElementTypes">
1983 /// An array of type which specify the types
1984 /// to test for, on order to filter the result. If omitted checking for
1985 /// elementTypes will be ignored and all kind of elementTypes will be
1986 /// valid.
1987 /// </param>
1988 /// <param name="ignoreTransparent">Indicates that transparent
1989 /// elements should be ignored.</param>
1990 /// <returns>
1991 /// A array of <see cref="HitTestResult"/> objects,
1992 /// which provides information concerning the chart element
1993 /// (if any) that is at the specified location. Result contains at least
1994 /// one element, which could be ChartElementType.Nothing.
1995 /// The objects in the result are sorted in from top to bottom of
1996 /// different layers of control. </returns>
1997 /// <remarks>Call this method to determine the gauge element
1998 /// (if any) that is located at a specified point. Often this method is used in
1999 /// some mouse-related event (e.g. MouseDown)
2000 /// to determine what gauge element the end-user clicked on.
2001 /// The X and Y mouse coordinates obtained from the
2002 /// event parameters are then used for the X and Y parameter
2003 /// values of this method call. The returned
2004 /// <see cref="HitTestResult"/> object's properties
2005 /// can then be used to determine what chart element was clicked on,
2006 /// and also provides a reference to the actual object selected (if
2007 /// any).</remarks>
2008 internal HitTestResult[] HitTest(int x, int y, bool ignoreTransparent, params ChartElementType[] requestedElementTypes)
2010 List<HitTestResult> result = new List<HitTestResult>();
2011 ArrayList regionList = this.ChartPicture.Common.HotRegionsList.List;
2013 if (regionList.Count == 0)
2015 this.ChartPicture.PaintOffScreen();
2018 string alowedElements = String.Empty;
2019 if (requestedElementTypes.Length > 0)
2021 StringBuilder builder = new StringBuilder();
2022 foreach (ChartElementType elementType in requestedElementTypes)
2024 builder.Append(elementType.ToString() + ";");
2026 alowedElements = builder.ToString();
2029 float newX;
2030 float newY;
2031 float relativeX;
2032 float relativeY;
2033 RectangleF newMouseRect;
2035 // Find mouse position in relative and absolute coordinates
2036 RectangleF mouseRect = new RectangleF(x - 1, y - 1, 2, 2);
2037 relativeX = this.Graph.GetRelativePoint(new PointF(x, y)).X;
2038 relativeY = this.Graph.GetRelativePoint(new PointF(x, y)).Y;
2039 RectangleF relativeMouseRect = this.Graph.GetRelativeRectangle(mouseRect);
2041 // Try to pass through series object in design time.
2042 // The series ussualy contain autogenerated points with short lifetime - during painting;
2043 // This hit test result will be used in VS2005 desing time click.
2044 for (int index = regionList.Count - 1; index >= 0; index--)
2046 HotRegion region = (HotRegion)regionList[index];
2048 // Check if only looking for specific chart element type
2049 if (!String.IsNullOrEmpty(alowedElements) && alowedElements.IndexOf(region.Type.ToString() + ";", StringComparison.Ordinal) == -1)
2051 continue;
2055 // Change coordinates if relative path is used
2056 if (region.RelativeCoordinates)
2058 newX = relativeX;
2059 newY = relativeY;
2060 newMouseRect = relativeMouseRect;
2062 else
2064 newX = (float)x;
2065 newY = (float)y;
2066 newMouseRect = mouseRect;
2070 // Check if series name and point index are valid
2071 if (region.SeriesName.Length > 0 &&
2072 (this.ChartControl.Series.IndexOf(region.SeriesName) < 0 || region.PointIndex >= this.ChartControl.Series[region.SeriesName].Points.Count)
2075 continue;
2078 // Check if transparent chart elements should be ignored
2079 if (ignoreTransparent && IsElementTransparent(region))
2081 continue;
2083 // Check intersection with bounding rectangle
2084 if (region.BoundingRectangle.IntersectsWith(newMouseRect))
2086 bool pointVisible = false;
2088 if (region.Path != null)
2090 // If there is more then one graphical path split them and create
2091 // image maps for every graphical path separately.
2092 GraphicsPathIterator iterator = new GraphicsPathIterator(region.Path);
2094 // There is more then one path.
2095 if (iterator.SubpathCount > 1)
2097 GraphicsPath subPath = new GraphicsPath();
2098 while (iterator.NextMarker(subPath) > 0 && pointVisible == false)
2100 if (subPath.IsVisible(newX, newY))
2102 pointVisible = true;
2104 subPath.Reset();
2108 // There is only one path
2109 else if (region.Path.IsVisible(newX, newY))
2111 pointVisible = true;
2114 else
2116 // Point is inside bounding rectangle and path is not specified
2117 pointVisible = true;
2120 // Check if point is inside the hot region
2121 if (pointVisible)
2123 HitTestResult hitTestToAdd = this.GetHitTestResult(
2124 region.SeriesName,
2125 region.PointIndex,
2126 region.Type,
2127 region.SelectedObject,
2128 region.SelectedSubObject
2131 int elementIndex = result.FindIndex(
2132 delegate(HitTestResult test)
2134 if (
2135 (test.ChartElementType == hitTestToAdd.ChartElementType) &&
2136 (test.Object == hitTestToAdd.Object) &&
2137 (test.SubObject == hitTestToAdd.SubObject) &&
2138 (test.Series == hitTestToAdd.Series) &&
2139 (test.PointIndex == hitTestToAdd.PointIndex)
2142 return true;
2144 return false;
2148 if (elementIndex == -1)
2150 result.Add(hitTestToAdd);
2155 if (result.Count == 0)
2157 result.Add(this.GetHitTestResult(String.Empty, 0, ChartElementType.Nothing, null, null));
2159 return result.ToArray();
2162 /// <summary>
2163 /// This method performs the hit test and returns a HitTestResult objects.
2164 /// </summary>
2165 /// <param name="x">X coordinate</param>
2166 /// <param name="y">Y coordinate</param>
2167 /// <returns>Hit test result object</returns>
2168 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
2169 Justification = "X and Y are cartesian coordinates and well understood")]
2170 internal HitTestResult HitTest(int x, int y)
2172 return this.HitTest(x, y, false, new ChartElementType[] {})[0];
2175 /// <summary>
2176 /// This method performs the hit test and returns a HitTestResult object.
2177 /// </summary>
2178 /// <param name="x">X coordinate</param>
2179 /// <param name="y">Y coordinate</param>
2180 /// <param name="ignoreTransparent">Indicates that transparent elements should be ignored.</param>
2181 /// <returns>Hit test result object</returns>
2182 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
2183 Justification = "X and Y are cartesian coordinates and well understood")]
2184 public HitTestResult HitTest(int x, int y, bool ignoreTransparent)
2186 return this.HitTest(x, y, ignoreTransparent, new ChartElementType[] { })[0];
2189 /// <summary>
2190 /// This method performs the hit test and returns a HitTestResult object.
2191 /// </summary>
2192 /// <param name="x">X coordinate</param>
2193 /// <param name="y">Y coordinate</param>
2194 /// <param name="requestedElement">Only this chart element will be hit tested.</param>
2195 /// <returns>Hit test result object</returns>
2196 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
2197 Justification = "X and Y are cartesian coordinates and well understood")]
2198 public HitTestResult HitTest(int x, int y, ChartElementType requestedElement)
2200 return this.HitTest(x, y, false, requestedElement)[0];
2203 /// <summary>
2204 /// Checks if chart element associated with hot region has transparent background.
2205 /// </summary>
2206 /// <param name="region">Element hot region.</param>
2207 /// <returns>True if chart element is transparent.</returns>
2208 private bool IsElementTransparent(HotRegion region)
2210 bool isTransparent = false;
2212 if (region.Type == ChartElementType.DataPoint)
2214 if (this.ChartControl != null)
2216 DataPoint dataPoint = region.SelectedObject as DataPoint;
2217 if (region.SeriesName.Length > 0)
2219 dataPoint = this.ChartControl.Series[region.SeriesName].Points[region.PointIndex];
2221 if (dataPoint != null && dataPoint.Color == Color.Transparent)
2223 isTransparent = true;
2227 else if (region.SelectedObject is Axis)
2229 if (((Axis)region.SelectedObject).LineColor == Color.Transparent)
2231 isTransparent = true;
2234 else if (region.SelectedObject is ChartArea)
2236 if (((ChartArea)region.SelectedObject).BackColor == Color.Transparent)
2238 isTransparent = true;
2241 else if (region.SelectedObject is Legend)
2243 if (((Legend)region.SelectedObject).BackColor == Color.Transparent)
2245 isTransparent = true;
2248 else if (region.SelectedObject is Grid)
2250 if (((Grid)region.SelectedObject).LineColor == Color.Transparent)
2252 isTransparent = true;
2255 else if (region.SelectedObject is StripLine)
2257 if (((StripLine)region.SelectedObject).BackColor == Color.Transparent)
2259 isTransparent = true;
2262 else if (region.SelectedObject is TickMark)
2264 if (((TickMark)region.SelectedObject).LineColor == Color.Transparent)
2266 isTransparent = true;
2269 else if (region.SelectedObject is Title)
2271 Title title = (Title)region.SelectedObject;
2272 if ((title.Text.Length == 0 || title.ForeColor == Color.Transparent) &&
2273 (title.BackColor == Color.Transparent || title.BackColor.IsEmpty))
2275 isTransparent = true;
2279 return isTransparent;
2282 /// <summary>
2283 /// Returns Hit Test Result object
2284 /// </summary>
2285 /// <param name="seriesName">Data series Name</param>
2286 /// <param name="pointIndex">Data point index</param>
2287 /// <param name="type">Selected Chart element type</param>
2288 /// <param name="obj">Selected object</param>
2289 /// <param name="subObject">Selected sub object</param>
2290 /// <returns>Hit test result object</returns>
2291 [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily",
2292 Justification = "Too large of a code change to justify making this change")]
2293 internal HitTestResult GetHitTestResult(
2294 string seriesName,
2295 int pointIndex,
2296 ChartElementType type,
2297 object obj,
2298 object subObject)
2300 HitTestResult result = new HitTestResult();
2301 Chart chart = this.ChartControl;
2302 // If data point is selected convert series
2303 // name to series object.
2304 if (seriesName.Length > 0)
2306 result.Series = chart.Series[seriesName];
2309 // Selected Object
2310 result.Object = obj;
2312 result.SubObject = subObject;
2314 result.PointIndex = pointIndex;
2315 result.ChartElementType = type;
2317 #if Microsoft_CONTROL
2318 AxisScrollBar scrollBar;
2319 #endif // Microsoft_CONTROL
2321 switch (type)
2323 case ChartElementType.Axis:
2324 Axis axis = (Axis)obj;
2325 result.Axis = axis;
2326 if (axis != null)
2328 result.ChartArea = axis.ChartArea;
2330 break;
2331 case ChartElementType.DataPoint:
2333 if (chart.Series.IndexOf(seriesName) >= 0 &&
2334 pointIndex < chart.Series[seriesName].Points.Count)
2336 DataPoint dataPoint = chart.Series[seriesName].Points[pointIndex];
2337 result.Axis = null;
2338 result.ChartArea = chart.ChartAreas[dataPoint.series.ChartArea];
2339 result.Object = dataPoint;
2341 break;
2344 case ChartElementType.DataPointLabel:
2346 if (chart.Series.IndexOf(seriesName) >= 0 &&
2347 pointIndex < chart.Series[seriesName].Points.Count)
2349 DataPoint dataPoint = chart.Series[seriesName].Points[pointIndex];
2350 result.Axis = null;
2351 result.ChartArea = chart.ChartAreas[dataPoint.series.ChartArea];
2352 result.Object = dataPoint;
2354 break;
2357 case ChartElementType.Gridlines:
2358 Grid gridLines = (Grid)obj;
2359 result.Axis = gridLines.Axis;
2360 if (gridLines.Axis != null)
2362 result.ChartArea = gridLines.Axis.ChartArea;
2364 break;
2365 case ChartElementType.LegendArea:
2366 result.Axis = null;
2367 result.ChartArea = null;
2368 break;
2369 case ChartElementType.LegendItem:
2370 result.PointIndex = ((LegendItem)obj).SeriesPointIndex;
2371 result.Axis = null;
2372 result.ChartArea = null;
2373 break;
2374 case ChartElementType.PlottingArea:
2375 ChartArea area = (ChartArea)obj;
2376 result.Axis = null;
2377 result.ChartArea = area;
2378 break;
2379 case ChartElementType.StripLines:
2380 StripLine stripLines = (StripLine)obj;
2381 result.Axis = stripLines.Axis;
2382 if (stripLines.Axis != null)
2384 result.ChartArea = stripLines.Axis.ChartArea;
2386 break;
2387 case ChartElementType.TickMarks:
2388 TickMark tickMarks = (TickMark)obj;
2389 result.Axis = tickMarks.Axis;
2390 if (tickMarks.Axis != null)
2392 result.ChartArea = tickMarks.Axis.ChartArea;
2394 break;
2395 case ChartElementType.Title:
2396 result.Axis = null;
2397 result.ChartArea = null;
2398 break;
2399 case ChartElementType.AxisLabels:
2400 if (obj is CustomLabel)
2402 CustomLabel label = (CustomLabel)obj;
2403 result.Axis = label.Axis;
2404 result.ChartArea = label.Axis!=null ? label.Axis.ChartArea : null;
2406 break;
2407 case ChartElementType.AxisLabelImage:
2408 if (obj is CustomLabel)
2410 CustomLabel label = (CustomLabel)obj;
2411 result.Axis = label.Axis;
2412 result.ChartArea = label.Axis!=null ? label.Axis.ChartArea : null;
2414 break;
2415 case ChartElementType.AxisTitle:
2416 if (obj is Axis)
2418 result.Axis = (Axis)obj;
2419 result.ChartArea = result.Axis.ChartArea;
2421 break;
2422 #if Microsoft_CONTROL
2423 case ChartElementType.ScrollBarLargeDecrement:
2424 scrollBar = (AxisScrollBar)obj;
2425 result.Axis = scrollBar.axis;
2426 if (scrollBar.axis != null)
2428 result.ChartArea = scrollBar.axis.ChartArea;
2430 break;
2431 case ChartElementType.ScrollBarLargeIncrement:
2432 scrollBar = (AxisScrollBar)obj;
2433 result.Axis = scrollBar.axis;
2434 if (scrollBar.axis != null)
2436 result.ChartArea = scrollBar.axis.ChartArea;
2438 break;
2439 case ChartElementType.ScrollBarSmallDecrement:
2440 scrollBar = (AxisScrollBar)obj;
2441 result.Axis = scrollBar.axis;
2442 if (scrollBar.axis != null)
2444 result.ChartArea = scrollBar.axis.ChartArea;
2446 break;
2447 case ChartElementType.ScrollBarSmallIncrement:
2448 scrollBar = (AxisScrollBar)obj;
2449 result.Axis = scrollBar.axis;
2450 if (scrollBar.axis != null)
2452 result.ChartArea = scrollBar.axis.ChartArea;
2454 break;
2455 case ChartElementType.ScrollBarThumbTracker:
2456 scrollBar = (AxisScrollBar)obj;
2457 result.Axis = scrollBar.axis;
2458 if (scrollBar.axis != null)
2460 result.ChartArea = scrollBar.axis.ChartArea;
2462 break;
2463 #endif // Microsoft_CONTROL
2465 case ChartElementType.Annotation:
2466 result.Axis = null;
2467 result.ChartArea = null;
2468 break;
2470 return result;
2473 #endregion //HitTest
2475 #region Outline
2477 /// <summary>
2478 /// Gets the chart element outline.
2479 /// </summary>
2480 /// <param name="chartObject">The chart object.</param>
2481 /// <param name="elementType">Type of the element.</param>
2482 /// <returns></returns>
2483 internal ChartElementOutline GetChartElementOutline(object chartObject, ChartElementType elementType)
2485 // Check arguments
2486 if (chartObject == null)
2487 throw new ArgumentNullException("chartObject");
2489 // Get outline
2490 ChartElementOutline result = new ChartElementOutline();
2491 chartObject = this.GetAutoGeneratedObject(chartObject);
2492 ArrayList list = this.GetMarkers(chartObject, elementType);
2493 result.Markers = new ReadOnlyCollection<PointF>((PointF[])list.ToArray(typeof(PointF)));
2494 result.OutlinePath = GetGraphicsPath(list, chartObject, elementType);
2495 return result;
2498 #endregion //Outline
2500 #region Selection
2502 /// <summary>
2503 /// Gets the graphics path.
2504 /// </summary>
2505 /// <param name="markers">The markers.</param>
2506 /// <param name="chartObject">The chart object.</param>
2507 /// <param name="elementType">Type of the element.</param>
2508 /// <returns></returns>
2509 private GraphicsPath GetGraphicsPath(IList markers, object chartObject, ChartElementType elementType)
2511 bool chartArea3D = false;
2512 ChartArea chartArea = chartObject as ChartArea;
2513 if (chartArea != null && elementType == ChartElementType.PlottingArea)
2515 chartArea3D = IsArea3D(chartArea);
2517 if (elementType != ChartElementType.DataPoint &&
2518 elementType != ChartElementType.Gridlines &&
2519 elementType != ChartElementType.StripLines &&
2520 elementType != ChartElementType.TickMarks &&
2521 !chartArea3D
2524 GraphicsPath path = new GraphicsPath();
2525 PointF[] points = new PointF[markers.Count];
2526 markers.CopyTo(points, 0);
2527 if (points.Length > 3)
2529 if (elementType == ChartElementType.DataPointLabel)
2531 for (int i = 0; i < points.Length; i += 4)
2533 RectangleF rect = RectangleF.FromLTRB(points[i].X, points[i].Y, points[i + 2].X, points[i + 2].Y);
2534 path.Reset();
2535 path.AddRectangle(Rectangle.Round(rect));
2538 else
2540 if (points.Length == 4)
2542 Point[] pointsAlligned = new Point[points.Length];
2543 for (int i = 0; i < points.Length; i++)
2545 pointsAlligned[i] = Point.Round(points[i]);
2547 path.AddPolygon(pointsAlligned);
2549 else
2551 path.AddPolygon(points);
2555 return path;
2557 return null;
2560 private static Int32 GetDataPointIndex(DataPoint dataPoint)
2562 int pointIndex = -1;
2563 if (dataPoint != null && dataPoint.series != null)
2565 pointIndex = dataPoint.series.Points.IndexOf(dataPoint);
2566 if (pointIndex == -1 && dataPoint.IsCustomPropertySet("OriginalPointIndex"))
2568 if (!Int32.TryParse(dataPoint.GetCustomProperty("OriginalPointIndex"), out pointIndex))
2569 return -1;
2572 return pointIndex;
2575 /// <summary>
2576 /// Gets the auto generated object.
2577 /// </summary>
2578 /// <param name="chartObject">The chart object.</param>
2579 /// <returns></returns>
2580 private object GetAutoGeneratedObject(object chartObject)
2582 DataPoint dataPoint = chartObject as DataPoint;
2583 if (dataPoint != null)
2585 if (dataPoint.series != null)
2587 string seriesName = dataPoint.series.Name;
2588 int pointIndex = dataPoint.series.Points.IndexOf(dataPoint);
2589 if (this.ChartControl.Series.IndexOf(seriesName) != -1)
2591 Series series = this.ChartControl.Series[seriesName];
2592 if (series.Points.Contains(dataPoint))
2594 return chartObject;
2596 if (pointIndex >= 0)
2598 if (series.Points.Count > pointIndex)
2600 return series.Points[pointIndex];
2607 Series asSeries = chartObject as Series;
2608 if (asSeries != null)
2610 if (this.ChartControl.Series.Contains(asSeries))
2612 return chartObject;
2614 if (this.ChartControl.Series.IndexOf(asSeries.Name) != -1)
2616 return this.ChartControl.Series[asSeries.Name];
2619 return chartObject;
2622 /// <summary>
2623 /// Gets the hot regions.
2624 /// </summary>
2625 /// <param name="cntxObj">The CNTX obj.</param>
2626 /// <param name="elementType">Type of the element.</param>
2627 /// <returns></returns>
2628 private HotRegion[] GetHotRegions(object cntxObj, ChartElementType elementType)
2630 ArrayList result = new ArrayList();
2631 HotRegionsList hrList = this.ChartPicture.Common.HotRegionsList;
2632 string dataPointSeries = String.Empty;
2633 int dataPointIndex = -1;
2635 for (int i = hrList.List.Count - 1; i >= 0; i--)
2637 HotRegion rgn = (HotRegion)hrList.List[i];
2638 if (rgn.Type == elementType)
2640 switch (rgn.Type)
2642 case ChartElementType.LegendItem:
2643 LegendItem legendItem = cntxObj as LegendItem;
2644 if (legendItem != null)
2646 if (((LegendItem)rgn.SelectedObject).Name == legendItem.Name)
2648 result.Add(rgn);
2651 break;
2652 case ChartElementType.AxisLabelImage:
2653 case ChartElementType.AxisLabels:
2654 CustomLabel label1 = cntxObj as CustomLabel;
2655 CustomLabel label2 = rgn.SelectedObject as CustomLabel;
2656 if (label1 != null)
2658 if (label1 != null && label2 != null)
2660 if (label1.Axis == label2.Axis)
2662 if (label1.FromPosition == label2.FromPosition &&
2663 label1.ToPosition == label2.ToPosition &&
2664 label1.RowIndex == label2.RowIndex)
2666 if (rgn.Path == null)
2668 result.Add(rgn);
2674 else
2676 Axis axis = cntxObj as Axis;
2677 if (axis != null)
2679 if (axis == label2.Axis)
2681 if (rgn.Path == null)
2683 result.Add(rgn);
2688 break;
2689 case ChartElementType.DataPointLabel:
2690 case ChartElementType.DataPoint:
2691 DataPoint dataPoint = cntxObj as DataPoint;
2692 if (dataPoint != null)
2694 if (String.IsNullOrEmpty(dataPointSeries) || dataPointIndex == -1)
2696 dataPointSeries = dataPoint.series.Name;
2697 dataPointIndex = GetDataPointIndex(dataPoint);
2699 if (rgn.PointIndex == dataPointIndex && rgn.SeriesName == dataPointSeries)
2701 result.Add(rgn);
2704 else
2706 DataPointCollection dataPointCollection = cntxObj as DataPointCollection;
2707 if (dataPointCollection != null)
2709 cntxObj = dataPointCollection.series;
2711 Series series = cntxObj as Series;
2712 if (series != null)
2714 if (String.IsNullOrEmpty(dataPointSeries) || dataPointIndex == -1)
2716 dataPointSeries = series.Name;
2718 if (rgn.SeriesName == dataPointSeries)
2720 result.Add(rgn);
2724 break;
2726 default:
2727 if (rgn.SelectedObject == cntxObj)
2729 result.Add(rgn);
2731 break;
2735 return (HotRegion[])result.ToArray(typeof(HotRegion));
2740 /// <summary>
2741 /// Gets the markers from regions.
2742 /// </summary>
2743 /// <param name="chartObject">The chart object.</param>
2744 /// <param name="elementType">Type of the element.</param>
2745 /// <returns></returns>
2746 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
2747 private ArrayList GetMarkersFromRegions(object chartObject, ChartElementType elementType)
2749 ArrayList list = new ArrayList();
2750 HotRegion[] regions = this.GetHotRegions(chartObject, elementType);
2751 ChartGraphics graph = this.Graph;
2752 RectangleF rect;
2754 Grid grid = chartObject as Grid;
2755 if (grid != null)
2757 foreach (HotRegion rgn in regions)
2759 if (!IsArea3D(grid.Axis.ChartArea))
2761 if (IsChartAreaCircular(grid.Axis.ChartArea))
2763 GraphicsPathIterator iterator = new GraphicsPathIterator(rgn.Path);
2765 // There is more then one path.
2766 if (iterator.SubpathCount > 1)
2768 GraphicsPath subPath = new GraphicsPath();
2769 while (iterator.NextMarker(subPath) > 0)
2771 rect = subPath.GetBounds();
2772 list.Add(new PointF(rect.Left + rect.Width / 2, rect.Top));
2773 list.Add(new PointF(rect.Right, rect.Top + rect.Height / 2));
2774 list.Add(new PointF(rect.Right - rect.Width / 2, rect.Bottom));
2775 list.Add(new PointF(rect.Left, rect.Bottom - rect.Height / 2));
2776 subPath.Reset();
2780 else
2782 // 2D
2783 rect = this.GetHotRegionRectangle(rgn, RectangleF.Empty, elementType);
2784 if (grid != null)
2786 if (grid.GetAxis().AxisPosition == AxisPosition.Bottom ||
2787 grid.GetAxis().AxisPosition == AxisPosition.Top)
2789 rect.Offset(rect.Width / 2, 0);
2790 rect.Width = 0;
2792 else
2794 rect.Offset(0, rect.Height / 2);
2795 rect.Height = 0;
2798 list.AddRange(this.GetMarkers(rect, false));
2801 else
2802 { // 3D
2803 PointF[] points = rgn.Path.PathPoints;
2804 for (int i = 0; i < points.Length - 3; i = i + 4)
2805 { //Each gridline has a corresponding set of 4 points in the path
2806 //One of the ends of a gridline is in the middle the line between points #0 and #3
2807 //Another ends of a gridline is in the middle the line between points #1 and #2
2808 //So we find those middles and put a marks to the ends of the gridline.
2809 PointF middleP0P3 = new PointF((points[i].X + points[i + 3].X) / 2f, (points[i].Y + points[i + 3].Y) / 2f);
2810 PointF middleP1P2 = new PointF((points[i + 1].X + points[i + 2].X) / 2f, (points[i + 1].Y + points[i + 2].Y) / 2f);
2811 list.Add(graph.GetAbsolutePoint(middleP0P3));
2812 list.Add(graph.GetAbsolutePoint(middleP1P2));
2816 return list;
2819 DataPoint dataPoint = chartObject as DataPoint;
2820 if (dataPoint != null && elementType != ChartElementType.DataPointLabel)
2822 rect = Rectangle.Empty;
2823 Series series = dataPoint.series;
2824 if (this.ChartControl.ChartAreas.IndexOf(series.ChartArea) == -1)
2826 return list;
2828 ChartArea area = this.ChartControl.ChartAreas[series.ChartArea];
2829 PointF pp = this.Transform3D(area, dataPoint);
2830 if (!(float.IsNaN(pp.X) || float.IsNaN(pp.Y)))
2832 list.Add(graph.GetAbsolutePoint(pp));
2834 return list;
2837 Axis axis = chartObject as Axis;
2838 if (axis != null && elementType == ChartElementType.AxisTitle)
2840 foreach (HotRegion rgn in regions)
2842 if (!IsArea3D(axis.ChartArea))
2843 { // 2D
2844 rect = this.GetHotRegionRectangle(rgn, RectangleF.Empty, elementType);
2845 list.AddRange(this.GetMarkers(rect, elementType));
2847 else
2848 { // 3D
2849 PointF[] points = rgn.Path.PathPoints;
2850 list.AddRange(points);
2853 return list;
2856 LegendItem legendItem = chartObject as LegendItem;
2857 if (legendItem != null)
2859 rect = Rectangle.Empty;
2860 foreach (HotRegion rgn in regions)
2862 rect = this.GetHotRegionRectangle(rgn, rect, elementType);
2864 if (!rect.IsEmpty)
2866 list.AddRange(this.GetMarkers(rect, elementType));
2868 return list;
2870 else if (chartObject is Annotation)
2872 rect = Rectangle.Empty;
2873 foreach (HotRegion rgn in regions)
2875 rect = this.GetHotRegionRectangle(rgn, rect, elementType);
2877 if (!rect.IsEmpty)
2879 list.AddRange(this.GetMarkers(rect, elementType));
2881 return list;
2883 foreach (HotRegion rgn in regions)
2885 rect = this.GetHotRegionRectangle(rgn, RectangleF.Empty, elementType);
2886 list.AddRange(this.GetMarkers(rect, elementType));
2888 return list;
2893 /// <summary>
2894 /// Gets the markers.
2895 /// </summary>
2896 /// <param name="chartObject">The chart object.</param>
2897 /// <param name="elementType">Type of the element.</param>
2898 /// <returns></returns>
2899 private ArrayList GetMarkers(object chartObject, ChartElementType elementType)
2901 ChartArea chartArea = chartObject as ChartArea;
2902 if (chartArea != null)
2904 return this.GetAreaMarkers(this.Graph, chartArea);
2908 Axis axis = chartObject as Axis;
2909 if (axis != null)
2911 if (
2912 elementType == ChartElementType.AxisLabelImage ||
2913 elementType == ChartElementType.AxisLabels ||
2914 elementType == ChartElementType.AxisTitle
2917 return this.GetMarkersFromRegions(chartObject, elementType);
2919 return this.GetAxisMarkers(this.Graph, axis);
2922 DataPoint dataPoint = chartObject as DataPoint;
2923 if (dataPoint != null)
2925 return this.GetMarkersFromRegions(chartObject, elementType);
2928 Series series = chartObject as Series;
2929 if (series != null)
2931 if (elementType == ChartElementType.DataPointLabel)
2933 return this.GetMarkersFromRegions(chartObject, elementType);
2935 return this.GetSeriesMarkers(series);
2938 return this.GetMarkersFromRegions(chartObject, elementType);
2941 /// <summary>
2942 /// Determines whether specified chart area is circular or not have axes. These chart areas contain pie, doughnut, polar, radar
2943 /// </summary>
2944 /// <param name="area">The area.</param>
2945 /// <returns>
2946 /// <c>true</c> if specified chart area is circular; otherwise, <c>false</c>.
2947 /// </returns>
2948 private Boolean IsChartAreaCircular(ChartArea area)
2950 foreach (object o in area.ChartTypes)
2952 ChartTypes.IChartType chartType = area.Common.ChartTypeRegistry.GetChartType(o.ToString());
2953 if (chartType != null && (chartType.CircularChartArea || !chartType.RequireAxes))
2955 return true;
2958 return false;
2961 /// <summary>
2962 /// Determines whether the chart area is in 3D mode.
2963 /// </summary>
2964 /// <param name="area">The area.</param>
2965 /// <returns>
2966 /// <c>true</c> if the chart area is in 3D mode; otherwise, <c>false</c>.
2967 /// </returns>
2968 private Boolean IsArea3D(ChartArea area)
2970 return area.Area3DStyle.Enable3D && !this.IsChartAreaCircular(area) && area.matrix3D != null && area.matrix3D.IsInitialized();
2973 /// <summary>
2974 /// Gets the series markers.
2975 /// </summary>
2976 /// <param name="series">The series.</param>
2977 /// <returns>List of PointF.</returns>
2978 private ArrayList GetSeriesMarkers(Series series)
2980 ArrayList list = new ArrayList();
2981 if (series != null)
2983 String areaName = series.ChartArea;
2985 if (String.IsNullOrEmpty(areaName))
2987 areaName = ChartPicture.ChartAreas.DefaultNameReference;
2990 if (ChartPicture.ChartAreas.IndexOf(areaName) != -1 && series.Enabled)
2993 ChartArea chartArea = ChartPicture.ChartAreas[areaName];
2995 if (ChartControl.Series.IndexOf(series.Name) != -1)
2997 series = ChartControl.Series[series.Name];
3000 DataPointCollection points = series.Points;
3001 // in design mode we have usually fake points
3002 if (points.Count == 0)
3004 points = series.fakeDataPoints;
3006 // transform points in 3D
3007 foreach (DataPoint point in points)
3009 PointF pp = this.Transform3D(chartArea, point);
3010 if (float.IsNaN(pp.X) || float.IsNaN(pp.Y))
3012 continue;
3014 list.Add(this.Graph.GetAbsolutePoint(pp));
3018 return list;
3021 /// <summary>
3022 /// Gets the axis markers - list of points where markers are drawn.
3023 /// </summary>
3024 /// <param name="graph">The graph.</param>
3025 /// <param name="axis">The axis.</param>
3026 /// <returns>List of PointF.</returns>
3027 private ArrayList GetAxisMarkers(ChartGraphics graph, Axis axis)
3029 ArrayList list = new ArrayList();
3030 if (axis == null)
3032 return list;
3034 PointF first = PointF.Empty;
3035 PointF second = PointF.Empty;
3037 // Set the position of axis
3038 switch (axis.AxisPosition)
3041 case AxisPosition.Left:
3043 first.X = (float)axis.GetAxisPosition();
3044 first.Y = axis.PlotAreaPosition.Y;
3045 second.X = (float)axis.GetAxisPosition();
3046 second.Y = axis.PlotAreaPosition.Bottom;
3047 first.X -= axis.labelSize + axis.markSize;
3048 break;
3050 case AxisPosition.Right:
3052 first.X = (float)axis.GetAxisPosition();
3053 first.Y = axis.PlotAreaPosition.Y;
3054 second.X = (float)axis.GetAxisPosition();
3055 second.Y = axis.PlotAreaPosition.Bottom;
3056 second.X += axis.labelSize + axis.markSize;
3057 break;
3059 case AxisPosition.Bottom:
3061 first.X = axis.PlotAreaPosition.X;
3062 first.Y = (float)axis.GetAxisPosition();
3063 second.X = axis.PlotAreaPosition.Right;
3064 second.Y = (float)axis.GetAxisPosition();
3065 second.Y += axis.labelSize + axis.markSize;
3066 break;
3068 case AxisPosition.Top:
3070 first.X = axis.PlotAreaPosition.X;
3071 first.Y = (float)axis.GetAxisPosition();
3072 second.X = axis.PlotAreaPosition.Right;
3073 second.Y = (float)axis.GetAxisPosition();
3074 first.Y -= axis.labelSize + axis.markSize;
3075 break;
3078 // Update axis line position for circular area
3079 if (axis.ChartArea.chartAreaIsCurcular)
3081 second.Y = axis.PlotAreaPosition.Y + axis.PlotAreaPosition.Height / 2f;
3084 RectangleF rect1 = new RectangleF(first.X, first.Y, second.X - first.X, second.Y - first.Y);
3086 SizeF size = graph.GetRelativeSize(new SizeF(3, 3));
3087 if (axis.AxisPosition == AxisPosition.Top || axis.AxisPosition == AxisPosition.Bottom)
3089 rect1.Inflate(2, size.Height);
3091 else
3093 rect1.Inflate(size.Width, 2);
3095 IList list1 = this.GetMarkers(rect1, ChartElementType.Axis);
3096 ChartArea area = axis.ChartArea;
3097 if (this.IsArea3D(area))
3100 Boolean axisOnEdge = false;
3101 float zPositon = axis.GetMarksZPosition(out axisOnEdge);
3103 // Transform coordinates
3104 Point3D[] points = new Point3D[list1.Count];
3105 for (int i = 0; i < list1.Count; i++)
3107 points[i] = new Point3D(((PointF)list1[i]).X, ((PointF)list1[i]).Y, zPositon);
3109 axis.ChartArea.matrix3D.TransformPoints(points);
3110 for (int i = 0; i < list1.Count; i++)
3112 list1[i] = points[i].PointF;
3115 foreach (PointF p in list1)
3117 list.Add(graph.GetAbsolutePoint(p));
3119 return list;
3122 /// <summary>
3123 /// Gets the area markers.
3124 /// </summary>
3125 /// <param name="graph">The graph.</param>
3126 /// <param name="area">The area.</param>
3127 /// <returns>List of PointF.</returns>
3128 private ArrayList GetAreaMarkers(ChartGraphics graph, ChartArea area)
3130 ArrayList list = new ArrayList();
3131 if (area == null)
3133 return list;
3135 IList list1 = this.GetMarkers(area.PlotAreaPosition.ToRectangleF(), ChartElementType.PlottingArea);
3136 if (this.IsChartAreaCircular(area))
3138 list1 = this.GetMarkers(area.lastAreaPosition, ChartElementType.PlottingArea);
3140 if (IsArea3D(area))
3142 float zPositon = 0; // area.areaSceneDepth;
3143 // Transform coordinates
3144 Point3D[] points = new Point3D[list1.Count];
3145 for (int i = 0; i < list1.Count; i++)
3147 points[i] = new Point3D(((PointF)list1[i]).X, ((PointF)list1[i]).Y, zPositon);
3149 area.matrix3D.TransformPoints(points);
3150 for (int i = 0; i < list1.Count; i++)
3152 list1[i] = points[i].PointF;
3155 foreach (PointF p in list1)
3157 list.Add(graph.GetAbsolutePoint(p));
3159 return list;
3162 /// <summary>
3163 /// Builds list of markers (PointF) based on rectangle
3164 /// </summary>
3165 /// <param name="rect">The rectangle</param>
3166 /// <param name="elementType">The type of chart elements to retrieve.</param>
3167 /// <returns>List of PointF</returns>
3168 private ArrayList GetMarkers(RectangleF rect, ChartElementType elementType)
3170 if (elementType.ToString().StartsWith("Legend", StringComparison.Ordinal) || elementType.ToString().StartsWith("Title", StringComparison.Ordinal))
3172 rect.Inflate(4f, 4f);
3174 if (elementType.ToString().StartsWith("PlottingArea", StringComparison.Ordinal))
3176 SizeF relSize = this.Graph.GetRelativeSize(new SizeF(4f, 4f));
3177 rect.Inflate(relSize.Width, relSize.Height);
3180 if ((elementType != ChartElementType.Nothing) && (elementType != ChartElementType.PlottingArea))
3182 return this.GetMarkers(rect, false);
3184 return this.GetMarkers(rect, true);
3188 /// <summary>
3189 /// Builds list of markers (PointF) based on rectangle
3190 /// </summary>
3191 /// <param name="rect">The rectangle</param>
3192 /// <param name="addAdditionalMarkers">Add additional markers to the rectangle.</param>
3193 /// <returns>List of PointF</returns>
3194 private ArrayList GetMarkers(RectangleF rect, Boolean addAdditionalMarkers)
3196 ArrayList list = new ArrayList();
3197 if (!addAdditionalMarkers)
3199 if (rect.Width > 0 && rect.Height > 0)
3201 list.Add(new PointF(rect.Left, rect.Top));
3202 list.Add(new PointF(rect.Right, rect.Top));
3203 list.Add(new PointF(rect.Right, rect.Bottom));
3204 list.Add(new PointF(rect.Left, rect.Bottom));
3206 else if (rect.Width > 0)
3208 list.Add(new PointF(rect.Left, rect.Top));
3209 list.Add(new PointF(rect.Right, rect.Top));
3211 else if (rect.Height > 0)
3213 list.Add(new PointF(rect.Left, rect.Top));
3214 list.Add(new PointF(rect.Left, rect.Bottom));
3217 else
3219 if (rect.Width > 0)
3221 list.Add(new PointF(rect.Left, rect.Top));
3223 if (rect.Width > 30)
3225 list.Add(new PointF(rect.Left + rect.Width / 2, rect.Top));
3228 list.Add(new PointF(rect.Right, rect.Top));
3230 if (rect.Height > 30)
3232 list.Add(new PointF(rect.Right, rect.Top + rect.Height / 2));
3235 list.Add(new PointF(rect.Right, rect.Bottom));
3236 if (rect.Width > 30)
3238 list.Add(new PointF(rect.Left + rect.Width / 2, rect.Bottom));
3241 list.Add(new PointF(rect.Left, rect.Bottom));
3242 if (rect.Height > 30)
3244 list.Add(new PointF(rect.Left, rect.Top + rect.Height / 2));
3248 else if (rect.Width > 0)
3250 list.Add(new PointF(rect.Left, rect.Top));
3252 if (rect.Width > 30)
3254 list.Add(new PointF(rect.Left + rect.Width / 2, rect.Top));
3257 list.Add(new PointF(rect.Right, rect.Top));
3259 else if (rect.Height > 0)
3261 list.Add(new PointF(rect.Left, rect.Bottom));
3262 if (rect.Height > 30)
3264 list.Add(new PointF(rect.Left, rect.Top + rect.Height / 2));
3266 list.Add(new PointF(rect.Left, rect.Top));
3269 return list;
3272 /// <summary>
3273 /// Gets the region markers from graphics path.
3274 /// </summary>
3275 /// <param name="path">The path.</param>
3276 /// <returns>List of PointF.</returns>
3277 private ArrayList GetRegionMarkers(GraphicsPath path)
3279 return new ArrayList(path.PathPoints);
3282 /// <summary>
3283 /// Calculates a DataPoint of 3D area into PointF to draw.
3284 /// </summary>
3285 /// <param name="chartArea">3D chart area</param>
3286 /// <param name="point">The DataPoint</param>
3287 /// <returns>Calculated PointF</returns>
3288 private PointF Transform3D(ChartArea chartArea, DataPoint point)
3290 if (chartArea is ChartArea && IsArea3D(chartArea))
3292 // Get anotation Z coordinate (use scene depth or anchored point Z position)
3293 float positionZ = chartArea.areaSceneDepth;
3294 if (point != null && point.series != null)
3296 float depth = 0f;
3297 chartArea.GetSeriesZPositionAndDepth(
3298 point.series,
3299 out depth,
3300 out positionZ);
3301 positionZ += depth / 2f;
3304 PointF pf = point.positionRel;
3306 // Define 3D points of annotation object
3307 Point3D[] annot3DPoints = new Point3D[1];
3308 annot3DPoints[0] = new Point3D(pf.X, pf.Y, positionZ);
3310 // Tranform cube coordinates
3311 chartArea.matrix3D.TransformPoints(annot3DPoints);
3313 return annot3DPoints[0].PointF;
3315 return point.positionRel;
3318 /// <summary>
3319 /// Gets the hot region rectangle.
3320 /// </summary>
3321 /// <param name="rgn">The hot region.</param>
3322 /// <param name="unionWith">The rectangle to union with.</param>
3323 /// <param name="elementType">The type of the element.</param>
3324 /// <returns>Returns the rectangle around the hot region.</returns>
3325 private RectangleF GetHotRegionRectangle(HotRegion rgn, RectangleF unionWith, ChartElementType elementType)
3327 RectangleF rect;
3328 if (rgn.Path != null)
3330 rect = rgn.Path.GetBounds();
3332 else
3334 rect = rgn.BoundingRectangle;
3336 if (rgn.RelativeCoordinates)
3338 rect = this.Graph.GetAbsoluteRectangle(rect);
3340 if (elementType == ChartElementType.AxisLabels)
3342 if (rect.Width > rect.Height)
3344 rect.Inflate(-5, -2);
3346 else if (rect.Width < rect.Height)
3348 rect.Inflate(-2, -5);
3351 if (!unionWith.IsEmpty)
3353 return RectangleF.Union(unionWith, rect);
3355 return rect;
3358 #endregion //Selection
3360 #endregion //Tooltips
3362 #region IServiceProvider Members
3364 /// <summary>
3365 /// Gets the service object of the specified type.
3366 /// </summary>
3367 /// <param name="serviceType">An object that specifies the type of service object to get.</param>
3368 /// <returns>
3369 /// A service object of type <paramref name="serviceType"/>. It returns null
3370 /// if there is no service object of type <paramref name="serviceType"/>.
3371 /// </returns>
3372 object IServiceProvider.GetService(Type serviceType)
3374 if (serviceType == typeof(Selection))
3376 return this;
3378 if (_service != null)
3380 return _service.GetService(serviceType);
3382 return null;
3385 #endregion
3390 #if Microsoft_CONTROL
3391 /// <summary>
3392 /// The ToolTipEventArgs class stores the tool tips event arguments.
3393 /// </summary>
3394 public class ToolTipEventArgs : EventArgs
3396 #region Private fields
3398 // Private fields for properties values storage
3399 private int x = 0;
3400 private int y = 0;
3401 private string text = "";
3402 private HitTestResult result = new HitTestResult();
3404 #endregion
3406 #region Constructors
3408 /// <summary>
3409 /// ToolTipEventArgs constructor. Creates ToolTip event arguments.
3410 /// </summary>
3411 /// <param name="x">X-coordinate of mouse.</param>
3412 /// <param name="y">Y-coordinate of mouse.</param>
3413 /// <param name="text">Tooltip text.</param>
3414 /// <param name="result">Hit test result object.</param>
3415 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
3416 Justification = "X and Y are cartesian coordinates and well understood")]
3417 public ToolTipEventArgs(int x, int y, string text, HitTestResult result)
3419 this.x = x;
3420 this.y = y;
3421 this.text = text;
3422 this.result = result;
3425 #endregion
3427 #region Properties
3429 /// <summary>
3430 /// Gets the x-coordinate of the mouse.
3431 /// </summary>
3433 SRDescription("DescriptionAttributeToolTipEventArgs_X"),
3435 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "X")]
3436 public int X
3440 return x;
3444 /// <summary>
3445 /// Gets the result of the hit test.
3446 /// </summary>
3448 SRDescription("DescriptionAttributeToolTipEventArgs_HitTestResult"),
3450 public HitTestResult HitTestResult
3454 return result;
3458 /// <summary>
3459 /// Gets the y-coordinate of the mouse.
3460 /// </summary>
3462 SRDescription("DescriptionAttributeToolTipEventArgs_Y"),
3464 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Y")]
3465 public int Y
3469 return y;
3473 /// <summary>
3474 /// Gets the text of the tooltip.
3475 /// </summary>
3477 SRDescription("DescriptionAttributeToolTipEventArgs_Text"),
3479 public string Text
3483 return text;
3487 text = value;
3491 #endregion
3494 #endif // #if Microsoft_CONTROL