1237 lines
35 KiB
C#
1237 lines
35 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Drawing.Design;
|
|
using System.Windows.Forms;
|
|
using DevComponents.DotNetBar.Charts.Primitives;
|
|
using DevComponents.DotNetBar.Charts.Style;
|
|
|
|
namespace DevComponents.DotNetBar.Charts
|
|
{
|
|
/// <summary>
|
|
/// Represents a base chart.
|
|
/// </summary>
|
|
[TypeConverter(typeof(BlankExpandableObjectConverter))]
|
|
public class BaseChart : ChartContainer
|
|
{
|
|
#region Static variables
|
|
|
|
// DNB base color palettes
|
|
|
|
static public Color[] PaletteLight = new Color[] {
|
|
ColorFactory.GetColor(136, 189, 230), ColorFactory.GetColor(251, 178, 88),
|
|
ColorFactory.GetColor(144, 205, 151), ColorFactory.GetColor(246, 170, 201),
|
|
ColorFactory.GetColor(191, 165, 84), ColorFactory.GetColor(188, 153, 199),
|
|
ColorFactory.GetColor(237, 221, 70), ColorFactory.GetColor(240, 126, 110),
|
|
ColorFactory.GetColor(140, 140, 140), };
|
|
|
|
static public Color[] PaletteMedium = new Color[] {
|
|
ColorFactory.GetColor(93, 165, 218), ColorFactory.GetColor(250, 164, 58),
|
|
ColorFactory.GetColor(96, 189, 104), ColorFactory.GetColor(241, 124, 176),
|
|
ColorFactory.GetColor(178, 145, 47), ColorFactory.GetColor(178, 118, 178),
|
|
ColorFactory.GetColor(222, 207, 63), ColorFactory.GetColor(241, 88, 84),
|
|
ColorFactory.GetColor(77, 77, 77), };
|
|
|
|
static public Color[] PaletteDark = new Color[] {
|
|
ColorFactory.GetColor(38, 93, 171), ColorFactory.GetColor(223, 92, 36),
|
|
ColorFactory.GetColor(5, 151, 72), ColorFactory.GetColor(229, 18, 111),
|
|
ColorFactory.GetColor(157, 114, 42), ColorFactory.GetColor(123, 58, 150),
|
|
ColorFactory.GetColor(199, 180, 46), ColorFactory.GetColor(203, 32, 39),
|
|
ColorFactory.GetColor(0, 0, 0), };
|
|
|
|
// Excel 2016 colors palettes
|
|
|
|
static public Color[] PaletteColor1 = new Color[] {
|
|
ColorFactory.GetColor(79, 129, 189), // Medium Blue
|
|
ColorFactory.GetColor(192, 80, 77), // Red
|
|
ColorFactory.GetColor(155, 187, 89), // Green
|
|
ColorFactory.GetColor(128, 100, 162), // Purple
|
|
ColorFactory.GetColor(75, 172, 198), // Light Blue
|
|
ColorFactory.GetColor(247, 150, 70), }; // Orange
|
|
|
|
static public Color[] PaletteColor2 = new Color[] {
|
|
ColorFactory.GetColor(79, 129, 180), // Medium Blue
|
|
ColorFactory.GetColor(155, 187, 89), // Green
|
|
ColorFactory.GetColor(75, 172, 198), // Light Blue
|
|
ColorFactory.GetColor(44, 76, 116), // Dark Blue
|
|
ColorFactory.GetColor(95, 117, 48), // Dark Green
|
|
ColorFactory.GetColor(39, 106, 124), }; // Dark Cyan
|
|
|
|
static public Color[] PaletteColor3 = new Color[] {
|
|
ColorFactory.GetColor(192, 80, 77), // Red
|
|
ColorFactory.GetColor(128, 100, 162), // Purple
|
|
ColorFactory.GetColor(247, 150, 70), // Orange
|
|
ColorFactory.GetColor(119, 44, 42), // Dark Red
|
|
ColorFactory.GetColor(77, 59, 98), // Dark Purple
|
|
ColorFactory.GetColor(182, 87, 8), }; // Dark Orange
|
|
|
|
static public Color[] PaletteColor4 = new Color[] {
|
|
ColorFactory.GetColor(247, 150, 70), // Orange
|
|
ColorFactory.GetColor(75, 172, 198), // Light Blue
|
|
ColorFactory.GetColor(128, 100, 162), // Purple
|
|
ColorFactory.GetColor(182, 87, 8), // Dark Orange
|
|
ColorFactory.GetColor(39, 106, 124), // Dark Cyan
|
|
ColorFactory.GetColor(77, 59, 98), }; // Dark Purple
|
|
|
|
// Monochrome
|
|
|
|
static public Color[] PaletteMonoBlue = new Color[] {
|
|
ColorFactory.GetColor(56, 93, 138), ColorFactory.GetColor(66, 109, 161),
|
|
ColorFactory.GetColor(75, 123, 180), ColorFactory.GetColor(115, 148, 197),
|
|
ColorFactory.GetColor(161, 180, 212), ColorFactory.GetColor(194, 205, 225), };
|
|
|
|
static public Color[] PaletteMonoRed = new Color[] {
|
|
ColorFactory.GetColor(140, 56, 54), ColorFactory.GetColor(164, 67, 64),
|
|
ColorFactory.GetColor(183, 76, 73), ColorFactory.GetColor(200, 161, 160),
|
|
ColorFactory.GetColor(214, 180, 212), ColorFactory.GetColor(226, 194, 194), };
|
|
|
|
static public Color[] PaletteMonoGreen = new Color[] {
|
|
ColorFactory.GetColor(113, 137, 63), ColorFactory.GetColor(132, 159, 75),
|
|
ColorFactory.GetColor(148, 178, 85), ColorFactory.GetColor(169, 195, 121),
|
|
ColorFactory.GetColor(192, 210, 164), ColorFactory.GetColor(213, 224, 196), };
|
|
|
|
static public Color[] PaletteMonoPurple = new Color[] {
|
|
ColorFactory.GetColor(92, 71, 118), ColorFactory.GetColor(108, 84, 138),
|
|
ColorFactory.GetColor(122, 95, 154), ColorFactory.GetColor(148, 128, 174),
|
|
ColorFactory.GetColor(179, 168, 196), ColorFactory.GetColor(205, 198, 215), };
|
|
|
|
static public Color[] PaletteMonoTeal = new Color[] {
|
|
ColorFactory.GetColor(53, 125, 145), ColorFactory.GetColor(63, 146, 169),
|
|
ColorFactory.GetColor(71, 164, 189), ColorFactory.GetColor(112, 183, 205),
|
|
ColorFactory.GetColor(160, 202, 217), ColorFactory.GetColor(193, 219, 229), };
|
|
|
|
static public Color[] PaletteMonoOrange = new Color[] {
|
|
ColorFactory.GetColor(182, 109, 49), ColorFactory.GetColor(211, 127, 58),
|
|
ColorFactory.GetColor(236, 143, 66), ColorFactory.GetColor(248, 165, 110),
|
|
ColorFactory.GetColor(249, 190, 158), ColorFactory.GetColor(251, 211, 193), };
|
|
|
|
static public Color[] PaletteMonoGray = new Color[] {
|
|
ColorFactory.GetColor(95, 95, 95), ColorFactory.GetColor(179, 179, 179),
|
|
ColorFactory.GetColor(137, 137, 137), ColorFactory.GetColor(33, 33, 33),
|
|
ColorFactory.GetColor(218, 218, 218), ColorFactory.GetColor(170, 170, 170), };
|
|
|
|
// Palette groups
|
|
|
|
static public Color[][] PaletteGroups = new Color[][] {
|
|
PaletteColor1, PaletteColor2, PaletteColor3, PaletteColor4,
|
|
|
|
PaletteMonoBlue, PaletteMonoRed, PaletteMonoGreen,
|
|
PaletteMonoPurple, PaletteMonoTeal, PaletteMonoOrange, PaletteMonoGray,
|
|
|
|
PaletteLight, PaletteMedium, PaletteDark, };
|
|
|
|
#endregion
|
|
|
|
#region Private variables
|
|
|
|
private States _States;
|
|
|
|
private object _DataSource;
|
|
private string _DataMember;
|
|
private DataBinder _DataBinder;
|
|
|
|
private string _DataPropertyNameSeries;
|
|
private string _DataPropertyNameX;
|
|
private CustomCollection<string> _DataPropertyNamesY;
|
|
|
|
private ChartBaseSeriesCollection _BaseSeries;
|
|
|
|
private object _BoundSource;
|
|
|
|
private List<ChartLegendItem> _LegendData;
|
|
|
|
private PaletteGroup _PaletteGroup = PaletteGroup.Color1;
|
|
private Color[] _CustomPalette;
|
|
|
|
private int _SeriesPointCount;
|
|
private int _SeriesLayoutCount;
|
|
|
|
private SeriesDisplayOrder _SeriesDisplayOrder = SeriesDisplayOrder.NotSet;
|
|
|
|
#endregion
|
|
|
|
public BaseChart()
|
|
{
|
|
InitDefaultStates();
|
|
|
|
VScrollBar.Inverted = true;
|
|
}
|
|
|
|
#region InitDefaultStates
|
|
|
|
private void InitDefaultStates()
|
|
{
|
|
SetState(States.SeriesRangeChanged, true);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public properties
|
|
|
|
#region AutoGenSeriesCollection
|
|
|
|
///<summary>
|
|
/// Gets or sets whether series definitions are automatically generated.
|
|
/// from the associated bound data.
|
|
///</summary>
|
|
[DefaultValue(false), Category("Data")]
|
|
[Description("Indicates whether series definitions are automatically generated from the associated bound data.")]
|
|
public bool AutoGenSeriesCollection
|
|
{
|
|
get { return (TestState(States.AutoGenSeriesCollection)); }
|
|
|
|
set
|
|
{
|
|
if (value != AutoGenSeriesCollection)
|
|
{
|
|
SetState(States.AutoGenSeriesCollection, value);
|
|
|
|
OnPropertyChangedEx("AutoGenSeriesCollection", VisualChangeType.Layout);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region BaseSeries
|
|
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public ChartBaseSeriesCollection BaseSeries
|
|
{
|
|
get
|
|
{
|
|
if (_BaseSeries == null)
|
|
_BaseSeries = GetBaseSeries();
|
|
|
|
return (_BaseSeries);
|
|
}
|
|
|
|
set { _BaseSeries = value; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetBaseSeries
|
|
|
|
internal virtual ChartBaseSeriesCollection GetBaseSeries()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region CustomPalette
|
|
|
|
///<summary>
|
|
/// Gets or sets the custom palette for the chart.
|
|
///</summary>
|
|
[DefaultValue(null), Category("Appearance")]
|
|
[Description("Indicates the custom palette for the chart.")]
|
|
public virtual Color[] CustomPalette
|
|
{
|
|
get { return (_CustomPalette); }
|
|
|
|
set
|
|
{
|
|
_CustomPalette = value;
|
|
|
|
OnPropertyChangedEx("CustomPalette", VisualChangeType.Layout);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region DataMember
|
|
|
|
///<summary>
|
|
/// Gets or sets the name of the list or table
|
|
/// in the data source that the Chart is bound to.
|
|
///</summary>
|
|
[DefaultValue(null), Category("Data")]
|
|
[Description("Indicates the name of the list or table in the data source that the Chart is bound to.")]
|
|
public string DataMember
|
|
{
|
|
get { return (_DataMember); }
|
|
|
|
set
|
|
{
|
|
if (_DataBinder != null)
|
|
_DataBinder.Clear();
|
|
|
|
_DataMember = value;
|
|
|
|
NeedToUpdateBindings = true;
|
|
|
|
OnPropertyChangedEx("DataMember", VisualChangeType.Layout);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region DataSource
|
|
|
|
///<summary>
|
|
/// Gets or sets the data source that the Chart is bound to
|
|
///</summary>
|
|
[DefaultValue(null), AttributeProvider(typeof(IListSource)), Category("Data")]
|
|
[Description("Indicates the data source that the Chart is bound to.")]
|
|
public object DataSource
|
|
{
|
|
get { return (_DataSource); }
|
|
|
|
set
|
|
{
|
|
if (_DataBinder != null)
|
|
_DataBinder.Clear();
|
|
|
|
_DataSource = value;
|
|
|
|
NeedToUpdateBindings = true;
|
|
|
|
OnPropertyChangedEx("DataSource", VisualChangeType.Layout);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region DataPropertyNameSeries
|
|
|
|
///<summary>
|
|
/// Gets or sets the default name of the data field to which the Series Name is bound.
|
|
///</summary>
|
|
[DefaultValue(null), Category("Data")]
|
|
[Description("Indicates the default name of the data field to which the Series Name is bound.")]
|
|
public string DataPropertyNameSeries
|
|
{
|
|
get { return (_DataPropertyNameSeries); }
|
|
|
|
set
|
|
{
|
|
if (value != _DataPropertyNameSeries)
|
|
{
|
|
_DataPropertyNameSeries = value;
|
|
|
|
NeedToUpdateBindings = true;
|
|
|
|
InvalidateLayout();
|
|
|
|
OnPropertyChangedEx("DataPropertyNameSeries", VisualChangeType.Layout);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region DataPropertyNameX
|
|
|
|
///<summary>
|
|
/// Gets or sets the default name of the data field to which the X-Axis data is bound.
|
|
///</summary>
|
|
[DefaultValue(null), Category("Data")]
|
|
[Description("Indicates the default name of the data field to which the X-Axis data is bound.")]
|
|
public string DataPropertyNameX
|
|
{
|
|
get { return (_DataPropertyNameX); }
|
|
|
|
set
|
|
{
|
|
if (value != _DataPropertyNameX)
|
|
{
|
|
_DataPropertyNameX = value;
|
|
|
|
NeedToUpdateBindings = true;
|
|
|
|
InvalidateLayout();
|
|
|
|
OnPropertyChangedEx("DataPropertyNameX", VisualChangeType.Layout);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region DataPropertyNamesY
|
|
|
|
///<summary>
|
|
/// Gets or sets the default names of the data fields to which the Y-Axis data is bound.
|
|
///</summary>
|
|
[DefaultValue(null), Category("Data")]
|
|
[Description("Indicates the default names of the data fields to which the Y-Axis data is bound.")]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
|
[Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version= 2.0.0.0, Culture=neutral," +
|
|
"PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
|
|
public CustomCollection<string> DataPropertyNamesY
|
|
{
|
|
get
|
|
{
|
|
if (_DataPropertyNamesY == null)
|
|
{
|
|
_DataPropertyNamesY = new CustomCollection<string>();
|
|
|
|
_DataPropertyNamesY.CollectionChanged += DataPropertyNamesY_CollectionChanged;
|
|
}
|
|
|
|
return (_DataPropertyNamesY);
|
|
}
|
|
|
|
set
|
|
{
|
|
if (value != _DataPropertyNamesY)
|
|
{
|
|
if (_DataPropertyNamesY != null)
|
|
{
|
|
_DataPropertyNamesY.Clear();
|
|
|
|
_DataPropertyNamesY.CollectionChanged -= DataPropertyNamesY_CollectionChanged;
|
|
}
|
|
|
|
_DataPropertyNamesY = value;
|
|
|
|
if (_DataPropertyNamesY != null)
|
|
_DataPropertyNamesY.CollectionChanged += DataPropertyNamesY_CollectionChanged;
|
|
|
|
OnPropertyChangedEx("DataPropertyNamesY", Style.VisualChangeType.Layout);
|
|
}
|
|
}
|
|
}
|
|
|
|
void DataPropertyNamesY_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
|
{
|
|
NeedToUpdateBindings = true;
|
|
|
|
InvalidateLayout();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region EnableDiscreteBoundItems
|
|
|
|
/// <summary>
|
|
/// Gets or sets whether discrete bound item suport is enabled.
|
|
/// This property permits each List bound item to be a separate object type.
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool EnableDiscreteBoundItems
|
|
{
|
|
get { return (TestState(States.EnableDiscreteBoundItems)); }
|
|
|
|
set
|
|
{
|
|
if (value != EnableDiscreteBoundItems)
|
|
{
|
|
SetState(States.EnableDiscreteBoundItems, value);
|
|
|
|
OnPropertyChangedEx("EnableDiscreteBoundItems", VisualChangeType.Layout);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region PaletteGroup
|
|
|
|
/// <summary>
|
|
/// Gets or sets the palette color group to use (Light/Medium/Dark/Color1/MonoBlue/etc).
|
|
/// </summary>
|
|
[DefaultValue(PaletteGroup.Color1), Category("Appearance")]
|
|
[Description("Indicates the palette color group to use (Light/Medium/Dark/Color1/MonoBlue/etc.).")]
|
|
public virtual PaletteGroup PaletteGroup
|
|
{
|
|
get { return (_PaletteGroup); }
|
|
|
|
set
|
|
{
|
|
if (value != _PaletteGroup)
|
|
{
|
|
_PaletteGroup = value;
|
|
|
|
OnPropertyChangedEx("PaletteGroup", VisualChangeType.Layout);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ReversePaletteColors
|
|
|
|
///<summary>
|
|
/// Gets or sets whether default palette colors are utilized in reverse order.
|
|
///</summary>
|
|
[DefaultValue(false), Category("Behavior")]
|
|
[Description("Indicates whether default palette colors are utilized in reverse order.")]
|
|
public virtual bool ReversePaletteColors
|
|
{
|
|
get { return (TestState(States.ReversePaletteColors)); }
|
|
|
|
set
|
|
{
|
|
if (value != ReversePaletteColors)
|
|
{
|
|
SetState(States.ReversePaletteColors, value);
|
|
|
|
OnPropertyChangedEx("ReversePaletteColors", VisualChangeType.Layout);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region SeriesDisplayOrder
|
|
|
|
/// <summary>
|
|
/// Gets or sets the order in which the charts series are displayed.
|
|
/// </summary>
|
|
[DefaultValue(SeriesDisplayOrder.NotSet), Category("Display")]
|
|
[Description("Indicates the order in which the charts series are displayed.")]
|
|
public SeriesDisplayOrder SeriesDisplayOrder
|
|
{
|
|
get { return (_SeriesDisplayOrder); }
|
|
|
|
set
|
|
{
|
|
if (value != _SeriesDisplayOrder)
|
|
{
|
|
_SeriesDisplayOrder = value;
|
|
|
|
OnPropertyChangedEx("SeriesDisplayOrder", VisualChangeType.Layout);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region SeriesRangeChanged
|
|
|
|
/// <summary>
|
|
/// Signals to the chart that an underlying chart series data has changed.
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool SeriesRangeChanged
|
|
{
|
|
get { return (TestState(States.SeriesRangeChanged)); }
|
|
set { SetState(States.SeriesRangeChanged, value); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Internal properties
|
|
|
|
#region DataBinder
|
|
|
|
internal DataBinder DataBinder
|
|
{
|
|
get
|
|
{
|
|
if (_DataBinder == null)
|
|
_DataBinder = new DataBinder(this);
|
|
|
|
return (_DataBinder);
|
|
}
|
|
|
|
set
|
|
{
|
|
if (_DataBinder != null)
|
|
_DataBinder.Clear();
|
|
|
|
_DataBinder = value;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region LegendData
|
|
|
|
internal List<ChartLegendItem> LegendData
|
|
{
|
|
get { return (_LegendData); }
|
|
set { _LegendData = value; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region NeedToUpdateBindings
|
|
|
|
internal bool NeedToUpdateBindings
|
|
{
|
|
get { return (TestState(States.NeedToUpdateBindings)); }
|
|
set { SetState(States.NeedToUpdateBindings, value); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region SeriesLayoutCount
|
|
|
|
internal int SeriesLayoutCount
|
|
{
|
|
get { return (_SeriesLayoutCount); }
|
|
set { _SeriesLayoutCount = value; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region SeriesPointCount
|
|
|
|
internal int SeriesPointCount
|
|
{
|
|
get { return (_SeriesPointCount); }
|
|
set { _SeriesPointCount = value; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region VisibleSeriesCount
|
|
|
|
internal int VisibleSeriesCount
|
|
{
|
|
get
|
|
{
|
|
int count = 0;
|
|
|
|
ChartBaseSeriesCollection baseSeries = BaseSeries;
|
|
|
|
foreach (BaseSeries series in baseSeries)
|
|
{
|
|
if (series.Visible == true)
|
|
count++;
|
|
}
|
|
|
|
return (count);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region DisplayedSeriesCount
|
|
|
|
internal int DisplayedSeriesCount
|
|
{
|
|
get
|
|
{
|
|
int count = 0;
|
|
|
|
ChartBaseSeriesCollection baseSeries = BaseSeries;
|
|
|
|
foreach (BaseSeries series in baseSeries)
|
|
{
|
|
if (series.Visible == true)
|
|
{
|
|
if (Legend.Visible == false ||
|
|
(series.ShowCheckBoxInLegend == false || series.CheckedInLegend == true))
|
|
{
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return (count);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region RenderFrameBackground
|
|
|
|
protected virtual void RenderFrameBackground(
|
|
Graphics g, Rectangle bounds, ContainerVisualStyle cstyle)
|
|
{
|
|
ChartControl chartControl = ChartControl;
|
|
|
|
if (chartControl.DoPreRenderFrameBackgroundEvent(g, this, bounds) == false)
|
|
{
|
|
cstyle.RenderBackground(g, bounds);
|
|
|
|
chartControl.DoPostRenderFrameBackgroundEvent(g, this, bounds);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region UpdateDataBindings
|
|
|
|
protected void UpdateDataBindings()
|
|
{
|
|
if (NeedToUpdateBindings == true)
|
|
{
|
|
NeedToUpdateBindings = false;
|
|
|
|
DataBinder.Clear();
|
|
|
|
object boundSource = null;
|
|
|
|
if (DataSource != null)
|
|
_BoundSource = DataBinder.DataConnect(DataSource, DataMember);
|
|
|
|
if (boundSource != null)
|
|
ChartControl.DoChartDataBindingCompleteEvent(this, boundSource);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region FinalizeDataBindings
|
|
|
|
protected void FinalizeDataBindings()
|
|
{
|
|
if (_BoundSource != null)
|
|
{
|
|
ChartControl.DoChartDataBindingCompleteEvent(this, _BoundSource);
|
|
|
|
_BoundSource = null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region DataCompare
|
|
|
|
internal int DataCompare(object value1, object value2)
|
|
{
|
|
if (value1 == value2)
|
|
return (0);
|
|
|
|
if (value1 == null)
|
|
return (-1);
|
|
|
|
if (value2 == null)
|
|
return (1);
|
|
|
|
if (value1.GetType() == value2.GetType())
|
|
{
|
|
IComparable icompa = value1 as IComparable;
|
|
|
|
if (icompa == null)
|
|
throw new Exception("Values must support IComparable");
|
|
|
|
return (icompa.CompareTo(value2));
|
|
}
|
|
|
|
double v1 = Convert.ToDouble(value1);
|
|
double v2 = Convert.ToDouble(value2);
|
|
|
|
return (v1.CompareTo(v2));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetAutoGenSeriesType
|
|
|
|
internal virtual SeriesType GetAutoGenSeriesType()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetAutoGenSeriesNameCount
|
|
|
|
internal virtual int GetAutoGenSeriesNameCount()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetNewSeries
|
|
|
|
internal virtual BaseSeries GetNewSeries()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region AddChartSeries
|
|
|
|
internal virtual void AddChartSeries(BaseSeries series)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetPaletteColor
|
|
|
|
/// <summary>
|
|
/// Gets the series default Palette color.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public Color GetPaletteColor(int index)
|
|
{
|
|
return (GetPaletteColor(index, PaletteGroup));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the series default Palette color from the
|
|
/// specified PaletteGroup.
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <param name="group"></param>
|
|
/// <returns></returns>
|
|
public Color GetPaletteColor(int index, PaletteGroup group)
|
|
{
|
|
if (group == PaletteGroup.NotSet)
|
|
group = PaletteGroup.Color1;
|
|
|
|
Color[] palette = (group == PaletteGroup.Custom)
|
|
? CustomPalette : PaletteGroups[(int)group];
|
|
|
|
return (GetPaletteColor(index, palette, ReversePaletteColors));
|
|
}
|
|
|
|
internal Color GetPaletteColor(
|
|
int index, Color[] palette, bool reversePaletteColors)
|
|
{
|
|
if (palette == null || palette.Length == 0)
|
|
palette = PaletteColor1;
|
|
|
|
int n = index % palette.Length;
|
|
|
|
if (reversePaletteColors == true)
|
|
n = (palette.Length - n - 1);
|
|
|
|
index = index % (palette.Length * 3);
|
|
|
|
Color color = palette[n];
|
|
|
|
if (color.IsEmpty == false)
|
|
{
|
|
n = index / palette.Length;
|
|
|
|
if (n > 0)
|
|
{
|
|
int z = (int)(Math.Ceiling(n * .75d));
|
|
|
|
float fn = (float)(z) * .05f;
|
|
|
|
if ((n % 2) == 0)
|
|
color = ControlPaint.Light(color, fn);
|
|
else
|
|
color = ControlPaint.Dark(color, fn);
|
|
}
|
|
}
|
|
|
|
return (color);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetShadowBounds
|
|
|
|
internal Rectangle GetShadowBounds(Rectangle bounds)
|
|
{
|
|
bounds.Width -= 3;
|
|
bounds.Height -= 3;
|
|
|
|
return (bounds);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Style handling
|
|
|
|
#region ApplyStyles
|
|
|
|
public override void ApplyStyles(BaseVisualStyle style)
|
|
{
|
|
base.ApplyStyles(style);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ClearEffectiveStyles
|
|
|
|
protected override void ClearEffectiveStyles()
|
|
{
|
|
base.ClearEffectiveStyles();
|
|
|
|
ChartBaseSeriesCollection baseSeries = BaseSeries;
|
|
|
|
foreach (BaseSeries series in baseSeries)
|
|
series.InvalidateStyle();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region ILegendData
|
|
|
|
#region GetLegendData
|
|
|
|
public override List<ChartLegendItem> GetLegendData()
|
|
{
|
|
LegendData = new List<ChartLegendItem>();
|
|
|
|
ChartBaseSeriesCollection baseSeries = BaseSeries;
|
|
|
|
foreach (BaseSeries series in baseSeries)
|
|
{
|
|
if (series.Visible == true)
|
|
{
|
|
List<ChartLegendItem> items = series.GetLegendItems();
|
|
|
|
if (items != null && items.Count > 0)
|
|
_LegendData.AddRange(items);
|
|
}
|
|
}
|
|
|
|
return (_LegendData);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region OnSeriesCheckStateChanged
|
|
|
|
internal virtual void OnSeriesCheckStateChanged(string property)
|
|
{
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Copy/CopyTo
|
|
|
|
public override ChartVisualElement Copy()
|
|
{
|
|
BaseChart copy = new BaseChart();
|
|
|
|
CopyTo(copy);
|
|
|
|
return (copy);
|
|
}
|
|
|
|
public override void CopyTo(ChartVisualElement copy)
|
|
{
|
|
BaseChart c = copy as BaseChart;
|
|
|
|
if (c != null)
|
|
{
|
|
base.CopyTo(c);
|
|
|
|
c.AutoGenSeriesCollection = AutoGenSeriesCollection;
|
|
|
|
if (_CustomPalette != null)
|
|
{
|
|
c.CustomPalette = new Color[CustomPalette.Length];
|
|
|
|
CustomPalette.CopyTo(c.CustomPalette, 0);
|
|
}
|
|
|
|
c.DataMember = DataMember;
|
|
c.DataSource = DataSource;
|
|
c.DataPropertyNameSeries = DataPropertyNameSeries;
|
|
c.DataPropertyNameX = DataPropertyNameX;
|
|
c.DataPropertyNamesY = DataPropertyNamesY;
|
|
c.EnableDiscreteBoundItems = EnableDiscreteBoundItems;
|
|
|
|
c.PaletteGroup = PaletteGroup;
|
|
c.ReversePaletteColors = ReversePaletteColors;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetSerialData
|
|
|
|
internal override SerialElementCollection GetSerialData(string serialName)
|
|
{
|
|
SerialElementCollection sec = new SerialElementCollection();
|
|
|
|
if (serialName != null)
|
|
{
|
|
if (serialName.Equals("") == true)
|
|
serialName = "BaseChart";
|
|
|
|
sec.AddStartElement(serialName);
|
|
}
|
|
|
|
sec.AddValue("AutoGenSeriesCollection", AutoGenSeriesCollection, false);
|
|
|
|
if (_CustomPalette != null && _CustomPalette.Length > 0)
|
|
{
|
|
sec.AddStartElement("CustomPalette count=\"" + _CustomPalette.Length + "\"");
|
|
|
|
foreach (Color color in _CustomPalette)
|
|
sec.AddValue("PaletteColor", color);
|
|
|
|
sec.AddEndElement("CustomPalette");
|
|
}
|
|
|
|
sec.AddDataValue("DataSource", DataSource, null);
|
|
sec.AddValue("DataMember", DataMember, null);
|
|
|
|
sec.AddValue("DataPropertyNameSeries", DataPropertyNameSeries, null);
|
|
sec.AddValue("DataPropertyNameX", DataPropertyNameX, null);
|
|
|
|
if (_DataPropertyNamesY != null && _DataPropertyNamesY.Count > 0)
|
|
{
|
|
sec.AddStartElement("DataPropertyNamesYs count=\"" + _DataPropertyNamesY.Count + "\"");
|
|
|
|
foreach (string s in _DataPropertyNamesY)
|
|
sec.AddValue("DataPropertyNamesY", s);
|
|
|
|
sec.AddEndElement("DataPropertyNamesYs");
|
|
}
|
|
|
|
sec.AddValue("EnableDiscreteBoundItems", EnableDiscreteBoundItems, false);
|
|
|
|
sec.AddValue("PaletteGroup", PaletteGroup, PaletteGroup.Color1);
|
|
sec.AddValue("ReversePaletteColors", ReversePaletteColors, false);
|
|
|
|
sec.AddElement(base.GetSerialData(null));
|
|
|
|
if (serialName != null)
|
|
sec.AddEndElement(serialName);
|
|
|
|
return (sec);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region PutSerialData
|
|
|
|
#region ProcessValue
|
|
|
|
internal override void ProcessValue(SerialElement se)
|
|
{
|
|
switch (se.Name)
|
|
{
|
|
case "AutoGenSeriesCollection":
|
|
AutoGenSeriesCollection = bool.Parse(se.StringValue);
|
|
break;
|
|
|
|
case "DataMember":
|
|
DataMember = se.StringValue;
|
|
break;
|
|
|
|
case "DataSource":
|
|
DataSource = se.DataValue;
|
|
break;
|
|
|
|
case "DataPropertyNameSeries":
|
|
DataPropertyNameSeries = se.StringValue;
|
|
break;
|
|
|
|
case "DataPropertyNameX":
|
|
DataPropertyNameX = se.StringValue;
|
|
break;
|
|
|
|
case "DataPropertyNamesY":
|
|
DataPropertyNamesY.Add(se.StringValue);
|
|
break;
|
|
|
|
case "EnableDiscreteBoundItems":
|
|
EnableDiscreteBoundItems = bool.Parse(se.StringValue);
|
|
break;
|
|
|
|
case "PaletteColor":
|
|
CustomPalette[se.ValueIndex] = se.GetValueColor();
|
|
break;
|
|
|
|
case "PaletteGroup":
|
|
PaletteGroup = (PaletteGroup)se.GetValueEnum(typeof(PaletteGroup));
|
|
break;
|
|
|
|
case "ReversePaletteColors":
|
|
ReversePaletteColors = bool.Parse(se.StringValue);
|
|
break;
|
|
|
|
default:
|
|
base.ProcessValue(se);
|
|
break;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ProcessCollection
|
|
|
|
internal override void ProcessCollection(SerialElement se)
|
|
{
|
|
SerialElementCollection sec = se.Sec;
|
|
|
|
switch (se.Name)
|
|
{
|
|
case "ChartContainers":
|
|
sec.PutSerialData(this);
|
|
break;
|
|
|
|
case "CustomPalette":
|
|
if (se.ArrayCount > 0)
|
|
{
|
|
CustomPalette = new Color[se.ArrayCount];
|
|
|
|
sec.PutSerialData(this);
|
|
}
|
|
break;
|
|
|
|
case "DataPropertyNamesYs":
|
|
if (se.ArrayCount > 0)
|
|
{
|
|
DataPropertyNamesY = new CustomCollection<string>(se.ArrayCount);
|
|
|
|
sec.PutSerialData(this);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
base.ProcessCollection(se);
|
|
break;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region States
|
|
|
|
[Flags]
|
|
private enum States : uint
|
|
{
|
|
AutoGenSeriesCollection = (1U << 0),
|
|
EnableDiscreteBoundItems = (1U << 1),
|
|
ReversePaletteColors = (1U << 2),
|
|
|
|
//------------
|
|
|
|
SeriesRangeChanged = (1U << 3),
|
|
NeedToUpdateBindings = (1U << 4),
|
|
IsSelected = (1U << 5),
|
|
}
|
|
|
|
#region TestState
|
|
|
|
private bool TestState(States state)
|
|
{
|
|
return ((_States & state) == state);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region SetState
|
|
|
|
private void SetState(States state, bool value)
|
|
{
|
|
if (value == true)
|
|
_States |= state;
|
|
else
|
|
_States &= ~state;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region IDisposable
|
|
|
|
public override void Dispose()
|
|
{
|
|
base.Dispose();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
#region enums
|
|
|
|
#region PaletteGroup
|
|
|
|
public enum PaletteGroup
|
|
{
|
|
/// <summary>
|
|
/// NotSet.
|
|
/// </summary>
|
|
NotSet = -1,
|
|
|
|
/// <summary>
|
|
/// Colorful 'Color1' toned pallete
|
|
/// </summary>
|
|
Color1,
|
|
|
|
/// <summary>
|
|
/// Colorful 'Color2' toned pallete
|
|
/// </summary>
|
|
Color2,
|
|
|
|
/// <summary>
|
|
/// Colorful 'Color3' toned pallete
|
|
/// </summary>
|
|
Color3,
|
|
|
|
/// <summary>
|
|
/// Colorful 'Color4' toned pallete
|
|
/// </summary>
|
|
Color4,
|
|
|
|
/// <summary>
|
|
/// Monochromatic 'Blue' toned pallete
|
|
/// </summary>
|
|
MonoBlue,
|
|
|
|
/// <summary>
|
|
/// Monochromatic 'Red' toned pallete
|
|
/// </summary>
|
|
MonoRed,
|
|
|
|
/// <summary>
|
|
/// Monochromatic 'Green' toned pallete
|
|
/// </summary>
|
|
MonoGreen,
|
|
|
|
/// <summary>
|
|
/// Monochromatic 'Purple' toned pallete
|
|
/// </summary>
|
|
MonoPurple,
|
|
|
|
/// <summary>
|
|
/// Monochromatic 'Teal' toned pallete
|
|
/// </summary>
|
|
MonoTeal,
|
|
|
|
/// <summary>
|
|
/// Monochromatic 'Orange' toned pallete
|
|
/// </summary>
|
|
MonoOrange,
|
|
|
|
/// <summary>
|
|
/// Monochromatic 'Gray' toned pallete
|
|
/// </summary>
|
|
MonoGray,
|
|
|
|
/// <summary>
|
|
/// Colorful 'Light' toned pallete
|
|
/// </summary>
|
|
Light,
|
|
|
|
/// <summary>
|
|
/// Colorful 'Medium' toned pallete
|
|
/// </summary>
|
|
Medium,
|
|
|
|
/// <summary>
|
|
/// Colorful 'Dark' toned pallete
|
|
/// </summary>
|
|
Dark,
|
|
|
|
/// <summary>
|
|
/// Custom pallete (CustomPalette property)
|
|
/// </summary>
|
|
Custom
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
}
|