Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Web.DataVisualization / Common / DataManager / DataPoint.cs
blobde9402c6c5e0cf71b1a18dcd76d05e7d1deba11d
1 //-------------------------------------------------------------
2 // <copyright company=’Microsoft Corporation’>
3 // Copyright © Microsoft Corporation. All Rights Reserved.
4 // </copyright>
5 //-------------------------------------------------------------
6 // @owner=alexgor, deliant
7 //=================================================================
8 // File: DataPoint.cs
9 //
10 // Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Data
12 // Classes: DataPoint, DataPointCustomProperties, DataPointCollection,
13 // DataPointComparer, DataPoint3D, CustomProperties
15 // Purpose: Classes related to the Data Points:
16 // DataPointCollection - data points collection class
17 // DataPoint - data point properties and methods
18 // DataPointCustomProperties - data point & series properties
19 // DataPointComparer - used for sorting data points in series
21 // Reviewed: AG - Aug 1, 2002, GS - Aug 7, 2002
23 //===================================================================
26 #region Used namespaces
28 using System;
29 using System.Collections;
30 using System.Collections.Specialized;
31 using System.ComponentModel;
32 using System.ComponentModel.Design;
33 using System.Data;
34 using System.Data.Common;
35 using System.Drawing;
36 using System.Drawing.Design;
37 using System.Drawing.Drawing2D;
38 using System.Globalization;
39 using System.Diagnostics.CodeAnalysis;
40 using System.Collections.Generic;
41 using System.Collections.ObjectModel;
42 using System.Text;
44 #if Microsoft_CONTROL
45 using System.Windows.Forms.DataVisualization.Charting;
46 using System.Windows.Forms.DataVisualization.Charting.Data;
47 using System.Windows.Forms.DataVisualization.Charting.ChartTypes;
48 using System.Windows.Forms.DataVisualization.Charting.Utilities;
49 using System.Windows.Forms.DataVisualization.Charting.Borders3D;
52 using System.ComponentModel.Design.Serialization;
53 using System.Reflection;
54 using System.CodeDom;
55 using System.Windows.Forms.Design;
56 #else
57 using System.Web;
58 using System.Web.UI;
59 using System.Web.UI.DataVisualization.Charting;
60 using System.Web.UI.DataVisualization.Charting.Utilities;
61 using System.IO;
63 #endif
66 #endregion
68 #if Microsoft_CONTROL
69 namespace System.Windows.Forms.DataVisualization.Charting
70 #else
71 namespace System.Web.UI.DataVisualization.Charting
72 #endif
74 #region CustomProperties enumeration
76 /// <summary>
77 /// Enumeration of common properties names.
78 /// </summary>
79 internal enum CommonCustomProperties
81 PointName,
82 Label,
83 AxisLabel,
84 LabelFormat,
85 IsValueShownAsLabel,
86 Color,
87 BorderColor,
88 BorderDashStyle,
89 BorderWidth,
90 BackImage,
91 BackImageWrapMode,
92 BackImageAlignment,
93 BackImageTransparentColor,
94 BackGradientStyle,
95 BackSecondaryColor,
96 BackHatchStyle,
97 Font,
98 LabelForeColor,
99 LabelAngle,
100 MarkerStyle,
101 MarkerSize,
102 MarkerImage,
103 MarkerImageTransparentColor,
104 MarkerColor,
105 MarkerBorderColor,
106 MarkerBorderWidth,
107 MapAreaAttributes,
108 PostBackValue,
109 MapAreaType,
110 LegendMapAreaType,
111 LabelMapAreaType,
112 Url,
113 ToolTip,
114 Tag,
115 LegendUrl,
116 LegendToolTip,
117 LegendText,
118 LegendMapAreaAttributes,
119 LegendPostBackValue,
120 IsVisibleInLegend,
121 LabelUrl,
122 LabelToolTip,
123 LabelMapAreaAttributes,
124 LabelPostBackValue,
125 LabelBorderColor,
126 LabelBorderDashStyle,
127 LabelBorderWidth,
128 LabelBackColor,
131 #endregion
133 /// <summary>
134 /// Data points comparer class
135 /// </summary>
137 SRDescription("DescriptionAttributeDataPointComparer_DataPointComparer")
139 public class DataPointComparer : IComparer<DataPoint>
141 #region Fields
143 // Sorting order
144 private PointSortOrder _sortingOrder = PointSortOrder.Ascending;
146 // Sorting value index
147 private int _sortingValueIndex = 1;
149 #endregion
151 #region Constructors
153 /// <summary>
154 /// Private default constructor.
155 /// </summary>
156 private DataPointComparer()
160 /// <summary>
161 /// Data points comparer class constructor.
162 /// </summary>
163 /// <param name="series">Data series.</param>
164 /// <param name="sortOrder">Sorting order.</param>
165 /// <param name="sortBy">Value used for sorting ("X", "Y or Y1", "Y2", ...).</param>
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 DataPointComparer(Series series, PointSortOrder sortOrder, string sortBy)
172 // Check if sorting value is valid
173 sortBy = sortBy.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
174 if(String.Compare(sortBy, "X", StringComparison.Ordinal) == 0)
176 _sortingValueIndex = -1;
178 else if (String.Compare(sortBy, "Y", StringComparison.Ordinal) == 0)
180 _sortingValueIndex = 0;
182 else if (String.Compare(sortBy, "AXISLABEL", StringComparison.Ordinal) == 0)
184 _sortingValueIndex = -2;
186 else if(sortBy.Length == 2 &&
187 sortBy.StartsWith("Y", StringComparison.Ordinal) &&
188 Char.IsDigit(sortBy[1]))
190 _sortingValueIndex = Int32.Parse(sortBy.Substring(1), System.Globalization.CultureInfo.InvariantCulture) - 1;
192 else
194 throw(new ArgumentException( SR.ExceptionDataPointConverterInvalidSorting, "sortBy"));
197 // Check if data series support as many Y values as required
198 if(_sortingValueIndex > 0 && _sortingValueIndex >= series.YValuesPerPoint)
200 throw(new ArgumentException( SR.ExceptionDataPointConverterUnavailableSorting(sortBy, series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture) ), "sortBy"));
203 this._sortingOrder = sortOrder;
206 #endregion
208 #region Comparing method
210 /// <summary>
211 /// Compares two data points.
212 /// </summary>
213 /// <param name="x">First data point.</param>
214 /// <param name="y">Second data point.</param>
215 /// <returns>If the two values are equal, it returns zero. If point 1 is greater than point 2,
216 /// it returns a positive integer; otherwise, it returns a negative integer.
217 /// </returns>
218 public int Compare(DataPoint x, DataPoint y)
220 int result = -1;
222 // Compare X value
223 if(_sortingValueIndex == -1)
225 result = x.XValue.CompareTo(y.XValue);
227 // Compare Axis Label value
228 else if(_sortingValueIndex == -2)
230 result = string.Compare(x.AxisLabel, y.AxisLabel, StringComparison.CurrentCulture);
232 // Compare one of the Y value(s)
233 else
235 result = x.YValues[_sortingValueIndex].CompareTo(y.YValues[_sortingValueIndex]);
238 // Invert result depending on the sorting order
239 if(this._sortingOrder == PointSortOrder.Descending)
241 result = -result;
244 return result;
247 #endregion
250 /// <summary>
251 /// A collection of data points.
252 /// </summary>
254 SRDescription("DescriptionAttributeDataPointCollection_DataPointCollection"),
256 #if ASPPERM_35
257 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
258 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
259 #endif
260 #if !Microsoft_CONTROL
261 [Themeable(false)]
262 #endif
263 public class DataPointCollection : ChartElementCollection<DataPoint>
265 #region Fields
267 // Reference to the sereies of data points
268 internal Series series = null;
270 #endregion
272 #region Constructors and Initialization
274 /// <summary>
275 /// Data Point Collection object constructor.
276 /// </summary>
277 /// <param name="series">Series object, which the Data Point Collection belongs to.</param>
278 internal DataPointCollection(Series series) : base(series)
280 this.series = series;
283 /// <summary>
284 /// Initialize data point series and name.
285 /// </summary>
286 /// <param name="dataPoint">Reference to the data point object to initialize.</param>
287 internal void DataPointInit(ref DataPoint dataPoint)
289 DataPointInit(this.series, ref dataPoint);
292 /// <summary>
293 /// Initialize data point series and name.
294 /// </summary>
295 /// <param name="series">Series the data point belongs to.</param>
296 /// <param name="dataPoint">Reference to the data point object to initialize.</param>
297 internal static void DataPointInit(Series series, ref DataPoint dataPoint)
299 dataPoint.series = series;
301 if(dataPoint.AxisLabel.Length > 0 && series != null)
303 series.noLabelsInPoints = false;
306 #if Microsoft_CONTROL
307 // Set flag that tooltips flags should be recalculated
308 if(dataPoint.ToolTip.Length > 0 &&
309 dataPoint.LegendToolTip.Length > 0 &&
310 dataPoint.LabelToolTip.Length > 0 &&
311 series != null && series.Chart != null && series.Chart.selection != null)
313 series.Chart.selection.enabledChecked = false;
315 #endif
318 #endregion
320 #region Data point binding, adding and inserting methods
322 /// <summary>
323 /// Adds the new DataPoint to a collection and sets its Y values.
324 /// </summary>
325 /// <param name="y">The y.</param>
326 /// <returns></returns>
327 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
328 Justification = "X and Y are cartesian coordinates and well understood")]
329 public DataPoint Add(params double[] y)
331 DataPoint point = new DataPoint(0, y);
332 this.Add(point);
333 return point;
336 /// <summary>
337 /// Parse the input parameter with other point attribute binding rule
338 /// in format: PointProperty=Field[{Format}] [,PointProperty=Field[{Format}]].
339 /// For example: "Tooltip=Price{C1},Url=WebSiteName".
340 /// </summary>
341 /// <param name="otherFields">Other fields parameter.</param>
342 /// <param name="otherAttributeNames">Returns array of attribute names.</param>
343 /// <param name="otherFieldNames">Returns array of field names.</param>
344 /// <param name="otherValueFormat">Returns array of format strings.</param>
345 internal static void ParsePointFieldsParameter(
346 string otherFields,
347 ref string[] otherAttributeNames,
348 ref string[] otherFieldNames,
349 ref string[] otherValueFormat)
351 if(otherFields != null && otherFields.Length > 0)
353 // Split string by comma
354 otherAttributeNames = otherFields.Replace(",,", "\n").Split(',');
355 otherFieldNames = new string[otherAttributeNames.Length];
356 otherValueFormat = new string[otherAttributeNames.Length];
358 // Loop through all strings
359 for(int index = 0; index < otherAttributeNames.Length; index++)
361 // Split string by equal sign
362 int equalSignIndex = otherAttributeNames[index].IndexOf('=');
363 if(equalSignIndex > 0)
365 otherFieldNames[index] = otherAttributeNames[index].Substring(equalSignIndex + 1);
366 otherAttributeNames[index] = otherAttributeNames[index].Substring(0, equalSignIndex);
368 else
370 throw (new ArgumentException(SR.ExceptionParameterFormatInvalid, "otherFields"));
373 // Check if format string was specified
374 int bracketIndex = otherFieldNames[index].IndexOf('{');
375 if(bracketIndex > 0 && otherFieldNames[index][otherFieldNames[index].Length - 1] == '}')
377 otherValueFormat[index] = otherFieldNames[index].Substring(bracketIndex + 1);
378 otherValueFormat[index] = otherValueFormat[index].Trim('{', '}');
379 otherFieldNames[index] = otherFieldNames[index].Substring(0, bracketIndex);
382 // Trim and replace new line character
383 otherAttributeNames[index] = otherAttributeNames[index].Trim().Replace("\n", ",");
384 otherFieldNames[index] = otherFieldNames[index].Trim().Replace("\n", ",");
385 if ( otherValueFormat[index] != null )
386 otherValueFormat[index] = otherValueFormat[index].Trim().Replace("\n", ",");
391 /// <summary>
392 /// Data bind X, Y and other values (like Tooltip, LabelStyle,...) of the data points to the data source.
393 /// Data source can be the Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow.
394 /// </summary>
395 /// <param name="dataSource">Data source.</param>
396 /// <param name="xField">Name of the field for X values.</param>
397 /// <param name="yFields">Comma separated names of the fields for Y values.</param>
398 /// <param name="otherFields">Other point properties binding rule in format: PointProperty=Field[{Format}] [,PointProperty=Field[{Format}]]. For example: "Tooltip=Price{C1},Url=WebSiteName".</param>
399 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
400 Justification = "X and Y are cartesian coordinates and well understood")]
401 public void DataBind(IEnumerable dataSource, string xField, string yFields, string otherFields)
403 // Check arguments
404 if (dataSource == null)
405 throw new ArgumentNullException("dataSource", SR.ExceptionDataPointInsertionNoDataSource);
406 if (dataSource is string)
407 throw (new ArgumentException(SR.ExceptionDataBindSeriesToString, "dataSource"));
408 if (yFields == null)
409 throw new ArgumentNullException("yFields");
411 // Convert comma separated Y values field names string to array of names
412 string[] yFieldNames = yFields.Replace(",,", "\n").Split(',');
413 for(int index = 0; index < yFieldNames.Length; index++)
415 yFieldNames[index] = yFieldNames[index].Replace("\n", ",");
418 if (yFieldNames.GetLength(0) > series.YValuesPerPoint)
419 throw (new ArgumentOutOfRangeException("yFields", SR.ExceptionDataPointYValuesCountMismatch(series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture))));
421 // Convert other fields/properties names to two arrays of names
422 string[] otherAttributeNames = null;
423 string[] otherFieldNames = null;
424 string[] otherValueFormat = null;
425 ParsePointFieldsParameter(
426 otherFields,
427 ref otherAttributeNames,
428 ref otherFieldNames,
429 ref otherValueFormat);
431 // Remove all existing data points
432 this.Clear();
434 // Get and reset enumerator
435 IEnumerator enumerator = GetDataSourceEnumerator(dataSource);
436 if (enumerator.GetType() != typeof(System.Data.Common.DbEnumerator))
440 enumerator.Reset();
442 // Some enumerators may not support Resetting
443 catch (InvalidOperationException)
446 catch (NotImplementedException)
449 catch (NotSupportedException)
454 // Add data points
455 bool valueExsist = true;
456 object[] yValuesObj = new object[yFieldNames.Length];
457 object xValueObj = null;
458 bool autoDetectType = true;
460 this.SuspendUpdates();
465 // Move to the next objects in the enumerations
466 if (valueExsist)
468 valueExsist = enumerator.MoveNext();
471 // Auto detect valu(s) type
472 if (autoDetectType)
474 autoDetectType = false;
475 AutoDetectValuesType(this.series, enumerator, xField, enumerator, yFieldNames[0]);
478 // Create and initialize data point
479 if (valueExsist)
481 DataPoint newDataPoint = new DataPoint(series);
482 bool emptyValues = false;
484 // Set X to the value provided
485 if (xField.Length > 0)
487 xValueObj = ConvertEnumerationItem(enumerator.Current, xField);
488 if (IsEmptyValue(xValueObj))
490 emptyValues = true;
491 xValueObj = 0.0;
495 // Set Y values
496 if (yFieldNames.Length == 0)
498 yValuesObj[0] = ConvertEnumerationItem(enumerator.Current, null);
499 if (IsEmptyValue(yValuesObj[0]))
501 emptyValues = true;
502 yValuesObj[0] = 0.0;
505 else
507 for (int i = 0; i < yFieldNames.Length; i++)
509 yValuesObj[i] = ConvertEnumerationItem(enumerator.Current, yFieldNames[i]);
510 if (IsEmptyValue(yValuesObj[i]))
512 emptyValues = true;
513 yValuesObj[i] = 0.0;
518 // Set other values
519 if (otherAttributeNames != null &&
520 otherAttributeNames.Length > 0)
522 for (int i = 0; i < otherFieldNames.Length; i++)
524 // Get object by field name
525 object obj = ConvertEnumerationItem(enumerator.Current, otherFieldNames[i]);
526 if (!IsEmptyValue(obj))
528 newDataPoint.SetPointCustomProperty(
529 obj,
530 otherAttributeNames[i],
531 otherValueFormat[i]);
536 // IsEmpty value was detected
537 if (emptyValues)
539 if (xValueObj != null)
541 newDataPoint.SetValueXY(xValueObj, yValuesObj);
543 else
545 newDataPoint.SetValueXY(0, yValuesObj);
547 DataPointInit(ref newDataPoint);
548 newDataPoint.IsEmpty = true;
549 this.Add(newDataPoint);
551 else
553 if (xValueObj != null)
555 newDataPoint.SetValueXY(xValueObj, yValuesObj);
557 else
559 newDataPoint.SetValueXY(0, yValuesObj);
561 DataPointInit(ref newDataPoint);
562 this.Add(newDataPoint);
566 } while (valueExsist);
569 finally
571 this.ResumeUpdates();
575 /// <summary>
576 /// Data bind Y values of the data points to the data source.
577 /// Data source can be the Array, Collection, Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow.
578 /// </summary>
579 /// <param name="yValue">One or more enumerable objects with Y values.</param>
580 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
581 Justification = "Y is a cartesian coordinate and well understood")]
582 public void DataBindY(params IEnumerable[] yValue)
584 DataBindXY(null, yValue);
587 /// <summary>
588 /// Data bind X and Y values of the data points to the data source.
589 /// Data source can be the Array, Collection, Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow.
590 /// </summary>
591 /// <param name="xValue">Enumerable objects with X values.</param>
592 /// <param name="yValues">One or more enumerable objects with Y values.</param>
593 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
594 Justification = "X and Y are cartesian coordinates and well understood")]
595 public void DataBindXY(IEnumerable xValue, params IEnumerable[] yValues)
597 // Y value must be provided
598 if (yValues == null ||
599 yValues.Length==1 && yValues[0]==null)
600 throw new ArgumentNullException("yValues");
601 if (yValues.GetLength(0) == 0)
602 throw new ArgumentException(SR.ExceptionDataPointBindingYValueNotSpecified, "yValues");
604 // Double check that a string object is not provided for data binding
605 for(int i = 0; i < yValues.Length; i++)
607 if(yValues[i] is string)
609 throw (new ArgumentException(SR.ExceptionDataBindYValuesToString, "yValues"));
613 // Check if number of Y values do not out of range
614 if(yValues.GetLength(0) > series.YValuesPerPoint)
616 throw(new ArgumentOutOfRangeException("yValues", SR.ExceptionDataPointYValuesBindingCountMismatch( series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture) ) ) );
619 // Remove all existing data points
620 this.Clear();
622 // Reset X, Y enumerators
623 IEnumerator xEnumerator = null;
624 IEnumerator[] yEnumerator = new IEnumerator[yValues.GetLength(0)];
625 if(xValue != null)
627 // Double check that a string object is not provided for data binding
628 if(xValue is string)
630 throw (new ArgumentException(SR.ExceptionDataBindXValuesToString, "xValue"));
633 // Get and reset Y values enumerators
634 xEnumerator = GetDataSourceEnumerator(xValue);
635 if(xEnumerator.GetType() != typeof(System.Data.Common.DbEnumerator))
637 xEnumerator.Reset();
640 for(int i = 0; i < yValues.Length; i++)
642 // Get and reset Y values enumerators
643 yEnumerator[i] = GetDataSourceEnumerator(yValues[i]);
644 if(yEnumerator[i].GetType() != typeof(System.Data.Common.DbEnumerator))
646 yEnumerator[i].Reset();
650 // Add data points
651 bool xValueExsist = false;
652 bool yValueExsist = true;
653 object[] yValuesObj = new object[series.YValuesPerPoint];
654 object xValueObj = null;
655 bool autoDetectType = true;
657 SuspendUpdates();
662 // Move to the next objects in the enumerations
663 yValueExsist = true;
664 for (int i = 0; i < yValues.Length; i++)
666 if (yValueExsist)
668 yValueExsist = yEnumerator[i].MoveNext();
671 if (xValue != null)
673 xValueExsist = xEnumerator.MoveNext();
674 if (yValueExsist && !xValueExsist)
676 throw (new ArgumentOutOfRangeException("xValue", SR.ExceptionDataPointInsertionXValuesQtyIsLessYValues));
680 // Auto detect value(s) type
681 if (autoDetectType)
683 autoDetectType = false;
684 AutoDetectValuesType(this.series, xEnumerator, null, yEnumerator[0], null);
687 // Create and initialize data point
688 if (xValueExsist || yValueExsist)
690 DataPoint newDataPoint = new DataPoint(series);
691 bool emptyValues = false;
693 // Set X to the value provided
694 if (xValueExsist)
696 xValueObj = ConvertEnumerationItem(xEnumerator.Current, null);
697 if (xValueObj is System.DBNull || xValueObj == null)
699 emptyValues = true;
700 xValueObj = 0.0;
704 // Set Y values
705 for (int i = 0; i < yValues.Length; i++)
707 yValuesObj[i] = ConvertEnumerationItem(yEnumerator[i].Current, null);
708 if (yValuesObj[i] is System.DBNull || yValuesObj[i] == null)
710 emptyValues = true;
711 yValuesObj[i] = 0.0;
715 // IsEmpty value was detected
716 if (emptyValues)
718 if (xValueObj != null)
720 newDataPoint.SetValueXY(xValueObj, yValuesObj);
722 else
724 newDataPoint.SetValueXY(0, yValuesObj);
726 DataPointInit(ref newDataPoint);
727 newDataPoint.IsEmpty = true;
728 this.Add(newDataPoint);
730 else
732 if (xValueObj != null)
734 newDataPoint.SetValueXY(xValueObj, yValuesObj);
736 else
738 newDataPoint.SetValueXY(0, yValuesObj);
740 DataPointInit(ref newDataPoint);
741 this.Add(newDataPoint);
746 } while (xValueExsist || yValueExsist);
749 finally
751 this.ResumeUpdates();
755 /// <summary>
756 /// Data bind Y values of the data points to the data source.
757 /// Data source can be the Array, Collection, Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow.
758 /// </summary>
759 /// <param name="yValue">Enumerable objects with Y values.</param>
760 /// <param name="yFields">Name of the fields for Y values.</param>
761 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
762 Justification = "X and Y are cartesian coordinates and well understood")]
763 public void DataBindY(IEnumerable yValue, string yFields)
765 DataBindXY(null, null, yValue, yFields);
768 /// <summary>
769 /// Data bind X and Y values of the data points to the data source.
770 /// Data source can be the Array, Collection, Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow.
771 /// </summary>
772 /// <param name="xValue">Enumerable object with X values.</param>
773 /// <param name="xField">Name of the field for X values.</param>
774 /// <param name="yValue">Enumerable objects with Y values.</param>
775 /// <param name="yFields">Comma separated names of the fields for Y values.</param>
776 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
777 Justification = "X and Y are cartesian coordinates and well understood")]
778 public void DataBindXY(IEnumerable xValue, string xField, IEnumerable yValue, string yFields)
780 // Check arguments
781 if (xValue is string)
782 throw new ArgumentException(SR.ExceptionDataBindXValuesToString, "xValue");
783 if (yValue == null)
784 throw new ArgumentNullException("yValue", SR.ExceptionDataPointInsertionYValueNotSpecified);
785 if (yValue is string)
786 throw new ArgumentException(SR.ExceptionDataBindYValuesToString, "yValue");
787 if (yFields == null)
788 throw new ArgumentOutOfRangeException("yFields", SR.ExceptionDataPointYValuesCountMismatch(series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture)));
790 // Convert comma separated field names string to array of names
791 string[] yFieldNames = yFields.Replace(",,", "\n").Split(',');;
792 for(int index = 0; index < yFieldNames.Length; index++)
794 yFieldNames[index] = yFieldNames[index].Replace("\n", ",");
796 if (yFieldNames.GetLength(0) > series.YValuesPerPoint)
797 throw new ArgumentOutOfRangeException("yFields", SR.ExceptionDataPointYValuesCountMismatch(series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture)));
799 // Remove all existing data points
800 this.Clear();
802 // Reset X, Y enumerators
803 IEnumerator xEnumerator = null;
804 IEnumerator yEnumerator = GetDataSourceEnumerator(yValue);
806 if(yEnumerator.GetType() != typeof(System.Data.Common.DbEnumerator))
808 yEnumerator.Reset();
811 if(xValue != null)
813 if(xValue != yValue)
815 xEnumerator = GetDataSourceEnumerator(xValue);
816 if(xEnumerator.GetType() != typeof(System.Data.Common.DbEnumerator))
818 xEnumerator.Reset();
821 else
823 xEnumerator = yEnumerator;
827 // Add data points
828 bool xValueExsist = false;
829 bool yValueExsist = true;
830 object[] yValuesObj = new object[yFieldNames.Length];
831 object xValueObj = null;
832 bool autoDetectType = true;
834 this.SuspendUpdates();
839 // Move to the next objects in the enumerations
840 if (yValueExsist)
842 yValueExsist = yEnumerator.MoveNext();
844 if (xValue != null)
846 if (xValue != yValue)
848 xValueExsist = xEnumerator.MoveNext();
849 if (yValueExsist && !xValueExsist)
851 throw (new ArgumentOutOfRangeException("xValue", SR.ExceptionDataPointInsertionXValuesQtyIsLessYValues));
854 else
856 xValueExsist = yValueExsist;
860 // Auto detect valu(s) type
861 if (autoDetectType)
863 autoDetectType = false;
864 AutoDetectValuesType(this.series, xEnumerator, xField, yEnumerator, yFieldNames[0]);
867 // Create and initialize data point
868 if (xValueExsist || yValueExsist)
870 DataPoint newDataPoint = new DataPoint(series);
871 bool emptyValues = false;
873 // Set X to the value provided or use sequence numbers starting with 1
874 if (xValueExsist)
876 xValueObj = ConvertEnumerationItem(xEnumerator.Current, xField);
877 if (IsEmptyValue(xValueObj))
879 emptyValues = true;
880 xValueObj = 0.0;
885 if (yFieldNames.Length == 0)
887 yValuesObj[0] = ConvertEnumerationItem(yEnumerator.Current, null);
888 if (IsEmptyValue(yValuesObj[0]))
890 emptyValues = true;
891 yValuesObj[0] = 0.0;
894 else
896 for (int i = 0; i < yFieldNames.Length; i++)
898 yValuesObj[i] = ConvertEnumerationItem(yEnumerator.Current, yFieldNames[i]);
899 if (IsEmptyValue(yValuesObj[i]))
901 emptyValues = true;
902 yValuesObj[i] = 0.0;
907 // IsEmpty value was detected
908 if (emptyValues)
910 if (xValueObj != null)
912 newDataPoint.SetValueXY(xValueObj, yValuesObj);
914 else
916 newDataPoint.SetValueXY(0, yValuesObj);
918 DataPointInit(ref newDataPoint);
919 newDataPoint.IsEmpty = true;
920 this.Add(newDataPoint);
922 else
924 if (xValueObj != null)
926 newDataPoint.SetValueXY(xValueObj, yValuesObj);
928 else
930 newDataPoint.SetValueXY(0, yValuesObj);
932 DataPointInit(ref newDataPoint);
933 this.Add(newDataPoint);
937 } while (xValueExsist || yValueExsist);
940 finally
942 this.ResumeUpdates();
946 /// <summary>
947 /// Returns true if objet represents an empty value.
948 /// </summary>
949 /// <param name="val">Value to test.</param>
950 /// <returns>True if empty.</returns>
951 internal static bool IsEmptyValue(object val)
953 if(val is System.DBNull || val == null)
955 return true;
957 if(val is double && double.IsNaN((double)val))
959 return true;
961 if(val is Single && Single.IsNaN((Single)val))
963 return true;
966 return false;
969 /// <summary>
970 /// Adds one data point with one Y value.
971 /// </summary>
972 /// <param name="yValue">Y value of the data point.</param>
973 /// <returns>Index of newly added data point.</returns>
974 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
975 Justification = "Y is a cartesian coordinate and well understood")]
976 public int AddY(double yValue)
978 // Create new point object
979 DataPoint newDataPoint = new DataPoint(series);
980 newDataPoint.SetValueY(yValue);
981 DataPointInit(ref newDataPoint);
982 Add(newDataPoint);
983 return Count - 1;
986 /// <summary>
987 /// Adds one data point with one or more Y values.
988 /// </summary>
989 /// <param name="yValue">List of Y values of the data point.</param>
990 /// <returns>Index of newly added data point.</returns>
991 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
992 Justification = "Y is a cartesian coordinate and well understood")]
993 public int AddY(params object[] yValue)
995 //Check arguments
996 if (yValue == null ||
997 yValue.Length==1 && yValue[0]==null)
998 throw new ArgumentNullException("yValue");
1000 // Auto detect DateTime values type
1001 if(this.series.YValueType == ChartValueType.Auto &&
1002 yValue.Length > 0 &&
1003 yValue[0] != null)
1005 if (yValue[0] is DateTime)
1007 this.series.YValueType = ChartValueType.DateTime;
1008 this.series.autoYValueType = true;
1010 else if (yValue[0] is DateTimeOffset)
1012 this.series.YValueType = ChartValueType.DateTimeOffset;
1013 this.series.autoYValueType = true;
1017 // Create new point object
1018 DataPoint newDataPoint = new DataPoint(series);
1019 newDataPoint.SetValueY(yValue);
1020 DataPointInit(ref newDataPoint);
1021 Add(newDataPoint);
1022 return Count - 1;
1025 /// <summary>
1026 /// Adds one data point with X value and one Y value.
1027 /// </summary>
1028 /// <param name="yValue">Y value of the data point.</param>
1029 /// <param name="xValue">X value of the data point.</param>
1030 /// <returns>Index of newly added data poit.</returns>
1031 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
1032 Justification = "X and Y are cartesian coordinates and well understood")]
1033 public int AddXY(double xValue, double yValue)
1035 // Create new point object
1036 DataPoint newDataPoint = new DataPoint(series);
1037 newDataPoint.SetValueXY(xValue, yValue);
1038 DataPointInit(ref newDataPoint);
1039 Add(newDataPoint);
1040 return Count - 1;
1043 /// <summary>
1044 /// Adds one data point with X value and one or more Y values.
1045 /// </summary>
1046 /// <param name="yValue">List of Y values of the data point.</param>
1047 /// <param name="xValue">X value of the data point.</param>
1048 /// <returns>Index of newly added data poit.</returns>
1049 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
1050 Justification = "X and Y are cartesian coordinates and well understood")]
1051 public int AddXY(object xValue, params object[] yValue)
1054 // Auto detect DateTime and String values type
1055 if(this.series.XValueType == ChartValueType.Auto)
1057 if(xValue is DateTime)
1059 this.series.XValueType = ChartValueType.DateTime;
1061 if(xValue is DateTimeOffset)
1063 this.series.XValueType = ChartValueType.DateTimeOffset;
1065 if(xValue is string)
1067 this.series.XValueType = ChartValueType.String;
1070 this.series.autoXValueType = true;
1073 if(this.series.YValueType == ChartValueType.Auto &&
1074 yValue.Length > 0 &&
1075 yValue[0] != null)
1077 if (yValue[0] is DateTime)
1079 this.series.YValueType = ChartValueType.DateTime;
1080 this.series.autoYValueType = true;
1082 else if (yValue[0] is DateTimeOffset)
1084 this.series.YValueType = ChartValueType.DateTimeOffset;
1085 this.series.autoYValueType = true;
1089 // Create new point object
1090 DataPoint newDataPoint = new DataPoint(series);
1091 newDataPoint.SetValueXY(xValue, yValue);
1092 DataPointInit(ref newDataPoint);
1093 Add(newDataPoint);
1094 return Count - 1;
1097 /// <summary>
1098 /// Insert one data point with X value and one or more Y values.
1099 /// </summary>
1100 /// <param name="index">Index after which to insert the data point.</param>
1101 /// <param name="xValue">X value of the data point.</param>
1102 /// <param name="yValue">List of Y values of the data point.</param>
1103 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
1104 Justification = "X and Y are cartesian coordinates and well understood")]
1105 public void InsertXY(int index, object xValue, params object[] yValue)
1107 DataPoint newDataPoint = new DataPoint(series);
1108 newDataPoint.SetValueXY(xValue, yValue);
1109 DataPointInit(ref newDataPoint);
1110 this.Insert(index, newDataPoint);
1113 /// <summary>
1114 /// Insert one data point with one or more Y values.
1115 /// </summary>
1116 /// <param name="index">Index after which to insert the data point.</param>
1117 /// <param name="yValue">List of Y values of the data point.</param>
1118 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
1119 Justification = "Y is a cartesian coordinate and well understood")]
1120 public void InsertY(int index, params object[] yValue)
1122 DataPoint newDataPoint = new DataPoint(series);
1123 newDataPoint.SetValueY(yValue);
1124 DataPointInit(ref newDataPoint);
1125 this.Insert(index, newDataPoint);
1128 /// <summary>
1129 /// Get data source enumerator object helper function.
1130 /// </summary>
1131 /// <param name="dataSource">Data source.</param>
1132 /// <returns>Returns data source enumerator.</returns>
1133 internal static IEnumerator GetDataSourceEnumerator(IEnumerable dataSource)
1135 DataView dataView = dataSource as DataView;
1136 if(dataView != null)
1138 return dataView.GetEnumerator();
1140 DataSet dataSet = dataSource as DataSet;
1141 if(dataSet != null)
1143 if(dataSet.Tables.Count > 0)
1145 return dataSet.Tables[0].Rows.GetEnumerator();
1149 return dataSource.GetEnumerator();
1152 /// <summary>
1153 /// Convert enumeration item object from DataRow and DataRowView
1154 /// to the actual value of specified column in row
1155 /// </summary>
1156 /// <param name="item">Enumeration item.</param>
1157 /// <param name="fieldName">Converted item.</param>
1158 /// <returns></returns>
1159 internal static object ConvertEnumerationItem(object item, string fieldName)
1161 object result = item;
1163 // If original object is DataRow
1164 DataRow dataRow = item as DataRow;
1165 if(dataRow != null)
1167 if(fieldName != null && fieldName.Length > 0)
1169 // Check if specified column exist
1170 bool failed = true;
1171 if (dataRow.Table.Columns.Contains(fieldName))
1173 result = dataRow[fieldName];
1174 failed = false;
1176 else
1178 // Try to treat field name as column index number
1179 int columnIndex;
1180 failed = !int.TryParse(fieldName, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex);
1182 if (!failed && columnIndex < dataRow.Table.Columns.Count && columnIndex >= 0)
1184 result = dataRow[columnIndex];
1188 if(failed)
1190 throw(new ArgumentException( SR.ExceptionColumnNameNotFound( fieldName) ) );
1193 else
1195 // Get first column value if name not specified
1196 result = dataRow[0];
1200 // If original object is DataRowView
1202 DataRowView dataRowView = item as DataRowView;
1203 if(dataRowView != null)
1205 if(fieldName != null && fieldName.Length > 0)
1207 // Check if specified column exist
1208 bool failed = true;
1209 if (dataRowView.DataView.Table.Columns.Contains(fieldName))
1211 result = dataRowView[fieldName];
1212 failed = false;
1214 else
1216 // Try to treat field name as column index number
1217 int columnIndex;
1218 failed = !int.TryParse(fieldName, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex);
1219 if (!failed && columnIndex < dataRowView.DataView.Table.Columns.Count && columnIndex >= 0)
1221 result = dataRowView[columnIndex];
1225 if(failed)
1227 throw(new ArgumentException( SR.ExceptionColumnNameNotFound(fieldName)));
1230 else
1232 // Get first column value if name not specified
1233 result = dataRowView[0];
1237 // If original object is DbDataRecord
1238 DbDataRecord dbDataRecord = item as DbDataRecord;
1239 if(dbDataRecord != null)
1241 if(fieldName != null && fieldName.Length > 0)
1243 // Check if specified column exist
1244 bool failed = true;
1245 if(!Char.IsNumber(fieldName, 0))
1249 result = dbDataRecord[fieldName];
1250 failed = false;
1252 catch (IndexOutOfRangeException)
1254 failed = true;
1258 if(failed)
1260 // Try to treat field name as column index number
1263 int columnIndex;
1264 bool parseSucceed = int.TryParse(fieldName, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex);
1266 if (parseSucceed)
1268 result = dbDataRecord[columnIndex];
1269 failed = false;
1271 else
1273 failed = true;
1276 catch (IndexOutOfRangeException)
1278 failed = true;
1282 if(failed)
1284 throw(new ArgumentException( SR.ExceptionColumnNameNotFound(fieldName)));
1288 else
1290 // Get first column value if name not specified
1291 result = dbDataRecord[0];
1294 else
1296 if (fieldName != null && fieldName.Length > 0)
1298 PropertyDescriptor descriptor = TypeDescriptor.GetProperties(item).Find(fieldName, true);
1299 if (descriptor != null)
1301 result = descriptor.GetValue(item);
1302 return result ?? null;
1308 return result;
1310 /// <summary>
1311 /// Auto detects the X and Y(s) values type
1312 /// </summary>
1313 /// <param name="series">Series the values type is detected for.</param>
1314 /// <param name="xEnumerator">X values enumerator.</param>
1315 /// <param name="xField">X value field.</param>
1316 /// <param name="yEnumerator">Y values enumerator.</param>
1317 /// <param name="yField">Y value field.</param>
1318 internal static void AutoDetectValuesType(
1319 Series series,
1320 IEnumerator xEnumerator,
1321 string xField,
1322 IEnumerator yEnumerator,
1323 string yField)
1325 if(series.XValueType == ChartValueType.Auto)
1327 series.XValueType = GetValueType(xEnumerator, xField);
1328 if(series.XValueType != ChartValueType.Auto)
1330 series.autoXValueType = true;
1333 if(series.YValueType == ChartValueType.Auto)
1335 series.YValueType = GetValueType(yEnumerator, yField);
1336 if(series.YValueType != ChartValueType.Auto)
1338 series.autoYValueType = true;
1343 /// <summary>
1344 /// Return value type.
1345 /// </summary>
1346 /// <param name="enumerator">Values enumerator.</param>
1347 /// <param name="field">Value field.</param>
1348 private static ChartValueType GetValueType(IEnumerator enumerator, string field)
1350 ChartValueType type = ChartValueType.Auto;
1351 Type columnDataType = null;
1353 // Check parameters
1354 if(enumerator == null)
1356 return type;
1359 // Check if current enumeration element is available
1362 if(enumerator.Current == null)
1364 return type;
1367 catch(InvalidOperationException)
1369 return type;
1373 // If original object is DataRow
1374 if(enumerator.Current is DataRow)
1376 if(field != null && field.Length > 0)
1378 // Check if specified column exist
1379 bool failed = true;
1380 if(((DataRow)enumerator.Current).Table.Columns.Contains(field))
1382 columnDataType = ((DataRow)enumerator.Current).Table.Columns[field].DataType;
1383 failed = false;
1386 // Try to treat field as column number
1387 if (failed)
1389 int columnIndex;
1390 bool parseSucceed = int.TryParse(field, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex);
1392 if (parseSucceed)
1394 columnDataType = ((DataRow)enumerator.Current).Table.Columns[columnIndex].DataType;
1395 failed = false;
1397 else
1399 failed = true;
1403 if(failed)
1405 throw(new ArgumentException( SR.ExceptionColumnNameNotFound(field)));
1409 else if(((DataRow)enumerator.Current).Table.Columns.Count > 0)
1411 columnDataType = ((DataRow)enumerator.Current).Table.Columns[0].DataType;
1415 // If original object is DataRowView
1416 else if(enumerator.Current is DataRowView)
1418 if(field != null && field.Length > 0)
1420 // Check if specified column exist
1421 bool failed = true;
1422 if(((DataRowView)enumerator.Current).DataView.Table.Columns.Contains(field))
1424 columnDataType = ((DataRowView)enumerator.Current).DataView.Table.Columns[field].DataType;
1425 failed = false;
1428 // Try to treat field as column number
1429 if (failed)
1431 int columnIndex;
1432 bool parseSucceed = int.TryParse(field, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex);
1433 if (parseSucceed)
1435 columnDataType = ((DataRowView)enumerator.Current).DataView.Table.Columns[columnIndex].DataType;
1436 failed = false;
1438 else
1440 failed = true;
1444 if(failed)
1446 throw(new ArgumentException(SR.ExceptionColumnNameNotFound(field)));
1450 else if(((DataRowView)enumerator.Current).DataView.Table.Columns.Count > 0)
1452 columnDataType = ((DataRowView)enumerator.Current).DataView.Table.Columns[0].DataType;
1456 // If original object is DbDataRecord
1457 else if(enumerator.Current is DbDataRecord)
1459 if(field != null && field.Length > 0)
1461 bool failed = true;
1462 int columnIndex = 0;
1463 if(!Char.IsNumber(field, 0))
1465 columnIndex = ((DbDataRecord)enumerator.Current).GetOrdinal(field);
1466 columnDataType = ((DbDataRecord)enumerator.Current).GetFieldType(columnIndex);
1467 failed = false;
1470 // Try to treat field as column number
1471 if (failed)
1473 failed = !int.TryParse(field, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex);
1475 if (!failed)
1477 columnDataType = ((DbDataRecord)enumerator.Current).GetFieldType(columnIndex);
1481 if(failed)
1483 throw(new ArgumentException(SR.ExceptionColumnNameNotFound(field)));
1487 else if(((DbDataRecord)enumerator.Current).FieldCount > 0)
1489 columnDataType = ((DbDataRecord)enumerator.Current).GetFieldType(0);
1492 // Try detecting simple data types
1493 else
1495 if (field != null && field.Length > 0)
1497 PropertyDescriptor descriptor = TypeDescriptor.GetProperties(enumerator.Current).Find(field, true);
1498 if (descriptor != null)
1500 columnDataType = descriptor.PropertyType;
1503 if ( columnDataType == null )
1505 columnDataType = enumerator.Current.GetType();
1509 // Use data type
1510 if(columnDataType != null)
1512 if(columnDataType == typeof(DateTime))
1513 type = ChartValueType.DateTime;
1514 else if (columnDataType == typeof(DateTimeOffset))
1515 type = ChartValueType.DateTimeOffset;
1516 else if (columnDataType == typeof(TimeSpan))
1517 type = ChartValueType.Time;
1518 else if (columnDataType == typeof(Double))
1519 type = ChartValueType.Double;
1520 else if (columnDataType == typeof(Int32))
1521 type = ChartValueType.Int32;
1522 else if(columnDataType == typeof(Int64))
1523 type = ChartValueType.Int64;
1524 else if(columnDataType == typeof(Single))
1525 type = ChartValueType.Single;
1526 else if(columnDataType == typeof(String))
1527 type = ChartValueType.String;
1528 else if(columnDataType == typeof(UInt32))
1529 type = ChartValueType.UInt32;
1530 else if(columnDataType == typeof(UInt64))
1531 type = ChartValueType.UInt64;
1534 return type;
1537 #endregion
1539 #region DataPoint finding functions
1541 /// <summary>
1542 /// Find all the points that equal to the specified value starting from the specified index.
1543 /// </summary>
1544 /// <param name="valueToFind">Point value to find.</param>
1545 /// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
1546 /// <param name="startIndex">Index of the point to start looking from.</param>
1547 /// <returns>Enumerator of datapoints.</returns>
1548 public IEnumerable<DataPoint> FindAllByValue(double valueToFind, string useValue, int startIndex)
1550 // Loop through all points from specified index
1551 for (int i = startIndex; i < this.Count; i++)
1553 DataPoint point = this[i];
1554 if (point.GetValueByName(useValue) == valueToFind)
1556 yield return point;
1561 /// <summary>
1562 /// Find all the points that equal to the specified value.
1563 /// </summary>
1564 /// <param name="valueToFind">Point value to find.</param>
1565 /// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
1566 /// <returns>Enumerator of datapoints.</returns>
1567 public IEnumerable<DataPoint> FindAllByValue(double valueToFind, string useValue)
1569 // Loop through all points from specified index
1570 for (int i = 0; i < this.Count; i++)
1572 DataPoint point = this[i];
1573 if (point.GetValueByName(useValue) == valueToFind)
1575 yield return point;
1580 /// <summary>
1581 /// Find all the points that equal to the specified value.
1582 /// </summary>
1583 /// <param name="valueToFind">Point value to find.</param>
1584 /// <returns>Enumerator of datapoints.</returns>
1585 public IEnumerable<DataPoint> FindAllByValue(double valueToFind)
1587 return FindAllByValue(valueToFind, "Y");
1590 /// <summary>
1591 /// Find the first point that equals to the specified value starting from the specified index.
1592 /// </summary>
1593 /// <param name="valueToFind">Point value to find.</param>
1594 /// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
1595 /// <param name="startIndex">Index of the point to start looking from.</param>
1596 /// <returns>Datapoint which matches the value. Null if there is no match.</returns>
1597 public DataPoint FindByValue(double valueToFind, string useValue, int startIndex)
1599 //Check arguments
1600 if (useValue == null)
1601 throw new ArgumentNullException("useValue");
1602 if (startIndex < 0 || startIndex >= this.Count)
1603 throw new ArgumentOutOfRangeException("startIndex");
1605 // Loop through all points from specified index
1606 for (int i = startIndex; i < this.Count; i++)
1608 DataPoint point = this[i];
1609 if (point.GetValueByName(useValue) == valueToFind)
1611 return point;
1615 // Nothing was found
1616 return null;
1619 /// <summary>
1620 /// Find the first point that equals to the specified value.
1621 /// </summary>
1622 /// <param name="valueToFind">Point value to find.</param>
1623 /// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
1624 /// <returns>Datapoint which matches the value. Null if there is no match.</returns>
1625 public DataPoint FindByValue(double valueToFind, string useValue)
1627 return FindByValue(valueToFind, useValue, 0);
1630 /// <summary>
1631 /// Find the first point that equals to the specified value.
1632 /// </summary>
1633 /// <param name="valueToFind">Point value to find.</param>
1634 /// <returns>Datapoint which matches the value. Null if there is no match.</returns>
1635 public DataPoint FindByValue(double valueToFind)
1637 return FindByValue(valueToFind, "Y");
1640 /// <summary>
1641 /// Find point with the maximum value starting from specified index.
1642 /// </summary>
1643 /// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
1644 /// <param name="startIndex">Index of the point to start looking from.</param>
1645 /// <returns>Datapoint with the maximum value.</returns>
1646 public DataPoint FindMaxByValue(string useValue, int startIndex)
1648 //Check arguments
1649 if (useValue == null)
1650 throw new ArgumentNullException("useValue");
1651 if (startIndex < 0 || startIndex >= this.Count)
1652 throw new ArgumentOutOfRangeException("startIndex");
1654 bool isYValue = useValue.StartsWith("Y", StringComparison.OrdinalIgnoreCase);
1655 double maxValue = double.MinValue;
1656 DataPoint maxPoint = null;
1658 for (int i = startIndex; i < this.Count; i++)
1660 DataPoint point = this[i];
1662 // Skip empty points when searching for the Y values
1663 if (point.IsEmpty && isYValue)
1664 continue;
1666 double pointValue = point.GetValueByName(useValue);
1668 if (maxValue < pointValue)
1670 maxValue = pointValue;
1671 maxPoint = point;
1675 return maxPoint;
1678 /// <summary>
1679 /// Find point with the maximum value.
1680 /// </summary>
1681 /// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
1682 /// <returns>Datapoint with the maximum value.</returns>
1683 public DataPoint FindMaxByValue(string useValue)
1685 return FindMaxByValue(useValue, 0);
1688 /// <summary>
1689 /// Find data point with the maximum value.
1690 /// </summary>
1691 /// <returns>Datapoint with the maximum value.</returns>
1692 public DataPoint FindMaxByValue()
1694 return FindMaxByValue("Y");
1697 /// <summary>
1698 /// Find point with the Min value starting from specified index.
1699 /// </summary>
1700 /// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
1701 /// <param name="startIndex">Index of the point to start looking from.</param>
1702 /// <returns>Datapoint with the Min value.</returns>
1703 public DataPoint FindMinByValue(string useValue, int startIndex)
1705 if (useValue == null)
1706 throw new ArgumentNullException("useValue");
1707 if (startIndex < 0 || startIndex >= this.Count)
1708 throw new ArgumentOutOfRangeException("startIndex");
1710 bool isYValue = useValue.StartsWith("Y", StringComparison.OrdinalIgnoreCase);
1711 double minValue = double.MaxValue;
1712 DataPoint minPoint = null;
1714 for (int i = startIndex; i < this.Count; i++)
1716 DataPoint point = this[i];
1718 // Skip empty points when searching for the Y values
1719 if (point.IsEmpty && isYValue)
1720 continue;
1722 double pointValue = point.GetValueByName(useValue);
1724 if (minValue > pointValue)
1726 minValue = pointValue;
1727 minPoint = point;
1731 return minPoint;
1734 /// <summary>
1735 /// Find point with the Min value.
1736 /// </summary>
1737 /// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
1738 /// <returns>Datapoint with the Min value.</returns>
1739 public DataPoint FindMinByValue(string useValue)
1741 return FindMinByValue(useValue, 0);
1744 /// <summary>
1745 /// Find point with the Min value
1746 /// </summary>
1747 /// <returns>Datapoint with the Min value.</returns>
1748 public DataPoint FindMinByValue()
1750 return FindMinByValue("Y");
1753 #endregion
1755 #region Collection<T> overrides
1757 /// <summary>
1758 /// Initializes the specified item.
1759 /// </summary>
1760 /// <param name="item">The item.</param>
1761 internal override void Initialize(DataPoint item)
1763 DataPointInit(ref item);
1764 base.Initialize(item);
1767 #if Microsoft_CONTROL
1768 /// <summary>
1769 /// Removes all elements from the <see cref="T:System.Collections.ObjectModel.Collection`1"/>.
1770 /// </summary>
1771 protected override void ClearItems()
1774 // Refresh Minimum and Maximum from data
1775 // after recalc and set data
1776 if (Common != null && Common.ChartPicture != null)
1778 Common.ChartPicture.ResetMinMaxFromData();
1781 base.ClearItems();
1783 #endif
1785 #endregion
1788 /// <summary>
1789 /// Stores values and properties of a DataPoint of a Series.
1790 /// </summary>
1792 SRDescription("DescriptionAttributeDataPoint_DataPoint"),
1793 DefaultProperty("YValues"),
1794 TypeConverter(Editors.DataPointConverter.Convertor)
1796 #if ASPPERM_35
1797 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1798 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1799 #endif
1800 #if !Microsoft_CONTROL
1801 [Themeable(false)]
1802 #endif
1803 public class DataPoint : DataPointCustomProperties
1805 #region Fields
1807 // Point X value
1808 private double _xValue;
1810 // Point Y values
1811 private double[] _yValue = new double[1];
1813 // Pre calculated (during painting) relative position of data point
1814 internal PointF positionRel = PointF.Empty;
1816 // VSTS:199794 - Accessibility needs the last rendered label content to be exposed.
1817 // The current label content evaluation is scattered over different chart types and cannot be isolated without risk of regression.
1818 // This variable will cache the label content taken just before drawing.
1819 internal string _lastLabelText = String.Empty;
1821 #endregion
1823 #region Constructors
1825 /// <summary>
1826 /// DataPoint object constructor.
1827 /// </summary>
1828 public DataPoint() : base(null, true)
1830 _yValue = new double[1];
1833 /// <summary>
1834 /// DataPoint object constructor.
1835 /// </summary>
1836 /// <param name="series">series object, which the DataPoint belongs to.</param>
1837 public DataPoint(Series series) : base(series, true)
1839 // Create Y value(s) array
1840 _yValue = new double[series.YValuesPerPoint];
1841 _xValue = 0;
1844 /// <summary>
1845 /// DataPoint object constructor.
1846 /// </summary>
1847 /// <param name="xValue">X value.</param>
1848 /// <param name="yValue">Y value.</param>
1849 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
1850 Justification = "X and Y are cartesian coordinates and well understood")]
1851 public DataPoint(double xValue, double yValue)
1852 : base(null, true)
1854 // Set Y value
1855 this._yValue = new double[1];
1856 this._yValue[0] = yValue;
1858 // Set X value
1859 this._xValue = xValue;
1862 /// <summary>
1863 /// DataPoint object constructor.
1864 /// </summary>
1865 /// <param name="xValue">X value.</param>
1866 /// <param name="yValues">Array of Y values.</param>
1867 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
1868 Justification = "X and Y are cartesian coordinates and well understood")]
1869 public DataPoint(double xValue, double[] yValues)
1870 : base(null, true)
1872 // Set Y value
1873 this._yValue = yValues;
1875 // Set X value
1876 this._xValue = xValue;
1879 /// <summary>
1880 /// DataPoint object constructor.
1881 /// </summary>
1882 /// <remarks>
1883 /// This method is only used during the Windows Forms serialization of the chart.
1884 /// </remarks>
1885 /// <param name="xValue">X value.</param>
1886 /// <param name="yValues">String of comma separated Y values.</param>
1887 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
1888 Justification = "X and Y are cartesian coordinates and well understood")]
1889 [EditorBrowsable(EditorBrowsableState.Never)]
1890 public DataPoint(double xValue, string yValues)
1891 : base(null, true)
1893 string[] values = yValues.Split(',');
1895 // Create Y value(s) array
1896 _yValue = new double[values.Length];
1898 for (int index = 0; index < values.Length; index++)
1900 _yValue[index] = CommonElements.ParseDouble(values[index], true);
1903 // Set X value
1904 this._xValue = xValue;
1907 #endregion
1909 #region Data point methods
1911 /// <summary>
1912 /// Sets the specified data point attribute to the specified value.
1913 /// </summary>
1914 /// <param name="obj">Attribute value.</param>
1915 /// <param name="propertyName">Attribute name.</param>
1916 /// <param name="format">Value format.</param>
1917 internal void SetPointCustomProperty(
1918 object obj,
1919 string propertyName,
1920 string format)
1922 // Convert value to string
1923 string stringValue = obj as string;
1924 if(stringValue == null)
1926 double doubleObj = double.NaN;
1927 ChartValueType valueType = ChartValueType.Auto;
1928 if(obj is DateTime)
1930 doubleObj = ((DateTime)obj).ToOADate();
1931 valueType = ChartValueType.Date;
1933 else
1935 doubleObj = this.ConvertValue(obj);
1938 // Try converting to string
1939 if( !double.IsNaN(doubleObj) )
1943 stringValue = ValueConverter.FormatValue(
1944 this.Chart,
1945 this,
1946 this.Tag,
1947 doubleObj,
1948 format,
1949 valueType,
1950 ChartElementType.DataPoint);
1952 catch(FormatException)
1954 // Use basic string converter
1955 stringValue = obj.ToString();
1958 else
1960 // Use basic string converter
1961 stringValue = obj.ToString();
1965 // Assign data point attribute by name
1966 if(stringValue.Length > 0)
1968 if(String.Compare(propertyName, "AxisLabel", StringComparison.OrdinalIgnoreCase) == 0)
1970 this.AxisLabel = stringValue;
1972 else if (String.Compare(propertyName, "Tooltip", StringComparison.OrdinalIgnoreCase) == 0)
1974 this.ToolTip = stringValue;
1976 #if !Microsoft_CONTROL
1977 else if(String.Compare(propertyName, "Url", StringComparison.OrdinalIgnoreCase) == 0)
1979 this.Url = stringValue;
1981 else if (String.Compare(propertyName, "PostBackValue", StringComparison.OrdinalIgnoreCase) == 0)
1983 this.PostBackValue = stringValue;
1985 else if (String.Compare(propertyName, "LabelUrl", StringComparison.OrdinalIgnoreCase) == 0)
1987 this.LabelUrl = stringValue;
1989 else if (String.Compare(propertyName, "LabelPostBackValue", StringComparison.OrdinalIgnoreCase) == 0)
1991 this.LabelPostBackValue = stringValue;
1993 else if (String.Compare(propertyName, "LegendUrl", StringComparison.OrdinalIgnoreCase) == 0)
1995 this.LegendUrl = stringValue;
1997 else if (String.Compare(propertyName, "LegendPostBackValue", StringComparison.OrdinalIgnoreCase) == 0)
1999 this.LegendPostBackValue = stringValue;
2001 #endif // !Microsoft_CONTROL
2002 else if (String.Compare(propertyName, "Label", StringComparison.OrdinalIgnoreCase) == 0)
2004 this.Label = stringValue;
2006 else if (String.Compare(propertyName, "LegendTooltip", StringComparison.OrdinalIgnoreCase) == 0)
2008 this.LegendToolTip = stringValue;
2010 else if (String.Compare(propertyName, "LegendText", StringComparison.OrdinalIgnoreCase) == 0)
2012 this.LegendText = stringValue;
2014 else if (String.Compare(propertyName, "LabelToolTip", StringComparison.OrdinalIgnoreCase) == 0)
2016 this.LabelToolTip = stringValue;
2018 else
2020 this[propertyName] = stringValue;
2026 /// <summary>
2027 /// Converts object to double.
2028 /// </summary>
2029 /// <param name="value">Object to convert.</param>
2030 /// <returns>Double value.</returns>
2031 private double ConvertValue(object value)
2033 if(value == null)
2035 return 0;
2038 if(value is Double)
2040 return (double)value;
2042 else if(value is Single)
2044 return (double)((float)value);
2046 else if(value is Decimal)
2048 return (double)((Decimal)value);
2050 else if(value is Int32)
2052 return (double)((Int32)value);
2054 else if(value is UInt32)
2056 return (double)((UInt32)value);
2058 else if(value is Int64)
2060 return (double)((Int64)value);
2062 else if(value is UInt64)
2064 return (double)((UInt64)value);
2066 else if(value is Byte)
2068 return (double)((Byte)value);
2070 else if(value is SByte)
2072 return (double)((SByte)value);
2074 else if(value is Boolean)
2076 return ((Boolean)value) ? 1.0 : 0.0;
2078 else
2080 string stringValue = "";
2081 stringValue = value.ToString();
2082 return CommonElements.ParseDouble(stringValue);
2086 /// <summary>
2087 /// Set X value and one or more Y values of the data point.
2088 /// </summary>
2089 /// <param name="xValue">X value of the data point.</param>
2090 /// <param name="yValue">List of Y values of the data point.</param>
2091 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
2092 Justification = "X and Y are cartesian coordinates and well understood")]
2093 public void SetValueXY(object xValue, params object[] yValue)
2095 // Check arguments
2096 if (xValue == null)
2097 throw new ArgumentNullException("xValue");
2099 // Set Y value first
2100 SetValueY(yValue);
2102 // Check if parameters type matches with series type
2103 Type paramType = xValue.GetType();
2104 if(base.series != null)
2106 base.series.CheckSupportedTypes(paramType);
2109 // Save value in the array
2110 if(paramType == typeof(String))
2112 AxisLabel = (string)xValue;
2114 else if(paramType == typeof(DateTime))
2116 this._xValue = ((DateTime)xValue).ToOADate();
2118 else
2120 this._xValue = ConvertValue(xValue);
2123 // Get Date or Time if required
2124 if(base.series != null && xValue is DateTime)
2126 if(base.series.XValueType == ChartValueType.Date)
2128 DateTime time = new DateTime(
2129 ((DateTime)xValue).Year,
2130 ((DateTime)xValue).Month,
2131 ((DateTime)xValue).Day,
2136 this._xValue = time.ToOADate();
2138 else if(base.series.XValueType == ChartValueType.Time)
2140 DateTime time = new DateTime(
2141 1899,
2142 12,
2143 30,
2144 ((DateTime)xValue).Hour,
2145 ((DateTime)xValue).Minute,
2146 ((DateTime)xValue).Second,
2147 ((DateTime)xValue).Millisecond);
2148 this._xValue = time.ToOADate();
2152 // Check if one of Y values are not avilable
2153 bool empty = false;
2154 foreach(double d in this._yValue)
2156 if(double.IsNaN(d))
2158 empty = true;
2159 break;
2163 // Set point empty flag and values to zero
2164 if(empty)
2166 this.IsEmpty = true;
2167 for(int valueIndex = 0; valueIndex < this._yValue.Length; valueIndex++)
2169 this._yValue[valueIndex] = 0.0;
2174 /// <summary>
2175 /// Set one or more Y values of the data point.
2176 /// </summary>
2177 /// <param name="yValue">List of Y values of the data point.</param>
2178 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
2179 Justification = "Y is a cartesian coordinate and well understood")]
2180 public void SetValueY(params object[] yValue)
2182 // Check arguments
2183 if (yValue == null)
2184 throw new ArgumentNullException("yValue");
2186 // Check number of parameters. Should be more than 0 and
2187 if(yValue.Length == 0 || (base.series != null && yValue.Length > base.series.YValuesPerPoint))
2188 throw(new ArgumentOutOfRangeException("yValue", SR.ExceptionDataPointYValuesSettingCountMismatch(base.series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture))));
2190 // Check if there is a Null Y value
2191 for( int i = 0 ; i < yValue.Length ; i++ )
2193 if(yValue[i] == null || yValue[i] is System.DBNull)
2195 yValue[i] = 0.0;
2196 if(i == 0)
2198 this.IsEmpty = true;
2203 // Check if parameters type matches with series type
2204 Type paramType = yValue[0].GetType();
2205 if(base.series != null)
2207 base.series.CheckSupportedTypes(paramType);
2210 // Make sure the Y values array is big enough
2211 if (this._yValue.Length < yValue.Length)
2213 this._yValue = new double[yValue.Length];
2216 // Save value in the array
2217 if(paramType == typeof(String))
2221 for (int i = 0; i < yValue.Length; i++)
2223 this._yValue[i] = CommonElements.ParseDouble((string)yValue[i]);
2226 catch
2228 // Get reference to the chart object
2229 if (Common!=null && Common.ChartPicture!=null && Common.ChartPicture.SuppressExceptions)
2231 this.IsEmpty = true;
2232 for (int i = 0; i < yValue.Length; i++)
2234 yValue[i] = 0.0;
2237 else
2239 throw (new ArgumentException( SR.ExceptionDataPointYValueStringFormat));
2244 else if(paramType == typeof(DateTime))
2246 for( int i = 0 ; i < yValue.Length ; i++ )
2248 if(yValue[i] == null ||
2249 (yValue[i] is double && ((double)yValue[i]) == 0.0) )
2251 this._yValue[i] = DateTime.Now.ToOADate();
2253 else
2255 this._yValue[i] = ((DateTime)yValue[i]).ToOADate();
2259 else
2261 for( int i = 0 ; i < yValue.Length ; i++ )
2263 this._yValue[i] = ConvertValue(yValue[i]);
2267 // Get Date or Time if required
2268 if(base.series != null)
2270 for( int i = 0 ; i < yValue.Length ; i++ )
2272 if(yValue[i] == null ||
2273 (yValue[i] is double && ((double)yValue[i]) == 0.0) )
2275 if(base.series.YValueType == ChartValueType.Date)
2277 this._yValue[i] = Math.Floor(this._yValue[i]);
2279 else if(base.series.YValueType == ChartValueType.Time)
2281 this._yValue[i] = this._xValue - Math.Floor(this._yValue[i]);
2284 else
2286 if(base.series.YValueType == ChartValueType.Date)
2288 DateTime yDate;
2289 if (yValue[i] is DateTime)
2290 yDate = (DateTime)yValue[i];
2291 else if (yValue[i] is Double)
2292 yDate = DateTime.FromOADate((Double)yValue[i]);
2293 else
2294 yDate = Convert.ToDateTime(yValue[i], CultureInfo.InvariantCulture); //This will throw an exception in case when the yValue type is not compatible with the DateTime
2296 DateTime date = new DateTime(
2297 yDate.Year,
2298 yDate.Month,
2299 yDate.Day,
2305 this._yValue[i] = date.ToOADate();
2307 else if (base.series.YValueType == ChartValueType.Time)
2309 DateTime yTime;
2310 if (yValue[i] is DateTime)
2311 yTime = (DateTime)yValue[i];
2312 if (yValue[i] is Double)
2313 yTime = DateTime.FromOADate((Double)yValue[i]);
2314 else
2315 yTime = Convert.ToDateTime(yValue[i], CultureInfo.InvariantCulture); //This will throw an exception in case when the yValue type is not compatible with the DateTime
2317 DateTime time = new DateTime(
2318 1899,
2319 12,
2320 30,
2321 yTime.Hour,
2322 yTime.Minute,
2323 yTime.Second,
2324 yTime.Millisecond);
2326 this._yValue[i] = time.ToOADate();
2334 /// <summary>
2335 /// Creates an exact copy of this DataPoint object.
2336 /// </summary>
2337 /// <returns>An exact copy of this DataPoint object.</returns>
2338 public DataPoint Clone()
2340 // Create new data point
2341 DataPoint clonePoint = new DataPoint();
2343 // Reset series pointer
2344 clonePoint.series = null;
2345 clonePoint.pointCustomProperties = this.pointCustomProperties;
2347 // Copy values
2348 clonePoint._xValue = this.XValue;
2349 clonePoint._yValue = new double[this._yValue.Length];
2350 this._yValue.CopyTo(clonePoint._yValue, 0);
2351 clonePoint.tempColorIsSet = this.tempColorIsSet;
2352 clonePoint.isEmptyPoint = this.isEmptyPoint;
2354 // Copy properties
2355 foreach(object key in this.properties.Keys)
2357 clonePoint.properties.Add(key, this.properties[key]);
2360 return clonePoint;
2363 /// <summary>
2364 /// Resize Y values array.
2365 /// </summary>
2366 /// <param name="newSize">New number of Y values in array.</param>
2367 internal void ResizeYValueArray(int newSize)
2369 // Create new array
2370 double[] newArray = new Double[newSize];
2372 // Copy elements
2373 if(_yValue != null)
2375 for(int i = 0; i < ((_yValue.Length < newSize) ? _yValue.Length : newSize); i++)
2377 newArray[i] = _yValue[i];
2381 _yValue = newArray;
2384 /// <summary>
2385 /// Helper function, which returns point value by it's name.
2386 /// </summary>
2387 /// <param name="valueName">Point value names. X, Y, Y2,...</param>
2388 /// <returns>Point value.</returns>
2389 public double GetValueByName(string valueName)
2391 // Check arguments
2392 if (valueName == null)
2393 throw new ArgumentNullException("valueName");
2395 valueName = valueName.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
2396 if(String.Compare(valueName, "X", StringComparison.Ordinal) == 0)
2398 return this.XValue;
2400 else if (valueName.StartsWith("Y", StringComparison.Ordinal))
2403 if(valueName.Length == 1)
2405 return this.YValues[0];
2407 else
2409 int yIndex = 0;
2412 yIndex = Int32.Parse(valueName.Substring(1), System.Globalization.CultureInfo.InvariantCulture) - 1;
2414 catch(System.Exception)
2416 throw(new ArgumentException( SR.ExceptionDataPointValueNameInvalid, "valueName"));
2419 if(yIndex < 0)
2421 throw(new ArgumentException( SR.ExceptionDataPointValueNameYIndexIsNotPositive, "valueName"));
2424 if(yIndex >= this.YValues.Length)
2426 throw(new ArgumentException( SR.ExceptionDataPointValueNameYIndexOutOfRange, "valueName"));
2429 return this.YValues[yIndex];
2432 else
2434 throw(new ArgumentException( SR.ExceptionDataPointValueNameInvalid, "valueName"));
2438 /// <summary>
2439 /// Replaces predefined keyword inside the string with their values.
2440 /// </summary>
2441 /// <param name="strOriginal">Original string with keywords.</param>
2442 /// <returns>Modified string.</returns>
2443 internal override string ReplaceKeywords(string strOriginal)
2445 // Nothing to process
2446 if(strOriginal == null || strOriginal.Length == 0)
2447 return strOriginal;
2449 // Replace all "\n" strings with '\n' character
2450 string result = strOriginal;
2451 result = result.Replace("\\n", "\n");
2453 // #LABEL - point label
2454 result = result.Replace(KeywordName.Label, this.Label);
2456 // #LEGENDTEXT - series name
2457 result = result.Replace(KeywordName.LegendText, this.LegendText);
2459 // #AXISLABEL - series name
2460 result = result.Replace(KeywordName.AxisLabel, this.AxisLabel);
2462 // #CUSTOMPROPERTY - one of the custom properties by name
2463 result = DataPoint.ReplaceCustomPropertyKeyword(result, this);
2465 if(this.series != null)
2467 // #INDEX - point index
2468 result = result.Replace(KeywordName.Index, this.series.Points.IndexOf(this).ToString(System.Globalization.CultureInfo.InvariantCulture));
2470 // Replace series keywords
2471 result = this.series.ReplaceKeywords(result);
2473 // #PERCENT - percentage of Y value from total
2474 result = this.series.ReplaceOneKeyword(
2475 this.Chart,
2476 this,
2477 this.Tag,
2478 ChartElementType.DataPoint,
2479 result,
2480 KeywordName.Percent,
2481 (this.YValues[0]/(this.series.GetTotalYValue())),
2482 ChartValueType.Double,
2483 "P");
2485 // #VAL[X] - point value X, Y, Y2, ...
2486 if(this.series.XValueType == ChartValueType.String)
2488 result = result.Replace(KeywordName.ValX, this.AxisLabel);
2490 else
2492 result = this.series.ReplaceOneKeyword(
2493 this.Chart,
2494 this,
2495 this.Tag,
2496 ChartElementType.DataPoint,
2497 result,
2498 KeywordName.ValX,
2499 this.XValue,
2500 this.series.XValueType,
2501 "");
2504 // remove keywords #VAL? for unexisted Y value indices
2505 for (int index = this.YValues.Length; index <= 7; index++)
2507 result = this.RemoveOneKeyword(result, KeywordName.ValY + index + 1, SR.FormatErrorString);
2510 for(int index = 1; index <= this.YValues.Length; index++)
2512 result = this.series.ReplaceOneKeyword(
2513 this.Chart,
2514 this,
2515 this.Tag,
2516 ChartElementType.DataPoint,
2517 result,
2518 KeywordName.ValY + index,
2519 this.YValues[index - 1],
2520 this.series.YValueType,
2521 "");
2524 result = this.series.ReplaceOneKeyword(
2525 Chart,
2526 this,
2527 this.Tag,
2528 ChartElementType.DataPoint,
2529 result,
2530 KeywordName.ValY,
2531 this.YValues[0],
2532 this.series.YValueType,
2533 "");
2535 result = this.series.ReplaceOneKeyword(
2536 Chart,
2537 this,
2538 this.Tag,
2539 ChartElementType.DataPoint,
2540 result,
2541 KeywordName.Val,
2542 this.YValues[0],
2543 this.series.YValueType,
2544 "");
2547 return result;
2550 /// <summary>
2551 /// Removes one keyword from format string.
2552 /// </summary>
2553 /// <param name="strOriginal">Original format string</param>
2554 /// <param name="keyword">The keyword</param>
2555 /// <param name="strToReplace">String to replace the keyword.</param>
2556 /// <returns>Modified format string</returns>
2557 private string RemoveOneKeyword(string strOriginal, string keyword, string strToReplace)
2559 string result = strOriginal;
2560 int keyIndex = -1;
2561 while ((keyIndex = result.IndexOf(keyword, StringComparison.Ordinal)) != -1)
2563 // Get optional format
2564 int keyEndIndex = keyIndex + keyword.Length;
2565 if (result.Length > keyEndIndex && result[keyEndIndex] == '{')
2567 int formatEnd = result.IndexOf('}', keyEndIndex);
2568 if (formatEnd == -1)
2570 throw (new InvalidOperationException(SR.ExceptionDataSeriesKeywordFormatInvalid(result)));
2573 keyEndIndex = formatEnd + 1;
2575 // Remove keyword string (with optional format)
2576 result = result.Remove(keyIndex, keyEndIndex - keyIndex);
2577 if (!String.IsNullOrEmpty(strToReplace))
2579 result = result.Insert(keyIndex, strToReplace);
2582 return result;
2586 /// <summary>
2587 /// Replaces all "#CUSTOMPROPERTY(XXX)" (where XXX is the custom attribute name)
2588 /// keywords in the string provided.
2589 /// </summary>
2590 /// <param name="originalString">String where the keyword need to be replaced.</param>
2591 /// <param name="properties">DataPoint or Series properties class.</param>
2592 /// <returns>Converted string.</returns>
2593 internal static string ReplaceCustomPropertyKeyword(string originalString, DataPointCustomProperties properties)
2595 string result = originalString;
2596 int keyStartIndex = -1;
2597 while ((keyStartIndex = result.IndexOf(KeywordName.CustomProperty, StringComparison.Ordinal)) >= 0)
2599 string attributeValue = string.Empty;
2600 string attributeName = string.Empty;
2602 // Forward to the end of the keyword
2603 int keyEndIndex = keyStartIndex + KeywordName.CustomProperty.Length;
2605 // An opening bracket '(' must follow
2606 if (result.Length > keyEndIndex && result[keyEndIndex] == '(')
2608 ++keyEndIndex;
2609 int attributeNameStartIndex = keyEndIndex;
2611 // Search for the closing bracket
2612 int closingBracketIndex = result.IndexOf(')', keyEndIndex);
2613 if (closingBracketIndex >= keyEndIndex)
2615 keyEndIndex = closingBracketIndex + 1;
2616 attributeName = result.Substring(attributeNameStartIndex, keyEndIndex - attributeNameStartIndex - 1);
2618 // Get attribute value
2619 if (properties.IsCustomPropertySet(attributeName))
2621 attributeValue = properties.GetCustomProperty(attributeName);
2623 else
2625 // In case of the DataPoint check if the attribute is set in the parent series
2626 DataPoint dataPoint = properties as DataPoint;
2627 if (dataPoint != null && dataPoint.series != null)
2629 if (dataPoint.series.IsCustomPropertySet(attributeName))
2631 attributeValue = dataPoint.series.GetCustomProperty(attributeName);
2638 // Remove keyword string with attribute name
2639 result = result.Remove(keyStartIndex, keyEndIndex - keyStartIndex);
2641 // Insert value of the custom attribute
2642 result = result.Insert(keyStartIndex, attributeValue);
2645 return result;
2648 /// <summary>
2649 /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
2650 /// </summary>
2651 /// <returns>
2652 /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
2653 /// </returns>
2654 internal override string ToStringInternal()
2656 StringBuilder sb = new StringBuilder();
2657 sb.AppendFormat(CultureInfo.CurrentCulture, "{{X={0}, ", XValue);
2658 if (YValues.Length == 1)
2660 sb.AppendFormat(CultureInfo.CurrentCulture, "Y={0}", YValues[0]);
2662 else
2664 sb.Append("Y={");
2665 for (int i = 0; i < YValues.Length; i++)
2666 if (i == 0)
2667 sb.AppendFormat(CultureInfo.CurrentCulture, "{0}", YValues[i]);
2668 else
2669 sb.AppendFormat(CultureInfo.CurrentCulture, ", {0}", YValues[i]);
2670 sb.Append("}");
2672 sb.Append("}");
2673 return sb.ToString();
2675 #endregion
2677 #region DataPoint Properties
2680 /// <summary>
2681 /// X value of the data point.
2682 /// </summary>
2684 SRCategory("CategoryAttributeData"),
2685 Bindable(true),
2686 SRDescription("DescriptionAttributeDataPoint_XValue"),
2687 TypeConverter(typeof(DataPointValueConverter)),
2688 DefaultValue(typeof(double), "0.0"),
2691 #if Microsoft_CONTROL
2692 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
2693 #else
2694 PersistenceMode(PersistenceMode.Attribute)
2695 #endif
2697 public double XValue
2701 return _xValue;
2705 _xValue = value;
2706 this.Invalidate(false);
2710 /// <summary>
2711 /// List of Y values of the data point.
2712 /// </summary>
2714 SRCategory("CategoryAttributeData"),
2715 SRDescription("DescriptionAttributeDataPoint_YValues"),
2716 Bindable(true),
2718 #if Microsoft_CONTROL
2719 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
2720 #else
2721 PersistenceMode(PersistenceMode.Attribute),
2722 #endif
2723 TypeConverter(typeof(DoubleArrayConverter)),
2724 Editor(typeof(UITypeEditor), typeof(UITypeEditor)),
2725 RefreshProperties(RefreshProperties.All),
2726 SerializationVisibilityAttribute(SerializationVisibility.Attribute)
2728 [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
2729 public double[] YValues
2733 return _yValue;
2737 if(value == null)
2739 // Clear array data
2740 for(int i=0; i < _yValue.Length; i++)
2742 _yValue[i] = 0;
2745 else
2747 _yValue = value;
2749 this.Invalidate(false);
2753 /// <summary>
2754 /// A flag which indicates whether the data point is empty.
2755 /// </summary>
2757 SRCategory("CategoryAttributeData"),
2759 Bindable(true),
2760 SRDescription("DescriptionAttributeDataPoint_Empty"),
2761 #if !Microsoft_CONTROL
2762 PersistenceMode(PersistenceMode.Attribute),
2763 #endif
2764 DefaultValue(false)
2766 public bool IsEmpty
2770 return base.isEmptyPoint;
2774 base.isEmptyPoint = value;
2775 this.Invalidate(true);
2779 /// <summary>
2780 /// Name of the data point. This field is reserved for internal use only.
2781 /// </summary>
2783 SRCategory("CategoryAttributeData"),
2784 Bindable(true),
2785 Browsable(false),
2786 SRDescription("DescriptionAttributeDataPoint_Name"),
2787 DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
2788 SerializationVisibilityAttribute(SerializationVisibility.Hidden)
2790 public override string Name
2794 return "DataPoint";
2798 //Dont call the base method - the names don't need to be unique
2802 #endregion
2806 /// <summary>
2807 /// Stores properties of one Data Point and Data series.
2808 /// </summary>
2810 SRDescription("DescriptionAttributeDataPointCustomProperties_DataPointCustomProperties"),
2811 DefaultProperty("LabelStyle"),
2812 TypeConverter(Editors.DataPointCustomPropertiesConverter.Convertor)
2814 #if Microsoft_CONTROL
2815 public class DataPointCustomProperties : ChartNamedElement
2816 #else
2817 #if ASPPERM_35
2818 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
2819 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
2820 #endif
2821 public class DataPointCustomProperties : ChartNamedElement, IChartMapArea
2822 #endif
2824 #region Fields and enumerations
2826 // True indicates data point properties. Otherwise - series.
2827 internal bool pointCustomProperties = true;
2829 // Reference to the data point series
2830 internal Series series = null;
2832 // Storage for the custom properties names/values
2833 internal Hashtable properties = new Hashtable();
2835 // Flag indicating that temp. color was set
2836 internal bool tempColorIsSet = false;
2838 // Design time custom properties data
2839 internal CustomProperties customProperties = null;
2841 // IsEmpty point indicator
2842 internal bool isEmptyPoint = false;
2844 #endregion
2846 #region Constructors
2848 /// <summary>
2849 /// DataPointCustomProperties constructor.
2850 /// </summary>
2851 public DataPointCustomProperties()
2853 // Initialize the data series
2854 this.series = null;
2855 this.customProperties = new CustomProperties(this);
2858 /// <summary>
2859 /// DataPointCustomProperties constructor.
2860 /// </summary>
2861 /// <param name="series">The series which the data point belongs to.</param>
2862 /// <param name="pointProperties">Indicates whether this is a data point custom properties.</param>
2863 public DataPointCustomProperties(Series series, bool pointProperties): base( series, String.Empty)
2865 // Initialize the data series
2866 this.series = series;
2867 this.pointCustomProperties = pointProperties;
2868 this.customProperties = new CustomProperties(this);
2871 #endregion
2873 #region Custom Properties methods
2875 /// <summary>
2876 /// Checks if custom property with specified name was set.
2877 /// </summary>
2878 /// <param name="name">Name of the custom property to check.</param>
2879 /// <returns>True if custom property was set.</returns>
2880 virtual public bool IsCustomPropertySet(string name)
2882 return properties.ContainsKey(name);
2885 /// <summary>
2886 /// Checks if the custom property with specified name was set.
2887 /// </summary>
2888 /// <param name="property">The CommonCustomProperties object to check for.</param>
2889 /// <returns>True if attribute was set.</returns>
2890 internal bool IsCustomPropertySet(CommonCustomProperties property)
2892 return properties.ContainsKey((int)property);
2895 /// <summary>
2896 /// Delete the data point custom property with the specified name.
2897 /// </summary>
2898 /// <param name="name">Name of the property to delete.</param>
2899 virtual public void DeleteCustomProperty(string name)
2901 if(name == null)
2903 throw (new ArgumentNullException(SR.ExceptionAttributeNameIsEmpty));
2906 // Check if trying to delete the common attribute
2907 string[] AttributesNames = CommonCustomProperties.GetNames(typeof(CommonCustomProperties));
2908 foreach(string commonName in AttributesNames)
2910 if(name == commonName)
2912 DeleteCustomProperty((CommonCustomProperties)Enum.Parse(typeof(CommonCustomProperties), commonName));
2916 // Remove attribute
2917 properties.Remove(name);
2920 /// <summary>
2921 /// Delete Data Point attribute with specified name.
2922 /// </summary>
2923 /// <param name="property">ID of the attribute to delete.</param>
2924 internal void DeleteCustomProperty(CommonCustomProperties property)
2926 // Check if trying to delete the common attribute from the series
2927 if(!this.pointCustomProperties)
2929 throw(new ArgumentException( SR.ExceptionAttributeUnableToDelete));
2932 // Remove attribute
2933 properties.Remove((int)property);
2936 /// <summary>
2937 /// Gets the data point custom property with the specified name.
2938 /// </summary>
2939 /// <param name="name">Name of the property to get.</param>
2940 /// <returns>Returns the data point custom property with the specified name. If the requested one is not set,
2941 /// the default custom property of the data series will be returned.</returns>
2942 virtual public string GetCustomProperty(string name)
2944 if(!IsCustomPropertySet(name) && this.pointCustomProperties)
2946 // Check if we are in serialization mode
2947 bool serializing = false;
2949 if(Chart != null && Chart.serializing)
2951 serializing = true;
2954 if(!serializing)
2957 if(this.isEmptyPoint)
2959 // Return empty point properties from series
2960 return (string)series.EmptyPointStyle.properties[name];
2963 // Return properties from series
2964 return (string)series.properties[name];
2966 else
2968 // Return default properties
2969 return (string)Series.defaultCustomProperties[name];
2973 return (string)properties[name];
2977 /// <summary>
2978 /// Checks if data is currently serialized.
2979 /// </summary>
2980 /// <returns>True if serialized.</returns>
2981 internal bool IsSerializing()
2983 // Check if series object is provided
2984 if(series == null)
2986 return true;
2989 // Check if we are in serialization mode
2990 if(Chart != null)
2992 return Chart.serializing;
2994 else
2996 return false;
3000 /// <summary>
3001 /// Returns an attribute object of the Data Point. If required attribute is not set
3002 /// in the Data Point the default attribute of the Data series is returned.
3003 /// </summary>
3004 /// <param name="attrib">Attribute name ID.</param>
3005 /// <returns>Attribute value.</returns>
3006 internal object GetAttributeObject(CommonCustomProperties attrib)
3008 // Get series properties
3009 if(!this.pointCustomProperties || series == null)
3011 return properties[(int)attrib];
3014 // Get data point properties
3015 if(properties.Count == 0 || !IsCustomPropertySet(attrib))
3017 // Check if we are in serialization mode
3018 bool serializing = false;
3019 if(Chart != null)
3021 serializing = Chart.serializing;
3024 if(!serializing)
3026 if(this.isEmptyPoint)
3028 // Return empty point properties from series
3029 return series.EmptyPointStyle.properties[(int)attrib];
3032 // Return properties from series
3033 return series.properties[(int)attrib];
3035 else
3037 // Return default properties
3038 return Series.defaultCustomProperties.properties[(int)attrib];
3041 return properties[(int)attrib];
3044 /// <summary>
3045 /// Sets a custom property of the data point.
3046 /// </summary>
3047 /// <param name="name">Property name.</param>
3048 /// <param name="propertyValue">Property value.</param>
3049 virtual public void SetCustomProperty(string name, string propertyValue)
3051 properties[name] = propertyValue;
3054 /// <summary>
3055 /// Sets an attribute of the Data Point as an object.
3056 /// </summary>
3057 /// <param name="attrib">Attribute name ID.</param>
3058 /// <param name="attributeValue">Attribute new value.</param>
3059 internal void SetAttributeObject(CommonCustomProperties attrib, object attributeValue)
3061 properties[(int)attrib] = attributeValue;
3064 /// <summary>
3065 /// Set the default properties of the data point.
3066 /// <param name="clearAll">Indicates that previous properties must be cleared.</param>
3067 /// </summary>
3068 virtual public void SetDefault(bool clearAll)
3070 // If setting defaults for the data series - clear all properties and initialize common one
3071 if(!this.pointCustomProperties)
3073 if(clearAll)
3075 properties.Clear();
3078 // !!! IMPORTANT !!!
3079 // After changing the default value of the common attribute you must also
3080 // change the DefaultAttribute of the property representing this attribute.
3081 if(!IsCustomPropertySet(CommonCustomProperties.ToolTip))
3082 SetAttributeObject(CommonCustomProperties.ToolTip, "");
3083 if(!IsCustomPropertySet(CommonCustomProperties.LegendToolTip))
3084 SetAttributeObject(CommonCustomProperties.LegendToolTip, "");
3085 if(!IsCustomPropertySet(CommonCustomProperties.Color))
3086 SetAttributeObject(CommonCustomProperties.Color, Color.Empty);
3087 if(!IsCustomPropertySet(CommonCustomProperties.IsValueShownAsLabel))
3088 SetAttributeObject(CommonCustomProperties.IsValueShownAsLabel, false);
3089 if(!IsCustomPropertySet(CommonCustomProperties.MarkerStyle))
3090 SetAttributeObject(CommonCustomProperties.MarkerStyle, MarkerStyle.None);
3091 if(!IsCustomPropertySet(CommonCustomProperties.MarkerSize))
3092 SetAttributeObject(CommonCustomProperties.MarkerSize, 5);
3093 if(!IsCustomPropertySet(CommonCustomProperties.MarkerImage))
3094 SetAttributeObject(CommonCustomProperties.MarkerImage, "");
3095 if(!IsCustomPropertySet(CommonCustomProperties.Label))
3096 SetAttributeObject(CommonCustomProperties.Label, "");
3097 if(!IsCustomPropertySet(CommonCustomProperties.BorderWidth))
3098 SetAttributeObject(CommonCustomProperties.BorderWidth, 1);
3099 if(!IsCustomPropertySet(CommonCustomProperties.BorderDashStyle))
3100 SetAttributeObject(CommonCustomProperties.BorderDashStyle, ChartDashStyle.Solid);
3103 if(!IsCustomPropertySet(CommonCustomProperties.AxisLabel))
3104 SetAttributeObject(CommonCustomProperties.AxisLabel, "");
3105 if(!IsCustomPropertySet(CommonCustomProperties.LabelFormat))
3106 SetAttributeObject(CommonCustomProperties.LabelFormat, "");
3107 if(!IsCustomPropertySet(CommonCustomProperties.BorderColor))
3108 SetAttributeObject(CommonCustomProperties.BorderColor, Color.Empty);
3109 if(!IsCustomPropertySet(CommonCustomProperties.BackImage))
3110 SetAttributeObject(CommonCustomProperties.BackImage, "");
3111 if(!IsCustomPropertySet(CommonCustomProperties.BackImageWrapMode))
3112 SetAttributeObject(CommonCustomProperties.BackImageWrapMode, ChartImageWrapMode.Tile);
3113 if(!IsCustomPropertySet(CommonCustomProperties.BackImageAlignment))
3114 SetAttributeObject(CommonCustomProperties.BackImageAlignment, ChartImageAlignmentStyle.TopLeft);
3115 if(!IsCustomPropertySet(CommonCustomProperties.BackImageTransparentColor))
3116 SetAttributeObject(CommonCustomProperties.BackImageTransparentColor, Color.Empty);
3117 if(!IsCustomPropertySet(CommonCustomProperties.BackGradientStyle))
3118 SetAttributeObject(CommonCustomProperties.BackGradientStyle, GradientStyle.None);
3119 if(!IsCustomPropertySet(CommonCustomProperties.BackSecondaryColor))
3120 SetAttributeObject(CommonCustomProperties.BackSecondaryColor, Color.Empty);
3121 if(!IsCustomPropertySet(CommonCustomProperties.BackHatchStyle))
3122 SetAttributeObject(CommonCustomProperties.BackHatchStyle, ChartHatchStyle.None);
3123 if(!IsCustomPropertySet(CommonCustomProperties.Font))
3124 SetAttributeObject(CommonCustomProperties.Font, null);
3125 if(!IsCustomPropertySet(CommonCustomProperties.MarkerImageTransparentColor))
3126 SetAttributeObject(CommonCustomProperties.MarkerImageTransparentColor, Color.Empty);
3127 if(!IsCustomPropertySet(CommonCustomProperties.MarkerColor))
3128 SetAttributeObject(CommonCustomProperties.MarkerColor, Color.Empty);
3129 if(!IsCustomPropertySet(CommonCustomProperties.MarkerBorderColor))
3130 SetAttributeObject(CommonCustomProperties.MarkerBorderColor, Color.Empty);
3131 if(!IsCustomPropertySet(CommonCustomProperties.MarkerBorderWidth))
3132 SetAttributeObject(CommonCustomProperties.MarkerBorderWidth, 1);
3133 if(!IsCustomPropertySet(CommonCustomProperties.MapAreaAttributes))
3134 SetAttributeObject(CommonCustomProperties.MapAreaAttributes, "");
3135 if (!IsCustomPropertySet(CommonCustomProperties.PostBackValue))
3136 SetAttributeObject(CommonCustomProperties.PostBackValue, "");
3138 if (!IsCustomPropertySet(CommonCustomProperties.LabelForeColor))
3139 SetAttributeObject(CommonCustomProperties.LabelForeColor, Color.Black);
3140 if (!IsCustomPropertySet(CommonCustomProperties.LabelAngle))
3141 SetAttributeObject(CommonCustomProperties.LabelAngle, 0);
3142 if (!IsCustomPropertySet(CommonCustomProperties.LabelToolTip))
3143 SetAttributeObject(CommonCustomProperties.LabelToolTip, "");
3144 if(!IsCustomPropertySet(CommonCustomProperties.LabelUrl))
3145 SetAttributeObject(CommonCustomProperties.LabelUrl, "");
3146 if (!IsCustomPropertySet(CommonCustomProperties.LabelPostBackValue))
3147 SetAttributeObject(CommonCustomProperties.LabelPostBackValue, "");
3148 if (!IsCustomPropertySet(CommonCustomProperties.LabelMapAreaAttributes))
3149 SetAttributeObject(CommonCustomProperties.LabelMapAreaAttributes, "");
3150 if(!IsCustomPropertySet(CommonCustomProperties.LabelBackColor))
3151 SetAttributeObject(CommonCustomProperties.LabelBackColor, Color.Empty);
3152 if(!IsCustomPropertySet(CommonCustomProperties.LabelBorderWidth))
3153 SetAttributeObject(CommonCustomProperties.LabelBorderWidth, 1);
3154 if(!IsCustomPropertySet(CommonCustomProperties.LabelBorderDashStyle))
3155 SetAttributeObject(CommonCustomProperties.LabelBorderDashStyle, ChartDashStyle.Solid);
3156 if(!IsCustomPropertySet(CommonCustomProperties.LabelBorderColor))
3157 SetAttributeObject(CommonCustomProperties.LabelBorderColor, Color.Empty);
3159 if(!IsCustomPropertySet(CommonCustomProperties.Url))
3160 SetAttributeObject(CommonCustomProperties.Url, "");
3161 if(!IsCustomPropertySet(CommonCustomProperties.LegendUrl))
3162 SetAttributeObject(CommonCustomProperties.LegendUrl, "");
3163 if (!IsCustomPropertySet(CommonCustomProperties.LegendPostBackValue))
3164 SetAttributeObject(CommonCustomProperties.LegendPostBackValue, "");
3165 if (!IsCustomPropertySet(CommonCustomProperties.LegendText))
3166 SetAttributeObject(CommonCustomProperties.LegendText, "");
3167 if(!IsCustomPropertySet(CommonCustomProperties.LegendMapAreaAttributes))
3168 SetAttributeObject(CommonCustomProperties.LegendMapAreaAttributes, "");
3169 if(!IsCustomPropertySet(CommonCustomProperties.IsVisibleInLegend))
3170 SetAttributeObject(CommonCustomProperties.IsVisibleInLegend, true);
3173 // If setting defaults for the data point - clear all properties
3174 else
3176 properties.Clear();
3180 #endregion
3182 #region DataPointCustomProperties Properties
3184 /// <summary>
3185 /// Indexer of the custom properties. Returns the DataPointCustomProperties object by index.
3186 /// </summary>
3187 /// <param name="index">Index of the custom property.</param>
3188 public string this[int index]
3192 int currentIndex = 0;
3193 foreach(object key in properties.Keys)
3195 if(currentIndex == index)
3197 string keyStr = key as string;
3198 if (keyStr != null)
3200 return keyStr;
3202 else if (key is int)
3204 return Enum.GetName(typeof(CommonCustomProperties), key);
3206 return key.ToString();
3208 ++currentIndex;
3210 // we can't throw IndexOutOfRangeException here, it is reserved
3211 // by the CLR.
3212 throw (new InvalidOperationException());
3216 /// <summary>
3217 /// Indexer of the custom properties. Returns the DataPointCustomProperties object by name.
3218 /// </summary>
3219 /// <param name="name">Name of the custom property.</param>
3220 public string this[string name]
3224 // If attribute is not set in data point - try getting it from the series
3225 if(!IsCustomPropertySet(name) && this.pointCustomProperties)
3227 if(this.isEmptyPoint)
3229 return (string)series.EmptyPointStyle.properties[name];
3232 return (string)series.properties[name];
3234 return (string)properties[name];
3238 properties[name] = value;
3239 this.Invalidate(true);
3243 /// <summary>
3244 /// The text of the data point label.
3245 /// </summary>
3247 Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base),
3248 #if !Microsoft_CONTROL
3249 PersistenceMode(PersistenceMode.Attribute),
3250 #endif
3251 SRCategory("CategoryAttributeLabel"),
3252 Bindable(true),
3253 SRDescription("DescriptionAttributeLabel"),
3255 virtual public string Label
3259 if(this.pointCustomProperties)
3261 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.Label))
3263 return (string)GetAttributeObject(CommonCustomProperties.Label);
3265 else
3267 if(IsSerializing())
3269 return "";
3271 if(this.isEmptyPoint)
3273 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.Label);
3276 return series.label;
3279 else
3281 return series.label;
3286 // Replace NULL with empty string
3287 if(value == null)
3289 value = string.Empty;
3292 if (this.pointCustomProperties)
3293 SetAttributeObject(CommonCustomProperties.Label, value);
3294 else
3295 series.label = value;
3297 this.Invalidate(true);
3301 /// <summary>
3302 /// The text of X axis label for the data point.
3303 /// </summary>
3305 SRCategory("CategoryAttributeMisc"),
3306 Bindable(true),
3307 SRDescription("DescriptionAttributeAxisLabel"),
3308 Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base),
3309 #if !Microsoft_CONTROL
3310 PersistenceMode(PersistenceMode.Attribute)
3311 #endif
3313 virtual public string AxisLabel
3317 if(this.pointCustomProperties)
3319 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.AxisLabel))
3321 return (string)GetAttributeObject(CommonCustomProperties.AxisLabel);
3323 else
3325 if(IsSerializing())
3327 return "";
3329 if(this.isEmptyPoint)
3331 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.AxisLabel);
3334 return series.axisLabel;
3338 else
3340 return series.axisLabel;
3345 // Replace NULL with empty string
3346 if(value == null)
3348 value = string.Empty;
3351 if(this.pointCustomProperties)
3352 SetAttributeObject(CommonCustomProperties.AxisLabel, value);
3353 else
3354 series.axisLabel = value;
3356 // Set flag that there are non-empy axis labels in series or points
3357 if(value.Length > 0 && series != null)
3359 series.noLabelsInPoints = false;
3362 this.Invalidate(false);
3366 /// <summary>
3367 /// Format string of the data point label.
3368 /// </summary>
3371 SRCategory("CategoryAttributeLabel"),
3372 Bindable(true),
3373 SRDescription("DescriptionAttributeLabelFormat"),
3374 #if !Microsoft_CONTROL
3375 PersistenceMode(PersistenceMode.Attribute),
3376 #endif
3378 public string LabelFormat
3382 if(this.pointCustomProperties)
3384 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelFormat))
3386 return (string)GetAttributeObject(CommonCustomProperties.LabelFormat);
3388 else
3390 if(IsSerializing())
3392 return "";
3394 if(this.isEmptyPoint)
3396 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelFormat);
3399 return series.labelFormat;
3402 else
3404 return series.labelFormat;
3409 // Replace NULL with empty string
3410 if(value == null)
3412 value = string.Empty;
3415 if(this.pointCustomProperties)
3416 SetAttributeObject(CommonCustomProperties.LabelFormat, value);
3417 else
3418 series.labelFormat = value;
3419 this.Invalidate(false);
3423 /// <summary>
3424 /// A flag which indicates whether to show the data point's value on the label.
3425 /// </summary>
3428 SRCategory("CategoryAttributeLabel"),
3429 Bindable(true),
3430 SRDescription("DescriptionAttributeShowLabelAsValue"),
3431 #if !Microsoft_CONTROL
3432 PersistenceMode(PersistenceMode.Attribute)
3433 #endif
3435 public bool IsValueShownAsLabel
3439 if(this.pointCustomProperties)
3441 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.IsValueShownAsLabel))
3443 return (bool)GetAttributeObject(CommonCustomProperties.IsValueShownAsLabel);
3445 else
3447 if(IsSerializing())
3449 return false;
3451 if(this.isEmptyPoint)
3453 return (bool)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.IsValueShownAsLabel);
3456 return series.showLabelAsValue;
3460 else
3462 return series.showLabelAsValue;
3467 if(this.pointCustomProperties)
3468 SetAttributeObject(CommonCustomProperties.IsValueShownAsLabel, value);
3469 else
3470 series.showLabelAsValue = value;
3471 this.Invalidate(false);
3475 /// <summary>
3476 /// Color of the data point.
3477 /// </summary>
3479 SRCategory("CategoryAttributeAppearance"),
3480 Bindable(true),
3481 SRDescription("DescriptionAttributeColor4"),
3482 TypeConverter(typeof(ColorConverter)),
3483 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
3484 #if !Microsoft_CONTROL
3485 PersistenceMode(PersistenceMode.Attribute)
3486 #endif
3488 public Color Color
3492 if(this.pointCustomProperties)
3494 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.Color))
3496 return (Color)GetAttributeObject(CommonCustomProperties.Color);
3498 else
3500 if(IsSerializing())
3502 return Color.Empty;
3504 if(this.isEmptyPoint)
3506 return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.Color);
3509 return series.color;
3512 else
3514 return series.color;
3519 // Remove the temp color flag
3520 this.tempColorIsSet = false;
3522 if(value == Color.Empty && this.pointCustomProperties)
3524 DeleteCustomProperty(CommonCustomProperties.Color);
3526 else
3528 if(this.pointCustomProperties)
3529 SetAttributeObject(CommonCustomProperties.Color, value);
3530 else
3531 series.color = value;
3532 this.Invalidate(true);
3537 /// <summary>
3538 /// Border color of the data point.
3539 /// </summary>
3541 SRCategory("CategoryAttributeAppearance"),
3542 Bindable(true),
3543 SRDescription("DescriptionAttributeBorderColor"),
3544 TypeConverter(typeof(ColorConverter)),
3545 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
3546 #if !Microsoft_CONTROL
3547 PersistenceMode(PersistenceMode.Attribute)
3548 #endif
3550 public Color BorderColor
3554 if(this.pointCustomProperties)
3556 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BorderColor))
3558 return (Color)GetAttributeObject(CommonCustomProperties.BorderColor);
3560 else
3562 if(IsSerializing())
3564 return Color.Empty;
3566 if(this.isEmptyPoint)
3568 return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BorderColor);
3571 return series.borderColor;
3574 else
3576 return series.borderColor;
3581 if(this.pointCustomProperties)
3582 SetAttributeObject(CommonCustomProperties.BorderColor, value);
3583 else
3584 series.borderColor = value;
3585 this.Invalidate(true);
3589 /// <summary>
3590 /// Border style of the data point.
3591 /// </summary>
3593 SRCategory("CategoryAttributeAppearance"),
3594 Bindable(true),
3595 SRDescription("DescriptionAttributeBorderDashStyle"),
3596 #if !Microsoft_CONTROL
3597 PersistenceMode(PersistenceMode.Attribute)
3598 #endif
3600 public ChartDashStyle BorderDashStyle
3604 if(this.pointCustomProperties)
3606 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BorderDashStyle))
3608 return (ChartDashStyle)GetAttributeObject(CommonCustomProperties.BorderDashStyle);
3610 else
3612 if(IsSerializing())
3614 return ChartDashStyle.Solid;
3616 if(this.isEmptyPoint)
3618 return (ChartDashStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BorderDashStyle);
3621 return series.borderDashStyle;
3625 else
3627 return series.borderDashStyle;
3632 if(this.pointCustomProperties)
3633 SetAttributeObject(CommonCustomProperties.BorderDashStyle, value);
3634 else
3635 series.borderDashStyle = value;
3636 this.Invalidate(true);
3640 /// <summary>
3641 /// Border width of the data point.
3642 /// </summary>
3644 SRCategory("CategoryAttributeAppearance"),
3645 Bindable(true),
3646 SRDescription("DescriptionAttributeBorderWidth"),
3647 #if !Microsoft_CONTROL
3648 PersistenceMode(PersistenceMode.Attribute)
3649 #endif
3651 public int BorderWidth
3655 if(this.pointCustomProperties)
3657 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BorderWidth))
3659 return (int)GetAttributeObject(CommonCustomProperties.BorderWidth);
3661 else
3663 if(IsSerializing())
3665 return 1;
3667 if(this.isEmptyPoint)
3669 return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BorderWidth);
3672 return series.borderWidth;
3676 else
3678 return series.borderWidth;
3683 if(value < 0)
3685 throw (new ArgumentOutOfRangeException("value", SR.ExceptionBorderWidthIsNotPositive));
3687 if(this.pointCustomProperties)
3688 SetAttributeObject(CommonCustomProperties.BorderWidth, value);
3689 else
3690 series.borderWidth = value;
3691 this.Invalidate(true);
3695 /// <summary>
3696 /// Background image of the data point.
3697 /// </summary>
3699 SRCategory("CategoryAttributeAppearance"),
3700 Bindable(true),
3701 SRDescription("DescriptionAttributeBackImage"),
3702 Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base),
3703 #if !Microsoft_CONTROL
3704 PersistenceMode(PersistenceMode.Attribute),
3705 #endif
3707 public string BackImage
3711 if(this.pointCustomProperties)
3713 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackImage))
3715 return (string)GetAttributeObject(CommonCustomProperties.BackImage);
3717 else
3719 if(IsSerializing())
3721 return "";
3723 if(this.isEmptyPoint)
3725 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackImage);
3728 return series.backImage;
3732 else
3734 return series.backImage;
3739 // Replace NULL with empty string
3740 if(value == null)
3742 value = string.Empty;
3745 if(this.pointCustomProperties)
3746 SetAttributeObject(CommonCustomProperties.BackImage, value);
3747 else
3748 series.backImage = value;
3749 this.Invalidate(true);
3753 /// <summary>
3754 /// Gets or sets the drawing mode of the background image.
3755 /// </summary>
3756 /// <value>
3757 /// A <see cref="ChartImageWrapMode"/> value that defines the drawing mode of the image.
3758 /// </value>
3760 SRCategory("CategoryAttributeAppearance"),
3761 Bindable(true),
3762 SRDescription("DescriptionAttributeImageWrapMode"),
3763 #if !Microsoft_CONTROL
3764 PersistenceMode(PersistenceMode.Attribute)
3765 #endif
3767 public ChartImageWrapMode BackImageWrapMode
3771 if(this.pointCustomProperties)
3773 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackImageWrapMode))
3775 return (ChartImageWrapMode)GetAttributeObject(CommonCustomProperties.BackImageWrapMode);
3777 else
3779 if(IsSerializing())
3781 return ChartImageWrapMode.Tile;
3783 if(this.isEmptyPoint)
3785 return (ChartImageWrapMode)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackImageWrapMode);
3788 return series.backImageWrapMode;
3792 else
3794 return series.backImageWrapMode;
3799 if(this.pointCustomProperties)
3800 SetAttributeObject(CommonCustomProperties.BackImageWrapMode, value);
3801 else
3802 series.backImageWrapMode = value;
3803 this.Invalidate(true);
3807 /// <summary>
3808 /// Gets or sets a color which will be replaced with a transparent color while drawing the background image.
3809 /// </summary>
3810 /// <value>
3811 /// A <see cref="Color"/> value which will be replaced with a transparent color while drawing the image.
3812 /// </value>
3814 SRCategory("CategoryAttributeAppearance"),
3815 Bindable(true),
3816 NotifyParentPropertyAttribute(true),
3817 SRDescription("DescriptionAttributeImageTransparentColor"),
3818 TypeConverter(typeof(ColorConverter)),
3819 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
3820 #if !Microsoft_CONTROL
3821 PersistenceMode(PersistenceMode.Attribute)
3822 #endif
3824 public Color BackImageTransparentColor
3828 if(this.pointCustomProperties)
3830 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackImageTransparentColor))
3832 return (Color)GetAttributeObject(CommonCustomProperties.BackImageTransparentColor);
3834 else
3836 if(IsSerializing())
3838 return Color.Empty;
3840 if(this.isEmptyPoint)
3842 return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackImageTransparentColor);
3845 return series.backImageTransparentColor;
3849 else
3851 return series.backImageTransparentColor;
3856 if(this.pointCustomProperties)
3857 SetAttributeObject(CommonCustomProperties.BackImageTransparentColor, value);
3858 else
3859 series.backImageTransparentColor = value;
3860 this.Invalidate(true);
3864 /// <summary>
3865 /// Gets or sets the alignment of the background image which is used by ClampUnscale drawing mode.
3866 /// </summary>
3868 SRCategory("CategoryAttributeAppearance"),
3869 Bindable(true),
3870 NotifyParentPropertyAttribute(true),
3871 SRDescription("DescriptionAttributeBackImageAlign"),
3872 #if !Microsoft_CONTROL
3873 PersistenceMode(PersistenceMode.Attribute)
3874 #endif
3876 public ChartImageAlignmentStyle BackImageAlignment
3880 if(this.pointCustomProperties)
3882 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackImageAlignment))
3884 return (ChartImageAlignmentStyle)GetAttributeObject(CommonCustomProperties.BackImageAlignment);
3886 else
3888 if(IsSerializing())
3890 return ChartImageAlignmentStyle.TopLeft;
3892 if(this.isEmptyPoint)
3894 return (ChartImageAlignmentStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackImageAlignment);
3897 return series.backImageAlignment;
3901 else
3903 return series.backImageAlignment;
3908 if(this.pointCustomProperties)
3909 SetAttributeObject(CommonCustomProperties.BackImageAlignment, value);
3910 else
3911 series.backImageAlignment = value;
3912 this.Invalidate(true);
3916 /// <summary>
3917 /// Gets or sets the background gradient style.
3918 /// </summary>
3920 SRCategory("CategoryAttributeAppearance"),
3921 Bindable(true),
3922 SRDescription("DescriptionAttributeBackGradientStyle"),
3923 #if !Microsoft_CONTROL
3924 PersistenceMode(PersistenceMode.Attribute),
3925 #endif
3926 Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base)
3928 public GradientStyle BackGradientStyle
3932 if(this.pointCustomProperties)
3934 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackGradientStyle))
3936 return (GradientStyle)GetAttributeObject(CommonCustomProperties.BackGradientStyle);
3938 else
3940 if(IsSerializing())
3942 return GradientStyle.None;
3944 if(this.isEmptyPoint)
3946 return (GradientStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackGradientStyle);
3949 return series.backGradientStyle;
3953 else
3955 return series.backGradientStyle;
3960 if(this.pointCustomProperties)
3961 SetAttributeObject(CommonCustomProperties.BackGradientStyle, value);
3962 else
3963 series.backGradientStyle = value;
3964 this.Invalidate(true);
3968 /// <summary>
3969 /// Gets or sets the secondary background color.
3970 /// </summary>
3972 SRCategory("CategoryAttributeAppearance"),
3973 Bindable(true),
3974 SRDescription("DescriptionAttributeBackSecondaryColor"),
3975 TypeConverter(typeof(ColorConverter)),
3976 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
3977 #if !Microsoft_CONTROL
3978 PersistenceMode(PersistenceMode.Attribute)
3979 #endif
3981 public Color BackSecondaryColor
3985 if(this.pointCustomProperties)
3987 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackSecondaryColor))
3989 return (Color)GetAttributeObject(CommonCustomProperties.BackSecondaryColor);
3991 else
3993 if(IsSerializing())
3995 return Color.Empty;
3997 if(this.isEmptyPoint)
3999 return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackSecondaryColor);
4002 return series.backSecondaryColor;
4006 else
4008 return series.backSecondaryColor;
4013 if(this.pointCustomProperties)
4014 SetAttributeObject(CommonCustomProperties.BackSecondaryColor, value);
4015 else
4016 series.backSecondaryColor = value;
4017 this.Invalidate(true);
4021 /// <summary>
4022 /// Gets or sets the background hatch style.
4023 /// </summary>
4025 SRCategory("CategoryAttributeAppearance"),
4026 Bindable(true),
4027 SRDescription("DescriptionAttributeBackHatchStyle"),
4028 #if !Microsoft_CONTROL
4029 PersistenceMode(PersistenceMode.Attribute),
4030 #endif
4031 Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base)
4033 public ChartHatchStyle BackHatchStyle
4037 if(this.pointCustomProperties)
4039 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackHatchStyle))
4041 return (ChartHatchStyle)GetAttributeObject(CommonCustomProperties.BackHatchStyle);
4043 else
4045 if(IsSerializing())
4047 return ChartHatchStyle.None;
4049 if(this.isEmptyPoint)
4051 return (ChartHatchStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackHatchStyle);
4054 return series.backHatchStyle;
4058 else
4060 return series.backHatchStyle;
4065 if(this.pointCustomProperties)
4066 SetAttributeObject(CommonCustomProperties.BackHatchStyle, value);
4067 else
4068 series.backHatchStyle = value;
4069 this.Invalidate(true);
4073 /// <summary>
4074 /// Gets or sets the font of the data point.
4075 /// </summary>
4077 SRCategory("CategoryAttributeLabelAppearance"),
4078 Bindable(true),
4079 SRDescription("DescriptionAttributeFont"),
4080 #if !Microsoft_CONTROL
4081 PersistenceMode(PersistenceMode.Attribute)
4082 #endif
4084 public Font Font
4088 if(this.pointCustomProperties)
4090 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.Font))
4092 Font font = GetAttributeObject(CommonCustomProperties.Font) as Font;
4093 if (font != null)
4094 return font;
4097 if(IsSerializing())
4099 return series.FontCache.DefaultFont;
4102 if(this.isEmptyPoint)
4104 return series.EmptyPointStyle.Font;
4107 return series.font;
4109 else
4111 return series.font;
4116 if(this.pointCustomProperties)
4117 SetAttributeObject(CommonCustomProperties.Font, value);
4118 else
4119 series.font = value;
4120 this.Invalidate(false);
4124 /// <summary>
4125 /// Gets or sets the label color.
4126 /// </summary>
4128 SRCategory("CategoryAttributeLabelAppearance"),
4129 Bindable(true),
4130 SRDescription("DescriptionAttributeFontColor"),
4131 TypeConverter(typeof(ColorConverter)),
4132 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
4133 #if !Microsoft_CONTROL
4134 PersistenceMode(PersistenceMode.Attribute)
4135 #endif
4137 public Color LabelForeColor
4141 if(this.pointCustomProperties)
4143 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelForeColor))
4145 Color color = (Color)GetAttributeObject(CommonCustomProperties.LabelForeColor);
4146 return color;
4148 else
4150 if(IsSerializing())
4152 return Color.Black;
4154 if(this.isEmptyPoint)
4156 return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelForeColor);
4159 return series.fontColor;
4163 else
4165 return series.fontColor;
4170 if(this.pointCustomProperties)
4171 SetAttributeObject(CommonCustomProperties.LabelForeColor, value);
4172 else
4173 series.fontColor = value;
4174 this.Invalidate(false);
4178 /// <summary>
4179 /// Gets or sets the angle of the label.
4180 /// </summary>
4182 SRCategory("CategoryAttributeLabelAppearance"),
4183 Bindable(true),
4184 SRDescription(SR.Keys.DescriptionAttributeLabel_FontAngle),
4185 #if !Microsoft_CONTROL
4186 PersistenceMode(PersistenceMode.Attribute),
4187 #endif
4189 public int LabelAngle
4193 if(this.pointCustomProperties)
4195 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelAngle))
4197 return (int)GetAttributeObject(CommonCustomProperties.LabelAngle);
4199 else
4201 if(IsSerializing())
4203 return 0;
4205 if(this.isEmptyPoint)
4207 return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelAngle);
4210 return series.fontAngle;
4214 else
4216 return series.fontAngle;
4221 if(value < -90 || value > 90)
4223 throw (new ArgumentOutOfRangeException("value", SR.ExceptionAngleRangeInvalid));
4225 if(this.pointCustomProperties)
4226 SetAttributeObject(CommonCustomProperties.LabelAngle, value);
4227 else
4228 series.fontAngle = value;
4229 this.Invalidate(false);
4233 /// <summary>
4234 /// Gets or sets the marker style.
4235 /// </summary>
4237 SRCategory("CategoryAttributeMarker"),
4238 Bindable(true),
4239 SRDescription("DescriptionAttributeMarkerStyle4"),
4240 #if !Microsoft_CONTROL
4241 PersistenceMode(PersistenceMode.Attribute),
4242 #endif
4243 Editor(Editors.MarkerStyleEditor.Editor, Editors.MarkerStyleEditor.Base),
4244 RefreshProperties(RefreshProperties.All)
4246 public MarkerStyle MarkerStyle
4250 if(this.pointCustomProperties)
4252 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerStyle))
4254 return (MarkerStyle)GetAttributeObject(CommonCustomProperties.MarkerStyle);
4256 else
4258 if(IsSerializing())
4260 return MarkerStyle.None;
4262 if(this.isEmptyPoint)
4264 return (MarkerStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerStyle);
4267 return series.markerStyle;
4271 else
4273 return series.markerStyle;
4278 if(this.pointCustomProperties)
4279 SetAttributeObject(CommonCustomProperties.MarkerStyle, value);
4280 else
4281 series.markerStyle = value;
4283 Series thisSeries = this as Series;
4284 if(thisSeries != null)
4286 thisSeries.tempMarkerStyleIsSet = false;
4288 this.Invalidate(true);
4292 /// <summary>
4293 /// Gets or sets the size of the marker.
4294 /// </summary>
4296 SRCategory("CategoryAttributeMarker"),
4297 Bindable(true),
4298 SRDescription("DescriptionAttributeMarkerSize"),
4299 #if !Microsoft_CONTROL
4300 PersistenceMode(PersistenceMode.Attribute),
4301 #endif
4302 RefreshProperties(RefreshProperties.All)
4304 public int MarkerSize
4308 if(this.pointCustomProperties)
4310 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerSize))
4312 return (int)GetAttributeObject(CommonCustomProperties.MarkerSize);
4314 else
4316 if(IsSerializing())
4318 return 5;
4320 if(this.isEmptyPoint)
4322 return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerSize);
4325 return series.markerSize;
4329 else
4331 return series.markerSize;
4336 if(this.pointCustomProperties)
4337 SetAttributeObject(CommonCustomProperties.MarkerSize, value);
4338 else
4339 series.markerSize = value;
4340 this.Invalidate(true);
4344 /// <summary>
4345 /// Gets or sets the marker image.
4346 /// </summary>
4348 SRCategory("CategoryAttributeMarker"),
4349 Bindable(true),
4350 SRDescription("DescriptionAttributeMarkerImage"),
4351 Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base),
4352 #if !Microsoft_CONTROL
4353 PersistenceMode(PersistenceMode.Attribute),
4354 #endif
4355 RefreshProperties(RefreshProperties.All)
4357 public string MarkerImage
4361 if(this.pointCustomProperties)
4363 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerImage))
4365 return (string)GetAttributeObject(CommonCustomProperties.MarkerImage);
4367 else
4369 if(IsSerializing())
4371 return "";
4373 if(this.isEmptyPoint)
4375 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerImage);
4378 return series.markerImage;
4382 else
4384 return series.markerImage;
4389 // Replace NULL with empty string
4390 if(value == null)
4392 value = string.Empty;
4395 if(this.pointCustomProperties)
4396 SetAttributeObject(CommonCustomProperties.MarkerImage, value);
4397 else
4398 series.markerImage = value;
4399 this.Invalidate(true);
4403 /// <summary>
4404 /// Gets or sets the color which will be replaced with a transparent color while drawing the marker image.
4405 /// </summary>
4407 SRCategory("CategoryAttributeMarker"),
4408 Bindable(true),
4409 SRDescription("DescriptionAttributeImageTransparentColor"),
4410 TypeConverter(typeof(ColorConverter)),
4411 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
4412 #if !Microsoft_CONTROL
4413 PersistenceMode(PersistenceMode.Attribute),
4414 #endif
4415 RefreshProperties(RefreshProperties.All)
4417 public Color MarkerImageTransparentColor
4421 if(this.pointCustomProperties)
4423 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerImageTransparentColor))
4425 return (Color)GetAttributeObject(CommonCustomProperties.MarkerImageTransparentColor);
4427 else
4429 if(IsSerializing())
4431 return Color.Empty;
4433 if(this.isEmptyPoint)
4435 return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerImageTransparentColor);
4438 return series.markerImageTransparentColor;
4442 else
4444 return series.markerImageTransparentColor;
4449 if(this.pointCustomProperties)
4450 SetAttributeObject(CommonCustomProperties.MarkerImageTransparentColor, value);
4451 else
4452 series.markerImageTransparentColor = value;
4453 this.Invalidate(true);
4457 /// <summary>
4458 /// Gets or sets the marker color.
4459 /// </summary>
4461 SRCategory("CategoryAttributeMarker"),
4462 Bindable(true),
4463 SRDescription("DescriptionAttributeMarkerColor3"),
4464 TypeConverter(typeof(ColorConverter)),
4465 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
4466 #if !Microsoft_CONTROL
4467 PersistenceMode(PersistenceMode.Attribute),
4468 #endif
4469 RefreshProperties(RefreshProperties.All)
4471 public Color MarkerColor
4475 if(this.pointCustomProperties)
4477 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerColor))
4479 return (Color)GetAttributeObject(CommonCustomProperties.MarkerColor);
4481 else
4483 if(IsSerializing())
4485 return Color.Empty;
4487 if(this.isEmptyPoint)
4489 return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerColor);
4492 return series.markerColor;
4496 else
4498 return series.markerColor;
4503 if(this.pointCustomProperties)
4504 SetAttributeObject(CommonCustomProperties.MarkerColor, value);
4505 else
4506 series.markerColor = value;
4507 this.Invalidate(true);
4511 /// <summary>
4512 /// Gets or sets the border color of the marker.
4513 /// </summary>
4515 SRCategory("CategoryAttributeMarker"),
4516 Bindable(true),
4517 SRDescription("DescriptionAttributeMarkerBorderColor"),
4518 TypeConverter(typeof(ColorConverter)),
4519 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
4520 #if !Microsoft_CONTROL
4521 PersistenceMode(PersistenceMode.Attribute),
4522 #endif
4523 RefreshProperties(RefreshProperties.All)
4525 public Color MarkerBorderColor
4529 if(this.pointCustomProperties)
4531 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerBorderColor))
4533 return (Color)GetAttributeObject(CommonCustomProperties.MarkerBorderColor);
4535 else
4537 if(IsSerializing())
4539 return Color.Empty;
4541 if(this.isEmptyPoint)
4543 return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerBorderColor);
4546 return series.markerBorderColor;
4550 else
4552 return series.markerBorderColor;
4557 if(this.pointCustomProperties)
4558 SetAttributeObject(CommonCustomProperties.MarkerBorderColor, value);
4559 else
4560 series.markerBorderColor = value;
4561 this.Invalidate(true);
4567 /// <summary>
4568 /// Gets or sets the border width of the marker.
4569 /// </summary>
4572 SRCategory("CategoryAttributeMarker"),
4573 Bindable(true),
4574 SRDescription("DescriptionAttributeMarkerBorderWidth"),
4575 #if !Microsoft_CONTROL
4576 PersistenceMode(PersistenceMode.Attribute)
4577 #endif
4579 public int MarkerBorderWidth
4583 if(this.pointCustomProperties)
4585 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerBorderWidth))
4587 return (int)GetAttributeObject(CommonCustomProperties.MarkerBorderWidth);
4589 else
4591 if(IsSerializing())
4593 return 1;
4595 if(this.isEmptyPoint)
4597 return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerBorderWidth);
4600 return series.markerBorderWidth;
4604 else
4606 return series.markerBorderWidth;
4611 if(value < 0)
4613 throw (new ArgumentOutOfRangeException("value", SR.ExceptionBorderWidthIsNotPositive));
4615 if(this.pointCustomProperties)
4616 SetAttributeObject(CommonCustomProperties.MarkerBorderWidth, value);
4617 else
4618 series.markerBorderWidth = value;
4619 this.Invalidate(true);
4625 /// <summary>
4626 /// Gets or sets the extended custom properties of the data point.
4627 /// Extended custom properties can be specified in the following format:
4628 /// AttrName1=Value1, AttrName2=Value2, ...
4629 /// </summary>
4631 SRCategory("CategoryAttributeMisc"),
4632 Bindable(false),
4633 SRDescription("DescriptionAttributeCustomAttributesExtended"),
4634 DefaultValue(null),
4635 RefreshProperties(RefreshProperties.All),
4636 NotifyParentPropertyAttribute(true),
4637 DesignOnlyAttribute(true),
4638 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
4639 SerializationVisibilityAttribute(SerializationVisibility.Hidden),
4640 EditorBrowsableAttribute(EditorBrowsableState.Never),
4641 DisplayName("CustomProperties")
4643 public CustomProperties CustomPropertiesExtended
4647 customProperties = value;
4651 return customProperties;
4655 /// <summary>
4656 /// Gets or sets the custom properties of the data point.
4657 /// Custom properties can be specified in the following format:
4658 /// AttrName1=Value1, AttrName2=Value2, ...
4659 /// </summary>
4661 SRCategory("CategoryAttributeMisc"),
4662 Bindable(true),
4663 Browsable(false),
4664 SRDescription("DescriptionAttributeCustomAttributesExtended"),
4665 DefaultValue(""),
4666 #if !Microsoft_CONTROL
4667 PersistenceMode(PersistenceMode.Attribute)
4668 #endif
4670 public string CustomProperties
4674 // Save all custom properties in a string
4675 string result = "";
4676 string[] attributesNames = CommonCustomProperties.GetNames(typeof(CommonCustomProperties));
4677 for(int i = properties.Count - 1; i >= 0; i--)
4679 if(this[i] != null)
4681 string attributeName = this[i];
4683 // Check if attribute is custom
4684 bool customAttribute = true;
4685 foreach(string name in attributesNames)
4687 if(String.Compare(attributeName, name, StringComparison.OrdinalIgnoreCase) == 0)
4689 customAttribute = false;
4690 break;
4694 // Add custom attribute to the string
4695 if(customAttribute && properties[attributeName] != null)
4697 if(result.Length > 0)
4699 result += ", ";
4701 string attributeValue = properties[attributeName].ToString().Replace(",", "\\,");
4702 attributeValue = attributeValue.Replace("=", "\\=");
4704 result += attributeName + "=" + attributeValue;
4709 return result;
4713 // Replace NULL with empty string
4714 if(value == null)
4716 value = string.Empty;
4719 // Copy all common properties to the new collection
4720 Hashtable newAttributes = new Hashtable();
4721 Array enumValues = Enum.GetValues(typeof(CommonCustomProperties));
4722 foreach(object val in enumValues)
4724 if(IsCustomPropertySet((CommonCustomProperties)val))
4726 newAttributes[(int)val] = properties[(int)val];
4730 if(value.Length > 0)
4732 // Replace commas in value string
4733 value = value.Replace("\\,", "\\x45");
4734 value = value.Replace("\\=", "\\x46");
4736 // Add new custom properties
4737 string[] nameValueStrings = value.Split(',');
4738 foreach(string nameValue in nameValueStrings)
4740 string[] values = nameValue.Split('=');
4742 // Check format
4743 if(values.Length != 2)
4745 throw(new FormatException( SR.ExceptionAttributeInvalidFormat));
4748 // Check for empty name or value
4749 values[0] = values[0].Trim();
4750 values[1] = values[1].Trim();
4751 if(values[0].Length == 0)
4753 throw(new FormatException( SR.ExceptionAttributeInvalidFormat));
4756 // Check if value already defined
4757 foreach(object existingAttributeName in newAttributes.Keys)
4759 string existingAttributeNameStr = existingAttributeName as string;
4760 if (existingAttributeNameStr != null)
4762 if (String.Compare(existingAttributeNameStr, values[0], StringComparison.OrdinalIgnoreCase) == 0)
4764 throw(new FormatException( SR.ExceptionAttributeNameIsNotUnique(values[0] ) ) );
4769 string newValue = values[1].Replace("\\x45", ",");
4770 newAttributes[values[0]] = newValue.Replace("\\x46", "=");
4774 properties = newAttributes;
4775 this.Invalidate(true);
4779 #endregion
4781 #region IMapAreaAttributesutes Properties implementation
4783 /// <summary>
4784 /// Tooltip.
4785 /// </summary>
4787 SRCategory("CategoryAttributeMapArea"),
4788 Bindable(true),
4789 SRDescription("DescriptionAttributeToolTip"),
4790 Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base),
4791 #if !Microsoft_CONTROL
4792 DefaultValue(""),
4793 PersistenceMode(PersistenceMode.Attribute)
4794 #endif
4796 public string ToolTip
4800 if(this.pointCustomProperties)
4801 SetAttributeObject(CommonCustomProperties.ToolTip, value);
4802 else
4803 series.toolTip = value;
4805 #if Microsoft_CONTROL
4806 if(Chart != null && Chart.selection != null)
4808 Chart.selection.enabledChecked = false;
4810 #endif
4814 if(this.pointCustomProperties)
4816 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.ToolTip))
4818 return (String)GetAttributeObject(CommonCustomProperties.ToolTip);
4820 else
4822 if(IsSerializing())
4824 return "";
4826 if(this.isEmptyPoint)
4828 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.ToolTip);
4831 return series.toolTip;
4835 else
4837 return series.toolTip;
4842 #if !Microsoft_CONTROL
4844 /// <summary>
4845 /// URL target of the area.
4846 /// </summary>
4848 SRCategory("CategoryAttributeMapArea"),
4849 Bindable(true),
4850 SRDescription("DescriptionAttributeUrl"),
4851 DefaultValue(""),
4852 #if !Microsoft_CONTROL
4853 PersistenceMode(PersistenceMode.Attribute),
4854 Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base)
4855 #endif
4857 public string Url
4861 if(this.pointCustomProperties)
4862 SetAttributeObject(CommonCustomProperties.Url, value);
4863 else
4864 series.url = value;
4868 if(this.pointCustomProperties)
4870 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.Url))
4872 return (String)GetAttributeObject(CommonCustomProperties.Url);
4874 else
4876 if(IsSerializing())
4878 return "";
4880 if(this.isEmptyPoint)
4882 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.Url);
4885 return series.url;
4889 else
4891 return series.url;
4896 /// <summary>
4897 /// Other attributes of the area.
4898 /// </summary>
4900 SRCategory("CategoryAttributeMapArea"),
4901 Bindable(true),
4902 SRDescription("DescriptionAttributeMapAreaAttributes"),
4903 DefaultValue(""),
4904 PersistenceMode(PersistenceMode.Attribute),
4905 Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base)
4907 public string MapAreaAttributes
4911 if(this.pointCustomProperties)
4912 SetAttributeObject(CommonCustomProperties.MapAreaAttributes, value);
4913 else
4914 series.mapAreaAttributes = value;
4918 if(this.pointCustomProperties)
4920 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MapAreaAttributes))
4922 return (String)GetAttributeObject(CommonCustomProperties.MapAreaAttributes);
4924 else
4926 if(IsSerializing())
4928 return "";
4930 if(this.isEmptyPoint)
4932 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MapAreaAttributes);
4935 return series.mapAreaAttributes;
4938 else
4940 return series.mapAreaAttributes;
4945 /// <summary>
4946 /// Gets or sets the postback value which can be processed on click event.
4947 /// </summary>
4948 /// <value>The value which is passed to click event as argument.</value>
4949 [DefaultValue("")]
4950 [SRCategory(SR.Keys.CategoryAttributeMapArea)]
4951 [SRDescription(SR.Keys.DescriptionAttributePostBackValue)]
4952 [Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base)]
4953 public string PostBackValue
4957 if (this.pointCustomProperties)
4959 if (properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.PostBackValue))
4961 return (String)GetAttributeObject(CommonCustomProperties.PostBackValue);
4963 else
4965 if (IsSerializing())
4967 return "";
4969 if (this.isEmptyPoint)
4971 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.PostBackValue);
4974 return series.postbackValue;
4977 else
4979 return series.postbackValue;
4984 if (this.pointCustomProperties)
4985 SetAttributeObject(CommonCustomProperties.PostBackValue, value);
4986 else
4987 series.postbackValue = value;
4994 #endif
4995 /// <summary>
4996 /// Replaces predefined keyword inside the string with their values.
4997 /// </summary>
4998 /// <param name="strOriginal">Original string with keywords.</param>
4999 /// <returns>Modified string.</returns>
5000 internal virtual string ReplaceKeywords(string strOriginal)
5002 return strOriginal;
5005 #endregion
5007 #region Legend properties
5009 /// <summary>
5010 /// Indicates whether the item is shown in the legend.
5011 /// </summary>
5013 SRCategory("CategoryAttributeLegend"),
5015 Bindable(true),
5016 SRDescription("DescriptionAttributeShowInLegend"),
5017 #if !Microsoft_CONTROL
5018 DefaultValue(true),
5019 PersistenceMode(PersistenceMode.Attribute)
5020 #endif
5022 public bool IsVisibleInLegend
5026 if(this.pointCustomProperties)
5028 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.IsVisibleInLegend))
5030 return (bool)GetAttributeObject(CommonCustomProperties.IsVisibleInLegend);
5032 else
5034 if(IsSerializing())
5036 return true;
5038 if(this.isEmptyPoint)
5040 return (bool)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.IsVisibleInLegend);
5043 return series.showInLegend;
5046 else
5048 return series.showInLegend;
5053 if(this.pointCustomProperties)
5054 SetAttributeObject(CommonCustomProperties.IsVisibleInLegend, value);
5055 else
5056 series.showInLegend = value;
5057 this.Invalidate(true);
5061 /// <summary>
5062 /// Text of the item in the legend
5063 /// </summary>
5065 SRCategory("CategoryAttributeLegend"),
5066 Bindable(true),
5067 SRDescription("DescriptionAttributeLegendText"),
5068 Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base),
5069 #if !Microsoft_CONTROL
5070 DefaultValue(""),
5071 PersistenceMode(PersistenceMode.Attribute)
5072 #endif
5074 public string LegendText
5078 if(this.pointCustomProperties)
5079 SetAttributeObject(CommonCustomProperties.LegendText, value);
5080 else
5081 series.legendText = value;
5082 this.Invalidate(true);
5086 if(this.pointCustomProperties)
5088 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendText))
5090 return (String)GetAttributeObject(CommonCustomProperties.LegendText);
5092 else
5094 if(IsSerializing())
5096 return "";
5098 if(this.isEmptyPoint)
5100 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendText);
5103 return series.legendText;
5106 else
5108 return series.legendText;
5113 /// <summary>
5114 /// Tooltip of the item in the legend
5115 /// </summary>
5117 SRCategory("CategoryAttributeLegend"),
5118 Bindable(true),
5119 SRDescription("DescriptionAttributeLegendToolTip"),
5120 Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base),
5121 #if !Microsoft_CONTROL
5122 DefaultValue(""),
5123 PersistenceMode(PersistenceMode.Attribute)
5124 #endif
5126 public string LegendToolTip
5130 if(this.pointCustomProperties)
5131 SetAttributeObject(CommonCustomProperties.LegendToolTip, value);
5132 else
5133 series.legendToolTip = value;
5135 #if Microsoft_CONTROL
5136 if(Chart != null && Chart.selection != null)
5138 Chart.selection.enabledChecked = false;
5140 #endif
5144 if(this.pointCustomProperties)
5146 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendToolTip))
5148 return (String)GetAttributeObject(CommonCustomProperties.LegendToolTip);
5150 else
5152 if(IsSerializing())
5154 return "";
5156 if(this.isEmptyPoint)
5158 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendToolTip);
5161 return series.legendToolTip;
5165 else
5167 return series.legendToolTip;
5174 /// <summary>
5175 /// Background color of the data point label.
5176 /// </summary>
5178 SRCategory("CategoryAttributeLabelAppearance"),
5179 Bindable(true),
5180 SRDescription("DescriptionAttributeLabelBackColor"),
5181 TypeConverter(typeof(ColorConverter)),
5182 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
5183 DefaultValue(typeof(Color), ""),
5184 #if !Microsoft_CONTROL
5185 PersistenceMode(PersistenceMode.Attribute)
5186 #endif
5188 public Color LabelBackColor
5192 if(this.pointCustomProperties)
5194 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelBackColor))
5196 return (Color)GetAttributeObject(CommonCustomProperties.LabelBackColor);
5198 else
5200 if(IsSerializing())
5202 return Color.Empty;
5204 if(this.isEmptyPoint)
5206 return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelBackColor);
5209 return series.labelBackColor;
5212 else
5214 return series.labelBackColor;
5219 if(this.pointCustomProperties)
5220 SetAttributeObject(CommonCustomProperties.LabelBackColor, value);
5221 else
5222 series.labelBackColor = value;
5223 this.Invalidate(true);
5227 /// <summary>
5228 /// Border color of the data point label.
5229 /// </summary>
5231 SRCategory("CategoryAttributeLabelAppearance"),
5232 Bindable(true),
5233 SRDescription("DescriptionAttributeBorderColor"),
5234 TypeConverter(typeof(ColorConverter)),
5235 Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
5236 DefaultValue(typeof(Color), ""),
5237 #if !Microsoft_CONTROL
5238 PersistenceMode(PersistenceMode.Attribute)
5239 #endif
5241 public Color LabelBorderColor
5245 if(this.pointCustomProperties)
5247 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelBorderColor))
5249 return (Color)GetAttributeObject(CommonCustomProperties.LabelBorderColor);
5251 else
5253 if(IsSerializing())
5255 return Color.Empty;
5257 if(this.isEmptyPoint)
5259 return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelBorderColor);
5262 return series.labelBorderColor;
5265 else
5267 return series.labelBorderColor;
5272 if(this.pointCustomProperties)
5273 SetAttributeObject(CommonCustomProperties.LabelBorderColor, value);
5274 else
5275 series.labelBorderColor = value;
5276 this.Invalidate(true);
5280 /// <summary>
5281 /// Border style of the label.
5282 /// </summary>
5284 SRCategory("CategoryAttributeLabelAppearance"),
5285 Bindable(true),
5286 SRDescription("DescriptionAttributeLabelBorderDashStyle"),
5287 #if !Microsoft_CONTROL
5288 DefaultValue(ChartDashStyle.Solid),
5289 PersistenceMode(PersistenceMode.Attribute)
5290 #endif
5292 public ChartDashStyle LabelBorderDashStyle
5296 if(this.pointCustomProperties)
5298 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelBorderDashStyle))
5300 return (ChartDashStyle)GetAttributeObject(CommonCustomProperties.LabelBorderDashStyle);
5302 else
5304 if(IsSerializing())
5306 return ChartDashStyle.Solid;
5308 if(this.isEmptyPoint)
5310 return (ChartDashStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelBorderDashStyle);
5313 return series.labelBorderDashStyle;
5317 else
5319 return series.labelBorderDashStyle;
5324 if(this.pointCustomProperties)
5325 SetAttributeObject(CommonCustomProperties.LabelBorderDashStyle, value);
5326 else
5327 series.labelBorderDashStyle = value;
5328 this.Invalidate(true);
5332 /// <summary>
5333 /// Border width of the label.
5334 /// </summary>
5336 SRCategory("CategoryAttributeLabelAppearance"),
5337 Bindable(true),
5338 SRDescription("DescriptionAttributeBorderWidth"),
5339 #if !Microsoft_CONTROL
5340 DefaultValue(1),
5341 PersistenceMode(PersistenceMode.Attribute)
5342 #endif
5344 public int LabelBorderWidth
5348 if(this.pointCustomProperties)
5350 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelBorderWidth))
5352 return (int)GetAttributeObject(CommonCustomProperties.LabelBorderWidth);
5354 else
5356 if(IsSerializing())
5358 return 1;
5360 if(this.isEmptyPoint)
5362 return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelBorderWidth);
5365 return series.labelBorderWidth;
5369 else
5371 return series.labelBorderWidth;
5376 if(value < 0)
5378 throw(new ArgumentOutOfRangeException("value", SR.ExceptionLabelBorderIsNotPositive));
5380 if(this.pointCustomProperties)
5381 SetAttributeObject(CommonCustomProperties.LabelBorderWidth, value);
5382 else
5383 series.labelBorderWidth = value;
5384 this.Invalidate(true);
5388 /// <summary>
5389 /// Tooltip of the data point label.
5390 /// </summary>
5392 SRCategory("CategoryAttributeLabel"),
5393 Bindable(true),
5394 SRDescription("DescriptionAttributeLabelToolTip"),
5395 Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base),
5396 #if !Microsoft_CONTROL
5397 DefaultValue(""),
5398 PersistenceMode(PersistenceMode.Attribute)
5399 #endif
5401 public string LabelToolTip
5405 if(this.pointCustomProperties)
5406 SetAttributeObject(CommonCustomProperties.LabelToolTip, value);
5407 else
5408 series.labelToolTip = value;
5410 #if Microsoft_CONTROL
5411 if(Chart != null && Chart.selection != null)
5413 Chart.selection.enabledChecked = false;
5415 #endif
5419 if(this.pointCustomProperties)
5421 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelToolTip))
5423 return (String)GetAttributeObject(CommonCustomProperties.LabelToolTip);
5425 else
5427 if(IsSerializing())
5429 return "";
5431 if(this.isEmptyPoint)
5433 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelToolTip);
5436 return series.labelToolTip;
5440 else
5442 return series.labelToolTip;
5448 #if !Microsoft_CONTROL
5450 /// <summary>
5451 /// URL target of the item in the legend.
5452 /// </summary>
5454 SRCategory("CategoryAttributeLegend"),
5455 Bindable(true),
5456 SRDescription("DescriptionAttributeLegendUrl"),
5457 DefaultValue(""),
5458 PersistenceMode(PersistenceMode.Attribute),
5459 Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base),
5460 SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")
5462 public string LegendUrl
5466 if(this.pointCustomProperties)
5467 SetAttributeObject(CommonCustomProperties.LegendUrl, value);
5468 else
5469 series.legendUrl = value;
5473 if(this.pointCustomProperties)
5475 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendUrl))
5477 return (String)GetAttributeObject(CommonCustomProperties.LegendUrl);
5479 else
5481 if(IsSerializing())
5483 return "";
5485 if(this.isEmptyPoint)
5487 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendUrl);
5490 return series.legendUrl;
5493 else
5495 return series.legendUrl;
5500 #endif
5502 #if !Microsoft_CONTROL
5504 /// <summary>
5505 /// Other attributes of the legend map area.
5506 /// </summary>
5508 SRCategory("CategoryAttributeLegend"),
5509 Bindable(true),
5510 SRDescription("DescriptionAttributeMapAreaAttributes"),
5511 DefaultValue(""),
5512 PersistenceMode(PersistenceMode.Attribute),
5513 Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base)
5515 public string LegendMapAreaAttributes
5519 if(this.pointCustomProperties)
5520 SetAttributeObject(CommonCustomProperties.LegendMapAreaAttributes, value);
5521 else
5522 series.legendMapAreaAttributes = value;
5526 if(this.pointCustomProperties)
5528 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendMapAreaAttributes))
5530 return (String)GetAttributeObject(CommonCustomProperties.LegendMapAreaAttributes);
5532 else
5534 if(IsSerializing())
5536 return "";
5538 if(this.isEmptyPoint)
5540 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendMapAreaAttributes);
5543 return series.legendMapAreaAttributes;
5547 else
5549 return series.legendMapAreaAttributes;
5554 /// <summary>
5555 /// Gets or sets the postback value which can be processed on click event.
5556 /// </summary>
5557 /// <value>The value which is passed to click event as argument.</value>
5558 [DefaultValue("")]
5559 [SRCategory("CategoryAttributeLegend")]
5560 [SRDescription(SR.Keys.DescriptionAttributePostBackValue)]
5561 [Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base)]
5562 public string LegendPostBackValue
5566 if (this.pointCustomProperties)
5568 if (properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendPostBackValue))
5570 return (String)GetAttributeObject(CommonCustomProperties.LegendPostBackValue);
5572 else
5574 if (IsSerializing())
5576 return "";
5578 if (this.isEmptyPoint)
5580 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendPostBackValue);
5583 return series.legendPostbackValue;
5586 else
5588 return series.legendPostbackValue;
5593 if (this.pointCustomProperties)
5594 SetAttributeObject(CommonCustomProperties.LegendPostBackValue, value);
5595 else
5596 series.legendPostbackValue = value;
5600 #endif // !Microsoft_CONTROL
5604 #if !Microsoft_CONTROL
5606 /// <summary>
5607 /// URL target of the data point label.
5608 /// </summary>
5610 SRCategory("CategoryAttributeMapArea"),
5611 Bindable(true),
5612 SRDescription("DescriptionAttributeUrl"),
5613 DefaultValue(""),
5614 PersistenceMode(PersistenceMode.Attribute),
5615 Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base),
5616 SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")
5618 public string LabelUrl
5622 if(this.pointCustomProperties)
5623 SetAttributeObject(CommonCustomProperties.LabelUrl, value);
5624 else
5625 series.labelUrl = value;
5629 if(this.pointCustomProperties)
5631 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelUrl))
5633 return (String)GetAttributeObject(CommonCustomProperties.LabelUrl);
5635 else
5637 if(IsSerializing())
5639 return "";
5641 if(this.isEmptyPoint)
5643 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelUrl);
5646 return series.labelUrl;
5649 else
5651 return series.labelUrl;
5656 #endif //if !Microsoft_CONTROL
5658 #if !Microsoft_CONTROL
5660 /// <summary>
5661 /// Other attributes of the data point label.
5662 /// </summary>
5664 SRCategory("CategoryAttributeLabel"),
5665 Bindable(true),
5666 SRDescription("DescriptionAttributeMapAreaAttributes"),
5667 DefaultValue(""),
5668 PersistenceMode(PersistenceMode.Attribute)
5670 public string LabelMapAreaAttributes
5674 if(this.pointCustomProperties)
5675 SetAttributeObject(CommonCustomProperties.LabelMapAreaAttributes, value);
5676 else
5677 series.labelMapAreaAttributes = value;
5681 if(this.pointCustomProperties)
5683 if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelMapAreaAttributes))
5685 return (String)GetAttributeObject(CommonCustomProperties.LabelMapAreaAttributes);
5687 else
5689 if(IsSerializing())
5691 return "";
5693 if(this.isEmptyPoint)
5695 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelMapAreaAttributes);
5698 return series.labelMapAreaAttributes;
5702 else
5704 return series.labelMapAreaAttributes;
5709 /// <summary>
5710 /// Gets or sets the postback value which can be processed on click event.
5711 /// </summary>
5712 /// <value>The value which is passed to click event as argument.</value>
5713 [DefaultValue("")]
5714 [SRCategory("CategoryAttributeLabel")]
5715 [SRDescription(SR.Keys.DescriptionAttributePostBackValue)]
5716 [Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base)]
5717 public string LabelPostBackValue
5721 if (this.pointCustomProperties)
5723 if (properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelPostBackValue))
5725 return (String)GetAttributeObject(CommonCustomProperties.LabelPostBackValue);
5727 else
5729 if (IsSerializing())
5731 return "";
5733 if (this.isEmptyPoint)
5735 return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelPostBackValue);
5738 return series.labelPostbackValue;
5741 else
5743 return series.labelPostbackValue;
5748 if (this.pointCustomProperties)
5749 SetAttributeObject(CommonCustomProperties.LabelPostBackValue, value);
5750 else
5751 series.labelPostbackValue = value;
5756 #endif // !Microsoft_CONTROL
5760 #endregion
5762 #region Serialization control
5766 private bool CheckIfSerializationRequired(CommonCustomProperties attribute)
5768 if(this is DataPoint)
5770 return IsCustomPropertySet(attribute);
5772 else
5774 object attr1 = this.GetAttributeObject(attribute);
5775 object attr2 = Series.defaultCustomProperties.GetAttributeObject(attribute);
5776 if(attr1 == null || attr2 == null)
5778 return false;
5780 return ! attr1.Equals(attr2);
5784 private void ResetProperty(CommonCustomProperties attribute)
5786 if(this is DataPoint)
5788 DeleteCustomProperty(attribute);
5790 else
5792 this.SetAttributeObject(attribute, Series.defaultCustomProperties.GetAttributeObject(attribute));
5796 /// <summary>
5797 /// Returns true if property should be serialized.
5798 /// </summary>
5800 internal bool ShouldSerializeLabel()
5802 if(this.pointCustomProperties)
5803 return CheckIfSerializationRequired(CommonCustomProperties.Label);
5804 else
5805 return !String.IsNullOrEmpty(series.label);
5808 /// <summary>
5809 /// Returns true if property should be serialized.
5810 /// </summary>
5812 internal bool ShouldSerializeAxisLabel()
5814 if(this.pointCustomProperties)
5815 return CheckIfSerializationRequired(CommonCustomProperties.AxisLabel);
5816 else
5817 return !String.IsNullOrEmpty(series.axisLabel);
5820 /// <summary>
5821 /// Returns true if property should be serialized.
5822 /// </summary>
5824 internal bool ShouldSerializeLabelFormat()
5826 if(this.pointCustomProperties)
5827 return CheckIfSerializationRequired(CommonCustomProperties.LabelFormat);
5828 else
5829 return !String.IsNullOrEmpty(series.labelFormat);
5832 /// <summary>
5833 /// Returns true if property should be serialized.
5834 /// </summary>
5836 internal bool ShouldSerializeIsValueShownAsLabel()
5838 if(this.pointCustomProperties)
5839 return CheckIfSerializationRequired(CommonCustomProperties.IsValueShownAsLabel);
5840 else
5841 return series.showLabelAsValue != false;
5844 /// <summary>
5845 /// Returns true if property should be serialized.
5846 /// </summary>
5848 internal bool ShouldSerializeColor()
5850 if(this.pointCustomProperties)
5851 return CheckIfSerializationRequired(CommonCustomProperties.Color);
5852 else
5853 return series.color != Color.Empty;
5856 /// <summary>
5857 /// Returns true if property should be serialized.
5858 /// </summary>
5860 internal bool ShouldSerializeBorderColor()
5862 if(this.pointCustomProperties)
5863 return CheckIfSerializationRequired(CommonCustomProperties.BorderColor);
5864 else
5865 return series.borderColor != Color.Empty;
5868 /// <summary>
5869 /// Returns true if property should be serialized.
5870 /// </summary>
5872 internal bool ShouldSerializeBorderDashStyle()
5874 if(this.pointCustomProperties)
5875 return CheckIfSerializationRequired(CommonCustomProperties.BorderDashStyle);
5876 else
5877 return series.borderDashStyle != ChartDashStyle.Solid;
5880 /// <summary>
5881 /// Returns true if property should be serialized.
5882 /// </summary>
5884 internal bool ShouldSerializeBorderWidth()
5886 if(this.pointCustomProperties)
5887 return CheckIfSerializationRequired(CommonCustomProperties.BorderWidth);
5888 else
5889 return series.borderWidth != 1;
5892 /// <summary>
5893 /// Returns true if property should be serialized.
5894 /// </summary>
5896 internal bool ShouldSerializeMarkerBorderWidth()
5898 if(this.pointCustomProperties)
5899 return CheckIfSerializationRequired(CommonCustomProperties.MarkerBorderWidth);
5900 else
5901 return series.markerBorderWidth != 1;
5904 /// <summary>
5905 /// Returns true if property should be serialized.
5906 /// </summary>
5908 internal bool ShouldSerializeBackImage()
5910 if(this.pointCustomProperties)
5911 return CheckIfSerializationRequired(CommonCustomProperties.BackImage);
5912 else
5913 return !String.IsNullOrEmpty(series.backImage);
5916 /// <summary>
5917 /// Returns true if property should be serialized.
5918 /// </summary>
5920 internal bool ShouldSerializeBackImageWrapMode()
5922 if(this.pointCustomProperties)
5923 return CheckIfSerializationRequired(CommonCustomProperties.BackImageWrapMode);
5924 else
5925 return series.backImageWrapMode != ChartImageWrapMode.Tile;
5928 /// <summary>
5929 /// Returns true if property should be serialized.
5930 /// </summary>
5932 internal bool ShouldSerializeBackImageTransparentColor()
5934 if(this.pointCustomProperties)
5935 return CheckIfSerializationRequired(CommonCustomProperties.BackImageTransparentColor);
5936 else
5937 return series.backImageTransparentColor != Color.Empty;
5940 /// <summary>
5941 /// Returns true if property should be serialized.
5942 /// </summary>
5944 internal bool ShouldSerializeBackImageAlignment()
5946 if(this.pointCustomProperties)
5947 return CheckIfSerializationRequired(CommonCustomProperties.BackImageAlignment);
5948 else
5949 return series.backImageAlignment != ChartImageAlignmentStyle.TopLeft;
5952 /// <summary>
5953 /// Returns true if property should be serialized.
5954 /// </summary>
5956 internal bool ShouldSerializeBackGradientStyle()
5958 if(this.pointCustomProperties)
5959 return CheckIfSerializationRequired(CommonCustomProperties.BackGradientStyle);
5960 else
5961 return series.backGradientStyle != GradientStyle.None;
5964 /// <summary>
5965 /// Returns true if property should be serialized.
5966 /// </summary>
5968 internal bool ShouldSerializeBackSecondaryColor()
5970 if(this.pointCustomProperties)
5971 return CheckIfSerializationRequired(CommonCustomProperties.BackSecondaryColor);
5972 else
5973 return series.backSecondaryColor != Color.Empty;
5976 /// <summary>
5977 /// Returns true if property should be serialized.
5978 /// </summary>
5980 internal bool ShouldSerializeBackHatchStyle()
5982 if(this.pointCustomProperties)
5983 return CheckIfSerializationRequired(CommonCustomProperties.BackHatchStyle);
5984 else
5985 return series.backHatchStyle != ChartHatchStyle.None;
5988 /// <summary>
5989 /// Returns true if property should be serialized.
5990 /// </summary>
5992 internal bool ShouldSerializeFont()
5994 if(this.pointCustomProperties)
5995 return CheckIfSerializationRequired(CommonCustomProperties.Font);
5996 else
5998 return series.font != series.FontCache.DefaultFont;
6002 /// <summary>
6003 /// Returns true if property should be serialized.
6004 /// </summary>
6005 internal bool ShouldSerializeLabelForeColor()
6007 if(this.pointCustomProperties)
6008 return CheckIfSerializationRequired(CommonCustomProperties.LabelForeColor);
6009 else
6010 return series.fontColor != Color.Black;
6013 /// <summary>
6014 /// Returns true if property should be serialized.
6015 /// </summary>
6017 internal bool ShouldSerializeLabelAngle()
6019 if(this.pointCustomProperties)
6020 return CheckIfSerializationRequired(CommonCustomProperties.LabelAngle);
6021 else
6022 return series.fontAngle != 0f;
6025 /// <summary>
6026 /// Returns true if property should be serialized.
6027 /// </summary>
6029 internal bool ShouldSerializeMarkerStyle()
6031 if(this.pointCustomProperties)
6032 return CheckIfSerializationRequired(CommonCustomProperties.MarkerStyle);
6033 else
6034 return series.markerStyle != MarkerStyle.None;
6037 /// <summary>
6038 /// Returns true if property should be serialized.
6039 /// </summary>
6041 internal bool ShouldSerializeMarkerSize()
6043 if(this.pointCustomProperties)
6044 return CheckIfSerializationRequired(CommonCustomProperties.MarkerSize);
6045 else
6046 return series.markerSize != 5;
6049 /// <summary>
6050 /// Returns true if property should be serialized.
6051 /// </summary>
6053 internal bool ShouldSerializeMarkerImage()
6055 if(this.pointCustomProperties)
6056 return CheckIfSerializationRequired(CommonCustomProperties.MarkerImage);
6057 else
6058 return !String.IsNullOrEmpty(series.markerImage);
6061 /// <summary>
6062 /// Returns true if property should be serialized.
6063 /// </summary>
6065 internal bool ShouldSerializeMarkerImageTransparentColor()
6067 if(this.pointCustomProperties)
6068 return CheckIfSerializationRequired(CommonCustomProperties.MarkerImageTransparentColor);
6069 else
6070 return series.markerImageTransparentColor != Color.Empty;
6073 /// <summary>
6074 /// Returns true if property should be serialized.
6075 /// </summary>
6077 internal bool ShouldSerializeMarkerColor()
6079 if(this.pointCustomProperties)
6080 return CheckIfSerializationRequired(CommonCustomProperties.MarkerColor);
6081 else
6082 return series.markerColor != Color.Empty;
6085 /// <summary>
6086 /// Returns true if property should be serialized.
6087 /// </summary>
6089 internal bool ShouldSerializeMarkerBorderColor()
6091 if(this.pointCustomProperties)
6092 return CheckIfSerializationRequired(CommonCustomProperties.MarkerBorderColor);
6093 else
6094 return series.markerBorderColor != Color.Empty;
6097 /// <summary>
6098 /// Returns true if property should be serialized.
6099 /// </summary>
6101 internal bool ShouldSerializeToolTip()
6103 if(this.pointCustomProperties)
6104 return CheckIfSerializationRequired(CommonCustomProperties.ToolTip);
6105 else
6106 return !String.IsNullOrEmpty(series.toolTip);
6109 #if !Microsoft_CONTROL
6111 /// <summary>
6112 /// Returns true if property should be serialized.
6113 /// </summary>
6115 internal bool ShouldSerializeUrl()
6117 if(this.pointCustomProperties)
6118 return CheckIfSerializationRequired(CommonCustomProperties.Url);
6119 else
6120 return !String.IsNullOrEmpty(series.url);
6123 /// <summary>
6124 /// Returns true if property should be serialized.
6125 /// </summary>
6127 internal bool ShouldSerializeMapAreaAttributes()
6129 if(this.pointCustomProperties)
6130 return CheckIfSerializationRequired(CommonCustomProperties.MapAreaAttributes);
6131 else
6132 return !String.IsNullOrEmpty(series.mapAreaAttributes);
6135 /// <summary>
6136 /// Returns true if property should be serialized.
6137 /// </summary>
6138 internal bool ShouldSerializePostBackValue()
6140 if (this.pointCustomProperties)
6141 return CheckIfSerializationRequired(CommonCustomProperties.PostBackValue);
6142 else
6143 return !String.IsNullOrEmpty(series.postbackValue);
6146 /// <summary>
6147 /// Returns true if property should be serialized.
6148 /// </summary>
6150 internal bool ShouldSerializeLegendUrl()
6152 if(this.pointCustomProperties)
6153 return CheckIfSerializationRequired(CommonCustomProperties.LegendUrl);
6154 else
6155 return !String.IsNullOrEmpty(series.legendUrl);
6158 /// <summary>
6159 /// Returns true if property should be serialized.
6160 /// </summary>
6162 internal bool ShouldSerializeLegendMapAreaAttributes()
6164 if(this.pointCustomProperties)
6165 return CheckIfSerializationRequired(CommonCustomProperties.LegendMapAreaAttributes);
6166 else
6167 return !String.IsNullOrEmpty(series.legendMapAreaAttributes);
6172 /// <summary>
6173 /// Returns true if property should be serialized.
6174 /// </summary>
6176 internal bool ShouldSerializeLabelUrl()
6178 if(this.pointCustomProperties)
6179 return CheckIfSerializationRequired(CommonCustomProperties.LabelUrl);
6180 else
6181 return !String.IsNullOrEmpty(series.labelUrl);
6184 /// <summary>
6185 /// Returns true if property should be serialized.
6186 /// </summary>
6188 internal bool ShouldSerializeLabelMapAreaAttributes()
6190 if(this.pointCustomProperties)
6191 return CheckIfSerializationRequired(CommonCustomProperties.LabelMapAreaAttributes);
6192 else
6193 return !String.IsNullOrEmpty(series.labelMapAreaAttributes);
6198 #endif // !Microsoft_CONTROL
6200 /// <summary>
6201 /// Returns true if property should be serialized.
6202 /// </summary>
6204 internal bool ShouldSerializeIsVisibleInLegend()
6206 if(this.pointCustomProperties)
6207 return CheckIfSerializationRequired(CommonCustomProperties.IsVisibleInLegend);
6208 else
6209 return series.showInLegend != true;
6212 /// <summary>
6213 /// Returns true if property should be serialized.
6214 /// </summary>
6216 internal bool ShouldSerializeLegendText()
6218 if(this.pointCustomProperties)
6219 return CheckIfSerializationRequired(CommonCustomProperties.LegendText);
6220 else
6221 return !String.IsNullOrEmpty(series.legendText);
6224 /// <summary>
6225 /// Returns true if property should be serialized.
6226 /// </summary>
6228 internal bool ShouldSerializeLegendToolTip()
6230 if(this.pointCustomProperties)
6231 return CheckIfSerializationRequired(CommonCustomProperties.LegendToolTip);
6232 else
6233 return !String.IsNullOrEmpty(series.legendToolTip);
6238 /// <summary>
6239 /// Returns true if property should be serialized.
6240 /// </summary>
6242 internal bool ShouldSerializeLabelToolTip()
6244 if(this.pointCustomProperties)
6245 return CheckIfSerializationRequired(CommonCustomProperties.LabelToolTip);
6246 else
6247 return !String.IsNullOrEmpty(series.labelToolTip);
6250 /// <summary>
6251 /// Returns true if property should be serialized.
6252 /// </summary>
6254 internal bool ShouldSerializeLabelBackColor()
6256 if(this.pointCustomProperties)
6257 return CheckIfSerializationRequired(CommonCustomProperties.LabelBackColor);
6258 else
6259 return series.labelBackColor != Color.Empty;
6262 /// <summary>
6263 /// Returns true if property should be serialized.
6264 /// </summary>
6266 internal bool ShouldSerializeLabelBorderColor()
6268 if(this.pointCustomProperties)
6269 return CheckIfSerializationRequired(CommonCustomProperties.LabelBorderColor);
6270 else
6271 return series.labelBorderColor != Color.Empty;
6274 /// <summary>
6275 /// Returns true if property should be serialized.
6276 /// </summary>
6278 internal bool ShouldSerializeLabelBorderDashStyle()
6280 if(this.pointCustomProperties)
6281 return CheckIfSerializationRequired(CommonCustomProperties.LabelBorderDashStyle);
6282 else
6283 return series.labelBorderDashStyle != ChartDashStyle.Solid;
6286 /// <summary>
6287 /// Returns true if property should be serialized.
6288 /// </summary>
6290 internal bool ShouldSerializeLabelBorderWidth()
6292 if(this.pointCustomProperties)
6293 return CheckIfSerializationRequired(CommonCustomProperties.LabelBorderWidth);
6294 else
6295 return series.labelBorderWidth != 1;
6299 /// <summary>
6300 /// Resets property to its default value.
6301 /// </summary>
6303 internal void ResetLabel()
6305 if(this.pointCustomProperties)
6306 ResetProperty(CommonCustomProperties.Label);
6307 else
6308 series.label = "";
6311 /// <summary>
6312 /// Resets property to its default value.
6313 /// </summary>
6315 internal void ResetAxisLabel()
6317 if(this.pointCustomProperties)
6318 ResetProperty(CommonCustomProperties.AxisLabel);
6319 else
6320 series.axisLabel = "";
6323 /// <summary>
6324 /// Resets property to its default value.
6325 /// </summary>
6327 internal void ResetLabelFormat()
6329 if(this.pointCustomProperties)
6330 ResetProperty(CommonCustomProperties.LabelFormat);
6331 else
6332 series.labelFormat = "";
6335 /// <summary>
6336 /// Resets property to its default value.
6337 /// </summary>
6339 public void ResetIsValueShownAsLabel()
6341 if(this.pointCustomProperties)
6342 ResetProperty(CommonCustomProperties.IsValueShownAsLabel);
6343 else
6344 series.IsValueShownAsLabel = false;
6347 /// <summary>
6348 /// Resets property to its default value.
6349 /// </summary>
6351 internal void ResetColor()
6353 if(this.pointCustomProperties)
6354 ResetProperty(CommonCustomProperties.Color);
6355 else
6356 series.color = Color.Empty;
6359 /// <summary>
6360 /// Resets property to its default value.
6361 /// </summary>
6363 internal void ResetBorderColor()
6365 if(this.pointCustomProperties)
6366 ResetProperty(CommonCustomProperties.BorderColor);
6367 else
6368 series.borderColor = Color.Empty;
6371 /// <summary>
6372 /// Resets property to its default value.
6373 /// </summary>
6375 internal void ResetBorderDashStyle()
6377 if(this.pointCustomProperties)
6378 ResetProperty(CommonCustomProperties.BorderDashStyle);
6379 else
6380 series.borderDashStyle = ChartDashStyle.Solid;
6383 /// <summary>
6384 /// Resets property to its default value.
6385 /// </summary>
6387 internal void ResetBorderWidth()
6389 if(this.pointCustomProperties)
6390 ResetProperty(CommonCustomProperties.BorderWidth);
6391 else
6392 series.borderWidth = 1;
6397 /// <summary>
6398 /// Resets property to its default value.
6399 /// </summary>
6401 internal void ResetMarkerBorderWidth()
6403 if(this.pointCustomProperties)
6404 ResetProperty(CommonCustomProperties.MarkerBorderWidth);
6405 else
6406 series.markerBorderWidth = 1;
6411 /// <summary>
6412 /// Resets property to its default value.
6413 /// </summary>
6415 internal void ResetBackImage()
6417 if(this.pointCustomProperties)
6418 ResetProperty(CommonCustomProperties.BackImage);
6419 else
6420 series.backImage = "";
6423 /// <summary>
6424 /// Resets property to its default value.
6425 /// </summary>
6427 internal void ResetBackImageWrapMode()
6429 if(this.pointCustomProperties)
6430 ResetProperty(CommonCustomProperties.BackImageWrapMode);
6431 else
6432 series.backImageWrapMode = ChartImageWrapMode.Tile;
6435 /// <summary>
6436 /// Resets property to its default value.
6437 /// </summary>
6439 internal void ResetBackImageTransparentColor()
6441 if(this.pointCustomProperties)
6442 ResetProperty(CommonCustomProperties.BackImageTransparentColor);
6443 else
6444 series.backImageTransparentColor = Color.Empty;
6447 /// <summary>
6448 /// Resets property to its default value.
6449 /// </summary>
6451 internal void ResetBackSecondaryColor()
6453 if(this.pointCustomProperties)
6454 ResetProperty(CommonCustomProperties.BackSecondaryColor);
6455 else
6456 series.backSecondaryColor = Color.Empty;
6459 /// <summary>
6460 /// Resets property to its default value.
6461 /// </summary>
6463 internal void ResetBackHatchStyle()
6465 if(this.pointCustomProperties)
6466 ResetProperty(CommonCustomProperties.BackHatchStyle);
6467 else
6468 series.backHatchStyle = ChartHatchStyle.None;
6471 /// <summary>
6472 /// Resets property to its default value.
6473 /// </summary>
6475 internal void ResetFont()
6477 if (this.pointCustomProperties)
6478 ResetProperty(CommonCustomProperties.Font);
6479 else
6481 series.font = series.FontCache.DefaultFont;
6486 /// <summary>
6487 /// Resets property to its default value.
6488 /// </summary>
6490 internal void ResetLabelAngle()
6492 if(this.pointCustomProperties)
6493 ResetProperty(CommonCustomProperties.LabelAngle);
6494 else
6495 series.fontAngle = 0;
6498 /// <summary>
6499 /// Resets property to its default value.
6500 /// </summary>
6502 internal void ResetMarkerStyle()
6504 if(this.pointCustomProperties)
6505 ResetProperty(CommonCustomProperties.MarkerStyle);
6506 else
6507 series.markerStyle = MarkerStyle.None;
6510 /// <summary>
6511 /// Resets property to its default value.
6512 /// </summary>
6514 internal void ResetMarkerSize()
6516 if(this.pointCustomProperties)
6517 ResetProperty(CommonCustomProperties.MarkerSize);
6518 else
6519 series.markerSize = 5;
6522 /// <summary>
6523 /// Resets property to its default value.
6524 /// </summary>
6526 internal void ResetMarkerImage()
6528 if(this.pointCustomProperties)
6529 ResetProperty(CommonCustomProperties.MarkerImage);
6530 else
6531 series.markerImage = "";
6534 /// <summary>
6535 /// Resets property to its default value.
6536 /// </summary>
6538 internal void ResetMarkerImageTransparentColor()
6540 if(this.pointCustomProperties)
6541 ResetProperty(CommonCustomProperties.MarkerImageTransparentColor);
6542 else
6543 series.markerImageTransparentColor = Color.Empty;
6546 /// <summary>
6547 /// Resets property to its default value.
6548 /// </summary>
6550 internal void ResetMarkerColor()
6552 if(this.pointCustomProperties)
6553 ResetProperty(CommonCustomProperties.MarkerColor);
6554 else
6555 series.markerColor = Color.Empty;
6558 /// <summary>
6559 /// Resets property to its default value.
6560 /// </summary>
6562 internal void ResetMarkerBorderColor()
6564 if(this.pointCustomProperties)
6565 ResetProperty(CommonCustomProperties.MarkerBorderColor);
6566 else
6567 series.markerBorderColor = Color.Empty;
6570 /// <summary>
6571 /// Resets property to its default value.
6572 /// </summary>
6574 internal void ResetToolTip()
6576 if(this.pointCustomProperties)
6577 ResetProperty(CommonCustomProperties.ToolTip);
6578 else
6579 series.toolTip = "";
6581 #if Microsoft_CONTROL
6582 if(Chart != null && Chart.selection != null)
6584 Chart.selection.enabledChecked = false;
6586 #endif
6589 #if !Microsoft_CONTROL
6591 /// <summary>
6592 /// Resets property to its default value.
6593 /// </summary>
6595 internal void ResetUrl()
6597 if(this.pointCustomProperties)
6598 ResetProperty(CommonCustomProperties.Url);
6599 else
6600 series.url = "";
6603 /// <summary>
6604 /// Resets property to its default value.
6605 /// </summary>
6607 internal void ResetMapAreaAttributes()
6609 if(this.pointCustomProperties)
6610 ResetProperty(CommonCustomProperties.MapAreaAttributes);
6611 else
6612 series.mapAreaAttributes = "";
6615 /// <summary>
6616 /// Resets property to its default value.
6617 /// </summary>
6618 internal void ResetPostBackValue()
6620 if (this.pointCustomProperties)
6621 ResetProperty(CommonCustomProperties.PostBackValue);
6622 else
6623 series.postbackValue = "";
6626 /// <summary>
6627 /// Resets property to its default value.
6628 /// </summary>
6630 internal void ResetLegendUrl()
6632 if(this.pointCustomProperties)
6633 ResetProperty(CommonCustomProperties.LegendUrl);
6634 else
6635 series.legendUrl = "";
6638 /// <summary>
6639 /// Resets property to its default value.
6640 /// </summary>
6642 internal void ResetLegendMapAreaAttributes()
6644 if(this.pointCustomProperties)
6645 ResetProperty(CommonCustomProperties.LegendMapAreaAttributes);
6646 else
6647 series.legendMapAreaAttributes = "";
6652 /// <summary>
6653 /// Resets property to its default value.
6654 /// </summary>
6656 internal void ResetLabelUrl()
6658 if(this.pointCustomProperties)
6659 ResetProperty(CommonCustomProperties.LabelUrl);
6660 else
6661 series.labelUrl = "";
6664 /// <summary>
6665 /// Resets property to its default value.
6666 /// </summary>
6668 internal void ResetLabelMapAreaAttributes()
6670 if(this.pointCustomProperties)
6671 ResetProperty(CommonCustomProperties.LabelMapAreaAttributes);
6672 else
6673 series.labelMapAreaAttributes = "";
6677 #endif // !Microsoft_CONTROL
6679 /// <summary>
6680 /// Resets property to its default value.
6681 /// </summary>
6683 public void ResetIsVisibleInLegend()
6685 if(this.pointCustomProperties)
6686 ResetProperty(CommonCustomProperties.IsVisibleInLegend);
6687 else
6688 series.showInLegend = true;
6691 /// <summary>
6692 /// Resets property to its default value.
6693 /// </summary>
6695 internal void ResetLegendText()
6697 if(this.pointCustomProperties)
6698 ResetProperty(CommonCustomProperties.LegendText);
6699 else
6700 series.legendText = "";
6703 /// <summary>
6704 /// Resets property to its default value.
6705 /// </summary>
6707 internal void ResetLegendToolTip()
6709 if(this.pointCustomProperties)
6710 ResetProperty(CommonCustomProperties.LegendToolTip);
6711 else
6712 series.legendToolTip = "";
6714 #if Microsoft_CONTROL
6715 if(Chart != null && Chart.selection != null)
6717 Chart.selection.enabledChecked = false;
6719 #endif
6724 /// <summary>
6725 /// Resets property to its default value.
6726 /// </summary>
6728 internal void ResetLabelBackColor()
6730 if(this.pointCustomProperties)
6731 ResetProperty(CommonCustomProperties.LabelBackColor);
6732 else
6733 series.labelBackColor = Color.Empty;
6736 /// <summary>
6737 /// Resets property to its default value.
6738 /// </summary>
6740 internal void ResetLabelBorderColor()
6742 if(this.pointCustomProperties)
6743 ResetProperty(CommonCustomProperties.LabelBorderColor);
6744 else
6745 series.labelBorderColor = Color.Empty;
6748 /// <summary>
6749 /// Resets property to its default value.
6750 /// </summary>
6752 internal void ResetLabelBorderDashStyle()
6754 if(this.pointCustomProperties)
6755 ResetProperty(CommonCustomProperties.LabelBorderDashStyle);
6756 else
6757 series.labelBorderDashStyle = ChartDashStyle.Solid;
6760 /// <summary>
6761 /// Resets property to its default value.
6762 /// </summary>
6764 internal void ResetLabelBorderWidth()
6766 if(this.pointCustomProperties)
6767 ResetProperty(CommonCustomProperties.LabelBorderWidth);
6768 else
6769 series.labelBorderWidth = 1;
6772 /// <summary>
6773 /// Resets property to its default value.
6774 /// </summary>
6776 internal void ResetLabelToolTip()
6778 if(this.pointCustomProperties)
6779 ResetProperty(CommonCustomProperties.LabelToolTip);
6780 else
6781 series.labelToolTip = "";
6783 #if Microsoft_CONTROL
6784 if(Chart != null && Chart.selection != null)
6786 Chart.selection.enabledChecked = false;
6788 #endif
6793 #endregion
6795 #region Invalidating method
6797 /// <summary>
6798 /// Invalidate chart area.
6799 /// </summary>
6800 /// <param name="invalidateLegend">Invalidate legend area only.</param>
6801 [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "This parameter is used when compiling for the Microsoft version of Chart")]
6802 internal void Invalidate(bool invalidateLegend)
6804 #if Microsoft_CONTROL
6805 if(this.series != null)
6807 series.Invalidate(true, invalidateLegend);
6809 else
6811 Series thisSeries = this as Series;
6812 if (thisSeries != null)
6814 thisSeries.Invalidate(true, invalidateLegend);
6817 #endif
6820 #endregion
6823 /// <summary>
6824 /// Class stores additional information about the data point in 3D space.
6825 /// </summary>
6826 internal class DataPoint3D
6828 #region Fields
6830 /// <summary>
6831 /// Reference to the 2D data point object
6832 /// </summary>
6833 internal DataPoint dataPoint = null;
6835 /// <summary>
6836 /// Data point index.
6837 /// </summary>
6838 internal int index = 0;
6840 /// <summary>
6841 /// Point X position in relative coordinates.
6842 /// </summary>
6843 internal double xPosition = 0.0;
6845 /// <summary>
6846 /// Point Y position in relative coordinates.
6847 /// </summary>
6848 internal double yPosition = 0.0;
6850 /// <summary>
6851 /// Point X center position in relative coordinates. Used for side-by-side charts.
6852 /// </summary>
6853 internal double xCenterVal = 0.0;
6855 /// <summary>
6856 /// Point Z position in relative coordinates.
6857 /// </summary>
6858 internal float zPosition = 0f;
6860 /// <summary>
6861 /// Point width.
6862 /// </summary>
6863 internal double width = 0.0;
6865 /// <summary>
6866 /// Point height.
6867 /// </summary>
6868 internal double height = 0.0;
6870 /// <summary>
6871 /// Point depth.
6872 /// </summary>
6873 internal float depth = 0f;
6875 /// <summary>
6876 /// Indicates that point belongs to indexed series.
6877 /// </summary>
6878 internal bool indexedSeries = false;
6880 #endregion
6883 /// <summary>
6884 /// Design-time representation of the CustomProperties.
6885 /// This class is used instead of the string "CustomProperties"
6886 /// property at design time and supports expandable list
6887 /// of custom properties.
6888 /// </summary>
6889 [ TypeConverter(typeof(CustomPropertiesTypeConverter)) ]
6890 [EditorBrowsable(EditorBrowsableState.Never)]
6891 #if ASPPERM_35
6892 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
6893 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
6894 #endif
6895 public class CustomProperties
6897 #region Fields
6899 // Reference to the properties class
6900 internal DataPointCustomProperties m_DataPointCustomProperties = null;
6902 #endregion // Fields
6904 #region Constructor
6906 /// <summary>
6907 /// Constructor
6908 /// </summary>
6909 /// <param name="properties">Attributes object.</param>
6910 internal CustomProperties(DataPointCustomProperties properties)
6912 this.m_DataPointCustomProperties = properties;
6915 #endregion // Constructor
6917 #region Properties
6919 internal virtual DataPointCustomProperties DataPointCustomProperties
6923 return this.m_DataPointCustomProperties;
6927 this.m_DataPointCustomProperties = value;
6932 #endregion //Properties
6934 #region Methods
6936 /// <summary>
6937 /// Gets a comma separated string of user defined custom properties.
6938 /// </summary>
6939 /// <returns>Comma separated string of user defined custom properties.</returns>
6940 internal virtual string GetUserDefinedCustomProperties()
6942 return GetUserDefinedCustomProperties(true);
6945 /// <summary>
6946 /// Gets a comma separated string of user defined or non-user defined custom properties.
6947 /// </summary>
6948 /// <param name="userDefined">True if user defined properties must be returned.</param>
6949 /// <returns>Comma separated string of user defined custom properties.</returns>
6950 internal virtual string GetUserDefinedCustomProperties(bool userDefined)
6952 // Get comma separated string of custom properties
6953 string customAttribute = this.DataPointCustomProperties.CustomProperties;
6954 string userDefinedCustomAttribute = string.Empty;
6956 // Get custom attribute registry
6957 CustomPropertyRegistry registry = (CustomPropertyRegistry)this.DataPointCustomProperties.Common.container.GetService(typeof(CustomPropertyRegistry));
6959 // Replace commas in value string
6960 customAttribute = customAttribute.Replace("\\,", "\\x45");
6961 customAttribute = customAttribute.Replace("\\=", "\\x46");
6963 // Split custom properties by commas into individual properties
6964 if(customAttribute.Length > 0)
6966 string[] nameValueStrings = customAttribute.Split(',');
6967 foreach(string nameValue in nameValueStrings)
6969 string[] values = nameValue.Split('=');
6971 // Check format
6972 if(values.Length != 2)
6974 throw(new FormatException(SR.ExceptionAttributeInvalidFormat));
6977 // Check for empty name or value
6978 values[0] = values[0].Trim();
6979 values[1] = values[1].Trim();
6980 if(values[0].Length == 0)
6982 throw(new FormatException(SR.ExceptionAttributeInvalidFormat));
6985 // Check if attribute is registered or user defined
6986 bool userDefinedAttribute = true;
6987 foreach(CustomPropertyInfo info in registry.registeredCustomProperties)
6989 if(string.Compare(info.Name, values[0], StringComparison.OrdinalIgnoreCase) == 0)
6991 userDefinedAttribute = false;
6995 // Copy attribute into the output string
6996 if(userDefinedAttribute == userDefined)
6998 if(userDefinedCustomAttribute.Length > 0)
7000 userDefinedCustomAttribute += ", ";
7003 string val = values[1].Replace("\\x45", ",");
7004 val = val.Replace("\\x46", "=");
7005 userDefinedCustomAttribute += values[0] + "=" + val;
7010 return userDefinedCustomAttribute;
7013 /// <summary>
7014 /// Sets user defined custom properties without cleaning registered properties.
7015 /// </summary>
7016 /// <param name="val">New user defined properties.</param>
7017 internal virtual void SetUserDefinedAttributes(string val)
7019 // Get non-user defined custom properties
7020 string properties = GetUserDefinedCustomProperties(false);
7022 // Check if new string is empty
7023 if(val.Length > 0)
7025 // Add comma at the end
7026 if(properties.Length > 0)
7028 properties += ", ";
7031 // Add new user defined properties
7032 properties += val;
7035 // Set new custom attribute string
7036 this.DataPointCustomProperties.CustomProperties = properties;
7040 #endregion // Methods