//--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #region Non-Public //--------------------------------------------------------------------------- #region Non-Public Methods ///-------------------------------------------------------------------------- /// <summary> /// Individual x- and y- zooming. If, during a zoom action, the extention in /// one of the directions is less than 10 pixels, the zoom action is only be /// done for the direction with the big extension. A line is drawn instead /// of the rectangular rubberband. /// </summary> /// <returns>True, if a line has been drawn, false otherwise.</returns> ///-------------------------------------------------------------------------- /* * private bool DrawLineInsteadOfRectangle() * { * if (!EnableIndividualXYZoom) * return false; * * Color color = Color.Cyan; * int xPad = Math.Abs(_dragStartPt.X - _dragEndPt.X); * int yPad = Math.Abs(_dragStartPt.Y - _dragEndPt.Y); * * if (!_drawCrossline && (xPad > 1 || yPad > 1)) * _drawCrossline = true; * * if (xPad < 10) * { * // Draw vertical line. * Point p1 = new Point(_dragStartPt.X, _dragStartPt.Y); * Point p2 = new Point(_dragStartPt.X, _dragEndPt.Y); * ControlPaint.DrawReversibleLine(PointToScreen(p1), PointToScreen(p2), color); * if (_drawCrossline) * { * p1 = new Point(_dragStartPt.X - 10, _dragStartPt.Y); * p2 = new Point(_dragStartPt.X + 10, _dragStartPt.Y); * ControlPaint.DrawReversibleLine(PointToScreen(p1), PointToScreen(p2), color); * * p1 = new Point(_dragStartPt.X - 10, _dragEndPt.Y); * p2 = new Point(_dragStartPt.X + 10, _dragEndPt.Y); * ControlPaint.DrawReversibleLine(PointToScreen(p1), PointToScreen(p2), color); * } * * _isEnableHZoom = false; * _isEnableVZoom = true; * return true; * } * * if (yPad < 10) * { * // Draw horizontal line. * Point p1 = new Point(_dragStartPt.X, _dragStartPt.Y); * Point p2 = new Point(_dragEndPt.X, _dragStartPt.Y); * ControlPaint.DrawReversibleLine(PointToScreen(p1), PointToScreen(p2), color); * if (_drawCrossline) * { * p1 = new Point(_dragStartPt.X, _dragStartPt.Y - 10); * p2 = new Point(_dragStartPt.X, _dragStartPt.Y + 10); * ControlPaint.DrawReversibleLine(PointToScreen(p1), PointToScreen(p2), color); * * p1 = new Point(_dragEndPt.X, _dragStartPt.Y - 10); * p2 = new Point(_dragEndPt.X, _dragStartPt.Y + 10); * ControlPaint.DrawReversibleLine(PointToScreen(p1), PointToScreen(p2), color); * } * * _isEnableVZoom = false; * _isEnableHZoom = true; * return true; * } * * // Draw rectangle as usual. * _drawCrossline = false; * _isEnableHZoom = true; * _isEnableVZoom = true; * return false; * } */ ///------------------------------------------------------------------------ /// <summary> /// Handles the Opening event of the ContextMenuStrip control. /// It should not pop down when a legend item was clicked. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> /// instance containing the event data.</param> ///------------------------------------------------------------------------ private void ContextMenuStrip_Opening(object sender, CancelEventArgs e) { var graphPane = this.MasterPane.FindPane(this._menuClickPt); using (var g = this.CreateGraphics()) { object nearestObject; int index; if (MasterPane.FindNearestPaneObject(_menuClickPt, g, out graphPane, out nearestObject, out index)) { if (nearestObject is Legend) { e.Cancel = true; } } else if (MasterPane.Legend.FindPoint(_menuClickPt, MasterPane, MasterPane.CalcScaleFactor(), out index)) { e.Cancel = true; } } }
/// <summary> /// Generate an ImageMap as Html tags /// </summary> /// <param name="masterPane">The source <see cref="MasterPane" /> to be /// image mapped.</param> /// <param name="output">An <see cref="HtmlTextWriter" /> instance in which /// the html tags will be written for the image map.</param> public void MakeImageMap( MasterPane masterPane, HtmlTextWriter output ) { string shape; string coords; Bitmap image = new Bitmap( 1, 1 ); using ( Graphics g = Graphics.FromImage( image ) ) { float masterScale = masterPane.CalcScaleFactor(); // Frontmost objects are MasterPane objects with A_InFront foreach ( GraphObj obj in masterPane.GraphObjList ) { if ( obj.Link.IsActive && obj.ZOrder == ZOrder.A_InFront ) { obj.GetCoords( masterPane, g, masterScale, out shape, out coords ); MakeAreaTag( shape, coords, obj.Link.Url, obj.Link.Target, obj.Link.Title, obj.Link.Tag, output ); } } // Now loop over each GraphPane foreach ( GraphPane pane in masterPane.PaneList ) { float scaleFactor = pane.CalcScaleFactor(); // Next comes GraphPane GraphObjs in front of data points foreach ( GraphObj obj in pane.GraphObjList ) { if ( obj.Link.IsActive && obj.IsInFrontOfData ) { obj.GetCoords( pane, g, scaleFactor, out shape, out coords ); MakeAreaTag( shape, coords, obj.Link.Url, obj.Link.Target, obj.Link.Title, obj.Link.Tag, output ); } } // Then come the data points (CurveItems) foreach ( CurveItem curve in pane.CurveList ) { if ( curve.Link.IsActive && curve.IsVisible ) { for ( int i=0; i < (curve is PieItem ? 1 : curve.Points.Count); i++ ) { //if ( curve.GetCoords( pane, i, pane.Rect.Left, pane.Rect.Top, out coords ) ) if ( curve.GetCoords( pane, i, out coords ) ) { if ( curve is PieItem ) { MakeAreaTag( "poly", coords, curve.Link.Url, curve.Link.Target, curve.Link.Title, curve.Link.Tag, output ); // only one point for PieItems break; } else { // Add an "?index=4" type tag to the url to indicate which // point was selected string url; if ( curve.Link.Url != string.Empty ) url = curve.Link.MakeCurveItemUrl( pane, curve, i ); else url = ""; string title = curve.Link.Title; if ( curve.Points[i].Tag is string ) title = curve.Points[i].Tag as string; MakeAreaTag( "rect", coords, url, curve.Link.Target, title, curve.Points[i].Tag, output ); } } } } } // Then comes the GraphObjs behind the data points foreach ( GraphObj obj in pane.GraphObjList ) { if ( obj.Link.IsActive && !obj.IsInFrontOfData ) { obj.GetCoords( pane, g, scaleFactor, out shape, out coords ); MakeAreaTag( shape, coords, obj.Link.Url, obj.Link.Target, obj.Link.Title, obj.Link.Tag, output ); } } } // Hindmost objects are MasterPane objects with !A_InFront foreach ( GraphObj obj in masterPane.GraphObjList ) { if ( obj.Link.IsActive && obj.ZOrder != ZOrder.A_InFront ) { obj.GetCoords( masterPane, g, masterScale, out shape, out coords ); MakeAreaTag( shape, coords, obj.Link.Url, obj.Link.Target, obj.Link.Title, obj.Link.Tag, output ); } } } }
/// <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> /// Zeds the graph control_ double click event. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> /// instance containing the event data.</param> /// <returns> /// Return true if you have handled the MouseDown event entirely, and you /// do not want the <see cref="ZedGraphControl"/> to do any further action /// (e.g., starting a zoom operation). Return false if ZedGraph should go /// ahead and process the MouseDown event. /// </returns> ///------------------------------------------------------------------------ private bool ZedGraphControl_DoubleClickEvent(ZedGraphControl sender, MouseEventArgs e) { PointF mousePoint = e.Location; var curveIndex = -1; if (MasterPane.Legend.FindPoint(mousePoint, MasterPane, MasterPane.CalcScaleFactor(), out curveIndex)) { MouseDoubleClickOnMasterPaneLegendItem?.Invoke(sender.GraphPane, e, sender.GraphPane.CurveList[curveIndex].Label.Text); } else if (mousePoint.Y <= this.MasterPane.Legend.Rect.Bottom) { if (MouseDoubleClickMasterPaneLegendArea?.Invoke(sender.GraphPane, e, "") ?? false) { return(true); } if (e.Button == MouseButtons.Left) { this.MakeCurvesVisible(sender.GraphPane); return(true); } } var graphPane = sender.MasterPane.FindPane(mousePoint) as GraphPane; // No graph pane was hit. if (graphPane == null) { return(false); } if (MouseDoubleClickGraphPane?.Invoke(graphPane, e, null) ?? false) { return(true); } if (!graphPane.Legend.FindPoint(mousePoint, graphPane, graphPane.CalcScaleFactor(), out curveIndex) && mousePoint.Y > graphPane.Legend.Rect.Bottom) { OnResetScale(graphPane); return(true); } if (graphPane.Legend.FindPoint(mousePoint, graphPane, graphPane.CalcScaleFactor(), out curveIndex)) { if (curveIndex < graphPane.CurveList.Count) { if (MouseDoubleClickOnLegendItem?.Invoke(graphPane, e, graphPane.CurveList[curveIndex].Label.Text) ?? false) { return(true); } if (e.Button == MouseButtons.Left) { this.ShowCurveExclusive(graphPane, graphPane.CurveList[curveIndex].Label.Text, true); return(true); } } else { if (MouseDoubleClickLegendArea != null) { MouseDoubleClickLegendArea(graphPane, e, ""); OnResetScale(graphPane); return(false); } if (e.Button == MouseButtons.Left) { MakeCurvesVisible(graphPane); OnResetScale(graphPane); return(true); } } } else if (mousePoint.Y <= graphPane.Legend.Rect.Bottom) { if (MouseDoubleClickLegendArea != null) { this.MouseDoubleClickLegendArea(graphPane, e, ""); OnResetScale(graphPane); return(false); } if (e.Button == MouseButtons.Left) { this.MakeCurvesVisible(graphPane); OnResetScale(graphPane); return(true); } } return(false); }
/// <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; } } }