|
//-------------------------------------------------------------
// <copyright company=’Microsoft Corporation’>
// Copyright © Microsoft Corporation. All Rights Reserved.
// </copyright>
//-------------------------------------------------------------
// @owner=alexgor, deliant
//=================================================================
// File: DataPoint.cs
//
// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Data
//
// Classes: DataPoint, DataPointCustomProperties, DataPointCollection,
// DataPointComparer, DataPoint3D, CustomProperties
//
// Purpose: Classes related to the Data Points:
// DataPointCollection - data points collection class
// DataPoint - data point properties and methods
// DataPointCustomProperties - data point & series properties
// DataPointComparer - used for sorting data points in series
//
// Reviewed: AG - Aug 1, 2002, GS - Aug 7, 2002
//
//===================================================================
#region Used namespaces
using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
#if Microsoft_CONTROL
using System.Windows.Forms.DataVisualization.Charting;
using System.Windows.Forms.DataVisualization.Charting.Data;
using System.Windows.Forms.DataVisualization.Charting.ChartTypes;
using System.Windows.Forms.DataVisualization.Charting.Utilities;
using System.Windows.Forms.DataVisualization.Charting.Borders3D;
using System.ComponentModel.Design.Serialization;
using System.Reflection;
using System.CodeDom;
using System.Windows.Forms.Design;
#else
using System.Web;
using System.Web.UI;
using System.Web.UI.DataVisualization.Charting;
using System.Web.UI.DataVisualization.Charting.Utilities;
using System.IO;
#endif
#endregion
#if Microsoft_CONTROL
namespace System.Windows.Forms.DataVisualization.Charting
#else
namespace System.Web.UI.DataVisualization.Charting
#endif
{
#region CustomProperties enumeration
/// <summary>
/// Enumeration of common properties names.
/// </summary>
internal enum CommonCustomProperties
{
PointName,
Label,
AxisLabel,
LabelFormat,
IsValueShownAsLabel,
Color,
BorderColor,
BorderDashStyle,
BorderWidth,
BackImage,
BackImageWrapMode,
BackImageAlignment,
BackImageTransparentColor,
BackGradientStyle,
BackSecondaryColor,
BackHatchStyle,
Font,
LabelForeColor,
LabelAngle,
MarkerStyle,
MarkerSize,
MarkerImage,
MarkerImageTransparentColor,
MarkerColor,
MarkerBorderColor,
MarkerBorderWidth,
MapAreaAttributes,
PostBackValue,
MapAreaType,
LegendMapAreaType,
LabelMapAreaType,
Url,
ToolTip,
Tag,
LegendUrl,
LegendToolTip,
LegendText,
LegendMapAreaAttributes,
LegendPostBackValue,
IsVisibleInLegend,
LabelUrl,
LabelToolTip,
LabelMapAreaAttributes,
LabelPostBackValue,
LabelBorderColor,
LabelBorderDashStyle,
LabelBorderWidth,
LabelBackColor,
};
#endregion
/// <summary>
/// Data points comparer class
/// </summary>
[
SRDescription("DescriptionAttributeDataPointComparer_DataPointComparer")
]
public class DataPointComparer : IComparer<DataPoint>
{
#region Fields
// Sorting order
private PointSortOrder _sortingOrder = PointSortOrder.Ascending;
// Sorting value index
private int _sortingValueIndex = 1;
#endregion
#region Constructors
/// <summary>
/// Private default constructor.
/// </summary>
private DataPointComparer()
{
}
/// <summary>
/// Data points comparer class constructor.
/// </summary>
/// <param name="series">Data series.</param>
/// <param name="sortOrder">Sorting order.</param>
/// <param name="sortBy">Value used for sorting ("X", "Y or Y1", "Y2", ...).</param>
#if ASPPERM_35
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
#endif
public DataPointComparer(Series series, PointSortOrder sortOrder, string sortBy)
{
// Check if sorting value is valid
sortBy = sortBy.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
if(String.Compare(sortBy, "X", StringComparison.Ordinal) == 0)
{
_sortingValueIndex = -1;
}
else if (String.Compare(sortBy, "Y", StringComparison.Ordinal) == 0)
{
_sortingValueIndex = 0;
}
else if (String.Compare(sortBy, "AXISLABEL", StringComparison.Ordinal) == 0)
{
_sortingValueIndex = -2;
}
else if(sortBy.Length == 2 &&
sortBy.StartsWith("Y", StringComparison.Ordinal) &&
Char.IsDigit(sortBy[1]))
{
_sortingValueIndex = Int32.Parse(sortBy.Substring(1), System.Globalization.CultureInfo.InvariantCulture) - 1;
}
else
{
throw(new ArgumentException( SR.ExceptionDataPointConverterInvalidSorting, "sortBy"));
}
// Check if data series support as many Y values as required
if(_sortingValueIndex > 0 && _sortingValueIndex >= series.YValuesPerPoint)
{
throw(new ArgumentException( SR.ExceptionDataPointConverterUnavailableSorting(sortBy, series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture) ), "sortBy"));
}
this._sortingOrder = sortOrder;
}
#endregion
#region Comparing method
/// <summary>
/// Compares two data points.
/// </summary>
/// <param name="x">First data point.</param>
/// <param name="y">Second data point.</param>
/// <returns>If the two values are equal, it returns zero. If point 1 is greater than point 2,
/// it returns a positive integer; otherwise, it returns a negative integer.
/// </returns>
public int Compare(DataPoint x, DataPoint y)
{
int result = -1;
// Compare X value
if(_sortingValueIndex == -1)
{
result = x.XValue.CompareTo(y.XValue);
}
// Compare Axis Label value
else if(_sortingValueIndex == -2)
{
result = string.Compare(x.AxisLabel, y.AxisLabel, StringComparison.CurrentCulture);
}
// Compare one of the Y value(s)
else
{
result = x.YValues[_sortingValueIndex].CompareTo(y.YValues[_sortingValueIndex]);
}
// Invert result depending on the sorting order
if(this._sortingOrder == PointSortOrder.Descending)
{
result = -result;
}
return result;
}
#endregion
}
/// <summary>
/// A collection of data points.
/// </summary>
[
SRDescription("DescriptionAttributeDataPointCollection_DataPointCollection"),
]
#if ASPPERM_35
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
#endif
#if !Microsoft_CONTROL
[Themeable(false)]
#endif
public class DataPointCollection : ChartElementCollection<DataPoint>
{
#region Fields
// Reference to the sereies of data points
internal Series series = null;
#endregion
#region Constructors and Initialization
/// <summary>
/// Data Point Collection object constructor.
/// </summary>
/// <param name="series">Series object, which the Data Point Collection belongs to.</param>
internal DataPointCollection(Series series) : base(series)
{
this.series = series;
}
/// <summary>
/// Initialize data point series and name.
/// </summary>
/// <param name="dataPoint">Reference to the data point object to initialize.</param>
internal void DataPointInit(ref DataPoint dataPoint)
{
DataPointInit(this.series, ref dataPoint);
}
/// <summary>
/// Initialize data point series and name.
/// </summary>
/// <param name="series">Series the data point belongs to.</param>
/// <param name="dataPoint">Reference to the data point object to initialize.</param>
internal static void DataPointInit(Series series, ref DataPoint dataPoint)
{
dataPoint.series = series;
if(dataPoint.AxisLabel.Length > 0 && series != null)
{
series.noLabelsInPoints = false;
}
#if Microsoft_CONTROL
// Set flag that tooltips flags should be recalculated
if(dataPoint.ToolTip.Length > 0 &&
dataPoint.LegendToolTip.Length > 0 &&
dataPoint.LabelToolTip.Length > 0 &&
series != null && series.Chart != null && series.Chart.selection != null)
{
series.Chart.selection.enabledChecked = false;
}
#endif
}
#endregion
#region Data point binding, adding and inserting methods
/// <summary>
/// Adds the new DataPoint to a collection and sets its Y values.
/// </summary>
/// <param name="y">The y.</param>
/// <returns></returns>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "X and Y are cartesian coordinates and well understood")]
public DataPoint Add(params double[] y)
{
DataPoint point = new DataPoint(0, y);
this.Add(point);
return point;
}
/// <summary>
/// Parse the input parameter with other point attribute binding rule
/// in format: PointProperty=Field[{Format}] [,PointProperty=Field[{Format}]].
/// For example: "Tooltip=Price{C1},Url=WebSiteName".
/// </summary>
/// <param name="otherFields">Other fields parameter.</param>
/// <param name="otherAttributeNames">Returns array of attribute names.</param>
/// <param name="otherFieldNames">Returns array of field names.</param>
/// <param name="otherValueFormat">Returns array of format strings.</param>
internal static void ParsePointFieldsParameter(
string otherFields,
ref string[] otherAttributeNames,
ref string[] otherFieldNames,
ref string[] otherValueFormat)
{
if(otherFields != null && otherFields.Length > 0)
{
// Split string by comma
otherAttributeNames = otherFields.Replace(",,", "\n").Split(',');
otherFieldNames = new string[otherAttributeNames.Length];
otherValueFormat = new string[otherAttributeNames.Length];
// Loop through all strings
for(int index = 0; index < otherAttributeNames.Length; index++)
{
// Split string by equal sign
int equalSignIndex = otherAttributeNames[index].IndexOf('=');
if(equalSignIndex > 0)
{
otherFieldNames[index] = otherAttributeNames[index].Substring(equalSignIndex + 1);
otherAttributeNames[index] = otherAttributeNames[index].Substring(0, equalSignIndex);
}
else
{
throw (new ArgumentException(SR.ExceptionParameterFormatInvalid, "otherFields"));
}
// Check if format string was specified
int bracketIndex = otherFieldNames[index].IndexOf('{');
if(bracketIndex > 0 && otherFieldNames[index][otherFieldNames[index].Length - 1] == '}')
{
otherValueFormat[index] = otherFieldNames[index].Substring(bracketIndex + 1);
otherValueFormat[index] = otherValueFormat[index].Trim('{', '}');
otherFieldNames[index] = otherFieldNames[index].Substring(0, bracketIndex);
}
// Trim and replace new line character
otherAttributeNames[index] = otherAttributeNames[index].Trim().Replace("\n", ",");
otherFieldNames[index] = otherFieldNames[index].Trim().Replace("\n", ",");
if ( otherValueFormat[index] != null )
otherValueFormat[index] = otherValueFormat[index].Trim().Replace("\n", ",");
}
}
}
/// <summary>
/// Data bind X, Y and other values (like Tooltip, LabelStyle,...) of the data points to the data source.
/// Data source can be the Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow.
/// </summary>
/// <param name="dataSource">Data source.</param>
/// <param name="xField">Name of the field for X values.</param>
/// <param name="yFields">Comma separated names of the fields for Y values.</param>
/// <param name="otherFields">Other point properties binding rule in format: PointProperty=Field[{Format}] [,PointProperty=Field[{Format}]]. For example: "Tooltip=Price{C1},Url=WebSiteName".</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "X and Y are cartesian coordinates and well understood")]
public void DataBind(IEnumerable dataSource, string xField, string yFields, string otherFields)
{
// Check arguments
if (dataSource == null)
throw new ArgumentNullException("dataSource", SR.ExceptionDataPointInsertionNoDataSource);
if (dataSource is string)
throw (new ArgumentException(SR.ExceptionDataBindSeriesToString, "dataSource"));
if (yFields == null)
throw new ArgumentNullException("yFields");
// Convert comma separated Y values field names string to array of names
string[] yFieldNames = yFields.Replace(",,", "\n").Split(',');
for(int index = 0; index < yFieldNames.Length; index++)
{
yFieldNames[index] = yFieldNames[index].Replace("\n", ",");
}
if (yFieldNames.GetLength(0) > series.YValuesPerPoint)
throw (new ArgumentOutOfRangeException("yFields", SR.ExceptionDataPointYValuesCountMismatch(series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture))));
// Convert other fields/properties names to two arrays of names
string[] otherAttributeNames = null;
string[] otherFieldNames = null;
string[] otherValueFormat = null;
ParsePointFieldsParameter(
otherFields,
ref otherAttributeNames,
ref otherFieldNames,
ref otherValueFormat);
// Remove all existing data points
this.Clear();
// Get and reset enumerator
IEnumerator enumerator = GetDataSourceEnumerator(dataSource);
if (enumerator.GetType() != typeof(System.Data.Common.DbEnumerator))
{
try
{
enumerator.Reset();
}
// Some enumerators may not support Resetting
catch (InvalidOperationException)
{
}
catch (NotImplementedException)
{
}
catch (NotSupportedException)
{
}
}
// Add data points
bool valueExsist = true;
object[] yValuesObj = new object[yFieldNames.Length];
object xValueObj = null;
bool autoDetectType = true;
this.SuspendUpdates();
try
{
do
{
// Move to the next objects in the enumerations
if (valueExsist)
{
valueExsist = enumerator.MoveNext();
}
// Auto detect valu(s) type
if (autoDetectType)
{
autoDetectType = false;
AutoDetectValuesType(this.series, enumerator, xField, enumerator, yFieldNames[0]);
}
// Create and initialize data point
if (valueExsist)
{
DataPoint newDataPoint = new DataPoint(series);
bool emptyValues = false;
// Set X to the value provided
if (xField.Length > 0)
{
xValueObj = ConvertEnumerationItem(enumerator.Current, xField);
if (IsEmptyValue(xValueObj))
{
emptyValues = true;
xValueObj = 0.0;
}
}
// Set Y values
if (yFieldNames.Length == 0)
{
yValuesObj[0] = ConvertEnumerationItem(enumerator.Current, null);
if (IsEmptyValue(yValuesObj[0]))
{
emptyValues = true;
yValuesObj[0] = 0.0;
}
}
else
{
for (int i = 0; i < yFieldNames.Length; i++)
{
yValuesObj[i] = ConvertEnumerationItem(enumerator.Current, yFieldNames[i]);
if (IsEmptyValue(yValuesObj[i]))
{
emptyValues = true;
yValuesObj[i] = 0.0;
}
}
}
// Set other values
if (otherAttributeNames != null &&
otherAttributeNames.Length > 0)
{
for (int i = 0; i < otherFieldNames.Length; i++)
{
// Get object by field name
object obj = ConvertEnumerationItem(enumerator.Current, otherFieldNames[i]);
if (!IsEmptyValue(obj))
{
newDataPoint.SetPointCustomProperty(
obj,
otherAttributeNames[i],
otherValueFormat[i]);
}
}
}
// IsEmpty value was detected
if (emptyValues)
{
if (xValueObj != null)
{
newDataPoint.SetValueXY(xValueObj, yValuesObj);
}
else
{
newDataPoint.SetValueXY(0, yValuesObj);
}
DataPointInit(ref newDataPoint);
newDataPoint.IsEmpty = true;
this.Add(newDataPoint);
}
else
{
if (xValueObj != null)
{
newDataPoint.SetValueXY(xValueObj, yValuesObj);
}
else
{
newDataPoint.SetValueXY(0, yValuesObj);
}
DataPointInit(ref newDataPoint);
this.Add(newDataPoint);
}
}
} while (valueExsist);
}
finally
{
this.ResumeUpdates();
}
}
/// <summary>
/// Data bind Y values of the data points to the data source.
/// Data source can be the Array, Collection, Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow.
/// </summary>
/// <param name="yValue">One or more enumerable objects with Y values.</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "Y is a cartesian coordinate and well understood")]
public void DataBindY(params IEnumerable[] yValue)
{
DataBindXY(null, yValue);
}
/// <summary>
/// Data bind X and Y values of the data points to the data source.
/// Data source can be the Array, Collection, Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow.
/// </summary>
/// <param name="xValue">Enumerable objects with X values.</param>
/// <param name="yValues">One or more enumerable objects with Y values.</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "X and Y are cartesian coordinates and well understood")]
public void DataBindXY(IEnumerable xValue, params IEnumerable[] yValues)
{
// Y value must be provided
if (yValues == null ||
yValues.Length==1 && yValues[0]==null)
throw new ArgumentNullException("yValues");
if (yValues.GetLength(0) == 0)
throw new ArgumentException(SR.ExceptionDataPointBindingYValueNotSpecified, "yValues");
// Double check that a string object is not provided for data binding
for(int i = 0; i < yValues.Length; i++)
{
if(yValues[i] is string)
{
throw (new ArgumentException(SR.ExceptionDataBindYValuesToString, "yValues"));
}
}
// Check if number of Y values do not out of range
if(yValues.GetLength(0) > series.YValuesPerPoint)
{
throw(new ArgumentOutOfRangeException("yValues", SR.ExceptionDataPointYValuesBindingCountMismatch( series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture) ) ) );
}
// Remove all existing data points
this.Clear();
// Reset X, Y enumerators
IEnumerator xEnumerator = null;
IEnumerator[] yEnumerator = new IEnumerator[yValues.GetLength(0)];
if(xValue != null)
{
// Double check that a string object is not provided for data binding
if(xValue is string)
{
throw (new ArgumentException(SR.ExceptionDataBindXValuesToString, "xValue"));
}
// Get and reset Y values enumerators
xEnumerator = GetDataSourceEnumerator(xValue);
if(xEnumerator.GetType() != typeof(System.Data.Common.DbEnumerator))
{
xEnumerator.Reset();
}
}
for(int i = 0; i < yValues.Length; i++)
{
// Get and reset Y values enumerators
yEnumerator[i] = GetDataSourceEnumerator(yValues[i]);
if(yEnumerator[i].GetType() != typeof(System.Data.Common.DbEnumerator))
{
yEnumerator[i].Reset();
}
}
// Add data points
bool xValueExsist = false;
bool yValueExsist = true;
object[] yValuesObj = new object[series.YValuesPerPoint];
object xValueObj = null;
bool autoDetectType = true;
SuspendUpdates();
try
{
do
{
// Move to the next objects in the enumerations
yValueExsist = true;
for (int i = 0; i < yValues.Length; i++)
{
if (yValueExsist)
{
yValueExsist = yEnumerator[i].MoveNext();
}
}
if (xValue != null)
{
xValueExsist = xEnumerator.MoveNext();
if (yValueExsist && !xValueExsist)
{
throw (new ArgumentOutOfRangeException("xValue", SR.ExceptionDataPointInsertionXValuesQtyIsLessYValues));
}
}
// Auto detect value(s) type
if (autoDetectType)
{
autoDetectType = false;
AutoDetectValuesType(this.series, xEnumerator, null, yEnumerator[0], null);
}
// Create and initialize data point
if (xValueExsist || yValueExsist)
{
DataPoint newDataPoint = new DataPoint(series);
bool emptyValues = false;
// Set X to the value provided
if (xValueExsist)
{
xValueObj = ConvertEnumerationItem(xEnumerator.Current, null);
if (xValueObj is System.DBNull || xValueObj == null)
{
emptyValues = true;
xValueObj = 0.0;
}
}
// Set Y values
for (int i = 0; i < yValues.Length; i++)
{
yValuesObj[i] = ConvertEnumerationItem(yEnumerator[i].Current, null);
if (yValuesObj[i] is System.DBNull || yValuesObj[i] == null)
{
emptyValues = true;
yValuesObj[i] = 0.0;
}
}
// IsEmpty value was detected
if (emptyValues)
{
if (xValueObj != null)
{
newDataPoint.SetValueXY(xValueObj, yValuesObj);
}
else
{
newDataPoint.SetValueXY(0, yValuesObj);
}
DataPointInit(ref newDataPoint);
newDataPoint.IsEmpty = true;
this.Add(newDataPoint);
}
else
{
if (xValueObj != null)
{
newDataPoint.SetValueXY(xValueObj, yValuesObj);
}
else
{
newDataPoint.SetValueXY(0, yValuesObj);
}
DataPointInit(ref newDataPoint);
this.Add(newDataPoint);
}
}
} while (xValueExsist || yValueExsist);
}
finally
{
this.ResumeUpdates();
}
}
/// <summary>
/// Data bind Y values of the data points to the data source.
/// Data source can be the Array, Collection, Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow.
/// </summary>
/// <param name="yValue">Enumerable objects with Y values.</param>
/// <param name="yFields">Name of the fields for Y values.</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "X and Y are cartesian coordinates and well understood")]
public void DataBindY(IEnumerable yValue, string yFields)
{
DataBindXY(null, null, yValue, yFields);
}
/// <summary>
/// Data bind X and Y values of the data points to the data source.
/// Data source can be the Array, Collection, Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow.
/// </summary>
/// <param name="xValue">Enumerable object with X values.</param>
/// <param name="xField">Name of the field for X values.</param>
/// <param name="yValue">Enumerable objects with Y values.</param>
/// <param name="yFields">Comma separated names of the fields for Y values.</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "X and Y are cartesian coordinates and well understood")]
public void DataBindXY(IEnumerable xValue, string xField, IEnumerable yValue, string yFields)
{
// Check arguments
if (xValue is string)
throw new ArgumentException(SR.ExceptionDataBindXValuesToString, "xValue");
if (yValue == null)
throw new ArgumentNullException("yValue", SR.ExceptionDataPointInsertionYValueNotSpecified);
if (yValue is string)
throw new ArgumentException(SR.ExceptionDataBindYValuesToString, "yValue");
if (yFields == null)
throw new ArgumentOutOfRangeException("yFields", SR.ExceptionDataPointYValuesCountMismatch(series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture)));
// Convert comma separated field names string to array of names
string[] yFieldNames = yFields.Replace(",,", "\n").Split(',');;
for(int index = 0; index < yFieldNames.Length; index++)
{
yFieldNames[index] = yFieldNames[index].Replace("\n", ",");
}
if (yFieldNames.GetLength(0) > series.YValuesPerPoint)
throw new ArgumentOutOfRangeException("yFields", SR.ExceptionDataPointYValuesCountMismatch(series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture)));
// Remove all existing data points
this.Clear();
// Reset X, Y enumerators
IEnumerator xEnumerator = null;
IEnumerator yEnumerator = GetDataSourceEnumerator(yValue);
if(yEnumerator.GetType() != typeof(System.Data.Common.DbEnumerator))
{
yEnumerator.Reset();
}
if(xValue != null)
{
if(xValue != yValue)
{
xEnumerator = GetDataSourceEnumerator(xValue);
if(xEnumerator.GetType() != typeof(System.Data.Common.DbEnumerator))
{
xEnumerator.Reset();
}
}
else
{
xEnumerator = yEnumerator;
}
}
// Add data points
bool xValueExsist = false;
bool yValueExsist = true;
object[] yValuesObj = new object[yFieldNames.Length];
object xValueObj = null;
bool autoDetectType = true;
this.SuspendUpdates();
try
{
do
{
// Move to the next objects in the enumerations
if (yValueExsist)
{
yValueExsist = yEnumerator.MoveNext();
}
if (xValue != null)
{
if (xValue != yValue)
{
xValueExsist = xEnumerator.MoveNext();
if (yValueExsist && !xValueExsist)
{
throw (new ArgumentOutOfRangeException("xValue", SR.ExceptionDataPointInsertionXValuesQtyIsLessYValues));
}
}
else
{
xValueExsist = yValueExsist;
}
}
// Auto detect valu(s) type
if (autoDetectType)
{
autoDetectType = false;
AutoDetectValuesType(this.series, xEnumerator, xField, yEnumerator, yFieldNames[0]);
}
// Create and initialize data point
if (xValueExsist || yValueExsist)
{
DataPoint newDataPoint = new DataPoint(series);
bool emptyValues = false;
// Set X to the value provided or use sequence numbers starting with 1
if (xValueExsist)
{
xValueObj = ConvertEnumerationItem(xEnumerator.Current, xField);
if (IsEmptyValue(xValueObj))
{
emptyValues = true;
xValueObj = 0.0;
}
}
if (yFieldNames.Length == 0)
{
yValuesObj[0] = ConvertEnumerationItem(yEnumerator.Current, null);
if (IsEmptyValue(yValuesObj[0]))
{
emptyValues = true;
yValuesObj[0] = 0.0;
}
}
else
{
for (int i = 0; i < yFieldNames.Length; i++)
{
yValuesObj[i] = ConvertEnumerationItem(yEnumerator.Current, yFieldNames[i]);
if (IsEmptyValue(yValuesObj[i]))
{
emptyValues = true;
yValuesObj[i] = 0.0;
}
}
}
// IsEmpty value was detected
if (emptyValues)
{
if (xValueObj != null)
{
newDataPoint.SetValueXY(xValueObj, yValuesObj);
}
else
{
newDataPoint.SetValueXY(0, yValuesObj);
}
DataPointInit(ref newDataPoint);
newDataPoint.IsEmpty = true;
this.Add(newDataPoint);
}
else
{
if (xValueObj != null)
{
newDataPoint.SetValueXY(xValueObj, yValuesObj);
}
else
{
newDataPoint.SetValueXY(0, yValuesObj);
}
DataPointInit(ref newDataPoint);
this.Add(newDataPoint);
}
}
} while (xValueExsist || yValueExsist);
}
finally
{
this.ResumeUpdates();
}
}
/// <summary>
/// Returns true if objet represents an empty value.
/// </summary>
/// <param name="val">Value to test.</param>
/// <returns>True if empty.</returns>
internal static bool IsEmptyValue(object val)
{
if(val is System.DBNull || val == null)
{
return true;
}
if(val is double && double.IsNaN((double)val))
{
return true;
}
if(val is Single && Single.IsNaN((Single)val))
{
return true;
}
return false;
}
/// <summary>
/// Adds one data point with one Y value.
/// </summary>
/// <param name="yValue">Y value of the data point.</param>
/// <returns>Index of newly added data point.</returns>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "Y is a cartesian coordinate and well understood")]
public int AddY(double yValue)
{
// Create new point object
DataPoint newDataPoint = new DataPoint(series);
newDataPoint.SetValueY(yValue);
DataPointInit(ref newDataPoint);
Add(newDataPoint);
return Count - 1;
}
/// <summary>
/// Adds one data point with one or more Y values.
/// </summary>
/// <param name="yValue">List of Y values of the data point.</param>
/// <returns>Index of newly added data point.</returns>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "Y is a cartesian coordinate and well understood")]
public int AddY(params object[] yValue)
{
//Check arguments
if (yValue == null ||
yValue.Length==1 && yValue[0]==null)
throw new ArgumentNullException("yValue");
// Auto detect DateTime values type
if(this.series.YValueType == ChartValueType.Auto &&
yValue.Length > 0 &&
yValue[0] != null)
{
if (yValue[0] is DateTime)
{
this.series.YValueType = ChartValueType.DateTime;
this.series.autoYValueType = true;
}
else if (yValue[0] is DateTimeOffset)
{
this.series.YValueType = ChartValueType.DateTimeOffset;
this.series.autoYValueType = true;
}
}
// Create new point object
DataPoint newDataPoint = new DataPoint(series);
newDataPoint.SetValueY(yValue);
DataPointInit(ref newDataPoint);
Add(newDataPoint);
return Count - 1;
}
/// <summary>
/// Adds one data point with X value and one Y value.
/// </summary>
/// <param name="yValue">Y value of the data point.</param>
/// <param name="xValue">X value of the data point.</param>
/// <returns>Index of newly added data poit.</returns>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "X and Y are cartesian coordinates and well understood")]
public int AddXY(double xValue, double yValue)
{
// Create new point object
DataPoint newDataPoint = new DataPoint(series);
newDataPoint.SetValueXY(xValue, yValue);
DataPointInit(ref newDataPoint);
Add(newDataPoint);
return Count - 1;
}
/// <summary>
/// Adds one data point with X value and one or more Y values.
/// </summary>
/// <param name="yValue">List of Y values of the data point.</param>
/// <param name="xValue">X value of the data point.</param>
/// <returns>Index of newly added data poit.</returns>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "X and Y are cartesian coordinates and well understood")]
public int AddXY(object xValue, params object[] yValue)
{
// Auto detect DateTime and String values type
if(this.series.XValueType == ChartValueType.Auto)
{
if(xValue is DateTime)
{
this.series.XValueType = ChartValueType.DateTime;
}
if(xValue is DateTimeOffset)
{
this.series.XValueType = ChartValueType.DateTimeOffset;
}
if(xValue is string)
{
this.series.XValueType = ChartValueType.String;
}
this.series.autoXValueType = true;
}
if(this.series.YValueType == ChartValueType.Auto &&
yValue.Length > 0 &&
yValue[0] != null)
{
if (yValue[0] is DateTime)
{
this.series.YValueType = ChartValueType.DateTime;
this.series.autoYValueType = true;
}
else if (yValue[0] is DateTimeOffset)
{
this.series.YValueType = ChartValueType.DateTimeOffset;
this.series.autoYValueType = true;
}
}
// Create new point object
DataPoint newDataPoint = new DataPoint(series);
newDataPoint.SetValueXY(xValue, yValue);
DataPointInit(ref newDataPoint);
Add(newDataPoint);
return Count - 1;
}
/// <summary>
/// Insert one data point with X value and one or more Y values.
/// </summary>
/// <param name="index">Index after which to insert the data point.</param>
/// <param name="xValue">X value of the data point.</param>
/// <param name="yValue">List of Y values of the data point.</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "X and Y are cartesian coordinates and well understood")]
public void InsertXY(int index, object xValue, params object[] yValue)
{
DataPoint newDataPoint = new DataPoint(series);
newDataPoint.SetValueXY(xValue, yValue);
DataPointInit(ref newDataPoint);
this.Insert(index, newDataPoint);
}
/// <summary>
/// Insert one data point with one or more Y values.
/// </summary>
/// <param name="index">Index after which to insert the data point.</param>
/// <param name="yValue">List of Y values of the data point.</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "Y is a cartesian coordinate and well understood")]
public void InsertY(int index, params object[] yValue)
{
DataPoint newDataPoint = new DataPoint(series);
newDataPoint.SetValueY(yValue);
DataPointInit(ref newDataPoint);
this.Insert(index, newDataPoint);
}
/// <summary>
/// Get data source enumerator object helper function.
/// </summary>
/// <param name="dataSource">Data source.</param>
/// <returns>Returns data source enumerator.</returns>
internal static IEnumerator GetDataSourceEnumerator(IEnumerable dataSource)
{
DataView dataView = dataSource as DataView;
if(dataView != null)
{
return dataView.GetEnumerator();
}
DataSet dataSet = dataSource as DataSet;
if(dataSet != null)
{
if(dataSet.Tables.Count > 0)
{
return dataSet.Tables[0].Rows.GetEnumerator();
}
}
return dataSource.GetEnumerator();
}
/// <summary>
/// Convert enumeration item object from DataRow and DataRowView
/// to the actual value of specified column in row
/// </summary>
/// <param name="item">Enumeration item.</param>
/// <param name="fieldName">Converted item.</param>
/// <returns></returns>
internal static object ConvertEnumerationItem(object item, string fieldName)
{
object result = item;
// If original object is DataRow
DataRow dataRow = item as DataRow;
if(dataRow != null)
{
if(fieldName != null && fieldName.Length > 0)
{
// Check if specified column exist
bool failed = true;
if (dataRow.Table.Columns.Contains(fieldName))
{
result = dataRow[fieldName];
failed = false;
}
else
{
// Try to treat field name as column index number
int columnIndex;
failed = !int.TryParse(fieldName, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex);
if (!failed && columnIndex < dataRow.Table.Columns.Count && columnIndex >= 0)
{
result = dataRow[columnIndex];
}
}
if(failed)
{
throw(new ArgumentException( SR.ExceptionColumnNameNotFound( fieldName) ) );
}
}
else
{
// Get first column value if name not specified
result = dataRow[0];
}
}
// If original object is DataRowView
DataRowView dataRowView = item as DataRowView;
if(dataRowView != null)
{
if(fieldName != null && fieldName.Length > 0)
{
// Check if specified column exist
bool failed = true;
if (dataRowView.DataView.Table.Columns.Contains(fieldName))
{
result = dataRowView[fieldName];
failed = false;
}
else
{
// Try to treat field name as column index number
int columnIndex;
failed = !int.TryParse(fieldName, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex);
if (!failed && columnIndex < dataRowView.DataView.Table.Columns.Count && columnIndex >= 0)
{
result = dataRowView[columnIndex];
}
}
if(failed)
{
throw(new ArgumentException( SR.ExceptionColumnNameNotFound(fieldName)));
}
}
else
{
// Get first column value if name not specified
result = dataRowView[0];
}
}
// If original object is DbDataRecord
DbDataRecord dbDataRecord = item as DbDataRecord;
if(dbDataRecord != null)
{
if(fieldName != null && fieldName.Length > 0)
{
// Check if specified column exist
bool failed = true;
if(!Char.IsNumber(fieldName, 0))
{
try
{
result = dbDataRecord[fieldName];
failed = false;
}
catch (IndexOutOfRangeException)
{
failed = true;
}
}
if(failed)
{
// Try to treat field name as column index number
try
{
int columnIndex;
bool parseSucceed = int.TryParse(fieldName, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex);
if (parseSucceed)
{
result = dbDataRecord[columnIndex];
failed = false;
}
else
{
failed = true;
}
}
catch (IndexOutOfRangeException)
{
failed = true;
}
}
if(failed)
{
throw(new ArgumentException( SR.ExceptionColumnNameNotFound(fieldName)));
}
}
else
{
// Get first column value if name not specified
result = dbDataRecord[0];
}
}
else
{
if (fieldName != null && fieldName.Length > 0)
{
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(item).Find(fieldName, true);
if (descriptor != null)
{
result = descriptor.GetValue(item);
return result ?? null;
}
}
}
return result;
}
/// <summary>
/// Auto detects the X and Y(s) values type
/// </summary>
/// <param name="series">Series the values type is detected for.</param>
/// <param name="xEnumerator">X values enumerator.</param>
/// <param name="xField">X value field.</param>
/// <param name="yEnumerator">Y values enumerator.</param>
/// <param name="yField">Y value field.</param>
internal static void AutoDetectValuesType(
Series series,
IEnumerator xEnumerator,
string xField,
IEnumerator yEnumerator,
string yField)
{
if(series.XValueType == ChartValueType.Auto)
{
series.XValueType = GetValueType(xEnumerator, xField);
if(series.XValueType != ChartValueType.Auto)
{
series.autoXValueType = true;
}
}
if(series.YValueType == ChartValueType.Auto)
{
series.YValueType = GetValueType(yEnumerator, yField);
if(series.YValueType != ChartValueType.Auto)
{
series.autoYValueType = true;
}
}
}
/// <summary>
/// Return value type.
/// </summary>
/// <param name="enumerator">Values enumerator.</param>
/// <param name="field">Value field.</param>
private static ChartValueType GetValueType(IEnumerator enumerator, string field)
{
ChartValueType type = ChartValueType.Auto;
Type columnDataType = null;
// Check parameters
if(enumerator == null)
{
return type;
}
// Check if current enumeration element is available
try
{
if(enumerator.Current == null)
{
return type;
}
}
catch(InvalidOperationException)
{
return type;
}
// If original object is DataRow
if(enumerator.Current is DataRow)
{
if(field != null && field.Length > 0)
{
// Check if specified column exist
bool failed = true;
if(((DataRow)enumerator.Current).Table.Columns.Contains(field))
{
columnDataType = ((DataRow)enumerator.Current).Table.Columns[field].DataType;
failed = false;
}
// Try to treat field as column number
if (failed)
{
int columnIndex;
bool parseSucceed = int.TryParse(field, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex);
if (parseSucceed)
{
columnDataType = ((DataRow)enumerator.Current).Table.Columns[columnIndex].DataType;
failed = false;
}
else
{
failed = true;
}
}
if(failed)
{
throw(new ArgumentException( SR.ExceptionColumnNameNotFound(field)));
}
}
else if(((DataRow)enumerator.Current).Table.Columns.Count > 0)
{
columnDataType = ((DataRow)enumerator.Current).Table.Columns[0].DataType;
}
}
// If original object is DataRowView
else if(enumerator.Current is DataRowView)
{
if(field != null && field.Length > 0)
{
// Check if specified column exist
bool failed = true;
if(((DataRowView)enumerator.Current).DataView.Table.Columns.Contains(field))
{
columnDataType = ((DataRowView)enumerator.Current).DataView.Table.Columns[field].DataType;
failed = false;
}
// Try to treat field as column number
if (failed)
{
int columnIndex;
bool parseSucceed = int.TryParse(field, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex);
if (parseSucceed)
{
columnDataType = ((DataRowView)enumerator.Current).DataView.Table.Columns[columnIndex].DataType;
failed = false;
}
else
{
failed = true;
}
}
if(failed)
{
throw(new ArgumentException(SR.ExceptionColumnNameNotFound(field)));
}
}
else if(((DataRowView)enumerator.Current).DataView.Table.Columns.Count > 0)
{
columnDataType = ((DataRowView)enumerator.Current).DataView.Table.Columns[0].DataType;
}
}
// If original object is DbDataRecord
else if(enumerator.Current is DbDataRecord)
{
if(field != null && field.Length > 0)
{
bool failed = true;
int columnIndex = 0;
if(!Char.IsNumber(field, 0))
{
columnIndex = ((DbDataRecord)enumerator.Current).GetOrdinal(field);
columnDataType = ((DbDataRecord)enumerator.Current).GetFieldType(columnIndex);
failed = false;
}
// Try to treat field as column number
if (failed)
{
failed = !int.TryParse(field, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex);
if (!failed)
{
columnDataType = ((DbDataRecord)enumerator.Current).GetFieldType(columnIndex);
}
}
if(failed)
{
throw(new ArgumentException(SR.ExceptionColumnNameNotFound(field)));
}
}
else if(((DbDataRecord)enumerator.Current).FieldCount > 0)
{
columnDataType = ((DbDataRecord)enumerator.Current).GetFieldType(0);
}
}
// Try detecting simple data types
else
{
if (field != null && field.Length > 0)
{
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(enumerator.Current).Find(field, true);
if (descriptor != null)
{
columnDataType = descriptor.PropertyType;
}
}
if ( columnDataType == null )
{
columnDataType = enumerator.Current.GetType();
}
}
// Use data type
if(columnDataType != null)
{
if(columnDataType == typeof(DateTime))
type = ChartValueType.DateTime;
else if (columnDataType == typeof(DateTimeOffset))
type = ChartValueType.DateTimeOffset;
else if (columnDataType == typeof(TimeSpan))
type = ChartValueType.Time;
else if (columnDataType == typeof(Double))
type = ChartValueType.Double;
else if (columnDataType == typeof(Int32))
type = ChartValueType.Int32;
else if(columnDataType == typeof(Int64))
type = ChartValueType.Int64;
else if(columnDataType == typeof(Single))
type = ChartValueType.Single;
else if(columnDataType == typeof(String))
type = ChartValueType.String;
else if(columnDataType == typeof(UInt32))
type = ChartValueType.UInt32;
else if(columnDataType == typeof(UInt64))
type = ChartValueType.UInt64;
}
return type;
}
#endregion
#region DataPoint finding functions
/// <summary>
/// Find all the points that equal to the specified value starting from the specified index.
/// </summary>
/// <param name="valueToFind">Point value to find.</param>
/// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
/// <param name="startIndex">Index of the point to start looking from.</param>
/// <returns>Enumerator of datapoints.</returns>
public IEnumerable<DataPoint> FindAllByValue(double valueToFind, string useValue, int startIndex)
{
// Loop through all points from specified index
for (int i = startIndex; i < this.Count; i++)
{
DataPoint point = this[i];
if (point.GetValueByName(useValue) == valueToFind)
{
yield return point;
}
}
}
/// <summary>
/// Find all the points that equal to the specified value.
/// </summary>
/// <param name="valueToFind">Point value to find.</param>
/// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
/// <returns>Enumerator of datapoints.</returns>
public IEnumerable<DataPoint> FindAllByValue(double valueToFind, string useValue)
{
// Loop through all points from specified index
for (int i = 0; i < this.Count; i++)
{
DataPoint point = this[i];
if (point.GetValueByName(useValue) == valueToFind)
{
yield return point;
}
}
}
/// <summary>
/// Find all the points that equal to the specified value.
/// </summary>
/// <param name="valueToFind">Point value to find.</param>
/// <returns>Enumerator of datapoints.</returns>
public IEnumerable<DataPoint> FindAllByValue(double valueToFind)
{
return FindAllByValue(valueToFind, "Y");
}
/// <summary>
/// Find the first point that equals to the specified value starting from the specified index.
/// </summary>
/// <param name="valueToFind">Point value to find.</param>
/// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
/// <param name="startIndex">Index of the point to start looking from.</param>
/// <returns>Datapoint which matches the value. Null if there is no match.</returns>
public DataPoint FindByValue(double valueToFind, string useValue, int startIndex)
{
//Check arguments
if (useValue == null)
throw new ArgumentNullException("useValue");
if (startIndex < 0 || startIndex >= this.Count)
throw new ArgumentOutOfRangeException("startIndex");
// Loop through all points from specified index
for (int i = startIndex; i < this.Count; i++)
{
DataPoint point = this[i];
if (point.GetValueByName(useValue) == valueToFind)
{
return point;
}
}
// Nothing was found
return null;
}
/// <summary>
/// Find the first point that equals to the specified value.
/// </summary>
/// <param name="valueToFind">Point value to find.</param>
/// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
/// <returns>Datapoint which matches the value. Null if there is no match.</returns>
public DataPoint FindByValue(double valueToFind, string useValue)
{
return FindByValue(valueToFind, useValue, 0);
}
/// <summary>
/// Find the first point that equals to the specified value.
/// </summary>
/// <param name="valueToFind">Point value to find.</param>
/// <returns>Datapoint which matches the value. Null if there is no match.</returns>
public DataPoint FindByValue(double valueToFind)
{
return FindByValue(valueToFind, "Y");
}
/// <summary>
/// Find point with the maximum value starting from specified index.
/// </summary>
/// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
/// <param name="startIndex">Index of the point to start looking from.</param>
/// <returns>Datapoint with the maximum value.</returns>
public DataPoint FindMaxByValue(string useValue, int startIndex)
{
//Check arguments
if (useValue == null)
throw new ArgumentNullException("useValue");
if (startIndex < 0 || startIndex >= this.Count)
throw new ArgumentOutOfRangeException("startIndex");
bool isYValue = useValue.StartsWith("Y", StringComparison.OrdinalIgnoreCase);
double maxValue = double.MinValue;
DataPoint maxPoint = null;
for (int i = startIndex; i < this.Count; i++)
{
DataPoint point = this[i];
// Skip empty points when searching for the Y values
if (point.IsEmpty && isYValue)
continue;
double pointValue = point.GetValueByName(useValue);
if (maxValue < pointValue)
{
maxValue = pointValue;
maxPoint = point;
}
}
return maxPoint;
}
/// <summary>
/// Find point with the maximum value.
/// </summary>
/// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
/// <returns>Datapoint with the maximum value.</returns>
public DataPoint FindMaxByValue(string useValue)
{
return FindMaxByValue(useValue, 0);
}
/// <summary>
/// Find data point with the maximum value.
/// </summary>
/// <returns>Datapoint with the maximum value.</returns>
public DataPoint FindMaxByValue()
{
return FindMaxByValue("Y");
}
/// <summary>
/// Find point with the Min value starting from specified index.
/// </summary>
/// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
/// <param name="startIndex">Index of the point to start looking from.</param>
/// <returns>Datapoint with the Min value.</returns>
public DataPoint FindMinByValue(string useValue, int startIndex)
{
if (useValue == null)
throw new ArgumentNullException("useValue");
if (startIndex < 0 || startIndex >= this.Count)
throw new ArgumentOutOfRangeException("startIndex");
bool isYValue = useValue.StartsWith("Y", StringComparison.OrdinalIgnoreCase);
double minValue = double.MaxValue;
DataPoint minPoint = null;
for (int i = startIndex; i < this.Count; i++)
{
DataPoint point = this[i];
// Skip empty points when searching for the Y values
if (point.IsEmpty && isYValue)
continue;
double pointValue = point.GetValueByName(useValue);
if (minValue > pointValue)
{
minValue = pointValue;
minPoint = point;
}
}
return minPoint;
}
/// <summary>
/// Find point with the Min value.
/// </summary>
/// <param name="useValue">Which point value to use (X, Y1, Y2,...).</param>
/// <returns>Datapoint with the Min value.</returns>
public DataPoint FindMinByValue(string useValue)
{
return FindMinByValue(useValue, 0);
}
/// <summary>
/// Find point with the Min value
/// </summary>
/// <returns>Datapoint with the Min value.</returns>
public DataPoint FindMinByValue()
{
return FindMinByValue("Y");
}
#endregion
#region Collection<T> overrides
/// <summary>
/// Initializes the specified item.
/// </summary>
/// <param name="item">The item.</param>
internal override void Initialize(DataPoint item)
{
DataPointInit(ref item);
base.Initialize(item);
}
#if Microsoft_CONTROL
/// <summary>
/// Removes all elements from the <see cref="T:System.Collections.ObjectModel.Collection`1"/>.
/// </summary>
protected override void ClearItems()
{
// Refresh Minimum and Maximum from data
// after recalc and set data
if (Common != null && Common.ChartPicture != null)
{
Common.ChartPicture.ResetMinMaxFromData();
}
base.ClearItems();
}
#endif
#endregion
}
/// <summary>
/// Stores values and properties of a DataPoint of a Series.
/// </summary>
[
SRDescription("DescriptionAttributeDataPoint_DataPoint"),
DefaultProperty("YValues"),
TypeConverter(Editors.DataPointConverter.Convertor)
]
#if ASPPERM_35
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
#endif
#if !Microsoft_CONTROL
[Themeable(false)]
#endif
public class DataPoint : DataPointCustomProperties
{
#region Fields
// Point X value
private double _xValue;
// Point Y values
private double[] _yValue = new double[1];
// Pre calculated (during painting) relative position of data point
internal PointF positionRel = PointF.Empty;
// VSTS:199794 - Accessibility needs the last rendered label content to be exposed.
// The current label content evaluation is scattered over different chart types and cannot be isolated without risk of regression.
// This variable will cache the label content taken just before drawing.
internal string _lastLabelText = String.Empty;
#endregion
#region Constructors
/// <summary>
/// DataPoint object constructor.
/// </summary>
public DataPoint() : base(null, true)
{
_yValue = new double[1];
}
/// <summary>
/// DataPoint object constructor.
/// </summary>
/// <param name="series">series object, which the DataPoint belongs to.</param>
public DataPoint(Series series) : base(series, true)
{
// Create Y value(s) array
_yValue = new double[series.YValuesPerPoint];
_xValue = 0;
}
/// <summary>
/// DataPoint object constructor.
/// </summary>
/// <param name="xValue">X value.</param>
/// <param name="yValue">Y value.</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "X and Y are cartesian coordinates and well understood")]
public DataPoint(double xValue, double yValue)
: base(null, true)
{
// Set Y value
this._yValue = new double[1];
this._yValue[0] = yValue;
// Set X value
this._xValue = xValue;
}
/// <summary>
/// DataPoint object constructor.
/// </summary>
/// <param name="xValue">X value.</param>
/// <param name="yValues">Array of Y values.</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "X and Y are cartesian coordinates and well understood")]
public DataPoint(double xValue, double[] yValues)
: base(null, true)
{
// Set Y value
this._yValue = yValues;
// Set X value
this._xValue = xValue;
}
/// <summary>
/// DataPoint object constructor.
/// </summary>
/// <remarks>
/// This method is only used during the Windows Forms serialization of the chart.
/// </remarks>
/// <param name="xValue">X value.</param>
/// <param name="yValues">String of comma separated Y values.</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "X and Y are cartesian coordinates and well understood")]
[EditorBrowsable(EditorBrowsableState.Never)]
public DataPoint(double xValue, string yValues)
: base(null, true)
{
string[] values = yValues.Split(',');
// Create Y value(s) array
_yValue = new double[values.Length];
for (int index = 0; index < values.Length; index++)
{
_yValue[index] = CommonElements.ParseDouble(values[index], true);
}
// Set X value
this._xValue = xValue;
}
#endregion
#region Data point methods
/// <summary>
/// Sets the specified data point attribute to the specified value.
/// </summary>
/// <param name="obj">Attribute value.</param>
/// <param name="propertyName">Attribute name.</param>
/// <param name="format">Value format.</param>
internal void SetPointCustomProperty(
object obj,
string propertyName,
string format)
{
// Convert value to string
string stringValue = obj as string;
if(stringValue == null)
{
double doubleObj = double.NaN;
ChartValueType valueType = ChartValueType.Auto;
if(obj is DateTime)
{
doubleObj = ((DateTime)obj).ToOADate();
valueType = ChartValueType.Date;
}
else
{
doubleObj = this.ConvertValue(obj);
}
// Try converting to string
if( !double.IsNaN(doubleObj) )
{
try
{
stringValue = ValueConverter.FormatValue(
this.Chart,
this,
this.Tag,
doubleObj,
format,
valueType,
ChartElementType.DataPoint);
}
catch(FormatException)
{
// Use basic string converter
stringValue = obj.ToString();
}
}
else
{
// Use basic string converter
stringValue = obj.ToString();
}
}
// Assign data point attribute by name
if(stringValue.Length > 0)
{
if(String.Compare(propertyName, "AxisLabel", StringComparison.OrdinalIgnoreCase) == 0)
{
this.AxisLabel = stringValue;
}
else if (String.Compare(propertyName, "Tooltip", StringComparison.OrdinalIgnoreCase) == 0)
{
this.ToolTip = stringValue;
}
#if !Microsoft_CONTROL
else if(String.Compare(propertyName, "Url", StringComparison.OrdinalIgnoreCase) == 0)
{
this.Url = stringValue;
}
else if (String.Compare(propertyName, "PostBackValue", StringComparison.OrdinalIgnoreCase) == 0)
{
this.PostBackValue = stringValue;
}
else if (String.Compare(propertyName, "LabelUrl", StringComparison.OrdinalIgnoreCase) == 0)
{
this.LabelUrl = stringValue;
}
else if (String.Compare(propertyName, "LabelPostBackValue", StringComparison.OrdinalIgnoreCase) == 0)
{
this.LabelPostBackValue = stringValue;
}
else if (String.Compare(propertyName, "LegendUrl", StringComparison.OrdinalIgnoreCase) == 0)
{
this.LegendUrl = stringValue;
}
else if (String.Compare(propertyName, "LegendPostBackValue", StringComparison.OrdinalIgnoreCase) == 0)
{
this.LegendPostBackValue = stringValue;
}
#endif // !Microsoft_CONTROL
else if (String.Compare(propertyName, "Label", StringComparison.OrdinalIgnoreCase) == 0)
{
this.Label = stringValue;
}
else if (String.Compare(propertyName, "LegendTooltip", StringComparison.OrdinalIgnoreCase) == 0)
{
this.LegendToolTip = stringValue;
}
else if (String.Compare(propertyName, "LegendText", StringComparison.OrdinalIgnoreCase) == 0)
{
this.LegendText = stringValue;
}
else if (String.Compare(propertyName, "LabelToolTip", StringComparison.OrdinalIgnoreCase) == 0)
{
this.LabelToolTip = stringValue;
}
else
{
this[propertyName] = stringValue;
}
}
}
/// <summary>
/// Converts object to double.
/// </summary>
/// <param name="value">Object to convert.</param>
/// <returns>Double value.</returns>
private double ConvertValue(object value)
{
if(value == null)
{
return 0;
}
if(value is Double)
{
return (double)value;
}
else if(value is Single)
{
return (double)((float)value);
}
else if(value is Decimal)
{
return (double)((Decimal)value);
}
else if(value is Int32)
{
return (double)((Int32)value);
}
else if(value is UInt32)
{
return (double)((UInt32)value);
}
else if(value is Int64)
{
return (double)((Int64)value);
}
else if(value is UInt64)
{
return (double)((UInt64)value);
}
else if(value is Byte)
{
return (double)((Byte)value);
}
else if(value is SByte)
{
return (double)((SByte)value);
}
else if(value is Boolean)
{
return ((Boolean)value) ? 1.0 : 0.0;
}
else
{
string stringValue = "";
stringValue = value.ToString();
return CommonElements.ParseDouble(stringValue);
}
}
/// <summary>
/// Set X value and one or more Y values of the data point.
/// </summary>
/// <param name="xValue">X value of the data point.</param>
/// <param name="yValue">List of Y values of the data point.</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "X and Y are cartesian coordinates and well understood")]
public void SetValueXY(object xValue, params object[] yValue)
{
// Check arguments
if (xValue == null)
throw new ArgumentNullException("xValue");
// Set Y value first
SetValueY(yValue);
// Check if parameters type matches with series type
Type paramType = xValue.GetType();
if(base.series != null)
{
base.series.CheckSupportedTypes(paramType);
}
// Save value in the array
if(paramType == typeof(String))
{
AxisLabel = (string)xValue;
}
else if(paramType == typeof(DateTime))
{
this._xValue = ((DateTime)xValue).ToOADate();
}
else
{
this._xValue = ConvertValue(xValue);
}
// Get Date or Time if required
if(base.series != null && xValue is DateTime)
{
if(base.series.XValueType == ChartValueType.Date)
{
DateTime time = new DateTime(
((DateTime)xValue).Year,
((DateTime)xValue).Month,
((DateTime)xValue).Day,
0,
0,
0,
0);
this._xValue = time.ToOADate();
}
else if(base.series.XValueType == ChartValueType.Time)
{
DateTime time = new DateTime(
1899,
12,
30,
((DateTime)xValue).Hour,
((DateTime)xValue).Minute,
((DateTime)xValue).Second,
((DateTime)xValue).Millisecond);
this._xValue = time.ToOADate();
}
}
// Check if one of Y values are not avilable
bool empty = false;
foreach(double d in this._yValue)
{
if(double.IsNaN(d))
{
empty = true;
break;
}
}
// Set point empty flag and values to zero
if(empty)
{
this.IsEmpty = true;
for(int valueIndex = 0; valueIndex < this._yValue.Length; valueIndex++)
{
this._yValue[valueIndex] = 0.0;
}
}
}
/// <summary>
/// Set one or more Y values of the data point.
/// </summary>
/// <param name="yValue">List of Y values of the data point.</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
Justification = "Y is a cartesian coordinate and well understood")]
public void SetValueY(params object[] yValue)
{
// Check arguments
if (yValue == null)
throw new ArgumentNullException("yValue");
// Check number of parameters. Should be more than 0 and
if(yValue.Length == 0 || (base.series != null && yValue.Length > base.series.YValuesPerPoint))
throw(new ArgumentOutOfRangeException("yValue", SR.ExceptionDataPointYValuesSettingCountMismatch(base.series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture))));
// Check if there is a Null Y value
for( int i = 0 ; i < yValue.Length ; i++ )
{
if(yValue[i] == null || yValue[i] is System.DBNull)
{
yValue[i] = 0.0;
if(i == 0)
{
this.IsEmpty = true;
}
}
}
// Check if parameters type matches with series type
Type paramType = yValue[0].GetType();
if(base.series != null)
{
base.series.CheckSupportedTypes(paramType);
}
// Make sure the Y values array is big enough
if (this._yValue.Length < yValue.Length)
{
this._yValue = new double[yValue.Length];
}
// Save value in the array
if(paramType == typeof(String))
{
try
{
for (int i = 0; i < yValue.Length; i++)
{
this._yValue[i] = CommonElements.ParseDouble((string)yValue[i]);
}
}
catch
{
// Get reference to the chart object
if (Common!=null && Common.ChartPicture!=null && Common.ChartPicture.SuppressExceptions)
{
this.IsEmpty = true;
for (int i = 0; i < yValue.Length; i++)
{
yValue[i] = 0.0;
}
}
else
{
throw (new ArgumentException( SR.ExceptionDataPointYValueStringFormat));
}
}
}
else if(paramType == typeof(DateTime))
{
for( int i = 0 ; i < yValue.Length ; i++ )
{
if(yValue[i] == null ||
(yValue[i] is double && ((double)yValue[i]) == 0.0) )
{
this._yValue[i] = DateTime.Now.ToOADate();
}
else
{
this._yValue[i] = ((DateTime)yValue[i]).ToOADate();
}
}
}
else
{
for( int i = 0 ; i < yValue.Length ; i++ )
{
this._yValue[i] = ConvertValue(yValue[i]);
}
}
// Get Date or Time if required
if(base.series != null)
{
for( int i = 0 ; i < yValue.Length ; i++ )
{
if(yValue[i] == null ||
(yValue[i] is double && ((double)yValue[i]) == 0.0) )
{
if(base.series.YValueType == ChartValueType.Date)
{
this._yValue[i] = Math.Floor(this._yValue[i]);
}
else if(base.series.YValueType == ChartValueType.Time)
{
this._yValue[i] = this._xValue - Math.Floor(this._yValue[i]);
}
}
else
{
if(base.series.YValueType == ChartValueType.Date)
{
DateTime yDate;
if (yValue[i] is DateTime)
yDate = (DateTime)yValue[i];
else if (yValue[i] is Double)
yDate = DateTime.FromOADate((Double)yValue[i]);
else
yDate = Convert.ToDateTime(yValue[i], CultureInfo.InvariantCulture); //This will throw an exception in case when the yValue type is not compatible with the DateTime
DateTime date = new DateTime(
yDate.Year,
yDate.Month,
yDate.Day,
0,
0,
0,
0);
this._yValue[i] = date.ToOADate();
}
else if (base.series.YValueType == ChartValueType.Time)
{
DateTime yTime;
if (yValue[i] is DateTime)
yTime = (DateTime)yValue[i];
if (yValue[i] is Double)
yTime = DateTime.FromOADate((Double)yValue[i]);
else
yTime = Convert.ToDateTime(yValue[i], CultureInfo.InvariantCulture); //This will throw an exception in case when the yValue type is not compatible with the DateTime
DateTime time = new DateTime(
1899,
12,
30,
yTime.Hour,
yTime.Minute,
yTime.Second,
yTime.Millisecond);
this._yValue[i] = time.ToOADate();
}
}
}
}
}
/// <summary>
/// Creates an exact copy of this DataPoint object.
/// </summary>
/// <returns>An exact copy of this DataPoint object.</returns>
public DataPoint Clone()
{
// Create new data point
DataPoint clonePoint = new DataPoint();
// Reset series pointer
clonePoint.series = null;
clonePoint.pointCustomProperties = this.pointCustomProperties;
// Copy values
clonePoint._xValue = this.XValue;
clonePoint._yValue = new double[this._yValue.Length];
this._yValue.CopyTo(clonePoint._yValue, 0);
clonePoint.tempColorIsSet = this.tempColorIsSet;
clonePoint.isEmptyPoint = this.isEmptyPoint;
// Copy properties
foreach(object key in this.properties.Keys)
{
clonePoint.properties.Add(key, this.properties[key]);
}
return clonePoint;
}
/// <summary>
/// Resize Y values array.
/// </summary>
/// <param name="newSize">New number of Y values in array.</param>
internal void ResizeYValueArray(int newSize)
{
// Create new array
double[] newArray = new Double[newSize];
// Copy elements
if(_yValue != null)
{
for(int i = 0; i < ((_yValue.Length < newSize) ? _yValue.Length : newSize); i++)
{
newArray[i] = _yValue[i];
}
}
_yValue = newArray;
}
/// <summary>
/// Helper function, which returns point value by it's name.
/// </summary>
/// <param name="valueName">Point value names. X, Y, Y2,...</param>
/// <returns>Point value.</returns>
public double GetValueByName(string valueName)
{
// Check arguments
if (valueName == null)
throw new ArgumentNullException("valueName");
valueName = valueName.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
if(String.Compare(valueName, "X", StringComparison.Ordinal) == 0)
{
return this.XValue;
}
else if (valueName.StartsWith("Y", StringComparison.Ordinal))
{
if(valueName.Length == 1)
{
return this.YValues[0];
}
else
{
int yIndex = 0;
try
{
yIndex = Int32.Parse(valueName.Substring(1), System.Globalization.CultureInfo.InvariantCulture) - 1;
}
catch(System.Exception)
{
throw(new ArgumentException( SR.ExceptionDataPointValueNameInvalid, "valueName"));
}
if(yIndex < 0)
{
throw(new ArgumentException( SR.ExceptionDataPointValueNameYIndexIsNotPositive, "valueName"));
}
if(yIndex >= this.YValues.Length)
{
throw(new ArgumentException( SR.ExceptionDataPointValueNameYIndexOutOfRange, "valueName"));
}
return this.YValues[yIndex];
}
}
else
{
throw(new ArgumentException( SR.ExceptionDataPointValueNameInvalid, "valueName"));
}
}
/// <summary>
/// Replaces predefined keyword inside the string with their values.
/// </summary>
/// <param name="strOriginal">Original string with keywords.</param>
/// <returns>Modified string.</returns>
internal override string ReplaceKeywords(string strOriginal)
{
// Nothing to process
if(strOriginal == null || strOriginal.Length == 0)
return strOriginal;
// Replace all "\n" strings with '\n' character
string result = strOriginal;
result = result.Replace("\\n", "\n");
// #LABEL - point label
result = result.Replace(KeywordName.Label, this.Label);
// #LEGENDTEXT - series name
result = result.Replace(KeywordName.LegendText, this.LegendText);
// #AXISLABEL - series name
result = result.Replace(KeywordName.AxisLabel, this.AxisLabel);
// #CUSTOMPROPERTY - one of the custom properties by name
result = DataPoint.ReplaceCustomPropertyKeyword(result, this);
if(this.series != null)
{
// #INDEX - point index
result = result.Replace(KeywordName.Index, this.series.Points.IndexOf(this).ToString(System.Globalization.CultureInfo.InvariantCulture));
// Replace series keywords
result = this.series.ReplaceKeywords(result);
// #PERCENT - percentage of Y value from total
result = this.series.ReplaceOneKeyword(
this.Chart,
this,
this.Tag,
ChartElementType.DataPoint,
result,
KeywordName.Percent,
(this.YValues[0]/(this.series.GetTotalYValue())),
ChartValueType.Double,
"P");
// #VAL[X] - point value X, Y, Y2, ...
if(this.series.XValueType == ChartValueType.String)
{
result = result.Replace(KeywordName.ValX, this.AxisLabel);
}
else
{
result = this.series.ReplaceOneKeyword(
this.Chart,
this,
this.Tag,
ChartElementType.DataPoint,
result,
KeywordName.ValX,
this.XValue,
this.series.XValueType,
"");
}
// remove keywords #VAL? for unexisted Y value indices
for (int index = this.YValues.Length; index <= 7; index++)
{
result = this.RemoveOneKeyword(result, KeywordName.ValY + index + 1, SR.FormatErrorString);
}
for(int index = 1; index <= this.YValues.Length; index++)
{
result = this.series.ReplaceOneKeyword(
this.Chart,
this,
this.Tag,
ChartElementType.DataPoint,
result,
KeywordName.ValY + index,
this.YValues[index - 1],
this.series.YValueType,
"");
}
result = this.series.ReplaceOneKeyword(
Chart,
this,
this.Tag,
ChartElementType.DataPoint,
result,
KeywordName.ValY,
this.YValues[0],
this.series.YValueType,
"");
result = this.series.ReplaceOneKeyword(
Chart,
this,
this.Tag,
ChartElementType.DataPoint,
result,
KeywordName.Val,
this.YValues[0],
this.series.YValueType,
"");
}
return result;
}
/// <summary>
/// Removes one keyword from format string.
/// </summary>
/// <param name="strOriginal">Original format string</param>
/// <param name="keyword">The keyword</param>
/// <param name="strToReplace">String to replace the keyword.</param>
/// <returns>Modified format string</returns>
private string RemoveOneKeyword(string strOriginal, string keyword, string strToReplace)
{
string result = strOriginal;
int keyIndex = -1;
while ((keyIndex = result.IndexOf(keyword, StringComparison.Ordinal)) != -1)
{
// Get optional format
int keyEndIndex = keyIndex + keyword.Length;
if (result.Length > keyEndIndex && result[keyEndIndex] == '{')
{
int formatEnd = result.IndexOf('}', keyEndIndex);
if (formatEnd == -1)
{
throw (new InvalidOperationException(SR.ExceptionDataSeriesKeywordFormatInvalid(result)));
}
keyEndIndex = formatEnd + 1;
}
// Remove keyword string (with optional format)
result = result.Remove(keyIndex, keyEndIndex - keyIndex);
if (!String.IsNullOrEmpty(strToReplace))
{
result = result.Insert(keyIndex, strToReplace);
}
}
return result;
}
/// <summary>
/// Replaces all "#CUSTOMPROPERTY(XXX)" (where XXX is the custom attribute name)
/// keywords in the string provided.
/// </summary>
/// <param name="originalString">String where the keyword need to be replaced.</param>
/// <param name="properties">DataPoint or Series properties class.</param>
/// <returns>Converted string.</returns>
internal static string ReplaceCustomPropertyKeyword(string originalString, DataPointCustomProperties properties)
{
string result = originalString;
int keyStartIndex = -1;
while ((keyStartIndex = result.IndexOf(KeywordName.CustomProperty, StringComparison.Ordinal)) >= 0)
{
string attributeValue = string.Empty;
string attributeName = string.Empty;
// Forward to the end of the keyword
int keyEndIndex = keyStartIndex + KeywordName.CustomProperty.Length;
// An opening bracket '(' must follow
if (result.Length > keyEndIndex && result[keyEndIndex] == '(')
{
++keyEndIndex;
int attributeNameStartIndex = keyEndIndex;
// Search for the closing bracket
int closingBracketIndex = result.IndexOf(')', keyEndIndex);
if (closingBracketIndex >= keyEndIndex)
{
keyEndIndex = closingBracketIndex + 1;
attributeName = result.Substring(attributeNameStartIndex, keyEndIndex - attributeNameStartIndex - 1);
// Get attribute value
if (properties.IsCustomPropertySet(attributeName))
{
attributeValue = properties.GetCustomProperty(attributeName);
}
else
{
// In case of the DataPoint check if the attribute is set in the parent series
DataPoint dataPoint = properties as DataPoint;
if (dataPoint != null && dataPoint.series != null)
{
if (dataPoint.series.IsCustomPropertySet(attributeName))
{
attributeValue = dataPoint.series.GetCustomProperty(attributeName);
}
}
}
}
}
// Remove keyword string with attribute name
result = result.Remove(keyStartIndex, keyEndIndex - keyStartIndex);
// Insert value of the custom attribute
result = result.Insert(keyStartIndex, attributeValue);
}
return result;
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
/// </returns>
internal override string ToStringInternal()
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat(CultureInfo.CurrentCulture, "{{X={0}, ", XValue);
if (YValues.Length == 1)
{
sb.AppendFormat(CultureInfo.CurrentCulture, "Y={0}", YValues[0]);
}
else
{
sb.Append("Y={");
for (int i = 0; i < YValues.Length; i++)
if (i == 0)
sb.AppendFormat(CultureInfo.CurrentCulture, "{0}", YValues[i]);
else
sb.AppendFormat(CultureInfo.CurrentCulture, ", {0}", YValues[i]);
sb.Append("}");
}
sb.Append("}");
return sb.ToString();
}
#endregion
#region DataPoint Properties
/// <summary>
/// X value of the data point.
/// </summary>
[
SRCategory("CategoryAttributeData"),
Bindable(true),
SRDescription("DescriptionAttributeDataPoint_XValue"),
TypeConverter(typeof(DataPointValueConverter)),
DefaultValue(typeof(double), "0.0"),
#if Microsoft_CONTROL
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
#else
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public double XValue
{
get
{
return _xValue;
}
set
{
_xValue = value;
this.Invalidate(false);
}
}
/// <summary>
/// List of Y values of the data point.
/// </summary>
[
SRCategory("CategoryAttributeData"),
SRDescription("DescriptionAttributeDataPoint_YValues"),
Bindable(true),
#if Microsoft_CONTROL
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
#else
PersistenceMode(PersistenceMode.Attribute),
#endif
TypeConverter(typeof(DoubleArrayConverter)),
Editor(typeof(UITypeEditor), typeof(UITypeEditor)),
RefreshProperties(RefreshProperties.All),
SerializationVisibilityAttribute(SerializationVisibility.Attribute)
]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public double[] YValues
{
get
{
return _yValue;
}
set
{
if(value == null)
{
// Clear array data
for(int i=0; i < _yValue.Length; i++)
{
_yValue[i] = 0;
}
}
else
{
_yValue = value;
}
this.Invalidate(false);
}
}
/// <summary>
/// A flag which indicates whether the data point is empty.
/// </summary>
[
SRCategory("CategoryAttributeData"),
Bindable(true),
SRDescription("DescriptionAttributeDataPoint_Empty"),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute),
#endif
DefaultValue(false)
]
public bool IsEmpty
{
get
{
return base.isEmptyPoint;
}
set
{
base.isEmptyPoint = value;
this.Invalidate(true);
}
}
/// <summary>
/// Name of the data point. This field is reserved for internal use only.
/// </summary>
[
SRCategory("CategoryAttributeData"),
Bindable(true),
Browsable(false),
SRDescription("DescriptionAttributeDataPoint_Name"),
DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
SerializationVisibilityAttribute(SerializationVisibility.Hidden)
]
public override string Name
{
get
{
return "DataPoint";
}
set
{
//Dont call the base method - the names don't need to be unique
}
}
#endregion
}
/// <summary>
/// Stores properties of one Data Point and Data series.
/// </summary>
[
SRDescription("DescriptionAttributeDataPointCustomProperties_DataPointCustomProperties"),
DefaultProperty("LabelStyle"),
TypeConverter(Editors.DataPointCustomPropertiesConverter.Convertor)
]
#if Microsoft_CONTROL
public class DataPointCustomProperties : ChartNamedElement
#else
#if ASPPERM_35
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
#endif
public class DataPointCustomProperties : ChartNamedElement, IChartMapArea
#endif
{
#region Fields and enumerations
// True indicates data point properties. Otherwise - series.
internal bool pointCustomProperties = true;
// Reference to the data point series
internal Series series = null;
// Storage for the custom properties names/values
internal Hashtable properties = new Hashtable();
// Flag indicating that temp. color was set
internal bool tempColorIsSet = false;
// Design time custom properties data
internal CustomProperties customProperties = null;
// IsEmpty point indicator
internal bool isEmptyPoint = false;
#endregion
#region Constructors
/// <summary>
/// DataPointCustomProperties constructor.
/// </summary>
public DataPointCustomProperties()
{
// Initialize the data series
this.series = null;
this.customProperties = new CustomProperties(this);
}
/// <summary>
/// DataPointCustomProperties constructor.
/// </summary>
/// <param name="series">The series which the data point belongs to.</param>
/// <param name="pointProperties">Indicates whether this is a data point custom properties.</param>
public DataPointCustomProperties(Series series, bool pointProperties): base( series, String.Empty)
{
// Initialize the data series
this.series = series;
this.pointCustomProperties = pointProperties;
this.customProperties = new CustomProperties(this);
}
#endregion
#region Custom Properties methods
/// <summary>
/// Checks if custom property with specified name was set.
/// </summary>
/// <param name="name">Name of the custom property to check.</param>
/// <returns>True if custom property was set.</returns>
virtual public bool IsCustomPropertySet(string name)
{
return properties.ContainsKey(name);
}
/// <summary>
/// Checks if the custom property with specified name was set.
/// </summary>
/// <param name="property">The CommonCustomProperties object to check for.</param>
/// <returns>True if attribute was set.</returns>
internal bool IsCustomPropertySet(CommonCustomProperties property)
{
return properties.ContainsKey((int)property);
}
/// <summary>
/// Delete the data point custom property with the specified name.
/// </summary>
/// <param name="name">Name of the property to delete.</param>
virtual public void DeleteCustomProperty(string name)
{
if(name == null)
{
throw (new ArgumentNullException(SR.ExceptionAttributeNameIsEmpty));
}
// Check if trying to delete the common attribute
string[] AttributesNames = CommonCustomProperties.GetNames(typeof(CommonCustomProperties));
foreach(string commonName in AttributesNames)
{
if(name == commonName)
{
DeleteCustomProperty((CommonCustomProperties)Enum.Parse(typeof(CommonCustomProperties), commonName));
}
}
// Remove attribute
properties.Remove(name);
}
/// <summary>
/// Delete Data Point attribute with specified name.
/// </summary>
/// <param name="property">ID of the attribute to delete.</param>
internal void DeleteCustomProperty(CommonCustomProperties property)
{
// Check if trying to delete the common attribute from the series
if(!this.pointCustomProperties)
{
throw(new ArgumentException( SR.ExceptionAttributeUnableToDelete));
}
// Remove attribute
properties.Remove((int)property);
}
/// <summary>
/// Gets the data point custom property with the specified name.
/// </summary>
/// <param name="name">Name of the property to get.</param>
/// <returns>Returns the data point custom property with the specified name. If the requested one is not set,
/// the default custom property of the data series will be returned.</returns>
virtual public string GetCustomProperty(string name)
{
if(!IsCustomPropertySet(name) && this.pointCustomProperties)
{
// Check if we are in serialization mode
bool serializing = false;
if(Chart != null && Chart.serializing)
{
serializing = true;
}
if(!serializing)
{
if(this.isEmptyPoint)
{
// Return empty point properties from series
return (string)series.EmptyPointStyle.properties[name];
}
// Return properties from series
return (string)series.properties[name];
}
else
{
// Return default properties
return (string)Series.defaultCustomProperties[name];
}
}
return (string)properties[name];
}
/// <summary>
/// Checks if data is currently serialized.
/// </summary>
/// <returns>True if serialized.</returns>
internal bool IsSerializing()
{
// Check if series object is provided
if(series == null)
{
return true;
}
// Check if we are in serialization mode
if(Chart != null)
{
return Chart.serializing;
}
else
{
return false;
}
}
/// <summary>
/// Returns an attribute object of the Data Point. If required attribute is not set
/// in the Data Point the default attribute of the Data series is returned.
/// </summary>
/// <param name="attrib">Attribute name ID.</param>
/// <returns>Attribute value.</returns>
internal object GetAttributeObject(CommonCustomProperties attrib)
{
// Get series properties
if(!this.pointCustomProperties || series == null)
{
return properties[(int)attrib];
}
// Get data point properties
if(properties.Count == 0 || !IsCustomPropertySet(attrib))
{
// Check if we are in serialization mode
bool serializing = false;
if(Chart != null)
{
serializing = Chart.serializing;
}
if(!serializing)
{
if(this.isEmptyPoint)
{
// Return empty point properties from series
return series.EmptyPointStyle.properties[(int)attrib];
}
// Return properties from series
return series.properties[(int)attrib];
}
else
{
// Return default properties
return Series.defaultCustomProperties.properties[(int)attrib];
}
}
return properties[(int)attrib];
}
/// <summary>
/// Sets a custom property of the data point.
/// </summary>
/// <param name="name">Property name.</param>
/// <param name="propertyValue">Property value.</param>
virtual public void SetCustomProperty(string name, string propertyValue)
{
properties[name] = propertyValue;
}
/// <summary>
/// Sets an attribute of the Data Point as an object.
/// </summary>
/// <param name="attrib">Attribute name ID.</param>
/// <param name="attributeValue">Attribute new value.</param>
internal void SetAttributeObject(CommonCustomProperties attrib, object attributeValue)
{
properties[(int)attrib] = attributeValue;
}
/// <summary>
/// Set the default properties of the data point.
/// <param name="clearAll">Indicates that previous properties must be cleared.</param>
/// </summary>
virtual public void SetDefault(bool clearAll)
{
// If setting defaults for the data series - clear all properties and initialize common one
if(!this.pointCustomProperties)
{
if(clearAll)
{
properties.Clear();
}
// !!! IMPORTANT !!!
// After changing the default value of the common attribute you must also
// change the DefaultAttribute of the property representing this attribute.
if(!IsCustomPropertySet(CommonCustomProperties.ToolTip))
SetAttributeObject(CommonCustomProperties.ToolTip, "");
if(!IsCustomPropertySet(CommonCustomProperties.LegendToolTip))
SetAttributeObject(CommonCustomProperties.LegendToolTip, "");
if(!IsCustomPropertySet(CommonCustomProperties.Color))
SetAttributeObject(CommonCustomProperties.Color, Color.Empty);
if(!IsCustomPropertySet(CommonCustomProperties.IsValueShownAsLabel))
SetAttributeObject(CommonCustomProperties.IsValueShownAsLabel, false);
if(!IsCustomPropertySet(CommonCustomProperties.MarkerStyle))
SetAttributeObject(CommonCustomProperties.MarkerStyle, MarkerStyle.None);
if(!IsCustomPropertySet(CommonCustomProperties.MarkerSize))
SetAttributeObject(CommonCustomProperties.MarkerSize, 5);
if(!IsCustomPropertySet(CommonCustomProperties.MarkerImage))
SetAttributeObject(CommonCustomProperties.MarkerImage, "");
if(!IsCustomPropertySet(CommonCustomProperties.Label))
SetAttributeObject(CommonCustomProperties.Label, "");
if(!IsCustomPropertySet(CommonCustomProperties.BorderWidth))
SetAttributeObject(CommonCustomProperties.BorderWidth, 1);
if(!IsCustomPropertySet(CommonCustomProperties.BorderDashStyle))
SetAttributeObject(CommonCustomProperties.BorderDashStyle, ChartDashStyle.Solid);
if(!IsCustomPropertySet(CommonCustomProperties.AxisLabel))
SetAttributeObject(CommonCustomProperties.AxisLabel, "");
if(!IsCustomPropertySet(CommonCustomProperties.LabelFormat))
SetAttributeObject(CommonCustomProperties.LabelFormat, "");
if(!IsCustomPropertySet(CommonCustomProperties.BorderColor))
SetAttributeObject(CommonCustomProperties.BorderColor, Color.Empty);
if(!IsCustomPropertySet(CommonCustomProperties.BackImage))
SetAttributeObject(CommonCustomProperties.BackImage, "");
if(!IsCustomPropertySet(CommonCustomProperties.BackImageWrapMode))
SetAttributeObject(CommonCustomProperties.BackImageWrapMode, ChartImageWrapMode.Tile);
if(!IsCustomPropertySet(CommonCustomProperties.BackImageAlignment))
SetAttributeObject(CommonCustomProperties.BackImageAlignment, ChartImageAlignmentStyle.TopLeft);
if(!IsCustomPropertySet(CommonCustomProperties.BackImageTransparentColor))
SetAttributeObject(CommonCustomProperties.BackImageTransparentColor, Color.Empty);
if(!IsCustomPropertySet(CommonCustomProperties.BackGradientStyle))
SetAttributeObject(CommonCustomProperties.BackGradientStyle, GradientStyle.None);
if(!IsCustomPropertySet(CommonCustomProperties.BackSecondaryColor))
SetAttributeObject(CommonCustomProperties.BackSecondaryColor, Color.Empty);
if(!IsCustomPropertySet(CommonCustomProperties.BackHatchStyle))
SetAttributeObject(CommonCustomProperties.BackHatchStyle, ChartHatchStyle.None);
if(!IsCustomPropertySet(CommonCustomProperties.Font))
SetAttributeObject(CommonCustomProperties.Font, null);
if(!IsCustomPropertySet(CommonCustomProperties.MarkerImageTransparentColor))
SetAttributeObject(CommonCustomProperties.MarkerImageTransparentColor, Color.Empty);
if(!IsCustomPropertySet(CommonCustomProperties.MarkerColor))
SetAttributeObject(CommonCustomProperties.MarkerColor, Color.Empty);
if(!IsCustomPropertySet(CommonCustomProperties.MarkerBorderColor))
SetAttributeObject(CommonCustomProperties.MarkerBorderColor, Color.Empty);
if(!IsCustomPropertySet(CommonCustomProperties.MarkerBorderWidth))
SetAttributeObject(CommonCustomProperties.MarkerBorderWidth, 1);
if(!IsCustomPropertySet(CommonCustomProperties.MapAreaAttributes))
SetAttributeObject(CommonCustomProperties.MapAreaAttributes, "");
if (!IsCustomPropertySet(CommonCustomProperties.PostBackValue))
SetAttributeObject(CommonCustomProperties.PostBackValue, "");
if (!IsCustomPropertySet(CommonCustomProperties.LabelForeColor))
SetAttributeObject(CommonCustomProperties.LabelForeColor, Color.Black);
if (!IsCustomPropertySet(CommonCustomProperties.LabelAngle))
SetAttributeObject(CommonCustomProperties.LabelAngle, 0);
if (!IsCustomPropertySet(CommonCustomProperties.LabelToolTip))
SetAttributeObject(CommonCustomProperties.LabelToolTip, "");
if(!IsCustomPropertySet(CommonCustomProperties.LabelUrl))
SetAttributeObject(CommonCustomProperties.LabelUrl, "");
if (!IsCustomPropertySet(CommonCustomProperties.LabelPostBackValue))
SetAttributeObject(CommonCustomProperties.LabelPostBackValue, "");
if (!IsCustomPropertySet(CommonCustomProperties.LabelMapAreaAttributes))
SetAttributeObject(CommonCustomProperties.LabelMapAreaAttributes, "");
if(!IsCustomPropertySet(CommonCustomProperties.LabelBackColor))
SetAttributeObject(CommonCustomProperties.LabelBackColor, Color.Empty);
if(!IsCustomPropertySet(CommonCustomProperties.LabelBorderWidth))
SetAttributeObject(CommonCustomProperties.LabelBorderWidth, 1);
if(!IsCustomPropertySet(CommonCustomProperties.LabelBorderDashStyle))
SetAttributeObject(CommonCustomProperties.LabelBorderDashStyle, ChartDashStyle.Solid);
if(!IsCustomPropertySet(CommonCustomProperties.LabelBorderColor))
SetAttributeObject(CommonCustomProperties.LabelBorderColor, Color.Empty);
if(!IsCustomPropertySet(CommonCustomProperties.Url))
SetAttributeObject(CommonCustomProperties.Url, "");
if(!IsCustomPropertySet(CommonCustomProperties.LegendUrl))
SetAttributeObject(CommonCustomProperties.LegendUrl, "");
if (!IsCustomPropertySet(CommonCustomProperties.LegendPostBackValue))
SetAttributeObject(CommonCustomProperties.LegendPostBackValue, "");
if (!IsCustomPropertySet(CommonCustomProperties.LegendText))
SetAttributeObject(CommonCustomProperties.LegendText, "");
if(!IsCustomPropertySet(CommonCustomProperties.LegendMapAreaAttributes))
SetAttributeObject(CommonCustomProperties.LegendMapAreaAttributes, "");
if(!IsCustomPropertySet(CommonCustomProperties.IsVisibleInLegend))
SetAttributeObject(CommonCustomProperties.IsVisibleInLegend, true);
}
// If setting defaults for the data point - clear all properties
else
{
properties.Clear();
}
}
#endregion
#region DataPointCustomProperties Properties
/// <summary>
/// Indexer of the custom properties. Returns the DataPointCustomProperties object by index.
/// </summary>
/// <param name="index">Index of the custom property.</param>
public string this[int index]
{
get
{
int currentIndex = 0;
foreach(object key in properties.Keys)
{
if(currentIndex == index)
{
string keyStr = key as string;
if (keyStr != null)
{
return keyStr;
}
else if (key is int)
{
return Enum.GetName(typeof(CommonCustomProperties), key);
}
return key.ToString();
}
++currentIndex;
}
// we can't throw IndexOutOfRangeException here, it is reserved
// by the CLR.
throw (new InvalidOperationException());
}
}
/// <summary>
/// Indexer of the custom properties. Returns the DataPointCustomProperties object by name.
/// </summary>
/// <param name="name">Name of the custom property.</param>
public string this[string name]
{
get
{
// If attribute is not set in data point - try getting it from the series
if(!IsCustomPropertySet(name) && this.pointCustomProperties)
{
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.properties[name];
}
return (string)series.properties[name];
}
return (string)properties[name];
}
set
{
properties[name] = value;
this.Invalidate(true);
}
}
/// <summary>
/// The text of the data point label.
/// </summary>
[
Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute),
#endif
SRCategory("CategoryAttributeLabel"),
Bindable(true),
SRDescription("DescriptionAttributeLabel"),
]
virtual public string Label
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.Label))
{
return (string)GetAttributeObject(CommonCustomProperties.Label);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.Label);
}
return series.label;
}
}
else
{
return series.label;
}
}
set
{
// Replace NULL with empty string
if(value == null)
{
value = string.Empty;
}
if (this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.Label, value);
else
series.label = value;
this.Invalidate(true);
}
}
/// <summary>
/// The text of X axis label for the data point.
/// </summary>
[
SRCategory("CategoryAttributeMisc"),
Bindable(true),
SRDescription("DescriptionAttributeAxisLabel"),
Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
virtual public string AxisLabel
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.AxisLabel))
{
return (string)GetAttributeObject(CommonCustomProperties.AxisLabel);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.AxisLabel);
}
return series.axisLabel;
}
}
else
{
return series.axisLabel;
}
}
set
{
// Replace NULL with empty string
if(value == null)
{
value = string.Empty;
}
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.AxisLabel, value);
else
series.axisLabel = value;
// Set flag that there are non-empy axis labels in series or points
if(value.Length > 0 && series != null)
{
series.noLabelsInPoints = false;
}
this.Invalidate(false);
}
}
/// <summary>
/// Format string of the data point label.
/// </summary>
[
SRCategory("CategoryAttributeLabel"),
Bindable(true),
SRDescription("DescriptionAttributeLabelFormat"),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute),
#endif
]
public string LabelFormat
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelFormat))
{
return (string)GetAttributeObject(CommonCustomProperties.LabelFormat);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelFormat);
}
return series.labelFormat;
}
}
else
{
return series.labelFormat;
}
}
set
{
// Replace NULL with empty string
if(value == null)
{
value = string.Empty;
}
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LabelFormat, value);
else
series.labelFormat = value;
this.Invalidate(false);
}
}
/// <summary>
/// A flag which indicates whether to show the data point's value on the label.
/// </summary>
[
SRCategory("CategoryAttributeLabel"),
Bindable(true),
SRDescription("DescriptionAttributeShowLabelAsValue"),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public bool IsValueShownAsLabel
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.IsValueShownAsLabel))
{
return (bool)GetAttributeObject(CommonCustomProperties.IsValueShownAsLabel);
}
else
{
if(IsSerializing())
{
return false;
}
if(this.isEmptyPoint)
{
return (bool)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.IsValueShownAsLabel);
}
return series.showLabelAsValue;
}
}
else
{
return series.showLabelAsValue;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.IsValueShownAsLabel, value);
else
series.showLabelAsValue = value;
this.Invalidate(false);
}
}
/// <summary>
/// Color of the data point.
/// </summary>
[
SRCategory("CategoryAttributeAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeColor4"),
TypeConverter(typeof(ColorConverter)),
Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public Color Color
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.Color))
{
return (Color)GetAttributeObject(CommonCustomProperties.Color);
}
else
{
if(IsSerializing())
{
return Color.Empty;
}
if(this.isEmptyPoint)
{
return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.Color);
}
return series.color;
}
}
else
{
return series.color;
}
}
set
{
// Remove the temp color flag
this.tempColorIsSet = false;
if(value == Color.Empty && this.pointCustomProperties)
{
DeleteCustomProperty(CommonCustomProperties.Color);
}
else
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.Color, value);
else
series.color = value;
this.Invalidate(true);
}
}
}
/// <summary>
/// Border color of the data point.
/// </summary>
[
SRCategory("CategoryAttributeAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeBorderColor"),
TypeConverter(typeof(ColorConverter)),
Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public Color BorderColor
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BorderColor))
{
return (Color)GetAttributeObject(CommonCustomProperties.BorderColor);
}
else
{
if(IsSerializing())
{
return Color.Empty;
}
if(this.isEmptyPoint)
{
return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BorderColor);
}
return series.borderColor;
}
}
else
{
return series.borderColor;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.BorderColor, value);
else
series.borderColor = value;
this.Invalidate(true);
}
}
/// <summary>
/// Border style of the data point.
/// </summary>
[
SRCategory("CategoryAttributeAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeBorderDashStyle"),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public ChartDashStyle BorderDashStyle
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BorderDashStyle))
{
return (ChartDashStyle)GetAttributeObject(CommonCustomProperties.BorderDashStyle);
}
else
{
if(IsSerializing())
{
return ChartDashStyle.Solid;
}
if(this.isEmptyPoint)
{
return (ChartDashStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BorderDashStyle);
}
return series.borderDashStyle;
}
}
else
{
return series.borderDashStyle;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.BorderDashStyle, value);
else
series.borderDashStyle = value;
this.Invalidate(true);
}
}
/// <summary>
/// Border width of the data point.
/// </summary>
[
SRCategory("CategoryAttributeAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeBorderWidth"),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public int BorderWidth
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BorderWidth))
{
return (int)GetAttributeObject(CommonCustomProperties.BorderWidth);
}
else
{
if(IsSerializing())
{
return 1;
}
if(this.isEmptyPoint)
{
return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BorderWidth);
}
return series.borderWidth;
}
}
else
{
return series.borderWidth;
}
}
set
{
if(value < 0)
{
throw (new ArgumentOutOfRangeException("value", SR.ExceptionBorderWidthIsNotPositive));
}
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.BorderWidth, value);
else
series.borderWidth = value;
this.Invalidate(true);
}
}
/// <summary>
/// Background image of the data point.
/// </summary>
[
SRCategory("CategoryAttributeAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeBackImage"),
Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute),
#endif
]
public string BackImage
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackImage))
{
return (string)GetAttributeObject(CommonCustomProperties.BackImage);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackImage);
}
return series.backImage;
}
}
else
{
return series.backImage;
}
}
set
{
// Replace NULL with empty string
if(value == null)
{
value = string.Empty;
}
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.BackImage, value);
else
series.backImage = value;
this.Invalidate(true);
}
}
/// <summary>
/// Gets or sets the drawing mode of the background image.
/// </summary>
/// <value>
/// A <see cref="ChartImageWrapMode"/> value that defines the drawing mode of the image.
/// </value>
[
SRCategory("CategoryAttributeAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeImageWrapMode"),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public ChartImageWrapMode BackImageWrapMode
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackImageWrapMode))
{
return (ChartImageWrapMode)GetAttributeObject(CommonCustomProperties.BackImageWrapMode);
}
else
{
if(IsSerializing())
{
return ChartImageWrapMode.Tile;
}
if(this.isEmptyPoint)
{
return (ChartImageWrapMode)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackImageWrapMode);
}
return series.backImageWrapMode;
}
}
else
{
return series.backImageWrapMode;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.BackImageWrapMode, value);
else
series.backImageWrapMode = value;
this.Invalidate(true);
}
}
/// <summary>
/// Gets or sets a color which will be replaced with a transparent color while drawing the background image.
/// </summary>
/// <value>
/// A <see cref="Color"/> value which will be replaced with a transparent color while drawing the image.
/// </value>
[
SRCategory("CategoryAttributeAppearance"),
Bindable(true),
NotifyParentPropertyAttribute(true),
SRDescription("DescriptionAttributeImageTransparentColor"),
TypeConverter(typeof(ColorConverter)),
Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public Color BackImageTransparentColor
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackImageTransparentColor))
{
return (Color)GetAttributeObject(CommonCustomProperties.BackImageTransparentColor);
}
else
{
if(IsSerializing())
{
return Color.Empty;
}
if(this.isEmptyPoint)
{
return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackImageTransparentColor);
}
return series.backImageTransparentColor;
}
}
else
{
return series.backImageTransparentColor;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.BackImageTransparentColor, value);
else
series.backImageTransparentColor = value;
this.Invalidate(true);
}
}
/// <summary>
/// Gets or sets the alignment of the background image which is used by ClampUnscale drawing mode.
/// </summary>
[
SRCategory("CategoryAttributeAppearance"),
Bindable(true),
NotifyParentPropertyAttribute(true),
SRDescription("DescriptionAttributeBackImageAlign"),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public ChartImageAlignmentStyle BackImageAlignment
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackImageAlignment))
{
return (ChartImageAlignmentStyle)GetAttributeObject(CommonCustomProperties.BackImageAlignment);
}
else
{
if(IsSerializing())
{
return ChartImageAlignmentStyle.TopLeft;
}
if(this.isEmptyPoint)
{
return (ChartImageAlignmentStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackImageAlignment);
}
return series.backImageAlignment;
}
}
else
{
return series.backImageAlignment;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.BackImageAlignment, value);
else
series.backImageAlignment = value;
this.Invalidate(true);
}
}
/// <summary>
/// Gets or sets the background gradient style.
/// </summary>
[
SRCategory("CategoryAttributeAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeBackGradientStyle"),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute),
#endif
Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base)
]
public GradientStyle BackGradientStyle
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackGradientStyle))
{
return (GradientStyle)GetAttributeObject(CommonCustomProperties.BackGradientStyle);
}
else
{
if(IsSerializing())
{
return GradientStyle.None;
}
if(this.isEmptyPoint)
{
return (GradientStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackGradientStyle);
}
return series.backGradientStyle;
}
}
else
{
return series.backGradientStyle;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.BackGradientStyle, value);
else
series.backGradientStyle = value;
this.Invalidate(true);
}
}
/// <summary>
/// Gets or sets the secondary background color.
/// </summary>
[
SRCategory("CategoryAttributeAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeBackSecondaryColor"),
TypeConverter(typeof(ColorConverter)),
Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public Color BackSecondaryColor
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackSecondaryColor))
{
return (Color)GetAttributeObject(CommonCustomProperties.BackSecondaryColor);
}
else
{
if(IsSerializing())
{
return Color.Empty;
}
if(this.isEmptyPoint)
{
return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackSecondaryColor);
}
return series.backSecondaryColor;
}
}
else
{
return series.backSecondaryColor;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.BackSecondaryColor, value);
else
series.backSecondaryColor = value;
this.Invalidate(true);
}
}
/// <summary>
/// Gets or sets the background hatch style.
/// </summary>
[
SRCategory("CategoryAttributeAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeBackHatchStyle"),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute),
#endif
Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base)
]
public ChartHatchStyle BackHatchStyle
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackHatchStyle))
{
return (ChartHatchStyle)GetAttributeObject(CommonCustomProperties.BackHatchStyle);
}
else
{
if(IsSerializing())
{
return ChartHatchStyle.None;
}
if(this.isEmptyPoint)
{
return (ChartHatchStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackHatchStyle);
}
return series.backHatchStyle;
}
}
else
{
return series.backHatchStyle;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.BackHatchStyle, value);
else
series.backHatchStyle = value;
this.Invalidate(true);
}
}
/// <summary>
/// Gets or sets the font of the data point.
/// </summary>
[
SRCategory("CategoryAttributeLabelAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeFont"),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public Font Font
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.Font))
{
Font font = GetAttributeObject(CommonCustomProperties.Font) as Font;
if (font != null)
return font;
}
if(IsSerializing())
{
return series.FontCache.DefaultFont;
}
if(this.isEmptyPoint)
{
return series.EmptyPointStyle.Font;
}
return series.font;
}
else
{
return series.font;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.Font, value);
else
series.font = value;
this.Invalidate(false);
}
}
/// <summary>
/// Gets or sets the label color.
/// </summary>
[
SRCategory("CategoryAttributeLabelAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeFontColor"),
TypeConverter(typeof(ColorConverter)),
Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public Color LabelForeColor
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelForeColor))
{
Color color = (Color)GetAttributeObject(CommonCustomProperties.LabelForeColor);
return color;
}
else
{
if(IsSerializing())
{
return Color.Black;
}
if(this.isEmptyPoint)
{
return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelForeColor);
}
#if Microsoft_CONTROL
if(SystemInformation.HighContrast && AccessibilityImprovements.Level3)
{
return SystemColors.WindowText;
}
#endif
return series.fontColor;
}
}
else
{
return series.fontColor;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LabelForeColor, value);
else
series.fontColor = value;
this.Invalidate(false);
}
}
/// <summary>
/// Gets or sets the angle of the label.
/// </summary>
[
SRCategory("CategoryAttributeLabelAppearance"),
Bindable(true),
SRDescription(SR.Keys.DescriptionAttributeLabel_FontAngle),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute),
#endif
]
public int LabelAngle
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelAngle))
{
return (int)GetAttributeObject(CommonCustomProperties.LabelAngle);
}
else
{
if(IsSerializing())
{
return 0;
}
if(this.isEmptyPoint)
{
return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelAngle);
}
return series.fontAngle;
}
}
else
{
return series.fontAngle;
}
}
set
{
if(value < -90 || value > 90)
{
throw (new ArgumentOutOfRangeException("value", SR.ExceptionAngleRangeInvalid));
}
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LabelAngle, value);
else
series.fontAngle = value;
this.Invalidate(false);
}
}
/// <summary>
/// Gets or sets the marker style.
/// </summary>
[
SRCategory("CategoryAttributeMarker"),
Bindable(true),
SRDescription("DescriptionAttributeMarkerStyle4"),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute),
#endif
Editor(Editors.MarkerStyleEditor.Editor, Editors.MarkerStyleEditor.Base),
RefreshProperties(RefreshProperties.All)
]
public MarkerStyle MarkerStyle
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerStyle))
{
return (MarkerStyle)GetAttributeObject(CommonCustomProperties.MarkerStyle);
}
else
{
if(IsSerializing())
{
return MarkerStyle.None;
}
if(this.isEmptyPoint)
{
return (MarkerStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerStyle);
}
return series.markerStyle;
}
}
else
{
return series.markerStyle;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.MarkerStyle, value);
else
series.markerStyle = value;
Series thisSeries = this as Series;
if(thisSeries != null)
{
thisSeries.tempMarkerStyleIsSet = false;
}
this.Invalidate(true);
}
}
/// <summary>
/// Gets or sets the size of the marker.
/// </summary>
[
SRCategory("CategoryAttributeMarker"),
Bindable(true),
SRDescription("DescriptionAttributeMarkerSize"),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute),
#endif
RefreshProperties(RefreshProperties.All)
]
public int MarkerSize
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerSize))
{
return (int)GetAttributeObject(CommonCustomProperties.MarkerSize);
}
else
{
if(IsSerializing())
{
return 5;
}
if(this.isEmptyPoint)
{
return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerSize);
}
return series.markerSize;
}
}
else
{
return series.markerSize;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.MarkerSize, value);
else
series.markerSize = value;
this.Invalidate(true);
}
}
/// <summary>
/// Gets or sets the marker image.
/// </summary>
[
SRCategory("CategoryAttributeMarker"),
Bindable(true),
SRDescription("DescriptionAttributeMarkerImage"),
Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute),
#endif
RefreshProperties(RefreshProperties.All)
]
public string MarkerImage
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerImage))
{
return (string)GetAttributeObject(CommonCustomProperties.MarkerImage);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerImage);
}
return series.markerImage;
}
}
else
{
return series.markerImage;
}
}
set
{
// Replace NULL with empty string
if(value == null)
{
value = string.Empty;
}
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.MarkerImage, value);
else
series.markerImage = value;
this.Invalidate(true);
}
}
/// <summary>
/// Gets or sets the color which will be replaced with a transparent color while drawing the marker image.
/// </summary>
[
SRCategory("CategoryAttributeMarker"),
Bindable(true),
SRDescription("DescriptionAttributeImageTransparentColor"),
TypeConverter(typeof(ColorConverter)),
Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute),
#endif
RefreshProperties(RefreshProperties.All)
]
public Color MarkerImageTransparentColor
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerImageTransparentColor))
{
return (Color)GetAttributeObject(CommonCustomProperties.MarkerImageTransparentColor);
}
else
{
if(IsSerializing())
{
return Color.Empty;
}
if(this.isEmptyPoint)
{
return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerImageTransparentColor);
}
return series.markerImageTransparentColor;
}
}
else
{
return series.markerImageTransparentColor;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.MarkerImageTransparentColor, value);
else
series.markerImageTransparentColor = value;
this.Invalidate(true);
}
}
/// <summary>
/// Gets or sets the marker color.
/// </summary>
[
SRCategory("CategoryAttributeMarker"),
Bindable(true),
SRDescription("DescriptionAttributeMarkerColor3"),
TypeConverter(typeof(ColorConverter)),
Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute),
#endif
RefreshProperties(RefreshProperties.All)
]
public Color MarkerColor
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerColor))
{
return (Color)GetAttributeObject(CommonCustomProperties.MarkerColor);
}
else
{
if(IsSerializing())
{
return Color.Empty;
}
if(this.isEmptyPoint)
{
return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerColor);
}
return series.markerColor;
}
}
else
{
return series.markerColor;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.MarkerColor, value);
else
series.markerColor = value;
this.Invalidate(true);
}
}
/// <summary>
/// Gets or sets the border color of the marker.
/// </summary>
[
SRCategory("CategoryAttributeMarker"),
Bindable(true),
SRDescription("DescriptionAttributeMarkerBorderColor"),
TypeConverter(typeof(ColorConverter)),
Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute),
#endif
RefreshProperties(RefreshProperties.All)
]
public Color MarkerBorderColor
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerBorderColor))
{
return (Color)GetAttributeObject(CommonCustomProperties.MarkerBorderColor);
}
else
{
if(IsSerializing())
{
return Color.Empty;
}
if(this.isEmptyPoint)
{
return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerBorderColor);
}
return series.markerBorderColor;
}
}
else
{
return series.markerBorderColor;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.MarkerBorderColor, value);
else
series.markerBorderColor = value;
this.Invalidate(true);
}
}
/// <summary>
/// Gets or sets the border width of the marker.
/// </summary>
[
SRCategory("CategoryAttributeMarker"),
Bindable(true),
SRDescription("DescriptionAttributeMarkerBorderWidth"),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public int MarkerBorderWidth
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerBorderWidth))
{
return (int)GetAttributeObject(CommonCustomProperties.MarkerBorderWidth);
}
else
{
if(IsSerializing())
{
return 1;
}
if(this.isEmptyPoint)
{
return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerBorderWidth);
}
return series.markerBorderWidth;
}
}
else
{
return series.markerBorderWidth;
}
}
set
{
if(value < 0)
{
throw (new ArgumentOutOfRangeException("value", SR.ExceptionBorderWidthIsNotPositive));
}
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.MarkerBorderWidth, value);
else
series.markerBorderWidth = value;
this.Invalidate(true);
}
}
/// <summary>
/// Gets or sets the extended custom properties of the data point.
/// Extended custom properties can be specified in the following format:
/// AttrName1=Value1, AttrName2=Value2, ...
/// </summary>
[
SRCategory("CategoryAttributeMisc"),
Bindable(false),
SRDescription("DescriptionAttributeCustomAttributesExtended"),
DefaultValue(null),
RefreshProperties(RefreshProperties.All),
NotifyParentPropertyAttribute(true),
DesignOnlyAttribute(true),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
SerializationVisibilityAttribute(SerializationVisibility.Hidden),
EditorBrowsableAttribute(EditorBrowsableState.Never),
DisplayName("CustomProperties")
]
public CustomProperties CustomPropertiesExtended
{
set
{
customProperties = value;
}
get
{
return customProperties;
}
}
/// <summary>
/// Gets or sets the custom properties of the data point.
/// Custom properties can be specified in the following format:
/// AttrName1=Value1, AttrName2=Value2, ...
/// </summary>
[
SRCategory("CategoryAttributeMisc"),
Bindable(true),
Browsable(false),
SRDescription("DescriptionAttributeCustomAttributesExtended"),
DefaultValue(""),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public string CustomProperties
{
get
{
// Save all custom properties in a string
string result = "";
string[] attributesNames = CommonCustomProperties.GetNames(typeof(CommonCustomProperties));
for(int i = properties.Count - 1; i >= 0; i--)
{
if(this[i] != null)
{
string attributeName = this[i];
// Check if attribute is custom
bool customAttribute = true;
foreach(string name in attributesNames)
{
if(String.Compare(attributeName, name, StringComparison.OrdinalIgnoreCase) == 0)
{
customAttribute = false;
break;
}
}
// Add custom attribute to the string
if(customAttribute && properties[attributeName] != null)
{
if(result.Length > 0)
{
result += ", ";
}
string attributeValue = properties[attributeName].ToString().Replace(",", "\\,");
attributeValue = attributeValue.Replace("=", "\\=");
result += attributeName + "=" + attributeValue;
}
}
}
return result;
}
set
{
// Replace NULL with empty string
if(value == null)
{
value = string.Empty;
}
// Copy all common properties to the new collection
Hashtable newAttributes = new Hashtable();
Array enumValues = Enum.GetValues(typeof(CommonCustomProperties));
foreach(object val in enumValues)
{
if(IsCustomPropertySet((CommonCustomProperties)val))
{
newAttributes[(int)val] = properties[(int)val];
}
}
if(value.Length > 0)
{
// Replace commas in value string
value = value.Replace("\\,", "\\x45");
value = value.Replace("\\=", "\\x46");
// Add new custom properties
string[] nameValueStrings = value.Split(',');
foreach(string nameValue in nameValueStrings)
{
string[] values = nameValue.Split('=');
// Check format
if(values.Length != 2)
{
throw(new FormatException( SR.ExceptionAttributeInvalidFormat));
}
// Check for empty name or value
values[0] = values[0].Trim();
values[1] = values[1].Trim();
if(values[0].Length == 0)
{
throw(new FormatException( SR.ExceptionAttributeInvalidFormat));
}
// Check if value already defined
foreach(object existingAttributeName in newAttributes.Keys)
{
string existingAttributeNameStr = existingAttributeName as string;
if (existingAttributeNameStr != null)
{
if (String.Compare(existingAttributeNameStr, values[0], StringComparison.OrdinalIgnoreCase) == 0)
{
throw(new FormatException( SR.ExceptionAttributeNameIsNotUnique(values[0] ) ) );
}
}
}
string newValue = values[1].Replace("\\x45", ",");
newAttributes[values[0]] = newValue.Replace("\\x46", "=");
}
}
properties = newAttributes;
this.Invalidate(true);
}
}
#endregion
#region IMapAreaAttributesutes Properties implementation
/// <summary>
/// Tooltip.
/// </summary>
[
SRCategory("CategoryAttributeMapArea"),
Bindable(true),
SRDescription("DescriptionAttributeToolTip"),
Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base),
#if !Microsoft_CONTROL
DefaultValue(""),
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public string ToolTip
{
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.ToolTip, value);
else
series.toolTip = value;
#if Microsoft_CONTROL
if(Chart != null && Chart.selection != null)
{
Chart.selection.enabledChecked = false;
}
#endif
}
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.ToolTip))
{
return (String)GetAttributeObject(CommonCustomProperties.ToolTip);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.ToolTip);
}
return series.toolTip;
}
}
else
{
return series.toolTip;
}
}
}
#if !Microsoft_CONTROL
/// <summary>
/// URL target of the area.
/// </summary>
[
SRCategory("CategoryAttributeMapArea"),
Bindable(true),
SRDescription("DescriptionAttributeUrl"),
DefaultValue(""),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute),
Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base)
#endif
]
public string Url
{
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.Url, value);
else
series.url = value;
}
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.Url))
{
return (String)GetAttributeObject(CommonCustomProperties.Url);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.Url);
}
return series.url;
}
}
else
{
return series.url;
}
}
}
/// <summary>
/// Other attributes of the area.
/// </summary>
[
SRCategory("CategoryAttributeMapArea"),
Bindable(true),
SRDescription("DescriptionAttributeMapAreaAttributes"),
DefaultValue(""),
PersistenceMode(PersistenceMode.Attribute),
Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base)
]
public string MapAreaAttributes
{
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.MapAreaAttributes, value);
else
series.mapAreaAttributes = value;
}
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MapAreaAttributes))
{
return (String)GetAttributeObject(CommonCustomProperties.MapAreaAttributes);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MapAreaAttributes);
}
return series.mapAreaAttributes;
}
}
else
{
return series.mapAreaAttributes;
}
}
}
/// <summary>
/// Gets or sets the postback value which can be processed on click event.
/// </summary>
/// <value>The value which is passed to click event as argument.</value>
[DefaultValue("")]
[SRCategory(SR.Keys.CategoryAttributeMapArea)]
[SRDescription(SR.Keys.DescriptionAttributePostBackValue)]
[Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base)]
public string PostBackValue
{
get
{
if (this.pointCustomProperties)
{
if (properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.PostBackValue))
{
return (String)GetAttributeObject(CommonCustomProperties.PostBackValue);
}
else
{
if (IsSerializing())
{
return "";
}
if (this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.PostBackValue);
}
return series.postbackValue;
}
}
else
{
return series.postbackValue;
}
}
set
{
if (this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.PostBackValue, value);
else
series.postbackValue = value;
}
}
#endif
/// <summary>
/// Replaces predefined keyword inside the string with their values.
/// </summary>
/// <param name="strOriginal">Original string with keywords.</param>
/// <returns>Modified string.</returns>
internal virtual string ReplaceKeywords(string strOriginal)
{
return strOriginal;
}
#endregion
#region Legend properties
/// <summary>
/// Indicates whether the item is shown in the legend.
/// </summary>
[
SRCategory("CategoryAttributeLegend"),
Bindable(true),
SRDescription("DescriptionAttributeShowInLegend"),
#if !Microsoft_CONTROL
DefaultValue(true),
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public bool IsVisibleInLegend
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.IsVisibleInLegend))
{
return (bool)GetAttributeObject(CommonCustomProperties.IsVisibleInLegend);
}
else
{
if(IsSerializing())
{
return true;
}
if(this.isEmptyPoint)
{
return (bool)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.IsVisibleInLegend);
}
return series.showInLegend;
}
}
else
{
return series.showInLegend;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.IsVisibleInLegend, value);
else
series.showInLegend = value;
this.Invalidate(true);
}
}
/// <summary>
/// Text of the item in the legend
/// </summary>
[
SRCategory("CategoryAttributeLegend"),
Bindable(true),
SRDescription("DescriptionAttributeLegendText"),
Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base),
#if !Microsoft_CONTROL
DefaultValue(""),
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public string LegendText
{
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LegendText, value);
else
series.legendText = value;
this.Invalidate(true);
}
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendText))
{
return (String)GetAttributeObject(CommonCustomProperties.LegendText);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendText);
}
return series.legendText;
}
}
else
{
return series.legendText;
}
}
}
/// <summary>
/// Tooltip of the item in the legend
/// </summary>
[
SRCategory("CategoryAttributeLegend"),
Bindable(true),
SRDescription("DescriptionAttributeLegendToolTip"),
Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base),
#if !Microsoft_CONTROL
DefaultValue(""),
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public string LegendToolTip
{
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LegendToolTip, value);
else
series.legendToolTip = value;
#if Microsoft_CONTROL
if(Chart != null && Chart.selection != null)
{
Chart.selection.enabledChecked = false;
}
#endif
}
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendToolTip))
{
return (String)GetAttributeObject(CommonCustomProperties.LegendToolTip);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendToolTip);
}
return series.legendToolTip;
}
}
else
{
return series.legendToolTip;
}
}
}
/// <summary>
/// Background color of the data point label.
/// </summary>
[
SRCategory("CategoryAttributeLabelAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeLabelBackColor"),
TypeConverter(typeof(ColorConverter)),
Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
DefaultValue(typeof(Color), ""),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public Color LabelBackColor
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelBackColor))
{
return (Color)GetAttributeObject(CommonCustomProperties.LabelBackColor);
}
else
{
if(IsSerializing())
{
return Color.Empty;
}
if(this.isEmptyPoint)
{
return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelBackColor);
}
#if Microsoft_CONTROL
if(SystemInformation.HighContrast && AccessibilityImprovements.Level3)
{
return SystemColors.Window;
}
#endif
return series.labelBackColor;
}
}
else
{
return series.labelBackColor;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LabelBackColor, value);
else
series.labelBackColor = value;
this.Invalidate(true);
}
}
/// <summary>
/// Border color of the data point label.
/// </summary>
[
SRCategory("CategoryAttributeLabelAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeBorderColor"),
TypeConverter(typeof(ColorConverter)),
Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
DefaultValue(typeof(Color), ""),
#if !Microsoft_CONTROL
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public Color LabelBorderColor
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelBorderColor))
{
return (Color)GetAttributeObject(CommonCustomProperties.LabelBorderColor);
}
else
{
if(IsSerializing())
{
return Color.Empty;
}
if(this.isEmptyPoint)
{
return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelBorderColor);
}
#if Microsoft_CONTROL
if(SystemInformation.HighContrast && AccessibilityImprovements.Level3)
{
return SystemColors.ActiveBorder;
}
#endif
return series.labelBorderColor;
}
}
else
{
return series.labelBorderColor;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LabelBorderColor, value);
else
series.labelBorderColor = value;
this.Invalidate(true);
}
}
/// <summary>
/// Border style of the label.
/// </summary>
[
SRCategory("CategoryAttributeLabelAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeLabelBorderDashStyle"),
#if !Microsoft_CONTROL
DefaultValue(ChartDashStyle.Solid),
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public ChartDashStyle LabelBorderDashStyle
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelBorderDashStyle))
{
return (ChartDashStyle)GetAttributeObject(CommonCustomProperties.LabelBorderDashStyle);
}
else
{
if(IsSerializing())
{
return ChartDashStyle.Solid;
}
if(this.isEmptyPoint)
{
return (ChartDashStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelBorderDashStyle);
}
return series.labelBorderDashStyle;
}
}
else
{
return series.labelBorderDashStyle;
}
}
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LabelBorderDashStyle, value);
else
series.labelBorderDashStyle = value;
this.Invalidate(true);
}
}
/// <summary>
/// Border width of the label.
/// </summary>
[
SRCategory("CategoryAttributeLabelAppearance"),
Bindable(true),
SRDescription("DescriptionAttributeBorderWidth"),
#if !Microsoft_CONTROL
DefaultValue(1),
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public int LabelBorderWidth
{
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelBorderWidth))
{
return (int)GetAttributeObject(CommonCustomProperties.LabelBorderWidth);
}
else
{
if(IsSerializing())
{
return 1;
}
if(this.isEmptyPoint)
{
return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelBorderWidth);
}
return series.labelBorderWidth;
}
}
else
{
return series.labelBorderWidth;
}
}
set
{
if(value < 0)
{
throw(new ArgumentOutOfRangeException("value", SR.ExceptionLabelBorderIsNotPositive));
}
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LabelBorderWidth, value);
else
series.labelBorderWidth = value;
this.Invalidate(true);
}
}
/// <summary>
/// Tooltip of the data point label.
/// </summary>
[
SRCategory("CategoryAttributeLabel"),
Bindable(true),
SRDescription("DescriptionAttributeLabelToolTip"),
Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base),
#if !Microsoft_CONTROL
DefaultValue(""),
PersistenceMode(PersistenceMode.Attribute)
#endif
]
public string LabelToolTip
{
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LabelToolTip, value);
else
series.labelToolTip = value;
#if Microsoft_CONTROL
if(Chart != null && Chart.selection != null)
{
Chart.selection.enabledChecked = false;
}
#endif
}
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelToolTip))
{
return (String)GetAttributeObject(CommonCustomProperties.LabelToolTip);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelToolTip);
}
return series.labelToolTip;
}
}
else
{
return series.labelToolTip;
}
}
}
#if !Microsoft_CONTROL
/// <summary>
/// URL target of the item in the legend.
/// </summary>
[
SRCategory("CategoryAttributeLegend"),
Bindable(true),
SRDescription("DescriptionAttributeLegendUrl"),
DefaultValue(""),
PersistenceMode(PersistenceMode.Attribute),
Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base),
SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")
]
public string LegendUrl
{
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LegendUrl, value);
else
series.legendUrl = value;
}
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendUrl))
{
return (String)GetAttributeObject(CommonCustomProperties.LegendUrl);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendUrl);
}
return series.legendUrl;
}
}
else
{
return series.legendUrl;
}
}
}
#endif
#if !Microsoft_CONTROL
/// <summary>
/// Other attributes of the legend map area.
/// </summary>
[
SRCategory("CategoryAttributeLegend"),
Bindable(true),
SRDescription("DescriptionAttributeMapAreaAttributes"),
DefaultValue(""),
PersistenceMode(PersistenceMode.Attribute),
Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base)
]
public string LegendMapAreaAttributes
{
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LegendMapAreaAttributes, value);
else
series.legendMapAreaAttributes = value;
}
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendMapAreaAttributes))
{
return (String)GetAttributeObject(CommonCustomProperties.LegendMapAreaAttributes);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendMapAreaAttributes);
}
return series.legendMapAreaAttributes;
}
}
else
{
return series.legendMapAreaAttributes;
}
}
}
/// <summary>
/// Gets or sets the postback value which can be processed on click event.
/// </summary>
/// <value>The value which is passed to click event as argument.</value>
[DefaultValue("")]
[SRCategory("CategoryAttributeLegend")]
[SRDescription(SR.Keys.DescriptionAttributePostBackValue)]
[Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base)]
public string LegendPostBackValue
{
get
{
if (this.pointCustomProperties)
{
if (properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendPostBackValue))
{
return (String)GetAttributeObject(CommonCustomProperties.LegendPostBackValue);
}
else
{
if (IsSerializing())
{
return "";
}
if (this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendPostBackValue);
}
return series.legendPostbackValue;
}
}
else
{
return series.legendPostbackValue;
}
}
set
{
if (this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LegendPostBackValue, value);
else
series.legendPostbackValue = value;
}
}
#endif // !Microsoft_CONTROL
#if !Microsoft_CONTROL
/// <summary>
/// URL target of the data point label.
/// </summary>
[
SRCategory("CategoryAttributeMapArea"),
Bindable(true),
SRDescription("DescriptionAttributeUrl"),
DefaultValue(""),
PersistenceMode(PersistenceMode.Attribute),
Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base),
SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")
]
public string LabelUrl
{
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LabelUrl, value);
else
series.labelUrl = value;
}
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelUrl))
{
return (String)GetAttributeObject(CommonCustomProperties.LabelUrl);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelUrl);
}
return series.labelUrl;
}
}
else
{
return series.labelUrl;
}
}
}
#endif //if !Microsoft_CONTROL
#if !Microsoft_CONTROL
/// <summary>
/// Other attributes of the data point label.
/// </summary>
[
SRCategory("CategoryAttributeLabel"),
Bindable(true),
SRDescription("DescriptionAttributeMapAreaAttributes"),
DefaultValue(""),
PersistenceMode(PersistenceMode.Attribute)
]
public string LabelMapAreaAttributes
{
set
{
if(this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LabelMapAreaAttributes, value);
else
series.labelMapAreaAttributes = value;
}
get
{
if(this.pointCustomProperties)
{
if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelMapAreaAttributes))
{
return (String)GetAttributeObject(CommonCustomProperties.LabelMapAreaAttributes);
}
else
{
if(IsSerializing())
{
return "";
}
if(this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelMapAreaAttributes);
}
return series.labelMapAreaAttributes;
}
}
else
{
return series.labelMapAreaAttributes;
}
}
}
/// <summary>
/// Gets or sets the postback value which can be processed on click event.
/// </summary>
/// <value>The value which is passed to click event as argument.</value>
[DefaultValue("")]
[SRCategory("CategoryAttributeLabel")]
[SRDescription(SR.Keys.DescriptionAttributePostBackValue)]
[Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base)]
public string LabelPostBackValue
{
get
{
if (this.pointCustomProperties)
{
if (properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelPostBackValue))
{
return (String)GetAttributeObject(CommonCustomProperties.LabelPostBackValue);
}
else
{
if (IsSerializing())
{
return "";
}
if (this.isEmptyPoint)
{
return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelPostBackValue);
}
return series.labelPostbackValue;
}
}
else
{
return series.labelPostbackValue;
}
}
set
{
if (this.pointCustomProperties)
SetAttributeObject(CommonCustomProperties.LabelPostBackValue, value);
else
series.labelPostbackValue = value;
}
}
#endif // !Microsoft_CONTROL
#endregion
#region Serialization control
private bool CheckIfSerializationRequired(CommonCustomProperties attribute)
{
if(this is DataPoint)
{
return IsCustomPropertySet(attribute);
}
else
{
object attr1 = this.GetAttributeObject(attribute);
object attr2 = Series.defaultCustomProperties.GetAttributeObject(attribute);
if(attr1 == null || attr2 == null)
{
return false;
}
return ! attr1.Equals(attr2);
}
}
private void ResetProperty(CommonCustomProperties attribute)
{
if(this is DataPoint)
{
DeleteCustomProperty(attribute);
}
else
{
this.SetAttributeObject(attribute, Series.defaultCustomProperties.GetAttributeObject(attribute));
}
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLabel()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.Label);
else
return !String.IsNullOrEmpty(series.label);
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeAxisLabel()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.AxisLabel);
else
return !String.IsNullOrEmpty(series.axisLabel);
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLabelFormat()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.LabelFormat);
else
return !String.IsNullOrEmpty(series.labelFormat);
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeIsValueShownAsLabel()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.IsValueShownAsLabel);
else
return series.showLabelAsValue != false;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeColor()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.Color);
else
return series.color != Color.Empty;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeBorderColor()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.BorderColor);
else
return series.borderColor != Color.Empty;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeBorderDashStyle()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.BorderDashStyle);
else
return series.borderDashStyle != ChartDashStyle.Solid;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeBorderWidth()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.BorderWidth);
else
return series.borderWidth != 1;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeMarkerBorderWidth()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.MarkerBorderWidth);
else
return series.markerBorderWidth != 1;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeBackImage()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.BackImage);
else
return !String.IsNullOrEmpty(series.backImage);
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeBackImageWrapMode()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.BackImageWrapMode);
else
return series.backImageWrapMode != ChartImageWrapMode.Tile;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeBackImageTransparentColor()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.BackImageTransparentColor);
else
return series.backImageTransparentColor != Color.Empty;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeBackImageAlignment()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.BackImageAlignment);
else
return series.backImageAlignment != ChartImageAlignmentStyle.TopLeft;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeBackGradientStyle()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.BackGradientStyle);
else
return series.backGradientStyle != GradientStyle.None;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeBackSecondaryColor()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.BackSecondaryColor);
else
return series.backSecondaryColor != Color.Empty;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeBackHatchStyle()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.BackHatchStyle);
else
return series.backHatchStyle != ChartHatchStyle.None;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeFont()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.Font);
else
{
return series.font != series.FontCache.DefaultFont;
}
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLabelForeColor()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.LabelForeColor);
else
return series.fontColor != Color.Black;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLabelAngle()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.LabelAngle);
else
return series.fontAngle != 0f;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeMarkerStyle()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.MarkerStyle);
else
return series.markerStyle != MarkerStyle.None;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeMarkerSize()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.MarkerSize);
else
return series.markerSize != 5;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeMarkerImage()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.MarkerImage);
else
return !String.IsNullOrEmpty(series.markerImage);
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeMarkerImageTransparentColor()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.MarkerImageTransparentColor);
else
return series.markerImageTransparentColor != Color.Empty;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeMarkerColor()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.MarkerColor);
else
return series.markerColor != Color.Empty;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeMarkerBorderColor()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.MarkerBorderColor);
else
return series.markerBorderColor != Color.Empty;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeToolTip()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.ToolTip);
else
return !String.IsNullOrEmpty(series.toolTip);
}
#if !Microsoft_CONTROL
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeUrl()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.Url);
else
return !String.IsNullOrEmpty(series.url);
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeMapAreaAttributes()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.MapAreaAttributes);
else
return !String.IsNullOrEmpty(series.mapAreaAttributes);
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializePostBackValue()
{
if (this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.PostBackValue);
else
return !String.IsNullOrEmpty(series.postbackValue);
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLegendUrl()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.LegendUrl);
else
return !String.IsNullOrEmpty(series.legendUrl);
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLegendMapAreaAttributes()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.LegendMapAreaAttributes);
else
return !String.IsNullOrEmpty(series.legendMapAreaAttributes);
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLabelUrl()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.LabelUrl);
else
return !String.IsNullOrEmpty(series.labelUrl);
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLabelMapAreaAttributes()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.LabelMapAreaAttributes);
else
return !String.IsNullOrEmpty(series.labelMapAreaAttributes);
}
#endif // !Microsoft_CONTROL
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeIsVisibleInLegend()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.IsVisibleInLegend);
else
return series.showInLegend != true;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLegendText()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.LegendText);
else
return !String.IsNullOrEmpty(series.legendText);
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLegendToolTip()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.LegendToolTip);
else
return !String.IsNullOrEmpty(series.legendToolTip);
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLabelToolTip()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.LabelToolTip);
else
return !String.IsNullOrEmpty(series.labelToolTip);
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLabelBackColor()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.LabelBackColor);
else
return series.labelBackColor != Color.Empty;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLabelBorderColor()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.LabelBorderColor);
else
return series.labelBorderColor != Color.Empty;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLabelBorderDashStyle()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.LabelBorderDashStyle);
else
return series.labelBorderDashStyle != ChartDashStyle.Solid;
}
/// <summary>
/// Returns true if property should be serialized.
/// </summary>
internal bool ShouldSerializeLabelBorderWidth()
{
if(this.pointCustomProperties)
return CheckIfSerializationRequired(CommonCustomProperties.LabelBorderWidth);
else
return series.labelBorderWidth != 1;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetLabel()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.Label);
else
series.label = "";
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetAxisLabel()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.AxisLabel);
else
series.axisLabel = "";
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetLabelFormat()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.LabelFormat);
else
series.labelFormat = "";
}
/// <summary>
/// Resets property to its default value.
/// </summary>
public void ResetIsValueShownAsLabel()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.IsValueShownAsLabel);
else
series.IsValueShownAsLabel = false;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetColor()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.Color);
else
series.color = Color.Empty;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetBorderColor()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.BorderColor);
else
series.borderColor = Color.Empty;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetBorderDashStyle()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.BorderDashStyle);
else
series.borderDashStyle = ChartDashStyle.Solid;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetBorderWidth()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.BorderWidth);
else
series.borderWidth = 1;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetMarkerBorderWidth()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.MarkerBorderWidth);
else
series.markerBorderWidth = 1;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetBackImage()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.BackImage);
else
series.backImage = "";
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetBackImageWrapMode()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.BackImageWrapMode);
else
series.backImageWrapMode = ChartImageWrapMode.Tile;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetBackImageTransparentColor()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.BackImageTransparentColor);
else
series.backImageTransparentColor = Color.Empty;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetBackSecondaryColor()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.BackSecondaryColor);
else
series.backSecondaryColor = Color.Empty;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetBackHatchStyle()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.BackHatchStyle);
else
series.backHatchStyle = ChartHatchStyle.None;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetFont()
{
if (this.pointCustomProperties)
ResetProperty(CommonCustomProperties.Font);
else
{
series.font = series.FontCache.DefaultFont;
}
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetLabelAngle()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.LabelAngle);
else
series.fontAngle = 0;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetMarkerStyle()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.MarkerStyle);
else
series.markerStyle = MarkerStyle.None;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetMarkerSize()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.MarkerSize);
else
series.markerSize = 5;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetMarkerImage()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.MarkerImage);
else
series.markerImage = "";
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetMarkerImageTransparentColor()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.MarkerImageTransparentColor);
else
series.markerImageTransparentColor = Color.Empty;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetMarkerColor()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.MarkerColor);
else
series.markerColor = Color.Empty;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetMarkerBorderColor()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.MarkerBorderColor);
else
series.markerBorderColor = Color.Empty;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetToolTip()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.ToolTip);
else
series.toolTip = "";
#if Microsoft_CONTROL
if(Chart != null && Chart.selection != null)
{
Chart.selection.enabledChecked = false;
}
#endif
}
#if !Microsoft_CONTROL
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetUrl()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.Url);
else
series.url = "";
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetMapAreaAttributes()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.MapAreaAttributes);
else
series.mapAreaAttributes = "";
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetPostBackValue()
{
if (this.pointCustomProperties)
ResetProperty(CommonCustomProperties.PostBackValue);
else
series.postbackValue = "";
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetLegendUrl()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.LegendUrl);
else
series.legendUrl = "";
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetLegendMapAreaAttributes()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.LegendMapAreaAttributes);
else
series.legendMapAreaAttributes = "";
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetLabelUrl()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.LabelUrl);
else
series.labelUrl = "";
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetLabelMapAreaAttributes()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.LabelMapAreaAttributes);
else
series.labelMapAreaAttributes = "";
}
#endif // !Microsoft_CONTROL
/// <summary>
/// Resets property to its default value.
/// </summary>
public void ResetIsVisibleInLegend()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.IsVisibleInLegend);
else
series.showInLegend = true;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetLegendText()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.LegendText);
else
series.legendText = "";
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetLegendToolTip()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.LegendToolTip);
else
series.legendToolTip = "";
#if Microsoft_CONTROL
if(Chart != null && Chart.selection != null)
{
Chart.selection.enabledChecked = false;
}
#endif
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetLabelBackColor()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.LabelBackColor);
else
series.labelBackColor = Color.Empty;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetLabelBorderColor()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.LabelBorderColor);
else
series.labelBorderColor = Color.Empty;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetLabelBorderDashStyle()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.LabelBorderDashStyle);
else
series.labelBorderDashStyle = ChartDashStyle.Solid;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetLabelBorderWidth()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.LabelBorderWidth);
else
series.labelBorderWidth = 1;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
internal void ResetLabelToolTip()
{
if(this.pointCustomProperties)
ResetProperty(CommonCustomProperties.LabelToolTip);
else
series.labelToolTip = "";
#if Microsoft_CONTROL
if(Chart != null && Chart.selection != null)
{
Chart.selection.enabledChecked = false;
}
#endif
}
#endregion
#region Invalidating method
/// <summary>
/// Invalidate chart area.
/// </summary>
/// <param name="invalidateLegend">Invalidate legend area only.</param>
[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "This parameter is used when compiling for the Microsoft version of Chart")]
internal void Invalidate(bool invalidateLegend)
{
#if Microsoft_CONTROL
if(this.series != null)
{
series.Invalidate(true, invalidateLegend);
}
else
{
Series thisSeries = this as Series;
if (thisSeries != null)
{
thisSeries.Invalidate(true, invalidateLegend);
}
}
#endif
}
#endregion
}
/// <summary>
/// Class stores additional information about the data point in 3D space.
/// </summary>
internal class DataPoint3D
{
#region Fields
/// <summary>
/// Reference to the 2D data point object
/// </summary>
internal DataPoint dataPoint = null;
/// <summary>
/// Data point index.
/// </summary>
internal int index = 0;
/// <summary>
/// Point X position in relative coordinates.
/// </summary>
internal double xPosition = 0.0;
/// <summary>
/// Point Y position in relative coordinates.
/// </summary>
internal double yPosition = 0.0;
/// <summary>
/// Point X center position in relative coordinates. Used for side-by-side charts.
/// </summary>
internal double xCenterVal = 0.0;
/// <summary>
/// Point Z position in relative coordinates.
/// </summary>
internal float zPosition = 0f;
/// <summary>
/// Point width.
/// </summary>
internal double width = 0.0;
/// <summary>
/// Point height.
/// </summary>
internal double height = 0.0;
/// <summary>
/// Point depth.
/// </summary>
internal float depth = 0f;
/// <summary>
/// Indicates that point belongs to indexed series.
/// </summary>
internal bool indexedSeries = false;
#endregion
}
/// <summary>
/// Design-time representation of the CustomProperties.
/// This class is used instead of the string "CustomProperties"
/// property at design time and supports expandable list
/// of custom properties.
/// </summary>
[ TypeConverter(typeof(CustomPropertiesTypeConverter)) ]
[EditorBrowsable(EditorBrowsableState.Never)]
#if ASPPERM_35
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
#endif
public class CustomProperties
{
#region Fields
// Reference to the properties class
internal DataPointCustomProperties m_DataPointCustomProperties = null;
#endregion // Fields
#region Constructor
/// <summary>
/// Constructor
/// </summary>
/// <param name="properties">Attributes object.</param>
internal CustomProperties(DataPointCustomProperties properties)
{
this.m_DataPointCustomProperties = properties;
}
#endregion // Constructor
#region Properties
internal virtual DataPointCustomProperties DataPointCustomProperties
{
get
{
return this.m_DataPointCustomProperties;
}
set
{
this.m_DataPointCustomProperties = value;
}
}
#endregion //Properties
#region Methods
/// <summary>
/// Gets a comma separated string of user defined custom properties.
/// </summary>
/// <returns>Comma separated string of user defined custom properties.</returns>
internal virtual string GetUserDefinedCustomProperties()
{
return GetUserDefinedCustomProperties(true);
}
/// <summary>
/// Gets a comma separated string of user defined or non-user defined custom properties.
/// </summary>
/// <param name="userDefined">True if user defined properties must be returned.</param>
/// <returns>Comma separated string of user defined custom properties.</returns>
internal virtual string GetUserDefinedCustomProperties(bool userDefined)
{
// Get comma separated string of custom properties
string customAttribute = this.DataPointCustomProperties.CustomProperties;
string userDefinedCustomAttribute = string.Empty;
// Get custom attribute registry
CustomPropertyRegistry registry = (CustomPropertyRegistry)this.DataPointCustomProperties.Common.container.GetService(typeof(CustomPropertyRegistry));
// Replace commas in value string
customAttribute = customAttribute.Replace("\\,", "\\x45");
customAttribute = customAttribute.Replace("\\=", "\\x46");
// Split custom properties by commas into individual properties
if(customAttribute.Length > 0)
{
string[] nameValueStrings = customAttribute.Split(',');
foreach(string nameValue in nameValueStrings)
{
string[] values = nameValue.Split('=');
// Check format
if(values.Length != 2)
{
throw(new FormatException(SR.ExceptionAttributeInvalidFormat));
}
// Check for empty name or value
values[0] = values[0].Trim();
values[1] = values[1].Trim();
if(values[0].Length == 0)
{
throw(new FormatException(SR.ExceptionAttributeInvalidFormat));
}
// Check if attribute is registered or user defined
bool userDefinedAttribute = true;
foreach(CustomPropertyInfo info in registry.registeredCustomProperties)
{
if(string.Compare(info.Name, values[0], StringComparison.OrdinalIgnoreCase) == 0)
{
userDefinedAttribute = false;
}
}
// Copy attribute into the output string
if(userDefinedAttribute == userDefined)
{
if(userDefinedCustomAttribute.Length > 0)
{
userDefinedCustomAttribute += ", ";
}
string val = values[1].Replace("\\x45", ",");
val = val.Replace("\\x46", "=");
userDefinedCustomAttribute += values[0] + "=" + val;
}
}
}
return userDefinedCustomAttribute;
}
/// <summary>
/// Sets user defined custom properties without cleaning registered properties.
/// </summary>
/// <param name="val">New user defined properties.</param>
internal virtual void SetUserDefinedAttributes(string val)
{
// Get non-user defined custom properties
string properties = GetUserDefinedCustomProperties(false);
// Check if new string is empty
if(val.Length > 0)
{
// Add comma at the end
if(properties.Length > 0)
{
properties += ", ";
}
// Add new user defined properties
properties += val;
}
// Set new custom attribute string
this.DataPointCustomProperties.CustomProperties = properties;
}
#endregion // Methods
}
}
|