/// <summary> /// Calculate the width of each bar, depending on the actual bar type /// </summary> /// <returns>The width for an individual bar, in pixel units</returns> public float GetBarWidth(GraphPane pane) { // Total axis width = // npts * ( nbars * ( bar + bargap ) - bargap + clustgap ) // cg * bar = cluster gap // npts = max number of points in any curve // nbars = total number of curves that are of type IsBar // bar = bar width // bg * bar = bar gap // therefore: // totwidth = npts * ( nbars * (bar + bg*bar) - bg*bar + cg*bar ) // totwidth = bar * ( npts * ( nbars * ( 1 + bg ) - bg + cg ) ) // solve for bar float barWidth; if (this is ErrorBarItem) { barWidth = (((ErrorBarItem)this).Bar.Symbol.Size * pane.CalcScaleFactor()); } else if (this is HiLowBarItem) { // barWidth = (float) ( ((HiLowBarItem)this).Bar.GetBarWidth( pane, // ((HiLowBarItem)this).BaseAxis(pane), pane.CalcScaleFactor() ) ); barWidth = (((HiLowBarItem)this).Bar.Size * pane.CalcScaleFactor()); } else // BarItem or LineItem { // For stacked bar types, the bar width will be based on a single bar float numBars = 1.0F; if (pane._barSettings.Type == BarType.Cluster || pane._barSettings.Type == BarType.ClusterHiLow) { numBars = pane.CurveList.NumBars; } float denom = numBars * (1.0F + pane._barSettings.MinBarGap) - pane._barSettings.MinBarGap + pane._barSettings.MinClusterGap; if (denom <= 0) { denom = 1; } barWidth = pane.BarSettings.GetClusterWidth() / denom; } if (barWidth <= 0) { return(1); } return(barWidth); }
/// <summary> /// Determine the coords for the rectangle associated with a specified point for /// this <see cref="CurveItem" /> /// </summary> /// <param name="pane">The <see cref="GraphPane" /> to which this curve belongs</param> /// <param name="i">The index of the point of interest</param> /// <param name="coords"> /// A list of coordinates that represents the "rect" for /// this point (used in an html AREA tag) /// </param> /// <returns>true if it's a valid point, false otherwise</returns> public override bool GetCoords(GraphPane pane, int i, out string coords) { coords = string.Empty; if ((i < 0) || (i >= Points.Count)) { return(false); } var valueAxis = ValueAxis(pane); var baseAxis = BaseAxis(pane); var scaledSize = _bar.Symbol.Size * pane.CalcScaleFactor(); // 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 var clusterWidth = pane.BarSettings.GetClusterWidth(); var barWidth = GetBarWidth(pane); var clusterGap = pane._barSettings.MinClusterGap * barWidth; var 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; var valueHandler = new ValueHandler(pane, false); valueHandler.GetValues(this, i, 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 (Points[i].IsInvalid) { return(false); } // calculate a pixel value for the top of the bar on value axis var pixLowVal = valueAxis.Scale.Transform(IsOverrideOrdinal, i, curLowVal); var pixHiVal = valueAxis.Scale.Transform(IsOverrideOrdinal, i, curHiVal); // calculate a pixel value for the center of the bar on the base axis var pixBase = baseAxis.Scale.Transform(IsOverrideOrdinal, i, curBase); // Calculate the pixel location for the side of the bar (on the base axis) var pixSide = pixBase - scaledSize / 2.0F; // Draw the bar coords = baseAxis is IXAxis ? $"{pixSide:f0},{pixLowVal:f0},{pixSide + scaledSize:f0},{pixHiVal:f0}" : $"{pixLowVal:f0},{pixSide:f0},{pixHiVal:f0},{pixSide + scaledSize:f0}"; return(true); }
/// <summary> /// Determine the coords for the rectangle associated with a specified point for /// this <see cref="CurveItem" /> /// </summary> /// <param name="pane">The <see cref="GraphPane" /> to which this curve belongs</param> /// <param name="i">The index of the point of interest</param> /// <param name="coords">A list of coordinates that represents the "rect" for /// this point (used in an html AREA tag)</param> /// <returns>true if it's a valid point, false otherwise</returns> public override bool GetCoords(GraphPane pane, int i, out string coords) { coords = string.Empty; if (i < 0 || i >= _points.Count) { return(false); } var valueAxis = ValueAxis(pane); var baseAxis = BaseAxis(pane); var halfSize = _stick.Size * pane.CalcScaleFactor(); var pt = _points[i]; var date = pt.X; var high = pt.Y; var low = pt.Z; if (!pt.IsInvalid3D && (date > 0 || !baseAxis._scale.IsLog) && ((high > 0 && low > 0) || !valueAxis._scale.IsLog)) { var pixBase = baseAxis.Scale.Transform(_isOverrideOrdinal, i, date); var pixHigh = valueAxis.Scale.Transform(_isOverrideOrdinal, i, high); var pixLow = valueAxis.Scale.Transform(_isOverrideOrdinal, i, low); // Calculate the pixel location for the side of the bar (on the base axis) var pixSide = pixBase - halfSize; // Draw the bar if (baseAxis is XAxis || baseAxis is X2Axis) { coords = String.Format( "{0:f0},{1:f0},{2:f0},{3:f0}", pixSide, pixLow, pixSide + halfSize * 2, pixHigh); } else { coords = String.Format( "{0:f0},{1:f0},{2:f0},{3:f0}", pixLow, pixSide, pixHigh, pixSide + halfSize * 2); } return(true); } return(false); }
/// <summary> /// Determine the coords for the rectangle associated with a specified point for /// this <see cref="CurveItem" /> /// </summary> /// <param name="pane">The <see cref="GraphPane" /> to which this curve belongs</param> /// <param name="i">The index of the point of interest</param> /// <param name="coords">A list of coordinates that represents the "rect" for /// this point (used in an html AREA tag)</param> /// <returns>true if it's a valid point, false otherwise</returns> public override bool GetCoords(GraphPane pane, int i, out string coords) { coords = string.Empty; if (i < 0 || i >= Points.Count) { return(false); } var valueAxis = ValueAxis(pane); var baseAxis = BaseAxis(pane); var halfSize = Bar.Size * pane.CalcScaleFactor(); var pt = Points[i]; var date = pt.X; double high; double low; if (pt is IOHLC) { var p = (IOHLC)pt; high = p.High; low = p.Low; } else { high = pt.Y; low = pt.Z; } if (pt.IsInvalid || (date <= 0 && baseAxis.Scale.IsLog) || ((high <= 0 || low <= 0) && valueAxis.Scale.IsLog)) { return(false); } var pixBase = baseAxis.Scale.Transform(IsOverrideOrdinal, i, date); var pixHigh = valueAxis.Scale.Transform(IsOverrideOrdinal, i, high); var pixLow = valueAxis.Scale.Transform(IsOverrideOrdinal, i, low); // Calculate the pixel location for the side of the bar (on the base axis) var pixSide = pixBase - halfSize; // Draw the bar coords = baseAxis is IXAxis ? $"{pixSide:f0},{pixLow:f0},{pixSide + halfSize*2:f0},{pixHigh:f0}" : $"{pixLow:f0},{pixSide:f0},{pixHigh:f0},{pixSide + halfSize*2:f0}"; return(true); }
/// <summary> /// Determine the coords for the rectangle associated with a specified point for /// this <see cref="CurveItem" /> /// </summary> /// <param name="pane">The <see cref="GraphPane" /> to which this curve belongs</param> /// <param name="i">The index of the point of interest</param> /// <param name="coords">A list of coordinates that represents the "rect" for /// this point (used in an html AREA tag)</param> /// <returns>true if it's a valid point, false otherwise</returns> public override bool GetCoords(GraphPane pane, int i, out string coords) { coords = string.Empty; if (i < 0 || i >= _points.Count) { return(false); } var pt = _points[i]; if (pt.IsInvalid) { return(false); } double x, y, z; var valueHandler = new ValueHandler(pane, false); valueHandler.GetValues(this, i, out x, out z, out y); var yAxis = GetYAxis(pane); var xAxis = GetXAxis(pane); var pixPt = new PointF( xAxis.Scale.Transform(_isOverrideOrdinal, i, x), yAxis.Scale.Transform(_isOverrideOrdinal, i, y)); if (!pane.Chart.Rect.Contains(pixPt)) { return(false); } var halfSize = _symbol.Size * pane.CalcScaleFactor(); coords = String.Format( "{0:f0},{1:f0},{2:f0},{3:f0}", pixPt.X - halfSize, pixPt.Y - halfSize, pixPt.X + halfSize, pixPt.Y + halfSize); return(true); }
/// <summary> /// Determine the coords for the rectangle associated with a specified point for /// this <see cref="CurveItem" /> /// </summary> /// <param name="pane">The <see cref="GraphPane" /> to which this curve belongs</param> /// <param name="i">The index of the point of interest</param> /// <param name="coords">A list of coordinates that represents the "rect" for /// this point (used in an html AREA tag)</param> /// <returns>true if it's a valid point, false otherwise</returns> override public bool GetCoords(GraphPane pane, int i, out string coords) { coords = string.Empty; if (i < 0 || i >= _points.Count) { return(false); } Axis valueAxis = ValueAxis(pane); Axis baseAxis = BaseAxis(pane); float scaledSize = _bar.Symbol.Size * pane.CalcScaleFactor(); // 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.BarSettings.GetClusterWidth(); float barWidth = 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(this, i, 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 (!_points[i].IsInvalid3D) { // calculate a pixel value for the top of the bar on value axis pixLowVal = valueAxis.Scale.Transform(_isOverrideOrdinal, i, curLowVal); pixHiVal = valueAxis.Scale.Transform(_isOverrideOrdinal, i, curHiVal); // calculate a pixel value for the center of the bar on the base axis pixBase = baseAxis.Scale.Transform(_isOverrideOrdinal, i, curBase); // Calculate the pixel location for the side of the bar (on the base axis) float pixSide = pixBase - scaledSize / 2.0F; // Draw the bar if (baseAxis is XAxis || baseAxis is X2Axis) { coords = String.Format("{0:f0},{1:f0},{2:f0},{3:f0}", pixSide, pixLowVal, pixSide + scaledSize, pixHiVal); } else { coords = String.Format("{0:f0},{1:f0},{2:f0},{3:f0}", pixLowVal, pixSide, pixHiVal, pixSide + scaledSize); } return(true); } return(false); }
/// <summary> /// Determine the coords for the rectangle associated with a specified point for /// this <see cref="CurveItem" /> /// </summary> /// <param name="pane">The <see cref="GraphPane" /> to which this curve belongs</param> /// <param name="i">The index of the point of interest</param> /// <param name="coords">A list of coordinates that represents the "rect" for /// this point (used in an html AREA tag)</param> /// <returns>true if it's a valid point, false otherwise</returns> override public bool GetCoords( GraphPane pane, int i, out string coords ) { coords = string.Empty; if ( i < 0 || i >= _points.Count ) return false; Axis valueAxis = ValueAxis( pane ); Axis baseAxis = BaseAxis( pane ); float scaledSize = _bar.Symbol.Size * pane.CalcScaleFactor(); // 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.BarSettings.GetClusterWidth(); float barWidth = 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( this, i, 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 ( !_points[i].IsInvalid3D ) { // calculate a pixel value for the top of the bar on value axis pixLowVal = valueAxis.Scale.Transform( _isOverrideOrdinal, i, curLowVal ); pixHiVal = valueAxis.Scale.Transform( _isOverrideOrdinal, i, curHiVal ); // calculate a pixel value for the center of the bar on the base axis pixBase = baseAxis.Scale.Transform( _isOverrideOrdinal, i, curBase ); // Calculate the pixel location for the side of the bar (on the base axis) float pixSide = pixBase - scaledSize / 2.0F; // Draw the bar if ( baseAxis is XAxis || baseAxis is X2Axis ) coords = String.Format( "{0:f0},{1:f0},{2:f0},{3:f0}", pixSide, pixLowVal, pixSide + scaledSize, pixHiVal ); else coords = String.Format( "{0:f0},{1:f0},{2:f0},{3:f0}", pixLowVal, pixSide, pixHiVal, pixSide + scaledSize ); return true; } return false; }
/// <summary> /// Determine the coords for the rectangle associated with a specified point for /// this <see cref="CurveItem" /> /// </summary> /// <param name="pane">The <see cref="GraphPane" /> to which this curve belongs</param> /// <param name="i">The index of the point of interest</param> /// <param name="coords">A list of coordinates that represents the "rect" for /// this point (used in an html AREA tag)</param> /// <returns>true if it's a valid point, false otherwise</returns> public override bool GetCoords(GraphPane pane, int i, out string coords) { coords = string.Empty; if (i < 0 || i >= _points.Count) return false; PointPair pt = _points[i]; if (pt.IsInvalid) return false; double x, y, z; ValueHandler valueHandler = new ValueHandler(pane, false); valueHandler.GetValues(this, i, out x, out z, out y); Axis yAxis = GetYAxis(pane); Axis xAxis = GetXAxis(pane); PointF pixPt = new PointF(xAxis.Scale.Transform(_isOverrideOrdinal, i, x), yAxis.Scale.Transform(_isOverrideOrdinal, i, y)); if (!pane.Chart.Rect.Contains(pixPt)) return false; float halfSize = _symbol.Size*pane.CalcScaleFactor(); coords = string.Format("{0:f0},{1:f0},{2:f0},{3:f0}", pixPt.X - halfSize, pixPt.Y - halfSize, pixPt.X + halfSize, pixPt.Y + halfSize); return true; }
/// <summary> /// Determine the coords for the rectangle associated with a specified point for /// this <see cref="CurveItem" /> /// </summary> /// <param name="pane">The <see cref="GraphPane" /> to which this curve belongs</param> /// <param name="i">The index of the point of interest</param> /// <param name="coords">A list of coordinates that represents the "rect" for /// this point (used in an html AREA tag)</param> /// <returns>true if it's a valid point, false otherwise</returns> public override bool GetCoords(GraphPane pane, int i, out string coords) { coords = string.Empty; if (i < 0 || i >= _points.Count) return false; Axis valueAxis = ValueAxis(pane); Axis baseAxis = BaseAxis(pane); float halfSize = _stick.Size*pane.CalcScaleFactor(); PointPair pt = _points[i]; double date = pt.X; double high = pt.Y; double low = pt.Z; if (!pt.IsInvalid3D && (date > 0 || !baseAxis._scale.IsLog) && ((high > 0 && low > 0) || !valueAxis._scale.IsLog)) { float pixBase, pixHigh, pixLow; pixBase = baseAxis.Scale.Transform(_isOverrideOrdinal, i, date); pixHigh = valueAxis.Scale.Transform(_isOverrideOrdinal, i, high); pixLow = valueAxis.Scale.Transform(_isOverrideOrdinal, i, low); // Calculate the pixel location for the side of the bar (on the base axis) float pixSide = pixBase - halfSize; // Draw the bar if (baseAxis is XAxis) coords = String.Format("{0:f0},{1:f0},{2:f0},{3:f0}", pixSide, pixLow, pixSide + halfSize*2, pixHigh); else coords = String.Format("{0:f0},{1:f0},{2:f0},{3:f0}", pixLow, pixSide, pixHigh, pixSide + halfSize*2); return true; } return false; }
/// <summary> /// Calculate the width of each bar, depending on the actual bar type /// </summary> /// <returns>The width for an individual bar, in pixel units</returns> public float GetBarWidth( GraphPane pane ) { // Total axis width = // npts * ( nbars * ( bar + bargap ) - bargap + clustgap ) // cg * bar = cluster gap // npts = max number of points in any curve // nbars = total number of curves that are of type IsBar // bar = bar width // bg * bar = bar gap // therefore: // totwidth = npts * ( nbars * (bar + bg*bar) - bg*bar + cg*bar ) // totwidth = bar * ( npts * ( nbars * ( 1 + bg ) - bg + cg ) ) // solve for bar float barWidth; if ( this is ErrorBarItem ) barWidth = (float) ( ((ErrorBarItem)this).Bar.Symbol.Size * pane.CalcScaleFactor() ); // else if ( this is HiLowBarItem && pane._barSettings.Type != BarType.ClusterHiLow ) // barWidth = (float) ( ((HiLowBarItem)this).Bar.GetBarWidth( pane, // ((HiLowBarItem)this).BaseAxis(pane), pane.CalcScaleFactor() ) ); // barWidth = (float) ( ((HiLowBarItem)this).Bar.Size * // pane.CalcScaleFactor() ); else // BarItem or LineItem { // For stacked bar types, the bar width will be based on a single bar float numBars = 1.0F; if ( pane._barSettings.Type == BarType.Cluster ) numBars = pane.CurveList.NumClusterableBars; float denom = numBars * ( 1.0F + pane._barSettings.MinBarGap ) - pane._barSettings.MinBarGap + pane._barSettings.MinClusterGap; if ( denom <= 0 ) denom = 1; barWidth = pane.BarSettings.GetClusterWidth() / denom; } if ( barWidth <= 0 ) return 1; return barWidth; }