/// <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 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> /// 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; }
/// <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 || 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; }