//-------------------------------------------------------------
//
// 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
}
}