//------------------------------------------------------------- // // Copyright © Microsoft Corporation. All Rights Reserved. // //------------------------------------------------------------- // @owner=alexgor, deliant //================================================================= // File: ChartSerializer.cs // // Namespace: System.Web.UI.WebControls[Windows.Forms].Charting // // Classes: ChartSerializer // // Purpose: Serialization saves the state of the chart and also // provides the ability to load the serialized data back // into the chart. All chart properties can be persisted, // including the chart's data. // // ChartSerializer class only provides serialization API // for the user and actual serialization is performed by // XmlFormatSerializer or BinaryFormatserializer classes // depending on the Format property. // // Reviewed: AG - Jul 31, 2002 // GS - Aug 7, 2002 // AG - Microsoft 15, 2007 // //=================================================================== #region Used namespaces using System; using System.IO; using System.Xml; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; #if Microsoft_CONTROL 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; #else using System.Web.UI.DataVisualization.Charting; using System.Web.UI.DataVisualization.Charting.Utilities; #endif #endregion #if Microsoft_CONTROL namespace System.Windows.Forms.DataVisualization.Charting #else namespace System.Web.UI.DataVisualization.Charting #endif { #region Serialization enumeration /// /// An enumeration of the formats of the chart serializer. /// public enum SerializationFormat { /// /// XML serializer format. /// Xml, /// /// Binary serializer format. /// Binary } /// /// An enumeration of chart serializable content definition flags /// [Flags] public enum SerializationContents { /// /// Default content. /// Default = 1, /// /// Serialize only series data. /// Data = 2, /// /// Serialize chart visual appearance (e.g. Colors, Line Styles). /// Appearance = 4, /// /// All content is serialized. /// All = Default | Data | Appearance } #endregion /// /// ChartSerializer class provides chart serialization. /// [ SRDescription("DescriptionAttributeChartSerializer_ChartSerializer"), DefaultProperty("Format"), ] #if ASPPERM_35 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] #endif public class ChartSerializer { #region Private fields // Reference to the service container private IServiceContainer _serviceContainer = null; // Reference to the chart object private Chart _chart = null; // Reference to the serializer object private SerializerBase _serializer = new XmlFormatSerializer(); // Format of the serializer in use private SerializationFormat _format = SerializationFormat.Xml; // Serialization content private SerializationContents _content = SerializationContents .Default; #endregion #region Constructors and Service Provider methods /// /// Default constructor is unavailable /// private ChartSerializer() { } /// /// Internal constructor /// /// Service container reference. internal ChartSerializer(IServiceContainer container) { if(container == null) { throw(new ArgumentNullException(SR.ExceptionInvalidServiceContainer)); } _serviceContainer = container; } /// /// Returns ChartSerializer service object /// /// Requested service type. /// ChartSerializer service object. internal object GetService(Type serviceType) { if(serviceType == typeof(ChartSerializer)) { return this; } throw (new ArgumentException( SR.ExceptionChartSerializerUnsupportedType( serviceType.ToString()))); } #endregion #region Public properties /// /// Gets or sets the serializable content. /// [ SRCategory("CategoryAttributeMisc"), DefaultValue(typeof(SerializationContents ), "Default"), SRDescription("DescriptionAttributeChartSerializer_Content") ] public SerializationContents Content { get { return _content; } set { // Set content value _content = value; // Automatically set SerializableContent and NonSerializableContent properties SetSerializableContent(); } } /// /// Gets or sets the format used to serialize the chart data. /// [ SRCategory("CategoryAttributeMisc"), DefaultValue(typeof(SerializationFormat), "Xml"), SRDescription("DescriptionAttributeChartSerializer_Format") ] public SerializationFormat Format { get { return _format; } set { if(_format != value) { _format = value; // Create new serializer object SerializerBase newSerializer = null; if(_format == SerializationFormat.Binary) { newSerializer = new BinaryFormatSerializer(); } else { newSerializer = new XmlFormatSerializer(); } // Copy serializer settings newSerializer.IsUnknownAttributeIgnored = _serializer.IsUnknownAttributeIgnored; newSerializer.NonSerializableContent = _serializer.NonSerializableContent; newSerializer.IsResetWhenLoading = _serializer.IsResetWhenLoading; newSerializer.SerializableContent = _serializer.SerializableContent; _serializer = newSerializer; } } } /// /// Gets or sets a flag which indicates whether object properties are reset to default /// values before loading. /// [ SRCategory("CategoryAttributeMisc"), DefaultValue(true), SRDescription("DescriptionAttributeChartSerializer_ResetWhenLoading") ] public bool IsResetWhenLoading { get { return _serializer.IsResetWhenLoading; } set { _serializer.IsResetWhenLoading = value; } } /// /// Gets or sets a flag which indicates whether unknown XML properties and elements will be /// ignored without throwing an exception. /// [ SRCategory("CategoryAttributeMisc"), DefaultValue(false), SRDescription("DescriptionAttributeChartSerializer_IgnoreUnknownXmlAttributes") ] public bool IsUnknownAttributeIgnored { get { return _serializer.IsUnknownAttributeIgnored; } set { _serializer.IsUnknownAttributeIgnored = value; } } /// /// Gets or sets a flag which indicates whether chart /// serializer is working in template creation mode. /// [ SRCategory("CategoryAttributeMisc"), DefaultValue(false), SRDescription("DescriptionAttributeChartSerializer_TemplateMode") ] public bool IsTemplateMode { get { return _serializer.IsTemplateMode; } set { _serializer.IsTemplateMode = value; } } /// /// Gets or sets the chart properties that can be serialized. /// Comma separated list of serializable (Save/Load/Reset) properties. /// "ClassName.PropertyName,[ClassName.PropertyName]". /// [ SRCategory("CategoryAttributeMisc"), DefaultValue(""), SRDescription("DescriptionAttributeChartSerializer_SerializableContent") ] public string SerializableContent { get { return _serializer.SerializableContent; } set { _serializer.SerializableContent = value; } } /// /// Gets or sets the chart properties that will not be serialized. /// Comma separated list of non-serializable (Save/Load/Reset) properties. /// "ClassName.PropertyName,[ClassName.PropertyName]". /// [ SRCategory("CategoryAttributeMisc"), DefaultValue(""), SRDescription("DescriptionAttributeChartSerializer_NonSerializableContent") ] public string NonSerializableContent { get { return _serializer.NonSerializableContent; } set { _serializer.NonSerializableContent = value; } } #endregion #region Public methods /// /// This method resets all properties of the chart to default values. By setting Content or /// SerializableContent/NonSerializableContent properties, specific set of /// properties can be reset. /// public void Reset() { // Set serializing flag if(GetChartObject() != null) { GetChartObject().serializing = true; GetChartObject().serializationStatus = SerializationStatus.Resetting; } // Reset properties _serializer.ResetObjectProperties(GetChartObject()); // Clear serializing flag if(GetChartObject() != null) { GetChartObject().serializing = false; GetChartObject().serializationStatus = SerializationStatus.None; } } /// /// This method saves all properties of the chart into a file. By setting Content or /// SerializableContent/NonSerializableContent properties, specific set of /// properties can be saved. /// /// The file name used to write the data. public void Save(string fileName) { //Check arguments if (fileName == null) throw new ArgumentNullException("fileName"); // Set serializing flag if(GetChartObject() != null) { GetChartObject().serializing = true; GetChartObject().serializationStatus = SerializationStatus.Saving; //GetChartObject().BeginInit(); } // Reset all auto-detected properties values GetChartObject().ResetAutoValues(); // Serialize chart data _serializer.Serialize(GetChartObject(), fileName); // Clear serializing flag if(GetChartObject() != null) { GetChartObject().serializing = false; GetChartObject().serializationStatus = SerializationStatus.None; //GetChartObject().EndInit(); } } /// /// This method saves all properties of the chart into a stream. By setting Content or /// SerializableContent/NonSerializableContent properties, specific set of /// properties can be saved. /// /// The stream where to save the data. public void Save(Stream stream) { //Check arguments if (stream == null) throw new ArgumentNullException("stream"); // Set serializing flag if(GetChartObject() != null) { GetChartObject().serializing = true; GetChartObject().serializationStatus = SerializationStatus.Saving; //GetChartObject().BeginInit(); } // Reset all auto-detected properties values GetChartObject().ResetAutoValues(); // Serialize chart data _serializer.Serialize(GetChartObject(), stream); // Clear serializing flag if(GetChartObject() != null) { GetChartObject().serializing = false; GetChartObject().serializationStatus = SerializationStatus.None; //GetChartObject().EndInit(); } } /// /// This method saves all properties of the chart into an XML writer. By setting Content or /// SerializableContent/NonSerializableContent properties, specific set of /// properties can be saved. /// /// XML writer to save the data. public void Save(XmlWriter writer) { //Check arguments if (writer == null) throw new ArgumentNullException("writer"); // Set serializing flag if(GetChartObject() != null) { GetChartObject().serializing = true; GetChartObject().serializationStatus = SerializationStatus.Saving; //GetChartObject().BeginInit(); } // Reset all auto-detected properties values GetChartObject().ResetAutoValues(); // Serialize chart data _serializer.Serialize(GetChartObject(), writer); // Clear serializing flag if(GetChartObject() != null) { GetChartObject().serializing = false; GetChartObject().serializationStatus = SerializationStatus.None; //GetChartObject().EndInit(); } } /// /// This method saves all properties of the chart into a text writer. By setting Content or /// SerializableContent/NonSerializableContent properties, specific set of /// properties can be saved. /// /// Text writer to save the data. public void Save(TextWriter writer) { //Check arguments if (writer == null) throw new ArgumentNullException("writer"); // Set serializing flag if(GetChartObject() != null) { GetChartObject().serializing = true; GetChartObject().serializationStatus = SerializationStatus.Saving; //GetChartObject().BeginInit(); } // Reset all auto-detected properties values GetChartObject().ResetAutoValues(); // Serialize chart data _serializer.Serialize(GetChartObject(), writer); // Clear serializing flag if(GetChartObject() != null) { GetChartObject().serializing = false; GetChartObject().serializationStatus = SerializationStatus.None; //GetChartObject().EndInit(); } } /// /// This method loads all properties of the chart from a file. By setting Content or /// SerializableContent/NonSerializableContent properties, specific set of /// properties can be loaded. /// /// The file to load the data from. public void Load(string fileName) { //Check arguments if (fileName == null) throw new ArgumentNullException("fileName"); // Set serializing flag if(GetChartObject() != null) { GetChartObject().serializing = true; GetChartObject().serializationStatus = SerializationStatus.Loading; } _serializer.Deserialize(GetChartObject(), fileName); // Clear serializing flag if(GetChartObject() != null) { GetChartObject().serializing = false; GetChartObject().serializationStatus = SerializationStatus.None; } } /// /// This method loads all properties of the chart from a stream. By setting Content or /// SerializableContent/NonSerializableContent properties, specific set of /// properties can be loaded. /// /// The stream to load the data from. public void Load(Stream stream) { //Check arguments if (stream == null) throw new ArgumentNullException("stream"); // Set serializing flag if(GetChartObject() != null) { GetChartObject().serializing = true; GetChartObject().serializationStatus = SerializationStatus.Loading; } _serializer.Deserialize(GetChartObject(), stream); // Clear serializing flag if(GetChartObject() != null) { GetChartObject().serializing = false; GetChartObject().serializationStatus = SerializationStatus.None; } } /// /// This method loads all properties of the chart from an XML reader. By setting Content or /// SerializableContent/NonSerializableContent properties, specific set of /// properties can be loaded. /// /// The XML reader to load the data from. public void Load(XmlReader reader) { //Check arguments if (reader == null) throw new ArgumentNullException("reader"); // Set serializing flag if(GetChartObject() != null) { GetChartObject().serializing = true; GetChartObject().serializationStatus = SerializationStatus.Loading; } _serializer.Deserialize(GetChartObject(), reader); // Clear serializing flag if(GetChartObject() != null) { GetChartObject().serializing = false; GetChartObject().serializationStatus = SerializationStatus.None; } } /// /// This method loads all properties of the chart from the text reader. By setting Content or /// SerializableContent/NonSerializableContent properties, specific set of /// properties can be loaded. /// /// The text reader to load the data from. public void Load(TextReader reader) { //Check arguments if (reader == null) throw new ArgumentNullException("reader"); // Set serializing flag if(GetChartObject() != null) { GetChartObject().serializing = true; GetChartObject().serializationStatus = SerializationStatus.Loading; } _serializer.Deserialize(GetChartObject(), reader); // Clear serializing flag if(GetChartObject() != null) { GetChartObject().serializing = false; GetChartObject().serializationStatus = SerializationStatus.None; } } #endregion #region Protected helper methods /// /// Sets SerializableContent and NonSerializableContent properties /// depending on the flags in the Content property. /// internal void SetSerializableContent() { // Reset content definition strings this.SerializableContent = ""; this.NonSerializableContent = ""; // Loop through all enumeration flags Array enumValues = Enum.GetValues(typeof(SerializationContents )); foreach(object flagObject in enumValues) { if(flagObject is SerializationContents ) { // Check if flag currently set SerializationContents flag = (SerializationContents )flagObject; if((this.Content & flag) == flag && flag != SerializationContents .All && this.Content != SerializationContents .All) { // Add comma at the end of existing string if(this.NonSerializableContent.Length != 0) { this.NonSerializableContent += ", "; } // Add serializable class/properties names this.NonSerializableContent += GetContentString(flag, false); this.NonSerializableContent = this.NonSerializableContent.TrimStart(','); // Add comma at the end of existing string if(this.SerializableContent.Length != 0) { this.SerializableContent += ", "; } // Add serializable class/properties names this.SerializableContent += GetContentString(flag, true); this.SerializableContent = this.SerializableContent.TrimStart(','); } } } } /// /// Return a serializable or non serializable class/properties names /// for the specific flag. /// /// Serializable content /// True - get serializable string, False - non serializable. /// Serializable or non serializable string with class/properties names. protected string GetContentString(SerializationContents content, bool serializable) { switch(content) { case(SerializationContents .All): return ""; case(SerializationContents .Default): return ""; case(SerializationContents .Data): if(serializable) { return "Chart.BuildNumber, " + "Chart.Series, " + "Series.Points, " + "Series.Name, " + "DataPoint.XValue, " + "DataPoint.YValues," + "DataPoint.LabelStyle," + "DataPoint.AxisLabel," + "DataPoint.LabelFormat," + "DataPoint.IsEmpty, " + "Series.YValuesPerPoint, " + "Series.IsXValueIndexed, " + "Series.XValueType, " + "Series.YValueType"; } return ""; case(SerializationContents .Appearance): if(serializable) { return "Chart.BuildNumber, " + "*.Name*, " + "*.Fore*, " + "*.Back*, " + "*.Border*, " + "*.Line*, " + "*.Frame*, " + "*.PageColor*, " + "*.SkinStyle*, " + "*.Palette, " + "*.PaletteCustomColors, " + "*.Font*, " + "*.*Font, " + "*.Color, " + "*.Shadow*, " + "*.MarkerColor, " + "*.MarkerStyle, " + "*.MarkerSize, " + "*.MarkerBorderColor, " + "*.MarkerImage, " + "*.MarkerImageTransparentColor, " + "*.LabelBackColor, " + "*.LabelBorder*, " + "*.Enable3D, " + "*.IsRightAngleAxes, " + "*.IsClustered, " + "*.LightStyle, " + "*.Perspective, " + "*.Inclination, " + "*.Rotation, " + "*.PointDepth, " + "*.PointGapDepth, " + "*.WallWidth"; } return ""; default: throw (new InvalidOperationException(SR.ExceptionChartSerializerContentFlagUnsupported)); } } /// /// Returns chart object for serialization. /// /// Chart object. internal Chart GetChartObject() { if(_chart == null) { _chart = (Chart)_serviceContainer.GetService(typeof(Chart)); } return _chart; } #endregion } }