2321 lines
		
	
	
		
			68 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			2321 lines
		
	
	
		
			68 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.ComponentModel;
 | |
| using System.Drawing;
 | |
| using System.Drawing.Design;
 | |
| using System.Drawing.Drawing2D;
 | |
| using System.Globalization;
 | |
| using System.Windows.Forms;
 | |
| using DevComponents.DotNetBar.Charts.Style;
 | |
| 
 | |
| namespace DevComponents.DotNetBar.Charts
 | |
| {
 | |
|     /// <summary>
 | |
|     /// ChartPanel is a container object which holds
 | |
|     /// and defines ChartGraphs, which can be single or multiple. 
 | |
|     /// </summary>
 | |
|     [TypeConverter(typeof(BlankExpandableObjectConverter))]
 | |
|     public class ChartPanel : ChartContainer, IEffectiveStyle
 | |
|     {
 | |
|         #region Private variables
 | |
| 
 | |
|         private States _States;
 | |
| 
 | |
|         private ChartContainerCollection _ChartContainers;
 | |
|         private ContainerLayout _ContainerLayout = ContainerLayout.Auto;
 | |
| 
 | |
|         private ChartMatrix _ChartMatrix;
 | |
|         private List<ChartContainer> _MatrixList;
 | |
| 
 | |
|         private DefaultVisualStyles _DefaultVisualStyles;
 | |
| 
 | |
|         private ChartPanelVisualStyle _ChartPanelVisualStyle;
 | |
|         private EffectiveStyle<ChartPanelVisualStyle> _EffectivePanelStyle;
 | |
| 
 | |
|         private List<ChartLegendItem> _LegendData;
 | |
|         private LegendSource _LegendSource = (LegendSource.NestedCharts | LegendSource.NestedPanels);
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         public ChartPanel(string name)
 | |
|             : this()
 | |
|         {
 | |
|             Name = name;
 | |
|         }
 | |
| 
 | |
|         public ChartPanel()
 | |
|         {
 | |
|             InitDefaultStates();
 | |
| 
 | |
|             _EffectivePanelStyle = new EffectiveStyle<ChartPanelVisualStyle>(this);
 | |
| 
 | |
|             Legend.Visible = false;
 | |
|         }
 | |
| 
 | |
|         #region InitDefaultStates
 | |
| 
 | |
|         private void InitDefaultStates()
 | |
|         {
 | |
|             SetState(States.AutoFillChartMatrix, true);
 | |
|             SetState(States.AutoSizeChartMatrix, true);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Public properties
 | |
| 
 | |
|         #region AutoFillChartMatrix
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether the ChartMatrix is auto filled
 | |
|         /// from the ChartContainer collection.
 | |
|         /// </summary>
 | |
|         [DefaultValue(true), Category("Layout")]
 | |
|         [Description("Indicates whether the ChartMatrix is auto filled from the ChartContainer collection.")]
 | |
|         public bool AutoFillChartMatrix
 | |
|         {
 | |
|             get { return (TestState(States.AutoFillChartMatrix)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != AutoFillChartMatrix)
 | |
|                 {
 | |
|                     SetState(States.AutoFillChartMatrix, value);
 | |
| 
 | |
|                     OnPropertyChangedEx("AutoFillChartMatrix", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region AutoGenSeriesCollection
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether series definitions are auto generated from the set DataSource.
 | |
|         /// </summary>
 | |
|         [DefaultValue(false), Category("Data")]
 | |
|         [Description("Indicates whether series definitions are auto generated from the set DataSource.")]
 | |
|         public bool AutoGenSeriesCollection
 | |
|         {
 | |
|             get { return (TestState(States.AutoGenSeriesCollection)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != AutoGenSeriesCollection)
 | |
|                 {
 | |
|                     SetState(States.AutoGenSeriesCollection, value);
 | |
| 
 | |
|                     OnPropertyChangedEx("AutoGenSeriesCollection", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region AutoSizeChartMatrix
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether the ChartMatrix is auto sized
 | |
|         /// from the ChartContainer collection.
 | |
|         /// </summary>
 | |
|         [DefaultValue(true), Category("Layout")]
 | |
|         [Description("Indicates whether the ChartMatrix is auto sized from the ChartContainer collection.")]
 | |
|         public bool AutoSizeChartMatrix
 | |
|         {
 | |
|             get { return (TestState(States.AutoSizeChartMatrix)); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != AutoSizeChartMatrix)
 | |
|                 {
 | |
|                     SetState(States.AutoSizeChartMatrix, value);
 | |
| 
 | |
|                     OnPropertyChangedEx("AutoSizeChartMatrix", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ChartContainers
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets a reference to the collection of Chart Containers (ChartPanels and Chart graphs).
 | |
|         /// </summary>
 | |
|         [Category("Layout")]
 | |
|         [Description("Indicates the reference to the collection of Chart Containers (ChartPanels and Chart graphs).")]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | |
|         public ChartContainerCollection ChartContainers
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_ChartContainers == null)
 | |
|                 {
 | |
|                     _ChartContainers = new ChartContainerCollection();
 | |
| 
 | |
|                     _ChartContainers.CollectionChanged += ChartContainersCollectionChanged;
 | |
|                 }
 | |
| 
 | |
|                 return (_ChartContainers);
 | |
|             }
 | |
| 
 | |
|             internal set
 | |
|             {
 | |
|                 if (_ChartContainers != null)
 | |
|                     _ChartContainers.CollectionChanged -= ChartContainersCollectionChanged;
 | |
| 
 | |
|                 _ChartContainers = value;
 | |
| 
 | |
|                 if (_ChartContainers != null)
 | |
|                     _ChartContainers.CollectionChanged += ChartContainersCollectionChanged;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region ChartContainersCollectionChanged
 | |
| 
 | |
|         void ChartContainersCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
 | |
|         {
 | |
|             ChartControl chartControl = ChartControl;
 | |
| 
 | |
|             switch (e.Action)
 | |
|             {
 | |
|                 case NotifyCollectionChangedAction.Add:
 | |
|                     foreach (ChartContainer item in e.NewItems)
 | |
|                     {
 | |
|                         item.Parent = this;
 | |
| 
 | |
|                         if (chartControl != null)
 | |
|                             AddSelectedItems(chartControl, item);
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case NotifyCollectionChangedAction.Replace:
 | |
|                     foreach (ChartContainer item in e.OldItems)
 | |
|                     {
 | |
|                         if (chartControl != null)
 | |
|                             RemoveSelectedItems(chartControl, item);
 | |
| 
 | |
|                         item.Parent = null;
 | |
|                     }
 | |
| 
 | |
|                     foreach (ChartContainer item in e.NewItems)
 | |
|                     {
 | |
|                         item.Parent = this;
 | |
| 
 | |
|                         if (chartControl != null)
 | |
|                             AddSelectedItems(chartControl, item);
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case NotifyCollectionChangedAction.Remove:
 | |
|                     foreach (ChartContainer item in e.OldItems)
 | |
|                     {
 | |
|                         item.Parent = null;
 | |
| 
 | |
|                         if (chartControl != null)
 | |
|                             RemoveSelectedItems(chartControl, item);
 | |
|                     }
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             InvalidateLayout();
 | |
|         }
 | |
| 
 | |
|         #region AddSelectedItems
 | |
| 
 | |
|         private void AddSelectedItems(ChartControl chartControl, ChartContainer item)
 | |
|         {
 | |
|             BaseChart chart = item as BaseChart;
 | |
| 
 | |
|             if (chart != null)
 | |
|             {
 | |
|                 if (chart.IsSelected == true)
 | |
|                     chartControl.SetSelected(item, true);
 | |
|             }
 | |
|             else if (item is ChartPanel)
 | |
|             {
 | |
|                 foreach (ChartContainer citem in ((ChartPanel)item).ChartContainers)
 | |
|                     AddSelectedItems(chartControl, citem);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RemoveSelectedItems
 | |
| 
 | |
|         private void RemoveSelectedItems(ChartControl chartControl, ChartContainer item)
 | |
|         {
 | |
|             BaseChart chart = item as BaseChart;
 | |
| 
 | |
|             if (chart != null)
 | |
|             {
 | |
|                 if (chart.IsSelected == true)
 | |
|                     chartControl.SetSelected(item, false);
 | |
|             }
 | |
|             else if (item is ChartPanel)
 | |
|             {
 | |
|                 foreach (ChartContainer citem in ((ChartPanel)item).ChartContainers)
 | |
|                     RemoveSelectedItems(chartControl, citem);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ChartMatrix
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the Matrix used to display the defined Panels and Charts in a Matrix format.
 | |
|         /// </summary>
 | |
|         [Category("Layout")]
 | |
|         [Description("Indicates the Matrix used to display the defined Panels and Charts in a Matrix format.")]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | |
|         public ChartMatrix ChartMatrix
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_ChartMatrix == null)
 | |
|                 {
 | |
|                     _ChartMatrix = new ChartMatrix();
 | |
|                     _ChartMatrix.Parent = this;
 | |
| 
 | |
|                     _ChartMatrix.PropertyChanged += ChartMatrix_PropertyChanged;
 | |
|                 }
 | |
| 
 | |
|                 return (_ChartMatrix);
 | |
|             }
 | |
| 
 | |
|             internal set
 | |
|             {
 | |
|                 if (_ChartMatrix != value)
 | |
|                 {
 | |
|                     if (_ChartMatrix != null)
 | |
|                     {
 | |
|                         _ChartMatrix.PropertyChanged -= ChartMatrix_PropertyChanged;
 | |
|                         _ChartMatrix.Parent = null;
 | |
|                     }
 | |
| 
 | |
|                     _ChartMatrix = value;
 | |
| 
 | |
|                     if (_ChartMatrix != null)
 | |
|                     {
 | |
|                         _ChartMatrix.Parent = this;
 | |
|                         _ChartMatrix.PropertyChanged += ChartMatrix_PropertyChanged;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region ChartMatrix_PropertyChanged
 | |
| 
 | |
|         void ChartMatrix_PropertyChanged(object sender, PropertyChangedEventArgs e)
 | |
|         {
 | |
|             if (ChartControl != null)
 | |
|             {
 | |
|                 if (e.PropertyName.Equals("Size") || e.PropertyName.Equals("Height") || e.PropertyName.Equals("Width"))
 | |
|                     ChartControl.DoChartMatrixResizedEvent(this);
 | |
| 
 | |
|                 if (ChartControl.InUpdateLayout == false)
 | |
|                     InvalidateLayout();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ChartPanelVisualStyle
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the visual style for the Chart Panel.
 | |
|         /// </summary>
 | |
|         [Category("Style")]
 | |
|         [Description("Indicates the visual style for the Chart Panel.")]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | |
|         public ChartPanelVisualStyle ChartPanelVisualStyle
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_ChartPanelVisualStyle == null)
 | |
|                 {
 | |
|                     _ChartPanelVisualStyle = new ChartPanelVisualStyle();
 | |
| 
 | |
|                     StyleVisualChangeHandler(null, _ChartPanelVisualStyle);
 | |
|                 }
 | |
| 
 | |
|                 return (_ChartPanelVisualStyle);
 | |
|             }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_ChartPanelVisualStyle != value)
 | |
|                 {
 | |
|                     ChartPanelVisualStyle oldValue = _ChartPanelVisualStyle;
 | |
| 
 | |
|                     _ChartPanelVisualStyle = value;
 | |
| 
 | |
|                     OnStyleChanged("ChartPanelVisualStyle", oldValue, value);
 | |
| 
 | |
|                     if (oldValue != null)
 | |
|                         oldValue.Dispose();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ContainerLayout
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the layout (horizontal, vertical, matrix) for the defined Chart Containers.
 | |
|         /// </summary>
 | |
|         [DefaultValue(ContainerLayout.Auto), Category("Layout")]
 | |
|         [Description("Indicates the layout (horizontal, vertical, matrix) for the defined Chart Containers.")]
 | |
|         public ContainerLayout ContainerLayout
 | |
|         {
 | |
|             get { return (_ContainerLayout); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_ContainerLayout != value)
 | |
|                 {
 | |
|                     _ContainerLayout = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("ContainerLayout", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region DefaultVisualStyles
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Gets or sets the Default Visual Styles for each Chart element.
 | |
|         ///</summary>
 | |
|         [Browsable(true), Category("Style"), DefaultValue(null)]
 | |
|         [Description("Indicates the Default Visual Styles for each Chart element.")]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | |
|         public DefaultVisualStyles DefaultVisualStyles
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_DefaultVisualStyles == null)
 | |
|                 {
 | |
|                     _DefaultVisualStyles = new DefaultVisualStyles();
 | |
| 
 | |
|                     _DefaultVisualStyles.PropertyChanged += DefaultVisualStylesPropertyChanged;
 | |
|                 }
 | |
| 
 | |
|                 return (_DefaultVisualStyles);
 | |
|             }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_DefaultVisualStyles != value)
 | |
|                 {
 | |
|                     if (_DefaultVisualStyles != null)
 | |
|                         _DefaultVisualStyles.PropertyChanged -= DefaultVisualStylesPropertyChanged;
 | |
| 
 | |
|                     _DefaultVisualStyles = value;
 | |
| 
 | |
|                     if (_DefaultVisualStyles != null)
 | |
|                         _DefaultVisualStyles.PropertyChanged += DefaultVisualStylesPropertyChanged;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region DefaultVisualStylesPropertyChanged
 | |
| 
 | |
|         private void DefaultVisualStylesPropertyChanged(object sender, PropertyChangedEventArgs e)
 | |
|         {
 | |
|             VisualChangeType changeType = ((VisualPropertyChangedEventArgs)e).ChangeType;
 | |
| 
 | |
|             switch (changeType)
 | |
|             {
 | |
|                 case VisualChangeType.Layout:
 | |
|                     InvalidateRender();
 | |
|                     break;
 | |
| 
 | |
|                 case VisualChangeType.Render:
 | |
|                     InvalidateRender();
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             //ChartControl cc = ChartControl;
 | |
| 
 | |
|             //if (cc != null)
 | |
|             //    cc.UpdateStyleCount();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region EffectivePanelStyle
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets a reference to the panel's effective (cached, composite) style.
 | |
|         /// </summary>
 | |
|         [Browsable(false)]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | |
|         public ChartPanelVisualStyle EffectivePanelStyle
 | |
|         {
 | |
|             get { return (_EffectivePanelStyle.Style); }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region LegendSource
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the source for the items in the panel legend.
 | |
|         /// </summary>
 | |
|         [Category("Layout")]
 | |
|         [Description("Indicates the source for the items in the panel legend.")]
 | |
|         [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " +
 | |
|                 "Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
 | |
|         public LegendSource LegendSource
 | |
|         {
 | |
|             get { return (_LegendSource); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _LegendSource)
 | |
|                 {
 | |
|                     _LegendSource = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("LegendSource", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         internal virtual bool ShouldSerializeLegendSource()
 | |
|         {
 | |
|             return (_LegendSource != (LegendSource.NestedCharts | LegendSource.NestedPanels));
 | |
|         }
 | |
| 
 | |
|         [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         internal virtual void ResetLegendSource()
 | |
|         {
 | |
|             LegendSource = (LegendSource.NestedCharts | LegendSource.NestedPanels);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Internal properties
 | |
| 
 | |
|         #region LegendData
 | |
| 
 | |
|         internal List<ChartLegendItem> LegendData
 | |
|         {
 | |
|             get { return (_LegendData); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_LegendData != null)
 | |
|                 {
 | |
|                     foreach (ChartLegendItem item in _LegendData)
 | |
|                         item.Dispose();
 | |
|                 }
 | |
| 
 | |
|                 _LegendData = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region MeasureOverride
 | |
| 
 | |
|         protected override void MeasureOverride(ChartLayoutInfo layoutInfo)
 | |
|         {
 | |
|             ChartPanelVisualStyle pstyle = EffectivePanelStyle;
 | |
|             ContainerVisualStyle cstyle = GetEffectiveContainerStyle();
 | |
| 
 | |
|             if (cstyle.DropShadow.Enabled == Tbool.True)
 | |
|             {
 | |
|                 layoutInfo.LayoutBounds.Height -= 3;
 | |
|                 layoutInfo.LayoutBounds.Width -= 3;
 | |
|             }
 | |
| 
 | |
|             BoundsRelative = layoutInfo.LayoutBounds;
 | |
| 
 | |
|             FrameBounds = GetAdjustedBounds(BoundsRelative, cstyle.Margin);
 | |
|             ContentBounds = GetAdjustedBounds(FrameBounds, cstyle.BorderThickness);
 | |
|             ContentBounds = GetAdjustedBounds(ContentBounds, cstyle.Padding);
 | |
| 
 | |
|             layoutInfo.LayoutBounds = ContentBounds;
 | |
| 
 | |
|             base.MeasureOverride(layoutInfo);
 | |
| 
 | |
|             ContentBounds = layoutInfo.LayoutBounds;
 | |
|             ContentBoundsEx = ContentBounds;
 | |
| 
 | |
|             if (AutoFillChartMatrix == true)
 | |
|                 AutoFillMatrix(layoutInfo);
 | |
|             else
 | |
|                 FillMatrix();
 | |
| 
 | |
|             Size size = MeasureMatrix(layoutInfo, pstyle);
 | |
| 
 | |
|             Size minContentSize = Dpi.Size(MinContentSize);
 | |
| 
 | |
|             if (size.Width < minContentSize.Width)
 | |
|                 size.Width = minContentSize.Width;
 | |
| 
 | |
|             if (size.Height < minContentSize.Height)
 | |
|                 size.Height = minContentSize.Height;
 | |
| 
 | |
|             Rectangle r = ContentBoundsEx;
 | |
| 
 | |
|             if (size.Width > r.Width)
 | |
|                 r.Width = size.Width;
 | |
| 
 | |
|             if (size.Height > r.Height)
 | |
|                 r.Height = size.Height;
 | |
| 
 | |
|             ContentBoundsEx = r;
 | |
| 
 | |
|             if ((ContentBoundsEx.Width > ContentBounds.Width  && ContentBoundsEx.Height == ContentBounds.Height) ||
 | |
|                 (ContentBoundsEx.Height > ContentBounds.Height && ContentBoundsEx.Width == ContentBounds.Width))
 | |
|             {
 | |
|                 layoutInfo.LayoutBounds = ContentBounds;
 | |
| 
 | |
|                 if (ContentBoundsEx.Width > ContentBounds.Width)
 | |
|                     layoutInfo.LayoutBounds.Height -= (HScrollBar.Height + 1);
 | |
| 
 | |
|                 if (ContentBoundsEx.Height > ContentBounds.Height)
 | |
|                     layoutInfo.LayoutBounds.Width -= (VScrollBar.Width + 1);
 | |
| 
 | |
|                 size = MeasureMatrix(layoutInfo, pstyle);
 | |
| 
 | |
|                 if (size.IsEmpty == false)
 | |
|                 {
 | |
|                     if (size.Width < minContentSize.Width)
 | |
|                         size.Width = minContentSize.Width;
 | |
| 
 | |
|                     if (size.Height < minContentSize.Height)
 | |
|                         size.Height = minContentSize.Height;
 | |
| 
 | |
|                     r = ContentBoundsEx;
 | |
|                     r.Size = size;
 | |
|                     ContentBoundsEx = r;
 | |
|                 }
 | |
|             }
 | |
|             else if (ContentBoundsEx.Width > ContentBounds.Width &&
 | |
|                 ContentBoundsEx.Height > ContentBounds.Height)
 | |
|             {
 | |
|                 r.Width += (VScrollBar.Width + 1);
 | |
|                 r.Height += (HScrollBar.Height + 1);
 | |
| 
 | |
|                 ContentBoundsEx = r;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region FillMatrix
 | |
| 
 | |
|         private void FillMatrix()
 | |
|         {
 | |
|             Size size = Size.Empty;
 | |
| 
 | |
|             _MatrixList = new List<ChartContainer>();
 | |
| 
 | |
|             foreach (ChartContainer cc in ChartContainers)
 | |
|             {
 | |
|                 if (cc.Visible == true)
 | |
|                 {
 | |
|                     if (cc.MatrixDisplayBounds.Right > 0 && cc.MatrixDisplayBounds.Bottom > 0)
 | |
|                     {
 | |
|                         _MatrixList.Add(cc);
 | |
| 
 | |
|                         if (cc.MatrixDisplayBounds.Right > size.Width)
 | |
|                             size.Width = cc.MatrixDisplayBounds.Right;
 | |
| 
 | |
|                         if (cc.MatrixDisplayBounds.Bottom > size.Height)
 | |
|                             size.Height = cc.MatrixDisplayBounds.Bottom;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (AutoSizeChartMatrix == true)
 | |
|             {
 | |
|                 ChartMatrix.Size = size;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (size.Width > ChartMatrix.Size.Width || size.Height > ChartMatrix.Size.Height)
 | |
|                     throw new Exception("ChartMatrix not large enough for assigned containers.");
 | |
|             }
 | |
| 
 | |
|             ChartMatrix.Clear();
 | |
| 
 | |
|             _MatrixList.Sort(new MatrixComparer());
 | |
| 
 | |
|             foreach (ChartContainer cc in _MatrixList)
 | |
|             {
 | |
|                 Rectangle r = cc.MatrixDisplayBounds;
 | |
| 
 | |
|                 for (int i = r.X; i < r.Right; i++)
 | |
|                 {
 | |
|                     for (int j = r.Y; j < r.Bottom; j++)
 | |
|                         ChartMatrix[i, j] = cc;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region AutoFillMatrix
 | |
| 
 | |
|         private void AutoFillMatrix(ChartLayoutInfo layoutInfo)
 | |
|         {
 | |
|             _MatrixList = new List<ChartContainer>();
 | |
| 
 | |
|             int count = VisibleContainerCount();
 | |
| 
 | |
|             if (count > 0)
 | |
|             {
 | |
|                 Size size = ChartMatrix.Size;
 | |
| 
 | |
|                 ContainerLayout clayout = ContainerLayout;
 | |
| 
 | |
|                 if (AutoSizeChartMatrix == true)
 | |
|                     size = GetAutoMatrixSize(layoutInfo, count, ref clayout);
 | |
| 
 | |
|                 ChartMatrix.Size = size;
 | |
| 
 | |
|                 int n = -1;
 | |
| 
 | |
|                 if (clayout == ContainerLayout.Horizontal)
 | |
|                 {
 | |
|                     for (int i = 0; i < size.Height; i++)
 | |
|                     {
 | |
|                         for (int j = 0; j < size.Width; j++)
 | |
|                         {
 | |
|                             ChartContainer container = GetNextVisibleContainer(ref n);
 | |
| 
 | |
|                             if (container == null)
 | |
|                             {
 | |
|                                 i = size.Height;
 | |
|                                 break;
 | |
|                             }
 | |
| 
 | |
|                             ChartMatrix[j, i] = container;
 | |
|                             container.MatrixDisplayBounds = new Rectangle(j, i, 1, 1);
 | |
| 
 | |
|                             _MatrixList.Add(container);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     for (int i = 0; i < size.Width; i++)
 | |
|                     {
 | |
|                         for (int j = 0; j < size.Height; j++)
 | |
|                         {
 | |
|                             ChartContainer container = GetNextVisibleContainer(ref n);
 | |
| 
 | |
|                             if (container == null)
 | |
|                             {
 | |
|                                 i = size.Width;
 | |
|                                 break;
 | |
|                             }
 | |
| 
 | |
|                             ChartMatrix[i, j] = container;
 | |
|                             container.MatrixDisplayBounds = new Rectangle(i, j, 1, 1);
 | |
| 
 | |
|                             _MatrixList.Add(container);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region VisibleContainerCount
 | |
| 
 | |
|         private int VisibleContainerCount()
 | |
|         {
 | |
|             int count = 0;
 | |
| 
 | |
|             foreach (ChartContainer cc in ChartContainers)
 | |
|             {
 | |
|                 if (cc.Visible == true)
 | |
|                     count++;
 | |
|             }
 | |
| 
 | |
|             return (count);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetAutoMatrixSize
 | |
| 
 | |
|         private Size GetAutoMatrixSize(
 | |
|             ChartLayoutInfo layoutInfo, int count, ref ContainerLayout clayout)
 | |
|         {
 | |
|             if (count > 0)
 | |
|             {
 | |
|                 if (ContainerLayout == ContainerLayout.Horizontal)
 | |
|                     return (new Size(count, 1));
 | |
| 
 | |
|                 if (ContainerLayout == ContainerLayout.Vertical)
 | |
|                     return (new Size(1, count));
 | |
| 
 | |
|                 double w = Math.Ceiling(Math.Sqrt((double)count));
 | |
|                 double h = (w * w == count) ? w : Math.Ceiling(count / w);
 | |
| 
 | |
|                 if (w != h)
 | |
|                 {
 | |
|                     if ((layoutInfo.LayoutBounds.Width > layoutInfo.LayoutBounds.Height && w < h) ||
 | |
|                         (layoutInfo.LayoutBounds.Width < layoutInfo.LayoutBounds.Height && w > h))
 | |
|                     {
 | |
|                         clayout = ContainerLayout.Vertical;
 | |
| 
 | |
|                         return (new Size((int)h, (int)w));
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 clayout = ContainerLayout.Horizontal;
 | |
| 
 | |
|                 return (new Size((int)w, (int)h));
 | |
|             }
 | |
| 
 | |
|             return (Size.Empty);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetNextVisibleContainer
 | |
| 
 | |
|         private ChartContainer GetNextVisibleContainer(ref int n)
 | |
|         {
 | |
|             n++;
 | |
| 
 | |
|             while (n < ChartContainers.Count)
 | |
|             {
 | |
|                 if (ChartContainers[n].Visible == true)
 | |
|                     return (ChartContainers[n]);
 | |
| 
 | |
|                 n++;
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region MeasureMatrix
 | |
| 
 | |
|         private Size MeasureMatrix(ChartLayoutInfo layoutInfo, ChartPanelVisualStyle style)
 | |
|         {
 | |
|             int hLen = GetMatrixLayout(layoutInfo, ContainerLayout.Horizontal);
 | |
|             int vLen = GetMatrixLayout(layoutInfo, ContainerLayout.Vertical);
 | |
| 
 | |
|             Rectangle layoutBounds = layoutInfo.LayoutBounds;
 | |
|             Point ptLayout = layoutBounds.Location;
 | |
| 
 | |
|             for (int i = 0; i < ChartMatrix.Width; i++)
 | |
|             {
 | |
|                 int width = ChartMatrix.ColumnProperties[i].Length;
 | |
| 
 | |
|                 Point ptBounds = ptLayout;
 | |
| 
 | |
|                 for (int j = 0; j < ChartMatrix.Height; j++)
 | |
|                 {
 | |
|                     int height = ChartMatrix.RowProperties[j].Length;
 | |
| 
 | |
|                     ChartMatrix.BoundsArray[i, j] = new Rectangle(ptBounds, new Size(width, height));
 | |
| 
 | |
|                     ptBounds.Y += height;
 | |
|                 }
 | |
| 
 | |
|                 ptLayout.X += width;
 | |
|             }
 | |
| 
 | |
|             int dx = style.DividerLineX.LineWidth / 2;
 | |
|             int dy = style.DividerLineY.LineWidth / 2;
 | |
| 
 | |
|             foreach (ChartContainer cc in _MatrixList)
 | |
|             {
 | |
|                 Rectangle r = GetMatrixBounds(cc, dx, dy);
 | |
| 
 | |
|                 cc.BoundsRelative = r;
 | |
| 
 | |
|                 layoutInfo.LayoutBounds = cc.BoundsRelative;
 | |
| 
 | |
|                 cc.Measure(layoutInfo);
 | |
|             }
 | |
| 
 | |
|             AlignMatrix(layoutInfo);
 | |
| 
 | |
|             return (new Size(hLen, vLen));
 | |
|         }
 | |
| 
 | |
|         #region GetMatrixBounds
 | |
| 
 | |
|         private Rectangle GetMatrixBounds(ChartContainer cc, int dx, int dy)
 | |
|         {
 | |
|             Rectangle r = Rectangle.Empty;
 | |
| 
 | |
|             Rectangle ccb = cc.MatrixDisplayBounds;
 | |
| 
 | |
|             for (int i = ccb.X; i < ccb.Right; i++)
 | |
|             {
 | |
|                 for (int j = ccb.Y; j < ccb.Bottom; j++)
 | |
|                 {
 | |
|                     if (r.IsEmpty == true)
 | |
|                         r = ChartMatrix.BoundsArray[i, j];
 | |
|                     else
 | |
|                         r = Rectangle.Union(r, ChartMatrix.BoundsArray[i, j]);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (ccb.X != 0)
 | |
|             {
 | |
|                 r.X += dy;
 | |
|                 r.Width -= dy;
 | |
|             }
 | |
| 
 | |
|             if (ccb.Right != ChartMatrix.Width)
 | |
|                 r.Width -= dy;
 | |
| 
 | |
|             if (ccb.Y != 0)
 | |
|             {
 | |
|                 r.Y += dx;
 | |
|                 r.Height -= dx;
 | |
|             }
 | |
| 
 | |
|             if (ccb.Bottom != ChartMatrix.Height)
 | |
|                 r.Height -= dx;
 | |
| 
 | |
|             return (r);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region AlignMatrix
 | |
| 
 | |
|         private void AlignMatrix(ChartLayoutInfo layoutInfo)
 | |
|         {
 | |
|             for (int i = 0; i < ChartMatrix.Width; i++)
 | |
|             {
 | |
|                 Vector v = GetMatrixColumnVector(i);
 | |
| 
 | |
|                 UpdateMatrixColumnBounds(v, i);
 | |
|             }
 | |
| 
 | |
|             for (int i = 0; i < ChartMatrix.Height; i++)
 | |
|             {
 | |
|                 Vector v = GetMatrixRowVector(i);
 | |
| 
 | |
|                 UpdateMatrixRowBounds(v, i);
 | |
|             }
 | |
| 
 | |
|             foreach (ChartContainer cc in _MatrixList)
 | |
|             {
 | |
|                 if (cc.MatrixColumnAligned == true || cc.MatrixRowAligned == true)
 | |
|                 {
 | |
|                     cc.MatrixColumnAligned = false;
 | |
|                     cc.MatrixRowAligned = false;
 | |
| 
 | |
|                     layoutInfo.LayoutBounds = cc.BoundsRelative;
 | |
| 
 | |
|                     cc.Measure(layoutInfo);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetMatrixColumnVector
 | |
| 
 | |
|         private Vector GetMatrixColumnVector(int index)
 | |
|         {
 | |
|             Vector v = new Vector();
 | |
| 
 | |
|             foreach (ChartContainer cc in _MatrixList)
 | |
|             {
 | |
|                 Rectangle cb = cc.ContentBounds;
 | |
| 
 | |
|                 if (cc.MatrixDisplayBounds.X == index)
 | |
|                 {
 | |
|                     if (cc.MatrixAlignStartColumn == true)
 | |
|                     {
 | |
|                         if (v.IsEmpty == true)
 | |
|                         {
 | |
|                             v.Start = cb.X;
 | |
|                             v.End = cb.Right;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             if (cb.X > v.Start)
 | |
|                             {
 | |
|                                 int n = cb.X - v.Start;
 | |
|                                 v.Start += n;
 | |
|                                 v.End -= n;
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (cc.MatrixDisplayBounds.Right - 1 == index)
 | |
|                 {
 | |
|                     if (cc.MatrixAlignEndColumn == true)
 | |
|                     {
 | |
|                         if (v.IsEmpty == true)
 | |
|                         {
 | |
|                             v.End = cb.Right;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             if (cb.Right < v.End)
 | |
|                             {
 | |
|                                 int n = v.End - cb.Right;
 | |
|                                 v.End -= n;
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (v);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region UpdateMatrixColumnBounds
 | |
| 
 | |
|         private void UpdateMatrixColumnBounds(Vector v, int index)
 | |
|         {
 | |
|             foreach (ChartContainer cc in _MatrixList)
 | |
|             {
 | |
|                 Rectangle cb = cc.ContentBounds;
 | |
|                 Rectangle t = cc.BoundsRelative;
 | |
| 
 | |
|                 if (cc.MatrixDisplayBounds.X == index)
 | |
|                 {
 | |
|                     if (cc.MatrixAlignStartColumn == true)
 | |
|                     {
 | |
|                         if (cb.X != v.Start)
 | |
|                         {
 | |
|                             t.X += (v.Start - cb.X);
 | |
|                             t.Width -= (v.Start - cb.X);
 | |
| 
 | |
|                             cc.MatrixColumnAligned = true;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (cc.MatrixDisplayBounds.Right - 1 == index)
 | |
|                 {
 | |
|                     if (cc.MatrixAlignEndColumn == true)
 | |
|                     {
 | |
|                         if (cb.Right != v.End)
 | |
|                         {
 | |
|                             t.Width -= (cb.Right - v.End);
 | |
| 
 | |
|                             cc.MatrixColumnAligned = true;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 cc.BoundsRelative = t;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetMatrixRowVector
 | |
| 
 | |
|         private Vector GetMatrixRowVector(int index)
 | |
|         {
 | |
|             Vector v = new Vector();
 | |
| 
 | |
|             foreach (ChartContainer cc in _MatrixList)
 | |
|             {
 | |
|                 Rectangle cb = cc.ContentBounds;
 | |
| 
 | |
|                 if (cc.MatrixDisplayBounds.Y == index)
 | |
|                 {
 | |
|                     if (cc.MatrixAlignStartRow == true)
 | |
|                     {
 | |
|                         if (v.IsEmpty == true)
 | |
|                         {
 | |
|                             v.Start = cb.Y;
 | |
|                             v.End = cb.Bottom;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             if (cb.Y > v.Start)
 | |
|                             {
 | |
|                                 int n = (cb.Y - v.Start);
 | |
| 
 | |
|                                 v.Start += n;
 | |
|                                 v.End -= n;
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (cc.MatrixDisplayBounds.Bottom - 1 == index)
 | |
|                 {
 | |
|                     if (cc.MatrixAlignEndRow == true)
 | |
|                     {
 | |
|                         if (v.IsEmpty == true)
 | |
|                         {
 | |
|                             v.Start = cb.Y;
 | |
|                             v.End = cb.Bottom;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             if (cb.Bottom < v.End)
 | |
|                                 v.End = cb.Bottom;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (v);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region UpdateMatrixRowBounds
 | |
| 
 | |
|         private void UpdateMatrixRowBounds(Vector v, int index)
 | |
|         {
 | |
|             foreach (ChartContainer cc in _MatrixList)
 | |
|             {
 | |
|                 if (cc.MatrixDisplayBounds.Y == index)
 | |
|                 {
 | |
|                     Rectangle cb = cc.ContentBounds;
 | |
|                     Rectangle t = cc.BoundsRelative;
 | |
| 
 | |
|                     if (cc.MatrixAlignStartRow == true)
 | |
|                     {
 | |
|                         if (cb.Y != v.Start)
 | |
|                         {
 | |
|                             t.Y += (v.Start - cb.Y);
 | |
|                             t.Height -= (v.Start - cb.Y);
 | |
| 
 | |
|                             cc.MatrixRowAligned = true;
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     if (cc.MatrixAlignEndRow == true)
 | |
|                     {
 | |
|                         if (cb.Bottom != v.End)
 | |
|                         {
 | |
|                             t.Height -= (cb.Bottom - v.End);
 | |
| 
 | |
|                             cc.MatrixRowAligned = true;
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     cc.BoundsRelative = t;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RowComparer
 | |
| 
 | |
|         private class MatrixComparer : IComparer<ChartContainer>
 | |
|         {
 | |
|             public int Compare(ChartContainer x, ChartContainer y)
 | |
|             {
 | |
|                 return (x.MatrixDisplayOrder - y.MatrixDisplayOrder);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetMatrixLayout
 | |
| 
 | |
|         private int GetMatrixLayout(
 | |
|             ChartLayoutInfo layoutInfo, ContainerLayout containerLayout)
 | |
|         {
 | |
|             int fillBase;
 | |
|             int noFillBase;
 | |
| 
 | |
|             CalculateMatrixFillData(layoutInfo, containerLayout, out fillBase, out noFillBase);
 | |
| 
 | |
|             int length = CalcMatrixContentSize(layoutInfo, containerLayout, fillBase, noFillBase);
 | |
| 
 | |
|             return (length);
 | |
|         }
 | |
| 
 | |
|         #region CalculateMatrixFillData
 | |
| 
 | |
|         private void CalculateMatrixFillData(ChartLayoutInfo layoutInfo, 
 | |
|             ContainerLayout containerLayout, out int fillBase, out int noFillBase)
 | |
|         {
 | |
|             fillBase = 0;
 | |
|             noFillBase = 0;
 | |
| 
 | |
|             if (containerLayout == ContainerLayout.Horizontal)
 | |
|             {
 | |
|                 for (int i = 0; i < ChartMatrix.Width; i++)
 | |
|                 {
 | |
|                     MatrixRowColProperties props = ChartMatrix.ColumnProperties[i];
 | |
| 
 | |
|                     if (props.AutoSizeMode == AutoSizeMode.NotSet)
 | |
|                     {
 | |
|                         if (ChartMatrix[i] != null && AutoSizeMode != AutoSizeMode.None)
 | |
|                             fillBase += ChartMatrix[i].FillWeight;
 | |
|                         else
 | |
|                             noFillBase += props.Length;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (props.AutoSizeMode != AutoSizeMode.None)
 | |
|                             fillBase += props.FillWeight;
 | |
|                         else
 | |
|                             noFillBase += props.Length;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 for (int i = 0; i < ChartMatrix.Height; i++)
 | |
|                 {
 | |
|                     MatrixRowColProperties props = ChartMatrix.RowProperties[i];
 | |
| 
 | |
|                     if (props.AutoSizeMode == AutoSizeMode.NotSet)
 | |
|                     {
 | |
|                         if (ChartMatrix[i] != null && AutoSizeMode != AutoSizeMode.None)
 | |
|                             fillBase += ChartMatrix[i].FillWeight;
 | |
|                         else
 | |
|                             noFillBase += props.Length;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (props.AutoSizeMode != AutoSizeMode.None)
 | |
|                             fillBase += props.FillWeight;
 | |
|                         else
 | |
|                             noFillBase += props.Length;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CalcMatrixContentSize
 | |
| 
 | |
|         private int CalcMatrixContentSize(ChartLayoutInfo layoutInfo, 
 | |
|             ContainerLayout containerLayout, int fillBase, int noFillBase)
 | |
|         {
 | |
|             int length;
 | |
| 
 | |
|             if (containerLayout == ContainerLayout.Horizontal)
 | |
|                 length = CalcHorizontalMatrixContentSize(layoutInfo, fillBase, noFillBase);
 | |
|             else
 | |
|                 length = CalctVerticalMatrixContentSize(layoutInfo, fillBase, noFillBase);
 | |
| 
 | |
|             return (length);
 | |
|         }
 | |
| 
 | |
|         #region CalcHorizontalMatrixContentSize
 | |
| 
 | |
|         private int CalcHorizontalMatrixContentSize(
 | |
|             ChartLayoutInfo layoutInfo, int fillBase, int noFillBase)
 | |
|         {
 | |
|             int lenNeeded = 0;
 | |
|             int n = layoutInfo.LayoutBounds.Width - noFillBase;
 | |
| 
 | |
|             for (int i = 0; i < ChartMatrix.Width; i++)
 | |
|             {
 | |
|                 MatrixRowColProperties props = ChartMatrix.ColumnProperties[i];
 | |
| 
 | |
|                 int length = 0;
 | |
|                 AutoSizeMode autoSizeMode = props.AutoSizeMode;
 | |
| 
 | |
|                 if (autoSizeMode == AutoSizeMode.NotSet)
 | |
|                     autoSizeMode = AutoSizeMode;
 | |
| 
 | |
|                 if (fillBase > 0)
 | |
|                 {
 | |
|                     int fillWeight = (ChartMatrix[i] != null && props.AutoSizeMode == AutoSizeMode.NotSet)
 | |
|                         ? ChartMatrix[i].FillWeight : props.FillWeight;
 | |
| 
 | |
|                     if (fillWeight != 0)
 | |
|                     {
 | |
|                         if (i == ChartMatrix.Width - 1)
 | |
|                             length = layoutInfo.LayoutBounds.Width - lenNeeded;
 | |
|                         else
 | |
|                             length = (int)(n * (float)fillWeight / fillBase);
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 int minLength = (props.MinimumLength > 0)
 | |
|                     ? props.MinimumLength : ChartMatrix.DefaultCellSize.Width;
 | |
| 
 | |
|                 length = Math.Max(length, minLength);
 | |
| 
 | |
|                 props.Length = length;
 | |
| 
 | |
|                 lenNeeded += length;
 | |
|             }
 | |
| 
 | |
|             return (lenNeeded);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CalctVerticalMatrixContentSize
 | |
| 
 | |
|         private int CalctVerticalMatrixContentSize(
 | |
|             ChartLayoutInfo layoutInfo, int fillBase, int noFillBase)
 | |
|         {
 | |
|             int lengthNeeded = 0;
 | |
|             int n = layoutInfo.LayoutBounds.Height - noFillBase;
 | |
| 
 | |
|             for (int i = 0; i < ChartMatrix.Height; i++)
 | |
|             {
 | |
|                 MatrixRowColProperties props = ChartMatrix.RowProperties[i];
 | |
| 
 | |
|                 int length = 0;
 | |
|                 AutoSizeMode autoSizeMode = props.AutoSizeMode;
 | |
| 
 | |
|                 if (autoSizeMode == AutoSizeMode.NotSet)
 | |
|                     autoSizeMode = AutoSizeMode;
 | |
| 
 | |
|                 if (fillBase > 0 && autoSizeMode != AutoSizeMode.None)
 | |
|                 {
 | |
|                     if (props.FillWeight != 0)
 | |
|                     {
 | |
|                         if (i == ChartMatrix.Height - 1)
 | |
|                             length = layoutInfo.LayoutBounds.Height - lengthNeeded;
 | |
|                         else
 | |
|                             length = (int)(n * (float)props.FillWeight / fillBase);
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 int minLength = (props.MinimumLength > 0)
 | |
|                     ? props.MinimumLength : ChartMatrix.DefaultCellSize.Height;
 | |
| 
 | |
|                 length = Math.Max(length, minLength);
 | |
| 
 | |
|                 props.Length = length;
 | |
| 
 | |
|                 lengthNeeded += length;
 | |
|             }
 | |
| 
 | |
|             return (lengthNeeded);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ArrangeOverride
 | |
| 
 | |
|         protected override void ArrangeOverride(ChartLayoutInfo layoutInfo)
 | |
|         {
 | |
|             base.ArrangeOverride(layoutInfo);
 | |
| 
 | |
|             layoutInfo.ScrollOffset.X += HScrollOffset;
 | |
|             layoutInfo.ScrollOffset.Y += VScrollOffset;
 | |
| 
 | |
|             Rectangle scContentBounds = GetScrollBounds(ContentBounds);
 | |
| 
 | |
|             _ChartMatrix.ScrollOffset = layoutInfo.ScrollOffset;
 | |
| 
 | |
|             foreach (ChartContainer cc in _MatrixList)
 | |
|             {
 | |
|                 if (cc.Visible == true)
 | |
|                 {
 | |
|                     cc.Arrange(layoutInfo);
 | |
| 
 | |
|                     cc.Displayed = cc.Bounds.IntersectsWith(scContentBounds);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             layoutInfo.ScrollOffset.X -= HScrollOffset;
 | |
|             layoutInfo.ScrollOffset.Y -= VScrollOffset;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderOverride
 | |
| 
 | |
|         protected override void RenderOverride(ChartRenderInfo renderInfo)
 | |
|         {
 | |
|             Graphics g = renderInfo.Graphics;
 | |
| 
 | |
|             ChartPanelVisualStyle pstyle = EffectivePanelStyle;
 | |
|             ContainerVisualStyle cstyle = GetEffectiveContainerStyle();
 | |
| 
 | |
|             Rectangle scFrameBounds = GetScrollBounds(FrameBounds);
 | |
|             Rectangle scContentBounds = GetScrollBounds(ContentBounds);
 | |
|             Rectangle scDisplayBounds = GetDisplayBounds(scContentBounds);
 | |
| 
 | |
|             RenderPanelBackground(g, scFrameBounds, cstyle);
 | |
| 
 | |
|             cstyle.RenderBorder(g, scFrameBounds);
 | |
| 
 | |
|             Rectangle imageBounds = GetImageBounds(FrameBounds, cstyle);
 | |
| 
 | |
|             if (cstyle.ImageOverlay != ImageOverlay.Top)
 | |
|                 cstyle.RenderBackgroundFigure(g, imageBounds);
 | |
| 
 | |
|             Region clip = g.Clip;
 | |
|             g.SetClip(scContentBounds, CombineMode.Intersect);
 | |
| 
 | |
|             if (ChartMatrix.Size.Width > 0 && ChartMatrix.Size.Height > 0)
 | |
|                 RenderMatrix(renderInfo, pstyle);
 | |
| 
 | |
|             if (_MatrixList == null || _MatrixList.Count <= 0)
 | |
|                 RenderEmptyText(g, cstyle, scDisplayBounds);
 | |
| 
 | |
|             if (cstyle.ImageOverlay == ImageOverlay.Top)
 | |
|                 cstyle.RenderBackgroundFigure(g, imageBounds);
 | |
| 
 | |
|             RenderScrollbars(renderInfo);
 | |
| 
 | |
|             g.Clip = clip;
 | |
| 
 | |
|             if (cstyle.DropShadow.Enabled == Tbool.True)
 | |
|                 cstyle.DropShadow.RenderDropShadow(g, scFrameBounds, true, true);
 | |
| 
 | |
|             base.RenderOverride(renderInfo);
 | |
|         }
 | |
| 
 | |
|         #region RenderPanelBackground
 | |
| 
 | |
|         private void RenderPanelBackground(
 | |
|             Graphics g, Rectangle bounds, ContainerVisualStyle cstyle)
 | |
|         {
 | |
|             ChartControl chartControl = ChartControl;
 | |
| 
 | |
|             if (chartControl.DoPreRenderPanelBackgroundEvent(g, this, bounds) == false)
 | |
|             {
 | |
|                 cstyle.RenderBackground(g, bounds);
 | |
| 
 | |
|                 chartControl.DoPostRenderPanelBackgroundEvent(g, this, bounds);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetImageBounds
 | |
| 
 | |
|         private Rectangle GetImageBounds(Rectangle bounds, ContainerVisualStyle style)
 | |
|         {
 | |
|             bounds = GetAdjustedBounds(bounds, style.BorderThickness);
 | |
| 
 | |
|             Rectangle scBounds = GetScrollBounds(bounds);
 | |
| 
 | |
|             if (HScrollBar.Visible == true)
 | |
|                 scBounds.Height -= HScrollBar.Height;
 | |
| 
 | |
|             if (VScrollBar.Visible == true)
 | |
|                 scBounds.Width -= VScrollBar.Width;
 | |
| 
 | |
|             return (scBounds);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderMatrix
 | |
| 
 | |
|         private void RenderMatrix(ChartRenderInfo renderInfo, ChartPanelVisualStyle style)
 | |
|         {
 | |
|             Graphics g = renderInfo.Graphics;
 | |
| 
 | |
|             // Render divider lines
 | |
| 
 | |
|             switch (ChartMatrix.DividerLines)
 | |
|             {
 | |
|                 case DividerLines.Horizontal:
 | |
|                     RenderDividerLinesX(g, style.DividerLineX);
 | |
|                     break;
 | |
| 
 | |
|                 case DividerLines.Vertical:
 | |
|                     RenderDividerLinesY(g, style.DividerLineY);
 | |
|                     break;
 | |
| 
 | |
|                 case DividerLines.BothXy:
 | |
|                     RenderDividerLinesX(g, style.DividerLineX);
 | |
|                     RenderDividerLinesY(g, style.DividerLineY);
 | |
|                     break;
 | |
| 
 | |
|                 case DividerLines.BothYx:
 | |
|                     RenderDividerLinesY(g, style.DividerLineY);
 | |
|                     RenderDividerLinesX(g, style.DividerLineX);
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             // Render each matrix item
 | |
| 
 | |
|             if (_MatrixList != null && _MatrixList.Count > 0)
 | |
|             {
 | |
|                 foreach (ChartContainer cc in _MatrixList)
 | |
|                     cc.Render(renderInfo);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderDividerLinesX
 | |
| 
 | |
|         private void RenderDividerLinesX(Graphics g, DividerLineVisualStyle style)
 | |
|         {
 | |
|             if (style.LinePattern != LinePattern.None && style.LineWidth != 0)
 | |
|             {
 | |
|                 LinePattern pattern = (style.LinePattern == LinePattern.NotSet) ? LinePattern.Solid : style.LinePattern;
 | |
|                 int thickness = (style.LineWidth > 0) ? style.LineWidth : 1;
 | |
| 
 | |
|                 int n = ChartMatrix.Width - 1;
 | |
|                 int xoffset = _ChartMatrix.ScrollOffset.X;
 | |
|                 int yoffset = _ChartMatrix.ScrollOffset.Y;
 | |
| 
 | |
|                 for (int i = 1; i < ChartMatrix.Height; i++)
 | |
|                 {
 | |
|                     Point pt1 = ChartMatrix.BoundsArray[0, i].Location;
 | |
|                     Point pt2 = ChartMatrix.BoundsArray[n, i].Location;
 | |
| 
 | |
|                     pt1.X -= xoffset;
 | |
|                     pt1.Y -= yoffset;
 | |
| 
 | |
|                     pt2.X -= xoffset;
 | |
|                     pt2.Y -= yoffset;
 | |
| 
 | |
|                     pt2.X += ChartMatrix.BoundsArray[n, i].Width;
 | |
| 
 | |
|                     using (Pen pen = new Pen(style.LineColor, Dpi.Width(style.LineWidth)))
 | |
|                     {
 | |
|                         pen.DashStyle = (DashStyle)pattern;
 | |
| 
 | |
|                         g.DrawLine(pen, pt1, pt2);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderDividerLinesY
 | |
| 
 | |
|         private void RenderDividerLinesY(Graphics g, DividerLineVisualStyle style)
 | |
|         {
 | |
|             if (style.LinePattern != LinePattern.None && style.LineWidth != 0)
 | |
|             {
 | |
|                 LinePattern pattern = (style.LinePattern == LinePattern.NotSet) ? LinePattern.Solid : style.LinePattern;
 | |
|                 int thickness = (style.LineWidth > 0) ? style.LineWidth : 1;
 | |
| 
 | |
|                 int n = ChartMatrix.Height - 1;
 | |
|                 int xoffset = _ChartMatrix.ScrollOffset.X;
 | |
|                 int yoffset = _ChartMatrix.ScrollOffset.Y;
 | |
| 
 | |
|                 for (int i = 1; i < ChartMatrix.Width; i++)
 | |
|                 {
 | |
|                     Point pt1 = ChartMatrix.BoundsArray[i, 0].Location;
 | |
|                     Point pt2 = ChartMatrix.BoundsArray[i, n].Location;
 | |
| 
 | |
|                     pt1.X -= xoffset;
 | |
|                     pt1.Y -= yoffset;
 | |
| 
 | |
|                     pt2.X -= xoffset;
 | |
|                     pt2.Y -= yoffset;
 | |
| 
 | |
|                     pt2.Y += ChartMatrix.BoundsArray[i, n].Height;
 | |
| 
 | |
|                     using (Pen pen = new Pen(style.LineColor, Dpi.Height(thickness)))
 | |
|                     {
 | |
|                         pen.DashStyle = (DashStyle)pattern;
 | |
| 
 | |
|                         g.DrawLine(pen, pt1, pt2);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Mouse handling
 | |
| 
 | |
|         #region OnMouseMove
 | |
| 
 | |
|         protected override bool OnMouseMove(MouseEventArgs e)
 | |
|         {
 | |
|             if (base.OnMouseMove(e) == true)
 | |
|                 return (true);
 | |
| 
 | |
|             return (false);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region OnResize
 | |
| 
 | |
|         protected override bool OnResize(EventArgs e)
 | |
|         {
 | |
|             InvalidateLayout();
 | |
| 
 | |
|             foreach (ChartContainer cc in ChartContainers)
 | |
|                 cc.InternalOnResize(e);
 | |
| 
 | |
|             return (base.OnResize(e));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetElementAt
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the visua element at the given Point.
 | |
|         /// </summary>
 | |
|         /// <param name="pt"></param>
 | |
|         /// <returns></returns>
 | |
|         public override ChartVisualElement GetElementAt(Point pt)
 | |
|         {
 | |
|             ChartVisualElement item = base.GetElementAt(pt);
 | |
| 
 | |
|             if (item == null)
 | |
|             {
 | |
|                 if (ContentBounds.Contains(pt))
 | |
|                 {
 | |
|                     if (ChartMatrix.IsEmpty == false)
 | |
|                     {
 | |
|                         item = ChartMatrix.GetElementAt(pt);
 | |
| 
 | |
|                         if (item != null && item.Visible == true)
 | |
|                         {
 | |
|                             if (item.Bounds.Contains(pt))
 | |
|                             {
 | |
|                                 ChartVisualElement subItem = item.GetElementAt(pt);
 | |
| 
 | |
|                                 if (subItem != null)
 | |
|                                     return (subItem);
 | |
| 
 | |
|                                 return (item);
 | |
|                             }
 | |
| 
 | |
|                             return (null);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (item);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetMatrixCoordAt
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the matric coordinate (row/column) at the given Point.
 | |
|         /// </summary>
 | |
|         /// <param name="pt"></param>
 | |
|         /// <param name="column"></param>
 | |
|         /// <param name="row"></param>
 | |
|         /// <returns>true if valid coordinate is returned</returns>
 | |
|         public bool GetMatrixCoordAt(Point pt, ref int column, ref int row)
 | |
|         {
 | |
|             if (ContentBounds.Contains(pt))
 | |
|                 return (ChartMatrix.GetMatrixCoordAt(pt, ref column, ref row));
 | |
| 
 | |
|             return (false);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetMatrixCoordOf
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the matric coordinate (row/column) of the given container.
 | |
|         /// </summary>
 | |
|         /// <param name="item"></param>
 | |
|         /// <param name="row"></param>
 | |
|         /// <param name="column"></param>
 | |
|         /// <returns>true if valid coordinate returned.</returns>
 | |
|         public bool GetMatrixCoordOf(ChartContainer item, ref int row, ref int column)
 | |
|         {
 | |
|             return (ChartMatrix.GetMatrixCoordOf(item, ref row, ref column));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Style handling
 | |
| 
 | |
|         #region ApplyStyles
 | |
| 
 | |
|         public override void ApplyStyles(BaseVisualStyle style)
 | |
|         {
 | |
|             ChartPanelVisualStyle pstyle = style as ChartPanelVisualStyle;
 | |
| 
 | |
|             if (pstyle != null)
 | |
|             {
 | |
|                 ApplyParentStyles(pstyle, Parent as ChartContainer);
 | |
| 
 | |
|                 pstyle.DividerLineX.ApplyStyle(DefaultVisualStyles.DividerLineVisualStyle);
 | |
|                 pstyle.DividerLineY.ApplyStyle(DefaultVisualStyles.DividerLineVisualStyle);
 | |
| 
 | |
|                 pstyle.ApplyStyle(DefaultVisualStyles.ChartPanelVisualStyle);
 | |
|                 pstyle.ApplyStyle(ChartPanelVisualStyle);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region ApplyParentStyles
 | |
| 
 | |
|         private void ApplyParentStyles(ChartPanelVisualStyle pstyle, ChartContainer item)
 | |
|         {
 | |
|             if (item != null)
 | |
|             {
 | |
|                 ApplyParentStyles(pstyle, item.Parent as ChartContainer);
 | |
| 
 | |
|                 ChartPanel panel = item as ChartPanel;
 | |
| 
 | |
|                 if (panel != null)
 | |
|                 {
 | |
|                     pstyle.DividerLineX.ApplyStyle(panel.DefaultVisualStyles.DividerLineVisualStyle);
 | |
|                     pstyle.DividerLineY.ApplyStyle(panel.DefaultVisualStyles.DividerLineVisualStyle);
 | |
| 
 | |
|                     pstyle.ApplyStyle(panel.DefaultVisualStyles.ChartPanelVisualStyle);
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 pstyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartPanelVisualStyle);
 | |
| 
 | |
|                 pstyle.DividerLineX.ApplyStyle(ChartControl.DefaultVisualStyles.DividerLineVisualStyle);
 | |
|                 pstyle.DividerLineY.ApplyStyle(ChartControl.DefaultVisualStyles.DividerLineVisualStyle);
 | |
| 
 | |
|                 pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartPanelVisualStyle);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ClearEffectiveStyles
 | |
| 
 | |
|         protected override void ClearEffectiveStyles()
 | |
|         {
 | |
|             base.ClearEffectiveStyles();
 | |
| 
 | |
|             _EffectivePanelStyle.InvalidateStyle();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ILegendData
 | |
| 
 | |
|         #region GetLegendData
 | |
| 
 | |
|         public override List<ChartLegendItem> GetLegendData()
 | |
|         {
 | |
|             LegendData = new List<ChartLegendItem>();
 | |
| 
 | |
|             if (LegendSource != LegendSource.None)
 | |
|             {
 | |
|                 ChartContainerCollection containers = ChartContainers;
 | |
| 
 | |
|                 foreach (ChartContainer cc in containers)
 | |
|                 {
 | |
|                     if ((cc is ChartPanel) && ((LegendSource & LegendSource.NestedPanels) != 0) ||
 | |
|                         (cc is BaseChart) && ((LegendSource & LegendSource.NestedCharts) != 0))
 | |
|                     {
 | |
|                         List<ChartLegendItem> data = cc.GetLegendData();
 | |
| 
 | |
|                         if (data != null && data.Count > 0)
 | |
|                             AddLegendItems(data);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (_LegendData);
 | |
|         }
 | |
| 
 | |
|         #region AddLegendItems
 | |
| 
 | |
|         private void AddLegendItems(List<ChartLegendItem> items)
 | |
|         {
 | |
|             foreach (ChartLegendItem item in items)
 | |
|             {
 | |
|                 ChartLegendItem likeItem = null;
 | |
| 
 | |
|                 if (Legend.CombineLikeItems == true)
 | |
|                     likeItem = FindLikeItems(item);
 | |
| 
 | |
|                 if (likeItem == null)
 | |
|                 {
 | |
|                     likeItem = new ChartLegendItem();
 | |
| 
 | |
|                     likeItem.Parent = Legend;
 | |
| 
 | |
|                     likeItem.Name = item.Name;
 | |
|                     likeItem.ItemText = item.ItemText;
 | |
| 
 | |
|                     _LegendData.Add(likeItem);
 | |
|                 }
 | |
| 
 | |
|                 likeItem.ChartItems.AddRange(item.ChartItems);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region FindLikeItems
 | |
| 
 | |
|         private ChartLegendItem FindLikeItems(ChartLegendItem item)
 | |
|         {
 | |
|             string itemName = item.Name ?? item.ItemText;
 | |
| 
 | |
|             if (String.IsNullOrEmpty(itemName) == false)
 | |
|             {
 | |
|                 foreach (ChartLegendItem likeItem in _LegendData)
 | |
|                 {
 | |
|                     string likeName = likeItem.Name ?? likeItem.ItemText;
 | |
| 
 | |
|                     if (String.IsNullOrEmpty(likeName) == false)
 | |
|                     {
 | |
|                         if (likeName.Equals(itemName) == true)
 | |
|                             return (likeItem);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetContainerByName
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the ChartContainer object from the given name.
 | |
|         /// </summary>
 | |
|         /// <param name="name"></param>
 | |
|         /// <returns></returns>
 | |
|         public ChartContainer GetContainerByName(string name)
 | |
|         {
 | |
|             return (GetContainerByName(name, false));
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the ChartContainer object from the given name, with
 | |
|         /// optional searching of nested panels/charts.
 | |
|         /// </summary>
 | |
|         /// <param name="name"></param>
 | |
|         /// <param name="searchNested"></param>
 | |
|         /// <returns></returns>
 | |
|         public ChartContainer GetContainerByName(string name, bool searchNested)
 | |
|         {
 | |
|             if (String.IsNullOrEmpty(name) == true)
 | |
|                 return (null);
 | |
| 
 | |
|             if (_ChartContainers != null)
 | |
|             {
 | |
|                 foreach (ChartContainer container in _ChartContainers)
 | |
|                 {
 | |
|                     if (name.Equals(container.Name) == true)
 | |
|                         return (container);
 | |
| 
 | |
|                     else if (searchNested == true)
 | |
|                     {
 | |
|                         ChartPanel panel = container as ChartPanel;
 | |
| 
 | |
|                         if (panel != null)
 | |
|                         {
 | |
|                             ChartContainer item = panel.GetContainerByName(name, true);
 | |
| 
 | |
|                             if (item != null)
 | |
|                                 return (item);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetChartByName
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the BaseChart from the given name.
 | |
|         /// </summary>
 | |
|         /// <param name="name"></param>
 | |
|         /// <returns></returns>
 | |
|         public BaseChart GetChartByName(string name)
 | |
|         {
 | |
|             return (GetChartByName(name, false));
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the BaseChart from the given name, optionally searching
 | |
|         /// nested panels and charts.
 | |
|         /// </summary>
 | |
|         /// <param name="name"></param>
 | |
|         /// <param name="searchNested"></param>
 | |
|         /// <returns></returns>
 | |
|         public BaseChart GetChartByName(string name, bool searchNested)
 | |
|         {
 | |
|             if (String.IsNullOrEmpty(name) == true)
 | |
|                 return (null);
 | |
| 
 | |
|             if (_ChartContainers != null)
 | |
|             {
 | |
|                 foreach (ChartContainer container in _ChartContainers)
 | |
|                 {
 | |
|                     if (container is BaseChart)
 | |
|                     {
 | |
|                         if (name.Equals(container.Name) == true)
 | |
|                             return ((BaseChart)container);
 | |
|                     }
 | |
|                     else if (searchNested == true)
 | |
|                     {
 | |
|                         ChartPanel panel = container as ChartPanel;
 | |
| 
 | |
|                         if (panel != null)
 | |
|                         {
 | |
|                             BaseChart item = panel.GetChartByName(name, true);
 | |
| 
 | |
|                             if (item != null)
 | |
|                                 return (item);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetPanelByName
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the ChartPanel from the given name.
 | |
|         /// </summary>
 | |
|         /// <param name="name"></param>
 | |
|         /// <returns></returns>
 | |
|         public ChartPanel GetPanelByName(string name)
 | |
|         {
 | |
|             return (GetPanelByName(name, false));
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the ChartPanel from the given name, optionally 
 | |
|         /// searching through nested panels.
 | |
|         /// </summary>
 | |
|         /// <param name="name"></param>
 | |
|         /// <param name="searchNested"></param>
 | |
|         /// <returns></returns>
 | |
|         public ChartPanel GetPanelByName(string name, bool searchNested)
 | |
|         {
 | |
|             if (String.IsNullOrEmpty(name) == true)
 | |
|                 return (null);
 | |
| 
 | |
|             if (_ChartContainers != null)
 | |
|             {
 | |
|                 foreach (ChartContainer container in _ChartContainers)
 | |
|                 {
 | |
|                     ChartPanel panel = container as ChartPanel;
 | |
| 
 | |
|                     if (panel != null)
 | |
|                     {
 | |
|                         if (name.Equals(panel.Name) == true)
 | |
|                             return (panel);
 | |
| 
 | |
|                         if (searchNested == true)
 | |
|                         {
 | |
|                             ChartPanel item = panel.GetPanelByName(name, true);
 | |
| 
 | |
|                             if (item != null)
 | |
|                                 return (item);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Copy/CopyTo
 | |
| 
 | |
|         public override ChartVisualElement Copy()
 | |
|         {
 | |
|             ChartPanel copy = new ChartPanel();
 | |
| 
 | |
|             CopyTo(copy);
 | |
| 
 | |
|             return (copy);
 | |
|         }
 | |
| 
 | |
|         public override void CopyTo(ChartVisualElement copy)
 | |
|         {
 | |
|             ChartPanel c = copy as ChartPanel;
 | |
| 
 | |
|             if (c != null)
 | |
|             {
 | |
|                 base.CopyTo(c);
 | |
| 
 | |
|                 c.AutoFillChartMatrix = AutoFillChartMatrix;
 | |
|                 c.AutoGenSeriesCollection = AutoGenSeriesCollection;
 | |
|                 c.AutoSizeChartMatrix = AutoSizeChartMatrix;
 | |
| 
 | |
|                 foreach (ChartContainer cc in ChartContainers)
 | |
|                     c.ChartContainers.Add((ChartContainer)cc.Copy());
 | |
| 
 | |
|                 c.ChartMatrix = ChartMatrix.Copy();
 | |
| 
 | |
|                 c.ChartPanelVisualStyle = 
 | |
|                     (_ChartPanelVisualStyle != null) ? ChartPanelVisualStyle.Copy() : null;
 | |
| 
 | |
|                 c.ContainerLayout = ContainerLayout;
 | |
| 
 | |
|                 c.DefaultVisualStyles =
 | |
|                     (_DefaultVisualStyles != null) ? DefaultVisualStyles.Copy() : null;
 | |
| 
 | |
|                 c.LegendSource = LegendSource;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetSerialData
 | |
| 
 | |
|         internal override SerialElementCollection GetSerialData(string serialName)
 | |
|         {
 | |
|             SerialElementCollection sec = new SerialElementCollection();
 | |
| 
 | |
|             if (serialName != null)
 | |
|             {
 | |
|                 if (serialName.Equals("") == true)
 | |
|                     serialName = "ChartPanel";
 | |
| 
 | |
|                 sec.AddStartElement(serialName);
 | |
|             }
 | |
| 
 | |
|             sec.AddValue("AutoFillChartMatrix", AutoFillChartMatrix, true);
 | |
|             sec.AddValue("AutoGenSeriesCollection", AutoGenSeriesCollection, false);
 | |
|             sec.AddValue("AutoSizeChartMatrix", AutoSizeChartMatrix, true);
 | |
| 
 | |
|             if (ChartContainers.Count > 0)
 | |
|             {
 | |
|                 sec.AddStartElement("ChartContainers count=\"" + ChartContainers.Count + "\"");
 | |
| 
 | |
|                 foreach (ChartContainer cc in ChartContainers)
 | |
|                     sec.AddElement(cc.GetSerialData(""));
 | |
| 
 | |
|                 sec.AddEndElement("ChartContainers");
 | |
|             }
 | |
| 
 | |
|             if (_ChartMatrix != null && _ChartMatrix.IsEmpty == false)
 | |
|             {
 | |
|                 if (AutoFillChartMatrix == false)
 | |
|                     sec.AddElement(_ChartMatrix.GetSerialData());
 | |
|             }
 | |
| 
 | |
|             if (_ChartPanelVisualStyle != null && _ChartPanelVisualStyle.IsEmpty == false)
 | |
|                 sec.AddElement(_ChartPanelVisualStyle.GetSerialData("ChartPanelVisualStyle"));
 | |
| 
 | |
|             sec.AddValue("ContainerLayout", ContainerLayout, ContainerLayout.Auto);
 | |
| 
 | |
|             if (_DefaultVisualStyles != null && _DefaultVisualStyles.IsEmpty == false)
 | |
|                 sec.AddElement(_DefaultVisualStyles.GetSerialData());
 | |
| 
 | |
|             sec.AddValue("LegendSource",
 | |
|                 LegendSource, (LegendSource.NestedCharts | LegendSource.NestedPanels));
 | |
| 
 | |
|             sec.AddElement(base.GetSerialData(null));
 | |
| 
 | |
|             if (serialName != null)
 | |
|                 sec.AddEndElement(serialName);
 | |
| 
 | |
|             return (sec);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PutSerialData
 | |
| 
 | |
|         #region ProcessValue
 | |
| 
 | |
|         internal override void ProcessValue(SerialElement se)
 | |
|         {
 | |
|             switch (se.Name)
 | |
|             {
 | |
|                 case "AutoFillChartMatrix":
 | |
|                     AutoFillChartMatrix = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "AutoGenSeriesCollection":
 | |
|                     AutoGenSeriesCollection = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "AutoSizeChartMatrix":
 | |
|                     AutoSizeChartMatrix = bool.Parse(se.StringValue);
 | |
|                     break;
 | |
| 
 | |
|                 case "ContainerLayout":
 | |
|                     ContainerLayout = (ContainerLayout)se.GetValueEnum(typeof(ContainerLayout));
 | |
|                     break;
 | |
| 
 | |
|                 case "LegendSource":
 | |
|                     LegendSource = (LegendSource)se.GetValueEnum(typeof(LegendSource));
 | |
|                     break;
 | |
| 
 | |
|                 default:
 | |
|                     base.ProcessValue(se);
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ProcessCollection
 | |
| 
 | |
|         internal override void ProcessCollection(SerialElement se)
 | |
|         {
 | |
|             SerialElementCollection sec = se.Sec;
 | |
| 
 | |
|             switch (se.Name)
 | |
|             {
 | |
|                 case "ChartPanel":
 | |
|                 case "ChartContainers":
 | |
|                     sec.PutSerialData(this);
 | |
|                     break;
 | |
| 
 | |
|                 case "ChartXy":
 | |
|                     string name = sec.GetItemValue("Name");
 | |
| 
 | |
|                     ChartXy chartXy = new ChartXy(name);
 | |
| 
 | |
|                     sec.PutSerialData(chartXy);
 | |
| 
 | |
|                     ChartContainers.Add(chartXy);
 | |
|                     break;
 | |
| 
 | |
|                 case "ChartMatrix":
 | |
|                     sec.PutSerialData(ChartMatrix);
 | |
|                     break;
 | |
| 
 | |
|                 case "ChartPanelVisualStyle":
 | |
|                     sec.PutSerialData(ChartPanelVisualStyle);
 | |
|                     break;
 | |
| 
 | |
|                 case "DefaultVisualStyles":
 | |
|                     sec.PutSerialData(DefaultVisualStyles);
 | |
|                     break;
 | |
| 
 | |
|                 case "PieChart":
 | |
|                     string pname = sec.GetItemValue("Name");
 | |
| 
 | |
|                     PieChart pieChart = new PieChart(pname);
 | |
| 
 | |
|                     sec.PutSerialData(pieChart);
 | |
| 
 | |
|                     ChartContainers.Add(pieChart);
 | |
|                     break;
 | |
| 
 | |
|                 default:
 | |
|                     base.ProcessCollection(se);
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region States
 | |
| 
 | |
|         [Flags]
 | |
|         private enum States : uint
 | |
|         {
 | |
|             AutoFillChartMatrix = (1U << 0),
 | |
|             AutoGenSeriesCollection = (1U << 1),
 | |
|             AutoSizeChartMatrix = (1U << 2),
 | |
|         }
 | |
| 
 | |
|         #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 Structs
 | |
| 
 | |
|         private struct Vector
 | |
|         {
 | |
|             public int Start;
 | |
|             public int End;
 | |
| 
 | |
|             public bool IsEmpty
 | |
|             {
 | |
|                 get { return (Start == End); }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IDisposable
 | |
| 
 | |
|         public override void Dispose()
 | |
|         {
 | |
|             ChartContainers = null;
 | |
|             ChartMatrix = null;
 | |
|             ChartPanelVisualStyle = null;
 | |
|             DefaultVisualStyles = null;
 | |
| 
 | |
|             base.Dispose();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|     }
 | |
| 
 | |
|     #region enums
 | |
| 
 | |
|     #region ContainerLayout
 | |
| 
 | |
|     public enum ContainerLayout
 | |
|     {
 | |
|         Auto,
 | |
|         Horizontal,
 | |
|         Vertical,
 | |
|         HorizontalThenVertical,
 | |
|         VerticalThenHorizontal,
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region DividerLines
 | |
| 
 | |
|     ///<summary>
 | |
|     /// Specifies which divider lines are displayed
 | |
|     ///</summary>
 | |
|     public enum DividerLines
 | |
|     {
 | |
|         ///<summary>
 | |
|         /// Not set
 | |
|         ///</summary>
 | |
|         NotSet,
 | |
| 
 | |
|         ///<summary>
 | |
|         /// No lines are displayed
 | |
|         ///</summary>
 | |
|         None,
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Only horizontal divider lines are displayed
 | |
|         ///</summary>
 | |
|         Horizontal,
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Only vertical divider lines are displayed
 | |
|         ///</summary>
 | |
|         Vertical,
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Both horizontal and vertical divider lines are displayed,
 | |
|         /// horizontal first, then vertical.
 | |
|         ///</summary>
 | |
|         BothXy,
 | |
| 
 | |
|         ///<summary>
 | |
|         /// Both horizontal and vertical divider lines are displayed
 | |
|         /// vertical first, then horizontal.
 | |
|         ///</summary>
 | |
|         BothYx,
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region LegendSource
 | |
| 
 | |
|     [Flags]
 | |
|     public enum LegendSource
 | |
|     {
 | |
|         None = 0,
 | |
| 
 | |
|         NestedCharts = (1 << 0),
 | |
|         NestedPanels = (1 << 1),
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region BlankExpandableObjectConverter
 | |
| 
 | |
|     ///<summary>
 | |
|     /// BlankExpandableObjectConverter
 | |
|     ///</summary>
 | |
|     public class BlankExpandableObjectConverter : ExpandableObjectConverter
 | |
|     {
 | |
|         ///<summary>
 | |
|         /// ConvertTo
 | |
|         ///</summary>
 | |
|         ///<param name="context"></param>
 | |
|         ///<param name="culture"></param>
 | |
|         ///<param name="value"></param>
 | |
|         ///<param name="destinationType"></param>
 | |
|         ///<returns></returns>
 | |
|         public override object ConvertTo(
 | |
|             ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
 | |
|         {
 | |
|             if (destinationType == typeof(string))
 | |
|                 return (" ");
 | |
| 
 | |
|             return (base.ConvertTo(context, culture, value, destinationType));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| }
 |