/// <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) { this.Add(ci); } this.UpdateSelection(master); }
/// <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 (this.components != null) { this.components.Dispose(); } } base.Dispose(disposing); this._masterPane = null; } }
/// <summary> /// Initializes a new instance of the <see cref="ZedGraphControl"/> class. Default Constructor /// </summary> public ZedGraphControl() { this.InitializeComponent(); // These commands do nothing, but they get rid of the compiler warnings for // unused events bool b = this.MouseDown == null || this.MouseUp == null || this.MouseMove == null; // Link in these events from the base class, since we disable them from this class. base.MouseDown += this.ZedGraphControl_MouseDown; base.MouseUp += this.ZedGraphControl_MouseUp; base.MouseMove += this.ZedGraphControl_MouseMove; // this.MouseWheel += new System.Windows.Forms.MouseEventHandler( this.ZedGraphControl_MouseWheel ); // Use double-buffering for flicker-free updating: this.SetStyle( ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer | ControlStyles.ResizeRedraw, true); // isTransparentBackground = false; // SetStyle( ControlStyles.Opaque, false ); this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); // this.BackColor = Color.Transparent; var asm = Assembly.GetExecutingAssembly(); var resNames = asm.GetManifestResourceNames(); foreach (var res in resNames) { if (res.Contains("ZedGraphLocale")) { var r = res.Substring(0, res.Length - 10); this._resourceManager = new ResourceManager(r, asm); break; } } Rectangle rect = new Rectangle(0, 0, this.Size.Width, this.Size.Height); this._masterPane = new MasterPane(string.Empty, rect); this._masterPane.Margin.All = 0; this._masterPane.Title.IsVisible = false; string titleStr = this._resourceManager.GetString("title_def"); string xStr = this._resourceManager.GetString("x_title_def"); string yStr = this._resourceManager.GetString("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(); } this._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; this._xScrollRange = new ScrollRange(true); this._yScrollRangeList = new ScrollRangeList(); this._y2ScrollRangeList = new ScrollRangeList(); this._yScrollRangeList.Add(new ScrollRange(true)); this._y2ScrollRangeList.Add(new ScrollRange(false)); this._zoomState = null; this._zoomStateStack = new ZoomStateStack(); }
/// <summary> /// Initializes a new instance of the <see cref="MasterPane"/> class. /// 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(); this._innerPaneGap = rhs._innerPaneGap; this._isUniformLegendEntries = rhs._isUniformLegendEntries; this._isCommonScaleFactor = rhs._isCommonScaleFactor; // Then, fill in all the reference types with deep copies this._paneList = rhs._paneList.Clone(); this._paneLayout = rhs._paneLayout; this._countList = rhs._countList; this._isColumnSpecified = rhs._isColumnSpecified; this._prop = rhs._prop; this._isAntiAlias = rhs._isAntiAlias; }
/// <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); } } this.UpdateSelection(master); }
/// <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 (this.Count <= 0) { this.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 (this.SelectionChangedEvent != null) { this.SelectionChangedEvent(this, new EventArgs()); } }
/// <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); } this.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" this.ClearSelection(master, false); this.AddToSelection(master, ciList); }
/// <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 (this.SelectionChangedEvent != null) { this.SelectionChangedEvent(this, new EventArgs()); } } }
/// <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) { this.ClearSelection(master, true); }
/// <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> /// <param name="g"> /// The g. /// </param> /// <param name="master"> /// The master. /// </param> /// <param name="isColumnSpecified"> /// The is Column Specified. /// </param> /// <param name="countList"> /// The count List. /// </param> /// <param name="proportion"> /// The proportion. /// </param> 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 = 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 = this._prop == null ? 1.0f / rows : this._prop[rowNum]; float height = (innerRect.Height - (rows - 1) * scaledInnerGap) * propFactor; int columns = countList[rowNum]; if (columns <= 0) { columns = 1; } float width = (innerRect.Width - (columns - 1) * scaledInnerGap) / 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 = this._prop == null ? 1.0f / columns : this._prop[colNum]; float width = (innerRect.Width - (columns - 1) * scaledInnerGap) * propFactor; int rows = countList[colNum]; if (rows <= 0) { rows = 1; } float height = (innerRect.Height - (rows - 1) * scaledInnerGap) / 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> /// 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> /// <param name="g"> /// The g. /// </param> /// <param name="master"> /// The master. /// </param> /// <param name="rows"> /// The rows. /// </param> /// <param name="columns"> /// The columns. /// </param> 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; } this.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) { this.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(count) + 0.9999999); // float[] widthList = new float[5]; switch (this._paneLayout) { case PaneLayout.ForceSquare: rows = root; cols = root; this.DoLayout(g, master, rows, cols); break; case PaneLayout.SingleColumn: rows = count; cols = 1; this.DoLayout(g, master, rows, cols); break; case PaneLayout.SingleRow: rows = 1; cols = count; this.DoLayout(g, master, rows, cols); break; default: case PaneLayout.SquareColPreferred: rows = root; cols = root; if (count <= root * (root - 1)) { rows--; } this.DoLayout(g, master, rows, cols); break; case PaneLayout.SquareRowPreferred: rows = root; cols = root; if (count <= root * (root - 1)) { cols--; } this.DoLayout(g, master, rows, cols); break; case PaneLayout.ExplicitCol12: this.DoLayout(g, master, true, new[] { 1, 2 }, null); break; case PaneLayout.ExplicitCol21: this.DoLayout(g, master, true, new[] { 2, 1 }, null); break; case PaneLayout.ExplicitCol23: this.DoLayout(g, master, true, new[] { 2, 3 }, null); break; case PaneLayout.ExplicitCol32: this.DoLayout(g, master, true, new[] { 3, 2 }, null); break; case PaneLayout.ExplicitRow12: this.DoLayout(g, master, false, new[] { 1, 2 }, null); break; case PaneLayout.ExplicitRow21: this.DoLayout(g, master, false, new[] { 2, 1 }, null); break; case PaneLayout.ExplicitRow23: this.DoLayout(g, master, false, new[] { 2, 3 }, null); break; case PaneLayout.ExplicitRow32: this.DoLayout(g, master, false, new[] { 3, 2 }, null); break; } } }