Beispiel #1
0
        /// <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>
        virtual protected 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);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Draw all the <see cref="ErrorBar"/>'s to the specified <see cref="Graphics"/>
        /// device as a an error bar at each defined point.
        /// </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="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 Draw(Graphics g, GraphPane pane, ErrorBarItem curve,
                         Axis baseAxis, Axis valueAxis, double scaleFactor)
        {
            BarValueHandler valueHandler = new BarValueHandler(pane);

            float  pixBase, pixValue, pixLowValue;
            double scaleBase, scaleValue, scaleLowValue;

            if (curve.Points != null && this.IsVisible)
            {
                Pen pen = new Pen(color, penWidth);

                // Loop over each defined point
                for (int i = 0; i < curve.Points.Count; i++)
                {
                    valueHandler.GetBarValues(curve, i, out scaleBase,
                                              out scaleLowValue, out scaleValue);

                    // 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[i].IsInvalid3D &&
                        (scaleBase > 0 || !baseAxis.IsLog) &&
                        ((scaleValue > 0 && scaleLowValue > 0) || !valueAxis.IsLog))
                    {
                        pixBase     = baseAxis.Transform(scaleBase);
                        pixValue    = valueAxis.Transform(scaleValue);
                        pixLowValue = valueAxis.Transform(scaleLowValue);

                        //if ( this.fill.IsGradientValueType )
                        //	brush = fill.MakeBrush( rect, points[i] );

                        this.Draw(g, pane, baseAxis is XAxis, pixBase, pixValue,
                                  pixLowValue, scaleFactor, pen);
                    }
                }
            }
        }
Beispiel #3
0
        /// <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 );
               }
        }
Beispiel #4
0
        /// <summary>
        /// Draw all the <see cref="ErrorBar"/>'s to the specified <see cref="Graphics"/>
        /// device as a an error bar at each defined point.
        /// </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="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 Draw( Graphics g, GraphPane pane, ErrorBarItem curve,
							Axis baseAxis, Axis valueAxis, double scaleFactor )
        {
            BarValueHandler valueHandler = new BarValueHandler( pane );

            float	pixBase, pixValue, pixLowValue;
            double	scaleBase, scaleValue, scaleLowValue;

            if ( curve.Points != null && this.IsVisible )
            {
                Pen pen = new Pen( color, penWidth );

                // Loop over each defined point
                for ( int i=0; i<curve.Points.Count; i++ )
                {
                    valueHandler.GetBarValues( curve, i, out scaleBase,
                                out scaleLowValue, out scaleValue );

                    // 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[i].IsInvalid3D &&
                            ( scaleBase > 0 || !baseAxis.IsLog ) &&
                            ( ( scaleValue > 0 && scaleLowValue > 0 ) || !valueAxis.IsLog ) )
                    {
                        pixBase = baseAxis.Transform( scaleBase );
                        pixValue = valueAxis.Transform( scaleValue );
                        pixLowValue = valueAxis.Transform( scaleLowValue );

                        //if ( this.fill.IsGradientValueType )
                        //	brush = fill.MakeBrush( rect, points[i] );

                        this.Draw( g, pane, baseAxis is XAxis, pixBase, pixValue,
                                        pixLowValue, scaleFactor, pen );
                    }
                }
            }
        }
Beispiel #5
0
        /// <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 override void DrawSingleBar( Graphics g, GraphPane pane,
							CurveItem curve,
							int index, int pos, Axis baseAxis, Axis valueAxis,
							double 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 = ( baseAxis is XAxis ) ? points[index].X : points[index].Y;
            //			double curValue = ( baseAxis is XAxis ) ? points[index].Y : points[index].X;

            double curBase, curLowVal, curHiVal;
            BarValueHandler valueHandler = new BarValueHandler( pane );
            valueHandler.GetBarValues( curve, index, out curBase,
                    out curLowVal, out curHiVal );

            // 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
            //double curLow = points[index].LowValue;

            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.Transform( index, curHiVal );
                // calculate a pixel value for the center of the bar on the base axis
                pixBase = baseAxis.Transform( index, curBase );

                pixLowVal = valueAxis.Transform( index, curLowVal );

                // 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 )
                    this.Draw( g, pane, pixSide, pixSide + scaledSize, pixLowVal,
                                pixHiVal, scaleFactor, true );
                else
                    this.Draw( g, pane, pixLowVal, pixHiVal, pixSide, pixSide + scaledSize,
                                scaleFactor, true );
               }
        }
Beispiel #6
0
        /// <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>
        override protected void DrawSingleBar(Graphics g, GraphPane pane,
                                              CurveItem curve,
                                              int index, int pos, Axis baseAxis, Axis valueAxis,
                                              double 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 = ( baseAxis is XAxis ) ? points[index].X : points[index].Y;
//			double curValue = ( baseAxis is XAxis ) ? points[index].Y : points[index].X;

            double          curBase, curLowVal, curHiVal;
            BarValueHandler valueHandler = new BarValueHandler(pane);

            valueHandler.GetBarValues(curve, index, out curBase,
                                      out curLowVal, out curHiVal);


            // 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
            //double curLow = points[index].LowValue;

            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.Transform(index, curHiVal);
                // calculate a pixel value for the center of the bar on the base axis
                pixBase = baseAxis.Transform(index, curBase);

                pixLowVal = valueAxis.Transform(index, curLowVal);

                // 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)
                {
                    this.Draw(g, pane, pixSide, pixSide + scaledSize, pixLowVal,
                              pixHiVal, scaleFactor, true);
                }
                else
                {
                    this.Draw(g, pane, pixLowVal, pixHiVal, pixSide, pixSide + scaledSize,
                              scaleFactor, true);
                }
            }
        }
Beispiel #7
0
        /// <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 axisRect, always return false
            if ( ! axisRect.Contains( mousePt ) )
                return false;

            double	x, y, y2;
            ReverseTransform( mousePt, out x, out y, out y2 );

            if ( xAxis.Min == xAxis.Max || yAxis.Min == yAxis.Max ||
                y2Axis.Min == y2Axis.Max )
                return false;

            BarValueHandler valueHandler = new BarValueHandler( this );

            double	xPixPerUnit = axisRect.Width / ( xAxis.Max - xAxis.Min );
            double	yPixPerUnit = axisRect.Height / ( yAxis.Max - yAxis.Min );
            double	y2PixPerUnit = axisRect.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 )
            {
                if ( curve.IsY2Axis )
                {
                    yAct = y2;
                    yMinAct = y2Axis.Min;
                    yMaxAct = y2Axis.Max;
                    yPixPerUnitAct = y2PixPerUnit;
                }
                else
                {
                    yAct = y;
                    yMinAct = yAxis.Min;
                    yMaxAct = yAxis.Max;
                    yPixPerUnitAct = yPixPerUnit;
                }

                PointPairList points = curve.Points;
                float barWidth = curve.GetBarWidth( this );
                double barWidthUserHalf;
                bool isXBaseAxis = ( curve.BaseAxis( this ) == XAxis );
                if ( isXBaseAxis )
                    barWidthUserHalf = barWidth / xPixPerUnit / 2.0;
                else
                    barWidthUserHalf = barWidth / yPixPerUnit / 2.0;

                if ( points != null )
                {
                    for ( int iPt=0; iPt<curve.NPts; iPt++ )
                    {
                        if ( xAxis.IsOrdinal )
                            xVal = (double) iPt + 1.0;
                        else
                            xVal = points[iPt].X;

                        if ( yAxis.IsOrdinal )
                            yVal = (double) iPt + 1.0;
                        else
                            yVal = points[iPt].Y;

                        if (	xVal != PointPair.Missing &&
                                xVal >= xAxis.Min && xVal <= xAxis.Max &&
                                yVal != PointPair.Missing &&
                                yVal >= yMinAct && yVal <= yMaxAct )
                        {

                            if ( curve.IsBar || curve is ErrorBarItem ||
                                    curve is HiLowBarItem )
                            {
                                double baseVal, lowVal, hiVal;
                                valueHandler.GetBarValues( 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 ||
                                            y < lowVal || y > hiVal )
                                        continue;
                                }
                                else
                                {
                                    double centerVal = valueHandler.BarCenterValue( curve, barWidth, iPt, yVal, iBar );

                                    if (	y < centerVal - barWidthUserHalf ||
                                            y > centerVal + barWidthUserHalf ||
                                            x < lowVal || x > hiVal )
                                        continue;
                                }

                                if ( nearestBar == null )
                                {
                                    iNearestBar = iPt;
                                    nearestBar = curve;
                                }
                            }
                            else
                            {
                                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;
        }