5682 lines
164 KiB
C#
5682 lines
164 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.ComponentModel.Design;
|
||
using System.Drawing;
|
||
using System.Drawing.Design;
|
||
using System.Drawing.Drawing2D;
|
||
using System.Globalization;
|
||
using System.Text;
|
||
using System.Text.RegularExpressions;
|
||
using System.Windows.Forms;
|
||
using DevComponents.DotNetBar.Charts.Style;
|
||
|
||
namespace DevComponents.DotNetBar.Charts
|
||
{
|
||
[Editor("DevComponents.Charts.Design.PieSeriesPointCollectionEditor, DevComponents.Charts.Design, " +
|
||
"Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
|
||
public class PieSeriesPointCollection : CustomNamedCollection<PieSeriesPoint>
|
||
{
|
||
#region Private variables
|
||
|
||
private ISeriesPointContainer _Parent;
|
||
|
||
private PieSeriesPointCollection _PieSlices;
|
||
private PieSeriesPointCollection _OtherSlices;
|
||
|
||
private PieSeriesPoint _OtherSlicePsp;
|
||
|
||
private double _PieTotal;
|
||
|
||
private double _PieMinExtent;
|
||
private double _PieMaxExtent;
|
||
private double _PieOuterExtent;
|
||
private double _PieTotalExtent;
|
||
|
||
private double _PieAverage;
|
||
private double _PieAverageExtent;
|
||
|
||
private PieRing _PieRing;
|
||
|
||
private States _States;
|
||
|
||
#endregion
|
||
|
||
#region Public properties
|
||
|
||
#region IsOther
|
||
|
||
/// <summary>
|
||
/// Gets whether the PieSeriesPoint is the 'Other' slice collection.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public bool IsOther
|
||
{
|
||
get { return (TestState(States.Other)); }
|
||
internal set { SetState(States.Other, value); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region OtherSlicePsp
|
||
|
||
/// <summary>
|
||
/// Gets the 'Other' slice PieSeriesPoint.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public PieSeriesPoint OtherSlicePsp
|
||
{
|
||
get
|
||
{
|
||
if (_OtherSlicePsp == null)
|
||
_OtherSlicePsp = new PieSeriesPoint("Other", null, null);
|
||
|
||
return (_OtherSlicePsp);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region OtherSlices
|
||
|
||
/// <summary>
|
||
/// Gets the 'Other' slice collection of SeriesPoints.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public PieSeriesPointCollection OtherSlices
|
||
{
|
||
get { return (_OtherSlices); }
|
||
internal set { _OtherSlices = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Parent
|
||
|
||
/// <summary>
|
||
/// Gets the parent of this item.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public ISeriesPointContainer Parent
|
||
{
|
||
get { return (_Parent); }
|
||
internal set { _Parent = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PieAverage
|
||
|
||
/// <summary>
|
||
/// Gets the average pie point 'value' (Y[0]) for the collection.
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public double PieAverage
|
||
{
|
||
get { return (_PieAverage); }
|
||
internal set { _PieAverage = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PieAverageExtent
|
||
|
||
/// <summary>
|
||
/// Gets the average extent for the collection.
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public double PieAverageExtent
|
||
{
|
||
get { return (_PieAverageExtent); }
|
||
internal set { _PieAverageExtent = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PieSlices
|
||
|
||
/// <summary>
|
||
/// Gets the collection of displayed Pie slices.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public PieSeriesPointCollection PieSlices
|
||
{
|
||
get { return (_PieSlices); }
|
||
|
||
internal set
|
||
{
|
||
if (_PieSlices != null)
|
||
SetOtherHandler(false);
|
||
|
||
_PieSlices = value;
|
||
|
||
if (_PieSlices != null)
|
||
SetOtherHandler(true);
|
||
}
|
||
}
|
||
|
||
#region SetOtherHandler
|
||
|
||
private void SetOtherHandler(bool notify)
|
||
{
|
||
PieSeriesPointCollection spc = _PieSlices;
|
||
|
||
foreach (PieSeriesPoint psp in spc)
|
||
{
|
||
if (psp.IsOther == true)
|
||
{
|
||
SetPointNotify(psp, notify);
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
#region SetPointNotify
|
||
|
||
private void SetPointNotify(PieSeriesPoint psp, bool notify)
|
||
{
|
||
if (notify == true)
|
||
{
|
||
psp.Parent = this;
|
||
psp.PropertyChanged += Sp_PropertyChanged;
|
||
}
|
||
else
|
||
{
|
||
psp.Parent = null;
|
||
psp.PropertyChanged -= Sp_PropertyChanged;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Sp_PropertyChanged
|
||
|
||
void Sp_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||
{
|
||
VisualPropertyChangedEventArgs vce = e as VisualPropertyChangedEventArgs;
|
||
|
||
if (vce != null)
|
||
{
|
||
PieSeriesPoint psp = sender as PieSeriesPoint;
|
||
|
||
if (psp != null)
|
||
psp.NotifyVisualParent(psp, vce.ChangeType);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region PieTotal
|
||
|
||
/// <summary>
|
||
/// Gets the sum total of the pie collection 'values' (Y[0]).
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public double PieTotal
|
||
{
|
||
get { return (_PieTotal); }
|
||
internal set { _PieTotal = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PieTotalExtent
|
||
|
||
/// <summary>
|
||
/// Gets the sum total of the collection 'extents' (Y[1]).
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public double PieTotalExtent
|
||
{
|
||
get { return (_PieTotalExtent); }
|
||
internal set { _PieTotalExtent = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region VisibleCount
|
||
|
||
///<summary>
|
||
/// Gets count of visible points in the collection.
|
||
///</summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public int VisibleCount
|
||
{
|
||
get
|
||
{
|
||
int vcount = 0;
|
||
|
||
foreach (PieSeriesPoint psp in Items)
|
||
{
|
||
if (psp.Visible == true)
|
||
vcount++;
|
||
}
|
||
|
||
return (vcount);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region Internal properties
|
||
|
||
#region PieMaxExtent
|
||
|
||
internal double PieMaxExtent
|
||
{
|
||
get { return (_PieMaxExtent); }
|
||
set { _PieMaxExtent = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PieMinExtent
|
||
|
||
internal double PieMinExtent
|
||
{
|
||
get { return (_PieMinExtent); }
|
||
set { _PieMinExtent = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PieOuterExtent
|
||
|
||
internal double PieOuterExtent
|
||
{
|
||
get { return (_PieOuterExtent); }
|
||
set { _PieOuterExtent = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PieRing
|
||
|
||
internal PieRing PieRing
|
||
{
|
||
get { return (_PieRing); }
|
||
set { _PieRing = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region ClearItems
|
||
|
||
protected override void ClearItems()
|
||
{
|
||
if (Parent is PieSeriesPoint)
|
||
{
|
||
for (int i = Items.Count - 1; i >= 0; i--)
|
||
RemoveItem(i);
|
||
}
|
||
else
|
||
{
|
||
CheckReentrancy();
|
||
|
||
Items.Clear();
|
||
|
||
OnPropertyChanged(CountString);
|
||
OnPropertyChanged(ItemString);
|
||
|
||
OnCollectionReset();
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SetSelected
|
||
|
||
internal void SetSelected(bool select)
|
||
{
|
||
foreach (PieSeriesPoint psp in Items)
|
||
{
|
||
if (psp != null)
|
||
{
|
||
psp.IsSelected = select;
|
||
|
||
if (psp.SeriesPoints.PieSlices != null)
|
||
psp.SeriesPoints.PieSlices.SetSelected(select);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region States
|
||
|
||
[Flags]
|
||
private enum States : uint
|
||
{
|
||
Other = (1 << 0),
|
||
}
|
||
|
||
#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 SliceVisualLayout
|
||
|
||
[TypeConverter(typeof(BlankExpandableObjectConverter))]
|
||
public class SliceVisualLayout : INotifyPropertyChanged, IProcessSerialElement, IDisposable
|
||
{
|
||
#region Private variables
|
||
|
||
private ChartVisualElement _Parent;
|
||
|
||
private double _AngleMargin = double.NaN;
|
||
|
||
private int _RingWeight = -1;
|
||
|
||
private int _MaxSlices = -1;
|
||
private int _MinExtent = -1;
|
||
private double _MinPercent = double.NaN;
|
||
|
||
private SliceLabelOrientation _InnerLabelOrientation = SliceLabelOrientation.NotSet;
|
||
private SliceLabelCropMode _SliceLabelCropMode = SliceLabelCropMode.NotSet;
|
||
private SliceLabelVisibility _SliceLabelVisibility = SliceLabelVisibility.NotSet;
|
||
private SliceLabelDisplayMode _SliceLabelDisplayMode = SliceLabelDisplayMode.NotSet;
|
||
|
||
private ChartSliceVisualStyles _SliceVisualStyles;
|
||
private ChartSliceVisualStyles _OtherSliceVisualStyles;
|
||
|
||
private Tbool _ShowSliceWhiteSpace = Tbool.NotSet;
|
||
|
||
private string _InnerSliceLabel;
|
||
private string _OuterSliceLabel;
|
||
|
||
private double _StartAngle = double.NaN;
|
||
private double _SweepAngle = double.NaN;
|
||
private SweepDirection _SweepDirection = SweepDirection.NotSet;
|
||
|
||
private string _ToolTipText;
|
||
|
||
private PieRefLineDisplayMode _RefLineDisplayMode = PieRefLineDisplayMode.NotSet;
|
||
private Tbool _ReferenceLineDisplayOnTop = Tbool.NotSet;
|
||
|
||
internal PieReferenceLineCollection _ReferenceLines;
|
||
|
||
#endregion
|
||
|
||
public SliceVisualLayout(ChartVisualElement parent)
|
||
{
|
||
_Parent = parent;
|
||
}
|
||
|
||
#region Public properties
|
||
|
||
#region AngleMargin
|
||
|
||
/// <summary>
|
||
/// Gets or sets the margin used to offset the angle at
|
||
/// which the slice sides are rendered. This can be used to
|
||
/// create a more 'wedge' shaped slice.
|
||
/// </summary>
|
||
[Description("Indicates the margin used to offset the angle at which the slice sides are rendered. This can be used to create a more 'wedge' shaped slice.")]
|
||
[DefaultValue(double.NaN)]
|
||
[Editor("DevComponents.Charts.Design.AngleMarginRangeValueEditor, DevComponents.Charts.Design, " +
|
||
"Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
|
||
public double AngleMargin
|
||
{
|
||
get { return (_AngleMargin); }
|
||
|
||
set
|
||
{
|
||
if (value != _AngleMargin)
|
||
{
|
||
_AngleMargin = value;
|
||
|
||
OnPropertyChangedEx("AngleMargin", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region InnerLabelOrientation
|
||
|
||
/// <summary>
|
||
/// Gets or sets the inner label orientation with respect to the slice.
|
||
/// </summary>
|
||
[Category("Behavior"), DefaultValue(SliceLabelOrientation.NotSet)]
|
||
[Description("Indicates the inner label orientation with respect to the slice.")]
|
||
public SliceLabelOrientation InnerLabelOrientation
|
||
{
|
||
get { return (_InnerLabelOrientation); }
|
||
|
||
set
|
||
{
|
||
if (value != _InnerLabelOrientation)
|
||
{
|
||
_InnerLabelOrientation = value;
|
||
|
||
OnPropertyChangedEx("InnerLabelOrientation", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region InnerSliceLabel
|
||
|
||
/// <summary>
|
||
/// Gets or sets the inner slice label for the pie slice. The label can be
|
||
/// straight text, or be comprised of text and formatting specifiers. The label
|
||
/// should be specified as (note that brackets denote optional elements):
|
||
/// "[text]{keyword[:format]}[text][{...}]".
|
||
///
|
||
/// Here are the formatting specifiers that can be used with both inner and
|
||
/// outer labels:
|
||
///
|
||
/// "AVG" "A" - Average (angular values).
|
||
/// "PCT" "P" - Percent of pie (angular values) - (.025 yields "2.5 %").
|
||
/// "TOT" "T" - Total of all values (angluar values).
|
||
/// "VAL" "V" - Value percent of pie (angular value) - (.025 yields ".025").
|
||
///
|
||
/// "AVGX" "AX" - Average (extent/radial values).
|
||
/// "PCTX" "PX" - Percent of pie (extent values) - (.025 yields "2.5 %").
|
||
/// "TOTX" "TX" - Total of all values (extent values).
|
||
/// "VALX" "VX" - Value percent of pie (extent value) - (.025 yields ".025").
|
||
///
|
||
/// "S" "SNAME" - Series name.
|
||
/// "X" - ValueX.
|
||
/// "Y", "Y0", "Yn" - ValueY values (where 'n' is index value).
|
||
///
|
||
/// Example use:
|
||
///
|
||
/// "{S}\\n{X:yyyy} ({Y:##,##0} - {P:Y1})"
|
||
/// "Individual cost {Y:C} and average cost {AVG:C} of goods."
|
||
///
|
||
/// </summary>
|
||
[DefaultValue(null), Category("Label")]
|
||
[Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]
|
||
[Description("Indicates the inner slice label for the pie slices (format specifiers {Keyword[:Format]} - " +
|
||
"S, X, Y, Y0-Yn, N, [A|AVG][X], [A|PCT][X], [A|TOT][X], [A|VAL][X]. e.g. \"{x:f2},{avg:##.##},{totx:c}\"")]
|
||
public string InnerSliceLabel
|
||
{
|
||
get { return (_InnerSliceLabel); }
|
||
|
||
set
|
||
{
|
||
if (String.Equals(value, _InnerSliceLabel) == false)
|
||
{
|
||
_InnerSliceLabel = value;
|
||
|
||
OnPropertyChangedEx("InnerSliceLabel", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region MaxSlices
|
||
|
||
/// <summary>
|
||
/// Gets or sets the maximum number of slices to represent in the pie. Any remaining values
|
||
/// are consolidated into the 'Other' slice, if shown, or are not displayed at all.
|
||
///
|
||
/// The slices are counted in the order in which they are displayed. This order is
|
||
/// affected by the ReverseSlices property.
|
||
/// </summary>
|
||
[DefaultValue(-1), Category("Display")]
|
||
[Description("Indicates the maximum number of slices to represent in the pie. Any remaining values are consolidated into the 'Other' slice, if shown, or are not displayed at all.")]
|
||
public int MaxSlices
|
||
{
|
||
get { return (_MaxSlices); }
|
||
|
||
set
|
||
{
|
||
if (value != _MaxSlices)
|
||
{
|
||
_MaxSlices = value;
|
||
|
||
OnPropertyChangedEx("MaxSlices", VisualChangeType.Recalc);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region MinExtent
|
||
|
||
///<summary>
|
||
/// Gets or sets the minimum extent for the collection.
|
||
///</summary>
|
||
[DefaultValue(-1), Category("Display")]
|
||
[Description("Indicates the minimum extent for the collection.")]
|
||
public int MinExtent
|
||
{
|
||
get { return (_MinExtent); }
|
||
|
||
set
|
||
{
|
||
if (value != _MinExtent)
|
||
{
|
||
_MinExtent = value;
|
||
|
||
OnPropertyChangedEx("MinExtent", Style.VisualChangeType.Recalc);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region MinPercent
|
||
|
||
/// <summary>
|
||
/// Gets or sets the minimum percent-of-total represented in individual slices.
|
||
/// Values less than the MinPercent are either accumulated into the 'Other' slice, if shown,
|
||
/// or left in the main pie display.
|
||
/// Range is 0–1.
|
||
/// </summary>
|
||
[DefaultValue(double.NaN), Category("Display")]
|
||
[Description("Indicates the minimum percent-of-total represented in individual slices. Values less than the MinPercent are accumulated into the 'Other' slice. Range is 0–1.")]
|
||
public double MinPercent
|
||
{
|
||
get { return (_MinPercent); }
|
||
|
||
set
|
||
{
|
||
if (value != _MinPercent)
|
||
{
|
||
_MinPercent = value;
|
||
|
||
OnPropertyChangedEx("MinPercent", VisualChangeType.Recalc);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region OtherSliceVisualStyles
|
||
|
||
/// <summary>
|
||
/// Gets or sets the default visual style for the series 'Other' slice.
|
||
/// </summary>
|
||
[Category("Style")]
|
||
[Description("Indicates the default visual style for the series 'Other' slice.")]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||
public ChartSliceVisualStyles OtherSliceVisualStyles
|
||
{
|
||
get
|
||
{
|
||
if (_OtherSliceVisualStyles == null)
|
||
{
|
||
_OtherSliceVisualStyles = new ChartSliceVisualStyles();
|
||
|
||
StyleChangeHandler(null, _OtherSliceVisualStyles);
|
||
}
|
||
|
||
return (_OtherSliceVisualStyles);
|
||
}
|
||
|
||
set
|
||
{
|
||
if (_OtherSliceVisualStyles != value)
|
||
{
|
||
ChartSliceVisualStyles oldValue = _OtherSliceVisualStyles;
|
||
|
||
_OtherSliceVisualStyles = value;
|
||
|
||
OnStyleChanged("OtherSliceVisualStyles", oldValue, value);
|
||
|
||
if (oldValue != null)
|
||
oldValue.Dispose();
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region OuterSliceLabel
|
||
|
||
/// <summary>
|
||
/// Gets or sets the outer slice label for the pie slice. See InnerSliceLabel for
|
||
/// further notes on Format Specifiers.
|
||
/// </summary>
|
||
[DefaultValue(null), Category("Label")]
|
||
[Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]
|
||
[Description("Indicates the inner slice label for the pie slices. See InnerSliceLabel for further notes on Format Specifiers.")]
|
||
public string OuterSliceLabel
|
||
{
|
||
get { return (_OuterSliceLabel); }
|
||
|
||
set
|
||
{
|
||
if (String.Equals(value, _OuterSliceLabel) == false)
|
||
{
|
||
_OuterSliceLabel = value;
|
||
|
||
OnPropertyChangedEx("OuterSliceLabel", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Parent
|
||
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public ChartVisualElement Parent
|
||
{
|
||
get { return (_Parent); }
|
||
|
||
internal set
|
||
{
|
||
_Parent = value;
|
||
|
||
UpdateRelations();
|
||
}
|
||
}
|
||
|
||
#region UpdateRelations
|
||
|
||
private void UpdateRelations()
|
||
{
|
||
foreach (PieReferenceLine line in ReferenceLines)
|
||
line.Parent = _Parent;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region ReferenceLineDisplayMode
|
||
|
||
/// <summary>
|
||
/// Gets or sets the type of pie reference lines to display.
|
||
/// </summary>
|
||
[Category("Appearance"), DefaultValue(PieRefLineDisplayMode.NotSet)]
|
||
[Description("Indicates the type of pie reference lines to display.")]
|
||
[Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " +
|
||
"Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
|
||
public PieRefLineDisplayMode ReferenceLineDisplayMode
|
||
{
|
||
get { return (_RefLineDisplayMode); }
|
||
|
||
set
|
||
{
|
||
if (value != _RefLineDisplayMode)
|
||
{
|
||
_RefLineDisplayMode = value;
|
||
|
||
OnPropertyChangedEx("ReferenceLineDisplayMode", VisualChangeType.Render);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ReferenceLineDisplayOnTop
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether references lines are displayed on top of chart data.
|
||
/// </summary>
|
||
[DefaultValue(Tbool.NotSet), Category("Appearance")]
|
||
[Description("Indicates whether the reference lines are displayed on top of chart data.")]
|
||
public Tbool ReferenceLineDisplayOnTop
|
||
{
|
||
get { return (_ReferenceLineDisplayOnTop); }
|
||
|
||
set
|
||
{
|
||
if (value != _ReferenceLineDisplayOnTop)
|
||
{
|
||
_ReferenceLineDisplayOnTop = value;
|
||
|
||
OnPropertyChangedEx("ReferenceLineDisplayOnTop", VisualChangeType.Render);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ReferenceLines
|
||
|
||
/// <summary>
|
||
/// Gets a reference to the collection of user defined Reference Lines.
|
||
/// </summary>
|
||
[Category("Appearance")]
|
||
[Description("Indicates the collection of user defined Reference Lines.")]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||
public PieReferenceLineCollection ReferenceLines
|
||
{
|
||
get
|
||
{
|
||
if (_ReferenceLines == null)
|
||
{
|
||
_ReferenceLines = new PieReferenceLineCollection();
|
||
|
||
_ReferenceLines.CollectionChanged += ReferenceLineCollectionChanged;
|
||
}
|
||
|
||
return (_ReferenceLines);
|
||
}
|
||
|
||
internal set
|
||
{
|
||
if (_ReferenceLines != null)
|
||
_ReferenceLines.CollectionChanged -= ReferenceLineCollectionChanged;
|
||
|
||
_ReferenceLines = value;
|
||
|
||
if (_ReferenceLines != null)
|
||
_ReferenceLines.CollectionChanged += ReferenceLineCollectionChanged;
|
||
}
|
||
}
|
||
|
||
#region ReferenceLineCollectionChanged
|
||
|
||
void ReferenceLineCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||
{
|
||
switch (e.Action)
|
||
{
|
||
case NotifyCollectionChangedAction.Add:
|
||
foreach (ChartElement item in e.NewItems)
|
||
{
|
||
item.Parent = Parent;
|
||
item.PropertyChanged += Item_PropertyChanged;
|
||
}
|
||
break;
|
||
|
||
case NotifyCollectionChangedAction.Replace:
|
||
foreach (ChartElement item in e.OldItems)
|
||
{
|
||
item.Parent = null;
|
||
item.PropertyChanged -= Item_PropertyChanged;
|
||
}
|
||
|
||
foreach (ChartElement item in e.NewItems)
|
||
{
|
||
item.Parent = Parent;
|
||
item.PropertyChanged += Item_PropertyChanged;
|
||
}
|
||
break;
|
||
|
||
case NotifyCollectionChangedAction.Remove:
|
||
foreach (ChartElement item in e.OldItems)
|
||
{
|
||
item.Parent = null;
|
||
item.PropertyChanged -= Item_PropertyChanged;
|
||
}
|
||
break;
|
||
}
|
||
|
||
OnPropertyChangedEx("ReferenceLines", VisualChangeType.Render);
|
||
}
|
||
|
||
void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||
{
|
||
OnPropertyChanged(e);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region RingWeight
|
||
|
||
///<summary>
|
||
/// Gets or sets the 'relative' thickness of the associated pie ring, as
|
||
/// compared to the relative thickness of other series rings
|
||
/// rings.
|
||
///</summary>
|
||
[DefaultValue(-1), Category("Layout")]
|
||
[Description("Indicates the 'relative' thickness of the associated pie ring, as compared to the relative thickness of other series rings. Default is 100.")]
|
||
public int RingWeight
|
||
{
|
||
get { return (_RingWeight); }
|
||
|
||
set
|
||
{
|
||
if (value != _RingWeight)
|
||
{
|
||
_RingWeight = value;
|
||
|
||
OnPropertyChangedEx("RingWeight", Style.VisualChangeType.Recalc);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ShowSliceWhiteSpace
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether to display, by default, the full
|
||
/// slice (includes potential area beyond slice extent). Default is false.
|
||
/// </summary>
|
||
[DefaultValue(Tbool.NotSet), Category("Display")]
|
||
[Description("Indicates whether to display, by default the full slice (includes potential area beyond slice extent). Default is false.")]
|
||
public Tbool ShowSliceWhiteSpace
|
||
{
|
||
get { return (_ShowSliceWhiteSpace); }
|
||
|
||
set
|
||
{
|
||
if (value != _ShowSliceWhiteSpace)
|
||
{
|
||
_ShowSliceWhiteSpace = value;
|
||
|
||
OnPropertyChangedEx("ShowSliceWhiteSpace", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SliceLabelCropMode
|
||
|
||
/// <summary>
|
||
/// Gets or sets the label display mode (ie. the action taken
|
||
/// when a label needs be clipped for full display). Default is Clip.
|
||
/// </summary>
|
||
[DefaultValue(SliceLabelCropMode.NotSet), Category("Label")]
|
||
[Description("Indicates the label display mode (ie. the action taken when a label needs clipped for full display). Default is Clip.")]
|
||
public SliceLabelCropMode SliceLabelCropMode
|
||
{
|
||
get { return (_SliceLabelCropMode); }
|
||
|
||
set
|
||
{
|
||
if (value != _SliceLabelCropMode)
|
||
{
|
||
_SliceLabelCropMode = value;
|
||
|
||
OnPropertyChangedEx("SliceLabelCropMode", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SliceLabelVisibility
|
||
|
||
/// <summary>
|
||
/// Gets or sets when the slice labels are visibly displayed.
|
||
/// </summary>
|
||
[DefaultValue(SliceLabelVisibility.NotSet), Category("Label")]
|
||
[Description("Indicates when the slice labels are visibly displayed.")]
|
||
public SliceLabelVisibility SliceLabelVisibility
|
||
{
|
||
get { return (_SliceLabelVisibility); }
|
||
|
||
set
|
||
{
|
||
if (value != _SliceLabelVisibility)
|
||
{
|
||
_SliceLabelVisibility = value;
|
||
|
||
OnPropertyChangedEx("SliceLabelVisibility", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SliceLabelDisplayMode
|
||
|
||
/// <summary>
|
||
/// Gets or sets the label display mode, which determines
|
||
/// which slice labels (inner/outer) are displayed. Default is InnerAndOuter.
|
||
/// </summary>
|
||
[DefaultValue(SliceLabelDisplayMode.NotSet), Category("Label")]
|
||
[Description("Indicates the label display mode, which determines which slice labels (inner/outer) are displayed. Default is InnerAndOuter.")]
|
||
public SliceLabelDisplayMode SliceLabelDisplayMode
|
||
{
|
||
get { return (_SliceLabelDisplayMode); }
|
||
|
||
set
|
||
{
|
||
if (value != _SliceLabelDisplayMode)
|
||
{
|
||
_SliceLabelDisplayMode = value;
|
||
|
||
OnPropertyChangedEx("SliceLabelDisplayMode", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SliceVisualStyles
|
||
|
||
/// <summary>
|
||
/// Gets or sets the visual styles for the slice.
|
||
/// </summary>
|
||
[Category("Style")]
|
||
[Description("Indicates the visual styles for the slice.")]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||
public ChartSliceVisualStyles SliceVisualStyles
|
||
{
|
||
get
|
||
{
|
||
if (_SliceVisualStyles == null)
|
||
{
|
||
_SliceVisualStyles = new ChartSliceVisualStyles();
|
||
|
||
StyleChangeHandler(null, _SliceVisualStyles);
|
||
}
|
||
|
||
return (_SliceVisualStyles);
|
||
}
|
||
|
||
set
|
||
{
|
||
if (_SliceVisualStyles != value)
|
||
{
|
||
ChartSliceVisualStyles oldValue = _SliceVisualStyles;
|
||
|
||
_SliceVisualStyles = value;
|
||
|
||
OnStyleChanged("SliceVisualStyles", oldValue, value);
|
||
|
||
if (oldValue != null)
|
||
oldValue.Dispose();
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region StartAngle
|
||
|
||
/// <summary>
|
||
/// Gets or sets the start angle of the pie in degrees where 0 is right and 270 is top.
|
||
/// Defaults to 270.
|
||
/// </summary>
|
||
[DefaultValue(double.NaN), Category("Layout")]
|
||
[Description("Indicates the start angle of the pie in degrees where 0 is right and 270 is top. Defaults to 270.")]
|
||
[Editor("DevComponents.Charts.Design.AngleRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
|
||
public double StartAngle
|
||
{
|
||
get { return (_StartAngle); }
|
||
|
||
set
|
||
{
|
||
if (value != _StartAngle)
|
||
{
|
||
_StartAngle = value;
|
||
|
||
OnPropertyChangedEx("StartAngle", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SweepAngle
|
||
|
||
/// <summary>
|
||
/// Gets or sets the sweep angle (distance from StartAngle to the
|
||
/// ending angle) of the pie in positive degrees (use SweepDirection
|
||
/// to change rotational direction).
|
||
/// </summary>
|
||
[DefaultValue(double.NaN), Category("Layout")]
|
||
[Description("Indicates the sweep angle (distance from StartAngle to the ending angle) of the pie in positive degrees (use SweepDirection to change rotational direction).")]
|
||
[Editor("DevComponents.Charts.Design.AngleRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
|
||
public double SweepAngle
|
||
{
|
||
get { return (_SweepAngle); }
|
||
|
||
set
|
||
{
|
||
if (value != _SweepAngle)
|
||
{
|
||
if (value < 0)
|
||
throw new Exception("SweepAngle cannot be negative (See SweepDirection).");
|
||
|
||
_SweepAngle = value;
|
||
|
||
OnPropertyChangedEx("SweepAngle", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SweepDirection
|
||
|
||
/// <summary>
|
||
/// Gets or sets the direction to display the pie slices - in either a clockwise
|
||
/// or counterclockwise direction.
|
||
/// </summary>
|
||
[DefaultValue(SweepDirection.NotSet), Category("Layout")]
|
||
[Description("Indicates the direction to display the pie slices - in either a clockwise or counterclockwise direction).")]
|
||
public SweepDirection SweepDirection
|
||
{
|
||
get { return (_SweepDirection); }
|
||
|
||
set
|
||
{
|
||
if (value != _SweepDirection)
|
||
{
|
||
_SweepDirection = value;
|
||
|
||
OnPropertyChangedEx("SweepDirection", VisualChangeType.Recalc);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ToolTipText
|
||
|
||
/// <summary>
|
||
/// Gets or sets the text to use for the point ToolTip.
|
||
/// </summary>
|
||
[DefaultValue(null), Category("Label")]
|
||
[Description("Indicates the text to use for the point ToolTip.")]
|
||
[Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]
|
||
public string ToolTipText
|
||
{
|
||
get { return (_ToolTipText); }
|
||
|
||
set
|
||
{
|
||
if (value != _ToolTipText)
|
||
{
|
||
_ToolTipText = value;
|
||
|
||
OnPropertyChanged("ToolTipText");
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region GetReferenceLineByName
|
||
|
||
/// <summary>
|
||
/// Gets the ReferenceLine from the given name.
|
||
/// </summary>
|
||
/// <param name="name"></param>
|
||
/// <returns></returns>
|
||
public PieReferenceLine GetReferenceLineByName(string name)
|
||
{
|
||
if (String.IsNullOrEmpty(name) == true)
|
||
return (null);
|
||
|
||
if (_ReferenceLines != null)
|
||
{
|
||
foreach (PieReferenceLine line in _ReferenceLines)
|
||
{
|
||
if (name.Equals(line.Name) == true)
|
||
return (line);
|
||
}
|
||
}
|
||
|
||
return (null);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Style support
|
||
|
||
#region OnStyleChanged
|
||
|
||
protected virtual void OnStyleChanged(string property,
|
||
INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue)
|
||
{
|
||
StyleChangeHandler(oldValue, newValue);
|
||
|
||
OnPropertyChanged(property);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region StyleChangeHandler
|
||
|
||
protected void StyleChangeHandler(
|
||
INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue)
|
||
{
|
||
if (oldValue != null)
|
||
oldValue.PropertyChanged -= StyleChanged;
|
||
|
||
if (newValue != null)
|
||
newValue.PropertyChanged += StyleChanged;
|
||
}
|
||
|
||
#region StyleChanged
|
||
|
||
/// <summary>
|
||
/// Occurs when one of element visual styles has property changes.
|
||
/// Default implementation invalidates visual appearance of element.
|
||
/// </summary>
|
||
/// <param name="sender">VisualStyle that changed.</param>
|
||
/// <param name="e">Event arguments.</param>
|
||
protected void StyleChanged(object sender, PropertyChangedEventArgs e)
|
||
{
|
||
OnPropertyChanged(e);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region INotifyPropertyChanged Members
|
||
|
||
/// <summary>
|
||
/// Occurs when property value has changed.
|
||
/// </summary>
|
||
public event PropertyChangedEventHandler PropertyChanged;
|
||
|
||
#region OnPropertyChanged
|
||
|
||
/// <summary>
|
||
/// Raises the PropertyChanged event.
|
||
/// </summary>
|
||
/// <param name="e">Event arguments</param>
|
||
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
|
||
{
|
||
if (PropertyChanged != null)
|
||
PropertyChanged(this, e);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Default PropertyChanged processing
|
||
/// </summary>
|
||
/// <param name="s"></param>
|
||
protected void OnPropertyChanged(string s)
|
||
{
|
||
if (PropertyChanged != null)
|
||
OnPropertyChanged(new PropertyChangedEventArgs(s));
|
||
}
|
||
|
||
/// <summary>
|
||
/// Default PropertyChanged processing
|
||
/// </summary>
|
||
/// <param name="s"></param>
|
||
/// <param name="changeType">invalidate</param>
|
||
protected void OnPropertyChangedEx(string s, VisualChangeType changeType)
|
||
{
|
||
if (PropertyChanged != null)
|
||
OnPropertyChanged(new VisualPropertyChangedEventArgs(s, changeType));
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region Copy/CopyTo
|
||
|
||
/// <summary>
|
||
/// Creates a copy of the SeriesPointsLayout
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public SliceVisualLayout Copy()
|
||
{
|
||
SliceVisualLayout copy = new SliceVisualLayout(null);
|
||
|
||
CopyTo(copy);
|
||
|
||
return (copy);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Copies the item data to the given SeriesPointsLayout.
|
||
/// </summary>
|
||
/// <param name="sp"></param>
|
||
public void CopyTo(SliceVisualLayout c)
|
||
{
|
||
c.AngleMargin = AngleMargin;
|
||
|
||
c.MaxSlices = MaxSlices;
|
||
c.MinExtent = MinExtent;
|
||
c.MinPercent = MinPercent;
|
||
|
||
c.InnerLabelOrientation = _InnerLabelOrientation;
|
||
c.InnerSliceLabel = _InnerSliceLabel;
|
||
|
||
c.OtherSliceVisualStyles = (_OtherSliceVisualStyles != null) ? _OtherSliceVisualStyles.Copy() : null;
|
||
|
||
c.OuterSliceLabel = OuterSliceLabel;
|
||
|
||
foreach (PieReferenceLine line in ReferenceLines)
|
||
c.ReferenceLines.Add((PieReferenceLine)line.Copy());
|
||
|
||
c.ReferenceLineDisplayMode = _RefLineDisplayMode;
|
||
c.ReferenceLineDisplayOnTop = _ReferenceLineDisplayOnTop;
|
||
|
||
c.RingWeight = RingWeight;
|
||
|
||
c.ShowSliceWhiteSpace = _ShowSliceWhiteSpace;
|
||
c.SliceLabelCropMode = _SliceLabelCropMode;
|
||
c.SliceLabelDisplayMode = _SliceLabelDisplayMode;
|
||
c.SliceLabelVisibility = _SliceLabelVisibility;
|
||
|
||
c.SliceVisualStyles = (_SliceVisualStyles != null) ? _SliceVisualStyles.Copy() : null;
|
||
|
||
c.StartAngle = _StartAngle;
|
||
c.SweepAngle = _SweepAngle;
|
||
c.SweepDirection = _SweepDirection;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetSerialData
|
||
|
||
internal virtual SerialElementCollection GetSerialData()
|
||
{
|
||
return (GetSerialData(true));
|
||
}
|
||
|
||
internal virtual SerialElementCollection GetSerialData(bool root)
|
||
{
|
||
SerialElementCollection sec = new SerialElementCollection();
|
||
|
||
if (root == true)
|
||
sec.AddStartElement("SliceVisualLayout");
|
||
|
||
sec.AddValue("AngleMargin", AngleMargin, double.NaN);
|
||
|
||
sec.AddValue("MaxSlices", MaxSlices, -1);
|
||
sec.AddValue("MinExtent", MinExtent, -1);
|
||
sec.AddValue("MinPercent", MinPercent, double.NaN);
|
||
|
||
sec.AddValue("InnerLabelOrientation", InnerLabelOrientation, SliceLabelOrientation.NotSet);
|
||
|
||
sec.AddValue("InnerSliceLabel", InnerSliceLabel, null);
|
||
|
||
if (_OtherSliceVisualStyles != null && _OtherSliceVisualStyles.IsEmpty == false)
|
||
sec.AddElement(_OtherSliceVisualStyles.GetSerialData("OtherSliceVisualStyles"));
|
||
|
||
sec.AddValue("OuterSliceLabel", OuterSliceLabel, null);
|
||
|
||
if (_ReferenceLines != null && _ReferenceLines.Count > 0)
|
||
{
|
||
sec.AddStartElement("ReferenceLines count=\"" + _ReferenceLines.Count + "\"");
|
||
|
||
foreach (PieReferenceLine rline in _ReferenceLines)
|
||
sec.AddElement(rline.GetSerialData(""));
|
||
|
||
sec.AddEndElement("ReferenceLines");
|
||
}
|
||
|
||
sec.AddValue("ReferenceLineDisplayMode", ReferenceLineDisplayMode, PieRefLineDisplayMode.NotSet);
|
||
sec.AddValue("ReferenceLineDisplayOnTop", ReferenceLineDisplayOnTop, Tbool.NotSet);
|
||
|
||
sec.AddValue("RingWeight", RingWeight, -1);
|
||
|
||
sec.AddValue("ShowSliceWhiteSpace", ShowSliceWhiteSpace, Tbool.NotSet);
|
||
sec.AddValue("SliceLabelCropMode", SliceLabelCropMode, SliceLabelCropMode.NotSet);
|
||
sec.AddValue("SliceLabelDisplayMode", SliceLabelDisplayMode, SliceLabelDisplayMode.NotSet);
|
||
sec.AddValue("SliceLabelVisibility", SliceLabelVisibility, SliceLabelVisibility.NotSet);
|
||
|
||
if (_SliceVisualStyles != null && _SliceVisualStyles.IsEmpty == false)
|
||
sec.AddElement(_SliceVisualStyles.GetSerialData("SliceVisualStyles"));
|
||
|
||
sec.AddValue("StartAngle", StartAngle, double.NaN);
|
||
sec.AddValue("SweepAngle", SweepAngle, double.NaN);
|
||
sec.AddValue("SweepDirection", SweepDirection, SweepDirection.NotSet);
|
||
|
||
if (root == true)
|
||
sec.AddEndElement("SliceVisualLayout");
|
||
|
||
return (sec);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PutSerialData
|
||
|
||
#region ProcessValue
|
||
|
||
void IProcessSerialElement.ProcessValue(SerialElement se)
|
||
{
|
||
switch (se.Name)
|
||
{
|
||
case "AngleMargin":
|
||
AngleMargin = double.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "InnerLabelOrientation":
|
||
InnerLabelOrientation = (SliceLabelOrientation)se.GetValueEnum(typeof(SliceLabelOrientation));
|
||
break;
|
||
|
||
case "InnerSliceLabel":
|
||
InnerSliceLabel = se.StringValue;
|
||
break;
|
||
|
||
case "MaxSlices":
|
||
MaxSlices = int.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "MinExtent":
|
||
MinExtent = int.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "MinPercent":
|
||
MinPercent = double.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "OuterSliceLabel":
|
||
OuterSliceLabel = se.StringValue;
|
||
break;
|
||
|
||
case "ReferenceLineDisplayMode":
|
||
ReferenceLineDisplayMode = (PieRefLineDisplayMode)se.GetValueEnum(typeof(PieRefLineDisplayMode));
|
||
break;
|
||
|
||
case "ReferenceLineDisplayOnTop":
|
||
ReferenceLineDisplayOnTop = (Tbool)se.GetValueEnum(typeof(Tbool));
|
||
break;
|
||
|
||
case "RingWeight":
|
||
RingWeight = int.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "ShowSliceWhiteSpace":
|
||
ShowSliceWhiteSpace = (Tbool)se.GetValueEnum(typeof(Tbool));
|
||
break;
|
||
|
||
case "SliceLabelCropMode":
|
||
SliceLabelCropMode = (SliceLabelCropMode)se.GetValueEnum(typeof(SliceLabelCropMode));
|
||
break;
|
||
|
||
case "SliceLabelDisplayMode":
|
||
SliceLabelDisplayMode = (SliceLabelDisplayMode)se.GetValueEnum(typeof(SliceLabelDisplayMode));
|
||
break;
|
||
|
||
case "SliceLabelVisibility":
|
||
SliceLabelVisibility = (SliceLabelVisibility)se.GetValueEnum(typeof(SliceLabelVisibility));
|
||
break;
|
||
|
||
case "StartAngle":
|
||
StartAngle = double.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "SweepAngle":
|
||
SweepAngle = double.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "SweepDirection":
|
||
SweepDirection = (SweepDirection)se.GetValueEnum(typeof(SweepDirection));
|
||
break;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ProcessCollection
|
||
|
||
void IProcessSerialElement.ProcessCollection(SerialElement se)
|
||
{
|
||
SerialElementCollection sec = se.Sec;
|
||
|
||
switch (se.Name)
|
||
{
|
||
case "OtherSliceVisualStyles":
|
||
sec.PutSerialData(OtherSliceVisualStyles);
|
||
break;
|
||
|
||
case "ReferenceLine":
|
||
PieReferenceLine line = GetReferenceLineByName(se.Name);
|
||
|
||
if (line != null)
|
||
sec.PutSerialData(line);
|
||
break;
|
||
|
||
case "ReferenceLines":
|
||
sec.PutSerialData(this);
|
||
break;
|
||
|
||
case "SliceVisualStyles":
|
||
sec.PutSerialData(SliceVisualStyles);
|
||
break;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region IDispose
|
||
|
||
public virtual void Dispose()
|
||
{
|
||
ReferenceLines = null;
|
||
OtherSliceVisualStyles = null;
|
||
SliceVisualStyles = null;
|
||
|
||
Parent = null;
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
#region ISeriesPointContainer
|
||
|
||
public interface ISeriesPointContainer
|
||
{
|
||
SliceVisualLayout SubSliceVisualLayout { get; set; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region PieSeriesPoint
|
||
|
||
[DesignTimeVisible(false), ToolboxItem(false)]
|
||
public class PieSeriesPoint : SeriesPoint,
|
||
IEffectiveStyle, INotifyPropertyChanged, ILegendItem, ILegendItemEx, ISeriesPointContainer, INamed
|
||
{
|
||
#region Private variables
|
||
|
||
private object _Parent;
|
||
|
||
private int _OrdinalValue;
|
||
|
||
private ChartControl _ChartControl;
|
||
private int _LocalUpdateCount;
|
||
|
||
private string _InnerSliceLabel;
|
||
private string _OuterSliceLabel;
|
||
|
||
private double _DetachedOffset = double.NaN;
|
||
|
||
private double _StartAngle = double.NaN;
|
||
private double _SweepAngle = double.NaN;
|
||
|
||
private double _AngleMarginExx;
|
||
|
||
private double _StartAngleEx;
|
||
private double _SweepAngleEx;
|
||
|
||
private Point _SliceCenter;
|
||
private double _SliceExtent;
|
||
private double _SliceValue;
|
||
|
||
private int _InnerRadius;
|
||
private int _OuterRadius;
|
||
|
||
private Rectangle _PathBounds;
|
||
private Rectangle _LastPathBounds;
|
||
|
||
private PieRing _PieRing;
|
||
|
||
private PieSeriesPoint _RootPsp;
|
||
|
||
private ChartSliceVisualStyles _SliceVisualStyles;
|
||
private EffectiveStyles<ChartSliceVisualStyle> _EffectiveSliceStyles;
|
||
private ChartSliceVisualStyle _LastEffectiveStyle;
|
||
|
||
private Color _DefaultPaletteColor = Color.Empty;
|
||
|
||
private ushort _LayoutUpdateCount;
|
||
private Rectangle _InscribedRect;
|
||
private List<WordPosLine> _WordPosLines;
|
||
private RectangleF[] _CharBounds;
|
||
|
||
private PieLabel _PieLabel;
|
||
|
||
private ChartLegendItem _LegendItem;
|
||
private string _LegendText;
|
||
private ChartLegendItemVisualStyles _ChartLegendItemVisualStyles;
|
||
|
||
private string _Name;
|
||
private string _ToolTipText;
|
||
|
||
private PieSeriesPointCollection _SeriesPoints;
|
||
private SliceVisualLayout _SliceVisualLayout;
|
||
|
||
private States _States;
|
||
|
||
// ---- Cached items
|
||
|
||
private double _AngleMarginEx;
|
||
|
||
private SliceLabelCropMode _SliceLabelCropModeEx;
|
||
private SliceLabelDisplayMode _SliceLabelDisplayModeEx;
|
||
private SliceLabelOrientation _InnerLabelOrientationEx;
|
||
private SliceLabelVisibility _SliceLabelVisibilityEx;
|
||
|
||
private string _InnerSliceLabelEx;
|
||
private string _OuterSliceLabelEx;
|
||
|
||
private int _MaxSlicesEx;
|
||
private int _MinExtentEx;
|
||
private double _MinPercentEx;
|
||
|
||
private int _RingWeightEx;
|
||
|
||
private PieRefLineDisplayMode _ReferenceLineDisplayModeEx;
|
||
private List<PieReferenceLine> _ReferenceLinesEx;
|
||
|
||
private string _ToolTipTextEx;
|
||
|
||
#endregion
|
||
|
||
#region Constructors
|
||
|
||
public PieSeriesPoint()
|
||
: this(0, 0)
|
||
{
|
||
}
|
||
|
||
/// <summary>
|
||
/// PieSeriesPoint
|
||
/// </summary>
|
||
/// <param name="xValue"></param>
|
||
/// <param name="yValue"></param>
|
||
public PieSeriesPoint(object xValue, object yValue)
|
||
: base(xValue, yValue)
|
||
{
|
||
InitDefaultStates();
|
||
|
||
_EffectiveSliceStyles = new EffectiveStyles<ChartSliceVisualStyle>(this);
|
||
}
|
||
|
||
/// <summary>
|
||
/// PieSeriesPoint
|
||
/// </summary>
|
||
/// <param name="xValue"></param>
|
||
/// <param name="yValue"></param>
|
||
public PieSeriesPoint(object xValue, object[] yValue)
|
||
: base(xValue, yValue)
|
||
{
|
||
InitDefaultStates();
|
||
|
||
_EffectiveSliceStyles = new EffectiveStyles<ChartSliceVisualStyle>(this);
|
||
}
|
||
|
||
/// <summary>
|
||
/// PieSeriesPoint
|
||
/// </summary>
|
||
/// <param name="xValue"></param>
|
||
/// <param name="yValue1">angular value</param>
|
||
/// <param name="yValue2">yValue2=radial</param>
|
||
public PieSeriesPoint(object xValue, object yValue1, object yValue2)
|
||
: base(xValue, yValue1, yValue2)
|
||
{
|
||
InitDefaultStates();
|
||
|
||
_EffectiveSliceStyles = new EffectiveStyles<ChartSliceVisualStyle>(this);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region InitDefaultStates
|
||
|
||
private void InitDefaultStates()
|
||
{
|
||
SetState(States.AllowDetach, true);
|
||
SetState(States.AllowSelect, true);
|
||
|
||
SetState(States.CheckedInLegend, true);
|
||
SetState(States.ShowInLegend, true);
|
||
SetState(States.ShowInParentLegend, true);
|
||
SetState(States.ShowMarkerInLegend, true);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Public properties
|
||
|
||
#region ActualStartAngle
|
||
|
||
/// <summary>
|
||
/// Gets the actual, calculated starting angle for the slice.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public double ActualStartAngle
|
||
{
|
||
get { return (StartAngleEx); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ActualSweepAngle
|
||
|
||
/// <summary>
|
||
/// Gets the actual, calculated sweep angle for the slice.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public double ActualSweepAngle
|
||
{
|
||
get { return (SweepAngleEx); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region AllowDetach
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether the element can be 'detached' from
|
||
/// the center of the pie by the user. Defaults to true.
|
||
/// </summary>
|
||
[DefaultValue(true), Category("Behavior")]
|
||
[Description("Indicates whether the element can be 'detached' from the center of the pie by the user. Defaults to true.")]
|
||
public bool AllowDetach
|
||
{
|
||
get { return (TestState(States.AllowDetach)); }
|
||
|
||
set
|
||
{
|
||
if (value != AllowDetach)
|
||
{
|
||
SetState(States.AllowDetach, value);
|
||
|
||
OnPropertyChanged("AllowDetach");
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region AllowSelect
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether the element can be selected by clicking on it. Defaults to true.
|
||
/// </summary>
|
||
[DefaultValue(true), Category("Behavior")]
|
||
[Description("Indicates whether the element can be selected by clicking on it. Defaults to true.")]
|
||
public bool AllowSelect
|
||
{
|
||
get { return (TestState(States.AllowSelect)); }
|
||
|
||
set
|
||
{
|
||
if (value != AllowSelect)
|
||
{
|
||
SetState(States.AllowSelect, value);
|
||
|
||
OnPropertyChanged("AllowSliceSelect");
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region CenterAngle
|
||
|
||
/// <summary>
|
||
/// Gets the Center Angle for the slice.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public double CenterAngle
|
||
{
|
||
get { return ((StartAngleEx + SweepAngleEx / 2) + 360000) % 360; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ChartSeries
|
||
|
||
/// <summary>
|
||
/// Gets the associated ChartSeries.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public PieSeries ChartSeries
|
||
{
|
||
get { return (_PieRing != null ? _PieRing.ChartSeries : null); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region DefaultPaletteColor
|
||
|
||
/// <summary>
|
||
/// Gets the default palette color assigned to the point when it
|
||
/// is arranged in the pie.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
[Description("Indicates the default palette color assigned to the point when it is arranged in the pie.")]
|
||
public Color DefaultPaletteColor
|
||
{
|
||
get { return (_DefaultPaletteColor); }
|
||
|
||
internal set
|
||
{
|
||
if (value != _DefaultPaletteColor)
|
||
{
|
||
_DefaultPaletteColor = value;
|
||
|
||
ClearEffectiveStyles();
|
||
|
||
OnPropertyChangedEx("DetachedOffset", VisualChangeType.Render);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region DetachedOffset
|
||
|
||
/// <summary>
|
||
/// Gets or sets the offset distance of the slice from the pie center, as measured
|
||
/// by a percentage of the pie radius (if between 0 and 1), or absolute pixel amount (if >= 1).
|
||
/// </summary>
|
||
[DefaultValue(double.NaN), Category("Appearance")]
|
||
[Description("Indicates the offset distance of the slice from the pie center, as measured by a percentage of the pie radius (if between 0 and 1), or absolute pixel amount (if >= 1).")]
|
||
[Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
|
||
public double DetachedOffset
|
||
{
|
||
get { return (_DetachedOffset); }
|
||
|
||
set
|
||
{
|
||
if (value != _DetachedOffset)
|
||
{
|
||
_DetachedOffset = value;
|
||
|
||
OnPropertyChangedEx("DetachedOffset", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region EffectiveSliceStyles
|
||
|
||
/// <summary>
|
||
/// Gets a reference to the Effective (cached, composite) Slice styles.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public EffectiveStyles<ChartSliceVisualStyle> EffectiveSliceStyles
|
||
{
|
||
get { return (_EffectiveSliceStyles); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ExtentRadius
|
||
|
||
/// <summary>
|
||
/// Gets the actual, calculated extent radius of the slice (the
|
||
/// radius between the inner and outer radius - ValuesY[1]).
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public double ExtentRadius
|
||
{
|
||
get
|
||
{
|
||
int width = OuterRadius - InnerRadius;
|
||
int extendWidth = (int)(SliceExtent * width);
|
||
|
||
return (InnerRadius + extendWidth);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region InnerRadius
|
||
|
||
/// <summary>
|
||
/// Gets the actual, inner radius of the slice.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public int InnerRadius
|
||
{
|
||
get { return (_InnerRadius); }
|
||
internal set { _InnerRadius = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region InnerSliceLabel
|
||
|
||
/// <summary>
|
||
/// Gets or sets the inner slice label for the pie slice. The label can be
|
||
/// straight text, or be comprised of text and formatting specifiers. The label
|
||
/// should be specified as "Some text {Keyword:Format} more text [{...:...}]".
|
||
///
|
||
/// Here are the formatting specifiers that can be used with both inner and
|
||
/// outer labels:
|
||
///
|
||
/// "AVG" "A" - Average (angular values).
|
||
/// "PCT" "P" - Percent of pie (angular values) - (.025 yields "2.5 %").
|
||
/// "TOT" "T" - Total of all values (angluar values).
|
||
/// "VAL" "V" - Value percent of pie (angular value) - (.025 yields ".025").
|
||
///
|
||
/// "AVGX" "AX" - Average (extent/radial values).
|
||
/// "PCTX" "PX" - Percent of pie (extent values) - (.025 yields "2.5 %").
|
||
/// "TOTX" "TX" - Total of all values (extent values).
|
||
/// "VALX" "VX" - Value percent of pie (extent value) - (.025 yields ".025").
|
||
///
|
||
/// "S" "SNAME" - Series name.
|
||
/// "X" - ValueX.
|
||
/// "Y", "Y0", "Yn" - ValueY values (where 'n' is index value).
|
||
///
|
||
/// Examples:
|
||
///
|
||
/// "{S}\\n{X:yyyy} ({Y:##,##0} - {P:Y1})"
|
||
/// "Individual cost {Y:C} and average cost {AVG:C} of goods."
|
||
///
|
||
/// </summary>
|
||
[DefaultValue(null), Category("Label")]
|
||
[Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]
|
||
[Description("Indicates the inner slice label for the pie slices (format specifiers {Keyword[:Format]} - " +
|
||
"S, X, Y, Y0-Yn, N, [A|AVG][X], [A|PCT][X], [A|TOT][X], [A|VAL][X]. e.g. \"{x:f2},{avg:##.##},{totx:c}\"")]
|
||
public string InnerSliceLabel
|
||
{
|
||
get { return (_InnerSliceLabel); }
|
||
|
||
set
|
||
{
|
||
if (String.Equals(value, _InnerSliceLabel) == false)
|
||
{
|
||
_InnerSliceLabel = value;
|
||
|
||
OnPropertyChangedEx("InnerSliceLabel", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsDetached
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether the slice is 'detached' from the center of the pie. This can be
|
||
/// used to create emphasis or to highlight a slice of the pie.
|
||
/// </summary>
|
||
[DefaultValue(false), Category("Appearance")]
|
||
[Description("Indicates whether the slice is 'detached' from the center of the pie.")]
|
||
public bool IsDetached
|
||
{
|
||
get { return (TestState(States.Detached)); }
|
||
|
||
set
|
||
{
|
||
if (value != IsDetached)
|
||
{
|
||
SetState(States.Detached, value);
|
||
|
||
OnPropertyChangedEx("IsDetached", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsDisplayed
|
||
|
||
///<summary>
|
||
/// Gets whether the series point is displayed
|
||
/// based upon its Visibility and Legend state.
|
||
///</summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public bool IsDisplayed
|
||
{
|
||
get { return (Visible == true && IsDisplayedEx == true); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsEmptyPoint
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether the point is an 'Empty' (or missing) Point.
|
||
/// </summary>
|
||
[DefaultValue(false), Category("Data")]
|
||
[Description("Indicates whether the point is an 'Empty' (or missing) Point.")]
|
||
public override bool IsEmptyPoint
|
||
{
|
||
get { return (base.IsEmptyPoint); }
|
||
|
||
set
|
||
{
|
||
if (value != base.IsEmptyPoint)
|
||
{
|
||
base.IsEmptyPoint = value;
|
||
|
||
OnPropertyChangedEx("IsEmptyPoint", VisualChangeType.Recalc);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsInOther
|
||
|
||
/// <summary>
|
||
/// Gets whether the slice is in the 'Other' slice.
|
||
/// </summary>
|
||
[DefaultValue(false), Category("Appearance")]
|
||
[Description("Indicates whether the slice is in the 'Other' slice.")]
|
||
public bool IsInOther
|
||
{
|
||
get { return (TestState(States.IsInOther)); }
|
||
|
||
set
|
||
{
|
||
if (value != IsInOther)
|
||
{
|
||
SetState(States.IsInOther, value);
|
||
|
||
OnPropertyChangedEx("IsInOther", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsOther
|
||
|
||
/// <summary>
|
||
/// Gets whether the slice is the 'Other' slice.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
[Description("Indicates whether the slice is the 'Other' slice.")]
|
||
public bool IsOther
|
||
{
|
||
get { return (TestState(States.IsOther)); }
|
||
internal set { SetState(States.IsOther, value); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsSelected
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether the slice is selected.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
[Description("Indicates whether the slice is selected.")]
|
||
public bool IsSelected
|
||
{
|
||
get { return (TestState(States.Selected)); }
|
||
|
||
set
|
||
{
|
||
if (value != IsSelected)
|
||
{
|
||
SetState(States.Selected, value);
|
||
|
||
OnPropertyChangedEx("IsSelected", VisualChangeType.Render);
|
||
|
||
PieSeries series = ChartSeries;
|
||
|
||
if (series != null)
|
||
{
|
||
PieChart pieChart = series.Parent as PieChart;
|
||
|
||
if (pieChart != null)
|
||
pieChart.GlobalSelectionCount++;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Name
|
||
|
||
/// <summary>
|
||
/// Gets or sets the Name of the item.
|
||
/// </summary>
|
||
[DefaultValue(null)]
|
||
[Description("Indicates the Name of the item.")]
|
||
public virtual string Name
|
||
{
|
||
get { return (_Name); }
|
||
set { _Name = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region OrdinalValue
|
||
|
||
/// <summary>
|
||
/// Gets the ordial value for the point (the ordinal value when added
|
||
/// to the PieSeriesPoint Collection
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public int OrdinalValue
|
||
{
|
||
get { return (_OrdinalValue); }
|
||
internal set { _OrdinalValue = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region OuterRadius
|
||
|
||
/// <summary>
|
||
/// Gets the actual, outer radius of the slice.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public int OuterRadius
|
||
{
|
||
get { return (_OuterRadius); }
|
||
internal set { _OuterRadius = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region OuterSliceLabel
|
||
|
||
/// <summary>
|
||
/// Gets or sets the outer slice label for the pie slice. See InnerSliceLabel for
|
||
/// further notes on Format Specifiers.
|
||
/// </summary>
|
||
[DefaultValue(null), Category("Label")]
|
||
[Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]
|
||
[Description("Indicates the inner slice label for the pie slices. See InnerSliceLabel for further notes on Format Specifiers.")]
|
||
public string OuterSliceLabel
|
||
{
|
||
get { return (_OuterSliceLabel); }
|
||
|
||
set
|
||
{
|
||
if (String.Equals(value, _OuterSliceLabel) == false)
|
||
{
|
||
_OuterSliceLabel = value;
|
||
|
||
OnPropertyChangedEx("OuterSliceLabel", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Parent
|
||
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
[Description("Indicates the item Parent.")]
|
||
public object Parent
|
||
{
|
||
get { return (_Parent); }
|
||
|
||
internal set
|
||
{
|
||
_Parent = value;
|
||
|
||
_RootPsp = null;
|
||
|
||
if (value != null)
|
||
{
|
||
PieSeriesPointCollection psp = value as PieSeriesPointCollection;
|
||
|
||
if (psp != null)
|
||
SubSliceVisualLayout.Parent = psp.Parent as ChartVisualElement;
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PieRing
|
||
|
||
/// <summary>
|
||
/// Gets the items associated PieRing (if applicable).
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public PieRing PieRing
|
||
{
|
||
get { return (_PieRing); }
|
||
internal set { _PieRing = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SeriesPoints
|
||
|
||
///<summary>
|
||
/// Gets the nested series point data collection.
|
||
///</summary>
|
||
[Category("Data")]
|
||
[Description("Indicates the nested series point data collection.")]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||
public PieSeriesPointCollection SeriesPoints
|
||
{
|
||
get
|
||
{
|
||
if (_SeriesPoints == null)
|
||
SeriesPoints = new PieSeriesPointCollection();
|
||
|
||
return (_SeriesPoints);
|
||
}
|
||
|
||
set
|
||
{
|
||
if (value != _SeriesPoints)
|
||
{
|
||
if (_SeriesPoints != null)
|
||
{
|
||
_SeriesPoints.Parent = null;
|
||
|
||
_SeriesPoints.CollectionChanged -= SeriesPoints_CollectionChanged;
|
||
}
|
||
|
||
_SeriesPoints = value;
|
||
|
||
if (_SeriesPoints != null)
|
||
{
|
||
_SeriesPoints.Parent = this;
|
||
|
||
_SeriesPoints.CollectionChanged += SeriesPoints_CollectionChanged;
|
||
}
|
||
|
||
OnPropertyChangedEx("SeriesPoints", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#region SeriesPoints_CollectionChanged
|
||
|
||
void SeriesPoints_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||
{
|
||
SetSpcNotify(e.OldItems, false);
|
||
SetSpcNotify(e.NewItems, true);
|
||
|
||
OnPropertyChangedEx("SeriesPoints", Style.VisualChangeType.Layout);
|
||
}
|
||
|
||
#region SetPointNotify
|
||
|
||
private void SetSpcNotify(IList list, bool notify)
|
||
{
|
||
if (list != null)
|
||
{
|
||
foreach (PieSeriesPoint psp in list)
|
||
{
|
||
if (psp != null)
|
||
{
|
||
if (notify == true)
|
||
{
|
||
psp.Parent = SeriesPoints;
|
||
psp.PropertyChanged += Spc_PropertyChanged;
|
||
}
|
||
else
|
||
{
|
||
psp.Parent = null;
|
||
psp.PropertyChanged -= Spc_PropertyChanged;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Spc_PropertyChanged
|
||
|
||
void Spc_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||
{
|
||
if (e is VisualPropertyChangedEventArgs)
|
||
OnPropertyChanged(e);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region SliceCenter
|
||
|
||
/// <summary>
|
||
/// Gets the slice center origin point.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public Point SliceCenter
|
||
{
|
||
get { return (_SliceCenter); }
|
||
internal set { _SliceCenter = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SliceExtent
|
||
|
||
/// <summary>
|
||
/// Gets the calculated slice extent value (the relative
|
||
/// percent-of-total ValuesY[1] value for the slice).
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public double SliceExtent
|
||
{
|
||
get { return (_SliceExtent); }
|
||
internal set { _SliceExtent = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SliceValue
|
||
|
||
/// <summary>
|
||
/// Gets the calculated slice value (the relative
|
||
/// percent-of-total ValuesY[0] value for the slice).
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public double SliceValue
|
||
{
|
||
get { return (_SliceValue); }
|
||
internal set { _SliceValue = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SliceVisualStyles
|
||
|
||
/// <summary>
|
||
/// Gets or sets the visual styles for the slice.
|
||
/// </summary>
|
||
[Category("Style")]
|
||
[Description("Indicates the visual styles for the slice.")]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||
public ChartSliceVisualStyles SliceVisualStyles
|
||
{
|
||
get
|
||
{
|
||
if (_SliceVisualStyles == null)
|
||
{
|
||
_SliceVisualStyles = new ChartSliceVisualStyles();
|
||
|
||
StyleChangeHandler(null, _SliceVisualStyles);
|
||
}
|
||
|
||
return (_SliceVisualStyles);
|
||
}
|
||
|
||
set
|
||
{
|
||
if (_SliceVisualStyles != value)
|
||
{
|
||
ChartSliceVisualStyles oldValue = _SliceVisualStyles;
|
||
|
||
_SliceVisualStyles = value;
|
||
|
||
OnStyleChanged("SliceVisualStyles", oldValue, value);
|
||
|
||
if (oldValue != null)
|
||
oldValue.Dispose();
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region StartAngle
|
||
|
||
///<summary>
|
||
/// Gets or sets the starting angle of the slice. For subsequent slices,
|
||
/// the default is the ending angle of the previous slice. Specify a value
|
||
/// for the StartAngle if you want the next slice to start at an angle that
|
||
/// is different from the previous ending angle.
|
||
///</summary>
|
||
[DefaultValue(double.NaN), Category("Layout")]
|
||
[Description("Indicates the starting angle of the slice. For subsequent slices, the default is the ending angle of the previous slice. Specify a value for the StartAngle if you want the next slice to start at an angle that is different from the previous ending angle.")]
|
||
[Editor("DevComponents.Charts.Design.AngleRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
|
||
public double StartAngle
|
||
{
|
||
get { return (_StartAngle); }
|
||
|
||
set
|
||
{
|
||
if (value != _StartAngle)
|
||
{
|
||
_StartAngle = value;
|
||
|
||
OnPropertyChangedEx("StartAngle", Style.VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SubSliceVisualLayout
|
||
|
||
/// <summary>
|
||
/// Gets or sets the layout of the subordinate (or nested) slices.
|
||
/// </summary>
|
||
[Category("Layout")]
|
||
[Description("Indicates the layout of the subordinate (or nested) slices.")]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||
public SliceVisualLayout SubSliceVisualLayout
|
||
{
|
||
get
|
||
{
|
||
if (_SliceVisualLayout == null)
|
||
SubSliceVisualLayout = new SliceVisualLayout(null);
|
||
|
||
return (_SliceVisualLayout);
|
||
}
|
||
set
|
||
{
|
||
if (value != _SliceVisualLayout)
|
||
{
|
||
if (_SliceVisualLayout != null)
|
||
_SliceVisualLayout.PropertyChanged -= SliceVisualLayout_PropertyChanged;
|
||
|
||
_SliceVisualLayout = value;
|
||
|
||
if (_SliceVisualLayout != null)
|
||
{
|
||
_SliceVisualLayout.SliceVisualStyles.Default.Tag = "PSP_Def";
|
||
_SliceVisualLayout.SliceVisualStyles.MouseOver.Tag = "PSP_Mov";
|
||
_SliceVisualLayout.SliceVisualStyles.Selected.Tag = "PSP_Sel";
|
||
_SliceVisualLayout.SliceVisualStyles.SelectedMouseOver.Tag = "PSP_Smo";
|
||
|
||
_SliceVisualLayout.PropertyChanged += SliceVisualLayout_PropertyChanged;
|
||
}
|
||
|
||
OnPropertyChangedEx("SubSliceVisualLayout", VisualChangeType.Recalc);
|
||
}
|
||
}
|
||
}
|
||
|
||
#region SliceVisualLayout_PropertyChanged
|
||
|
||
void SliceVisualLayout_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||
{
|
||
if (e is VisualPropertyChangedEventArgs)
|
||
OnPropertyChanged(e);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region SweepAngle
|
||
|
||
///<summary>
|
||
/// Gets or sets the sweep angle of the slice (angle size, in degrees).
|
||
///</summary>
|
||
[DefaultValue(double.NaN), Category("Layout")]
|
||
[Description("Indicates the sweep angle of the slice (angle size, in degrees).")]
|
||
[Editor("DevComponents.Charts.Design.AngleRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
|
||
public double SweepAngle
|
||
{
|
||
get { return (_SweepAngle); }
|
||
|
||
set
|
||
{
|
||
if (value != _SweepAngle)
|
||
{
|
||
if (value < 0)
|
||
throw new Exception("SweepAngle cannot be negative.");
|
||
|
||
_SweepAngle = value;
|
||
|
||
OnPropertyChangedEx("SweepAngle", Style.VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ToolTipText
|
||
|
||
/// <summary>
|
||
/// Gets or sets the text to use for the point ToolTip.
|
||
/// </summary>
|
||
[DefaultValue(null), Category("Label")]
|
||
[Description("Indicates the text to use for the point ToolTip.")]
|
||
[Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]
|
||
public string ToolTipText
|
||
{
|
||
get { return (_ToolTipText); }
|
||
|
||
set
|
||
{
|
||
if (value != _ToolTipText)
|
||
{
|
||
_ToolTipText = value;
|
||
|
||
OnPropertyChanged("ToolTipText");
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Visible
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether the point is Visible.
|
||
/// </summary>
|
||
[DefaultValue(true), Category("Appearance")]
|
||
[Description("Indicates whether the point is Visible.")]
|
||
public override bool Visible
|
||
{
|
||
get { return (base.Visible); }
|
||
|
||
set
|
||
{
|
||
if (value != base.Visible)
|
||
{
|
||
base.Visible = value;
|
||
|
||
OnPropertyChangedEx("Visible", VisualChangeType.Recalc);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region Internal properties
|
||
|
||
#region AngleMarginExx
|
||
|
||
internal double AngleMarginExx
|
||
{
|
||
get { return (_AngleMarginExx); }
|
||
set { _AngleMarginExx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region AngleMarginEx
|
||
|
||
internal double AngleMarginEx
|
||
{
|
||
get { UpdatePropertyCache(); return (_AngleMarginEx); }
|
||
set { _AngleMarginEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Bounds
|
||
|
||
internal Rectangle Bounds
|
||
{
|
||
get
|
||
{
|
||
Rectangle r = new Rectangle();
|
||
r.Location = _SliceCenter;
|
||
r.Inflate(OuterRadius, OuterRadius);
|
||
|
||
return (r);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region CharBounds
|
||
|
||
internal RectangleF[] CharBounds
|
||
{
|
||
get
|
||
{
|
||
VerifyLayoutUpdateCount();
|
||
|
||
return (_CharBounds);
|
||
}
|
||
|
||
set { _CharBounds = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region HasExtent
|
||
|
||
internal bool HasExtent
|
||
{
|
||
get { return (TestState(States.HasExtent)); }
|
||
set { SetState(States.HasExtent, value); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region InnerLabelClipped
|
||
|
||
internal bool InnerLabelClipped
|
||
{
|
||
get { return (TestState(States.InnerLabelClipped)); }
|
||
set { SetState(States.InnerLabelClipped, value); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region InnerLabelDisplayed
|
||
|
||
internal bool InnerLabelDisplayed
|
||
{
|
||
get { return (TestState(States.InnerLabelDisplayed)); }
|
||
set { SetState(States.InnerLabelDisplayed, value); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region InnerLabelOrientationEx
|
||
|
||
internal SliceLabelOrientation InnerLabelOrientationEx
|
||
{
|
||
get { UpdatePropertyCache(); return (_InnerLabelOrientationEx); }
|
||
set { _InnerLabelOrientationEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region InnerSliceLabelEx
|
||
|
||
internal string InnerSliceLabelEx
|
||
{
|
||
get { UpdatePropertyCache(); return (_InnerSliceLabelEx); }
|
||
set { _InnerSliceLabelEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region InscribedRect
|
||
|
||
internal Rectangle InscribedRect
|
||
{
|
||
get
|
||
{
|
||
VerifyLayoutUpdateCount();
|
||
|
||
return (_InscribedRect);
|
||
}
|
||
|
||
set
|
||
{
|
||
_InscribedRect = value;
|
||
|
||
InscribedRectValid = true;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region InscribedRectValid
|
||
|
||
internal bool InscribedRectValid
|
||
{
|
||
get
|
||
{
|
||
VerifyLayoutUpdateCount();
|
||
|
||
return (TestState(States.InscribedRectValid));
|
||
}
|
||
|
||
set
|
||
{
|
||
SetState(States.InscribedRectValid, value);
|
||
|
||
if (value == false)
|
||
_InscribedRect = Rectangle.Empty;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsDisplayable
|
||
|
||
internal bool IsDisplayable
|
||
{
|
||
get
|
||
{
|
||
if (Visible == false || IsEmpty == true)
|
||
return (false);
|
||
|
||
if (IsInOtherEx == false)
|
||
{
|
||
object item = Parent;
|
||
|
||
while (item != null)
|
||
{
|
||
if (item is PieSeriesPointCollection)
|
||
{
|
||
if (((PieSeriesPointCollection)item).IsOther == true)
|
||
{
|
||
IsInOtherEx = true;
|
||
break;
|
||
}
|
||
|
||
item = ((PieSeriesPointCollection)item).Parent;
|
||
}
|
||
else if (item is PieSeriesPoint)
|
||
{
|
||
if (((PieSeriesPoint)item).IsInOtherEx == true)
|
||
{
|
||
IsInOtherEx = true;
|
||
break;
|
||
}
|
||
|
||
item = ((PieSeriesPoint)item).Parent;
|
||
}
|
||
else
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return (IsInOtherEx == false);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsDisplayedEx
|
||
|
||
internal bool IsDisplayedEx
|
||
{
|
||
get
|
||
{
|
||
if (Visible == true)
|
||
{
|
||
if (ChartSeries != null)
|
||
{
|
||
PieChart pieChart = ChartSeries.Parent as PieChart;
|
||
|
||
if (pieChart != null)
|
||
{
|
||
ItemCheckAction ica = (pieChart != null)
|
||
? pieChart.Legend.ItemCheckAction : ItemCheckAction.ShowItem;
|
||
|
||
return ((ica == ItemCheckAction.None ||
|
||
(ShowCheckBoxInLegend == false || CheckedInLegend == true)));
|
||
}
|
||
}
|
||
}
|
||
|
||
return (false);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsInOtherEx
|
||
|
||
internal bool IsInOtherEx
|
||
{
|
||
get { return (TestState(States.IsInOtherEx)); }
|
||
set { SetState(States.IsInOtherEx, value); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsOffset
|
||
|
||
internal bool IsOffset
|
||
{
|
||
get { return (TestState(States.IsOffset)); }
|
||
set { SetState(States.IsOffset, value); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsEnabled
|
||
|
||
internal bool IsEnabled
|
||
{
|
||
get
|
||
{
|
||
PieRing pieRing = PieRing;
|
||
|
||
if (pieRing != null)
|
||
{
|
||
if (pieRing.IsEnabled == true)
|
||
return (pieRing.IsDisplayed);
|
||
}
|
||
|
||
return (false);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region LastPathBounds
|
||
|
||
internal Rectangle LastPathBounds
|
||
{
|
||
get { return (_LastPathBounds); }
|
||
set { _LastPathBounds = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region MaxSlicesEx
|
||
|
||
internal int MaxSlicesEx
|
||
{
|
||
get { UpdatePropertyCache(); return (_MaxSlicesEx); }
|
||
set { _MaxSlicesEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region MinExtentEx
|
||
|
||
internal int MinExtentEx
|
||
{
|
||
get { UpdatePropertyCache(); return (_MinExtentEx); }
|
||
set { _MinExtentEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region MinPercentEx
|
||
|
||
internal double MinPercentEx
|
||
{
|
||
get { UpdatePropertyCache(); return (_MinPercentEx); }
|
||
set { _MinPercentEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region OuterSliceLabelEx
|
||
|
||
internal string OuterSliceLabelEx
|
||
{
|
||
get { UpdatePropertyCache(); return (_OuterSliceLabelEx); }
|
||
set { _OuterSliceLabelEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PathBounds
|
||
|
||
internal Rectangle PathBounds
|
||
{
|
||
get { return (_PathBounds); }
|
||
set { _PathBounds = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PieLabel
|
||
|
||
internal PieLabel PieLabel
|
||
{
|
||
get { return (_PieLabel); }
|
||
set { _PieLabel = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ReferenceLineDisplayModeEx
|
||
|
||
internal PieRefLineDisplayMode ReferenceLineDisplayModeEx
|
||
{
|
||
get { UpdatePropertyCache(); return (_ReferenceLineDisplayModeEx); }
|
||
set { _ReferenceLineDisplayModeEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ReferenceLineDisplayOnTopEx
|
||
|
||
internal bool ReferenceLineDisplayOnTopEx
|
||
{
|
||
get
|
||
{
|
||
UpdatePropertyCache();
|
||
|
||
return (TestState(States.ReferenceLineDisplayOnTop));
|
||
}
|
||
|
||
set { SetState(States.ReferenceLineDisplayOnTop, value); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ReferenceLinesEx
|
||
|
||
internal List<PieReferenceLine> ReferenceLinesEx
|
||
{
|
||
get { UpdatePropertyCache(); return (_ReferenceLinesEx); }
|
||
set { _ReferenceLinesEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region RenderCount
|
||
|
||
private int _RenderCount;
|
||
|
||
internal int RenderCount
|
||
{
|
||
get { return (_RenderCount); }
|
||
set { _RenderCount = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region RingWeightEx
|
||
|
||
internal int RingWeightEx
|
||
{
|
||
get { UpdatePropertyCache(); return (_RingWeightEx); }
|
||
set { _RingWeightEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region RootPsp
|
||
|
||
internal PieSeriesPoint RootPsp
|
||
{
|
||
get
|
||
{
|
||
if (_RootPsp == null)
|
||
_RootPsp = GetRootPsp();
|
||
|
||
return (_RootPsp);
|
||
}
|
||
}
|
||
|
||
#region GetRootPsp
|
||
|
||
private PieSeriesPoint GetRootPsp()
|
||
{
|
||
if (PieRing.RingLevel > 0)
|
||
{
|
||
PieSeriesPointCollection spc = Parent as PieSeriesPointCollection;
|
||
|
||
if (spc != null)
|
||
{
|
||
PieSeriesPoint psp = spc.Parent as PieSeriesPoint;
|
||
|
||
if (psp != null)
|
||
return (psp.RootPsp);
|
||
}
|
||
}
|
||
|
||
return (this);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region ShowSliceWhiteSpaceEx
|
||
|
||
internal bool ShowSliceWhiteSpaceEx
|
||
{
|
||
get
|
||
{
|
||
UpdatePropertyCache();
|
||
|
||
return (TestState(States.ShowSliceWhiteSpaceEx));
|
||
}
|
||
|
||
set { SetState(States.ShowSliceWhiteSpaceEx, value); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SliceLabelCropModeEx
|
||
|
||
internal SliceLabelCropMode SliceLabelCropModeEx
|
||
{
|
||
get { UpdatePropertyCache(); return (_SliceLabelCropModeEx); }
|
||
set { _SliceLabelCropModeEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SliceLabelDisplayModeEx
|
||
|
||
internal SliceLabelDisplayMode SliceLabelDisplayModeEx
|
||
{
|
||
get { UpdatePropertyCache(); return (_SliceLabelDisplayModeEx); }
|
||
set { _SliceLabelDisplayModeEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SliceLabelVisibilityEx
|
||
|
||
internal SliceLabelVisibility SliceLabelVisibilityEx
|
||
{
|
||
get { UpdatePropertyCache(); return (_SliceLabelVisibilityEx); }
|
||
set { _SliceLabelVisibilityEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region StartAngleEx
|
||
|
||
internal double StartAngleEx
|
||
{
|
||
get { return (_StartAngleEx); }
|
||
set { _StartAngleEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SweepAngleEx
|
||
|
||
internal double SweepAngleEx
|
||
{
|
||
get { return (_SweepAngleEx); }
|
||
set { _SweepAngleEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ToolTipTextEx
|
||
|
||
internal string ToolTipTextEx
|
||
{
|
||
get { UpdatePropertyCache(); return (_ToolTipTextEx); }
|
||
set { _ToolTipTextEx = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region WordPosLines
|
||
|
||
internal List<WordPosLine> WordPosLines
|
||
{
|
||
get
|
||
{
|
||
VerifyLayoutUpdateCount();
|
||
|
||
return (_WordPosLines);
|
||
}
|
||
|
||
set { _WordPosLines = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region VerifyLayoutUpdateCount
|
||
|
||
private void VerifyLayoutUpdateCount()
|
||
{
|
||
PieSeries series = ChartSeries;
|
||
|
||
if (series != null)
|
||
{
|
||
ChartControl chartControl = series.ChartControl;
|
||
|
||
if (chartControl != null)
|
||
{
|
||
if (_LayoutUpdateCount != chartControl.LayoutUpdateCount)
|
||
{
|
||
_WordPosLines = null;
|
||
|
||
InscribedRectValid = false;
|
||
|
||
_LayoutUpdateCount = chartControl.LayoutUpdateCount;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region UpdatePropertyCache
|
||
|
||
private void UpdatePropertyCache()
|
||
{
|
||
if (ChartControl != null)
|
||
{
|
||
if (_LocalUpdateCount != ChartControl.GlobalUpdateCount)
|
||
{
|
||
PieSeriesPointCollection spc = Parent as PieSeriesPointCollection;
|
||
|
||
if (spc != null)
|
||
{
|
||
PieSeries pieSeries = this.ChartSeries;
|
||
PieChart pieChart = pieSeries.Parent as PieChart;
|
||
|
||
_AngleMarginEx = GetAngleMarginEx(pieChart, pieSeries, spc.Parent);
|
||
_InnerLabelOrientationEx = GetSliceLabelOrientationEx(pieChart, pieSeries, spc.Parent);
|
||
_InnerSliceLabelEx = GetInnerSliceLabelEx(pieChart, pieSeries, spc.Parent);
|
||
_MaxSlicesEx = GetMaxSlicesEx(pieChart, pieSeries, spc.Parent);
|
||
_MinExtentEx = GetMinExtentEx(pieChart, pieSeries, spc.Parent);
|
||
_MinPercentEx = GetMinPercentEx(pieChart, pieSeries, spc.Parent);
|
||
_OuterSliceLabelEx = GetOuterSliceLabelEx(pieChart, pieSeries, spc.Parent);
|
||
_ReferenceLineDisplayModeEx = GetReferenceLineDisplayModeEx(pieChart, pieSeries, spc.Parent);
|
||
_ReferenceLinesEx = GetReferenceLinesEx(pieChart, pieSeries, spc.Parent);
|
||
_RingWeightEx = GetRingWeightEx(pieChart, pieSeries, spc.Parent);
|
||
|
||
SetState(States.ReferenceLineDisplayOnTop, GetReferenceLineDisplayOnTopEx(pieChart, pieSeries, spc.Parent));
|
||
SetState(States.ShowSliceWhiteSpaceEx, GetShowSliceWhiteSpaceEx(pieChart, pieSeries, spc.Parent));
|
||
|
||
_SliceLabelCropModeEx = GetSliceLabelCropModeEx(pieChart, pieSeries, spc.Parent);
|
||
_SliceLabelDisplayModeEx = GetSliceLabelDisplayModeEx(pieChart, pieSeries, spc.Parent);
|
||
_SliceLabelVisibilityEx = GetSliceLabelVisibilityEx(pieChart, pieSeries, spc.Parent);
|
||
|
||
_ToolTipTextEx = GetToolTipTextEx(pieChart, pieSeries, spc.Parent);
|
||
}
|
||
|
||
_LocalUpdateCount = ChartControl.GlobalUpdateCount;
|
||
}
|
||
}
|
||
}
|
||
|
||
#region GetAngleMarginEx
|
||
|
||
private double GetAngleMarginEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (double.IsNaN(psp.SubSliceVisualLayout.AngleMargin) == false)
|
||
return (psp.SubSliceVisualLayout.AngleMargin);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (double.IsNaN(pieSeries.SubSliceVisualLayout.AngleMargin) == false)
|
||
return (pieSeries.SubSliceVisualLayout.AngleMargin);
|
||
|
||
if (double.IsNaN(pieChart.SubSliceVisualLayout.AngleMargin) == false)
|
||
return (pieChart.SubSliceVisualLayout.AngleMargin);
|
||
|
||
return (0);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetInnerSliceLabelEx
|
||
|
||
private string GetInnerSliceLabelEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
CharBounds = null;
|
||
|
||
if (InnerSliceLabel != null)
|
||
return (InnerSliceLabel);
|
||
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (psp.SubSliceVisualLayout.InnerSliceLabel != null)
|
||
return (psp.SubSliceVisualLayout.InnerSliceLabel);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (pieSeries.SubSliceVisualLayout.InnerSliceLabel != null)
|
||
return (pieSeries.SubSliceVisualLayout.InnerSliceLabel);
|
||
|
||
if (pieChart.SubSliceVisualLayout.InnerSliceLabel != null)
|
||
return (pieChart.SubSliceVisualLayout.InnerSliceLabel);
|
||
|
||
return ("{X}");
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetMaxSlicesEx
|
||
|
||
private int GetMaxSlicesEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (psp.SubSliceVisualLayout.MaxSlices >= 0)
|
||
return (psp.SubSliceVisualLayout.MaxSlices);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (pieSeries.SubSliceVisualLayout.MaxSlices >= 0)
|
||
return (pieSeries.SubSliceVisualLayout.MaxSlices);
|
||
|
||
if (pieChart.SubSliceVisualLayout.MaxSlices >= 0)
|
||
return (pieChart.SubSliceVisualLayout.MaxSlices);
|
||
|
||
return (100);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetMinExtentEx
|
||
|
||
private int GetMinExtentEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (psp.SubSliceVisualLayout.MinExtent >= 0)
|
||
return (psp.SubSliceVisualLayout.MinExtent);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (pieSeries.SubSliceVisualLayout.MinExtent >= 0)
|
||
return (pieSeries.SubSliceVisualLayout.MinExtent);
|
||
|
||
if (pieChart.SubSliceVisualLayout.MinExtent >= 0)
|
||
return (pieChart.SubSliceVisualLayout.MinExtent);
|
||
|
||
return (0);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetMinPercentEx
|
||
|
||
private double GetMinPercentEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (double.IsNaN(psp.SubSliceVisualLayout.MinPercent) == false)
|
||
return (psp.SubSliceVisualLayout.MinPercent);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (double.IsNaN(pieSeries.SubSliceVisualLayout.MinPercent) == false)
|
||
return (pieSeries.SubSliceVisualLayout.MinPercent);
|
||
|
||
if (double.IsNaN(pieChart.SubSliceVisualLayout.MinPercent) == false)
|
||
return (pieChart.SubSliceVisualLayout.MinPercent);
|
||
|
||
return (.04d);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetOuterSliceLabelEx
|
||
|
||
private string GetOuterSliceLabelEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
if (OuterSliceLabel != null)
|
||
return (OuterSliceLabel);
|
||
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (psp.SubSliceVisualLayout.OuterSliceLabel != null)
|
||
return (psp.SubSliceVisualLayout.OuterSliceLabel);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (pieSeries.SubSliceVisualLayout.OuterSliceLabel != null)
|
||
return (pieSeries.SubSliceVisualLayout.OuterSliceLabel);
|
||
|
||
if (pieChart.SubSliceVisualLayout.OuterSliceLabel != null)
|
||
return (pieChart.SubSliceVisualLayout.OuterSliceLabel);
|
||
|
||
return ("{X}");
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetReferenceLineDisplayModeEx
|
||
|
||
private PieRefLineDisplayMode GetReferenceLineDisplayModeEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (psp.SubSliceVisualLayout.ReferenceLineDisplayMode != PieRefLineDisplayMode.NotSet)
|
||
return (psp.SubSliceVisualLayout.ReferenceLineDisplayMode);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (pieSeries.SubSliceVisualLayout.ReferenceLineDisplayMode != PieRefLineDisplayMode.NotSet)
|
||
return (pieSeries.SubSliceVisualLayout.ReferenceLineDisplayMode);
|
||
|
||
if (pieChart.SubSliceVisualLayout.ReferenceLineDisplayMode != PieRefLineDisplayMode.NotSet)
|
||
return (pieChart.SubSliceVisualLayout.ReferenceLineDisplayMode);
|
||
|
||
return (PieRefLineDisplayMode.None);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetReferenceLineDisplayOnTopEx
|
||
|
||
private bool GetReferenceLineDisplayOnTopEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (psp.SubSliceVisualLayout.ReferenceLineDisplayOnTop != Tbool.NotSet)
|
||
return (psp.SubSliceVisualLayout.ReferenceLineDisplayOnTop == Tbool.True);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (pieSeries.SubSliceVisualLayout.ReferenceLineDisplayOnTop != Tbool.NotSet)
|
||
return (pieSeries.SubSliceVisualLayout.ReferenceLineDisplayOnTop == Tbool.True);
|
||
|
||
return (pieChart.SubSliceVisualLayout.ReferenceLineDisplayOnTop != Tbool.False);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetReferenceLinesEx
|
||
|
||
private List<PieReferenceLine> GetReferenceLinesEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
List<PieReferenceLine> lines = new List<PieReferenceLine>();
|
||
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (psp.SubSliceVisualLayout._ReferenceLines != null)
|
||
AddReferenceLines(lines, psp.SubSliceVisualLayout.ReferenceLines);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (pieSeries.SubSliceVisualLayout._ReferenceLines != null)
|
||
AddReferenceLines(lines, pieSeries.SubSliceVisualLayout.ReferenceLines);
|
||
|
||
if (pieChart.SubSliceVisualLayout._ReferenceLines != null)
|
||
AddReferenceLines(lines, pieChart.SubSliceVisualLayout.ReferenceLines);
|
||
|
||
return (lines);
|
||
}
|
||
|
||
#region AddReferenceLines
|
||
|
||
private void AddReferenceLines(
|
||
List<PieReferenceLine> lines, PieReferenceLineCollection rlc)
|
||
{
|
||
foreach (PieReferenceLine line in rlc)
|
||
lines.Add(line);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region GetRingWeightEx
|
||
|
||
private int GetRingWeightEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (psp.SubSliceVisualLayout.RingWeight >= 0)
|
||
return (psp.SubSliceVisualLayout.RingWeight);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (pieSeries.SubSliceVisualLayout.RingWeight >= 0)
|
||
return (pieSeries.SubSliceVisualLayout.RingWeight);
|
||
|
||
if (pieChart.SubSliceVisualLayout.RingWeight >= 0)
|
||
return (pieChart.SubSliceVisualLayout.RingWeight);
|
||
|
||
return (100);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetShowSliceWhiteSpaceEx
|
||
|
||
private bool GetShowSliceWhiteSpaceEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (psp.SubSliceVisualLayout.ShowSliceWhiteSpace != Tbool.NotSet)
|
||
return (psp.SubSliceVisualLayout.ShowSliceWhiteSpace == Tbool.True);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (pieSeries.SubSliceVisualLayout.ShowSliceWhiteSpace != Tbool.NotSet)
|
||
return (pieSeries.SubSliceVisualLayout.ShowSliceWhiteSpace == Tbool.True);
|
||
|
||
return (pieChart.SubSliceVisualLayout.ShowSliceWhiteSpace == Tbool.True);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetSliceLabelCropModeEx
|
||
|
||
private SliceLabelCropMode GetSliceLabelCropModeEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (psp.SubSliceVisualLayout.SliceLabelCropMode != SliceLabelCropMode.NotSet)
|
||
return (psp.SubSliceVisualLayout.SliceLabelCropMode);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (pieSeries.SubSliceVisualLayout.SliceLabelCropMode != SliceLabelCropMode.NotSet)
|
||
return (pieSeries.SubSliceVisualLayout.SliceLabelCropMode);
|
||
|
||
if (pieChart.SubSliceVisualLayout.SliceLabelCropMode != SliceLabelCropMode.NotSet)
|
||
return (pieChart.SubSliceVisualLayout.SliceLabelCropMode);
|
||
|
||
return (SliceLabelCropMode.Clip);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetSliceLabelDisplayModeEx
|
||
|
||
private SliceLabelDisplayMode GetSliceLabelDisplayModeEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (psp.SubSliceVisualLayout.SliceLabelDisplayMode != SliceLabelDisplayMode.NotSet)
|
||
return (psp.SubSliceVisualLayout.SliceLabelDisplayMode);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (pieSeries.SubSliceVisualLayout.SliceLabelDisplayMode != SliceLabelDisplayMode.NotSet)
|
||
return (pieSeries.SubSliceVisualLayout.SliceLabelDisplayMode);
|
||
|
||
if (pieChart.SubSliceVisualLayout.SliceLabelDisplayMode != SliceLabelDisplayMode.NotSet)
|
||
return (pieChart.SubSliceVisualLayout.SliceLabelDisplayMode);
|
||
|
||
return (SliceLabelDisplayMode.InnerAndOuter);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetSliceLabelOrientationEx
|
||
|
||
private SliceLabelOrientation GetSliceLabelOrientationEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (psp.SubSliceVisualLayout.InnerLabelOrientation != SliceLabelOrientation.NotSet)
|
||
return (psp.SubSliceVisualLayout.InnerLabelOrientation);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (pieSeries.SubSliceVisualLayout.InnerLabelOrientation != SliceLabelOrientation.NotSet)
|
||
return (pieSeries.SubSliceVisualLayout.InnerLabelOrientation);
|
||
|
||
if (pieChart.SubSliceVisualLayout.InnerLabelOrientation != SliceLabelOrientation.NotSet)
|
||
return (pieChart.SubSliceVisualLayout.InnerLabelOrientation);
|
||
|
||
return (SliceLabelOrientation.Adaptive);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetSliceLabelVisibilityEx
|
||
|
||
private SliceLabelVisibility GetSliceLabelVisibilityEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (psp.SubSliceVisualLayout.SliceLabelVisibility != SliceLabelVisibility.NotSet)
|
||
return (psp.SubSliceVisualLayout.SliceLabelVisibility);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (pieSeries.SubSliceVisualLayout.SliceLabelVisibility != SliceLabelVisibility.NotSet)
|
||
return (pieSeries.SubSliceVisualLayout.SliceLabelVisibility);
|
||
|
||
if (pieChart.SubSliceVisualLayout.SliceLabelVisibility != SliceLabelVisibility.NotSet)
|
||
return (pieChart.SubSliceVisualLayout.SliceLabelVisibility);
|
||
|
||
return (SliceLabelVisibility.NotSet);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetToolTipTextEx
|
||
|
||
private string GetToolTipTextEx(
|
||
PieChart pieChart, PieSeries pieSeries, object item)
|
||
{
|
||
PieSeriesPoint psp = item as PieSeriesPoint;
|
||
|
||
while (psp != null)
|
||
{
|
||
if (psp.SubSliceVisualLayout.ToolTipText != null)
|
||
return (psp.SubSliceVisualLayout.ToolTipText);
|
||
|
||
psp = GetParentPsp(psp);
|
||
}
|
||
|
||
if (pieSeries.SubSliceVisualLayout.ToolTipText != null)
|
||
return (pieSeries.SubSliceVisualLayout.ToolTipText);
|
||
|
||
if (pieChart.SubSliceVisualLayout.ToolTipText != null)
|
||
return (pieChart.SubSliceVisualLayout.ToolTipText);
|
||
|
||
return ("{x}");
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetParentPsp
|
||
|
||
private PieSeriesPoint GetParentPsp(PieSeriesPoint psp)
|
||
{
|
||
PieSeriesPointCollection spc = psp.Parent as PieSeriesPointCollection;
|
||
|
||
return (spc != null) ? spc.Parent as PieSeriesPoint : null;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region GetRayEndPoint
|
||
|
||
internal Point GetRayEndPoint(double angle, double radius)
|
||
{
|
||
Point pt = SliceCenter;
|
||
|
||
double radians = MathHelper.ToRadians(angle);
|
||
|
||
pt.X += (int)(Math.Cos(radians) * radius);
|
||
pt.Y += (int)(Math.Sin(radians) * radius);
|
||
|
||
return (pt);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetLabelText
|
||
|
||
internal string GetLabelText(string pattern)
|
||
{
|
||
pattern = pattern.Replace("\\n", "\n");
|
||
pattern = pattern.Replace("\\r", "\r");
|
||
|
||
Regex regex = new Regex("{([^}]*)}");
|
||
MatchCollection mc = regex.Matches(pattern);
|
||
|
||
StringBuilder sb = new StringBuilder();
|
||
|
||
int index = 0;
|
||
|
||
foreach (Match ma in mc)
|
||
{
|
||
if (ma.Index > index)
|
||
sb.Append(pattern.Substring(index, ma.Index - index));
|
||
|
||
sb.Append(ProcessSliceLabelFmt(ma.Value));
|
||
|
||
index = ma.Index + ma.Length;
|
||
}
|
||
|
||
if (index < pattern.Length)
|
||
sb.Append(pattern.Substring(index));
|
||
|
||
return (sb.ToString());
|
||
}
|
||
|
||
#region ProcessSliceLabelFmt
|
||
|
||
/// "AVG" "A" - Average (angular values).
|
||
/// "PCT" "P" - Percent of pie (angular values) - (.025 yields "2.5 %").
|
||
/// "TOT" "T" - Total of all values (angluar values).
|
||
/// "VAL" "V" - Value percent of pie (angular value) - (.025 yields ".025").
|
||
///
|
||
/// "AVGX" "AX" - Average (extent/radial values).
|
||
/// "PCTX" "PX" - Percent of pie (extent values) - (.025 yields "2.5 %").
|
||
/// "TOTX" "TX" - Total of all values (extent values).
|
||
/// "VALX" "VX" - Value percent of pie (extent value) - (.025 yields ".025").
|
||
///
|
||
/// "S" "SNAME" - Series name.
|
||
/// "X" - ValueX.
|
||
/// "Y", "Y0", "Yn" - ValueY values (where 'n' is index value).
|
||
///
|
||
/// Use: {format[:specifier]}
|
||
|
||
private string ProcessSliceLabelFmt(string pattern)
|
||
{
|
||
string s = pattern.Substring(1, pattern.Length - 2);
|
||
|
||
int n = s.IndexOf(':');
|
||
|
||
if ((uint)n > s.Length - 1)
|
||
n = s.Length;
|
||
|
||
string placeHolder = s.Substring(0, n).Trim().ToUpper();
|
||
string formatSpecifier = (n + 1 < s.Length) ? s.Substring(n + 1) : "";
|
||
|
||
try
|
||
{
|
||
PieSeriesPointCollection spc = Parent as PieSeriesPointCollection;
|
||
|
||
switch (placeHolder)
|
||
{
|
||
case "A":
|
||
case "AVG":
|
||
if (spc != null)
|
||
return (GetSliceLabelText(spc.PieAverage, formatSpecifier));
|
||
break;
|
||
|
||
case "AX":
|
||
case "AVGX":
|
||
if (spc != null)
|
||
return (GetSliceLabelText(spc.PieAverageExtent, formatSpecifier));
|
||
break;
|
||
|
||
case "N":
|
||
case "NAME":
|
||
if (string.IsNullOrEmpty(formatSpecifier) == false)
|
||
return (String.Format(formatSpecifier, Name));
|
||
|
||
return (Name);
|
||
|
||
case "P":
|
||
case "PCT":
|
||
if (string.IsNullOrEmpty(formatSpecifier) == false)
|
||
return (SliceValue.ToString(formatSpecifier));
|
||
|
||
return (GetSliceLabelText(SliceValue, "P"));
|
||
|
||
case "PX":
|
||
case "PCTX":
|
||
if (string.IsNullOrEmpty(formatSpecifier) == false)
|
||
return (SliceExtent.ToString(formatSpecifier));
|
||
|
||
return (GetSliceLabelText(SliceExtent, "P"));
|
||
|
||
case "S":
|
||
case "SNAME":
|
||
string sname = ChartSeries != null ? ChartSeries.Name : "";
|
||
|
||
if (string.IsNullOrEmpty(formatSpecifier) == false)
|
||
return (String.Format(formatSpecifier, sname));
|
||
|
||
return (sname);
|
||
|
||
case "T":
|
||
case "TOTA":
|
||
if (spc != null)
|
||
return (GetSliceLabelText(spc.PieTotal, formatSpecifier));
|
||
break;
|
||
|
||
case "TX":
|
||
case "TOTX":
|
||
if (spc != null)
|
||
return (GetSliceLabelText(spc.PieTotalExtent, formatSpecifier));
|
||
break;
|
||
|
||
case "V":
|
||
case "VAL":
|
||
return (GetSliceLabelText(SliceValue, formatSpecifier));
|
||
|
||
case "VX":
|
||
case "VALX":
|
||
return (GetSliceLabelText(SliceExtent, formatSpecifier));
|
||
|
||
case "X":
|
||
return (GetSliceLabelText(ValueX, formatSpecifier));
|
||
|
||
case "Y":
|
||
case "Y0":
|
||
if (ValueY != null && ValueY.Length > 0)
|
||
return (GetSliceLabelText(ValueY[0], formatSpecifier));
|
||
|
||
return ("");
|
||
|
||
default:
|
||
if (placeHolder.StartsWith("Y") == true)
|
||
{
|
||
int index = int.Parse(placeHolder.Substring(1));
|
||
|
||
if (ValueY != null && ValueY.Length > index)
|
||
return (GetSliceLabelText(ValueY[index], formatSpecifier));
|
||
}
|
||
|
||
return (s);
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
}
|
||
|
||
return (s);
|
||
}
|
||
|
||
#region GetSliceLabelText
|
||
|
||
private string GetSliceLabelText(object value, string format)
|
||
{
|
||
if (value is string)
|
||
{
|
||
if (string.IsNullOrEmpty(format) == true)
|
||
return ((string)value);
|
||
|
||
return (String.Format(format, value));
|
||
}
|
||
else
|
||
{
|
||
double d = Convert.ToDouble(value);
|
||
|
||
if (string.IsNullOrEmpty(format) == false)
|
||
return (d.ToString(format));
|
||
|
||
return (d.ToString("F3"));
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region Style handling
|
||
|
||
#region GetEffectiveSliceStyle
|
||
|
||
public ChartSliceVisualStyle
|
||
GetEffectiveSliceStyle(PieChart pieChart, PieSeries series)
|
||
{
|
||
StyleState state = StyleState.Default;
|
||
|
||
if (series.IsHighLightedPsp(pieChart, this) == true)
|
||
state |= StyleState.MouseOver;
|
||
|
||
if (IsSelected == true)
|
||
state |= StyleState.Selected;
|
||
|
||
ChartSliceVisualStyle estyle = EffectiveSliceStyles[state];
|
||
|
||
if (_WordPosLines != null)
|
||
{
|
||
if (_LastEffectiveStyle != null)
|
||
{
|
||
if (EqualFonts(estyle.SliceInnerLabelStyle.Font,
|
||
_LastEffectiveStyle.SliceInnerLabelStyle.Font) == false)
|
||
{
|
||
_CharBounds = null;
|
||
_WordPosLines = null;
|
||
}
|
||
}
|
||
|
||
_LastEffectiveStyle = estyle;
|
||
}
|
||
|
||
return (estyle);
|
||
}
|
||
|
||
#region EqualFonts
|
||
|
||
private bool EqualFonts(Font font1, Font font2)
|
||
{
|
||
if (font1 == null || font2 == null)
|
||
return (false);
|
||
|
||
return (font1.Name == font2.Name &&
|
||
font1.SizeInPoints == font2.SizeInPoints &&
|
||
font1.Style == font2.Style);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region ApplyStyles
|
||
|
||
public void ApplyStyles(BaseVisualStyle style)
|
||
{
|
||
}
|
||
|
||
public void ApplyStyles(BaseVisualStyle style, StyleType cs)
|
||
{
|
||
ChartSliceVisualStyle sstyle = style as ChartSliceVisualStyle;
|
||
|
||
if (sstyle != null)
|
||
{
|
||
PieSeriesPointCollection spc = Parent as PieSeriesPointCollection;
|
||
PieSeries series = ChartSeries;
|
||
|
||
if (IsOther == true)
|
||
{
|
||
ApplyOtherParentStyles(sstyle, cs, series.Parent as ChartContainer);
|
||
|
||
sstyle.ApplyStyle(series.SubSliceVisualLayout.OtherSliceVisualStyles[cs]);
|
||
|
||
ApplyOtherParentPspStyle(sstyle, cs, this);
|
||
}
|
||
else
|
||
{
|
||
ApplyParentStyles(sstyle, cs, series.Parent as ChartContainer);
|
||
|
||
sstyle.ApplyStyle(series.SubSliceVisualLayout.SliceVisualStyles[cs]);
|
||
|
||
ApplyParentPspStyle(sstyle, cs, this);
|
||
}
|
||
|
||
sstyle.ApplyStyle(SliceVisualStyles[cs]);
|
||
}
|
||
}
|
||
|
||
#region ApplyOtherParentStyles
|
||
|
||
private void ApplyOtherParentStyles(
|
||
ChartSliceVisualStyle sstyle, StyleType cs, ChartContainer item)
|
||
{
|
||
if (item != null)
|
||
{
|
||
ApplyOtherParentStyles(sstyle, cs, item.Parent as ChartContainer);
|
||
|
||
ChartPanel panel = item as ChartPanel;
|
||
|
||
if (panel != null)
|
||
{
|
||
sstyle.ApplyStyle(panel.DefaultVisualStyles.OtherSliceVisualStyles[cs]);
|
||
}
|
||
else
|
||
{
|
||
PieChart pieChart = item as PieChart;
|
||
|
||
if (pieChart != null)
|
||
sstyle.ApplyStyle(pieChart.SubSliceVisualLayout.OtherSliceVisualStyles[cs]);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ChartControl chartControl = ChartControl;
|
||
|
||
if (chartControl != null)
|
||
{
|
||
sstyle.ApplyStyle(chartControl.BaseVisualStyles.OtherSliceVisualStyles[cs]);
|
||
sstyle.ApplyStyle(chartControl.DefaultVisualStyles.OtherSliceVisualStyles[cs]);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ApplyOtherParentPspStyle
|
||
|
||
private void ApplyOtherParentPspStyle(
|
||
ChartSliceVisualStyle sstyle, StyleType cs, PieSeriesPoint psp)
|
||
{
|
||
psp = GetParentPsp(psp);
|
||
|
||
if (psp != null)
|
||
{
|
||
ApplyOtherParentPspStyle(sstyle, cs, psp);
|
||
|
||
sstyle.ApplyStyle(psp.SubSliceVisualLayout.OtherSliceVisualStyles[cs]);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ApplyParentStyles
|
||
|
||
private void ApplyParentStyles(
|
||
ChartSliceVisualStyle sstyle, StyleType cs, ChartContainer item)
|
||
{
|
||
if (item != null)
|
||
{
|
||
ApplyParentStyles(sstyle, cs, item.Parent as ChartContainer);
|
||
|
||
if (item is PieChart)
|
||
sstyle.ApplyStyle(((PieChart)item).SubSliceVisualLayout.SliceVisualStyles[cs]);
|
||
|
||
if (item is ChartPanel)
|
||
sstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.SliceVisualStyles[cs]);
|
||
}
|
||
else
|
||
{
|
||
ChartControl chartControl = ChartControl;
|
||
|
||
if (chartControl != null)
|
||
{
|
||
sstyle.ApplyStyle(ChartControl.BaseVisualStyles.SliceVisualStyles[cs]);
|
||
sstyle.ApplyStyle(ChartControl.DefaultVisualStyles.SliceVisualStyles[cs]);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ApplyParentPspStyle
|
||
|
||
private void ApplyParentPspStyle(
|
||
ChartSliceVisualStyle sstyle, StyleType cs, PieSeriesPoint psp)
|
||
{
|
||
psp = GetParentPsp(psp);
|
||
|
||
if (psp != null)
|
||
{
|
||
ApplyParentPspStyle(sstyle, cs, psp);
|
||
|
||
sstyle.ApplyStyle(psp.SubSliceVisualLayout.SliceVisualStyles[cs]);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region ApplyDefaults
|
||
|
||
public void ApplyDefaults(BaseVisualStyle style, StyleType styleType)
|
||
{
|
||
ChartSliceVisualStyle sstyle = style as ChartSliceVisualStyle;
|
||
|
||
if (sstyle != null)
|
||
{
|
||
HatchFillType hatch = HatchFillType.LightUpwardDiagonal;
|
||
|
||
switch (styleType)
|
||
{
|
||
case StyleType.Default:
|
||
if (sstyle.Background.IsEmpty == true)
|
||
sstyle.Background = new Background(DefaultPaletteColor);
|
||
|
||
if (sstyle.WhiteSpaceBackground.IsEmpty == true)
|
||
sstyle.WhiteSpaceBackground = new Background(Color.FromArgb(100, DefaultPaletteColor));
|
||
|
||
if (sstyle.WhiteSpaceBorder.LinePattern == LinePattern.NotSet)
|
||
sstyle.WhiteSpaceBorder.LinePattern = LinePattern.Solid;
|
||
|
||
break;
|
||
|
||
case StyleType.MouseOver:
|
||
if (sstyle.Background.IsEmpty == true)
|
||
sstyle.Background = new Background(ControlPaint.Light(DefaultPaletteColor));
|
||
|
||
if (sstyle.WhiteSpaceBackground.IsEmpty == true)
|
||
sstyle.WhiteSpaceBackground = new Background(Color.FromArgb(50, DefaultPaletteColor));
|
||
|
||
if (sstyle.WhiteSpaceBorder.LinePattern == LinePattern.NotSet)
|
||
sstyle.WhiteSpaceBorder.LinePattern = LinePattern.Solid;
|
||
|
||
break;
|
||
|
||
case StyleType.Selected:
|
||
if (sstyle.Background.IsEmpty == true)
|
||
{
|
||
sstyle.Background = new Background(Color.White, DefaultPaletteColor);
|
||
sstyle.Background.HatchFillType = hatch;
|
||
}
|
||
|
||
if (sstyle.Border.LineWidth < 0)
|
||
sstyle.Border.LineWidth = 2;
|
||
|
||
if (sstyle.WhiteSpaceBackground.IsEmpty == true)
|
||
{
|
||
sstyle.WhiteSpaceBackground = new Background(Color.White, Color.FromArgb(100, DefaultPaletteColor));
|
||
sstyle.WhiteSpaceBackground.HatchFillType = hatch;
|
||
}
|
||
|
||
if (sstyle.WhiteSpaceBorder.LineWidth < 0)
|
||
sstyle.WhiteSpaceBorder.LineWidth = 2;
|
||
|
||
break;
|
||
|
||
case StyleType.SelectedMouseOver:
|
||
if (sstyle.Background.IsEmpty == true)
|
||
{
|
||
sstyle.Background = new Background(Color.White, ControlPaint.Light(DefaultPaletteColor));
|
||
sstyle.Background.HatchFillType = hatch;
|
||
}
|
||
|
||
if (sstyle.Border.LineWidth < 0)
|
||
sstyle.Border.LineWidth = 2;
|
||
|
||
if (sstyle.WhiteSpaceBackground.IsEmpty == true)
|
||
{
|
||
sstyle.WhiteSpaceBackground = new Background(Color.White, Color.FromArgb(50, DefaultPaletteColor));
|
||
sstyle.WhiteSpaceBackground.HatchFillType = hatch;
|
||
}
|
||
|
||
if (sstyle.WhiteSpaceBorder.LineWidth < 0)
|
||
sstyle.WhiteSpaceBorder.LineWidth = 2;
|
||
|
||
break;
|
||
}
|
||
|
||
if (sstyle.Border.LineColor.IsEmpty == true)
|
||
sstyle.Border.LineColor = DefaultPaletteColor;
|
||
|
||
if (sstyle.WhiteSpaceBorder.LineColor.IsEmpty == true)
|
||
sstyle.WhiteSpaceBorder.LineColor = DefaultPaletteColor;
|
||
|
||
if (sstyle.ExtentAverageRefLineStyle.LineColor.IsEmpty == true)
|
||
sstyle.ExtentAverageRefLineStyle.LineColor = Color.DimGray;
|
||
|
||
if (sstyle.ExtentMinRefLineStyle.LineColor.IsEmpty == true)
|
||
sstyle.ExtentMinRefLineStyle.LineColor = Color.DimGray;
|
||
|
||
if (sstyle.ExtentMaxRefLineStyle.LineColor.IsEmpty == true)
|
||
sstyle.ExtentMaxRefLineStyle.LineColor = Color.DimGray;
|
||
|
||
if (sstyle.ExtentOuterRefLineStyle.LineColor.IsEmpty == true)
|
||
sstyle.ExtentOuterRefLineStyle.LineColor = Color.DimGray;
|
||
|
||
if (sstyle.SliceOuterLabelStyle.TextColor.IsEmpty == true)
|
||
sstyle.SliceOuterLabelStyle.TextColor = DefaultPaletteColor;
|
||
|
||
sstyle.ApplyDefaults();
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetElementStyle
|
||
|
||
public virtual void GetElementStyle(
|
||
IEffectiveStyle chartElement, StyleType styleType, ref BaseVisualStyle style)
|
||
{
|
||
ChartControl chartControl = ChartControl;
|
||
|
||
if (chartControl != null)
|
||
chartControl.DoGetPieSeriesPointStyleEvent(this, styleType, ref style);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ChartControl
|
||
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public ChartControl ChartControl
|
||
{
|
||
get
|
||
{
|
||
if (_ChartControl == null)
|
||
{
|
||
if (ChartSeries != null)
|
||
_ChartControl = ChartSeries.ChartControl;
|
||
}
|
||
|
||
return (_ChartControl);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ClearEffectiveStyles
|
||
|
||
protected void ClearEffectiveStyles()
|
||
{
|
||
_EffectiveSliceStyles.InvalidateStyles();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region OnStyleChanged
|
||
|
||
protected virtual void OnStyleChanged(string property,
|
||
INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue)
|
||
{
|
||
StyleChangeHandler(oldValue, newValue);
|
||
|
||
OnPropertyChanged(property);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region StyleChangeHandler
|
||
|
||
protected void StyleChangeHandler(
|
||
INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue)
|
||
{
|
||
if (oldValue != null)
|
||
oldValue.PropertyChanged -= StyleChanged;
|
||
|
||
if (newValue != null)
|
||
newValue.PropertyChanged += StyleChanged;
|
||
}
|
||
|
||
#region StyleChanged
|
||
|
||
/// <summary>
|
||
/// Occurs when one of element visual styles has property changes.
|
||
/// Default implementation invalidates visual appearance of element.
|
||
/// </summary>
|
||
/// <param name="sender">VisualStyle that changed.</param>
|
||
/// <param name="e">Event arguments.</param>
|
||
protected void StyleChanged(object sender, PropertyChangedEventArgs e)
|
||
{
|
||
VisualChangeType changeType = ((VisualPropertyChangedEventArgs)e).ChangeType;
|
||
|
||
PieSeries series = ChartSeries;
|
||
|
||
if (series != null)
|
||
{
|
||
if (series.ChartControl != null)
|
||
series.ChartControl.GlobalUpdateCount++;
|
||
|
||
if (changeType == VisualChangeType.Layout)
|
||
series.InvalidateLayout();
|
||
else
|
||
series.InvalidateRender();
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region ILegendItem
|
||
|
||
#region ChartLegendItemVisualStyles
|
||
|
||
/// <summary>
|
||
/// Gets or sets the visual styles for the Legend item.
|
||
/// </summary>
|
||
[Category("Style")]
|
||
[Description("Indicates the visual styles for the Legend item.")]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||
public ChartLegendItemVisualStyles ChartLegendItemVisualStyles
|
||
{
|
||
get
|
||
{
|
||
if (_ChartLegendItemVisualStyles == null)
|
||
{
|
||
_ChartLegendItemVisualStyles = new ChartLegendItemVisualStyles();
|
||
|
||
StyleChangeHandler(null, _ChartLegendItemVisualStyles);
|
||
}
|
||
|
||
return (_ChartLegendItemVisualStyles);
|
||
}
|
||
|
||
set
|
||
{
|
||
if (_ChartLegendItemVisualStyles != value)
|
||
{
|
||
ChartLegendItemVisualStyles oldValue = _ChartLegendItemVisualStyles;
|
||
|
||
_ChartLegendItemVisualStyles = value;
|
||
|
||
OnStyleChanged("ChartLegendItemVisualStyles", oldValue, value);
|
||
|
||
if (oldValue != null)
|
||
oldValue.Dispose();
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region CheckedInLegend
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether the item is checked in the Legend.
|
||
/// </summary>
|
||
[DefaultValue(true), Category("Legend")]
|
||
[Description("Indicates whether the item is checked in the Legend.")]
|
||
public bool CheckedInLegend
|
||
{
|
||
get { return (TestState(States.CheckedInLegend)); }
|
||
|
||
set
|
||
{
|
||
if (value != CheckedInLegend)
|
||
{
|
||
SetState(States.CheckedInLegend, value);
|
||
|
||
if (LegendItem != null)
|
||
LegendItem.UpdateCheckState();
|
||
|
||
OnPropertyChangedEx("CheckedInLegend", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ShowCheckBoxInLegend
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether a checkbox for the item is shown in the Legend.
|
||
/// </summary>
|
||
[DefaultValue(false), Category("Legend")]
|
||
[Description("Indicates whether a checkbox for the item is shown in the Legend.")]
|
||
public bool ShowCheckBoxInLegend
|
||
{
|
||
get { return (TestState(States.ShowCheckBoxInLegend)); }
|
||
|
||
set
|
||
{
|
||
if (value != ShowCheckBoxInLegend)
|
||
{
|
||
SetState(States.ShowCheckBoxInLegend, value);
|
||
|
||
OnPropertyChangedEx("ShowCheckBoxInLegend", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ShowInLegend
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether the item is shown in the Legend.
|
||
/// </summary>
|
||
[DefaultValue(true), Category("Legend")]
|
||
[Description("Indicates whether the item is shown in the Legend.")]
|
||
public bool ShowInLegend
|
||
{
|
||
get { return (TestState(States.ShowInLegend)); }
|
||
|
||
set
|
||
{
|
||
if (value != ShowInLegend)
|
||
{
|
||
SetState(States.ShowInLegend, value);
|
||
|
||
OnPropertyChangedEx("ShowInLegend", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ShowInParentLegend
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether the item Line is shown in parent Legend(s).
|
||
/// </summary>
|
||
[DefaultValue(true), Category("Legend")]
|
||
[Description("Indicates whether the item Line is shown in parent Legend(s).")]
|
||
public bool ShowInParentLegend
|
||
{
|
||
get { return (TestState(States.ShowInParentLegend)); }
|
||
|
||
set
|
||
{
|
||
if (value != ShowInParentLegend)
|
||
{
|
||
SetState(States.ShowInParentLegend, value);
|
||
|
||
OnPropertyChangedEx("ShowInParentLegend", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ShowMarkerInLegend
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether the item Marker is shown in the Legend.
|
||
/// </summary>
|
||
[DefaultValue(true), Category("Legend")]
|
||
[Description("Indicates whether the item Marker is shown in the Legend.")]
|
||
public bool ShowMarkerInLegend
|
||
{
|
||
get { return (TestState(States.ShowMarkerInLegend)); }
|
||
|
||
set
|
||
{
|
||
if (value != ShowMarkerInLegend)
|
||
{
|
||
SetState(States.ShowMarkerInLegend, value);
|
||
|
||
OnPropertyChangedEx("ShowMarkerInLegend", VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region LegendItem
|
||
|
||
///<summary>
|
||
/// Gets the item's parent LegendItem.
|
||
///</summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
[Description("Indicates the item's parent LegendItem.")]
|
||
public ChartLegendItem LegendItem
|
||
{
|
||
get
|
||
{
|
||
if (_LegendItem == null)
|
||
{
|
||
_LegendItem = new ChartLegendItem();
|
||
|
||
_LegendItem.Name = (ValueX != null ? ValueX.ToString() : "");
|
||
|
||
if (string.IsNullOrEmpty(_LegendItem.Name) == true)
|
||
_LegendItem.Name = "(Psp)";
|
||
|
||
_LegendItem.ChartItems.Add(this);
|
||
}
|
||
|
||
return (_LegendItem);
|
||
}
|
||
|
||
internal set { _LegendItem = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region LegendText
|
||
|
||
///<summary>
|
||
/// Gets or sets the text to display in the legend.
|
||
///</summary>
|
||
[DefaultValue(null), Category("Legend")]
|
||
[Description("Indicates the text to display in the legend.")]
|
||
[NotifyParentProperty(true)]
|
||
public string LegendText
|
||
{
|
||
get { return (_LegendText); }
|
||
|
||
set
|
||
{
|
||
if (value != _LegendText)
|
||
{
|
||
_LegendText = value;
|
||
|
||
OnPropertyChangedEx("LegendText", Style.VisualChangeType.Layout);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetLegendItem
|
||
|
||
/// <summary>
|
||
/// Creates the LegendItem for the item.
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public ChartLegendItem GetLegendItem()
|
||
{
|
||
ChartLegendItem item = LegendItem;
|
||
|
||
if (ShowInLegend == true)
|
||
{
|
||
item.CheckState = (CheckedInLegend == true)
|
||
? CheckState.Checked : CheckState.Unchecked;
|
||
|
||
item.ItemText = LegendText;
|
||
item.IsEnabled = IsEnabled;
|
||
|
||
}
|
||
|
||
return (item);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetLegendItems
|
||
|
||
/// <summary>
|
||
/// Creates a list of legend items associated with
|
||
/// the item.
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public List<ChartLegendItem> GetLegendItems()
|
||
{
|
||
List<ChartLegendItem> list = null;
|
||
|
||
ChartLegendItem litem = GetLegendItem();
|
||
|
||
if (litem != null)
|
||
{
|
||
list = new List<ChartLegendItem>(1);
|
||
|
||
list.Add(litem);
|
||
}
|
||
|
||
return (list);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetLegendItemColor
|
||
|
||
/// <summary>
|
||
/// Gets the default color associated with the legend item.
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public Color GetLegendItemColor()
|
||
{
|
||
ChartSliceVisualStyle sstyle = EffectiveSliceStyles[StyleState.Default];
|
||
|
||
Color color = sstyle.Background.Color1;
|
||
|
||
if (color.IsEmpty == false)
|
||
return (color);
|
||
|
||
return (Color.DimGray);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region RenderLegendItemMarker
|
||
|
||
/// <summary>
|
||
/// Renders the Legend item Marker.
|
||
/// </summary>
|
||
/// <param name="g"></param>
|
||
/// <param name="litem"></param>
|
||
/// <param name="style"></param>
|
||
public void RenderLegendItemMarker(Graphics g,
|
||
ChartLegendItem litem, ChartLegendItemVisualStyle style)
|
||
{
|
||
ChartSliceVisualStyle sstyle = EffectiveSliceStyles[StyleState.Default];
|
||
|
||
Rectangle r = litem.MarkerBounds;
|
||
r.Inflate(-1, -1);
|
||
|
||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||
|
||
using (GraphicsPath path = new GraphicsPath())
|
||
{
|
||
Point pt = new Point(r.Right - 2, r.Bottom - 2);
|
||
|
||
r.Height += (r.Height - 4);
|
||
r.Width += (r.Width - 4);
|
||
|
||
path.AddArc(r, 180, 90);
|
||
path.AddLine(pt, pt);
|
||
|
||
path.CloseFigure();
|
||
|
||
if (IsEnabled == true)
|
||
{
|
||
if (sstyle.Background.IsEmpty == true)
|
||
{
|
||
g.FillPath(Brushes.LightPink, path);
|
||
}
|
||
else
|
||
{
|
||
using (Brush br = sstyle.Background.GetBrush(r))
|
||
g.FillPath(br, path);
|
||
|
||
if (sstyle.Background.Color1.IsEmpty == false)
|
||
{
|
||
using (Pen pen = new Pen(sstyle.Background.Color1))
|
||
g.DrawPath(pen, path);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Background back = style.DisabledMarkerBackground;
|
||
|
||
if (back.IsEmpty == true)
|
||
{
|
||
using (Brush br = new SolidBrush(Color.LightGray))
|
||
g.FillPath(br, path);
|
||
}
|
||
else
|
||
{
|
||
using (Brush br = back.GetBrush(r))
|
||
g.FillPath(br, path);
|
||
|
||
if (back.Color1.IsEmpty == false)
|
||
{
|
||
using (Pen pen = new Pen(sstyle.Background.Color1))
|
||
g.DrawPath(pen, path);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region TrackLegendItem
|
||
|
||
/// <summary>
|
||
/// Gets whether legend item tracking is enabled.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public bool TrackLegendItem
|
||
{
|
||
get
|
||
{
|
||
if (ChartSeries != null)
|
||
return (ChartSeries.TrackLegendItem);
|
||
|
||
return (false);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region FormatItemText
|
||
|
||
/// <summary>
|
||
/// Formats the provided item text.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public string FormatItemText(string text)
|
||
{
|
||
return (GetLabelText(text));
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region States
|
||
|
||
[Flags]
|
||
private enum States : uint
|
||
{
|
||
AllowDetach = (1U << 0),
|
||
AllowSelect = (1U << 1),
|
||
|
||
Detached = (1U << 2),
|
||
Selected = (1U << 3),
|
||
|
||
IsOther = (1U << 4),
|
||
IsInOther = (1U << 5),
|
||
IsInOtherEx = (1U << 6),
|
||
|
||
InnerLabelClipped = (1U << 7),
|
||
InnerLabelDisplayed = (1U << 8),
|
||
|
||
IsOffset = (1U << 9),
|
||
InscribedRectValid = (1 << 10),
|
||
|
||
CheckedInLegend = (1U << 11),
|
||
ShowInLegend = (1U << 12),
|
||
ShowInParentLegend = (1U << 13),
|
||
ShowCheckBoxInLegend = (1U << 14),
|
||
ShowMarkerInLegend = (1U << 15),
|
||
|
||
ReferenceLineDisplayOnTop = (1U << 16),
|
||
ShowSliceWhiteSpaceEx = (1U << 17),
|
||
|
||
HasExtent = (1U << 18),
|
||
}
|
||
|
||
#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 Copy/CopyTo
|
||
|
||
/// <summary>
|
||
/// Creates a copy of the PieSeriesPoint
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public new PieSeriesPoint Copy()
|
||
{
|
||
PieSeriesPoint copy = new PieSeriesPoint(ValueX, 0);
|
||
|
||
CopyTo(copy);
|
||
|
||
return (copy);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Copies the item data to the given PieSeriesPoint.
|
||
/// </summary>
|
||
/// <param name="sp"></param>
|
||
public void CopyTo(PieSeriesPoint c)
|
||
{
|
||
base.CopyTo(c);
|
||
|
||
c.AllowDetach = AllowDetach;
|
||
c.AllowSelect = AllowSelect;
|
||
|
||
c.DetachedOffset = DetachedOffset;
|
||
c.InnerSliceLabel = InnerSliceLabel;
|
||
c.IsDetached = IsDetached;
|
||
c.IsInOther = IsInOther;
|
||
c.IsSelected = IsSelected;
|
||
c.Name = Name;
|
||
c.OuterSliceLabel = OuterSliceLabel;
|
||
|
||
if (_SeriesPoints != null)
|
||
{
|
||
PieSeriesPointCollection spc = SeriesPoints;
|
||
|
||
if (spc.Count > 0)
|
||
{
|
||
foreach (PieSeriesPoint psp in spc)
|
||
{
|
||
PieSeriesPoint pspCopy = psp.Copy();
|
||
|
||
c.SeriesPoints.Add(pspCopy);
|
||
}
|
||
}
|
||
}
|
||
|
||
c.SubSliceVisualLayout = (_SliceVisualLayout != null) ? _SliceVisualLayout.Copy() : null;
|
||
c.SliceVisualStyles = (_SliceVisualStyles != null) ? _SliceVisualStyles.Copy() : null;
|
||
|
||
c.StartAngle = StartAngle;
|
||
c.SweepAngle = SweepAngle;
|
||
|
||
c.CheckedInLegend = CheckedInLegend;
|
||
c.LegendText = LegendText;
|
||
c.ShowCheckBoxInLegend = ShowCheckBoxInLegend;
|
||
c.ShowInLegend = ShowInLegend;
|
||
c.ShowInParentLegend = ShowInParentLegend;
|
||
c.ShowMarkerInLegend = ShowMarkerInLegend;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetSerialData
|
||
|
||
internal override SerialElementCollection GetSerialData(bool root)
|
||
{
|
||
SerialElementCollection sec = new SerialElementCollection();
|
||
|
||
if (root == true)
|
||
sec.AddStartElement("SeriesPoint");
|
||
|
||
sec.AddValue("AllowDetach", AllowDetach, true);
|
||
sec.AddValue("AllowSelect", AllowSelect, true);
|
||
sec.AddValue("DetachedOffset", DetachedOffset, double.NaN);
|
||
sec.AddValue("InnerSliceLabel", InnerSliceLabel, null);
|
||
sec.AddValue("IsDetached", IsDetached, false);
|
||
sec.AddValue("IsInOther", IsInOther, false);
|
||
sec.AddValue("IsSelected", IsSelected, false);
|
||
sec.AddValue("Name", Name, null);
|
||
sec.AddValue("OuterSliceLabel", OuterSliceLabel, null);
|
||
|
||
sec.AddValue("StartAngle", StartAngle, double.NaN);
|
||
sec.AddValue("SweepAngle", SweepAngle, double.NaN);
|
||
|
||
if (_SeriesPoints != null)
|
||
{
|
||
PieSeriesPointCollection spc = SeriesPoints;
|
||
|
||
if (spc.Count > 0)
|
||
{
|
||
sec.AddStartElement("SeriesPoints count=\"" + spc.Count + "\"");
|
||
|
||
foreach (PieSeriesPoint psp in spc)
|
||
sec.AddElement(psp.GetSerialData());
|
||
|
||
sec.AddEndElement("SeriesPoints");
|
||
}
|
||
}
|
||
|
||
if (_SliceVisualLayout != null)
|
||
sec.AddElement(_SliceVisualLayout.GetSerialData());
|
||
|
||
if (_SliceVisualStyles != null && _SliceVisualStyles.IsEmpty == false)
|
||
sec.AddElement(_SliceVisualStyles.GetSerialData("SliceVisualStyles"));
|
||
|
||
sec.AddValue("CheckedInLegend", CheckedInLegend, true);
|
||
sec.AddValue("LegendText", LegendText, null);
|
||
sec.AddValue("ShowCheckBoxInLegend", ShowCheckBoxInLegend, true);
|
||
sec.AddValue("ShowInLegend", ShowInLegend, true);
|
||
sec.AddValue("ShowInParentLegend", ShowInParentLegend, true);
|
||
sec.AddValue("ShowMarkerInLegend", ShowMarkerInLegend, true);
|
||
|
||
sec.AddElement(base.GetSerialData(false));
|
||
|
||
if (root == true)
|
||
sec.AddEndElement("SeriesPoint");
|
||
|
||
return (sec);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PutSerialData
|
||
|
||
#region ProcessValue
|
||
|
||
internal override void ProcessValue(SerialElement se)
|
||
{
|
||
switch (se.Name)
|
||
{
|
||
case "AllowDetach":
|
||
AllowDetach = bool.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "AllowSelect":
|
||
AllowSelect = bool.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "DetachedOffset":
|
||
DetachedOffset = double.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "InnerSliceLabel":
|
||
InnerSliceLabel = se.StringValue;
|
||
break;
|
||
|
||
case "IsDetached":
|
||
IsDetached = bool.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "IsInOther":
|
||
IsInOther = bool.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "IsSelected":
|
||
IsSelected = bool.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "Name":
|
||
Name = se.StringValue;
|
||
break;
|
||
|
||
case "OuterSliceLabel":
|
||
OuterSliceLabel = se.StringValue;
|
||
break;
|
||
|
||
case "StartAngle":
|
||
StartAngle = double.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "SweepAngle":
|
||
SweepAngle = double.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "CheckedInLegend":
|
||
CheckedInLegend = bool.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "LegendText":
|
||
LegendText = se.StringValue;
|
||
break;
|
||
|
||
case "ShowCheckBoxInLegend":
|
||
ShowCheckBoxInLegend = bool.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "ShowInLegend":
|
||
ShowInLegend = bool.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "ShowInParentLegend":
|
||
ShowInParentLegend = bool.Parse(se.StringValue);
|
||
break;
|
||
|
||
case "ShowMarkerInLegend":
|
||
ShowMarkerInLegend = 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 "SeriesPoints":
|
||
if (se.ArrayCount > 0)
|
||
{
|
||
SeriesPoints = new PieSeriesPointCollection();
|
||
|
||
sec.PutSerialData(this);
|
||
}
|
||
break;
|
||
|
||
case "SeriesPoint":
|
||
PieSeriesPoint sp = new PieSeriesPoint();
|
||
|
||
sec.PutSerialData(sp);
|
||
|
||
SeriesPoints.Add(sp);
|
||
break;
|
||
|
||
case "SliceVisualLayout":
|
||
sec.PutSerialData(SubSliceVisualLayout);
|
||
break;
|
||
|
||
case "SliceVisualStyles":
|
||
se.Sec.PutSerialData(SliceVisualStyles);
|
||
break;
|
||
|
||
default:
|
||
base.ProcessCollection(se);
|
||
break;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region INotifyPropertyChanged Members
|
||
|
||
/// <summary>
|
||
/// Occurs when property value has changed.
|
||
/// </summary>
|
||
public event PropertyChangedEventHandler PropertyChanged;
|
||
|
||
#region OnPropertyChanged
|
||
|
||
/// <summary>
|
||
/// Raises the PropertyChanged event.
|
||
/// </summary>
|
||
/// <param name="e">Event arguments</param>
|
||
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
|
||
{
|
||
if (PropertyChanged != null)
|
||
PropertyChanged(this, e);
|
||
|
||
VisualPropertyChangedEventArgs vce = e as VisualPropertyChangedEventArgs;
|
||
|
||
if (vce != null)
|
||
NotifyVisualParent(this, vce.ChangeType);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Default PropertyChanged processing
|
||
/// </summary>
|
||
/// <param name="s"></param>
|
||
protected void OnPropertyChanged(string s)
|
||
{
|
||
if (PropertyChanged != null)
|
||
OnPropertyChanged(new PropertyChangedEventArgs(s));
|
||
}
|
||
|
||
/// <summary>
|
||
/// Default PropertyChanged processing
|
||
/// </summary>
|
||
/// <param name="s"></param>
|
||
/// <param name="changeType">invalidate</param>
|
||
protected void OnPropertyChangedEx(string s, VisualChangeType changeType)
|
||
{
|
||
if (PropertyChanged != null)
|
||
OnPropertyChanged(new VisualPropertyChangedEventArgs(s, changeType));
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region NotifyVisualParent
|
||
|
||
internal void NotifyVisualParent(object sender, VisualChangeType vct)
|
||
{
|
||
ChartVisualElement cve = GetParentCve(sender);
|
||
|
||
if (cve != null)
|
||
{
|
||
if (vct == VisualChangeType.Recalc)
|
||
{
|
||
cve.InvalidateRecalc();
|
||
cve.InvalidateLayout();
|
||
}
|
||
else if (vct == VisualChangeType.Layout)
|
||
{
|
||
cve.InvalidateLayout();
|
||
}
|
||
else
|
||
{
|
||
PieSeriesPoint psp = (PieSeriesPoint)sender;
|
||
|
||
cve.InvalidateRender(psp.PathBounds);
|
||
|
||
if (psp.PieLabel != null)
|
||
{
|
||
if (psp.PieLabel.Bounds.IsEmpty == false)
|
||
{
|
||
cve.InvalidateRender(psp.PieLabel.Bounds);
|
||
|
||
if (psp.PieLabel.ConnectorBounds.IsEmpty == false)
|
||
cve.InvalidateRender(psp.PieLabel.ConnectorBounds);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#region GetParentCve
|
||
|
||
private ChartVisualElement GetParentCve(object sender)
|
||
{
|
||
object parent = sender;
|
||
|
||
while (parent != null)
|
||
{
|
||
if (parent is ChartVisualElement)
|
||
break;
|
||
|
||
if (parent is PieSeriesPoint)
|
||
parent = ((PieSeriesPoint)parent).Parent;
|
||
|
||
else if (parent is PieSeriesPointCollection)
|
||
parent = ((PieSeriesPointCollection)parent).Parent;
|
||
|
||
else
|
||
parent = null;
|
||
}
|
||
|
||
return ((ChartVisualElement)parent);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region InvalidateRender
|
||
|
||
public void InvalidateRender()
|
||
{
|
||
ChartVisualElement cve = GetParentCve(Parent);
|
||
|
||
if (cve != null)
|
||
{
|
||
cve.InvalidateRender(PathBounds);
|
||
|
||
if (PieLabel != null)
|
||
{
|
||
if (PieLabel.Bounds.IsEmpty == false)
|
||
{
|
||
cve.InvalidateRender(PieLabel.Bounds);
|
||
|
||
if (PieLabel.ConnectorBounds.IsEmpty == false)
|
||
cve.InvalidateRender(PieLabel.ConnectorBounds);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IDispose
|
||
|
||
public override void Dispose()
|
||
{
|
||
SubSliceVisualLayout = null;
|
||
SliceVisualStyles = null;
|
||
|
||
base.Dispose();
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
#endregion
|
||
|
||
[Editor("DevComponents.Charts.Design.SeriesPointCollectionEditor, DevComponents.Charts.Design, " +
|
||
"Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
|
||
public class SeriesPointCollection : CustomCollection<SeriesPoint>
|
||
{
|
||
}
|
||
|
||
#region SeriesPoint
|
||
|
||
[DesignTimeVisible(false), ToolboxItem(false)]
|
||
public class SeriesPoint : IProcessSerialElement, IDisposable
|
||
{
|
||
#region Private variables
|
||
|
||
private object _ValueX;
|
||
private object[] _ValueY;
|
||
|
||
private Point[] _Point;
|
||
private int _SeriesValidationCount;
|
||
|
||
private Size _PointSize;
|
||
|
||
private States _States;
|
||
|
||
private object _DataItem;
|
||
private object _Tag;
|
||
|
||
#endregion
|
||
|
||
#region Constructors
|
||
|
||
public SeriesPoint()
|
||
: this(0, 0)
|
||
{
|
||
}
|
||
|
||
public SeriesPoint(object xValue)
|
||
{
|
||
_Point = new Point[1];
|
||
|
||
ValueX = xValue;
|
||
|
||
InitDefaultStates();
|
||
}
|
||
|
||
public SeriesPoint(object xValue, object yValue)
|
||
{
|
||
_ValueY = new object[1];
|
||
_Point = new Point[1];
|
||
|
||
ValueX = xValue;
|
||
|
||
_ValueY[0] = yValue;
|
||
|
||
InitDefaultStates();
|
||
}
|
||
|
||
public SeriesPoint(object xValue, object yValue, object size)
|
||
{
|
||
_ValueY = new object[2];
|
||
_Point = new Point[1];
|
||
|
||
ValueX = xValue;
|
||
|
||
_ValueY[0] = yValue;
|
||
_ValueY[1] = size;
|
||
|
||
InitDefaultStates();
|
||
}
|
||
|
||
public SeriesPoint(object xValue, object yValue, object size, object intensity)
|
||
{
|
||
_ValueY = new object[3];
|
||
_Point = new Point[1];
|
||
|
||
ValueX = xValue;
|
||
|
||
_ValueY[0] = yValue;
|
||
_ValueY[1] = size;
|
||
_ValueY[2] = intensity;
|
||
|
||
InitDefaultStates();
|
||
}
|
||
|
||
public SeriesPoint(object xValue, object[] yValue)
|
||
{
|
||
_ValueY = new object[yValue.Length];
|
||
_Point = new Point[yValue.Length];
|
||
|
||
ValueX = xValue;
|
||
|
||
for (int i = 0; i < yValue.Length; i++)
|
||
{
|
||
_ValueY[i] = yValue[i];
|
||
|
||
if (i > 0)
|
||
{
|
||
if (IsQuantitativeYValue != IsQuantitativeValue(yValue[i]))
|
||
throw new ArgumentException("Cannot have mixed qualitative/quantitative yValues");
|
||
}
|
||
}
|
||
|
||
InitDefaultStates();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region InitDefaultStates
|
||
|
||
private void InitDefaultStates()
|
||
{
|
||
SetState(States.Visible, true);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Public properties
|
||
|
||
#region DataItem
|
||
|
||
///<summary>
|
||
/// Gets the object to which the Point is bound.
|
||
///</summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public object DataItem
|
||
{
|
||
get { return (_DataItem); }
|
||
internal set { _DataItem = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsEmpty
|
||
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public bool IsEmpty
|
||
{
|
||
get { return (IsEmptyPoint || IsEmptyValue); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsEmptyPoint
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether the point is an 'Empty' (or missing) Point.
|
||
/// </summary>
|
||
[DefaultValue(false)]
|
||
public virtual bool IsEmptyPoint
|
||
{
|
||
get { return (TestState(States.IsEmptyPoint)); }
|
||
set { SetState(States.IsEmptyPoint, value); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsEmptyValue
|
||
|
||
/// <summary>
|
||
/// Gets whether the point is an 'Empty' value.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public bool IsEmptyValue
|
||
{
|
||
get { return (TestState(States.IsEmptyValue)); }
|
||
internal set { SetState(States.IsEmptyValue, value); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsQualitativeXValue
|
||
|
||
/// <summary>
|
||
/// Gets whether the X Value is a Qualitative value.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public bool IsQualitativeXValue
|
||
{
|
||
get { return (TestState(States.IsQualitativeXValue)); }
|
||
internal set { SetState(States.IsQualitativeXValue, value); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsQualitativeYValue
|
||
|
||
/// <summary>
|
||
/// Gets whether the Y Values are a Qualitative values.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public bool IsQualitativeYValue
|
||
{
|
||
get { return (IsQuantitativeYValue == false); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsQuantitativeXValue
|
||
|
||
/// <summary>
|
||
/// Gets whether the X Value is a Quantitative value.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public bool IsQuantitativeXValue
|
||
{
|
||
get { return (!IsQualitativeXValue); }
|
||
internal set { IsQualitativeXValue = !value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsQuantitativeYValue
|
||
|
||
/// <summary>
|
||
/// Gets whether the Y Values are Quantitative values.
|
||
/// </summary>
|
||
[Browsable(false)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
public bool IsQuantitativeYValue
|
||
{
|
||
get
|
||
{
|
||
if (_ValueY != null && _ValueY.Length > 0)
|
||
return (IsQuantitativeValue(_ValueY[0]));
|
||
|
||
return (true);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Tag
|
||
|
||
///<summary>
|
||
/// Gets or sets user-defined data associated with the point
|
||
///</summary>
|
||
[DefaultValue(null)]
|
||
[Description("Indicates the user-defined data associated with the point.")]
|
||
[TypeConverter("DevComponents.Charts.Design.PointValueConverter, DevComponents.Charts.Design," +
|
||
"Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")]
|
||
public object Tag
|
||
{
|
||
get { return (_Tag); }
|
||
set { _Tag = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ValueX
|
||
|
||
/// <summary>
|
||
/// Gets or sets the X-Axis Value.
|
||
/// </summary>
|
||
[Category("Data")]
|
||
[Description("Indicates the X-Axis Value.")]
|
||
[TypeConverter("DevComponents.Charts.Design.PointValueConverter, DevComponents.Charts.Design," +
|
||
"Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")]
|
||
public object ValueX
|
||
{
|
||
get { return (_ValueX); }
|
||
|
||
set
|
||
{
|
||
_ValueX = value;
|
||
|
||
IsQuantitativeXValue = IsQuantitativeValue(value);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ValueY
|
||
|
||
/// <summary>
|
||
/// Gets or sets the Y-Axis Values.
|
||
/// </summary>
|
||
[Category("Data")]
|
||
[Description("Indicates the Y-Axis Values.")]
|
||
[Editor("DevComponents.Charts.Design.SeriesPointValueEditor, DevComponents.Charts.Design, " +
|
||
"Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
|
||
public object[] ValueY
|
||
{
|
||
get { return (_ValueY); }
|
||
set { _ValueY = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Visible
|
||
|
||
/// <summary>
|
||
/// Gets or sets whether the point is Visible.
|
||
/// </summary>
|
||
[DefaultValue(true)]
|
||
public virtual bool Visible
|
||
{
|
||
get { return (TestState(States.Visible)); }
|
||
set { SetState(States.Visible, value); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region Internal properties
|
||
|
||
#region Point
|
||
|
||
internal Point[] Point
|
||
{
|
||
get { return (_Point); }
|
||
set { _Point = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PointSize
|
||
|
||
internal Size PointSize
|
||
{
|
||
get { return (_PointSize); }
|
||
set { _PointSize = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region SeriesValidationCount
|
||
|
||
internal int SeriesValidationCount
|
||
{
|
||
get { return (_SeriesValidationCount); }
|
||
set { _SeriesValidationCount = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region InvalidatePoints
|
||
|
||
internal void InvalidatePoints()
|
||
{
|
||
if (_Point != null)
|
||
_Point = new Point[_Point.Length];
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsQuantitativeValue
|
||
|
||
private bool IsQuantitativeValue(object value)
|
||
{
|
||
if (value is string || value is bool || value is char)
|
||
return (false);
|
||
|
||
return (true);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IsQualitativeValue
|
||
|
||
private bool IsQualitativeValue(object value)
|
||
{
|
||
return (IsQuantitativeValue(value) == false);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetScaleType
|
||
|
||
public static ScaleType GetScaleType(Type dataType)
|
||
{
|
||
if (dataType == typeof(DateTime))
|
||
return (ScaleType.DateTime);
|
||
|
||
if (dataType == typeof(string) || dataType == typeof(bool) || dataType == typeof(char))
|
||
return (ScaleType.Qualitative);
|
||
|
||
return (ScaleType.Quantitative);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Copy/CopyTo
|
||
|
||
/// <summary>
|
||
/// Creates a copy of the SeriesPoint
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public SeriesPoint Copy()
|
||
{
|
||
SeriesPoint copy = new SeriesPoint(ValueX);
|
||
|
||
CopyTo(copy);
|
||
|
||
return (copy);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Copies the item data to the given SeriesPoint.
|
||
/// </summary>
|
||
/// <param name="sp"></param>
|
||
public void CopyTo(SeriesPoint sp)
|
||
{
|
||
sp.IsEmptyPoint = IsEmptyPoint;
|
||
sp.Tag = Tag;
|
||
|
||
sp.ValueX = ValueX;
|
||
|
||
if (ValueY != null)
|
||
{
|
||
sp.ValueY = new object[ValueY.Length];
|
||
sp.Point = new Point[ValueY.Length];
|
||
|
||
for (int i = 0; i < ValueY.Length; i++)
|
||
sp.ValueY[i] = ValueY[i];
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetSerialData
|
||
|
||
internal virtual SerialElementCollection GetSerialData()
|
||
{
|
||
return (GetSerialData(true));
|
||
}
|
||
|
||
internal virtual SerialElementCollection GetSerialData(bool root)
|
||
{
|
||
SerialElementCollection sec = new SerialElementCollection();
|
||
|
||
if (root == true)
|
||
sec.AddStartElement("SeriesPoint");
|
||
|
||
sec.AddDataValue("Tag", Tag, null);
|
||
sec.AddDataValue("ValueX", ValueX);
|
||
|
||
if (ValueY != null)
|
||
{
|
||
if (ValueY.Length == 1)
|
||
{
|
||
sec.AddDataValue("ValueY0", ValueY[0]);
|
||
}
|
||
else
|
||
{
|
||
sec.AddStartElement("ValueYs count=\"" + ValueY.Length + "\"");
|
||
|
||
for (int i = 0; i < ValueY.Length; i++)
|
||
sec.AddDataValue("ValueY", ValueY[i]);
|
||
|
||
sec.AddEndElement("ValueYs");
|
||
}
|
||
}
|
||
|
||
if (root == true)
|
||
sec.AddEndElement("SeriesPoint");
|
||
|
||
return (sec);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PutSerialData
|
||
|
||
#region ProcessValue
|
||
|
||
void IProcessSerialElement.ProcessValue(SerialElement se)
|
||
{
|
||
ProcessValue(se);
|
||
}
|
||
|
||
internal virtual void ProcessValue(SerialElement se)
|
||
{
|
||
switch (se.Name)
|
||
{
|
||
case "Tag":
|
||
Tag = se.DataValue;
|
||
break;
|
||
|
||
case "ValueX":
|
||
ValueX = se.DataValue;
|
||
break;
|
||
|
||
case "ValueY":
|
||
ValueY[se.ValueIndex] = se.DataValue;
|
||
break;
|
||
|
||
case "ValueY0":
|
||
ValueY = new object[1];
|
||
ValueY[0] = se.DataValue;
|
||
break;
|
||
|
||
default:
|
||
throw new Exception("Unknown Serial Value (" + se.Name + ")");
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ProcessCollection
|
||
|
||
void IProcessSerialElement.ProcessCollection(SerialElement se)
|
||
{
|
||
ProcessCollection(se);
|
||
}
|
||
|
||
internal virtual void ProcessCollection(SerialElement se)
|
||
{
|
||
switch (se.Name)
|
||
{
|
||
case "ValueYs":
|
||
if (se.ArrayCount > 0)
|
||
{
|
||
ValueY = new object[se.ArrayCount];
|
||
|
||
se.Sec.PutSerialData(this);
|
||
}
|
||
break;
|
||
|
||
default:
|
||
throw new Exception("Unknown Serial Collection (" + se.Name + ")");
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region States
|
||
|
||
[Flags]
|
||
private enum States : uint
|
||
{
|
||
IsQualitativeXValue = (1U << 0),
|
||
IsQualitativeYValue = (1U << 1),
|
||
|
||
IsEmptyPoint = (1U << 2),
|
||
IsEmptyValue = (1U << 3),
|
||
|
||
Visible = (1U << 4),
|
||
}
|
||
|
||
#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 ToString
|
||
|
||
public override string ToString()
|
||
{
|
||
StringBuilder sb = new StringBuilder();
|
||
|
||
sb.Append("SeriesPoint (");
|
||
sb.Append(FormatToStringValue(ValueX));
|
||
sb.Append(",");
|
||
|
||
if (ValueY != null && ValueY.Length > 0)
|
||
{
|
||
if (ValueY.Length > 1)
|
||
sb.Append("[");
|
||
|
||
foreach (object value in ValueY)
|
||
{
|
||
sb.Append(FormatToStringValue(value));
|
||
sb.Append(",");
|
||
}
|
||
|
||
sb.Length--;
|
||
|
||
if (ValueY.Length > 1)
|
||
sb.Append("]");
|
||
}
|
||
|
||
sb.Append(")");
|
||
|
||
return (sb.ToString());
|
||
}
|
||
|
||
#region FormatToStringValue
|
||
|
||
private string FormatToStringValue(object value)
|
||
{
|
||
if (value == null)
|
||
return ("<null>");
|
||
|
||
if (value is string)
|
||
return ("\"" + value + "\"");
|
||
|
||
if (value is int)
|
||
return (value.ToString());
|
||
|
||
if (value is DateTime)
|
||
return (value.ToString());
|
||
|
||
return (String.Format("{0:0.0###############}", value));
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region IDispose
|
||
|
||
public virtual void Dispose()
|
||
{
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
#region PointValueConvertor
|
||
|
||
///<summary>
|
||
/// PointValueConvertor
|
||
///</summary>
|
||
public class PointValueConvertor : BlankExpandableObjectConverter
|
||
{
|
||
public override object ConvertTo(
|
||
ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
||
{
|
||
if (destinationType == typeof(string))
|
||
{
|
||
if (value == null)
|
||
return ("<null>");
|
||
|
||
if (value is string)
|
||
return ("\"" + value + "\"");
|
||
|
||
if (value is int)
|
||
return (value.ToString());
|
||
|
||
if (value is DateTime)
|
||
return (value.ToString());
|
||
|
||
return (String.Format("{0:0.0}", value));
|
||
}
|
||
|
||
return (base.ConvertTo(context, culture, value, destinationType));
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
}
|