public override void DrawSmoothFilledCurve(IGraphics g, GraphPane pane, CurveItem curve, float scaleFactor) { base.DrawSmoothFilledCurve(g, pane, curve, scaleFactor); // Draw the curve at the bottom of the graph. DrawCurve(g, pane, curve, scaleFactor, GetPointsForLowPointsArray(curve)); }
public DrawCurve(CurveItem _curve, string _curveName, GraphPane _pane, string _paneName) { CurveName = _curveName; PaneName = _paneName; Curve = _curve; Pane = _pane; }
//public static Color SelectedSymbolColor = Color.Gray; #endregion #region Methods /// <summary> /// Place a <see cref="CurveItem" /> 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="ci">The <see cref="CurveItem" /> to be added to the list.</param> public void Select( MasterPane master, CurveItem ci ) { //Clear the selection, but don't send the event, //the event will be sent in "AddToSelection" by calling "UpdateSelection" ClearSelection( master, false ); AddToSelection( master, ci ); }
private string MyPointValueHandler(ZedGraphControl control, GraphPane pane, CurveItem curve, int iPt) { // Get the PointPair that is under the mouse PointPair pt = curve[iPt]; return curve.Label.Text + " IV is " + pt.Y.ToString("f2") + "% " + pt.X.ToString("f1") + " strike"; }
/// <summary> /// Returns a new instance of a <see cref="ICurveDataHandler"/> appropriate for the /// <paramref name="curveItem"/>. /// </summary> public static ICurveDataHandler FindCurveHandler(CurveItem curveItem) { var handlerClass = curveItem.GetType().GetCustomAttributes(typeof (CurveDataHandlerAttribute), true) .Cast<CurveDataHandlerAttribute>().Select(attribute=>attribute.Class) .FirstOrDefault() ?? ((curveItem is HiLowBarItem) ? typeof (HiLowBarDataHandler) : typeof (CurveDataHandler)); var constructorInfo = handlerClass.GetConstructor(new Type[0]); if (constructorInfo != null) return (ICurveDataHandler) constructorInfo.Invoke(new object[0]); return null; }
static bool[] DimensionContainsNonZeroData(CurveItem curve) { bool[] ret = new bool[3]; for(int i = 0; i < curve.NPts; i++) { PointPair pp = curve.Points[i]; if (pp.X != 0) ret[0] = true; if (pp.Y != 0) ret[1] = true; if (pp.Z != 0) ret[2] = true; } return ret; }
static void WriteDataRow(CurveItem curve, bool[] validDims, int row, StreamWriter writer) { if (row < curve.NPts) { if (validDims[0]) WriteDouble(curve.Points[row].X, writer); if (validDims[1]) WriteDouble(curve.Points[row].Y, writer); if (validDims[2]) WriteDouble(curve.Points[row].Z, writer); } else { if (validDims[0]) WriteElement("", writer); if (validDims[1]) WriteElement("", writer); if (validDims[2]) WriteElement("", writer); } }
private static bool FindAllU12(ZedGraph.CurveItem gObj) { if (gObj.Tag == null) { return(false); } if (gObj.Tag.ToString().Contains("U12")) { return(true); } else { return(false); } }
private static bool FindAllPmax(ZedGraph.CurveItem ci) { if (ci.Tag == null) { return(false); } if (ci.Tag.ToString().Contains("Pmax")) { return(true); } else { return(false); } }
public override void CloseCurve(GraphPane pane, CurveItem curve, PointF[] arrPoints, int count, double yMin, System.Drawing.Drawing2D.GraphicsPath path) { if(pane.LineType == LineType.Stack) throw new NotSupportedException("Filled lines cannot be stacked"); FilledLineItem filledCurve = curve as FilledLineItem; if(filledCurve == null) throw new ArgumentException("Curve was of the wrong type. Expected FilledLineItem but was " + curve.GetType(), "curve"); // Build another points array consisting of the low points (It gets these from the LowerPoints property of the curve) PointF[] arrPoints2; int count2; BuildLowPointsArray(pane, curve, out arrPoints2, out count2); // Add the new points to the GraphicsPath float tension = _isSmooth ? _smoothTension : 0f; path.AddCurve(arrPoints2, 0, count2 - 2, tension); }
public CurveItemTypePair(CurveItem curve, CurveType type, String name, int nC) { Curve = curve; Type = type; Scale = GlobalVars.DEFAULTSCALE(type); CurrCoordinates = new CurveItemTypePair.CurrentCoordinates(); DrawCursorDot = true; DrawCursorLines = true; HorizontalCursorLine = new LineObj(); VerticalCursorLine = new LineObj(); SymbolsOn = true; Name = name; ComputeInterestingValues(); CurveObj = new CurveObject((PointPairList)curve.Points, nC); CurveObj.XMAX = this.XMax; CurveObj.YMAX = this.YMax; NCurves = nC; }
/// <summary> /// Draw the this <see cref="Bar"/> to the specified <see cref="Graphics"/> /// device as a bar at each defined point. This method /// is normally only called by the <see cref="BarItem.Draw"/> method of the /// <see cref="BarItem"/> object /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="CurveItem"/> object representing the /// <see cref="Bar"/>'s to be drawn.</param> /// <param name="baseAxis">The <see cref="Axis"/> class instance that defines the base (independent) /// axis for the <see cref="Bar"/></param> /// <param name="valueAxis">The <see cref="Axis"/> class instance that defines the value (dependent) /// axis for the <see cref="Bar"/></param> /// <param name="barWidth"> /// The width of each bar, in pixels. /// </param> /// <param name="pos"> /// The ordinal position of the this bar series (0=first bar, 1=second bar, etc.) /// in the cluster of bars. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void DrawBars(Graphics g, GraphPane pane, CurveItem curve, Axis baseAxis, Axis valueAxis, float barWidth, int pos, float scaleFactor) { // For Overlay and Stack bars, the position is always zero since the bars are on top // of eachother if (pane.BarType == BarType.Overlay || pane.BarType == BarType.Stack || pane.BarType == BarType.PercentStack) { pos = 0; } // Loop over each defined point and draw the corresponding bar for (int i = 0; i < curve.Points.Count; i++) { DrawSingleBar(g, pane, curve, i, pos, baseAxis, valueAxis, scaleFactor); } }
public DataFrameBuilder(GraphPane graphPane, CurveItem curveItem) { GraphPane = graphPane; CurveItem = curveItem; var msPointList = curveItem.Points as MSPointList; if (msPointList != null) { Points = msPointList.FullList; } else { Points = curveItem.Points; } XAxis = curveItem.GetXAxis(graphPane); YAxis = curveItem.GetYAxis(graphPane); BaseAxis = curveItem.BaseAxis(graphPane); ValueAxis = curveItem.ValueAxis(graphPane); }
/// <summary> /// Do all rendering associated with this <see cref="Line"/> to the specified /// <see cref="Graphics"/> device. This method is normally only /// called by the Draw method of the parent <see cref="LineItem"/> object. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <param name="pane"> /// A reference to the <see cref="ZedGraph.GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="LineItem"/> representing this /// curve.</param> public void Draw(Graphics g, GraphPane pane, CurveItem curve, float scaleFactor) { // If the line is being shown, draw it if (this.IsVisible) { if (curve is StickItem) { DrawSticks(g, pane, curve, scaleFactor); } else if (this.IsSmooth || this.Fill.IsVisible) { DrawSmoothFilledCurve(g, pane, curve, scaleFactor); } else { DrawCurve(g, pane, curve, scaleFactor); } } }
/// <summary> /// The Copy Constructor /// </summary> /// <param name="rhs">The CurveItem object from which to copy</param> public CurveItem(CurveItem rhs) { symbol = new Symbol(rhs.Symbol); line = new Line(rhs.Line); label = rhs.Label; stepType = rhs.StepType; isY2Axis = rhs.IsY2Axis; int len = rhs.X.GetLength(0); X = new double[len]; Y = new double[len]; for (int i = 0; i < len; i++) { X[i] = rhs.X[i]; Y[i] = rhs.Y[i]; } }
private void SetCurveFromControls(CurveItem aCurve) { if (aCurve != null) { aCurve.Label.Text = txtCurveLabel.Text; if (aCurve.IsY2Axis != (cboCurveAxis.SelectedIndex == 1)) { //TODO: move curve to other axis } aCurve.Color = txtCurveColor.BackColor; if (aCurve is LineItem) { int lWidth; if (int.TryParse(txtCurveWidth.Text, out lWidth)) { ((LineItem)aCurve).Line.Width = lWidth; } } } }
/// <summary> /// Draw the this <see cref="Bar"/> to the specified <see cref="Graphics"/> /// device as a bar at each defined point. This method /// is normally only called by the <see cref="BarItem.Draw"/> method of the /// <see cref="BarItem"/> object /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="CurveItem"/> object representing the /// <see cref="Bar"/>'s to be drawn.</param> /// <param name="baseAxis">The <see cref="Axis"/> class instance that defines the base (independent) /// axis for the <see cref="Bar"/></param> /// <param name="valueAxis">The <see cref="Axis"/> class instance that defines the value (dependent) /// axis for the <see cref="Bar"/></param> /// <param name="barWidth"> /// The width of each bar, in pixels. /// </param> /// <param name="pos"> /// The ordinal position of the this bar series (0=first bar, 1=second bar, etc.) /// in the cluster of bars. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void DrawBars(IGraphics g, GraphPane pane, CurveItem curve, Axis baseAxis, Axis valueAxis, float barWidth, int pos, float scaleFactor) { // For non-cluster bar types, the position is always zero since the bars are on top // of eachother BarType barType = pane._barSettings.Type; if (barType == BarType.Overlay || barType == BarType.Stack || barType == BarType.PercentStack || barType == BarType.SortedOverlay) { pos = 0; } // Loop over each defined point and draw the corresponding bar for (int i = 0; i < curve.Points.Count; i++) { DrawSingleBar(g, pane, curve, i, pos, baseAxis, valueAxis, barWidth, scaleFactor); } }
/// <summary> /// Calculate the screen pixel position of the center of the specified bar, using the /// <see cref="Axis"/> as specified by <see cref="GraphPane.BarBase"/>. This method is /// used primarily by the /// <see cref="GraphPane.FindNearestPoint(PointF,out CurveItem,out int)"/> method in order to /// determine the bar "location," which is defined as the center of the top of the individual bar. /// </summary> /// <param name="curve">The <see cref="CurveItem"/> representing the /// bar of interest.</param> /// <param name="barWidth">The width of each individual bar. This can be calculated using /// the <see cref="CurveItem.GetBarWidth"/> method.</param> /// <param name="iCluster">The cluster number for the bar of interest. This is the ordinal /// position of the current point. That is, if a particular <see cref="CurveItem"/> has /// 10 points, then a value of 3 would indicate the 4th point in the data array.</param> /// <param name="val">The actual independent axis value for the bar of interest.</param> /// <param name="iOrdinal">The ordinal position of the <see cref="CurveItem"/> of interest. /// That is, the first bar series is 0, the second is 1, etc. Note that this applies only /// to the bars. If a graph includes both bars and lines, then count only the bars.</param> /// <returns>A screen pixel X position of the center of the bar of interest.</returns> public double BarCenterValue(CurveItem curve, float barWidth, int iCluster, double val, int iOrdinal) { float clusterWidth = pane.GetClusterWidth(); float clusterGap = pane.MinClusterGap * barWidth; float barGap = barWidth * pane.MinBarGap; if ((curve.IsBar && !(pane.BarType == BarType.Cluster)) || curve is ErrorBarItem || curve is HiLowBarItem) { iOrdinal = 0; } Axis baseAxis = curve.BaseAxis(pane); float centerPix = baseAxis.Transform(iCluster, val) - clusterWidth / 2.0F + clusterGap / 2.0F + iOrdinal * (barWidth + barGap) + 0.5F * barWidth; return(baseAxis.ReverseTransform(centerPix)); }
/// <summary> /// Draw the this <see cref="CurveItem"/> to the specified <see cref="Graphics"/> /// device using the specified smoothing property (<see cref="ZedGraph.Line.SmoothTension"/>). /// The routine draws the line segments and the area fill (if any, see <see cref="FillType"/>; /// the symbols are drawn by the <see cref="Symbol.Draw"/> method. This method /// is normally only called by the Draw method of the /// <see cref="CurveItem"/> object. Note that the <see cref="StepType"/> property /// is ignored for smooth lines (e.g., when <see cref="ZedGraph.Line.IsSmooth"/> is true). /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="LineItem"/> representing this /// curve.</param> public void DrawSmoothFilledCurve(Graphics g, GraphPane pane, CurveItem curve, float scaleFactor) { PointF[] arrPoints; int count; PointPairList points = curve.Points; if (this.IsVisible && !this.Color.IsEmpty && points != null && BuildPointsArray(pane, curve, out arrPoints, out count) && count > 2) { Pen pen = new Pen(this.Color, pane.ScaledPenWidth(width, scaleFactor)); pen.DashStyle = this.Style; float tension = this.isSmooth ? this.smoothTension : 0f; // Fill the curve if needed if (this.Fill.IsVisible) { Axis yAxis = curve.IsY2Axis ? (Axis)pane.Y2Axis : (Axis)pane.YAxis; GraphicsPath path = new GraphicsPath(FillMode.Winding); path.AddCurve(arrPoints, 0, count - 2, tension); double yMin = yAxis.Min < 0 ? 0.0 : yAxis.Min; CloseCurve(pane, curve, arrPoints, count, yMin, path); RectangleF rect = path.GetBounds(); Brush brush = this.fill.MakeBrush(rect); g.FillPath(brush, path); brush.Dispose(); // restore the zero line if needed (since the fill tends to cover it up) yAxis.FixZeroLine(g, pane, scaleFactor, rect.Left, rect.Right); } // Stroke the curve g.DrawCurve(pen, arrPoints, 0, count - 2, tension); pen.Dispose(); } }
private void SetControlsFromCurve(CurveItem aCurve) { if (aCurve != null) { txtCurveLabel.Text = aCurve.Label.Text; cboCurveAxis.SelectedIndex = (aCurve.IsY2Axis) ? 1 : 0; txtCurveColor.BackColor = aCurve.Color; if (aCurve is LineItem) { lblCurve.Visible = true; txtCurveWidth.Visible = true; txtCurveWidth.Text = ((LineItem)aCurve).Line.Width.ToString(); } else { lblCurve.Visible = false; txtCurveWidth.Visible = false; } } }
/// <summary> /// The Copy Constructor /// </summary> /// <param name="rhs">The CurveItem object from which to copy</param> public CurveItem(CurveItem rhs) { _label = rhs._label.Clone(); _isY2Axis = rhs.IsY2Axis; _isVisible = rhs.IsVisible; _isOverrideOrdinal = rhs._isOverrideOrdinal; _yAxisIndex = rhs._yAxisIndex; if (rhs.Tag is ICloneable) { Tag = ((ICloneable)rhs.Tag).Clone(); } else { Tag = rhs.Tag; } _points = (IPointList)rhs.Points.Clone(); _link = rhs._link.Clone(); }
/// <summary> /// Draw the specified single bar (an individual "point") of this series to the specified /// <see cref="Graphics"/> device. This method is not as efficient as /// <see cref="DrawBars"/>, which draws the bars for all points. It is intended to be used /// only for <see cref="BarType.SortedOverlay"/>, which requires special handling of each bar. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="CurveItem"/> object representing the /// <see cref="Bar"/>'s to be drawn.</param> /// <param name="baseAxis">The <see cref="Axis"/> class instance that defines the base (independent) /// axis for the <see cref="Bar"/></param> /// <param name="valueAxis">The <see cref="Axis"/> class instance that defines the value (dependent) /// axis for the <see cref="Bar"/></param> /// <param name="pos"> /// The ordinal position of the this bar series (0=first bar, 1=second bar, etc.) /// in the cluster of bars. /// </param> /// <param name="index"> /// The zero-based index number for the single bar to be drawn. /// </param> /// <param name="barWidth"> /// The width of each bar, in pixels. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void DrawSingleBar(Graphics g, GraphPane pane, CurveItem curve, Axis baseAxis, Axis valueAxis, int pos, int index, float barWidth, float scaleFactor) { // Make sure that a bar value exists for the current curve and current ordinal position if (index >= curve.Points.Count) { return; } // For Overlay and Stack bars, the position is always zero since the bars are on top // of eachother if (pane._barSettings.Type == BarType.Overlay || pane._barSettings.Type == BarType.Stack || pane._barSettings.Type == BarType.PercentStack) { pos = 0; } // Draw the specified bar DrawSingleBar(g, pane, curve, index, pos, baseAxis, valueAxis, barWidth, scaleFactor); }
/// <summary> /// Draw the specified single bar (an individual "point") of this series to the specified /// <see cref="Graphics"/> device. This method is not as efficient as /// <see cref="DrawBars"/>, which draws the bars for all points. It is intended to be used /// only for <see cref="BarType.SortedOverlay"/>, which requires special handling of each bar. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="CurveItem"/> object representing the /// <see cref="Bar"/>'s to be drawn.</param> /// <param name="baseAxis">The <see cref="Axis"/> class instance that defines the base (independent) /// axis for the <see cref="Bar"/></param> /// <param name="valueAxis">The <see cref="Axis"/> class instance that defines the value (dependent) /// axis for the <see cref="Bar"/></param> /// <param name="pos"> /// The ordinal position of the this bar series (0=first bar, 1=second bar, etc.) /// in the cluster of bars. /// </param> /// <param name="index"> /// The zero-based index number for the single bar to be drawn. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="GraphPane.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void DrawSingleBar(Graphics g, GraphPane pane, CurveItem curve, Axis baseAxis, Axis valueAxis, int pos, int index, double scaleFactor) { if (index >= curve.Points.Count) { return; } //SetupBarStack( valueAxis, curve.Points.Count ); // For Overlay and Stack bars, the position is always zero since the bars are on top // of eachother if (pane.BarType == BarType.Overlay || pane.BarType == BarType.Stack || pane.BarType == BarType.PercentStack) { pos = 0; } DrawSingleBar(g, pane, curve, index, pos, baseAxis, valueAxis, scaleFactor); }
///------------------------------------------------------------------------ /// <summary> /// Toggles the curve visible. /// </summary> /// <param name="graphPane">The graph pane.</param> /// <param name="curveLabel">The curve label.</param> ///------------------------------------------------------------------------ public void ToggleCurveVisible(GraphPane graphPane, string curveLabel) { CurveItem ci = graphPane.CurveList[graphPane.CurveList.IndexOf(curveLabel)]; if (ci.IsVisible && graphPane.CurveList.Count(c => c.IsVisible) == 1) { return; } ci.IsVisible = !ci.IsVisible; AddRemoveHiddenCurveIndex(curveLabel); if (!ci.IsVisible) { ci.Tag = ci.Label.FontSpec; ci.Label.FontSpec = FontDisabled; ci.Label.FontSpec.Border.IsVisible = false; } else { ci.Label.FontSpec = null; } this.Invalidate(); }
/// <summary> /// Draw the this <see cref="Bar"/> to the specified <see cref="Graphics"/> /// device as a bar at each defined point. This method /// is normally only called by the <see cref="BarItem.Draw"/> method of the /// <see cref="BarItem"/> object /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="CurveItem"/> object representing the /// <see cref="Bar"/>'s to be drawn.</param> /// <param name="baseAxis">The <see cref="Axis"/> class instance that defines the base (independent) /// axis for the <see cref="Bar"/></param> /// <param name="valueAxis">The <see cref="Axis"/> class instance that defines the value (dependent) /// axis for the <see cref="Bar"/></param> /// <param name="barWidth"> /// The width of each bar, in pixels. /// </param> /// <param name="pos"> /// The ordinal position of the this bar series (0=first bar, 1=second bar, etc.) /// in the cluster of bars. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void DrawBars(Graphics g, GraphPane pane, CurveItem curve, Axis baseAxis, Axis valueAxis, float barWidth, int pos, float scaleFactor) { // For Overlay and Stack bars, the position is always zero since the bars are on top // of eachother if (pane._barSettings.Type == BarType.Overlay || pane._barSettings.Type == BarType.Stack || pane._barSettings.Type == BarType.PercentStack) { pos = 0; } // BioRad addition 7.9.2007 _barRectangles.Clear(); _barRectangles.AddRange(new RectangleF[curve.Points.Count]); // end BioRad // Loop over each defined point and draw the corresponding bar for (int i = 0; i < curve.Points.Count; i++) { DrawSingleBar(g, pane, curve, i, pos, baseAxis, valueAxis, barWidth, scaleFactor); } }
/// <summary> /// Create a URL for a <see cref="CurveItem" /> that includes the index of the /// point that was selected. /// </summary> /// <remarks> /// An "index" parameter is added to the <see cref="Url" /> property for this /// link to indicate which point was selected. Further, if the /// X or Y axes that correspond to this <see cref="CurveItem" /> are of /// <see cref="AxisType.Text" />, then an /// additional parameter will be added containing the text value that /// corresponds to the <paramref name="index" /> of the selected point. /// The <see cref="XAxis" /> text parameter will be labeled "xtext", and /// the <see cref="YAxis" /> text parameter will be labeled "ytext". /// </remarks> /// <param name="index">The zero-based index of the selected point</param> /// <param name="pane">The <see cref="GraphPane" /> of interest</param> /// <param name="curve">The <see cref="CurveItem" /> for which to /// make the url string.</param> /// <returns>A string containing the url with an index parameter added.</returns> public virtual string MakeCurveItemUrl(GraphPane pane, CurveItem curve, int index) { string url = _url; if (url.IndexOf('?') >= 0) url += "&index=" + index.ToString(); else url += "?index=" + index.ToString(); Axis xAxis = curve.GetXAxis(pane); if (xAxis.Type == AxisType.Text && index >= 0 && xAxis.Scale.TextLabels != null && index <= xAxis.Scale.TextLabels.Length) url += "&xtext=" + xAxis.Scale.TextLabels[index]; Axis yAxis = curve.GetYAxis(pane); if (yAxis != null && yAxis.Type == AxisType.Text && index >= 0 && yAxis.Scale.TextLabels != null && index <= yAxis.Scale.TextLabels.Length) url += "&ytext=" + yAxis.Scale.TextLabels[index]; return url; }
/// <summary> /// Draw the this <see cref="Bar"/> to the specified <see cref="Graphics"/> /// device as a bar at each defined point. This method /// is normally only called by the <see cref="BarItem.Draw"/> method of the /// <see cref="BarItem"/> object /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="CurveItem"/> object representing the /// <see cref="Bar"/>'s to be drawn.</param> /// <param name="baseAxis">The <see cref="Axis"/> class instance that defines the base (independent) /// axis for the <see cref="Bar"/></param> /// <param name="valueAxis">The <see cref="Axis"/> class instance that defines the value (dependent) /// axis for the <see cref="Bar"/></param> /// <param name="barWidth"> /// The width of each bar, in pixels. /// </param> /// <param name="pos"> /// The ordinal position of the this bar series (0=first bar, 1=second bar, etc.) /// in the cluster of bars. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void DrawBars(Graphics g, GraphPane pane, CurveItem curve, Axis baseAxis, Axis valueAxis, float barWidth, int pos, float scaleFactor) { // For non-cluster bar types, the position is always zero since the bars are on top // of eachother BarType barType = pane._barSettings.Type; if (barType == BarType.Overlay || barType == BarType.Stack || barType == BarType.PercentStack || barType == BarType.SortedOverlay) { pos = 0; } int minX = (int)pane.Chart.Rect.Left; int maxX = (int)pane.Chart.Rect.Right; int minY = (int)pane.Chart.Rect.Top; int maxY = (int)pane.Chart.Rect.Bottom; int minOrdinal = 0; int maxOrdinal = int.MaxValue; if (baseAxis.Scale.IsAnyOrdinal) { minOrdinal = (int)baseAxis.Scale.Min; maxOrdinal = (int)baseAxis.Scale.Max; } // Loop over each defined point and draw the corresponding bar var start = Math.Max(0, minOrdinal); int limit = Math.Min(curve.Points.Count, maxOrdinal); for (int i = start; i < limit; i++) { DrawSingleBar(g, pane, curve, i, pos, baseAxis, valueAxis, barWidth, scaleFactor); } }
/// <summary> /// Calculate the user scale position of the center of the specified bar, using the /// <see cref="Axis"/> as specified by <see cref="BarSettings.Base"/>. This method is /// used primarily by the /// <see cref="GraphPane.FindNearestPoint(PointF,out CurveItem,out int)"/> method in order to /// determine the bar "location," which is defined as the center of the top of the individual bar. /// </summary> /// <param name="curve">The <see cref="CurveItem"/> representing the /// bar of interest.</param> /// <param name="barWidth">The width of each individual bar. This can be calculated using /// the <see cref="CurveItem.GetBarWidth"/> method.</param> /// <param name="iCluster">The cluster number for the bar of interest. This is the ordinal /// position of the current point. That is, if a particular <see cref="CurveItem"/> has /// 10 points, then a value of 3 would indicate the 4th point in the data array.</param> /// <param name="val">The actual independent axis value for the bar of interest.</param> /// <param name="iOrdinal">The ordinal position of the <see cref="CurveItem"/> of interest. /// That is, the first bar series is 0, the second is 1, etc. Note that this applies only /// to the bars. If a graph includes both bars and lines, then count only the bars.</param> /// <returns>A user scale value position of the center of the bar of interest.</returns> public double BarCenterValue( CurveItem curve, float barWidth, int iCluster, double val, int iOrdinal) { var baseAxis = curve.BaseAxis(_pane); if (curve is ErrorBarItem || curve is HiLowBarItem || curve is OHLCBarItem || curve is JapaneseCandleStickItem) { if (baseAxis._scale.IsAnyOrdinal && iCluster >= 0 && !curve.IsOverrideOrdinal) { return(iCluster + 1.0); } else { return(val); } } var clusterWidth = _pane._barSettings.GetClusterWidth(); var clusterGap = _pane._barSettings.MinClusterGap * barWidth; var barGap = barWidth * _pane._barSettings.MinBarGap; if (curve.IsBar && _pane._barSettings.Type != BarType.Cluster) { iOrdinal = 0; } var centerPix = baseAxis.Scale.Transform(curve.IsOverrideOrdinal, iCluster, val) - clusterWidth / 2.0F + clusterGap / 2.0F + iOrdinal * (barWidth + barGap) + 0.5F * barWidth; return(baseAxis.Scale.ReverseTransform(centerPix)); }
/// <summary> /// Calculate the <see cref="Legend"/> rectangle (<see cref="Rect"/>), /// taking into account the number of required legend /// entries, and the legend drawing preferences. /// </summary> /// <remarks>Adjust the size of the /// <see cref="Chart.Rect"/> for the parent <see cref="GraphPane"/> to accomodate the /// space required by the legend. /// </remarks> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="PaneBase"/> object that is the parent or /// owner of this object. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <param name="tChartRect"> /// The rectangle that contains the area bounded by the axes, in pixel units. /// <seealso cref="Chart.Rect" /> /// </param> public void CalcRect(Graphics g, PaneBase pane, float scaleFactor, ref RectangleF tChartRect) { // Start with an empty rectangle _rect = Rectangle.Empty; _numberOfColumns = 1; _legendItemWidth = 1; _legendItemHeight = 0; RectangleF clientRect = pane.CalcClientRect(g, scaleFactor); // If the legend is invisible, don't do anything if (!_isVisible) { return; } int numberOfCurvesToDraw = 0; PaneList paneList = GetPaneList(pane); _tmpSize = GetMaxHeight(paneList, g, scaleFactor); float halfGap = _tmpSize / 2.0F, maxWidth = 0, tmpWidth = 0, gapPix = _gap * _tmpSize; bool showingSecondaryLabel = false; foreach (GraphPane tmpPane in paneList) { // Loop through each curve in the curve list // Find the maximum width of the legend labels //foreach ( CurveItem curve in tmpPane.CurveList ) //foreach ( CurveItem curve in GetIterator( tmpPane.CurveList, _isReverse ) ) int count = tmpPane.CurveList.Count; for (int i = 0; i < count; i++) { CurveItem curve = tmpPane.CurveList[_isReverse ? count - i - 1 : i]; bool atLeastOneLabelDrawn = false; if (curve._label._text != string.Empty && curve._label._isVisible) { // Calculate the width of the label save the max width FontSpec tmpFont = (curve._label._fontSpec != null) ? curve._label._fontSpec : this.FontSpec; tmpWidth = tmpFont.GetWidth(g, curve._label._text, scaleFactor); if (tmpWidth > maxWidth) { maxWidth = tmpWidth; } // Save the maximum symbol height for line-type curves if (curve is LineItem && ((LineItem)curve).Symbol.Size > _legendItemHeight) { _legendItemHeight = ((LineItem)curve).Symbol.Size; } atLeastOneLabelDrawn = true; } if (curve.SecondaryLabel._text != string.Empty && curve.SecondaryLabel._isVisible) { // Calculate the width of the label save the max width FontSpec tmpFont = (curve.SecondaryLabel._fontSpec != null) ? curve.SecondaryLabel._fontSpec : this.FontSpec; tmpWidth = tmpFont.GetWidth(g, curve.SecondaryLabel._text, scaleFactor); if (tmpWidth > maxWidth) { maxWidth = tmpWidth; } // Save the maximum symbol height for line-type curves if (curve is LineItem && ((LineItem)curve).Symbol.Size > _legendItemHeight) { _legendItemHeight = ((LineItem)curve).Symbol.Size; } atLeastOneLabelDrawn = true; showingSecondaryLabel = true; } if (atLeastOneLabelDrawn) { ++numberOfCurvesToDraw; } } if (pane is MasterPane && ((MasterPane)pane).IsUniformLegendEntries) { break; } } float widthAvail; // Is this legend horizontally stacked? if (_isHStack) { // Determine the available space for horizontal stacking switch (_position) { // Never stack if the legend is to the right or left case LegendPos.Right: case LegendPos.Left: widthAvail = 0; break; // for the top & bottom, the axis border width is available case LegendPos.Top: case LegendPos.TopCenter: case LegendPos.Bottom: case LegendPos.BottomCenter: widthAvail = tChartRect.Width; break; // for the top & bottom flush left, the panerect less margins is available case LegendPos.TopFlushLeft: case LegendPos.BottomFlushLeft: widthAvail = clientRect.Width; break; // for inside the axis area or Float, use 1/2 of the axis border width case LegendPos.InsideTopRight: case LegendPos.InsideTopLeft: case LegendPos.InsideBotRight: case LegendPos.InsideBotLeft: case LegendPos.Float: widthAvail = tChartRect.Width / 2; break; // shouldn't ever happen default: widthAvail = 0; break; } // width of one legend entry if (_isShowLegendSymbols) { if (showingSecondaryLabel) { _legendItemWidth = 3.0f * _tmpSize + maxWidth * 1.6f; } else { _legendItemWidth = 3.0f * _tmpSize + maxWidth; } } else { _legendItemWidth = 0.5f * _tmpSize + maxWidth; } // Calculate the number of columns in the legend // Normally, the legend is: // available width / ( max width of any entry + space for line&symbol ) if (maxWidth > 0) { _numberOfColumns = (int)((widthAvail - halfGap) / _legendItemWidth); } // You can never have more columns than legend entries if (_numberOfColumns > numberOfCurvesToDraw) { _numberOfColumns = numberOfCurvesToDraw; } // a saftey check if (_numberOfColumns == 0) { _numberOfColumns = 1; } } else { if (_isShowLegendSymbols) { _legendItemWidth = 4.0F * _tmpSize + maxWidth; } else { _legendItemWidth = 0.5F * _tmpSize + maxWidth; } } // legend is: // item: space line space text space // width: wid 4*wid wid maxWid wid // The symbol is centered on the line // // legend begins 3 * wid to the right of the plot rect // // The height of the legend is the actual height of the lines of text // (nCurve * hite) plus wid on top and wid on the bottom // total legend width float totLegWidth = _numberOfColumns * _legendItemWidth; // The total legend height _legendItemHeight = _legendItemHeight * (float)scaleFactor + halfGap; if (_tmpSize > _legendItemHeight) { _legendItemHeight = _tmpSize; } float totLegHeight = (float)Math.Ceiling((double)numberOfCurvesToDraw / (double)_numberOfColumns) * _legendItemHeight; RectangleF newRect = new RectangleF(); // Now calculate the legend rect based on the above determined parameters // Also, adjust the ChartRect to reflect the space for the legend if (numberOfCurvesToDraw > 0) { newRect = new RectangleF(0, 0, totLegWidth, totLegHeight); // The switch statement assigns the left and top edges, and adjusts the ChartRect // as required. The right and bottom edges are calculated at the bottom of the switch. switch (_position) { case LegendPos.Right: newRect.X = clientRect.Right - totLegWidth; newRect.Y = tChartRect.Top; tChartRect.Width -= totLegWidth + gapPix; break; case LegendPos.Top: newRect.X = tChartRect.Left; newRect.Y = clientRect.Top; tChartRect.Y += totLegHeight + gapPix; tChartRect.Height -= totLegHeight + gapPix; break; case LegendPos.TopFlushLeft: newRect.X = clientRect.Left; newRect.Y = clientRect.Top; tChartRect.Y += totLegHeight + gapPix * 1.5f; tChartRect.Height -= totLegHeight + gapPix * 1.5f; break; case LegendPos.TopCenter: newRect.X = tChartRect.Left + (tChartRect.Width - totLegWidth) / 2; newRect.Y = tChartRect.Top; tChartRect.Y += totLegHeight + gapPix; tChartRect.Height -= totLegHeight + gapPix; break; case LegendPos.Bottom: newRect.X = tChartRect.Left; newRect.Y = clientRect.Bottom - totLegHeight; tChartRect.Height -= totLegHeight + gapPix; break; case LegendPos.BottomFlushLeft: newRect.X = clientRect.Left; newRect.Y = clientRect.Bottom - totLegHeight; tChartRect.Height -= totLegHeight + gapPix; break; case LegendPos.BottomCenter: newRect.X = tChartRect.Left + (tChartRect.Width - totLegWidth) / 2; newRect.Y = clientRect.Bottom - totLegHeight; tChartRect.Height -= totLegHeight + gapPix; break; case LegendPos.Left: newRect.X = clientRect.Left; newRect.Y = tChartRect.Top; tChartRect.X += totLegWidth + halfGap; tChartRect.Width -= totLegWidth + gapPix; break; case LegendPos.InsideTopRight: newRect.X = tChartRect.Right - totLegWidth; newRect.Y = tChartRect.Top; break; case LegendPos.InsideTopLeft: newRect.X = tChartRect.Left; newRect.Y = tChartRect.Top; break; case LegendPos.InsideBotRight: newRect.X = tChartRect.Right - totLegWidth; newRect.Y = tChartRect.Bottom - totLegHeight; break; case LegendPos.InsideBotLeft: newRect.X = tChartRect.Left; newRect.Y = tChartRect.Bottom - totLegHeight; break; case LegendPos.Float: newRect.Location = this.Location.TransformTopLeft(pane, totLegWidth, totLegHeight); break; } } _rect = newRect; }
/// <summary> /// Render the <see cref="Legend"/> to the specified <see cref="Graphics"/> device. /// </summary> /// <remarks> /// This method is normally only called by the Draw method /// of the parent <see cref="GraphPane"/> object. /// </remarks> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="PaneBase"/> object that is the parent or /// owner of this object. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void Draw(Graphics g, PaneBase pane, float scaleFactor) { // if the legend is not visible, do nothing if (!_isVisible) { return; } // Fill the background with the specified color if required _fill.Draw(g, _rect); PaneList paneList = GetPaneList(pane); float halfGap = _tmpSize / 2.0F; // Check for bad data values if (_numberOfColumns <= 0) { _numberOfColumns = 1; } if (_legendItemWidth <= 0) { _legendItemWidth = 100; } if (_legendItemHeight <= 0) { _legendItemHeight = _tmpSize; } //float gap = pane.ScaledGap( scaleFactor ); int iEntry = 0; // Get a brush for the legend label text using (SolidBrush brushB = new SolidBrush(Color.Black)) { foreach (GraphPane tmpPane in paneList) { // Loop for each curve in the CurveList collection //foreach ( CurveItem curve in tmpPane.CurveList ) int count = tmpPane.CurveList.Count; for (int i = 0; i < count; i++) { CurveItem curve = tmpPane.CurveList[_isReverse ? count - i - 1 : i]; float x = _rect.Left + halfGap / 2.0F + (iEntry % _numberOfColumns) * (_legendItemWidth); float y = _rect.Top + (int)(iEntry / _numberOfColumns) * _legendItemHeight; float xEnd = DrawLabel(curve.Label, curve, g, pane, scaleFactor, tmpPane, _isShowLegendSymbols, x, y); x = xEnd; DrawLabel(curve.SecondaryLabel, curve, g, pane, scaleFactor, tmpPane, false, x, y); iEntry += 1; } if (pane is MasterPane && ((MasterPane)pane).IsUniformLegendEntries) { break; } } // Draw a border around the legend if required if (iEntry > 0) { this.Border.Draw(g, pane, scaleFactor, _rect); } } }
/* * /// <summary> * /// Remove a <see cref="CurveItem"/> object from the collection based on an object reference. * /// </summary> * /// <param name="curve">A reference to the <see cref="CurveItem"/> object that is to be * /// removed.</param> * /// <seealso cref="IList.Remove"/> * public void Remove( CurveItem curve ) * { * List.Remove( curve ); * } */ /// <summary> /// Insert a <see cref="CurveItem"/> object into the collection at the specified /// zero-based index location. /// </summary> /// <param name="index">The zero-based index location for insertion.</param> /// <param name="curve">A reference to the <see cref="CurveItem"/> object that is to be /// inserted.</param> /// <seealso cref="IList.Insert"/> public void Insert(int index, CurveItem curve) { List.Insert(index, curve); }
/// <summary> /// Draw the this <see cref="Bar"/> to the specified <see cref="Graphics"/> /// device as a bar at each defined point. This method /// is normally only called by the <see cref="BarItem.Draw"/> method of the /// <see cref="BarItem"/> object /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="CurveItem"/> object representing the /// <see cref="Bar"/>'s to be drawn.</param> /// <param name="baseAxis">The <see cref="Axis"/> class instance that defines the base (independent) /// axis for the <see cref="Bar"/></param> /// <param name="valueAxis">The <see cref="Axis"/> class instance that defines the value (dependent) /// axis for the <see cref="Bar"/></param> /// <param name="barWidth"> /// The width of each bar, in pixels. /// </param> /// <param name="pos"> /// The ordinal position of the this bar series (0=first bar, 1=second bar, etc.) /// in the cluster of bars. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="GraphPane.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void DrawBars( Graphics g, GraphPane pane, CurveItem curve, Axis baseAxis, Axis valueAxis, float barWidth, int pos, double scaleFactor ) { // For Overlay and Stack bars, the position is always zero since the bars are on top // of eachother if ( pane.BarType == BarType.Overlay || pane.BarType == BarType.Stack || pane.BarType == BarType.PercentStack ) pos = 0; // Loop over each defined point for ( int i=0; i<curve.Points.Count; i++ ) DrawSingleBar( g, pane, curve, i, pos, baseAxis, valueAxis, scaleFactor ); }
private string zg1_PointValueEvent(ZedGraphControl sender, GraphPane pane, CurveItem curve, int iPt) { PointPair pt = curve[iPt]; return (curve.Label.Text + pt.X.ToString()+" , "+pt.Y.ToString()); }
/// <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 ); }
// Define a "Contains" method so that this class works with .Net 1.1 or 2.0 internal bool Contains( CurveItem item ) { foreach ( CurveItem ci in this ) if ( item == ci ) return true; return false; }
/// <summary> /// Compares two <see cref="CurveItem"/>s using the previously specified index value /// and axis. Sorts in descending order. /// </summary> /// <param name="l">Curve to the left.</param> /// <param name="r">Curve to the right.</param> /// <returns>-1, 0, or 1 depending on l.X's relation to r.X</returns> int IComparer.Compare(object l, object r) { if (l == null && r == null) { return(0); } else if (l == null && r != null) { return(-1); } else if (l != null && r == null) { return(1); } CurveItem lc = (CurveItem)l; CurveItem rc = (CurveItem)r; if (rc != null && rc.NPts <= index) { r = null; } if (lc != null && lc.NPts <= index) { l = null; } double lVal, rVal; if (sortType == SortType.XValues) { lVal = System.Math.Abs(lc[index].X); rVal = System.Math.Abs(rc[index].X); } else { lVal = System.Math.Abs(lc[index].Y); rVal = System.Math.Abs(rc[index].Y); } if (lVal == PointPair.Missing || Double.IsInfinity(lVal) || Double.IsNaN(lVal)) { l = null; } if (rVal == PointPair.Missing || Double.IsInfinity(rVal) || Double.IsNaN(rVal)) { r = null; } if ((l == null && r == null) || (System.Math.Abs(lVal - rVal) < 1e-10)) { return(0); } else if (l == null && r != null) { return(-1); } else if (l != null && r == null) { return(1); } else { return(rVal < lVal ? -1 : 1); } }
/// <summary> /// Get the user scale values associate with a particular point of a /// particular curve.</summary> /// <remarks>The main purpose of this method is to handle /// stacked bars, in which case the stacked values are returned rather /// than the individual data values. /// </remarks> /// <param name="curve">A <see cref="CurveItem"/> object of interest.</param> /// <param name="iPt">The zero-based point index for the point of interest.</param> /// <param name="baseVal">A <see cref="Double"/> value representing the value /// for the independent axis.</param> /// <param name="lowVal">A <see cref="Double"/> value representing the lower /// value for the dependent axis.</param> /// <param name="hiVal">A <see cref="Double"/> value representing the upper /// value for the dependent axis.</param> /// <returns>true if the data point is value, false for /// <see cref="PointPair.Missing"/>, invalid, etc. data.</returns> public bool GetBarValues( CurveItem curve, int iPt, out double baseVal, out double lowVal, out double hiVal ) { return GetBarValues( this.pane, curve, iPt, out baseVal, out lowVal, out hiVal ); }
/// <summary> /// Get the user scale values associate with a particular point of a /// particular curve.</summary> /// <remarks>The main purpose of this method is to handle /// stacked bars, in which case the stacked values are returned rather /// than the individual data values. /// </remarks> /// <param name="curve">A <see cref="CurveItem"/> object of interest.</param> /// <param name="iPt">The zero-based point index for the point of interest.</param> /// <param name="baseVal">A <see cref="Double"/> value representing the value /// for the independent axis.</param> /// <param name="lowVal">A <see cref="Double"/> value representing the lower /// value for the dependent axis.</param> /// <param name="hiVal">A <see cref="Double"/> value representing the upper /// value for the dependent axis.</param> /// <returns>true if the data point is value, false for /// <see cref="PointPairBase.Missing"/>, invalid, etc. data.</returns> public bool GetValues(CurveItem curve, int iPt, out double baseVal, out double lowVal, out double hiVal) { return(GetValues(_pane, curve, iPt, out baseVal, out lowVal, out hiVal)); }
/// <summary> /// Get the user scale values associate with a particular point of a /// particular curve.</summary> /// <remarks>The main purpose of this method is to handle /// stacked bars and lines, in which case the stacked values are returned rather /// than the individual data values. However, this method works generically for any /// curve type. /// </remarks> /// <param name="pane">The parent <see cref="GraphPane"/> object.</param> /// <param name="curve">A <see cref="CurveItem"/> object of interest.</param> /// <param name="iPt">The zero-based point index for the point of interest.</param> /// <param name="baseVal">A <see cref="Double"/> value representing the value /// for the independent axis.</param> /// <param name="lowVal">A <see cref="Double"/> value representing the lower /// value for the dependent axis.</param> /// <param name="hiVal">A <see cref="Double"/> value representing the upper /// value for the dependent axis.</param> /// <returns>true if the data point is value, false for /// <see cref="PointPairBase.Missing"/>, invalid, etc. data.</returns> public static bool GetValues(GraphPane pane, CurveItem curve, int iPt, out double baseVal, out double lowVal, out double hiVal) { hiVal = PointPair.Missing; lowVal = PointPair.Missing; baseVal = PointPair.Missing; if (curve == null || curve.Points.Count <= iPt || !curve.IsVisible) { return(false); } Axis baseAxis = curve.BaseAxis(pane); Axis valueAxis = curve.ValueAxis(pane); if (baseAxis is XAxis || baseAxis is X2Axis) { baseVal = curve.Points[iPt].X; } else { baseVal = curve.Points[iPt].Y; } // is it a stacked bar type? if (curve is BarItem && (pane._barSettings.Type == BarType.Stack || pane._barSettings.Type == BarType.PercentStack)) { double positiveStack = 0; double negativeStack = 0; double curVal; // loop through all the curves, summing up the values to get a total (only // for the current ordinal position iPt) foreach (CurveItem tmpCurve in pane.CurveList) { // Sum the value for the current curve only if it is a bar if (tmpCurve.IsBar && tmpCurve.IsVisible) { curVal = PointPair.Missing; // For non-ordinal curves, find a matching base value (must match exactly) if (curve.IsOverrideOrdinal || !baseAxis._scale.IsAnyOrdinal) { IPointList points = tmpCurve.Points; for (int i = 0; i < points.Count; i++) { if ((baseAxis is XAxis || baseAxis is X2Axis) && points[i].X == baseVal) { curVal = points[i].Y; break; } else if (!(baseAxis is XAxis || baseAxis is X2Axis) && points[i].Y == baseVal) { curVal = points[i].X; break; } } } // otherwise, it's an ordinal type so use the value at the same ordinal position else if (iPt < tmpCurve.Points.Count) { // Get the value for the appropriate value axis if (baseAxis is XAxis || baseAxis is X2Axis) { curVal = tmpCurve.Points[iPt].Y; } else { curVal = tmpCurve.Points[iPt].X; } } // If it's a missing value, skip it if (curVal == PointPair.Missing) { positiveStack = PointPair.Missing; negativeStack = PointPair.Missing; } // the current curve is the target curve, save the summed values for later if (tmpCurve == curve) { // if the value is positive, use the positive stack if (curVal >= 0) { lowVal = positiveStack; hiVal = (curVal == PointPair.Missing || positiveStack == PointPair.Missing) ? PointPair.Missing : positiveStack + curVal; } // otherwise, use the negative stack else { hiVal = negativeStack; lowVal = (curVal == PointPair.Missing || negativeStack == PointPair.Missing) ? PointPair.Missing : negativeStack + curVal; } } // Add all positive values to the positive stack, and negative values to the // negative stack if (curVal >= 0) { positiveStack = (curVal == PointPair.Missing || positiveStack == PointPair.Missing) ? PointPair.Missing : positiveStack + curVal; } else { negativeStack = (curVal == PointPair.Missing || negativeStack == PointPair.Missing) ? PointPair.Missing : negativeStack + curVal; } } } // if the curve is a PercentStack type, then calculate the percent for this bar // based on the total height of the stack if (pane._barSettings.Type == BarType.PercentStack && hiVal != PointPair.Missing && lowVal != PointPair.Missing) { // Use the total magnitude of the positive plus negative bar stacks to determine // the percentage value positiveStack += Math.Abs(negativeStack); // just to avoid dividing by zero... if (positiveStack != 0) { // calculate the percentage values lowVal = lowVal / positiveStack * 100.0; hiVal = hiVal / positiveStack * 100.0; } else { lowVal = 0; hiVal = 0; } } if (baseVal == PointPair.Missing || lowVal == PointPair.Missing || hiVal == PointPair.Missing) { return(false); } else { return(true); } } // If the curve is a stacked line type, then sum up the values similar to the stacked bar type else if (curve is LineItem && pane.LineType == LineType.Stack) { double stack = 0; double curVal; // loop through all the curves, summing up the values to get a total (only // for the current ordinal position iPt) foreach (CurveItem tmpCurve in pane.CurveList) { // make sure the curve is a Line type if (tmpCurve is LineItem && tmpCurve.IsVisible) { curVal = PointPair.Missing; // For non-ordinal curves, find a matching base value (must match exactly) if (curve.IsOverrideOrdinal || !baseAxis._scale.IsAnyOrdinal) { IPointList points = tmpCurve.Points; for (int i = 0; i < points.Count; i++) { if (points[i].X == baseVal) { curVal = points[i].Y; break; } } } // otherwise, it's an ordinal type so use the value at the same ordinal position else if (iPt < tmpCurve.Points.Count) { // For line types, the Y axis is always the value axis curVal = tmpCurve.Points[iPt].Y; } // if the current value is missing, then the rest of the stack is missing if (curVal == PointPair.Missing) { stack = PointPair.Missing; } // if the current curve is the target curve, save the values if (tmpCurve == curve) { lowVal = stack; // if ( curVal < 0 && stack == 0 ) // { // stack = curVal; // lowVal = curVal; // hiVal = curVal; // } // else hiVal = (curVal == PointPair.Missing || stack == PointPair.Missing) ? PointPair.Missing : stack + curVal; } // sum all the curves to a single total. This includes both positive and // negative values (unlike the bar stack type). stack = (curVal == PointPair.Missing || stack == PointPair.Missing) ? PointPair.Missing : stack + curVal; } } if (baseVal == PointPair.Missing || lowVal == PointPair.Missing || hiVal == PointPair.Missing) { return(false); } else { return(true); } } // otherwise, the curve is not a stacked type (not a stacked bar or stacked line) else { if ((!(curve is HiLowBarItem)) && (!(curve is ErrorBarItem))) { lowVal = 0; } else { lowVal = curve.Points[iPt].LowValue; } if (baseAxis is XAxis || baseAxis is X2Axis) { hiVal = curve.Points[iPt].Y; } else { hiVal = curve.Points[iPt].X; } } // Special Exception: Bars on log scales should always plot from the Min value upwards, // since they can never be zero if (curve is BarItem && valueAxis._scale.IsLog && lowVal == 0) { lowVal = valueAxis._scale._min; } if (baseVal == PointPair.Missing || hiVal == PointPair.Missing || (lowVal == PointPair.Missing && (curve is ErrorBarItem || curve is HiLowBarItem))) { return(false); } else { return(true); } }
private void UpdateGraph() { if (!IsHandleCreated) { return; } zedGraphControl.GraphPane.GraphObjList.Clear(); zedGraphControl.GraphPane.CurveList.Clear(); _barGraph = null; _rows = null; var points = new PointPairList(); var groupComparisonModel = FoldChangeBindingSource.GroupComparisonModel; var groupComparisonDef = groupComparisonModel.GroupComparisonDef; var document = groupComparisonModel.Document; var sequences = new List<Tuple<string, bool>>(); foreach (var nodePep in document.Molecules) sequences.Add(new Tuple<string, bool>(nodePep.RawTextId, nodePep.IsProteomic)); var uniquePrefixGenerator = new UniquePrefixGenerator(sequences, 3); var textLabels = new List<string>(); var rows = _bindingListSource.OfType<RowItem>() .Select(rowItem => rowItem.Value) .OfType<FoldChangeBindingSource.FoldChangeRow>() .ToArray(); bool showLabelType = rows.Select(row => row.IsotopeLabelType).Distinct().Count() > 1; bool showMsLevel = rows.Select(row => row.MsLevel).Distinct().Count() > 1; bool showGroup = rows.Select(row => row.Group).Distinct().Count() > 1; foreach (var row in rows) { var foldChangeResult = row.FoldChangeResult; double error = Math.Log(foldChangeResult.MaxFoldChange/foldChangeResult.FoldChange, 2.0); var point = MeanErrorBarItem.MakePointPair(points.Count, foldChangeResult.Log2FoldChange, error); points.Add(point); string label; if (null != row.Peptide) { label = uniquePrefixGenerator.GetUniquePrefix(row.Peptide.GetDocNode().RawTextId, row.Peptide.GetDocNode().IsProteomic); } else { label = row.Protein.Name; } if (showMsLevel && row.MsLevel.HasValue) { label += " MS" + row.MsLevel; // Not L10N; } if (showLabelType && row.IsotopeLabelType != null) { label += " (" + row.IsotopeLabelType.Title + ")"; // Not L10N } if (showGroup && !Equals(row.Group, default(GroupIdentifier))) { label += " " + row.Group; // Not L10N } textLabels.Add(label); if (IsSelected(row)) { double y, height; if (foldChangeResult.Log2FoldChange >= 0) { y = foldChangeResult.Log2FoldChange + error; height = y; } else { y = 0; height = error - foldChangeResult.Log2FoldChange; } zedGraphControl.GraphPane.GraphObjList.Add(new BoxObj(point.X + .5, y, .99, height) { ZOrder = ZOrder.E_BehindCurves, IsClippedToChartRect = true }); } } zedGraphControl.GraphPane.XAxis.Title.Text = groupComparisonDef.PerProtein ? GroupComparisonStrings.FoldChangeBarGraph_UpdateGraph_Protein : GroupComparisonStrings.FoldChangeBarGraph_UpdateGraph_Peptide; zedGraphControl.GraphPane.YAxis.Title.Text = GroupComparisonStrings.FoldChangeBarGraph_UpdateGraph_Log_2_Fold_Change; var barGraph = new MeanErrorBarItem(null, points, Color.Black, Color.Blue); zedGraphControl.GraphPane.CurveList.Add(barGraph); zedGraphControl.GraphPane.XAxis.Type = AxisType.Text; zedGraphControl.GraphPane.XAxis.Scale.TextLabels = textLabels.ToArray(); _axisLabelScaler.ScaleAxisLabels(); zedGraphControl.GraphPane.AxisChange(); zedGraphControl.Invalidate(); _barGraph = barGraph; _rows = rows; }
void chk_box_CheckedChanged(object sender, EventArgs e) { if (((CheckBox) sender).Checked) { ((CheckBox) sender).BackColor = Color.Green; if (list1item == null) { if (setupPropertyInfo(ref list1item, ((CheckBox) sender).Name, MainV2.comPort.MAV.cs)) { list1.Clear(); list1curve = zg1.GraphPane.AddCurve(((CheckBox) sender).Name, list1, Color.Red, SymbolType.None); } } else if (list2item == null) { if (setupPropertyInfo(ref list2item, ((CheckBox) sender).Name, MainV2.comPort.MAV.cs)) { list2.Clear(); list2curve = zg1.GraphPane.AddCurve(((CheckBox) sender).Name, list2, Color.Blue, SymbolType.None); } } else if (list3item == null) { if (setupPropertyInfo(ref list3item, ((CheckBox) sender).Name, MainV2.comPort.MAV.cs)) { list3.Clear(); list3curve = zg1.GraphPane.AddCurve(((CheckBox) sender).Name, list3, Color.Green, SymbolType.None); } } else if (list4item == null) { if (setupPropertyInfo(ref list4item, ((CheckBox) sender).Name, MainV2.comPort.MAV.cs)) { list4.Clear(); list4curve = zg1.GraphPane.AddCurve(((CheckBox) sender).Name, list4, Color.Orange, SymbolType.None); } } else if (list5item == null) { if (setupPropertyInfo(ref list5item, ((CheckBox) sender).Name, MainV2.comPort.MAV.cs)) { list5.Clear(); list5curve = zg1.GraphPane.AddCurve(((CheckBox) sender).Name, list5, Color.Yellow, SymbolType.None); } } else if (list6item == null) { if (setupPropertyInfo(ref list6item, ((CheckBox) sender).Name, MainV2.comPort.MAV.cs)) { list6.Clear(); list6curve = zg1.GraphPane.AddCurve(((CheckBox) sender).Name, list6, Color.Magenta, SymbolType.None); } } else if (list7item == null) { if (setupPropertyInfo(ref list7item, ((CheckBox) sender).Name, MainV2.comPort.MAV.cs)) { list7.Clear(); list7curve = zg1.GraphPane.AddCurve(((CheckBox) sender).Name, list7, Color.Purple, SymbolType.None); } } else if (list8item == null) { if (setupPropertyInfo(ref list8item, ((CheckBox) sender).Name, MainV2.comPort.MAV.cs)) { list8.Clear(); list8curve = zg1.GraphPane.AddCurve(((CheckBox) sender).Name, list8, Color.LimeGreen, SymbolType.None); } } else if (list9item == null) { if (setupPropertyInfo(ref list9item, ((CheckBox) sender).Name, MainV2.comPort.MAV.cs)) { list9.Clear(); list9curve = zg1.GraphPane.AddCurve(((CheckBox) sender).Name, list9, Color.Cyan, SymbolType.None); } } else if (list10item == null) { if (setupPropertyInfo(ref list10item, ((CheckBox) sender).Name, MainV2.comPort.MAV.cs)) { list10.Clear(); list10curve = zg1.GraphPane.AddCurve(((CheckBox) sender).Name, list10, Color.Violet, SymbolType.None); } } else { CustomMessageBox.Show("Max 10 at a time."); ((CheckBox) sender).Checked = false; } ThemeManager.ApplyThemeTo(this); string selected = ""; try { foreach (var curve in zg1.GraphPane.CurveList) { selected = selected + curve.Label.Text + "|"; } } catch { } MainV2.config["Tuning_Graph_Selected"] = selected; } else { ((CheckBox) sender).BackColor = Color.Transparent; // reset old stuff if (list1item != null && list1item.Name == ((CheckBox) sender).Name) { list1item = null; zg1.GraphPane.CurveList.Remove(list1curve); } if (list2item != null && list2item.Name == ((CheckBox) sender).Name) { list2item = null; zg1.GraphPane.CurveList.Remove(list2curve); } if (list3item != null && list3item.Name == ((CheckBox) sender).Name) { list3item = null; zg1.GraphPane.CurveList.Remove(list3curve); } if (list4item != null && list4item.Name == ((CheckBox) sender).Name) { list4item = null; zg1.GraphPane.CurveList.Remove(list4curve); } if (list5item != null && list5item.Name == ((CheckBox) sender).Name) { list5item = null; zg1.GraphPane.CurveList.Remove(list5curve); } if (list6item != null && list6item.Name == ((CheckBox) sender).Name) { list6item = null; zg1.GraphPane.CurveList.Remove(list6curve); } if (list7item != null && list7item.Name == ((CheckBox) sender).Name) { list7item = null; zg1.GraphPane.CurveList.Remove(list7curve); } if (list8item != null && list8item.Name == ((CheckBox) sender).Name) { list8item = null; zg1.GraphPane.CurveList.Remove(list8curve); } if (list9item != null && list9item.Name == ((CheckBox) sender).Name) { list9item = null; zg1.GraphPane.CurveList.Remove(list9curve); } if (list10item != null && list10item.Name == ((CheckBox) sender).Name) { list10item = null; zg1.GraphPane.CurveList.Remove(list10curve); } } }
/// <summary> /// Protected internal routine that draws the specified single bar (an individual "point") /// of this series to the specified <see cref="Graphics"/> device. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="CurveItem"/> object representing the /// <see cref="Bar"/>'s to be drawn.</param> /// <param name="index"> /// The zero-based index number for the single bar to be drawn. /// </param> /// <param name="pos"> /// The ordinal position of the this bar series (0=first bar, 1=second bar, etc.) /// in the cluster of bars. /// </param> /// <param name="baseAxis">The <see cref="Axis"/> class instance that defines the base (independent) /// axis for the <see cref="Bar"/></param> /// <param name="valueAxis">The <see cref="Axis"/> class instance that defines the value (dependent) /// axis for the <see cref="Bar"/></param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="GraphPane.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> protected virtual void DrawSingleBar( Graphics g, GraphPane pane, CurveItem curve, int index, int pos, Axis baseAxis, Axis valueAxis, double scaleFactor ) { // pixBase = pixel value for the bar center on the base axis // pixHiVal = pixel value for the bar top on the value axis // pixLowVal = pixel value for the bar bottom on the value axis float pixBase, pixHiVal, pixLowVal; float clusterWidth = pane.GetClusterWidth(); float barWidth = curve.GetBarWidth( pane ); float clusterGap = pane.MinClusterGap * barWidth; float barGap = barWidth * pane.MinBarGap; // curBase = the scale value on the base axis of the current bar // curHiVal = the scale value on the value axis of the current bar // curLowVal = the scale value of the bottom of the bar double curBase, curLowVal, curHiVal; BarValueHandler valueHandler = new BarValueHandler( pane ); valueHandler.GetBarValues( curve, index, out curBase, out curLowVal, out curHiVal ); // Any value set to double max is invalid and should be skipped // This is used for calculated values that are out of range, divide // by zero, etc. // Also, any value <= zero on a log scale is invalid if ( !curve.Points[index].IsInvalid ) { // calculate a pixel value for the top of the bar on value axis pixLowVal = valueAxis.Transform( index, curLowVal ); pixHiVal = valueAxis.Transform( index, curHiVal ); // calculate a pixel value for the center of the bar on the base axis pixBase = baseAxis.Transform( index, curBase ); // Calculate the pixel location for the side of the bar (on the base axis) float pixSide = pixBase - clusterWidth / 2.0F + clusterGap / 2.0F + pos * ( barWidth + barGap ); // Draw the bar if ( pane.BarBase == BarBase.X ) this.Draw( g, pane, pixSide, pixSide + barWidth, pixLowVal, pixHiVal, scaleFactor, true ); else this.Draw( g, pane, pixLowVal, pixHiVal, pixSide, pixSide + barWidth, scaleFactor, true ); } }
/// <summary> /// Protected internal routine that draws the specified single bar (an individual "point") /// of this series to the specified <see cref="Graphics"/> device. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="CurveItem"/> object representing the /// <see cref="Bar"/>'s to be drawn.</param> /// <param name="index"> /// The zero-based index number for the single bar to be drawn. /// </param> /// <param name="pos"> /// The ordinal position of the this bar series (0=first bar, 1=second bar, etc.) /// in the cluster of bars. /// </param> /// <param name="baseAxis">The <see cref="Axis"/> class instance that defines the base (independent) /// axis for the <see cref="Bar"/></param> /// <param name="valueAxis">The <see cref="Axis"/> class instance that defines the value (dependent) /// axis for the <see cref="Bar"/></param> /// <param name="barWidth"> /// The width of each bar, in pixels. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> virtual protected void DrawSingleBar(Graphics g, GraphPane pane, CurveItem curve, int index, int pos, Axis baseAxis, Axis valueAxis, float barWidth, float scaleFactor) { // Parts of this method were changed by BioRad 2007.4.10 Debug.Assert(curve is BarItem); BarItem barItem = (BarItem)curve; // pixBase = pixel value for the bar center on the base axis // pixHiVal = pixel value for the bar top on the value axis // pixLowVal = pixel value for the bar bottom on the value axis float pixBase, pixHiVal, pixLowVal; // Added by BioRad 2007.4.10 float pixErrorHiVal = 0, pixErrorLowVal = 0; // End BioRad addition float clusterWidth = pane.BarSettings.GetClusterWidth(); //float barWidth = curve.GetBarWidth( pane ); float clusterGap = pane._barSettings.MinClusterGap * barWidth; float barGap = barWidth * pane._barSettings.MinBarGap; // curBase = the scale value on the base axis of the current bar // curHiVal = the scale value on the value axis of the current bar // curLowVal = the scale value of the bottom of the bar double curBase, curLowVal, curHiVal; ValueHandler valueHandler = new ValueHandler(pane, false); valueHandler.GetValues(curve, index, out curBase, out curLowVal, out curHiVal); // Any value set to double max is invalid and should be skipped // This is used for calculated values that are out of range, divide // by zero, etc. // Also, any value <= zero on a log scale is invalid if (!curve.Points[index].IsInvalid) { // calculate a pixel value for the top of the bar on value axis pixLowVal = valueAxis.Scale.Transform(curve.IsOverrideOrdinal, index, curLowVal); pixHiVal = valueAxis.Scale.Transform(curve.IsOverrideOrdinal, index, curHiVal); // calculate a pixel value for the center of the bar on the base axis pixBase = baseAxis.Scale.Transform(curve.IsOverrideOrdinal, index, curBase); // Calculate pixel vales for the error bars if any. if (barItem.ShowErrorBars) { Debug.Assert(barItem.ErrorBarValues.Length == barItem.Points.Count); double errorRadius = barItem.ErrorBarValues[index]; double errorRadiusHigh; double errorRadiusLow; barItem.GetErrorRadii(valueAxis.Scale, curHiVal, errorRadius, out errorRadiusHigh, out errorRadiusLow); pixErrorHiVal = valueAxis.Scale.Transform(curve.IsOverrideOrdinal, index, curHiVal + errorRadiusHigh); pixErrorLowVal = valueAxis.Scale.Transform(curve.IsOverrideOrdinal, index, curHiVal - errorRadiusLow); } // Calculate the pixel location for the side of the bar (on the base axis) float pixSide = pixBase - clusterWidth / 2.0F + clusterGap / 2.0F + pos * (barWidth + barGap); float pixMiddle = pixSide + barWidth / 2; // Draw the bar if (pane._barSettings.Base == BarBase.X) { this.Draw(g, pane, pixSide, pixSide + barWidth, pixLowVal, pixHiVal, scaleFactor, true, curve.Points[index], index); if (barItem.ShowErrorBars) { float width = 1; if (pane.IsPenWidthScaled) { width = scaleFactor; } using (Pen errorBarPen = new Pen(Color.Black, width)) { g.DrawLine(errorBarPen, pixMiddle, pixErrorHiVal, pixMiddle, pixErrorLowVal); g.DrawLine(errorBarPen, pixMiddle - barWidth * .4f, pixErrorHiVal, pixMiddle + barWidth * .4f, pixErrorHiVal); g.DrawLine(errorBarPen, pixMiddle - barWidth * .4f, pixErrorLowVal, pixMiddle + barWidth * .4f, pixErrorLowVal); } } } else { this.Draw(g, pane, pixLowVal, pixHiVal, pixSide, pixSide + barWidth, scaleFactor, true, curve.Points[index], index); if (barItem.ShowErrorBars) { float width = 1; if (pane.IsPenWidthScaled) { width = scaleFactor; } using (Pen errorBarPen = new Pen(Color.Black, width)) { g.DrawLine(errorBarPen, pixErrorLowVal, pixMiddle, pixErrorHiVal, pixMiddle); g.DrawLine(errorBarPen, pixErrorHiVal, pixMiddle - barWidth * .4f, pixErrorHiVal, pixMiddle + barWidth * .4f); g.DrawLine(errorBarPen, pixErrorLowVal, pixMiddle - barWidth * .4f, pixErrorLowVal, pixMiddle + barWidth * .4f); } } } } }
/// <summary> /// Find the data point that lies closest to the specified mouse (screen) /// point. /// </summary> /// <remarks> /// This method will search through all curves in /// <see cref="GraphPane.CurveList"/> to find which point is /// nearest. It will only consider points that are within /// <see cref="Default.NearestTol"/> pixels of the screen point. /// </remarks> /// <param name="mousePt">The screen point, in pixel coordinates.</param> /// <param name="nearestCurve">A reference to the <see cref="CurveItem"/> /// instance that contains the closest point. nearestCurve will be null if /// no data points are available.</param> /// <param name="iNearest">The index number of the closest point. The /// actual data vpoint will then be <see cref="CurveItem.Points">CurveItem.Points[iNearest]</see> /// . iNearest will /// be -1 if no data points are available.</param> /// <returns>true if a point was found and that point lies within /// <see cref="Default.NearestTol"/> pixels /// of the screen point, false otherwise.</returns> public bool FindNearestPoint( PointF mousePt, out CurveItem nearestCurve, out int iNearest ) { return FindNearestPoint( mousePt, _curveList, out nearestCurve, out iNearest ); }
/// <summary> /// Calculate the range for stacked bars and lines. /// </summary> /// <remarks>This method is required for the stacked /// types because (for bars), the negative values are a separate stack than the positive /// values. If you just sum up the bars, you will get the sum of the positive plus negative, /// which is less than the maximum positive value and greater than the maximum negative value. /// </remarks> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">The <see cref="CurveItem"/> for which to calculate the range</param> /// <param name="tXMinVal">The minimum X value so far</param> /// <param name="tYMinVal">The minimum Y value so far</param> /// <param name="tXMaxVal">The maximum X value so far</param> /// <param name="tYMaxVal">The maximum Y value so far</param> /// <seealso cref="GraphPane.IsBoundedRanges"/> private void GetStackRange(GraphPane pane, CurveItem curve, out double tXMinVal, out double tYMinVal, out double tXMaxVal, out double tYMaxVal) { // initialize the values to outrageous ones to start tXMinVal = tYMinVal = Double.MaxValue; tXMaxVal = tYMaxVal = Double.MinValue; ValueHandler valueHandler = new ValueHandler(pane, false); Axis baseAxis = curve.BaseAxis(pane); bool isXBase = baseAxis is XAxis || baseAxis is X2Axis; double lowVal, baseVal, hiVal; for (int i = 0; i < curve.Points.Count; i++) { valueHandler.GetValues(curve, i, out baseVal, out lowVal, out hiVal); double x = isXBase ? baseVal : hiVal; double y = isXBase ? hiVal : baseVal; if (x != PointPair.Missing && y != PointPair.Missing && lowVal != PointPair.Missing) { if (x < tXMinVal) { tXMinVal = x; } if (x > tXMaxVal) { tXMaxVal = x; } if (y < tYMinVal) { tYMinVal = y; } if (y > tYMaxVal) { tYMaxVal = y; } if (!isXBase) { if (lowVal < tXMinVal) { tXMinVal = lowVal; } if (lowVal > tXMaxVal) { tXMaxVal = lowVal; } } else { if (lowVal < tYMinVal) { tYMinVal = lowVal; } if (lowVal > tYMaxVal) { tYMaxVal = lowVal; } } } } }
private string zedGraphControl_PointValueEvent(ZedGraphControl sender, GraphPane pane, CurveItem curve, int iPt) { return String.Format("{0} hz/{1} rpm", curve[iPt].X,curve[iPt].X * 60.0); }
/// <summary> /// Draw the specified single bar (an individual "point") of this series to the specified /// <see cref="Graphics"/> device. This method is not as efficient as /// <see cref="DrawBars"/>, which draws the bars for all points. It is intended to be used /// only for <see cref="BarType.SortedOverlay"/>, which requires special handling of each bar. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="CurveItem"/> object representing the /// <see cref="Bar"/>'s to be drawn.</param> /// <param name="baseAxis">The <see cref="Axis"/> class instance that defines the base (independent) /// axis for the <see cref="Bar"/></param> /// <param name="valueAxis">The <see cref="Axis"/> class instance that defines the value (dependent) /// axis for the <see cref="Bar"/></param> /// <param name="pos"> /// The ordinal position of the this bar series (0=first bar, 1=second bar, etc.) /// in the cluster of bars. /// </param> /// <param name="index"> /// The zero-based index number for the single bar to be drawn. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="GraphPane.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void DrawSingleBar( Graphics g, GraphPane pane, CurveItem curve, Axis baseAxis, Axis valueAxis, int pos, int index, double scaleFactor ) { if ( index >= curve.Points.Count ) return; //SetupBarStack( valueAxis, curve.Points.Count ); // For Overlay and Stack bars, the position is always zero since the bars are on top // of eachother if ( pane.BarType == BarType.Overlay || pane.BarType == BarType.Stack || pane.BarType == BarType.PercentStack ) pos = 0; DrawSingleBar( g, pane, curve, index, pos, baseAxis, valueAxis, scaleFactor ); }
/// <summary> /// Allows hovering over each point to display a tooltip e.g. Power(Comparison) - 1000 (+100) /// </summary> private string zedGraphControl1_PointValueEvent(ZedGraph.ZedGraphControl sender, ZedGraph.GraphPane pane, ZedGraph.CurveItem curve, int iPt) { int pointvalue = 0; int xpoint = (int)curve[iPt].X; //MessageBox.Show(xpoint.ToString()); if (xpoint < HeartRate.Length) { if (curve.Label.Text.Contains("Power")) { pointvalue = Power[xpoint]; } if (curve.Label.Text.Contains("Heart")) { pointvalue = HeartRate[xpoint]; } if (curve.Label.Text.Contains("Speed")) { pointvalue = Speed[xpoint]; } if (curve.Label.Text.Contains("Altitude")) { pointvalue = Altitude[xpoint]; } if (curve.Label.Text.Contains("Cadence")) { pointvalue = Cadeance[xpoint]; } } string value = pointvalue.ToString(); int timeinseconds = xpoint * interval; TimeSpan time = TimeSpan.FromSeconds(timeinseconds); //time.TotalSeconds(timeinseconds) return(curve.Label.Text + ": " + value + "\n" + "Time: " + time); }
/// <summary> /// Find the data point that lies closest to the specified mouse (screen) /// point for the specified curve. /// </summary> /// <remarks> /// This method will search only through the points for the specified /// curve to determine which point is /// nearest the mouse point. It will only consider points that are within /// <see cref="Default.NearestTol"/> pixels of the screen point. /// </remarks> /// <param name="mousePt">The screen point, in pixel coordinates.</param> /// <param name="nearestCurve">A reference to the <see cref="CurveItem"/> /// instance that contains the closest point. nearestCurve will be null if /// no data points are available.</param> /// <param name="targetCurve">A <see cref="CurveItem"/> object containing /// the data points to be searched.</param> /// <param name="iNearest">The index number of the closest point. The /// actual data vpoint will then be <see cref="CurveItem.Points">CurveItem.Points[iNearest]</see> /// . iNearest will /// be -1 if no data points are available.</param> /// <returns>true if a point was found and that point lies within /// <see cref="Default.NearestTol"/> pixels /// of the screen point, false otherwise.</returns> public bool FindNearestPoint( PointF mousePt, CurveItem targetCurve, out CurveItem nearestCurve, out int iNearest ) { CurveList targetCurveList = new CurveList(); targetCurveList.Add( targetCurve ); return FindNearestPoint( mousePt, targetCurveList, out nearestCurve, out iNearest ); }
/// <summary> /// Calculate the user scale position of the center of the specified bar, using the /// <see cref="Axis"/> as specified by <see cref="BarSettings.Base"/>. This method is /// used primarily by the /// <see cref="GraphPane.FindNearestPoint(PointF,out CurveItem,out int)"/> method in order to /// determine the bar "location," which is defined as the center of the top of the individual bar. /// </summary> /// <param name="curve">The <see cref="CurveItem"/> representing the /// bar of interest.</param> /// <param name="barWidth">The width of each individual bar. This can be calculated using /// the <see cref="CurveItem.GetBarWidth"/> method.</param> /// <param name="iCluster">The cluster number for the bar of interest. This is the ordinal /// position of the current point. That is, if a particular <see cref="CurveItem"/> has /// 10 points, then a value of 3 would indicate the 4th point in the data array.</param> /// <param name="val">The actual independent axis value for the bar of interest.</param> /// <param name="iOrdinal">The ordinal position of the <see cref="CurveItem"/> of interest. /// That is, the first bar series is 0, the second is 1, etc. Note that this applies only /// to the bars. If a graph includes both bars and lines, then count only the bars.</param> /// <returns>A user scale value position of the center of the bar of interest.</returns> public double BarCenterValue( CurveItem curve, float barWidth, int iCluster, double val, int iOrdinal ) { Axis baseAxis = curve.BaseAxis( _pane ); if ( curve is ErrorBarItem || curve is HiLowBarItem || curve is OHLCBarItem || curve is JapaneseCandleStickItem ) { if ( baseAxis._scale.IsAnyOrdinal && iCluster >= 0 && !curve.IsOverrideOrdinal ) return (double) iCluster + 1.0; else return val; } else { float clusterWidth = _pane._barSettings.GetClusterWidth(); float clusterGap = _pane._barSettings.MinClusterGap * barWidth; float barGap = barWidth * _pane._barSettings.MinBarGap; if ( curve.IsBar && _pane._barSettings.Type != BarType.Cluster ) iOrdinal = 0; float centerPix = baseAxis.Scale.Transform( curve.IsOverrideOrdinal, iCluster, val ) - clusterWidth / 2.0F + clusterGap / 2.0F + iOrdinal * ( barWidth + barGap ) + 0.5F * barWidth; return baseAxis.Scale.ReverseTransform( centerPix ); } }
/// <summary> /// Find the data point that lies closest to the specified mouse (screen) /// point. /// </summary> /// <remarks> /// This method will search through the specified list of curves to find which point is /// nearest. It will only consider points that are within /// <see cref="Default.NearestTol"/> pixels of the screen point, and it will /// only consider <see cref="CurveItem"/>'s that are in /// <paramref name="targetCurveList"/>. /// </remarks> /// <param name="mousePt">The screen point, in pixel coordinates.</param> /// <param name="targetCurveList">A <see cref="CurveList"/> object containing /// a subset of <see cref="CurveItem"/>'s to be searched.</param> /// <param name="nearestCurve">A reference to the <see cref="CurveItem"/> /// instance that contains the closest point. nearestCurve will be null if /// no data points are available.</param> /// <param name="iNearest">The index number of the closest point. The /// actual data vpoint will then be <see cref="CurveItem.Points">CurveItem.Points[iNearest]</see> /// . iNearest will /// be -1 if no data points are available.</param> /// <returns>true if a point was found and that point lies within /// <see cref="Default.NearestTol"/> pixels /// of the screen point, false otherwise.</returns> public bool FindNearestPoint( PointF mousePt, CurveList targetCurveList, out CurveItem nearestCurve, out int iNearest ) { CurveItem nearestBar = null; int iNearestBar = -1; nearestCurve = null; iNearest = -1; // If the point is outside the ChartRect, always return false if ( !_chart._rect.Contains( mousePt ) ) return false; double x, x2; double[] y; double[] y2; //ReverseTransform( mousePt, out x, out y, out y2 ); ReverseTransform( mousePt, out x, out x2, out y, out y2 ); if ( !AxisRangesValid() ) return false; ValueHandler valueHandler = new ValueHandler( this, false ); double xPixPerUnit = _chart._rect.Width / ( _xAxis._scale._max - _xAxis._scale._min ); //double yPixPerUnit = chartRect.Height / ( yAxis.Max - yAxis.Min ); //double y2PixPerUnit; // = chartRect.Height / ( y2Axis.Max - y2Axis.Min ); double yPixPerUnitAct, yAct, yMinAct, yMaxAct; double minDist = 1e20; double xVal, yVal, dist = 99999, distX, distY; double tolSquared = Default.NearestTol * Default.NearestTol; int iBar = 0; foreach ( CurveItem curve in targetCurveList ) { //test for pie first...if it's a pie rest of method superfluous if ( curve is PieItem && curve.IsVisible ) { if ( ( (PieItem)curve ).SlicePath != null && ( (PieItem)curve ).SlicePath.IsVisible( mousePt ) ) { nearestBar = curve; iNearestBar = 0; } continue; } else if ( curve.IsVisible ) { int yIndex = curve.GetYAxisIndex( this ); Axis yAxis = curve.GetYAxis( this ); if ( curve.IsY2Axis ) { yAct = y2[yIndex]; yMinAct = _y2AxisList[yIndex]._scale._min; yMaxAct = _y2AxisList[yIndex]._scale._max; } else { yAct = y[yIndex]; yMinAct = _yAxisList[yIndex]._scale._min; yMaxAct = _yAxisList[yIndex]._scale._max; } yPixPerUnitAct = _chart._rect.Height / ( yMaxAct - yMinAct ); IPointList points = curve.Points; float barWidth = curve.GetBarWidth( this ); double barWidthUserHalf; Axis baseAxis = curve.BaseAxis( this ); bool isXBaseAxis = ( baseAxis is XAxis || baseAxis is X2Axis ); if ( isXBaseAxis ) barWidthUserHalf = barWidth / xPixPerUnit / 2.0; else barWidthUserHalf = barWidth / yPixPerUnitAct / 2.0; if ( points != null ) { for ( int iPt = 0; iPt < curve.NPts; iPt++ ) { // xVal is the user scale X value of the current point if ( _xAxis._scale.IsAnyOrdinal && !curve.IsOverrideOrdinal ) xVal = (double)iPt + 1.0; else xVal = points[iPt].X; // yVal is the user scale Y value of the current point if ( yAxis._scale.IsAnyOrdinal && !curve.IsOverrideOrdinal ) yVal = (double)iPt + 1.0; else yVal = points[iPt].Y; if ( xVal != PointPair.Missing && yVal != PointPair.Missing ) { if ( curve.IsBar || curve is ErrorBarItem || curve is HiLowBarItem || curve is OHLCBarItem || curve is JapaneseCandleStickItem ) { double baseVal, lowVal, hiVal; valueHandler.GetValues( curve, iPt, out baseVal, out lowVal, out hiVal ); if ( lowVal > hiVal ) { double tmpVal = lowVal; lowVal = hiVal; hiVal = tmpVal; } if ( isXBaseAxis ) { double centerVal = valueHandler.BarCenterValue( curve, barWidth, iPt, xVal, iBar ); if ( x < centerVal - barWidthUserHalf || x > centerVal + barWidthUserHalf || yAct < lowVal || yAct > hiVal ) continue; } else { double centerVal = valueHandler.BarCenterValue( curve, barWidth, iPt, yVal, iBar ); if ( yAct < centerVal - barWidthUserHalf || yAct > centerVal + barWidthUserHalf || x < lowVal || x > hiVal ) continue; } if ( nearestBar == null ) { iNearestBar = iPt; nearestBar = curve; } } else if ( xVal >= _xAxis._scale._min && xVal <= _xAxis._scale._max && yVal >= yMinAct && yVal <= yMaxAct ) { if ( curve is LineItem && _lineType == LineType.Stack ) { double zVal; valueHandler.GetValues( curve, iPt, out xVal, out zVal, out yVal ); } distX = ( xVal - x ) * xPixPerUnit; distY = ( yVal - yAct ) * yPixPerUnitAct; dist = distX * distX + distY * distY; if ( dist >= minDist ) continue; minDist = dist; iNearest = iPt; nearestCurve = curve; } } } if ( curve.IsBar ) iBar++; } } } if ( nearestCurve is LineItem ) { float halfSymbol = (float)( ( (LineItem)nearestCurve ).Symbol.Size * CalcScaleFactor() / 2 ); minDist -= halfSymbol * halfSymbol; if ( minDist < 0 ) minDist = 0; } if ( minDist >= tolSquared && nearestBar != null ) { // if no point met the tolerance, but a bar was found, use it nearestCurve = nearestBar; iNearest = iNearestBar; return true; } else if ( minDist < tolSquared ) { // Did we find a close point, and is it within the tolerance? // (minDist is the square of the distance in pixel units) return true; } else // otherwise, no valid point found return false; }
/// <summary> /// Get the user scale values associate with a particular point of a /// particular curve.</summary> /// <remarks>The main purpose of this method is to handle /// stacked bars and lines, in which case the stacked values are returned rather /// than the individual data values. However, this method works generically for any /// curve type. /// </remarks> /// <param name="pane">The parent <see cref="GraphPane"/> object.</param> /// <param name="curve">A <see cref="CurveItem"/> object of interest.</param> /// <param name="iPt">The zero-based point index for the point of interest.</param> /// <param name="baseVal">A <see cref="Double"/> value representing the value /// for the independent axis.</param> /// <param name="lowVal">A <see cref="Double"/> value representing the lower /// value for the dependent axis.</param> /// <param name="hiVal">A <see cref="Double"/> value representing the upper /// value for the dependent axis.</param> /// <returns>true if the data point is value, false for /// <see cref="PointPairBase.Missing"/>, invalid, etc. data.</returns> public static bool GetValues( GraphPane pane, CurveItem curve, int iPt, out double baseVal, out double lowVal, out double hiVal ) { hiVal = PointPair.Missing; lowVal = PointPair.Missing; baseVal = PointPair.Missing; if ( curve == null || curve.Points.Count <= iPt || !curve.IsVisible ) return false; Axis baseAxis = curve.BaseAxis( pane ); Axis valueAxis = curve.ValueAxis( pane ); if ( baseAxis is XAxis || baseAxis is X2Axis ) baseVal = curve.Points[iPt].X; else baseVal = curve.Points[iPt].Y; // is it a stacked bar type? if ( curve is BarItem && ( pane._barSettings.Type == BarType.Stack || pane._barSettings.Type == BarType.PercentStack ) ) { double positiveStack = 0; double negativeStack = 0; double curVal; // loop through all the curves, summing up the values to get a total (only // for the current ordinal position iPt) foreach ( CurveItem tmpCurve in pane.CurveList ) { // Sum the value for the current curve only if it is a bar if ( tmpCurve.IsBar && tmpCurve.IsVisible ) { curVal = PointPair.Missing; // For non-ordinal curves, find a matching base value (must match exactly) if ( curve.IsOverrideOrdinal || !baseAxis._scale.IsAnyOrdinal ) { IPointList points = tmpCurve.Points; for ( int i=0; i<points.Count; i++ ) { if ( ( baseAxis is XAxis || baseAxis is X2Axis ) && points[i].X == baseVal ) { curVal = points[i].Y; break; } else if ( !(baseAxis is XAxis || baseAxis is X2Axis) && points[i].Y == baseVal ) { curVal = points[i].X; break; } } } // otherwise, it's an ordinal type so use the value at the same ordinal position else if ( iPt < tmpCurve.Points.Count ) { // Get the value for the appropriate value axis if ( baseAxis is XAxis || baseAxis is X2Axis ) curVal = tmpCurve.Points[iPt].Y; else curVal = tmpCurve.Points[iPt].X; } // If it's a missing value, skip it if ( curVal == PointPair.Missing ) { positiveStack = PointPair.Missing; negativeStack = PointPair.Missing; } // the current curve is the target curve, save the summed values for later if ( tmpCurve == curve ) { // if the value is positive, use the positive stack if ( curVal >= 0 ) { lowVal = positiveStack; hiVal = ( curVal == PointPair.Missing || positiveStack == PointPair.Missing ) ? PointPair.Missing : positiveStack + curVal; } // otherwise, use the negative stack else { hiVal = negativeStack; lowVal = ( curVal == PointPair.Missing || negativeStack == PointPair.Missing ) ? PointPair.Missing : negativeStack + curVal; } } // Add all positive values to the positive stack, and negative values to the // negative stack if ( curVal >= 0 ) positiveStack = ( curVal == PointPair.Missing || positiveStack == PointPair.Missing ) ? PointPair.Missing : positiveStack + curVal; else negativeStack = ( curVal == PointPair.Missing || negativeStack == PointPair.Missing ) ? PointPair.Missing : negativeStack + curVal; } } // if the curve is a PercentStack type, then calculate the percent for this bar // based on the total height of the stack if ( pane._barSettings.Type == BarType.PercentStack && hiVal != PointPair.Missing && lowVal != PointPair.Missing ) { // Use the total magnitude of the positive plus negative bar stacks to determine // the percentage value positiveStack += Math.Abs( negativeStack ); // just to avoid dividing by zero... if ( positiveStack != 0 ) { // calculate the percentage values lowVal = lowVal / positiveStack * 100.0; hiVal = hiVal / positiveStack * 100.0; } else { lowVal = 0; hiVal = 0; } } if ( baseVal == PointPair.Missing || lowVal == PointPair.Missing || hiVal == PointPair.Missing ) return false; else return true; } // If the curve is a stacked line type, then sum up the values similar to the stacked bar type else if ( curve is LineItem && pane.LineType == LineType.Stack ) { double stack = 0; double curVal; // loop through all the curves, summing up the values to get a total (only // for the current ordinal position iPt) foreach ( CurveItem tmpCurve in pane.CurveList ) { // make sure the curve is a Line type if ( tmpCurve is LineItem && tmpCurve.IsVisible ) { curVal = PointPair.Missing; // For non-ordinal curves, find a matching base value (must match exactly) if ( curve.IsOverrideOrdinal || !baseAxis._scale.IsAnyOrdinal ) { IPointList points = tmpCurve.Points; for ( int i = 0; i < points.Count; i++ ) { if ( points[i].X == baseVal ) { curVal = points[i].Y; break; } } } // otherwise, it's an ordinal type so use the value at the same ordinal position else if ( iPt < tmpCurve.Points.Count ) { // For line types, the Y axis is always the value axis curVal = tmpCurve.Points[iPt].Y; } // if the current value is missing, then the rest of the stack is missing if ( curVal == PointPair.Missing ) stack = PointPair.Missing; // if the current curve is the target curve, save the values if ( tmpCurve == curve ) { lowVal = stack; // if ( curVal < 0 && stack == 0 ) // { // stack = curVal; // lowVal = curVal; // hiVal = curVal; // } // else hiVal = ( curVal == PointPair.Missing || stack == PointPair.Missing ) ? PointPair.Missing : stack + curVal; } // sum all the curves to a single total. This includes both positive and // negative values (unlike the bar stack type). stack = ( curVal == PointPair.Missing || stack == PointPair.Missing ) ? PointPair.Missing : stack + curVal; } } if ( baseVal == PointPair.Missing || lowVal == PointPair.Missing || hiVal == PointPair.Missing ) return false; else return true; } // otherwise, the curve is not a stacked type (not a stacked bar or stacked line) else { if ( ! (curve is HiLowBarItem) ) lowVal = 0; else lowVal = curve.Points[iPt].LowValue; if ( baseAxis is XAxis || baseAxis is X2Axis ) hiVal = curve.Points[iPt].Y; else hiVal = curve.Points[iPt].X; } // Special Exception: Bars on log scales should always plot from the Min value upwards, // since they can never be zero if ( curve is BarItem && valueAxis._scale.IsLog && lowVal == 0 ) lowVal = valueAxis._scale._min; if ( baseVal == PointPair.Missing || hiVal == PointPair.Missing || ( lowVal == PointPair.Missing && ( curve is ErrorBarItem || curve is HiLowBarItem ) ) ) return false; else return true; }
void chk_box_CheckedChanged(object sender, EventArgs e) { if (((CheckBox)sender).Checked) { if (list1item == null) { if (setupPropertyInfo(ref list1item, ((CheckBox)sender).Name, MainV2.cs)) list1curve = zg1.GraphPane.AddCurve(((CheckBox)sender).Name, list1, Color.Red, SymbolType.None); } else if (list2item == null) { if (setupPropertyInfo(ref list2item, ((CheckBox)sender).Name, MainV2.cs)) list2curve = zg1.GraphPane.AddCurve(((CheckBox)sender).Name, list2, Color.Blue, SymbolType.None); } else if (list3item == null) { if (setupPropertyInfo(ref list3item, ((CheckBox)sender).Name, MainV2.cs)) list3curve = zg1.GraphPane.AddCurve(((CheckBox)sender).Name, list3, Color.Green, SymbolType.None); } else if (list4item == null) { if (setupPropertyInfo(ref list4item, ((CheckBox)sender).Name, MainV2.cs)) list4curve = zg1.GraphPane.AddCurve(((CheckBox)sender).Name, list4, Color.Orange, SymbolType.None); } else if (list5item == null) { if (setupPropertyInfo(ref list5item, ((CheckBox)sender).Name, MainV2.cs)) list5curve = zg1.GraphPane.AddCurve(((CheckBox)sender).Name, list5, Color.Yellow, SymbolType.None); } else if (list6item == null) { if (setupPropertyInfo(ref list6item, ((CheckBox)sender).Name, MainV2.cs)) list6curve = zg1.GraphPane.AddCurve(((CheckBox)sender).Name, list6, Color.Magenta, SymbolType.None); } else if (list7item == null) { if (setupPropertyInfo(ref list7item, ((CheckBox)sender).Name, MainV2.cs)) list7curve = zg1.GraphPane.AddCurve(((CheckBox)sender).Name, list7, Color.Purple, SymbolType.None); } else if (list8item == null) { if (setupPropertyInfo(ref list8item, ((CheckBox)sender).Name, MainV2.cs)) list8curve = zg1.GraphPane.AddCurve(((CheckBox)sender).Name, list8, Color.LimeGreen, SymbolType.None); } else if (list9item == null) { if (setupPropertyInfo(ref list9item, ((CheckBox)sender).Name, MainV2.cs)) list9curve = zg1.GraphPane.AddCurve(((CheckBox)sender).Name, list9, Color.Cyan, SymbolType.None); } else if (list10item == null) { if (setupPropertyInfo(ref list10item, ((CheckBox)sender).Name, MainV2.cs)) list10curve = zg1.GraphPane.AddCurve(((CheckBox)sender).Name, list10, Color.Violet, SymbolType.None); } else { CustomMessageBox.Show("Max 10 at a time."); ((CheckBox)sender).Checked = false; } ThemeManager.ApplyThemeTo(this); string selected = ""; try { selected = selected + zg1.GraphPane.CurveList[0].Label.Text + "|"; selected = selected + zg1.GraphPane.CurveList[1].Label.Text + "|"; selected = selected + zg1.GraphPane.CurveList[2].Label.Text + "|"; selected = selected + zg1.GraphPane.CurveList[3].Label.Text + "|"; selected = selected + zg1.GraphPane.CurveList[4].Label.Text + "|"; selected = selected + zg1.GraphPane.CurveList[5].Label.Text + "|"; selected = selected + zg1.GraphPane.CurveList[6].Label.Text + "|"; selected = selected + zg1.GraphPane.CurveList[7].Label.Text + "|"; selected = selected + zg1.GraphPane.CurveList[8].Label.Text + "|"; selected = selected + zg1.GraphPane.CurveList[9].Label.Text + "|"; selected = selected + zg1.GraphPane.CurveList[10].Label.Text + "|"; } catch { } MainV2.config["Tuning_Graph_Selected"] = selected; } else { // reset old stuff if (list1item != null && list1item.Name == ((CheckBox)sender).Name) { list1item = null; zg1.GraphPane.CurveList.Remove(list1curve); } if (list2item != null && list2item.Name == ((CheckBox)sender).Name) { list2item = null; zg1.GraphPane.CurveList.Remove(list2curve); } if (list3item != null && list3item.Name == ((CheckBox)sender).Name) { list3item = null; zg1.GraphPane.CurveList.Remove(list3curve); } if (list4item != null && list4item.Name == ((CheckBox)sender).Name) { list4item = null; zg1.GraphPane.CurveList.Remove(list4curve); } if (list5item != null && list5item.Name == ((CheckBox)sender).Name) { list5item = null; zg1.GraphPane.CurveList.Remove(list5curve); } if (list6item != null && list6item.Name == ((CheckBox)sender).Name) { list6item = null; zg1.GraphPane.CurveList.Remove(list6curve); } if (list7item != null && list7item.Name == ((CheckBox)sender).Name) { list7item = null; zg1.GraphPane.CurveList.Remove(list7curve); } if (list8item != null && list8item.Name == ((CheckBox)sender).Name) { list8item = null; zg1.GraphPane.CurveList.Remove(list8curve); } if (list9item != null && list9item.Name == ((CheckBox)sender).Name) { list9item = null; zg1.GraphPane.CurveList.Remove(list9curve); } if (list10item != null && list10item.Name == ((CheckBox)sender).Name) { list10item = null; zg1.GraphPane.CurveList.Remove(list10curve); } } }
/// <summary> /// Add a <see cref="CurveItem"/> object to the collection at the end of the list. /// </summary> /// <param name="curve">A reference to the <see cref="CurveItem"/> object to /// be added</param> /// <seealso cref="IList.Add"/> public void Add(CurveItem curve) { List.Add(curve); }
/// <summary> /// Calculate the screen pixel position of the center of the specified bar, using the /// <see cref="Axis"/> as specified by <see cref="GraphPane.BarBase"/>. This method is /// used primarily by the /// <see cref="GraphPane.FindNearestPoint(PointF,out CurveItem,out int)"/> method in order to /// determine the bar "location," which is defined as the center of the top of the individual bar. /// </summary> /// <param name="curve">The <see cref="CurveItem"/> representing the /// bar of interest.</param> /// <param name="barWidth">The width of each individual bar. This can be calculated using /// the <see cref="CurveItem.GetBarWidth"/> method.</param> /// <param name="iCluster">The cluster number for the bar of interest. This is the ordinal /// position of the current point. That is, if a particular <see cref="CurveItem"/> has /// 10 points, then a value of 3 would indicate the 4th point in the data array.</param> /// <param name="val">The actual independent axis value for the bar of interest.</param> /// <param name="iOrdinal">The ordinal position of the <see cref="CurveItem"/> of interest. /// That is, the first bar series is 0, the second is 1, etc. Note that this applies only /// to the bars. If a graph includes both bars and lines, then count only the bars.</param> /// <returns>A screen pixel X position of the center of the bar of interest.</returns> public double BarCenterValue( CurveItem curve, float barWidth, int iCluster, double val, int iOrdinal ) { float clusterWidth = pane.GetClusterWidth(); float clusterGap = pane.MinClusterGap * barWidth; float barGap = barWidth * pane.MinBarGap; if ( ( curve.IsBar && !( pane.BarType == BarType.Cluster ) ) || curve is ErrorBarItem || curve is HiLowBarItem ) iOrdinal = 0; Axis baseAxis = curve.BaseAxis( pane ); float centerPix = baseAxis.Transform( iCluster, val ) - clusterWidth / 2.0F + clusterGap / 2.0F + iOrdinal * ( barWidth + barGap ) + 0.5F * barWidth; return baseAxis.ReverseTransform( centerPix ); }
/// <summary> /// Protected internal routine that draws the specified single bar (an individual "point") /// of this series to the specified <see cref="Graphics"/> device. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="CurveItem"/> object representing the /// <see cref="Bar"/>'s to be drawn.</param> /// <param name="index"> /// The zero-based index number for the single bar to be drawn. /// </param> /// <param name="pos"> /// The ordinal position of the this bar series (0=first bar, 1=second bar, etc.) /// in the cluster of bars. /// </param> /// <param name="baseAxis">The <see cref="Axis"/> class instance that defines the base (independent) /// axis for the <see cref="Bar"/></param> /// <param name="valueAxis">The <see cref="Axis"/> class instance that defines the value (dependent) /// axis for the <see cref="Bar"/></param> /// <param name="barWidth"> /// The width of each bar, in pixels. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> override protected void DrawSingleBar(Graphics g, GraphPane pane, CurveItem curve, int index, int pos, Axis baseAxis, Axis valueAxis, float barWidth, float scaleFactor) { //float scaledSize = GetBarWidth( pane, baseAxis, scaleFactor ); // pixBase = pixel value for the bar center on the base axis // pixValue = pixel value for the bar top on the value axis // pixLow = pixel value for the bar bottom on the value axis float pixBase, pixHiVal, pixLowVal; // curBase = the scale value on the base axis of the current bar // curValue = the scale value on the value axis of the current bar double curBase, curLowVal, curHiVal; ValueHandler valueHandler = new ValueHandler(pane, false); valueHandler.GetValues(curve, index, out curBase, out curLowVal, out curHiVal); barWidth = GetBarWidth(pane, baseAxis, scaleFactor); // curLow = the scale value on the value axis for the bottom of the current bar // Get a "low" value for the bottom of the bar and verify validity if (curLowVal == PointPair.Missing || System.Double.IsNaN(curLowVal) || System.Double.IsInfinity(curLowVal)) { curLowVal = 0; } // Any value set to double max is invalid and should be skipped // This is used for calculated values that are out of range, divide // by zero, etc. // Also, any value <= zero on a log scale is invalid if (!curve.Points[index].IsInvalid) { // calculate a pixel value for the top of the bar on value axis pixHiVal = valueAxis.Scale.Transform(curve.IsOverrideOrdinal, index, curHiVal); // calculate a pixel value for the center of the bar on the base axis pixBase = baseAxis.Scale.Transform(curve.IsOverrideOrdinal, index, curBase); pixLowVal = valueAxis.Scale.Transform(curve.IsOverrideOrdinal, index, curLowVal); // Calculate the pixel location for the side of the bar (on the base axis) float pixSide = pixBase - barWidth / 2.0F; // Draw the bar if (baseAxis is XAxis) { this.Draw(g, pane, pixSide, pixSide + barWidth, pixLowVal, pixHiVal, scaleFactor, true, curve.Points[index], index); } else { this.Draw(g, pane, pixLowVal, pixHiVal, pixSide, pixSide + barWidth, scaleFactor, true, curve.Points[index], index); } } }
/// <summary> /// Get the user scale values associate with a particular point of a /// particular curve.</summary> /// <remarks>The main purpose of this method is to handle /// stacked bars, in which case the stacked values are returned rather /// than the individual data values. /// </remarks> /// <param name="pane">The parent <see cref="GraphPane"/> object.</param> /// <param name="curve">A <see cref="CurveItem"/> object of interest.</param> /// <param name="iPt">The zero-based point index for the point of interest.</param> /// <param name="baseVal">A <see cref="Double"/> value representing the value /// for the independent axis.</param> /// <param name="lowVal">A <see cref="Double"/> value representing the lower /// value for the dependent axis.</param> /// <param name="hiVal">A <see cref="Double"/> value representing the upper /// value for the dependent axis.</param> /// <returns>true if the data point is value, false for /// <see cref="PointPair.Missing"/>, invalid, etc. data.</returns> public static bool GetBarValues( GraphPane pane, CurveItem curve, int iPt, out double baseVal, out double lowVal, out double hiVal ) { hiVal = PointPair.Missing; lowVal = PointPair.Missing; baseVal = PointPair.Missing; if ( curve == null || curve.Points.Count <= iPt ) return false; Axis baseAxis = curve.BaseAxis( pane ); if ( baseAxis is XAxis ) baseVal = curve.Points[iPt].X; else baseVal = curve.Points[iPt].Y; if ( curve is BarItem && ( pane.BarType == BarType.Stack || pane.BarType == BarType.PercentStack ) ) { double positiveStack = 0; double negativeStack = 0; double curVal; foreach ( CurveItem tmpCurve in pane.CurveList ) //for ( int iCurve=pane.CurveList.Count-1; iCurve >=0; iCurve-- ) { //CurveItem tmpCurve = pane.CurveList[iCurve]; if ( tmpCurve.IsBar && iPt < tmpCurve.Points.Count ) { if ( baseAxis is XAxis ) curVal = tmpCurve.Points[iPt].Y; else curVal = tmpCurve.Points[iPt].X; if ( curVal == PointPair.Missing ) continue; if ( tmpCurve == curve ) { if ( curVal >= 0 ) { lowVal = positiveStack; hiVal = positiveStack + curVal; } else { hiVal = negativeStack; lowVal = negativeStack + curVal; } } if ( curVal >= 0 ) positiveStack += curVal; else negativeStack += curVal; } } if ( pane.BarType == BarType.PercentStack ) { positiveStack += Math.Abs( negativeStack ); if ( positiveStack != 0 ) { lowVal = lowVal / positiveStack * 100.0; hiVal = hiVal / positiveStack * 100.0; } else { lowVal = 0; hiVal = 0; } } if ( baseVal == PointPair.Missing || lowVal == PointPair.Missing || hiVal == PointPair.Missing ) return false; else return true; } else { if ( curve is BarItem ) lowVal = 0; else lowVal = curve.Points[iPt].LowValue; if ( baseAxis is XAxis ) hiVal = curve.Points[iPt].Y; else hiVal = curve.Points[iPt].X; } if ( baseVal == PointPair.Missing || hiVal == PointPair.Missing || ( lowVal == PointPair.Missing && ( curve is ErrorBarItem || curve is HiLowBarItem ) ) ) return false; else return true; }
/// <summary> /// Render the <see cref="Legend"/> to the specified <see cref="Graphics"/> device. /// </summary> /// <remarks> /// This method is normally only called by the Draw method /// of the parent <see cref="GraphPane"/> object. /// </remarks> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="PaneBase"/> object that is the parent or /// owner of this object. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void Draw(Graphics g, PaneBase pane, float scaleFactor) { // if the legend is not visible, do nothing if (!_isVisible) { return; } // Fill the background with the specified color if required _fill.Draw(g, _rect); PaneList paneList = GetPaneList(pane); float halfGap = _tmpSize / 2.0F; // Check for bad data values if (_hStack <= 0) { _hStack = 1; } if (_legendItemWidth <= 0) { _legendItemWidth = 100; } if (_legendItemHeight <= 0) { _legendItemHeight = _tmpSize; } //float gap = pane.ScaledGap( scaleFactor ); int iEntry = 0; float x, y; // Get a brush for the legend label text using (SolidBrush brushB = new SolidBrush(Color.Black)) { foreach (GraphPane tmpPane in paneList) { // Loop for each curve in the CurveList collection //foreach ( CurveItem curve in tmpPane.CurveList ) int count = tmpPane.CurveList.Count; for (int i = 0; i < count; i++) { CurveItem curve = tmpPane.CurveList[_isReverse ? count - i - 1 : i]; if (curve._label._text != "" && curve._label._isVisible) { // Calculate the x,y (TopLeft) location of the current // curve legend label // assuming: // charHeight/2 for the left margin, plus legendWidth for each // horizontal column // legendHeight is the line spacing, with no extra margin above x = _rect.Left + halfGap / 2.0F + (iEntry % _hStack) * _legendItemWidth; y = _rect.Top + (int)(iEntry / _hStack) * _legendItemHeight; // Draw the legend label for the current curve FontSpec tmpFont = (curve._label._fontSpec != null) ? curve._label._fontSpec : this.FontSpec; // This is required because, for long labels, the centering can affect the // position in GDI+. tmpFont.StringAlignment = StringAlignment.Near; if (_isShowLegendSymbols) { tmpFont.Draw(g, pane, curve._label._text, x + 2.5F * _tmpSize, y + _legendItemHeight / 2.0F, AlignH.Left, AlignV.Center, scaleFactor); RectangleF rect = new RectangleF(x, y + _legendItemHeight / 4.0F, 2 * _tmpSize, _legendItemHeight / 2.0F); curve.DrawLegendKey(g, tmpPane, rect, scaleFactor); } else { if (curve._label._fontSpec == null) { tmpFont.FontColor = curve.Color; } tmpFont.Draw(g, pane, curve._label._text, x + 0.0F * _tmpSize, y + _legendItemHeight / 2.0F, AlignH.Left, AlignV.Center, scaleFactor); } // maintain a curve count for positioning iEntry++; } } if (pane is MasterPane && ((MasterPane)pane).IsUniformLegendEntries) { break; } } // Draw a border around the legend if required if (iEntry > 0) { this.Border.Draw(g, pane, scaleFactor, _rect); } } }
private void leftorrightaxis(bool left, CurveItem myCurve) { if (!left) { myCurve.Label.Text += " R"; myCurve.IsY2Axis = true; myCurve.YAxisIndex = 0; zg1.GraphPane.Y2Axis.IsVisible = true; } else if (left) { myCurve.IsY2Axis = false; } }
/// <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 ); }