/// <summary> /// Mark the <see cref="CurveItem" />'s that are included in the selection list /// by setting the <see cref="CurveItem.IsSelected" /> property to true. /// </summary> /// <param name="master">The <see cref="MasterPane" /> that "owns" the selection list.</param> public void UpdateSelection( MasterPane master ) { if ( Count <= 0 ) { ClearSelection( master ); return; } foreach ( GraphPane pane in master.PaneList ) { foreach ( CurveItem ci in pane.CurveList ) { //Make it Inactive ci.IsSelected = false; } } foreach ( CurveItem ci in this ) { //Make Active ci.IsSelected = true; //If it is a line / scatterplot, the selected Curve may be occluded by an unselected Curve //So, move it to the top of the ZOrder by removing it, and re-adding it. //Why only do this for Lines? ...Bar and Pie Curves are less likely to overlap, //and adding and removing Pie elements changes thier display order if ( ci.IsLine ) { //I don't know how to get a Pane, from a CurveItem, so I can only do it //if there is one and only one Pane, based on the assumption that the //Curve's Pane is MasterPane[0] //If there is only one Pane if ( master.PaneList.Count == 1 ) { GraphPane pane = master.PaneList[0]; pane.CurveList.Remove( ci ); pane.CurveList.Insert( 0, ci ); } } } //Send Selection Changed Event if ( SelectionChangedEvent != null ) SelectionChangedEvent( this, new EventArgs() ); }
/// <summary> /// Add a <see cref="CurveItem" /> to the selection list. /// </summary> /// <param name="master">The <see cref="MasterPane" /> that is the "owner" /// of the <see cref="CurveItem" />'s.</param> /// <param name="ci">The <see cref="CurveItem" /> to be added to the list.</param> public void AddToSelection( MasterPane master, CurveItem ci ) { if ( this.Contains( ci ) == false ) Add( ci ); UpdateSelection( master ); }
/// <summary> /// Remove the specified <see cref="CurveItem" /> from the selection list. /// </summary> /// <param name="master">The <see cref="MasterPane" /> that is the "owner" /// of the <see cref="CurveItem" />'s.</param> /// <param name="ci">The <see cref="CurveItem" /> to be removed from the list.</param> public void RemoveFromSelection( MasterPane master, CurveItem ci ) { if ( this.Contains( ci ) ) this.Remove( ci ); UpdateSelection( master ); }
/// <summary> /// Place a list of <see cref="CurveItem" />'s in the selection list, removing all other /// items. /// </summary> /// <param name="master">The <see cref="MasterPane" /> that is the "owner" /// of the <see cref="CurveItem" />'s.</param> /// <param name="ciList">The list of <see cref="CurveItem" /> to be added to the list.</param> public void Select( MasterPane master, CurveList ciList ) { //Clear the selection, but don't send the event, //the event will be sent in "AddToSelection" by calling "UpdateSelection" ClearSelection( master, false ); AddToSelection( master, ciList ); }
/// <summary> /// Clear the selection list and trigger a <see cref="SelectionChangedEvent" />. /// </summary> /// <param name="master">The <see cref="MasterPane" /> that "owns" the selection list.</param> public void ClearSelection( MasterPane master ) { ClearSelection( master, true ); }
/// <summary> /// Clear the selection list and optionally trigger a <see cref="SelectionChangedEvent" />. /// </summary> /// <param name="master">The <see cref="MasterPane" /> that "owns" the selection list.</param> /// <param name="sendEvent">true to trigger a <see cref="SelectionChangedEvent" />, /// false otherwise.</param> public void ClearSelection( MasterPane master, bool sendEvent ) { this.Clear(); foreach ( GraphPane pane in master.PaneList ) { foreach ( CurveItem ci in pane.CurveList ) { ci.IsSelected = false; } } if ( sendEvent ) { if ( SelectionChangedEvent != null ) SelectionChangedEvent( this, new EventArgs() ); } }
/// <summary> /// Internal method that applies a previously set layout with a rows per column or /// columns per row configuration. This method is only called by /// <see cref="DoLayout(Graphics,MasterPane)" />. /// </summary> internal void DoLayout( Graphics g, MasterPane master, bool isColumnSpecified, int[] countList, float[] proportion ) { // calculate scaleFactor on "normal" pane size (BaseDimension) float scaleFactor = master.CalcScaleFactor(); // innerRect is the area for the GraphPane's RectangleF innerRect = master.CalcClientRect( g, scaleFactor ); master.Legend.CalcRect( g, master, scaleFactor, ref innerRect ); // scaled InnerGap is the area between the GraphPane.Rect's float scaledInnerGap = (float)( master._innerPaneGap * scaleFactor ); int iPane = 0; if ( isColumnSpecified ) { int rows = countList.Length; float y = 0.0f; for ( int rowNum = 0; rowNum < rows; rowNum++ ) { float propFactor = _prop == null ? 1.0f / rows : _prop[rowNum]; float height = ( innerRect.Height - (float)( rows - 1 ) * scaledInnerGap ) * propFactor; int columns = countList[rowNum]; if ( columns <= 0 ) columns = 1; float width = ( innerRect.Width - (float)( columns - 1 ) * scaledInnerGap ) / (float)columns; if ( iPane >= master._paneList.Count ) return; for ( int colNum = 0; colNum < columns; colNum++ ) { master[iPane].Rect = new RectangleF( innerRect.X + colNum * ( width + scaledInnerGap ), innerRect.Y + y, width, height ); iPane++; } y += height + scaledInnerGap; } } else { int columns = countList.Length; float x = 0.0f; for ( int colNum = 0; colNum < columns; colNum++ ) { float propFactor = _prop == null ? 1.0f / columns : _prop[colNum]; float width = ( innerRect.Width - (float)( columns - 1 ) * scaledInnerGap ) * propFactor; int rows = countList[colNum]; if ( rows <= 0 ) rows = 1; float height = ( innerRect.Height - (float)( rows - 1 ) * scaledInnerGap ) / (float)rows; for ( int rowNum = 0; rowNum < rows; rowNum++ ) { if ( iPane >= master._paneList.Count ) return; master[iPane].Rect = new RectangleF( innerRect.X + x, innerRect.Y + rowNum * ( height + scaledInnerGap ), width, height ); iPane++; } x += width + scaledInnerGap; } } }
/// <summary> /// Add a list of <see cref="CurveItem" />'s to the selection list. /// </summary> /// <param name="master">The <see cref="MasterPane" /> that is the "owner" /// of the <see cref="CurveItem" />'s.</param> /// <param name="ciList">The list of <see cref="CurveItem" />'s to be added to the list.</param> public void AddToSelection( MasterPane master, CurveList ciList ) { foreach ( CurveItem ci in ciList ) { if ( this.Contains( ci ) == false ) this.Add( ci ); } UpdateSelection( master ); }
/// <summary> /// Internal method that applies a previously set layout with a specific /// row and column count. This method is only called by /// <see cref="DoLayout(Graphics,MasterPane)" />. /// </summary> internal void DoLayout( Graphics g, MasterPane master, int rows, int columns ) { if ( rows < 1 ) rows = 1; if ( columns < 1 ) columns = 1; int[] countList = new int[rows]; for (int i=0; i<rows; i++ ) countList[i] = columns; DoLayout( g, master, true, countList, null ); }
/// <summary> /// Modify the <see cref="GraphPane" /> <see cref="PaneBase.Rect" /> sizes of each /// <see cref="GraphPane" /> such that they fit within the <see cref="MasterPane" /> /// in a pre-configured layout. /// </summary> /// <remarks>The <see cref="SetLayout(PaneLayout)" /> method (and overloads) is /// used for setting the layout configuration.</remarks> /// <param name="g">A <see cref="Graphics" /> instance to be used for font sizing, /// etc. in determining the layout configuration.</param> /// <param name="master">The <see cref="MasterPane" /> instance which is to /// be resized.</param> /// <seealso cref="SetLayout(PaneLayout)" /> /// <seealso cref="SetLayout(int,int)" /> /// <seealso cref="SetLayout(bool,int[])" /> /// <seealso cref="SetLayout(bool,int[],float[])" /> public void DoLayout( Graphics g, MasterPane master ) { if ( this._countList != null ) DoLayout( g, master, this._isColumnSpecified, this._countList, this._prop ); else { int count = master.PaneList.Count; if ( count == 0 ) return; int rows, cols, root = (int)( Math.Sqrt( (double)count ) + 0.9999999 ); //float[] widthList = new float[5]; switch ( _paneLayout ) { case PaneLayout.ForceSquare: rows = root; cols = root; DoLayout( g, master, rows, cols ); break; case PaneLayout.SingleColumn: rows = count; cols = 1; DoLayout( g, master, rows, cols ); break; case PaneLayout.SingleRow: rows = 1; cols = count; DoLayout( g, master, rows, cols ); break; default: case PaneLayout.SquareColPreferred: rows = root; cols = root; if ( count <= root * ( root - 1 ) ) rows--; DoLayout( g, master, rows, cols ); break; case PaneLayout.SquareRowPreferred: rows = root; cols = root; if ( count <= root * ( root - 1 ) ) cols--; DoLayout( g, master, rows, cols ); break; case PaneLayout.ExplicitCol12: DoLayout( g, master, true, new int[2] { 1, 2 }, null ); break; case PaneLayout.ExplicitCol21: DoLayout( g, master, true, new int[2] { 2, 1 }, null ); break; case PaneLayout.ExplicitCol23: DoLayout( g, master, true, new int[2] { 2, 3 }, null ); break; case PaneLayout.ExplicitCol32: DoLayout( g, master, true, new int[2] { 3, 2 }, null ); break; case PaneLayout.ExplicitRow12: DoLayout( g, master, false, new int[2] { 1, 2 }, null ); break; case PaneLayout.ExplicitRow21: DoLayout( g, master, false, new int[2] { 2, 1 }, null ); break; case PaneLayout.ExplicitRow23: DoLayout( g, master, false, new int[2] { 2, 3 }, null ); break; case PaneLayout.ExplicitRow32: DoLayout( g, master, false, new int[2] { 3, 2 }, null ); break; } } }
/// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if the components should be /// disposed, false otherwise</param> protected override void Dispose( bool disposing ) { lock ( this ) { if ( disposing ) { if ( components != null ) components.Dispose(); } base.Dispose( disposing ); _masterPane = null; } }
/// <summary> /// Default Constructor /// </summary> public ZedGraphControl() { InitializeComponent(); // These commands do nothing, but they get rid of the compiler warnings for // unused events bool b = MouseDown == null || MouseUp == null || MouseMove == null; // Link in these events from the base class, since we disable them from this class. base.MouseDown += new System.Windows.Forms.MouseEventHandler( this.ZedGraphControl_MouseDown ); base.MouseUp += new System.Windows.Forms.MouseEventHandler( this.ZedGraphControl_MouseUp ); base.MouseMove += new System.Windows.Forms.MouseEventHandler( this.ZedGraphControl_MouseMove ); //this.MouseWheel += new System.Windows.Forms.MouseEventHandler( this.ZedGraphControl_MouseWheel ); // Use double-buffering for flicker-free updating: SetStyle( ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer | ControlStyles.ResizeRedraw, true ); //isTransparentBackground = false; //SetStyle( ControlStyles.Opaque, false ); SetStyle( ControlStyles.SupportsTransparentBackColor, true ); //this.BackColor = Color.Transparent; Rectangle rect = new Rectangle( 0, 0, this.Size.Width, this.Size.Height ); _masterPane = new MasterPane( "", rect ); _masterPane.Margin.All = 0; _masterPane.Title.IsVisible = false; string titleStr = Properties.Resources.Zedgraph_title_def; string xStr = Properties.Resources.Zedgraph_x_title_def; string yStr = Properties.Resources.Zedgraph_y_title_def; //GraphPane graphPane = new GraphPane( rect, "Title", "X Axis", "Y Axis" ); GraphPane graphPane = new GraphPane( rect, titleStr, xStr, yStr ); using ( Graphics g = this.CreateGraphics() ) { graphPane.AxisChange( g ); //g.Dispose(); } _masterPane.Add( graphPane ); this.hScrollBar1.Minimum = 0; this.hScrollBar1.Maximum = 100; this.hScrollBar1.Value = 0; this.vScrollBar1.Minimum = 0; this.vScrollBar1.Maximum = 100; this.vScrollBar1.Value = 0; _xScrollRange = new ScrollRange( true ); _yScrollRangeList = new ScrollRangeList(); _y2ScrollRangeList = new ScrollRangeList(); _yScrollRangeList.Add( new ScrollRange( true ) ); _y2ScrollRangeList.Add( new ScrollRange( false ) ); _zoomState = null; _zoomStateStack = new ZoomStateStack(); }
/// <summary> /// The Copy Constructor - Make a deep-copy clone of this class instance. /// </summary> /// <param name="rhs">The <see cref="MasterPane"/> object from which to copy</param> public MasterPane( MasterPane rhs ) : base(rhs) { // copy all the value types //_paneLayoutMgr = rhs._paneLayoutMgr.Clone(); _innerPaneGap = rhs._innerPaneGap; _isUniformLegendEntries = rhs._isUniformLegendEntries; _isCommonScaleFactor = rhs._isCommonScaleFactor; // Then, fill in all the reference types with deep copies _paneList = rhs._paneList.Clone(); _paneLayout = rhs._paneLayout; _countList = rhs._countList; _isColumnSpecified = rhs._isColumnSpecified; _prop = rhs._prop; _isAntiAlias = rhs._isAntiAlias; }