//------------------------------------------------------------- // // Copyright © Microsoft Corporation. All Rights Reserved. // //------------------------------------------------------------- // @owner=alexgor, deliant //================================================================= // File: AxisConverter.cs // // Namespace: DataVisualization.Charting.Design // // Classes: AxisLabelDateValueConverter, AxisCrossingValueConverter // AxisMinMaxValueConverter, AxisMinMaxAutoValueConverter, // StripLineTitleAngleConverter // // Purpose: Converters for the Axis object properties. // // Reviewed: AG - August 7, 2002 // //=================================================================== #region Used Namespaces using System; using System.ComponentModel; using System.ComponentModel.Design; using System.Collections; using System.Globalization; using System.Reflection; #if Microsoft_CONTROL using System.Windows.Forms.DataVisualization.Charting; #else using System.Web; using System.Web.UI; using System.Web.UI.DataVisualization.Charting; using System.Web.UI.DataVisualization.Charting.Data; using System.Web.UI.DataVisualization.Charting.ChartTypes; #endif #endregion #if Microsoft_CONTROL namespace System.Windows.Forms.DataVisualization.Charting #else namespace System.Web.UI.DataVisualization.Charting #endif { /// /// Converts labels, grid and ticks start position to support dates format /// internal class AxisLabelDateValueConverter : DoubleConverter { #region Converter methods /// /// Convert Min and Max values to string if step type is set to one of the DateTime type /// /// Descriptor context. /// Culture information. /// Value to convert. /// Convertion destination type. /// Converted object. public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (context != null && context.Instance != null) { // Convert to string if (destinationType == typeof(string)) { DateTimeIntervalType intervalType = DateTimeIntervalType.Auto; double interval = 0; // Get IntervalType property using reflection PropertyInfo propertyInfo = context.Instance.GetType().GetProperty("IntervalType"); if(propertyInfo != null) { intervalType = (DateTimeIntervalType)propertyInfo.GetValue(context.Instance, null); } // Get Interval property using reflection propertyInfo = context.Instance.GetType().GetProperty("Interval"); if(propertyInfo != null) { interval = (double)propertyInfo.GetValue(context.Instance, null); } // Try to get interval information from the axis if(intervalType == DateTimeIntervalType.Auto) { // Get object's axis Axis axis = null; if(context.Instance is Axis) { axis = (Axis)context.Instance; } else { MethodInfo methodInfo = context.Instance.GetType().GetMethod("GetAxis"); if(methodInfo != null) { // Get axis object axis = (Axis)methodInfo.Invoke(context.Instance, null); } } // Get axis value type if(axis != null) { intervalType = axis.GetAxisIntervalType(); } } // Convert value to date/time string if(context.Instance.GetType() != typeof(StripLine) || interval == 0) { if(intervalType != DateTimeIntervalType.Number && intervalType != DateTimeIntervalType.Auto) { // Covert value to date/time if(intervalType < DateTimeIntervalType.Hours) { return DateTime.FromOADate((double)value).ToShortDateString(); } return DateTime.FromOADate((double)value).ToString("g", System.Globalization.CultureInfo.CurrentCulture); } } } } return base.ConvertTo(context, culture, value, destinationType); } /// /// Convert Min and Max values from string if step type is set to one of the DateTime type /// /// Descriptor context. /// Culture information. /// Value to convert from. /// Converted object. public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { object result = null; bool convertFromDate = false; string stringValue = value as string; // If context interface provided check if we are dealing with DateTime values if (context != null && context.Instance != null) { DateTimeIntervalType intervalType = DateTimeIntervalType.Auto; // Get intervalType property using reflection PropertyInfo propertyInfo = context.Instance.GetType().GetProperty("intervalType"); if(propertyInfo != null) { intervalType = (DateTimeIntervalType)propertyInfo.GetValue(context.Instance, null); } // Try to get interval information from the axis if(intervalType == DateTimeIntervalType.Auto) { // Get object's axis Axis axis = null; if(context.Instance is Axis) { axis = (Axis)context.Instance; } else { MethodInfo methodInfo = context.Instance.GetType().GetMethod("GetAxis"); if(methodInfo != null) { // Get axis object axis = (Axis)methodInfo.Invoke(context.Instance, null); } } // Get axis value type if(axis != null) { intervalType = axis.GetAxisIntervalType(); } } if (stringValue != null && intervalType != DateTimeIntervalType.Number && intervalType != DateTimeIntervalType.Auto) { convertFromDate = true; } } // Try to convert from double string try { result = base.ConvertFrom(context, culture, value); } catch (ArgumentException) { result = null; } catch (NotSupportedException) { result = null; } // Try to convert from date/time string if (stringValue != null && (convertFromDate || result == null)) { DateTime valueAsDate; bool parseSucceed = DateTime.TryParse(stringValue, CultureInfo.InvariantCulture, DateTimeStyles.None, out valueAsDate); if (parseSucceed) { // Succeded converting from date format return valueAsDate.ToOADate(); } } // Call base converter return base.ConvertFrom(context, culture, value); } #endregion } /// /// Converts crossing property of the axis. /// Possible values: double, date, "Auto", "Min", "Max" /// internal class AxisCrossingValueConverter : AxisMinMaxValueConverter { #region Converter methods /// /// Standart values supported - return true. /// /// Descriptor context. /// Standard values supported. public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return true; } /// /// Standart values are not exclusive - return false /// /// Descriptor context. /// Non exclusive standard values. public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return false; } /// /// Fill in the list of standart values. /// /// Descriptor context. /// Standart values collection. public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { ArrayList values = new ArrayList(); values.Add(Double.NaN); values.Add(Double.MinValue); values.Add(Double.MaxValue); return new StandardValuesCollection(values); } /// /// Convert crossing value to string. /// /// Descriptor context. /// Culture information. /// Value to convert. /// Convertion destination type. /// Converted object. public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { double doubleValue = (double)value; if (destinationType == typeof(string)) { if(Double.IsNaN(doubleValue)) { return Constants.AutoValue; } else if(doubleValue == Double.MinValue) { return Constants.MinValue; } else if(doubleValue == Double.MaxValue) { return Constants.MaxValue; } } // Call base class return base.ConvertTo(context, culture, value, destinationType); } /// /// Convert crossing values from string /// /// Descriptor context. /// Culture information. /// Value to convert from. /// Converted object. public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { // If converting from string value string crossingValue = value as string; if (crossingValue != null) { if (String.Compare(crossingValue, Constants.AutoValue, StringComparison.OrdinalIgnoreCase) == 0) { return Double.NaN; } else if (String.Compare(crossingValue, Constants.MinValue, StringComparison.OrdinalIgnoreCase) == 0) { return Double.MinValue; } else if (String.Compare(crossingValue, Constants.MaxValue, StringComparison.OrdinalIgnoreCase) == 0) { return Double.MaxValue; } } // Call base converter return base.ConvertFrom(context, culture, value); } #endregion } /// /// Converts min and max properties of the axis depending on the values type /// internal class AxisMinMaxValueConverter : DoubleConverter { #region Converter methods /// /// Convert Min and Max values to string if step type is set to one of the DateTime type /// /// Descriptor context. /// Culture information. /// Value to convert. /// Convertion destination type. /// Converted object. public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (context != null && context.Instance != null && context.Instance is Axis) { Axis axis = (Axis)context.Instance; if (destinationType == typeof(string)) { string strValue = DoubleDateNanValueConverter.ConvertDateTimeToString( (double)value, axis.GetAxisValuesType(), axis.InternalIntervalType); if (strValue != null) return strValue; } } return base.ConvertTo(context, culture, value, destinationType); } /// /// Convert Min and Max values from string if step type is set to one of the DateTime type /// /// Descriptor context. /// Culture information. /// Value to convert from. /// Converted object. public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { object result = null; bool convertFromDate = false; string stringValue = value as string; // If context interface provided check if we are dealing with DateTime values if (context != null && context.Instance != null && context.Instance is Axis) { Axis axis = (Axis)context.Instance; if (stringValue != null) { if (axis.InternalIntervalType == DateTimeIntervalType.Auto) { if (axis.GetAxisValuesType() == ChartValueType.DateTime || axis.GetAxisValuesType() == ChartValueType.Date || axis.GetAxisValuesType() == ChartValueType.Time || axis.GetAxisValuesType() == ChartValueType.DateTimeOffset) { convertFromDate = true; } } else { if (axis.InternalIntervalType != DateTimeIntervalType.Number) { convertFromDate = true; } } } } // Try to convert from double string try { result = base.ConvertFrom(context, culture, value); } catch (ArgumentException) { result = null; } catch (NotSupportedException) { result = null; } // Try to convert from date/time string if (stringValue != null && (convertFromDate || result == null)) { DateTime valueAsDate; bool parseSucceed = DateTime.TryParse(stringValue, CultureInfo.CurrentCulture, DateTimeStyles.None, out valueAsDate); if (parseSucceed) { return valueAsDate.ToOADate(); } } // Call base converter return base.ConvertFrom(context, culture, value); } #endregion } /// /// Converts maximum and minimum property of the axis. /// Possible values: double, date, "Auto", /// internal class AxisMinMaxAutoValueConverter : AxisMinMaxValueConverter { #region Converter methods /// /// Standart values supported - return true /// /// Descriptor context. /// Standard values supported. public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return true; } /// /// Standart values are not exclusive - return false /// /// Descriptor context. /// Non exclusive standard values. public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return false; } /// /// Fill in the list of data series names. /// /// Descriptor context. public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { ArrayList values = new ArrayList(); values.Add(Double.NaN); return new StandardValuesCollection(values); } /// /// Convert minimum or maximum value to string /// /// Descriptor context. /// Culture information. /// Value to convert. /// Convertion destination type. /// Converted object. public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { double doubleValue = (double)value; if (destinationType == typeof(string)) { if(Double.IsNaN(doubleValue)) { return Constants.AutoValue; } } // Call base class return base.ConvertTo(context, culture, value, destinationType); } /// /// Convert minimum or maximum values from string /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { // If converting from string value string crossingValue = value as string; if (crossingValue != null) { if (String.Compare(crossingValue, Constants.AutoValue, StringComparison.OrdinalIgnoreCase) == 0) { return Double.NaN; } } // Call base converter return base.ConvertFrom(context, culture, value); } #endregion } /// /// Converts title angle property of the strip line /// Possible values: 0, 90, 180, 270 /// internal class StripLineTitleAngleConverter : Int32Converter { #region Converter methods /// /// Standart values supported - return true /// /// Descriptor context. /// Standard values supported. public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return true; } /// /// Standart values are not exclusive - return false /// /// Descriptor context. /// Non exclusive standard values. public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return true; } /// /// Fill in the list of data series names. /// /// Descriptor context. public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { ArrayList values = new ArrayList(); values.Add(0); values.Add(90); values.Add(180); values.Add(270); return new StandardValuesCollection(values); } #endregion } /// /// Converts Interval and IntervalOffset properties of the axis /// internal class AxisIntervalValueConverter : DoubleConverter { #region Converter methods /// /// Inicates that "NotSet" option is available /// internal bool hideNotSet = true; /// /// Standart values supported - return true. /// /// Descriptor context. /// Standard values supported. public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return true; } /// /// Standart values are not exclusive - return false /// /// Descriptor context. /// Non exclusive standard values. public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return false; } /// /// Fill in the list of standart values. /// /// Descriptor context. /// Standart values collection. public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { ArrayList values = new ArrayList(); if(!hideNotSet) { values.Add(Double.NaN); } values.Add(0.0); return new StandardValuesCollection(values); } /// /// Convert crossing value to string. /// /// Descriptor context. /// Culture information. /// Value to convert. /// Convertion destination type. /// Converted object. public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { double doubleValue = (double)value; if (destinationType == typeof(string)) { if(Double.IsNaN(doubleValue)) { return Constants.NotSetValue; } else if(doubleValue == 0.0) { return Constants.AutoValue; } } // Call base class return base.ConvertTo(context, culture, value, destinationType); } /// /// Convert crossing values from string /// /// Descriptor context. /// Culture information. /// Value to convert from. /// Converted object. public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { // If converting from string value string crossingValue = value as string; if (crossingValue != null) { if (String.Compare(crossingValue, Constants.AutoValue, StringComparison.OrdinalIgnoreCase) == 0) { return 0.0; } else if (String.Compare(crossingValue, Constants.NotSetValue, StringComparison.OrdinalIgnoreCase) == 0) { return Double.NaN; } } // Call base converter return base.ConvertFrom(context, culture, value); } #endregion } /// /// Converts Interval and IntervalOffset properties of the label style, tick marks and grids /// internal class AxisElementIntervalValueConverter : AxisIntervalValueConverter { /// /// Show the NotSet option for interval /// public AxisElementIntervalValueConverter() { base.hideNotSet = false; } } }