Esempio n. 1
0
		/// <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);

			// 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 - clusterWidth/2.0F + clusterGap/2.0F +
				                pane.CurveList.GetBarItemPos(pane, this)*(barWidth + barGap);

				// Draw the bar
				if (baseAxis is XAxis || baseAxis is X2Axis)
					coords = string.Format("{0:f0},{1:f0},{2:f0},{3:f0}",
					                       pixSide, pixLowVal,
					                       pixSide + barWidth, pixHiVal);
				else
					coords = string.Format("{0:f0},{1:f0},{2:f0},{3:f0}",
					                       pixLowVal, pixSide,
					                       pixHiVal, pixSide + barWidth);

				return true;
			}

			return false;
		}
Esempio n. 2
0
        /// <summary>
        /// Draw this <see cref="CurveItem"/> to the specified <see cref="Graphics"/>
        /// device as a symbol at each defined point.  The routine
        /// only draws the symbols; the lines are draw by the
        /// <see cref="Line.DrawCurve"/> method.  This method
        /// is normally only called by the Draw method of the
        /// <see cref="CurveItem"/> 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="LineItem"/> representing this
        /// curve.</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, GraphPane pane, LineItem curve, float scaleFactor)
        {
            float tmpX, tmpY;
            double curX, curY, lowVal;
            IPointList points = curve.Points;

            if (points != null && (_border.IsVisible || _fill.IsVisible))
            {
                SmoothingMode sModeSave = g.SmoothingMode;
                if (_isAntiAlias)
                    g.SmoothingMode = SmoothingMode.HighQuality;

                // For the sake of speed, go ahead and create a solid brush and a pen
                // If it's a gradient fill, it will be created on the fly for each symbol
                //SolidBrush	brush = new SolidBrush( this.fill.Color );

                using (Pen pen = _border.MakePen(pane.IsPenWidthScaled, scaleFactor))
                using (GraphicsPath path = MakePath(g, scaleFactor))
                {
                    RectangleF rect = path.GetBounds();

                    using (Brush brush = Fill.MakeBrush(rect))
                    {
                        var valueHandler = new ValueHandler(pane, false);
                        Scale xScale = pane.XAxis.Scale;
                        Scale yScale = curve.GetYAxis(pane).Scale;

                        bool xIsLog = xScale.IsLog;
                        bool yIsLog = yScale.IsLog;

                        // Loop over each defined point
                        for (int i = 0; i < points.Count; i++)
                        {
                            // Get the user scale values for the current point
                            // use the valueHandler only for stacked types
                            if (pane.LineType == LineType.Stack)
                            {
                                valueHandler.GetValues(curve, i, out curX, out lowVal, out curY);
                            }
                                // otherwise, just access the values directly.  Avoiding the valueHandler for
                                // non-stacked types is an optimization to minimize overhead in case there are
                                // a large number of points.
                            else
                            {
                                curX = points[i].X;
                                if (curve is StickItem)
                                    curY = points[i].Z;
                                else
                                    curY = points[i].Y;
                            }

                            // 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 (curX != PointPair.Missing &&
                                curY != PointPair.Missing &&
                                !Double.IsNaN(curX) &&
                                !Double.IsNaN(curY) &&
                                !Double.IsInfinity(curX) &&
                                !Double.IsInfinity(curY) &&
                                (curX > 0 || !xIsLog) &&
                                (!yIsLog || curY > 0.0))
                            {
                                // Transform the user scale values to pixel locations
                                tmpX = xScale.Transform(curve.IsOverrideOrdinal, i, curX);
                                tmpY = yScale.Transform(curve.IsOverrideOrdinal, i, curY);

                                // If the fill type for this symbol is a Gradient by value type,
                                // the make a brush corresponding to the appropriate current value
                                if (_fill.IsGradientValueType)
                                {
                                    using (Brush tBrush = _fill.MakeBrush(rect, points[i]))
                                        DrawSymbol(g, tmpX, tmpY, path, pen, tBrush);
                                }
                                else
                                {
                                    // Otherwise, the brush is already defined
                                    // Draw the symbol at the specified pixel location
                                    DrawSymbol(g, tmpX, tmpY, path, pen, brush);
                                }
                            }
                        }
                    }
                }

                g.SmoothingMode = sModeSave;
            }
        }
Esempio n. 3
0
		/// <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;
		}
Esempio n. 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="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, GraphPane pane, ErrorBarItem curve,
							Axis baseAxis, Axis valueAxis, float scaleFactor )
		{
			ValueHandler valueHandler = new ValueHandler( pane, false );

			float	pixBase, pixValue, pixLowValue;
			double	scaleBase, scaleValue, scaleLowValue;
		
			if ( curve.Points != null && this.IsVisible )
			{
				using ( Pen pen = !curve.IsSelected ? new Pen( _color, _penWidth ) :
						new Pen( Selection.Border.Color, Selection.Border.Width ) )
				{
					// Loop over each defined point							
					for ( int i = 0; i < curve.Points.Count; i++ )
					{
						valueHandler.GetValues( 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._scale.IsLog ) &&
								( ( scaleValue > 0 && scaleLowValue > 0 ) || !valueAxis._scale.IsLog ) )
						{
							pixBase = baseAxis.Scale.Transform( curve.IsOverrideOrdinal, i, scaleBase );
							pixValue = valueAxis.Scale.Transform( curve.IsOverrideOrdinal, i, scaleValue );
							pixLowValue = valueAxis.Scale.Transform( curve.IsOverrideOrdinal, i, scaleLowValue );

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

							this.Draw( g, pane, baseAxis is XAxis || baseAxis is X2Axis, pixBase, pixValue,
											pixLowValue, scaleFactor, pen, curve.IsSelected,
											curve.Points[i] );
						}
					}
				}
			}
		}
Esempio n. 5
0
        /// <summary>
        /// Build an array of <see cref="PointF"/> values (pixel coordinates) that represents
        /// the low values for the current curve.
        /// </summary>
        /// <remarks>Note that this drawing routine ignores <see cref="PointPairBase.Missing"/>
        /// values, but it does not "break" the line to indicate values are missing.
        /// </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">A <see cref="LineItem"/> representing this
        /// curve.</param>
        /// <param name="arrPoints">An array of <see cref="PointF"/> values in pixel
        /// coordinates representing the current curve.</param>
        /// <param name="count">The number of points contained in the "arrPoints"
        /// parameter.</param>
        /// <returns>true for a successful points array build, false for data problems</returns>
        public bool BuildLowPointsArray( GraphPane pane, CurveItem curve,
						out PointF[] arrPoints, out int count )
        {
            arrPoints = null;
            count = 0;
            IPointList points = curve.Points;

            if ( this.IsVisible && !this.Color.IsEmpty && points != null )
            {
                int index = 0;
                float curX, curY,
                        lastX = 0,
                        lastY = 0;
                double x, y, hiVal;
                ValueHandler valueHandler = new ValueHandler( pane, false );

                // Step type plots get twice as many points.  Always add three points so there is
                // room to close out the curve for area fills.
                arrPoints = new PointF[( _stepType == ZedGraph.StepType.NonStep ? 1 : 2 ) *
                    ( pane.LineType == LineType.Stack ? 2 : 1 ) *
                    points.Count + 1];

                // Loop backwards over all points in the curve
                // In this case an array of points was already built forward by BuildPointsArray().
                // This time we build backwards to complete a loop around the area between two curves.
                for ( int i = points.Count - 1; i >= 0; i-- )
                {
                    // Make sure the current point is valid
                    if ( !points[i].IsInvalid )
                    {
                        // Get the user scale values for the current point
                        valueHandler.GetValues( curve, i, out x, out y, out hiVal );

                        if ( x == PointPair.Missing || y == PointPair.Missing )
                            continue;

                        // Transform the user scale values to pixel locations
                        Axis xAxis = curve.GetXAxis( pane );
                        curX = xAxis.Scale.Transform( curve.IsOverrideOrdinal, i, x );
                        Axis yAxis = curve.GetYAxis( pane );
                        curY = yAxis.Scale.Transform( curve.IsOverrideOrdinal, i, y );

                        // Add the pixel value pair into the points array
                        // Two points are added for step type curves
                        // ignore step-type setting for smooth curves
                        if ( _isSmooth || index == 0 || this.StepType == StepType.NonStep )
                        {
                            arrPoints[index].X = curX;
                            arrPoints[index].Y = curY;
                        }
                        else if ( this.StepType == StepType.ForwardStep )
                        {
                            arrPoints[index].X = curX;
                            arrPoints[index].Y = lastY;
                            index++;
                            arrPoints[index].X = curX;
                            arrPoints[index].Y = curY;
                        }
                        else if ( this.StepType == StepType.RearwardStep )
                        {
                            arrPoints[index].X = lastX;
                            arrPoints[index].Y = curY;
                            index++;
                            arrPoints[index].X = curX;
                            arrPoints[index].Y = curY;
                        }

                        lastX = curX;
                        lastY = curY;
                        index++;

                    }

                }

                // Make sure there is at least one valid point
                if ( index == 0 )
                    return false;

                // Add an extra point at the end, since the smoothing algorithm requires it
                arrPoints[index] = arrPoints[index - 1];
                index++;

                count = index;
                return true;
            }
            else
            {
                return false;
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Draw the this <see cref="CurveItem"/> to the specified <see cref="Graphics"/>
        /// device.  The format (stair-step or line) of the curve is
        /// defined by the <see cref="StepType"/> property.  The routine
        /// only draws the line segments; 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
        /// </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 DrawCurve( Graphics g, GraphPane pane,
                                CurveItem curve, float scaleFactor )
        {
            Line source = this;
            if ( curve.IsSelected )
                source = Selection.Line;

            float tmpX, tmpY,
                    lastX = float.MaxValue,
                    lastY = float.MaxValue;
            double curX, curY, lowVal;
            PointPair curPt, lastPt = new PointPair();

            bool lastBad = true;
            IPointList points = curve.Points;
            ValueHandler valueHandler = new ValueHandler( pane, false );
            Axis yAxis = curve.GetYAxis( pane );
            Axis xAxis = curve.GetXAxis( pane );

            bool xIsLog = xAxis._scale.IsLog;
            bool yIsLog = yAxis._scale.IsLog;

            float minX = pane.Chart.Rect.Left;
            float maxX = pane.Chart.Rect.Right;

            using ( Pen pen = source.GetPen( pane, scaleFactor ) )
            {
                if ( points != null && !_color.IsEmpty && this.IsVisible )
                {
                    bool lastOut = false;
                    bool isOut;

                    // Loop over each point in the curve
                    for ( int i = 0; i < points.Count; i++ )
                    {
                        curPt = points[i];
                        if ( pane.LineType == LineType.Stack )
                        {
                            if ( !valueHandler.GetValues( curve, i, out curX, out lowVal, out curY ) )
                            {
                                curX = PointPair.Missing;
                                curY = PointPair.Missing;
                            }
                        }
                        else
                        {
                            curX = curPt.X;
                            curY = curPt.Y;
                        }

                        // 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 ( curX == PointPair.Missing ||
                                curY == PointPair.Missing ||
                                System.Double.IsNaN( curX ) ||
                                System.Double.IsNaN( curY ) ||
                                System.Double.IsInfinity( curX ) ||
                                System.Double.IsInfinity( curY ) ||
                                ( xIsLog && curX <= 0.0 ) ||
                                ( yIsLog && curY <= 0.0 ) )
                        {
                            // If the point is invalid, then make a linebreak only if IsIgnoreMissing is false
                            // LastX and LastY are always the last valid point, so this works out
                            lastBad = lastBad || !pane.IsIgnoreMissing;
                            isOut = true;
                        }
                        else
                        {
                            // Transform the current point from user scale units to
                            // screen coordinates
                            tmpX = xAxis.Scale.Transform( curve.IsOverrideOrdinal, i, curX );
                            tmpY = yAxis.Scale.Transform( curve.IsOverrideOrdinal, i, curY );
                            isOut = (tmpX < minX || tmpX > maxX);

                            if ( !lastBad )
                            {
                                try
                                {
                                    // GDI+ plots the data wrong and/or throws an exception for
                                    // outrageous coordinates, so we do a sanity check here
                                    if ( lastX > 5000000 || lastX < -5000000 ||
                                            lastY > 5000000 || lastY < -5000000 ||
                                            tmpX > 5000000 || tmpX < -5000000 ||
                                            tmpY > 5000000 || tmpY < -5000000 )
                                        InterpolatePoint( g, pane, curve, lastPt, scaleFactor, pen,
                                                        lastX, lastY, tmpX, tmpY );
                                    else if ( !lastOut || !isOut )
                                    {
                                        if ( !curve.IsSelected && this._gradientFill.IsGradientValueType )
                                        {
                                            using ( Pen tPen = GetPen( pane, scaleFactor, lastPt ) )
                                            {
                                                if ( this.StepType == StepType.ForwardStep )
                                                {
                                                    g.DrawLine( tPen, lastX, lastY, tmpX, lastY );
                                                    g.DrawLine( tPen, tmpX, lastY, tmpX, tmpY );
                                                }
                                                else if ( this.StepType == StepType.RearwardStep )
                                                {
                                                    g.DrawLine( tPen, lastX, lastY, lastX, tmpY );
                                                    g.DrawLine( tPen, lastX, tmpY, tmpX, tmpY );
                                                }
                                                else 		// non-step
                                                    g.DrawLine( tPen, lastX, lastY, tmpX, tmpY );
                                            }
                                        }
                                        else
                                        {
                                            if ( this.StepType == StepType.ForwardStep )
                                            {
                                                g.DrawLine( pen, lastX, lastY, tmpX, lastY );
                                                g.DrawLine( pen, tmpX, lastY, tmpX, tmpY );
                                            }
                                            else if ( this.StepType == StepType.RearwardStep )
                                            {
                                                g.DrawLine( pen, lastX, lastY, lastX, tmpY );
                                                g.DrawLine( pen, lastX, tmpY, tmpX, tmpY );
                                            }
                                            else 		// non-step
                                                g.DrawLine( pen, lastX, lastY, tmpX, tmpY );
                                        }
                                    }

                                }
                                catch
                                {
                                    InterpolatePoint( g, pane, curve, lastPt, scaleFactor, pen,
                                                lastX, lastY, tmpX, tmpY );
                                }

                            }

                            lastPt = curPt;
                            lastX = tmpX;
                            lastY = tmpY;
                            lastBad = false;
                            lastOut = isOut;
                        }
                    }
                }
            }
        }
Esempio n. 7
0
        // Call this method after calling AxisChange()
        private void CreateBarLabels( GraphPane pane )
        {
            // Make the gap between the bars and the labels = 2% of the axis range
            float labelOffset = (float)( pane.YAxis.Scale.Max - pane.YAxis.Scale.Min ) * 0.02f;

            foreach ( CurveItem curve in pane.CurveList )
            {
                BarItem bar = curve as BarItem;

                if ( bar != null )
                {
                    IPointList points = curve.Points;

                    for ( int i = 0; i < points.Count; i++ )
                    {
                        ValueHandler valueHandler		=
                            new ValueHandler( pane, true );

                        int curveIndex					=
                            pane.CurveList.IndexOf( curve );

                        double labelXCoordintate			=
                            valueHandler.BarCenterValue( bar,
                            bar.GetBarWidth( pane ), i, points[ i ].X,
                            curveIndex );

                        float labelYCoordinate				=
                            ( float ) points[ i ].Y + labelOffset;

                        string barLabelText				=
                            ( points[ i ].Y / 1000 ).ToString( "N2" );

                        TextObj label					=
                            new TextObj( barLabelText, ( float ) labelXCoordintate,
                            labelYCoordinate );

                        label.Location.CoordinateFrame	= CoordType.AxisXYScale;
                        label.FontSpec.Size				= 10;
                        label.FontSpec.FontColor		= Color.Black;
                        label.FontSpec.Angle = 90;
                        label.Location.AlignH			= AlignH.Left;
                        label.Location.AlignV			= AlignV.Center;
                        label.FontSpec.Border.IsVisible	= false;
                        label.FontSpec.Fill.IsVisible	= false;

                        pane.GraphObjList.Add( label );
                    }
                }
            }
        }
Esempio n. 8
0
        /// <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;
                    }
                }
            }
        }
Esempio n. 9
0
        /// <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;
                        }
                    }
                }
            }
        }
Esempio n. 10
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="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 || baseAxis is X2Axis)
                {
                    this.Draw(g, pane, pixSide, pixSide + barWidth, pixLowVal,
                              pixHiVal, scaleFactor, true, curve.IsSelected,
                              curve.Points[index]);
                }
                else
                {
                    this.Draw(g, pane, pixLowVal, pixHiVal, pixSide, pixSide + barWidth,
                              scaleFactor, true, curve.IsSelected,
                              curve.Points[index]);
                }
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Draw this <see cref="CurveItem"/> to the specified <see cref="Graphics"/>
        /// device as a symbol at each defined point.  The routine
        /// only draws the symbols; the lines are draw by the
        /// <see cref="Line.DrawCurve"/> method.  This method
        /// is normally only called by the Draw method of the
        /// <see cref="CurveItem"/> 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="LineItem"/> representing this
        /// curve.</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="isSelected">Indicates that the <see cref="Symbol" /> should be drawn
        /// with attributes from the <see cref="Selection" /> class.
        /// </param>
        public void Draw(Graphics g, GraphPane pane, LineItem curve, float scaleFactor,
                         bool isSelected)
        {
            Symbol source = this;

            if (isSelected)
            {
                source = Selection.Symbol;
            }

            int tmpX, tmpY;

            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;

            // (Dale-a-b) we'll set an element to true when it has been drawn
            bool[,] isPixelDrawn = new bool[maxX + 1, maxY + 1];

            double     curX, curY, lowVal;
            IPointList points = curve.Points;

            if (points != null && (_border.IsVisible || _fill.IsVisible))
            {
                SmoothingMode sModeSave = g.SmoothingMode;
                if (_isAntiAlias)
                {
                    g.SmoothingMode = SmoothingMode.HighQuality;
                }

                // For the sake of speed, go ahead and create a solid brush and a pen
                // If it's a gradient fill, it will be created on the fly for each symbol
                //SolidBrush	brush = new SolidBrush( this.fill.Color );

                using (Pen pen = source._border.GetPen(pane, scaleFactor))
                    using (GraphicsPath path = MakePath(g, scaleFactor))
                    {
                        RectangleF rect = path.GetBounds();

                        using (Brush brush = source.Fill.MakeBrush(rect))
                        {
                            ValueHandler valueHandler = new ValueHandler(pane, false);
                            Scale        xScale       = curve.GetXAxis(pane).Scale;
                            Scale        yScale       = curve.GetYAxis(pane).Scale;

                            bool xIsLog     = xScale.IsLog;
                            bool yIsLog     = yScale.IsLog;
                            bool xIsOrdinal = xScale.IsAnyOrdinal;

                            double xMin = xScale.Min;
                            double xMax = xScale.Max;

                            // Loop over each defined point
                            for (int i = 0; i < points.Count; i++)
                            {
                                if (points[i].Symbol == null && curve.Symbol != this)
                                {
                                    continue;
                                }
                                if (points[i].Symbol != null && (points[i].Symbol != this))
                                {
                                    continue;
                                }

                                // Get the user scale values for the current point
                                // use the valueHandler only for stacked types
                                if (pane.LineType == LineType.Stack)
                                {
                                    valueHandler.GetValues(curve, i, out curX, out lowVal, out curY);
                                }
                                // otherwise, just access the values directly.  Avoiding the valueHandler for
                                // non-stacked types is an optimization to minimize overhead in case there are
                                // a large number of points.
                                else
                                {
                                    curX = points[i].X;
                                    if (curve is StickItem)
                                    {
                                        curY = points[i].Z;
                                    }
                                    else
                                    {
                                        curY = points[i].Y;
                                    }
                                }

                                // 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 (curX != PointPair.Missing &&
                                    curY != PointPair.Missing &&
                                    !System.Double.IsNaN(curX) &&
                                    !System.Double.IsNaN(curY) &&
                                    !System.Double.IsInfinity(curX) &&
                                    !System.Double.IsInfinity(curY) &&
                                    (curX > 0 || !xIsLog) &&
                                    (!yIsLog || curY > 0.0) &&
                                    (xIsOrdinal || (curX >= xMin && curX <= xMax)))
                                {
                                    // Transform the user scale values to pixel locations
                                    tmpX = (int)xScale.Transform(curve.IsOverrideOrdinal, i, curX);
                                    tmpY = (int)yScale.Transform(curve.IsOverrideOrdinal, i, curY);

                                    // Maintain an array of "used" pixel locations to avoid duplicate drawing operations
                                    if (tmpX >= minX && tmpX <= maxX && tmpY >= minY && tmpY <= maxY)                               // guard against the zoom-in case
                                    {
                                        if (isPixelDrawn[tmpX, tmpY])
                                        {
                                            continue;
                                        }
                                        isPixelDrawn[tmpX, tmpY] = true;
                                    }

                                    // If the fill type for this symbol is a Gradient by value type,
                                    // the make a brush corresponding to the appropriate current value
                                    if (_fill.IsGradientValueType || _border._gradientFill.IsGradientValueType)
                                    {
                                        using (Brush tBrush = _fill.MakeBrush(rect, points[i]))
                                            using (Pen tPen = _border.GetPen(pane, scaleFactor, points[i]))
                                                this.DrawSymbol(g, tmpX, tmpY, path, tPen, tBrush);
                                    }
                                    else
                                    {
                                        // Otherwise, the brush is already defined
                                        // Draw the symbol at the specified pixel location
                                        this.DrawSymbol(g, tmpX, tmpY, path, pen, brush);
                                    }
                                }
                            }
                        }
                    }

                g.SmoothingMode = sModeSave;
            }
        }
Esempio n. 12
0
        /// <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);

            // 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 - clusterWidth / 2.0F + clusterGap / 2.0F +
                                pane.CurveList.GetBarItemPos(pane, this) * (barWidth + barGap);

                // Draw the bar
                if (baseAxis is XAxis || baseAxis is X2Axis)
                {
                    coords = String.Format("{0:f0},{1:f0},{2:f0},{3:f0}",
                                           pixSide, pixLowVal,
                                           pixSide + barWidth, pixHiVal);
                }
                else
                {
                    coords = String.Format("{0:f0},{1:f0},{2:f0},{3:f0}",
                                           pixLowVal, pixSide,
                                           pixHiVal, pixSide + barWidth);
                }

                return(true);
            }

            return(false);
        }
Esempio n. 13
0
        /// <summary>
        /// Create a <see cref="TextObj" /> for each bar in the <see cref="GraphPane" />.
        /// </summary>
        /// <remarks>
        /// This method will go through the bars, create a label that corresponds to the bar value,
        /// and place it on the graph depending on user preferences.  This works for horizontal or
        /// vertical bars in clusters or stacks, but only for <see cref="BarItem" /> types.  This method
        /// does not apply to <see cref="ErrorBarItem" /> or <see cref="HiLowBarItem" /> objects.
        /// Call this method only after calling <see cref="GraphPane.AxisChange()" />.
        /// </remarks>
        /// <param name="pane">The GraphPane in which to place the text labels.</param>
        /// <param name="isBarCenter">true to center the labels inside the bars, false to
        /// place the labels just above the top of the bar.</param>
        /// <param name="valueFormat">The double.ToString string format to use for creating
        /// the labels.
        /// </param>
        /// <param name="fontColor">The color in which to draw the labels</param>
        /// <param name="fontFamily">The string name of the font family to use for the labels</param>
        /// <param name="fontSize">The floating point size of the font, in scaled points</param>
        /// <param name="isBold">true for a bold font type, false otherwise</param>
        /// <param name="isItalic">true for an italic font type, false otherwise</param>
        /// <param name="isUnderline">true for an underline font type, false otherwise</param>
        public static void CreateBarLabels(GraphPane pane, bool isBarCenter, string valueFormat,
                                           string fontFamily, float fontSize, Color fontColor, bool isBold, bool isItalic,
                                           bool isUnderline)
        {
            bool isVertical = pane.BarSettings.Base == BarBase.X;

            // keep a count of the number of BarItems
            int curveIndex = 0;

            // Get a valuehandler to do some calculations for us
            ValueHandler valueHandler = new ValueHandler(pane, true);

            // Loop through each curve in the list
            foreach (CurveItem curve in pane.CurveList)
            {
                // work with BarItems only
                BarItem bar = curve as BarItem;
                if (bar != null)
                {
                    IPointList points = curve.Points;

                    // ADD JKB 9/21/07
                    // The labelOffset should depend on whether the curve is YAxis or Y2Axis.
                    // JHC - Generalize to any value axis
                    // Make the gap between the bars and the labels = 1.5% of the axis range
                    float labelOffset;

                    Scale scale = curve.ValueAxis(pane).Scale;
                    labelOffset = (float)(scale._max - scale._min) * 0.015f;

                    // Loop through each point in the BarItem
                    for (int i = 0; i < points.Count; i++)
                    {
                        // Get the high, low and base values for the current bar
                        // note that this method will automatically calculate the "effective"
                        // values if the bar is stacked
                        double baseVal, lowVal, hiVal;
                        valueHandler.GetValues(curve, i, out baseVal, out lowVal, out hiVal);

                        // Get the value that corresponds to the center of the bar base
                        // This method figures out how the bars are positioned within a cluster
                        float centerVal = (float)valueHandler.BarCenterValue(bar,
                                                                             bar.GetBarWidth(pane), i, baseVal, curveIndex);

                        // Create a text label -- note that we have to go back to the original point
                        // data for this, since hiVal and lowVal could be "effective" values from a bar stack
                        string barLabelText = (isVertical ? points[i].Y : points[i].X).ToString(valueFormat);

                        // Calculate the position of the label -- this is either the X or the Y coordinate
                        // depending on whether they are horizontal or vertical bars, respectively
                        float position;
                        if (isBarCenter)
                        {
                            position = (float)(hiVal + lowVal) / 2.0f;
                        }
                        else if (hiVal >= 0)
                        {
                            position = (float)hiVal + labelOffset;
                        }
                        else
                        {
                            position = (float)hiVal - labelOffset;
                        }

                        // Create the new TextObj
                        TextObj label;
                        if (isVertical)
                        {
                            label = new TextObj(barLabelText, centerVal, position);
                        }
                        else
                        {
                            label = new TextObj(barLabelText, position, centerVal);
                        }

                        label.FontSpec.Family = fontFamily;

                        // Configure the TextObj

                        // CHANGE JKB 9/21/07
                        // CoordinateFrame should depend on whether curve is YAxis or Y2Axis.
                        label.Location.CoordinateFrame =
                            (isVertical && curve.IsY2Axis) ? CoordType.AxisXY2Scale : CoordType.AxisXYScale;

                        label.FontSpec.Size        = fontSize;
                        label.FontSpec.FontColor   = fontColor;
                        label.FontSpec.IsItalic    = isItalic;
                        label.FontSpec.IsBold      = isBold;
                        label.FontSpec.IsUnderline = isUnderline;

                        label.FontSpec.Angle  = isVertical ? 90 : 0;
                        label.Location.AlignH = isBarCenter ? AlignH.Center :
                                                (hiVal >= 0 ? AlignH.Left : AlignH.Right);
                        label.Location.AlignV           = AlignV.Center;
                        label.FontSpec.Border.IsVisible = false;
                        label.FontSpec.Fill.IsVisible   = false;

                        // Add the TextObj to the GraphPane
                        pane.GraphObjList.Add(label);
                    }
                    curveIndex++;
                }
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Draw the this <see cref="CurveItem"/> to the specified <see cref="Graphics"/>
        /// device.  The format (stair-step or line) of the curve is
        /// defined by the <see cref="StepType"/> property.  The routine
        /// only draws the line segments; 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
        /// </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 DrawCurve( Graphics g, GraphPane pane,
            CurveItem curve, float scaleFactor)
        {
            Line source = this;
            if ( curve.IsSelected )
                source = Selection.Line;

            // switch to int to optimize drawing speed (per Dale-a-b)
            int	tmpX, tmpY,
                    lastX = int.MaxValue,
                    lastY = int.MaxValue;

            double curX, curY, lowVal;
            PointPair curPt, lastPt = new PointPair();

            bool lastBad = true;
            IPointList points = curve.Points;
            ValueHandler valueHandler = new ValueHandler( pane, false );
            Axis yAxis = curve.GetYAxis( pane );
            Axis xAxis = curve.GetXAxis( pane );

            bool xIsLog = xAxis._scale.IsLog;
            bool yIsLog = yAxis._scale.IsLog;

            // switch to int to optimize drawing speed (per Dale-a-b)
            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;

            using ( Pen pen = source.GetPen( pane, scaleFactor ) )
            {
                if ( points != null && !_color.IsEmpty && this.IsVisible )
                {
                    //bool lastOut = false;
                    bool isOut;

                    bool isOptDraw = _isOptimizedDraw && points.Count > 1000;

                    // (Dale-a-b) we'll set an element to true when it has been drawn
                    bool[,] isPixelDrawn = null;

                    if ( isOptDraw )
                        isPixelDrawn = new bool[maxX + 1, maxY + 1];

                    // Loop over each point in the curve
                    for ( int i = 0; i < points.Count; i++ )
                    {
                        curPt = points[i];
                        if ( pane.LineType == LineType.Stack )
                        {
                            if ( !valueHandler.GetValues( curve, i, out curX, out lowVal, out curY ) )
                            {
                                curX = PointPair.Missing;
                                curY = PointPair.Missing;
                            }
                        }
                        else
                        {
                            curX = curPt.X;
                            curY = curPt.Y;
                        }

                        // 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 ( curX == PointPair.Missing ||
                                curY == PointPair.Missing ||
                                System.Double.IsNaN( curX ) ||
                                System.Double.IsNaN( curY ) ||
                                System.Double.IsInfinity( curX ) ||
                                System.Double.IsInfinity( curY ) ||
                                ( xIsLog && curX <= 0.0 ) ||
                                ( yIsLog && curY <= 0.0 ) )
                        {
                            // If the point is invalid, then make a linebreak only if IsIgnoreMissing is false
                            // LastX and LastY are always the last valid point, so this works out
                            lastBad = lastBad || !pane.IsIgnoreMissing;
                            isOut = true;
                        }
                        else
                        {
                            // Transform the current point from user scale units to
                            // screen coordinates
                            tmpX = (int) xAxis.Scale.Transform( curve.IsOverrideOrdinal, i, curX );
                            tmpY = (int) yAxis.Scale.Transform( curve.IsOverrideOrdinal, i, curY );

                            // Maintain an array of "used" pixel locations to avoid duplicate drawing operations
                            // contributed by Dale-a-b
                            if ( isOptDraw && tmpX >= minX && tmpX <= maxX &&
                                        tmpY >= minY && tmpY <= maxY ) // guard against the zoom-in case
                            {
                                if ( isPixelDrawn[tmpX, tmpY] )
                                    continue;
                                isPixelDrawn[tmpX, tmpY] = true;
                            }

                            isOut = ( tmpX < minX && lastX < minX ) || ( tmpX > maxX && lastX > maxX ) ||
                                ( tmpY < minY && lastY < minY ) || ( tmpY > maxY && lastY > maxY );

                            if ( !lastBad )
                            {
                                try
                                {
                                    // GDI+ plots the data wrong and/or throws an exception for
                                    // outrageous coordinates, so we do a sanity check here
                                    if ( lastX > 5000000 || lastX < -5000000 ||
                                            lastY > 5000000 || lastY < -5000000 ||
                                            tmpX > 5000000 || tmpX < -5000000 ||
                                            tmpY > 5000000 || tmpY < -5000000 )
                                        InterpolatePoint( g, pane, curve, lastPt, scaleFactor, pen,
                                                        lastX, lastY, tmpX, tmpY );
                                    else if ( !isOut )
                                    {
                                        if ( !curve.IsSelected && this._gradientFill.IsGradientValueType )
                                        {
                                            using ( Pen tPen = GetPen( pane, scaleFactor, lastPt ) )
                                            {
                                                if ( this.StepType == StepType.NonStep )
                                                {
                                                    g.DrawLine( tPen, lastX, lastY, tmpX, tmpY );
                                                }
                                                else if ( this.StepType == StepType.ForwardStep )
                                                {
                                                    g.DrawLine( tPen, lastX, lastY, tmpX, lastY );
                                                    g.DrawLine( tPen, tmpX, lastY, tmpX, tmpY );
                                                }
                                                else if ( this.StepType == StepType.RearwardStep )
                                                {
                                                    g.DrawLine( tPen, lastX, lastY, lastX, tmpY );
                                                    g.DrawLine( tPen, lastX, tmpY, tmpX, tmpY );
                                                }
                                                else if ( this.StepType == StepType.ForwardSegment )
                                                {
                                                    g.DrawLine( tPen, lastX, lastY, tmpX, lastY );
                                                }
                                                else
                                                {
                                                    g.DrawLine( tPen, lastX, tmpY, tmpX, tmpY );
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if ( this.StepType == StepType.NonStep )
                                            {
                                                g.DrawLine( pen, lastX, lastY, tmpX, tmpY );
                                            }
                                            else if ( this.StepType == StepType.ForwardStep )
                                            {
                                                g.DrawLine( pen, lastX, lastY, tmpX, lastY );
                                                g.DrawLine( pen, tmpX, lastY, tmpX, tmpY );
                                            }
                                            else if ( this.StepType == StepType.RearwardStep )
                                            {
                                                g.DrawLine( pen, lastX, lastY, lastX, tmpY );
                                                g.DrawLine( pen, lastX, tmpY, tmpX, tmpY );
                                            }
                                            else if ( this.StepType == StepType.ForwardSegment )
                                            {
                                                g.DrawLine( pen, lastX, lastY, tmpX, lastY );
                                            }
                                            else if ( this.StepType == StepType.RearwardSegment )
                                            {
                                                g.DrawLine( pen, lastX, tmpY, tmpX, tmpY );
                                            }
                                        }
                                    }

                                }
                                catch
                                {
                                    InterpolatePoint( g, pane, curve, lastPt, scaleFactor, pen,
                                                lastX, lastY, tmpX, tmpY );
                                }

                            }

                            lastPt = curPt;
                            lastX = tmpX;
                            lastY = tmpY;
                            lastBad = false;
                            //lastOut = isOut;
                        }
                    }
                }
            }
        }
Esempio n. 15
0
        // Call this method only after calling AxisChange()
        private void CreateStackBarLabels( GraphPane graphPane )
        {
            float labelOffset = (float)( 0.02 * ( graphPane.XAxis.Scale.Max - graphPane.XAxis.Scale.Min ) );
            ValueHandler valueHandler = new ValueHandler( graphPane, true );
            int barIndex = -1;

            foreach ( CurveItem curve in graphPane.CurveList )
            {
                if ( curve is BarItem )
                {
                    BarItem bar = curve as BarItem;
                    barIndex++;
                    float barWidth = bar.GetBarWidth( graphPane );

                    IPointList points = bar.Points;

                    for ( int i = 0; i < points.Count; i++ )
                    {
                        double labelYCoordinate = valueHandler.BarCenterValue( bar, barWidth, i, points[i].Y, barIndex );

                        double baseVal, lowVal, hiVal;

                        valueHandler.GetValues( bar, i, out baseVal, out lowVal, out hiVal );

                        float labelXCoordinate = (float)( lowVal + hiVal ) / 2.0f;

                        string barLabelText = ( points[i].X ).ToString( "N2" );

                        TextObj label = new TextObj( barLabelText, (float)labelXCoordinate, (float)labelYCoordinate );

                        label.Location.CoordinateFrame = CoordType.AxisXYScale;
                        label.FontSpec.Size = 10;
                        label.FontSpec.FontColor = Color.Black;
                        label.Location.AlignH = AlignH.Left;
                        label.Location.AlignV = AlignV.Center;
                        label.FontSpec.Border.IsVisible = false;
                        label.FontSpec.Fill.IsVisible = false;

                        graphPane.GraphObjList.Add( label );
                    }
                }
            }
        }
Esempio n. 16
0
        private Point HandlePointValues( Point mousePt )
        {
            int iPt;
            GraphPane pane;
            object nearestObj;

            using ( Graphics g = this.CreateGraphics() )
            {
                if ( _masterPane.FindNearestPaneObject( mousePt,
                    g, out pane, out nearestObj, out iPt ) )
                {
                    if ( nearestObj is CurveItem && iPt >= 0 )
                    {
                        CurveItem curve = (CurveItem)nearestObj;
                        // Provide Callback for User to customize the tooltips
                        if ( this.PointValueEvent != null )
                        {
                            string label = this.PointValueEvent( this, pane, curve, iPt );
                            if ( label != null && label.Length > 0 )
                            {
                                this.SetToolTip(label, mousePt);
                                this.EnableToolTip();
                            }
                            else
                                this.DisableToolTip();
                        }
                        else
                        {
                            if ( curve is PieItem )
                            {
                                this.SetToolTip(((PieItem)curve).Value.ToString(this._pointValueFormat), mousePt);
                            }
                            else
                            {
                                PointPair pt = curve.Points[iPt];

                                if ( pt.Tag is string )
                                    this.SetToolTip((string)pt.Tag, mousePt);
                                else
                                {
                                    double xVal, yVal, lowVal;
                                    ValueHandler valueHandler = new ValueHandler( pane, false );
                                    if ( ( curve is BarItem || curve is ErrorBarItem || curve is HiLowBarItem )
                                            && pane.BarSettings.Base != BarBase.X )
                                        valueHandler.GetValues( curve, iPt, out yVal, out lowVal, out xVal );
                                    else
                                        valueHandler.GetValues( curve, iPt, out xVal, out lowVal, out yVal );

                                    string xStr = MakeValueLabel( curve.GetXAxis( pane ), xVal, iPt,
                                        curve.IsOverrideOrdinal );
                                    string yStr = MakeValueLabel( curve.GetYAxis( pane ), yVal, iPt,
                                        curve.IsOverrideOrdinal );

                                    this.SetToolTip("( " + xStr + ", " + yStr + " )", mousePt);
                                }
                            }

                            this.EnableToolTip();
                        }
                    }
                    else
                        this.DisableToolTip();
                }
                else
                    this.DisableToolTip();
            }
            return mousePt;
        }
Esempio n. 17
0
        private void Form1_Load(object sender, EventArgs e)
        {
            CreateGraph_BasicDate();

            Trace.Listeners.Add(new TextWriterTraceListener( @"myTrace.txt" ) );
            Trace.AutoFlush = true;

            memGraphics.CreateDoubleBuffer(this.CreateGraphics(),
                this.ClientRectangle.Width, this.ClientRectangle.Height);

            #if false	// Multi Y Axis demo
            myPane = new GraphPane( new Rectangle( 10, 10, 10, 10 ),
                "Demonstration of Multi Y Graph",
                "Time, s",
                "Velocity, m/s" );

            // Set the titles and axis labels
            myPane.Y2Axis.Title.Text = "Acceleration, m/s2";

            // Make up some data _points based on the Sine function
            PointPairList vList = new PointPairList();
            PointPairList aList = new PointPairList();
            PointPairList dList = new PointPairList();
            PointPairList eList = new PointPairList();

            for ( int i=0; i<30; i++ )
            {
                double time = (double) i;
                double acceleration = 2.0;
                double velocity = acceleration * time;
                double distance = acceleration * time * time / 2.0;
                double energy = 100.0 * velocity * velocity / 2.0;
                aList.Add( time, acceleration );
                vList.Add( time, velocity );
                eList.Add( time, energy );
                dList.Add( time, distance );
            }

            // Generate a red curve with diamond symbols, and "Velocity" in the _legend
            LineItem myCurve = myPane.AddCurve( "Velocity",
                vList, Color.Red, SymbolType.Diamond );
            // Fill the symbols with white
            myCurve.Symbol.Fill = new Fill( Color.White );

            // Generate a blue curve with circle symbols, and "Acceleration" in the _legend
            myCurve = myPane.AddCurve( "Acceleration",
                aList, Color.Blue, SymbolType.Circle );
            // Fill the symbols with white
            myCurve.Symbol.Fill = new Fill( Color.White );
            // Associate this curve with the Y2 axis
            myCurve.IsY2Axis = true;

            // Generate a green curve with square symbols, and "Distance" in the _legend
            myCurve = myPane.AddCurve( "Distance",
                dList, Color.Green, SymbolType.Square );
            // Fill the symbols with white
            myCurve.Symbol.Fill = new Fill( Color.White );
            // Associate this curve with the second Y axis
            myCurve.YAxisIndex = 1;

            // Generate a Black curve with triangle symbols, and "Energy" in the _legend
            myCurve = myPane.AddCurve( "Energy",
                eList, Color.Black, SymbolType.Triangle );
            // Fill the symbols with white
            myCurve.Symbol.Fill = new Fill( Color.White );
            // Associate this curve with the Y2 axis
            myCurve.IsY2Axis = true;
            // Associate this curve with the second Y2 axis
            myCurve.YAxisIndex = 1;

            // Show the x axis grid
            myPane.XAxis.MajorGrid.IsVisible = true;

            // Make the Y axis scale red
            myPane.YAxis.Scale.FontSpec.FontColor = Color.Red;
            myPane.YAxis.Title.FontSpec.FontColor = Color.Red;
            // turn off the opposite tics so the Y tics don't show up on the Y2 axis
            myPane.YAxis.MajorTic.IsOpposite = false;
            myPane.YAxis.MinorTic.IsOpposite = false;
            // Don't display the Y zero line
            myPane.YAxis.MajorGrid.IsZeroLine = false;
            // Align the Y axis labels so they are flush to the axis
            myPane.YAxis.Scale.Align = AlignP.Inside;
            myPane.YAxis.Scale.Max = 100;

            // Enable the Y2 axis display
            myPane.Y2Axis.IsVisible = true;
            // Make the Y2 axis scale blue
            myPane.Y2Axis.Scale.FontSpec.FontColor = Color.Blue;
            myPane.Y2Axis.Title.FontSpec.FontColor = Color.Blue;
            // turn off the opposite tics so the Y2 tics don't show up on the Y axis
            myPane.Y2Axis.MajorTic.IsOpposite = false;
            myPane.Y2Axis.MinorTic.IsOpposite = false;
            // Display the Y2 axis grid lines
            myPane.Y2Axis.MajorGrid.IsVisible = true;
            // Align the Y2 axis labels so they are flush to the axis
            myPane.Y2Axis.Scale.Align = AlignP.Inside;
            myPane.Y2Axis.Scale.Min = 1.5;
            myPane.Y2Axis.Scale.Max = 3;

            myPane.YAxis.IsVisible = true;
            //myPane.YAxis.IsTic = false;
            myPane.YAxis.MinorTic.IsOutside = false;
            myPane.YAxis.MajorTic.IsCrossOutside = false;
            myPane.YAxis.MinorTic.IsCrossOutside = false;
            myPane.YAxis.MajorTic.IsInside = false;
            myPane.YAxis.MinorTic.IsInside = false;
            myPane.YAxis.MajorTic.IsOpposite = false;
            myPane.YAxis.MinorTic.IsOpposite = false;

            // Create a second Y Axis, green
            YAxis yAxis3b = new YAxis( "Test Axis" );
            myPane.YAxisList.Add( yAxis3b );
            yAxis3b.Scale.FontSpec.FontColor = Color.Brown;
            yAxis3b.Title.FontSpec.FontColor = Color.Brown;
            yAxis3b.Color = Color.Brown;
            yAxis3b.MajorTic.IsOutside = false;
            yAxis3b.MinorTic.IsOutside = false;
            yAxis3b.MajorTic.IsOpposite = false;
            yAxis3b.MinorTic.IsOpposite = false;
            //yAxis3b.IsScaleLabelsInside = true;
            yAxis3b.Title.IsTitleAtCross = false;
            yAxis3b.MajorTic.IsInside = false;
            yAxis3b.MinorTic.IsInside = false;
            yAxis3b.MajorTic.IsOpposite = false;
            yAxis3b.MinorTic.IsOpposite = false;

            // Create a second Y Axis, green
            YAxis yAxis3c = new YAxis( "Test 2 Axis" );
            myPane.YAxisList.Add( yAxis3c );
            yAxis3c.Scale.FontSpec.FontColor = Color.Brown;
            yAxis3c.Title.FontSpec.FontColor = Color.Brown;
            yAxis3c.Color = Color.Brown;
            yAxis3c.MajorTic.IsOutside = false;
            yAxis3c.MinorTic.IsOutside = false;
            yAxis3c.MajorTic.IsOpposite = false;
            yAxis3c.MinorTic.IsOpposite = false;
            //yAxis3c.IsScaleLabelsInside = true;
            yAxis3c.Title.IsTitleAtCross = false;
            yAxis3c.MajorTic.IsInside = false;
            yAxis3c.MinorTic.IsInside = false;
            yAxis3c.MajorTic.IsOpposite = false;
            yAxis3c.MinorTic.IsOpposite = false;

            // Create a second Y Axis, green
            YAxis yAxis3 = new YAxis( "Distance, m" );
            myPane.YAxisList.Add( yAxis3 );
            yAxis3.Scale.FontSpec.FontColor = Color.Green;
            yAxis3.Title.FontSpec.FontColor = Color.Green;
            yAxis3.Color = Color.Green;
            // turn off the opposite tics so the Y2 tics don't show up on the Y axis
            yAxis3.MajorTic.IsInside = false;
            yAxis3.MinorTic.IsInside = false;
            yAxis3.MajorTic.IsOpposite = false;
            yAxis3.MinorTic.IsOpposite = false;
            // Align the Y2 axis labels so they are flush to the axis
            yAxis3.Scale.Align = AlignP.Inside;
            //yAxis3.AxisGap = 0;

            Y2Axis yAxis4 = new Y2Axis( "Energy" );
            yAxis4.IsVisible = true;
            myPane.Y2AxisList.Add( yAxis4 );
            // turn off the opposite tics so the Y2 tics don't show up on the Y axis
            yAxis4.MajorTic.IsInside = false;
            yAxis4.MinorTic.IsInside = false;
            yAxis4.MajorTic.IsOpposite = false;
            yAxis4.MinorTic.IsOpposite = false;
            // Align the Y2 axis labels so they are flush to the axis
            yAxis4.Scale.Align = AlignP.Inside;
            yAxis4.Type = AxisType.Log;
            yAxis4.Scale.Min = 100;

            // Fill the axis background with a gradient
            myPane.Chart.Fill = new Fill( Color.White, Color.LightGoldenrodYellow, 45.0f );
            #endif

            #if false	// SampleMultiPointList Demo
            myPane = new GraphPane( new Rectangle( 10, 10, 10, 10 ),
                "Demo for SampleMultiPointList",
                "Time",
                "Distance Traveled" );
            SetSize();

            SampleMultiPointList myList = new SampleMultiPointList();
            myList.YData = PerfDataType.Distance;

            // note how it does not matter that we created the second list before actually
            // adding the data -- this is because the cloned list shares data with the
            // original
            SampleMultiPointList myList2 = new SampleMultiPointList( myList );
            myList2.YData = PerfDataType.Velocity;

            for ( int i=0; i<20; i++ )
            {
                double time = (double) i;
                double acceleration = 1.0;
                double velocity = acceleration * time;
                double distance = acceleration * time * time / 2.0;
                PerformanceData perfData = new PerformanceData( time, distance, velocity, acceleration );
                myList.Add( perfData );
            }

            myPane.AddCurve( "Distance", myList, Color.Blue );
            myPane.AddCurve( "Velocity", myList2, Color.Red );

            #endif

            #if false	// GradientByZ

            myPane = new GraphPane( new Rectangle( 10, 10, 10, 10 ),
                "Wacky Widget Company\nProduction Report",
                "Time, Days\n(Since Plant Construction Startup)",
                "Widget Production\n(units/hour)" );
            SetSize();

            string[] ystr = { "one", "two", "three", "four", "five" };

            double[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            double[] y = { .1, .2, .3, .4, .5, .4, .3, .2, .1, .2 };
            //double[] y = { 20, 10, 50, 25, 35, 75, 90, 40, 33, 50 };
            double[] z = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 };
            PointPairList list = new PointPairList( x, y, z );

            Color[] colors = { Color.Red, Color.Green, Color.Blue,
                                Color.Yellow, Color.Orange };
            Fill fill = new Fill( colors );
            fill.Type = FillType.GradientByZ;
            fill.RangeMin = 1;
            fill.RangeMax = 5;

            BarItem myBar = myPane.AddBar( "My Bar", list, Color.Tomato );
            myBar.Bar.Fill = fill;
            myPane.XAxis.Type = AxisType.Ordinal;
            //myPane.YAxis.Type = AxisType.Text;
            //myPane.YAxis.TextLabels = ystr;
            //myPane.ClusterScaleWidth = 1;

            //myPane.AxisChange( this.CreateGraphics() );

            #endif

            #if false	// GradientByZ dual bars
            myPane = new GraphPane( new RectangleF(0,0,300,400), "Title", "X Label", "Y Label" );

            double[] xx = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            double[] yy = { 1, 2, 3, 4, 5, 4, 3, 2, 1, 2 };
            double[] yy2 = { 4, 5, 7, 8, 1, 3, 5, 2, 4, 9 };
            double[] zz = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 };
            double[] zz2 = { 5, 1, 4, 2, 3, 4, 2, 1, 5, 5 };
            PointPairList list = new PointPairList( xx, yy, zz );
            PointPairList list2 = new PointPairList( xx, yy2, zz2 );

            Color[] colors = { Color.Red, Color.Green, Color.Blue,
                                 Color.Yellow, Color.Orange };
            Fill fill = new Fill( colors );
            fill.Type = FillType.GradientByZ;
            fill.RangeMin = 1;
            fill.RangeMax = 5;

            BarItem myBar = myPane.AddBar( "My Bar", list, Color.Tomato );
            myBar.Bar.Fill = fill;
            BarItem myBar2 = myPane.AddBar( "My Bar 2", list2, Color.Tomato );
            myBar2.Bar.Fill = fill;
            myPane.XAxis.Type = AxisType.Ordinal;
            myPane.MinBarGap = 0.1f;
            //myPane.MinClusterGap = 0;
            myPane.AxisChange( this.CreateGraphics() );

            #endif

            #if false	// stacked bars

            Random rand = new Random();

            myPane = new GraphPane();
            //			myPane.Title.Text = "My Title";
            //			myPane.XAxis.Title.Text = "X Axis";
            //			myPane.YAxis.Title.Text = "Y Axis";

            PointPairList list1 = new PointPairList();
            PointPairList list2 = new PointPairList();
            PointPairList list3 = new PointPairList();
            PointPairList list4 = new PointPairList();

            for ( int i=1; i<5; i++ )
            {
                double y = (double) i;
                double x1 = 100.0 + rand.NextDouble() * 100.0;
                double x2 = 100.0 + rand.NextDouble() * 100.0;
                double x3 = 100.0 + rand.NextDouble() * 100.0;
                double x4 = 100.0 + rand.NextDouble() * 100.0;

                list1.Add( x1, y );
                list2.Add( x2, y );
                list3.Add( x3, y );
                list4.Add( x4, y );
            }

            BarItem bar1 = myPane.AddBar( "Bar 1", list1, Color.Red );
            BarItem bar2 = myPane.AddBar( "Bar 2", list2, Color.Blue );
            BarItem bar3 = myPane.AddBar( "Bar 3", list3, Color.Green );
            BarItem bar4 = myPane.AddBar( "Bar 4", list4, Color.Beige );

            myPane.BarBase = BarBase.Y;
            myPane.BarType = BarType.Stack;

            myPane.AxisChange( this.CreateGraphics() );

            this.CreateStackBarLabels( myPane );
            #endif

            #if false	// Bars and Dates

            //			Color color = Color.FromArgb( 123, 45, 67, 89 );
            //			HSBColor hsbColor = new HSBColor( color );
            //			Color color2 = hsbColor;

            Random rand = new Random();

            myPane = new GraphPane();
            myPane.Title.Text = "My Title";
            myPane.XAxis.Title.Text = "X Axis";
            myPane.YAxis.Title.Text = "Y Axis";
            //myPane.XAxis.Type = AxisType.Ordinal;
            //myPane.XAxis.Type = AxisType.Date;
            //myPane.ClusterScaleWidth = 0.75 / 1440.0;
            //myPane.XAxis.MinorStep = 1;
            //myPane.XAxis.MinorUnit = DateUnit.Minute;

            PointPairList list1 = new PointPairList();
            PointPairList list2 = new PointPairList();

            for ( int i=1; i<10; i++ )
            {
                //double x = new XDate( 1995, 5, 10, 12, i+1, 0 );
                double x = (double) i;
                double y1 = rand.NextDouble() * 100.0;
                double y2 = rand.NextDouble() * 100.0;

                list1.Add( x-0.25, y1, 0 );
                list2.Add( x+0.17, y2, 0 );
            }

            //myPane.AddCurve( "junk", list1, Color.Green );

            HiLowBarItem bar1 = myPane.AddHiLowBar( "Bar 1", list1, Color.Red );
            //bar1.Bar.Border.IsVisible = false;
            bar1.Bar.Size = 15;
            //bar1.Bar.Fill = new Fill( Color.Red );
            HiLowBarItem bar2 = myPane.AddHiLowBar( "Bar 2", list2, Color.Blue );
            //bar2.Bar.Border.IsVisible = false;
            //bar2.Bar.Fill = new Fill( Color.Blue );
            bar2.Bar.Size = 10;

            MasterPane mPane = new MasterPane();
            mPane.Add( myPane );

            myPane.AxisChange( this.CreateGraphics() );

            //this.CreateBarLabels(mPane);
            #endif

            #if false	// bar test with no gap
            myPane = new GraphPane( new Rectangle( 40, 40, 600, 300 ),
                "Score Report", "", "" );
            // Make up some random data points
            string[] labels = { "" };
            double[] y = { 800, 900 };
            double[] y2 = { 500 };

            // Generate a red bar with "Curve 1" in the legend
            BarItem myBar = myPane.AddBar( null, y, null, Color.RoyalBlue );

            // Generate a blue bar with "Curve 2" in the legend
            myBar = myPane.AddBar( null, y2, null, Color.Red );

            // Draw the X tics between the labels instead of at the labels
            myPane.YAxis.IsTicsBetweenLabels = true;

            // Set the XAxis labels
            myPane.YAxis.TextLabels = labels;
            // Set the XAxis to Text type
            myPane.YAxis.Type = AxisType.Text;
            // Fill the Axis and Pane backgrounds
            myPane.Chart.Fill = new Fill( Color.White,
                Color.FromArgb( 255, 255, 166), 90F );
            myPane.PaneFill = new Fill( Color.FromArgb( 250, 250, 255) );

            myPane.BarBase = BarBase.Y;

            myPane.MinBarGap = 0;
            myPane.MinClusterGap = 1;

            // Tell ZedGraph to refigure the
            // axes since the data have changed
            myPane.AxisChange( CreateGraphics() );
            #endif

            #if false	// Standard Sample Graph
            myPane = new GraphPane( new Rectangle( 10, 10, 10, 10 ),
                "Wacky Widget Company\nProduction Report",
                "Time, Days\n(Since Plant Construction Startup)",
                "Widget Production\n(units/hour)" );
            SetSize();

            // Set the titles and axis labels
            myPane.Title.Text = "Wacky Widget Company\nProduction Report";
            myPane.XAxis.Title.Text = "Time, Days\n(Since Plant Construction Startup)";
            myPane.YAxis.Title.Text = "Widget Production\n(units/hour)";

            LineItem curve;

            // Set up curve "Larry"
            double[] x = { 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 };
            double[] y = { 20, 10, 50, 25, 35, 75, 90, 40, 33, 50 };
            // Use green, with circle symbols
            curve = myPane.AddCurve( "Larry", x, y, Color.Green, SymbolType.Circle );
            curve.Line.Width = 1.5F;
            // Fill the area under the curve with a white-green gradient
            curve.Line.Fill = new Fill( Color.White, Color.FromArgb( 60, 190, 50), 90F );
            // Make it a smooth line
            curve.Line.IsSmooth = true;
            curve.Line.SmoothTension = 0.6F;
            // Fill the symbols with white
            curve.Symbol.Fill = new Fill( Color.White );
            curve.Symbol.Size = 10;

            // Second curve is "moe"
            double[] x3 = { 150, 250, 400, 520, 780, 940 };
            double[] y3 = { 5.2, 49.0, 33.8, 88.57, 99.9, 36.8 };
            // Use a red color with triangle symbols
            curve = myPane.AddCurve( "Moe", x3, y3, Color.FromArgb( 200, 55, 135), SymbolType.Triangle );
            curve.Line.Width = 1.5F;
            // Fill the area under the curve with semi-transparent pink using the alpha value
            curve.Line.Fill = new Fill( Color.White, Color.FromArgb( 160, 230, 145, 205), 90F );
            // Fill the symbols with white
            curve.Symbol.Fill = new Fill( Color.White );
            curve.Symbol.Size = 10;

            // Third Curve is a bar, called "Wheezy"
            double[] x4 = { 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 };
            double[] y4 = { 30, 45, 53, 60, 75, 83, 84, 79, 71, 57 };
            BarItem bar = myPane.AddBar( "Wheezy", x4, y4, Color.SteelBlue );
            // Fill the bars with a RosyBrown-White-RosyBrown gradient
            bar.Bar.Fill = new Fill( Color.RosyBrown, Color.White, Color.RosyBrown );

            // Fourth curve is a bar
            double[] x2 = { 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 };
            double[] y2 = { 10, 15, 17, 20, 25, 27, 29, 26, 24, 18 };
            bar = myPane.AddBar( "Curly", x2, y2, Color.RoyalBlue );
            // Fill the bars with a RoyalBlue-White-RoyalBlue gradient
            bar.Bar.Fill = new Fill( Color.RoyalBlue, Color.White, Color.RoyalBlue );

            // Fill the pane background with a gradient
            myPane.PaneFill = new Fill( Color.WhiteSmoke, Color.Lavender, 0F );
            // Fill the axis background with a gradient
            myPane.Chart.Fill = new Fill( Color.FromArgb( 255, 255, 245),
                Color.FromArgb( 255, 255, 190), 90F );

            // Make each cluster 100 user scale units wide.  This is needed because the X Axis
            // type is Linear rather than Text or Ordinal
            myPane.ClusterScaleWidth = 100;
            // Bars are stacked
            myPane.BarType = BarType.Stack;

            // Enable the X and Y axis grids
            myPane.XAxis.IsShowGrid = true;
            myPane.YAxis.IsShowGrid = true;

            // Manually set the scale maximums according to user preference
            myPane.XAxis.Max = 1200;
            myPane.YAxis.Max = 120;

            // Add a text item to decorate the graph
            TextItem text = new TextItem("First Prod\n21-Oct-93", 175F, 80.0F );
            // Align the text such that the Bottom-Center is at (175, 80) in user scale coordinates
            text.Location.AlignH = AlignH.Center;
            text.Location.AlignV = AlignV.Bottom;
            text.FontSpec.Fill = new Fill( Color.White, Color.PowderBlue, 45F );
            text.FontSpec.StringAlignment = StringAlignment.Near;
            myPane.GraphItemList.Add( text );

            // Add an arrow pointer for the above text item
            ArrowItem arrow = new ArrowItem( Color.Black, 12F, 175F, 77F, 100F, 45F );
            arrow.Location.CoordinateFrame = CoordType.AxisXYScale;
            myPane.GraphItemList.Add( arrow );

            // Add a another text item to to point out a graph feature
            text = new TextItem("Upgrade", 700F, 50.0F );
            // rotate the text 90 degrees
            text.FontSpec.Angle = 90;
            // Align the text such that the Right-Center is at (700, 50) in user scale coordinates
            text.Location.AlignH = AlignH.Right;
            text.Location.AlignV = AlignV.Center;
            // Disable the border and background fill options for the text
            text.FontSpec.Fill.IsVisible = false;
            text.FontSpec.Border.IsVisible = false;
            myPane.GraphItemList.Add( text );

            // Add an arrow pointer for the above text item
            arrow = new ArrowItem( Color.Black, 15, 700, 53, 700, 80 );
            arrow.Location.CoordinateFrame = CoordType.AxisXYScale;
            arrow.PenWidth = 2.0F;
            myPane.GraphItemList.Add( arrow );

            // Add a text "Confidential" stamp to the graph
            text = new TextItem("Confidential", 0.85F, -0.03F );
            // use AxisFraction coordinates so the text is placed relative to the ChartRect
            text.Location.CoordinateFrame = CoordType.AxisFraction;
            // rotate the text 15 degrees
            text.FontSpec.Angle = 15.0F;
            // Text will be red, bold, and 16 point
            text.FontSpec.FontColor = Color.Red;
            text.FontSpec.IsBold = true;
            text.FontSpec.Size = 16;
            // Disable the border and background fill options for the text
            text.FontSpec.Border.IsVisible = false;
            text.FontSpec.Fill.IsVisible = false;
            // Align the text such the the Left-Bottom corner is at the specified coordinates
            text.Location.AlignH = AlignH.Left;
            text.Location.AlignV = AlignV.Bottom;
            myPane.GraphItemList.Add( text );

            // Add a BoxItem to show a colored band behind the graph data
            BoxItem box = new BoxItem( new RectangleF( 0, 110, 1200, 10 ),
                Color.Empty, Color.FromArgb( 225, 245, 225) );
            box.Location.CoordinateFrame = CoordType.AxisXYScale;
            // Align the left-top of the box to (0, 110)
            box.Location.AlignH = AlignH.Left;
            box.Location.AlignV = AlignV.Top;
            // place the box behind the axis items, so the grid is drawn on top of it
            box.ZOrder = ZOrder.E_BehindAxis;
            myPane.GraphItemList.Add( box );

            // Add some text inside the above box to indicate "Peak Range"
            TextItem myText = new TextItem( "Peak Range", 1170, 105 );
            myText.Location.CoordinateFrame = CoordType.AxisXYScale;
            myText.Location.AlignH = AlignH.Right;
            myText.Location.AlignV = AlignV.Center;
            myText.FontSpec.IsItalic = true;
            myText.FontSpec.IsBold = false;
            myText.FontSpec.Fill.IsVisible = false;
            myText.FontSpec.Border.IsVisible = false;
            myPane.GraphItemList.Add( myText );

            // Calculate the Axis Scale Ranges
            Graphics g = this.CreateGraphics();
            myPane.AxisChange( g );
            g.Dispose();
            #endif

            #if false	// MasterPane
            master = new MasterPane( "ZedGraph MasterPane Example", new Rectangle( 10, 10, 10, 10 ) );

            master.PaneFill = new Fill( Color.White, Color.MediumSlateBlue, 45.0F );
            //master.IsShowTitle = true;

            //master.MarginAll = 10;
            //master.InnerPaneGap = 10;
            //master.Legend.IsVisible = true;
            //master.Legend.Position = LegendPos.TopCenter;

            /*
            TextItem text = new TextItem( "Priority", 0.88F, 0.12F );
            text.Location.CoordinateFrame = CoordType.PaneFraction;

            text.FontSpec.Angle = 15.0F;
            text.FontSpec.FontColor = Color.Red;
            text.FontSpec.IsBold = true;
            text.FontSpec.Size = 16;
            text.FontSpec.Border.IsVisible = false;
            text.FontSpec.Border.Color = Color.Red;
            text.FontSpec.Fill.IsVisible = false;

            text.Location.AlignH = AlignH.Left;
            text.Location.AlignV = AlignV.Bottom;
            master.GraphItemList.Add( text );

            text = new TextItem("DRAFT", 0.5F, 0.5F );
            text.Location.CoordinateFrame = CoordType.PaneFraction;

            text.FontSpec.Angle = 30.0F;
            text.FontSpec.FontColor = Color.FromArgb( 70, 255, 100, 100 );
            text.FontSpec.IsBold = true;
            text.FontSpec.Size = 100;
            text.FontSpec.Border.IsVisible = false;
            text.FontSpec.Fill.IsVisible = false;

            text.Location.AlignH = AlignH.Center;
            text.Location.AlignV = AlignV.Center;
            text.ZOrder = ZOrder.A_InFront;

            master.GraphItemList.Add( text );
            */
            ColorSymbolRotator rotator = new ColorSymbolRotator();

            for ( int j=0; j<6; j++ )
            {
                // Create a new graph with topLeft at (40,40) and size 600x400
                GraphPane myPaneT = new GraphPane( new Rectangle( 40, 40, 600, 400 ),
                    "Case #" + (j+1).ToString(),
                    "Time, Days",
                    "Rate, m/s" );

                myPaneT.PaneFill = new Fill( Color.White, Color.LightYellow, 45.0F );
                myPaneT.BaseDimension = 6.0F;

                // Make up some data arrays based on the Sine function
                double x, y;
                PointPairList list = new PointPairList();
                for ( int i=0; i<36; i++ )
                {
                    x = (double) i + 5;
                    y = 3.0 * ( 1.5 + Math.Sin( (double) i * 0.2 + (double) j ) );
                    list.Add( x, y );
                }

                LineItem myCurve = myPaneT.AddCurve( "Type " + j.ToString(),
                    list, rotator.NextColor, rotator.NextSymbol );
                myCurve.Symbol.Fill = new Fill( Color.White );

                master.Add( myPaneT );
            }

            myPane = master[0];

            Graphics g = this.CreateGraphics();

            //master.AutoPaneLayout( g, PaneLayout.ExplicitRow32 );
            //master.AutoPaneLayout( g, 2, 4 );
            master.AutoPaneLayout( g, false, new int[] { 1, 3, 2 }, new float[] { 2, 1, 3 } );
            master.AxisChange( g );

            g.Dispose();
            #endif

            #if false	// MasterPane - Single Pane
            master = new MasterPane( "ZedGraph MasterPane Single Pane Example", new Rectangle( 10, 10, 10, 10 ) );

            master.Fill = new Fill( Color.White, Color.MediumSlateBlue, 45.0F );

            // Create a new graph with topLeft at (40,40) and size 600x400
            GraphPane myPaneT = new GraphPane( new Rectangle( 40, 40, 600, 400 ),
                "Case 1",
                "Time, Days",
                "Rate, m/s" );

            myPaneT.Fill = new Fill( Color.White, Color.LightYellow, 45.0F );
            myPaneT.BaseDimension = 6.0F;

            // Make up some data arrays based on the Sine function
            double x, y;
            PointPairList list = new PointPairList();
            for ( int i=0; i<36; i++ )
            {
                x = (double) i + 5;
                y = 3.0 * ( 1.5 + Math.Sin( (double) i * 0.2 ) );
                list.Add( x, y );
            }

            LineItem myCurve = myPaneT.AddCurve( "Type 1",
                list, Color.Blue, SymbolType.Circle );
            myCurve.Symbol.Fill = new Fill( Color.White );

            master.Add( myPaneT );

            Graphics g = this.CreateGraphics();

            master.Title.IsVisible = false;
            master.Margin.All = 0;
            //master.AutoPaneLayout( g, PaneLayout.ExplicitRow32 );
            //master.AutoPaneLayout( g, 2, 4 );
            master.AutoPaneLayout( g );
            //master.AutoPaneLayout( g, false, new int[] { 1, 3, 2 }, new float[] { 2, 1, 3 } );
            master.AxisChange( g );

            g.Dispose();
            #endif

            #if false	// Pie
            myPane = new GraphPane( new Rectangle( 10, 10, 10, 10 ),
                "2004 ZedGraph Sales by Region\n($M)",
                "",
                "" );

            myPane.FontSpec.IsItalic = true;
            myPane.FontSpec.Size = 24f;
            myPane.FontSpec.Family = "Times";
            myPane.PaneFill = new Fill( Color.White, Color.Goldenrod, 45.0f );
            myPane.Chart.Fill.Type = FillType.None;
            myPane.Legend.Position = LegendPos.Float ;
            myPane.Legend.Location = new Location( 0.95f, 0.15f, CoordType.PaneFraction,
                                AlignH.Right, AlignV.Top );
            myPane.Legend.FontSpec.Size = 10f;
            myPane.Legend.IsHStack = false;

            PieItem segment1 = myPane.AddPieSlice( 20, Color.Navy, Color.White, 45f, 0, "North" );
            PieItem segment3 = myPane.AddPieSlice( 30, Color.Purple, Color.White, 45f, .0, "East" );
            PieItem segment4 = myPane.AddPieSlice( 10.21, Color.LimeGreen, Color.White, 45f, 0, "West" );
            PieItem segment2 = myPane.AddPieSlice( 40, Color.SandyBrown, Color.White, 45f, 0.2, "South" );
            PieItem segment6 = myPane.AddPieSlice( 250, Color.Red, Color.White, 45f, 0, "Europe" );
            PieItem segment7 = myPane.AddPieSlice( 50, Color.Blue, Color.White, 45f, 0.2, "Pac Rim" );
            PieItem segment8 = myPane.AddPieSlice( 400, Color.Green, Color.White, 45f, 0, "South America" );
            PieItem segment9 = myPane.AddPieSlice( 50, Color.Yellow, Color.White, 45f, 0.2, "Africa" );

            segment2.LabelDetail.FontSpec.FontColor = Color.Red ;

            CurveList curves = myPane.CurveList ;
            double total = 0 ;
            for ( int x = 0 ; x <  curves.Count ; x++ )
                total += ((PieItem)curves[x]).Value ;

            TextItem text = new TextItem( "Total 2004 Sales\n" + "$" + total.ToString () + "M",
                                0.18F, 0.40F, CoordType.PaneFraction );
            text.Location.AlignH = AlignH.Center;
            text.Location.AlignV = AlignV.Bottom;
            text.FontSpec.Border.IsVisible = false ;
            text.FontSpec.Fill = new Fill( Color.White, Color.FromArgb( 255, 100, 100 ), 45F );
            text.FontSpec.StringAlignment = StringAlignment.Center ;
            myPane.GraphItemList.Add( text );

            TextItem text2 = new TextItem( text );
            text2.FontSpec.Fill = new Fill( Color.Black );
            text2.Location.X += 0.008f;
            text2.Location.Y += 0.01f;
            myPane.GraphItemList.Add( text2 );

            myPane.AxisChange( this.CreateGraphics() );
            #endif

            #if false	// simple pie
            myPane = new GraphPane( new Rectangle( 10, 10, 10, 10 ),
                "People Signed Up",
                "",
                "" );
            // Create some pie slices
            PieItem segment1 = myPane.AddPieSlice(8, Color.Green, .3, "Signed Up");
            PieItem segment2 = myPane.AddPieSlice(5,Color.Red, 0.0, "Still Needed");

            //segment1.FontSpec = new FontSpec("GenericSansSerif", 35, Color.Black, true, false, false);
            // Sum up the values
            CurveList curves = myPane.CurveList;
            double total = 0;
            for (int x = 0; x < curves.Count; x++)
                total += ((PieItem)curves[x]).Value;

            myPane.PaneBorder.IsVisible = false;
            myPane.Legend.Border.IsVisible = false;
            myPane.Legend.Position = LegendPos.TopCenter;

            //			ArrowItem arrow = new ArrowItem( (float) new XDate(2007,1,1), 0, (float) new XDate(2007,1,1), 50 );

            #endif

            #if false	// Commerical Sales Graph
            myPane = new GraphPane( new RectangleF(0,0,10,10),
                        "Sales Growth Compared to\nActual Sales by Store Size - Rank Order Low to High",
                        "", "" );
            myPane.MarginAll = 20;
            myPane.FontSpec.Size = 10;
            myPane.Legend.Position = LegendPos.BottomCenter;
            myPane.Legend.FontSpec.Size = 7;

            Random rand = new Random();
            double y1 = 184;
            PointPairList list1 = new PointPairList();
            PointPairList list2 = new PointPairList();
            PointPairList trendList = new PointPairList();
            PointPairList projList = new PointPairList();
            string[] labels = new string[26];

            for ( int i=0; i<26; i++ )
            {
                double h1 = rand.NextDouble() * 10 - 2;
                double h2 = rand.NextDouble() * 10 - 2;
                double h3 = rand.NextDouble() * 8;
                double y2 = y1 + ( rand.NextDouble() * 2 - 1 );

                trendList.Add( i + 1.0 - 0.2, y1 );
                trendList.Add( i + 1.0 + 0.2, y2 );
                list1.Add( (double) i, y1+h1, y1 );
                list2.Add( (double) i, y2+h2, y2 );
                projList.Add( (double) i + 1.0 - 0.35, y1 + h3 );
                projList.Add( (double) i + 1.0 + 0.35, y1 + h3 );
                projList.Add( PointPair.Missing, PointPair.Missing );

                labels[i] = "Store " + (i+1).ToString();

                y1 += rand.NextDouble() * 4.0;
            }

            PointPairList minTargList = new PointPairList();
            minTargList.Add( 0.7, 218 );
            minTargList.Add( 26.3, 218 );
            PointPairList prefTargList = new PointPairList();
            prefTargList.Add( 0.7, 228 );
            prefTargList.Add( 26.3, 228 );

            LineItem minCurve = myPane.AddCurve("Minimum Target", minTargList, Color.Green, SymbolType.None );
            minCurve.Line.Width = 3.0f;
            minCurve.IsOverrideOrdinal = true;
            LineItem prefCurve = myPane.AddCurve("Preferred Target", prefTargList, Color.Blue, SymbolType.None );
            prefCurve.Line.Width = 3.0f;
            prefCurve.IsOverrideOrdinal = true;

            LineItem projCurve = myPane.AddCurve( "Projected Sales", projList, Color.Orange, SymbolType.None );
            projCurve.IsOverrideOrdinal = true;
            projCurve.Line.Width = 3.0f;

            LineItem myCurve = myPane.AddCurve( "Trendline", trendList,
                            Color.FromArgb( 50, 50, 50 ), SymbolType.None );
            myCurve.Line.Width = 2.5f;
            myCurve.Line.IsSmooth = true;
            myCurve.Line.SmoothTension = 0.3f;
            myCurve.IsOverrideOrdinal = true;

            BarItem myBar = myPane.AddBar( "Store Growth", list1, Color.Black );
            //myBar.Bar.Fill = new Fill( Color.Black );
            BarItem myBar2 = myPane.AddBar( "Average Growth", list2, Color.LightGray );
            //myBar2.Bar.Fill = new Fill( Color.LightGray );

            myPane.XAxis.Type = AxisType.Text;
            myPane.XAxis.TextLabels = labels;
            myPane.XAxis.Scale.FontSpec.Angle = -90;
            myPane.XAxis.Scale.FontSpec.Size = 8;
            myPane.XAxis.Scale.FontSpec.IsBold = true;
            myPane.XAxis.IsTicsBetweenLabels = true;
            myPane.XAxis.IsInsideTic = false;
            myPane.XAxis.IsOppositeTic = false;
            myPane.XAxis.IsMinorInsideTic = false;
            myPane.XAxis.IsMinorOppositeTic = false;

            myPane.YAxis.Scale.FontSpec.Size = 8;
            myPane.YAxis.Scale.FontSpec.IsBold = true;
            myPane.YAxis.IsShowGrid = true;
            myPane.YAxis.GridDashOn = 1.0f;
            myPane.YAxis.GridDashOff = 0.0f;

            myPane.BarType = BarType.ClusterHiLow;

            myPane.AxisChange( this.CreateGraphics() );
            myPane.YAxis.MinorStep = myPane.YAxis.Step;

            #endif

            #if false	// Basic curve test - Images as symbols
            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            PointPairList list = new PointPairList();

            for ( int i=0; i<10; i++ )
            {
                double x = (double) i;
                double y = Math.Sin( x / 8.0 );
                list.Add( x, y );
            }

            LineItem myCurve = myPane.AddCurve( "curve", list, Color.Blue, SymbolType.Diamond );

            Bitmap bm = new Bitmap( @"c:\windows\winnt256.bmp" );
            Image image = Image.FromHbitmap( bm.GetHbitmap() );

            myCurve.Line.IsVisible = false;
            myCurve.Symbol.Type = SymbolType.Square;
            myCurve.Symbol.Size = 16;
            myCurve.Symbol.Border.IsVisible = false;
            myCurve.Symbol.Fill = new Fill( image, WrapMode.Clamp );

            myPane.AxisChange( this.CreateGraphics() );

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 359;
            trackBar1.Value = 0;

            #endif

            #if false	// Stick Item Test
            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            PointPairList list = new PointPairList();
            for ( int i=0; i<100; i++ )
            {
                double x = (double) i;
                double y = Math.Sin( i / 8.0 );
                double z = Math.Abs(Math.Cos( i / 8.0 )) * y;
                list.Add( x, y, z );
            }

            StickItem myCurve = myPane.AddStick( "curve", list, Color.Blue );
            myCurve.Line.Width = 2.0f;
            myPane.XAxis.IsShowGrid = true;
            myPane.XAxis.Max = 100;

            myPane.AxisChange( this.CreateGraphics() );

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 359;
            trackBar1.Value = 0;

            #endif

            #if false	// Basic curve test - Dual Y axes

            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            myPane.Y2Axis.Title.Text = "My Y2 Axis";

            PointPairList list = new PointPairList();
            PointPairList list2 = new PointPairList();

            for ( int i=0; i<100; i++ )
            {
                double x = (double) i;
                double y = Math.Sin( i / 8.0 ) * 100000 + 150000;
                double y2 = Math.Sin( i / 3.0 ) * 300 - 400;
                list.Add( x, y );
                list2.Add( x, y2 );
                //double z = Math.Abs( Math.Cos( i / 8.0 ) ) * y;
            }

            LineItem myCurve = myPane.AddCurve( "curve", list, Color.Blue, SymbolType.Diamond );
            LineItem myCurve2 = myPane.AddCurve( "curve2", list2, Color.Red, SymbolType.Diamond );
            myCurve2.IsY2Axis = true;

            myPane.Y2Axis.IsVisible = true;

            AlignYZeroLines( myPane, 12 );
            myPane.YAxis.IsMinorOppositeTic = false;
            myPane.Y2Axis.IsMinorOppositeTic = false;

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;

            #endif

            #if false	// Basic curve test - Multi-Y axes

            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            myPane.AddYAxis( "Another Y Axis" );
            myPane.AddY2Axis( "Another Y2 Axis" );
            myPane.Y2Axis.Title.Text = "My Y2 Axis";
            myPane.Y2AxisList[0].IsVisible = true;
            myPane.Y2AxisList[1].IsVisible = true;

            PointPairList list = new PointPairList();

            for ( int i=0; i<100; i++ )
            {
                //double x = (double) i;
                double x = new XDate( 2001, 1, i*3 );
                double y = Math.Sin( i / 8.0 ) * 100000 + 100001;
                list.Add( x, y );
                double z = Math.Abs( Math.Cos( i / 8.0 ) ) * y;
            }

            LineItem myCurve = myPane.AddCurve( "curve", list, Color.Blue, SymbolType.Diamond );

            myCurve.YAxisIndex = 1;

            myPane.XAxis.IsSkipLastLabel = false;
            myPane.XAxis.Type = AxisType.DateAsOrdinal;
            myPane.AxisChange( this.CreateGraphics() );

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;

            #endif

            #if false	// Basic curve test - Date Axis w/ Time Span

            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            PointPairList list = new PointPairList();

            for ( int i=0; i<100; i++ )
            {
                double x = (double) i/123.0;
                //double x = new XDate( 0, 0, i, i*3, i*2, i );
                double y = Math.Sin( i / 8.0 ) * 1 + 1;
                list.Add( x, y );
                double z = Math.Abs( Math.Cos( i / 8.0 ) ) * y;
            }

            LineItem myCurve = myPane.AddCurve( "curve", list, Color.Blue, SymbolType.Diamond );

            myPane.XAxis.IsSkipLastLabel = false;
            //myPane.XAxis.IsPreventLabelOverlap = false;
            myPane.XAxis.ScaleFormat = "[d].[h]:[m]:[s]";
            myPane.XAxis.Type = AxisType.Date;
            myPane.AxisChange( this.CreateGraphics() );

            myPane.YAxis.ScaleFormat = "0.0'%'";
            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;

            myPane.PaneFill = new Fill( Color.FromArgb( 100, Color.Blue ), Color.FromArgb( 100, Color.White ), 45.0f );

            #endif

            #if false	// Basic curve test - DateAsOrdinal

            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            PointPairList list = new PointPairList();

            for ( int i=0; i<100; i++ )
            {
                //double x = (double) i;
                double x = new XDate( 2001, 1, i*3 );
                double y = Math.Sin( i / 8.0 ) * 100000 + 100001;
                list.Add( x, y );
                double z = Math.Abs( Math.Cos( i / 8.0 ) ) * y;
            }

            LineItem myCurve = myPane.AddCurve( "curve", list, Color.Blue, SymbolType.Diamond );

            myPane.XAxis.IsSkipLastLabel = false;
            myPane.XAxis.IsPreventLabelOverlap = false;
            myPane.XAxis.ScaleFormat = ZedGraph.Axis.Default.FormatDayDay;
            myPane.XAxis.Type = AxisType.DateAsOrdinal;
            myPane.AxisChange( this.CreateGraphics() );

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;

            #endif

            #if false	// Basic curve test - Linear Axis

            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            PointPairList list = new PointPairList();

            for ( int i=0; i<20; i++ )
            {
                double x = (double) i;
                double y = Math.Sin( x / 8.0 );
                double z = Math.Abs(Math.Cos( i / 8.0 )) * y;

                list.Add( x, y, z );
            }

            LineItem myCurve = myPane.AddCurve( "curve", list, Color.Blue, SymbolType.Diamond );

            //myPane.XAxis.Min = 1;
            //myPane.XAxis.Max = 100;
            //myPane.XAxis.IsReverse = true;
            //myPane.XAxis.Type = AxisType.Log;

            //RectangleF rect = new RectangleF( 3, 0.7, 8, 0.2 );
            myPane.AxisChange( this.CreateGraphics() );

            BoxItem m_selectionBox = new BoxItem(); // rect );
            m_selectionBox.Border.Color = Color.Orange;
            m_selectionBox.Border.IsVisible = true;
            m_selectionBox.Fill.Color = Color.LightYellow;
            m_selectionBox.Fill.Type = FillType.Solid;
            m_selectionBox.Fill.RangeMin = 1.0;
            m_selectionBox.Fill.RangeMax = 1.0;
            m_selectionBox.Fill.IsVisible = true;

            m_selectionBox.Location = new Location(
                (float)3,
                (float)myPane.YAxis.Max,
                (float)(8 - 3),
                (float)myPane.YAxis.Max - (float)myPane.YAxis.Min,
                CoordType.AxisXYScale,
                AlignH.Left,
                AlignV.Top);

            m_selectionBox.IsClippedToChartRect = true;
            m_selectionBox.ZOrder = ZOrder.E_BehindAxis;
            m_selectionBox.IsVisible = true;

            myPane.GraphItemList.Add( m_selectionBox );

            #endif

            #if false	// Box and Whisker diagram

            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            // Throw some data points on the chart for good looks
            PointPairList list = new PointPairList();
            for ( int i=0; i<20; i++ )
            {
                double x = (double) i * 5;
                double y = Math.Sin( x / 8.0 );
                list.Add( x, y );
            }
            LineItem myCurve = myPane.AddCurve( "curve", list, Color.Blue, SymbolType.Diamond );
            myCurve.Line.IsVisible = false;

            // Horizontal box and whisker chart
            // yval is the vertical position of the box & whisker
            double yval = 0.3;
            // pct5 = 5th percentile value
            double pct5 = 5;
            // pct25 = 25th percentile value
            double pct25 = 40;
            // median = median value
            double median = 55;
            // pct75 = 75th percentile value
            double pct75 = 80;
            // pct95 = 95th percentile value
            double pct95 = 95;

            // Draw the box
            PointPairList list2 = new PointPairList();
            list2.Add( pct25, yval, median );
            list2.Add( median, yval, pct75 );
            HiLowBarItem myBar = myPane.AddHiLowBar( "box", list2, Color.Black );
            // set the size of the box (in points, scaled to graph size)
            myBar.Bar.Size = 20;
            myBar.Bar.Fill.IsVisible = false;
            myPane.BarBase = BarBase.Y;

            // Draw the whiskers
            double[] xwhisk = { pct5, pct25, PointPair.Missing, pct75, pct95 };
            double[] ywhisk = { yval, yval, yval, yval, yval };
            PointPairList list3 = new PointPairList();
            list3.Add( xwhisk, ywhisk );
            LineItem mywhisk = myPane.AddCurve( "whisker", list3, Color.Black, SymbolType.None );

            myPane.AxisChange( this.CreateGraphics() );

            #endif

            #if false	// Basic curve test - Linear Axis with Many Points

            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            PointPairList list = new PointPairList();

            for ( int i=0; i<100000; i++ )
            {
                double x = (double) i;
                double y = Math.Sin( x / 8.0 );
                double z = Math.Abs(Math.Cos( i / 8.0 )) * y;

                list.Add( x, y, z );
            }

            LineItem myCurve = myPane.AddCurve( "curve", list, Color.Blue, SymbolType.HDash );
            myCurve.Symbol.IsVisible = false;
            //myPane.XAxis.Min = 1;
            //myPane.XAxis.Max = 100;
            //myPane.XAxis.IsReverse = true;
            //myPane.XAxis.Type = AxisType.Log;

            //RectangleF rect = new RectangleF( 3, 0.7, 8, 0.2 );
            Graphics g = this.CreateGraphics();
            myPane.AxisChange( g );
            SetSize();

            int startTick = Environment.TickCount;

            myPane.Draw( g );

            int endTick = Environment.TickCount;

            MessageBox.Show( "ticks = " + ( endTick - startTick ).ToString() );
            #endif

            #if false	// Gantt Chart
            myPane = new GraphPane();

            myPane.Title.Text = "Gantt Chart";
            myPane.XAxis.Title.Text = "Date";
            myPane.YAxis.Title.Text = "Project";

            myPane.XAxis.Type = AxisType.Date;
            myPane.YAxis.Type = AxisType.Text;
            myPane.BarBase = BarBase.Y;

            string[] labels = { "Project 1", "Project 2" };
            myPane.YAxis.TextLabels = labels;
            myPane.YAxis.IsTicsBetweenLabels = true;

            // First, define all the bars that you want to be red
            PointPairList ppl = new PointPairList();
            XDate start = new XDate( 2005, 10, 31 );
            XDate end = new XDate( 2005, 11, 15 );
            // x is start of bar, y is project number, z is end of bar
            // Define this first one using start/end variables for illustration
            ppl.Add( start, 1.0, end );
            // add another red bar, assigned to project 2
            // Didn't use start/end variables here, but it's the same concept
            ppl.Add( new XDate( 2005, 12, 16 ), 2.0, new XDate( 2005, 12, 31 ) );
            HiLowBarItem myBar = myPane.AddHiLowBar( "job 1", ppl, Color.Red );
            // This tells the bar that we want to manually define the Y position
            // Y is AxisType.Text, which is ordinal, so a Y value of 1.0 goes with the first label,
            // 2.0 with the second, etc.
            myBar.IsOverrideOrdinal = true;
            myBar.Bar.Fill = new Fill( Color.Red, Color.White, Color.Red, 90.0f );
            // This size is the width of the bar
            myBar.Bar.Size = 20f;

            // Now, define all the bars that you want to be Green
            ppl = new PointPairList();
            ppl.Add( new XDate( 2005, 11,16 ), 2.0, new XDate( 2005, 11, 26 ) );
            myBar = myPane.AddHiLowBar( "job 2", ppl, Color.Green );
            myBar.IsOverrideOrdinal = true;
            myBar.Bar.Fill = new Fill( Color.Green, Color.White, Color.Green, 90.0f );
            myBar.Bar.Size = 20f;

            // Define all the bars that you want to be blue
            ppl = new PointPairList();
            ppl.Add( new XDate( 2005, 11, 27 ), 1.0, new XDate( 2005, 12, 15 ) );
            myBar = myPane.AddHiLowBar( "job 3", ppl, Color.Blue );
            myBar.IsOverrideOrdinal = true;
            myBar.Bar.Fill = new Fill( Color.Blue, Color.White, Color.Blue, 90.0f );
            myBar.Bar.Size = 20f;
            #endif

            #if false		// DeSerialize
                DeSerialize( out myPane, @"c:\temp\myZedGraphFile" );

                trackBar1.Minimum = 0;
                trackBar1.Maximum = 100;
                trackBar1.Value = 50;

                myPane.AxisChange( this.CreateGraphics() );
            #endif

            #if false			// spline test

            myPane = new GraphPane();
            PointPairList ppl = new PointPairList();

            ppl.Add( 0, 713 );
            ppl.Add( 7360, 333 );
            ppl.Add( 10333.333, 45.333336 );
            ppl.Add( 11666.667, 5 );
            ppl.Add( 12483.333, 45.333336 );
            ppl.Add( 13600, 110 );
            ppl.Add( 15800, 184.66667 );
            ppl.Add( 18644.998, 186.33368 );
            ppl.Add( 18770.002, 186.66664 );
            ppl.Add( 18896.666, 187.08336 );
            ppl.Add( 18993.334, 187.50002 );
            ppl.Add( 19098.332, 188.08334 );
            ppl.Add( 19285.002, 189.41634 );
            ppl.Add( 19443.332, 190.83334 );
            ppl.Add( 19633.334, 193.16634 );
            ppl.Add( 19823.336, 196.49983 );
            ppl.Add( 19940.002, 199.16669 );
            ppl.Add( 20143.303, 204.66566 );
            ppl.Add( 20350, 210.91667 );
            ppl.Add( 36000, 713 );

            LineItem curve = myPane.AddCurve( "test", ppl, Color.Green, SymbolType.Default );
            curve.Line.IsSmooth = true;
            curve.Line.SmoothTension = 0.4F;

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;
            #endif

            #if false	// hilowbar test

            myPane = new GraphPane();

            myPane.Title.Text = "Bar Type Sample";
            myPane.XAxis.Title.Text = "Text Axis";
            myPane.YAxis.Title.Text = "Some Data Value";
            myPane.XAxis.Type = AxisType.Text;
            myPane.ClusterScaleWidth = 1.0;
            //myPane.BarType = BarType.Overlay;

            myPane.FontSpec.Size = 18;
            myPane.YAxis.TitleFontSpec.Size = 16;
            myPane.XAxis.TitleFontSpec.Size = 16;

            string[] labels = { "North", "South", "East", "West", "Up", "Down" };
            myPane.XAxis.TextLabels = labels;
            //Random rand = new Random();

            double[] xArray = { 3, 5, 9, 11, 16, 18 };
            double[] xArray2 = { 10, 12, 13, 15, 17, 19 };
            double[] yArray = { 10, 45, 78, 34, 15, 26 };
            double[] yArray2 = { 54, 34, 64, 24, 44, 74 };
            PointPairList list1 = new PointPairList( xArray, yArray );
            PointPairList list2 = new PointPairList( xArray2, yArray2 );
            /*
            for ( int i = 0; i < 6; i++ )
            {
                double x = xArray[i];
                double y1 = rand.NextDouble() * 1.0 + .00001;
                double y2 = rand.NextDouble() * 1.0 + .00001;

                list1.Add( x, y1 );
                list2.Add( x, y2 );
            }
            */
            HiLowBarItem bar1 = myPane.AddHiLowBar( "First", list1, Color.Blue );
            HiLowBarItem bar2 = myPane.AddHiLowBar( "Second", list2, Color.Red );
            //myPane.YAxis.Type = AxisType.Log;
            //myPane.BarType = BarType.ClusterHiLow;
            //myPane.XAxis.Scale.ScaleFormatEvent += new Scale.ScaleFormatHandler( CustomFormatter );

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;

            myPane.AxisChange( this.CreateGraphics() );

            #endif

            #if false	// Basic bar test - Linear

            myPane = new GraphPane();

            myPane.Title.Text = "BarItem Sample (BarType.ClusterHiLow)";
            myPane.XAxis.Title.Text = "Text Axis";
            myPane.YAxis.Title.Text = "Some Data Value";
            myPane.XAxis.Type = AxisType.Text;
            myPane.ClusterScaleWidth = 2.0;
            myPane.BarType = BarType.ClusterHiLow;

            myPane.FontSpec.Size = 18;
            myPane.YAxis.TitleFontSpec.Size = 16;
            myPane.XAxis.TitleFontSpec.Size = 16;

            string[] labels = { "North", "South", "East", "West", "Up", "Down" };
            myPane.XAxis.TextLabels = labels;
            //Random rand = new Random();

            //double[] xArray = { 3, 5, 9, 11, 16, 18 };
            double[] xArray = { 1, 1.8, 3.2, 4, 5, 6 };
            double[] xArray2 = { 10, 12, 13, 15, 17, 19 };
            double[] yArray = { 10, 75, 25, 16, 15, 26 };
            double[] yArray2 = { 54, 62, 44, 24, 44, 74 };
            double[] ylArray2 = { 34, 42, 15, 0, 5, 20 };
            double[] yArray3 = { 54, 62, 44, 24, 34, 74 };
            double[] ylArray3 = { 44, 42, 14, 14, 14, 34 };
            PointPairList list1 = new PointPairList( xArray, yArray, ylArray2 );
            PointPairList list2 = new PointPairList( xArray, yArray2, ylArray2 );
            PointPairList list3 = new PointPairList( xArray, yArray3, ylArray3 );
            /*
            for ( int i = 0; i < 6; i++ )
            {
                double x = xArray[i];
                double y1 = rand.NextDouble() * 1.0 + .00001;
                double y2 = rand.NextDouble() * 1.0 + .00001;

                list1.Add( x, y1 );
                list2.Add( x, y2 );
            }
            */
            //ErrorBarItem bar1 = myPane.AddErrorBar( "First", list3, Color.Blue );
            //bar1.ErrorBar.Symbol.Size = 12;
            //bar1.ErrorBar.PenWidth = 2;
            //HiLowBarItem bar1 = myPane.AddHiLowBar( "First", list3, Color.Blue );
            //bar1.Bar.Size = 20;
            BarItem bar1 = myPane.AddBar( "First", list1, Color.Blue );
            BarItem bar2 = myPane.AddBar( "Second", list2, Color.Red );
            //myPane.YAxis.Type = AxisType.Log;
            //myPane.BarType = BarType.ClusterHiLow;
            //myPane.XAxis.Scale.ScaleFormatEvent += new Scale.ScaleFormatHandler( CustomFormatter );

            myPane.YAxis.IsTitleAtCross = false;

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;

            myPane.AxisChange( this.CreateGraphics() );

            #endif

            #if false	// Bars - different colors thru IsOverrideOrdinal

            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            /*			PointPairList list1 = new PointPairList();
            list1.Add(1,13);
            HiLowBarItem bar1 = myPane.AddHiLowBar( "First", list1, Color.Blue );
            PointPairList list2 = new PointPairList();
            list2.Add(2,22);
            HiLowBarItem bar2 = myPane.AddHiLowBar( "Second", list2, Color.Red );

            bar1.Bar.Size = 30;
            bar1.IsOverrideOrdinal = true;
            bar2.Bar.Size = 30;
            bar2.IsOverrideOrdinal = true;
            */
            PointPairList list1 = new PointPairList();
            list1.Add(1,13);
            BarItem bar1 = myPane.AddBar( "First", list1, Color.Blue );
            PointPairList list2 = new PointPairList();
            list2.Add(2,22);
            BarItem bar2 = myPane.AddBar( "Second", list2, Color.Red );

            bar1.IsOverrideOrdinal = true;
            bar2.IsOverrideOrdinal = true;

            myPane.Legend.Position = LegendPos.TopFlushLeft;

            myPane.BarType = BarType.Overlay;
            myPane.XAxis.Type = AxisType.Text;
            string[] labels = { "Label1", "Label2" };
            myPane.XAxis.TextLabels = labels;
            myPane.AxisChange( this.CreateGraphics() );

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;

            #endif

            #if false	// Basic curve test - two text axes

            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            double[] y = { 2, 4, 1, 5, 3 };

            LineItem myCurve = myPane.AddCurve( "curve 1", null, y, Color.Blue, SymbolType.Diamond );
            myCurve.IsOverrideOrdinal = true;
            myPane.XAxis.Type = AxisType.Text;
            myPane.YAxis.Type = AxisType.Text;

            string[] xLabels = { "one", "two", "three", "four", "five" };
            string[] yLabels = { "alpha", "bravo", "charlie", "delta", "echo" };
            //myPane.XAxis.TextLabels = xLabels;
            //myPane.YAxis.TextLabels = yLabels;

            myPane.AxisChange( this.CreateGraphics() );

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;

            #endif

            #if false	// Basic horizontal bar test

            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            PointPairList list = new PointPairList();

            for ( int i=0; i<5; i++ )
            {
                double y = (double) i;
                //double x = new XDate( 2001, 1, i*3 );
                double x = Math.Sin( i / 8.0 ) * 100000 + 100001;
                list.Add( x, y );
                //double z = Math.Abs( Math.Cos( i / 8.0 ) ) * y;
            }

            PointPairList list2 = new PointPairList( list );
            PointPairList list3 = new PointPairList( list );
            BarItem myCurve = myPane.AddBar( "curve 1", list, Color.Blue );
            BarItem myCurve2 = myPane.AddBar( "curve 2", list2, Color.Red );
            BarItem myCurve3 = myPane.AddBar( "curve 3", list3, Color.Green );

            //myPane.XAxis.IsSkipLastLabel = false;
            //myPane.XAxis.IsPreventLabelOverlap = false;
            //myPane.XAxis.ScaleFormat = "dd/MM HH:mm";
            //myPane.XAxis.Type = AxisType.Date;
            myPane.BarType = BarType.PercentStack;
            myPane.BarBase = BarBase.Y;
            myPane.AxisChange( this.CreateGraphics() );

            ValueHandler valueHandler = new ValueHandler(myPane, true);
            const float shift = 0;
            int iOrd = 0;
            foreach (CurveItem oCurveItem in myPane.CurveList)
            {
                BarItem oBarItem = oCurveItem as BarItem;
                if (oBarItem != null)
                {
                    PointPairList oPointPairList = oCurveItem.Points as PointPairList;
                    for (int i=0; i<oPointPairList.Count; i++)
                    {
                        double xVal = oPointPairList[i].X;
                        string sLabel = string.Concat(xVal.ToString("F0"), "%");

                        double yVal = valueHandler.BarCenterValue(oCurveItem, oCurveItem.GetBarWidth(myPane), i, oPointPairList[i].Y, iOrd);
                        double x1, x2, y;
                        valueHandler.GetValues( oCurveItem, i, out y, out x1, out x2 );

                        xVal = ( x1 + x2 ) / 2.0;

                        TextItem oTextItem = new TextItem(sLabel, (float) xVal + (xVal > 0 ? shift : -shift ), (float) yVal);
                        oTextItem.Location.CoordinateFrame = CoordType.AxisXYScale;
                        oTextItem.Location.AlignH =  AlignH.Center;
                        oTextItem.Location.AlignV = AlignV.Center;
                        oTextItem.FontSpec.Border.IsVisible = true;
                        oTextItem.FontSpec.Angle = 0;
                        oTextItem.FontSpec.Fill.IsVisible = false;
                        myPane.GraphItemList.Add(oTextItem);
                    }
                }

                iOrd++;
            }

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;

            #endif

            #if false	// vertical bars with labels

            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            PointPairList list = new PointPairList();
            PointPairList list2 = new PointPairList();
            PointPairList list3 = new PointPairList();
            Random rand = new Random();

            for ( int i=0; i<5; i++ )
            {
                double x = (double) i;
                double y = rand.NextDouble() * 1000;
                double y2 = rand.NextDouble() * 1000;
                double y3 = rand.NextDouble() * 1000;
                list.Add( x, y );
                list2.Add( x, y2 );
                list3.Add( x, y3 );
            }

            BarItem myCurve = myPane.AddBar( "curve 1", list, Color.Blue );
            BarItem myCurve2 = myPane.AddBar( "curve 2", list2, Color.Red );
            BarItem myCurve3 = myPane.AddBar( "curve 3", list3, Color.Green );

            //myPane.XAxis.IsReverse = true;
            myPane.AxisChange( this.CreateGraphics() );
            myPane.XAxis.IsTicsBetweenLabels = true;
            string[] labels = { "one", "two", "three", "four", "five" };
            myPane.XAxis.TextLabels = labels;
            myPane.XAxis.Type = AxisType.Text;
            //myPane.XAxis.Step = 3;
            myPane.XAxis.IsAllTics = false;

            ArrowItem tic = new ArrowItem( Color.Black, 1.0f, 2.5f, 0.99f, 2.5f, 1.01f );
            tic.IsArrowHead = false;
            tic.Location.CoordinateFrame = CoordType.XScaleYAxisFraction;
            myPane.GraphItemList.Add( tic );

            CreateBarLabels( myPane );

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;

            #endif

            #if false	// Basic curve test - log/exponential axis
            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            PointPairList ppl1 = new PointPairList();
            PointPairList ppl2 = new PointPairList();

            for ( int i=0; i<100; i++ )
            {
                double x = (double) i * 1.52 + 0.001;
                double x2 = x*10000;
                double y = Math.Sin( i / 8.0 ) * 100000 + 100001;
                double y2 = Math.Sin( i / 8.0 ) * 100000 + 100001;
                double z = Math.Abs( Math.Cos( i / 8.0 ) ) * y;
                ppl1.Add( x, y, z );
                ppl2.Add( x2, y2, z );
            }

            LineItem myCurve = myPane.AddCurve( "curve", ppl1, Color.Blue, SymbolType.Diamond );
            LineItem myCurve2 = myPane.AddCurve( "curve2", ppl2, Color.Red, SymbolType.Triangle );

            myPane.XAxis.IsUseTenPower = false;
            myPane.XAxis.Type = AxisType.Log;
            myPane.XAxis.Exponent = 0.3;

            myPane.AxisChange( this.CreateGraphics() );

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;

            #endif

            #if false	// Basic curve test
            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            double[] x = new double[100];
            double[] y = new double[100];

            for ( int i=0; i<100; i++ )
            {
                x[i] = (double) i;
                y[i] = Math.Sin( i / 8.0 ) * 100000 + 100001;
                double z = Math.Abs(Math.Cos( i / 8.0 )) * y[i];
            }
            BasicArrayPointList list = new BasicArrayPointList( x, y );

            //LineItem myCurve = myPane.AddCurve( "curve", list, Color.Blue, SymbolType.Diamond );
            LineItem myCurve = myPane.AddCurve( "curve", list, Color.Blue, SymbolType.Diamond );
            //myCurve.Symbol.IsVisible = true;
            //myCurve.IsY2Axis = true;
            //myPane.Y2Axis.IsVisible = true;
            //myPane.YAxis.Type = AxisType.Log;
            //myPane.YAxis.IsScaleVisible = false;
            //myPane.YAxis.IsShowTitle = false;
            //myPane.MarginLeft = 50;

            //TextItem text = new TextItem("5000", -0.01f, 5000f, CoordType.XAxisFractionYScale, AlignH.Right, AlignV.Center );
            //text.FontSpec.Border.IsVisible = false;
            //text.FontSpec.Fill.IsVisible = false;
            //myPane.GraphItemList.Add( text );

            //TextItem text2 = new TextItem( "My Title", 0.01f, 0.5f, CoordType.XPaneFractionYAxisFraction,
            //	AlignH.Center, AlignV.Top );
            //text2.FontSpec.Border.IsVisible = false;
            //text2.FontSpec.Fill.IsVisible = false;
            //text2.FontSpec.Angle = 90f;
            //myPane.GraphItemList.Add( text2 );

            //myPane.YAxis.IsVisible = false;
            //myPane.Y2Axis.Title.Text = "Y2 Axis";
            //myPane.XAxis.BaseTic = 1;
            //myPane.XAxis.Step = 5;
            //myPane.Y2Axis.Cross = 60;
            //myPane.YAxis.IsScaleLabelsInside = true;
            //myPane.Y2Axis.IsShowGrid = true;
            //myPane.XAxis.IsShowGrid = true;
            //myPane.YAxis.IsSkipFirstLabel = true;
            myPane.XAxis.IsSkipLastLabel = true;
            //myPane.XAxis.IsSkipLastLabel = true;
            //myPane.XAxis.IsReverse = true;
            //myPane.AxisBorder.IsVisible = false;
            //myPane.XAxis.Type = AxisType.Log;

            PointF[] polyPts = new PointF[7];
            polyPts[0] = new PointF( 30f, 0.2f );
            polyPts[1] = new PointF( 25f, 0.4f );
            polyPts[2] = new PointF( 27f, 0.6f );
            polyPts[3] = new PointF( 30f, 0.8f );
            polyPts[4] = new PointF( 35f, 0.6f );
            polyPts[5] = new PointF( 37f, 0.4f );
            polyPts[6] = new PointF( 30f, 0.2f );
            PolyItem poly = new PolyItem( polyPts, Color.Red, Color.LightSeaGreen, Color.White );
            myPane.GraphItemList.Add( poly );

            myPane.AxisChange( this.CreateGraphics() );

            myPane.FontSpec.IsDropShadow = true;
            myPane.FontSpec.DropShadowColor = Color.Red;
            myPane.FontSpec.Border.IsVisible = true;
            myPane.FontSpec.Fill = new Fill( Color.White, Color.LightGoldenrodYellow );

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;

            #endif

            #if false	// repetitive points
            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );

            double[] Track_DateTime_Xaxis = {1};
            double[] Y_processed_axis = {10};

            LineItem myCurve = myPane.AddCurve( "Curve Legend", Track_DateTime_Xaxis, Y_processed_axis,
                Color.DarkRed );
            myCurve.Symbol.Fill = new Fill( Color.Red );
            myPane.XAxis.Max = 1;
            myPane.YAxis.IsShowGrid = true;
            myPane.YAxis.IsShowMinorGrid = true;
            //myPane.AxisChange( g );

            #endif

            #if false	// masterpane test

            master = new MasterPane( "ZedGraph MasterPane Example",
                new Rectangle( 10, 10, this.Width-20, this.Height-100 ) );

            master.PaneFill = new Fill( Color.White, Color.MediumSlateBlue, 45.0F );

            master.Legend.IsVisible = true;
            master.Legend.Position = LegendPos.TopCenter;

            TextItem text = new TextItem( "Priority", 0.88F, 0.12F );
            text.Location.CoordinateFrame = CoordType.PaneFraction;
            text.FontSpec.Angle = 15.0F;
            text.FontSpec.FontColor = Color.Red;
            text.FontSpec.IsBold = true;
            text.FontSpec.Size = 16;
            text.FontSpec.Border.IsVisible = false;
            text.FontSpec.Border.Color = Color.Red;
            text.FontSpec.Fill.IsVisible = false;
            text.Location.AlignH = AlignH.Left;
            text.Location.AlignV = AlignV.Bottom;
            master.GraphItemList.Add( text );

            text = new TextItem( "DRAFT", 0.5F, 0.5F );
            text.Location.CoordinateFrame = CoordType.PaneFraction;
            text.FontSpec.Angle = 30.0F;
            text.FontSpec.FontColor = Color.FromArgb( 70, 255, 100, 100 );
            text.FontSpec.IsBold = true;
            text.FontSpec.Size = 100;
            text.FontSpec.Border.IsVisible = false;
            text.FontSpec.Fill.IsVisible = false;
            text.Location.AlignH = AlignH.Center;
            text.Location.AlignV = AlignV.Center;
            text.ZOrder = ZOrder.A_InFront;
            master.GraphItemList.Add( text );

            ColorSymbolRotator rotator = new ColorSymbolRotator();

            for ( int j=0; j<8; j++ )
            {
                // Create a new graph - rect dimensions do not matter here, since it
                // will be resized by MasterPane.AutoPaneLayout()
                GraphPane newPane = new GraphPane( new Rectangle( 10, 10, 10, 10 ),
                    "Case #" + (j+1).ToString(),
                    "Time, Days",
                    "Rate, m/s" );

                newPane.PaneFill = new Fill( Color.PowderBlue, Color.LightYellow, 45.0F );
                newPane.BaseDimension = 6.0F;

                // Make up some data arrays based on the Sine function
                double x, y;
                PointPairList list = new PointPairList();
                for ( int i=0; i<36; i++ )
                {
                    x = (double) i + 5;
                    y = 3.0 * ( 1.5 + Math.Sin( (double) i * 0.2 + (double) j ) );
                    list.Add( x, y );
                }

                LineItem myCurve = newPane.AddCurve( "Type " + j.ToString(),
                    list, rotator.NextColor, rotator.NextSymbol );
                myCurve.Symbol.Fill = new Fill( Color.White );

                master.Add( newPane );
            }

            Graphics g = this.CreateGraphics();

            master.AutoPaneLayout( g, PaneLayout.SquareRowPreferred);
            master.AxisChange( g );
            #endif

            #if false
            // Create a new GraphPane

            myPane = new GraphPane( new RectangleF( 0, 0, 640, 480 ), "Title", "XAxis", "YAxis" );
            string[] labels = { "Panther", "Lion", "Cheetah", "Cougar", "Tiger", "Leopard" };
            double[] x = { 100, 115, 75, 22, 98, 40 };
            double[] x2 = { 120, 175, 95, 57, 113, 110 };
            double[] x3 = { 204, 192, 119, 80, 134, 156 };
            BarItem myCurve = myPane.AddBar( "Here", x, null, Color.Red );
            myCurve.Bar.Fill = new Fill( Color.Red, Color.White, Color.Red, 90f );
            myCurve = myPane.AddBar( "There", x2, null, Color.Blue );
            myCurve.Bar.Fill = new Fill( Color.Blue, Color.White, Color.Blue, 90f );
            myCurve = myPane.AddBar( "Elsewhere", x3, null, Color.Green );
            myCurve.Bar.Fill = new Fill( Color.Green, Color.White, Color.Green, 90f );
            myPane.YAxis.IsTicsBetweenLabels = true;
            myPane.YAxis.TextLabels = labels;
            myPane.YAxis.Type = AxisType.Text;
            myPane.BarType = BarType.Stack;
            myPane.BarBase = BarBase.Y;
            myPane.Chart.Fill = new Fill( Color.White, Color.FromArgb( 255, 255, 166), 45.0F );

            #endif

            #if false	// ordinal demo

            myPane = new GraphPane( new RectangleF( 0, 0, 300, 200 ), "Ordinal Demo", "X Value (ordinal)", "Y Value" );

            PointPairList list = new PointPairList();
            list.Add( 10, 50 );
            list.Add( 11, 24 );
            list.Add( 20, 75 );
            list.Add( 21, 62 );

            LineItem myCurve = myPane.AddCurve( "Curve", list, Color.Blue, SymbolType.Diamond );
            myCurve.Symbol.Fill = new Fill( Color.White );

            myPane.FontSpec.Size = 24;
            myPane.XAxis.TitleFontSpec.Size = 18;
            myPane.XAxis.Scale.FontSpec.Size = 18;
            myPane.YAxis.TitleFontSpec.Size = 18;
            myPane.YAxis.Scale.FontSpec.Size = 18;
            myPane.XAxis.Type = AxisType.Ordinal;
            myPane.AxisChange( this.CreateGraphics() );

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;

            #endif

            if ( master != null )
                _crossAxis = master[0].Y2Axis;
            else
                _crossAxis = myPane.YAxisList[1];

            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;
            trackBar1.Value = 50;
            UpdateControls();
            SetSize();

            //this.WindowState = FormWindowState.Maximized ;
            if ( this.myPane != null )
                this.myPane.AxisChange( this.CreateGraphics() );
        }
Esempio n. 18
0
        /// <summary>
        /// Draw this <see cref="CurveItem"/> to the specified <see cref="Graphics"/>
        /// device as a symbol at each defined point.  The routine
        /// only draws the symbols; the lines are draw by the
        /// <see cref="Line.DrawCurve"/> method.  This method
        /// is normally only called by the Draw method of the
        /// <see cref="CurveItem"/> 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="LineItem"/> representing this
        /// curve.</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="isSelected">Indicates that the <see cref="Symbol" /> should be drawn
        /// with attributes from the <see cref="Selection" /> class.
        /// </param>
        public void Draw( Graphics g, GraphPane pane, LineItem curve, float scaleFactor,
			bool isSelected )
        {
            Symbol source = this;
            if ( isSelected )
                source = Selection.Symbol;

            int tmpX, tmpY;

            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;

            // (Dale-a-b) we'll set an element to true when it has been drawn
            bool[,] isPixelDrawn = new bool[maxX + 1, maxY + 1];

            double curX, curY, lowVal;
            IPointList points = curve.Points;

            if ( points != null && ( _border.IsVisible || _fill.IsVisible ) )
            {
                SmoothingMode sModeSave = g.SmoothingMode;
                if ( _isAntiAlias )
                    g.SmoothingMode = SmoothingMode.HighQuality;

                // For the sake of speed, go ahead and create a solid brush and a pen
                // If it's a gradient fill, it will be created on the fly for each symbol
                //SolidBrush	brush = new SolidBrush( this.fill.Color );

                using ( Pen pen = source._border.GetPen( pane, scaleFactor ) )
                using ( GraphicsPath path = MakePath( g, scaleFactor ) )
                {
                    RectangleF rect = path.GetBounds();

                    using ( Brush brush = source.Fill.MakeBrush( rect ) )
                    {
                        ValueHandler valueHandler = new ValueHandler( pane, false );
                        Scale xScale = curve.GetXAxis( pane ).Scale;
                        Scale yScale = curve.GetYAxis( pane ).Scale;

                        bool xIsLog = xScale.IsLog;
                        bool yIsLog = yScale.IsLog;
                        bool xIsOrdinal = xScale.IsAnyOrdinal;

                        double xMin = xScale.Min;
                        double xMax = xScale.Max;

                        // Loop over each defined point
                        for ( int i = 0; i < points.Count; i++ )
                        {
                            // Get the user scale values for the current point
                            // use the valueHandler only for stacked types
                            if ( pane.LineType == LineType.Stack )
                            {
                                valueHandler.GetValues( curve, i, out curX, out lowVal, out curY );
                            }
                            // otherwise, just access the values directly.  Avoiding the valueHandler for
                            // non-stacked types is an optimization to minimize overhead in case there are
                            // a large number of points.
                            else
                            {
                                curX = points[i].X;
                                if ( curve is StickItem )
                                    curY = points[i].Z;
                                else
                                    curY = points[i].Y;
                            }

                            // 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 ( curX != PointPair.Missing &&
                                    curY != PointPair.Missing &&
                                    !System.Double.IsNaN( curX ) &&
                                    !System.Double.IsNaN( curY ) &&
                                    !System.Double.IsInfinity( curX ) &&
                                    !System.Double.IsInfinity( curY ) &&
                                    ( curX > 0 || !xIsLog ) &&
                                    ( !yIsLog || curY > 0.0 ) &&
                                    ( xIsOrdinal || ( curX >= xMin && curX <= xMax ) ) )
                            {
                                // Transform the user scale values to pixel locations
                                tmpX = (int) xScale.Transform( curve.IsOverrideOrdinal, i, curX );
                                tmpY = (int) yScale.Transform( curve.IsOverrideOrdinal, i, curY );

                                // Maintain an array of "used" pixel locations to avoid duplicate drawing operations
                                if ( tmpX >= minX && tmpX <= maxX && tmpY >= minY && tmpY <= maxY ) // guard against the zoom-in case
                                {
                                    if ( isPixelDrawn[tmpX, tmpY] )
                                        continue;
                                    isPixelDrawn[tmpX, tmpY] = true;
                                }

                                // If the fill type for this symbol is a Gradient by value type,
                                // the make a brush corresponding to the appropriate current value
                                if ( _fill.IsGradientValueType || _border._gradientFill.IsGradientValueType )
                                {
                                    using ( Brush tBrush = _fill.MakeBrush( rect, points[i] ) )
                                    using ( Pen tPen = _border.GetPen( pane, scaleFactor, points[i] ) )
                                        this.DrawSymbol( g, tmpX, tmpY, path, tPen, tBrush );
                                }
                                else
                                {
                                    // Otherwise, the brush is already defined
                                    // Draw the symbol at the specified pixel location
                                    this.DrawSymbol( g, tmpX, tmpY, path, pen, brush );
                                }
                            }
                        }
                    }
                }

                g.SmoothingMode = sModeSave;
            }
        }
Esempio n. 19
0
        public HorizontalBarDemo()
            : base("A sideways bar demo.\n" +
								"This demo also shows how to add labels to the bars, in this " +
								"case showing the value of each bar",
								"HorizontalBar Demo", DemoType.Bar)
        {
            GraphPane myPane = base.GraphPane;

            // Set the title and axis labels
            myPane.Title.Text = "Horizontal Bar Graph";
            myPane.XAxis.Title.Text = "Performance Factor";
            myPane.YAxis.Title.Text = "Grouping";

            // Enter some random data values
            double[] y = { 100, 115, 75, -22, 98, 40, -10 };
            double[] y2 = { 90, 100, 95, -35, 80, 35, 35 };
            double[] y3 = { 80, 110, 65, -15, 54, 67, 18 };

            // Generate a bar with "Curve 1" in the legend
            BarItem myCurve = myPane.AddBar( "Curve 1", y, null, Color.Red );
            // Fill the bar with a red-white-red gradient
            myCurve.Bar.Fill = new Fill( Color.Red, Color.White, Color.Red, 90F );

            // Generate a bar with "Curve 2" in the legend
            myCurve = myPane.AddBar( "Curve 2", y2, null, Color.Blue );
            // Fill the bar with a blue-white-blue gradient for a 3d look
            myCurve.Bar.Fill = new Fill( Color.Blue, Color.White, Color.Blue, 90F );

            // Generate a bar with "Curve 3" in the legend
            myCurve = myPane.AddBar( "Curve 3", y3, null, Color.Green );
            // Fill the bar with a Green-white-Green gradient for a 3d look
            myCurve.Bar.Fill = new Fill( Color.White, Color.Green, 90F );

            // Draw the X tics between the labels instead of at the labels
            myPane.YAxis.MajorTic.IsBetweenLabels = true;

            // Set the XAxis to an ordinal type
            myPane.YAxis.Type = AxisType.Ordinal;
            // draw the X axis zero line
            myPane.XAxis.MajorGrid.IsZeroLine = true;

            //This is the part that makes the bars horizontal
            myPane.BarSettings.Base = BarBase.Y;

            // Fill the axis background with a color gradient
            myPane.Chart.Fill = new Fill( Color.White,
                Color.FromArgb( 255, 255, 166), 45.0F );

            base.ZedGraphControl.AxisChange();

            // The ValueHandler is a helper that does some position calculations for us.
            ValueHandler valueHandler = new ValueHandler( myPane, true );

            // Display a value for the maximum of each bar cluster
            // Shift the text items by 5 user scale units above the bars
            const float shift = 3;

            int ord = 0;
            foreach ( CurveItem curve in myPane.CurveList )
            {
                BarItem bar = curve as BarItem;

                if ( bar != null )
                {
                    IPointList points = curve.Points;

                    for ( int i=0; i<points.Count; i++ )
                    {
                        double xVal = points[i].X;
                        // Calculate the Y value at the center of each bar
                        double yVal = valueHandler.BarCenterValue( curve, curve.GetBarWidth( myPane ),
                                    i, points[i].Y, ord );

                        // format the label string to have 1 decimal place
                        string lab = xVal.ToString( "F0" );

                        // create the text item (assumes the x axis is ordinal or text)
                        // for negative bars, the label appears just above the zero value
                        TextObj text = new TextObj( lab, (float) xVal + ( xVal > 0 ? shift : -shift ),
                                                        (float) yVal );

                        // tell Zedgraph to use user scale units for locating the TextObj
                        text.Location.CoordinateFrame = CoordType.AxisXYScale;
                        text.FontSpec.Size = 10;
                        // AlignH the left-center of the text to the specified point
                        text.Location.AlignH =  xVal > 0 ? AlignH.Left : AlignH.Right;
                        text.Location.AlignV = AlignV.Center;
                        text.FontSpec.Border.IsVisible = false;
                        // rotate the text 90 degrees
                        text.FontSpec.Angle = 0;
                        text.FontSpec.Fill.IsVisible = false;
                        // add the TextObj to the list
                        myPane.GraphObjList.Add( text );
                    }
                }

                ord++;
            }
        }
Esempio n. 20
0
        /// <summary>
        /// Build an array of <see cref="PointF"/> values (pixel coordinates) that represents
        /// the current curve.  Note that this drawing routine ignores <see cref="PointPairBase.Missing"/>
        /// values, but it does not "break" the line to indicate values are missing.
        /// </summary>
        /// <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>
        /// <param name="arrPoints">An array of <see cref="PointF"/> values in pixel
        /// coordinates representing the current curve.</param>
        /// <param name="count">The number of points contained in the "arrPoints"
        /// parameter.</param>
        /// <returns>true for a successful points array build, false for data problems</returns>
        public bool BuildPointsArray( GraphPane pane, CurveItem curve,
			out PointF[] arrPoints, out int count )
        {
            arrPoints = null;
            count = 0;
            IPointList points = curve.Points;

            if ( this.IsVisible && !this.Color.IsEmpty && points != null )
            {
                int index = 0;
                float curX, curY,
                            lastX = 0,
                            lastY = 0;
                double x, y, lowVal;
                ValueHandler valueHandler = new ValueHandler( pane, false );

                // Step type plots get twice as many points.  Always add three points so there is
                // room to close out the curve for area fills.
                arrPoints = new PointF[( _stepType == ZedGraph.StepType.NonStep ? 1 : 2 ) *
                                            points.Count + 1];

                // Loop over all points in the curve
                for ( int i = 0; i < points.Count; i++ )
                {
                    // make sure that the current point is valid
                    if ( !points[i].IsInvalid )
                    {
                        // Get the user scale values for the current point
                        // use the valueHandler only for stacked types
                        if ( pane.LineType == LineType.Stack )
                        {
                            valueHandler.GetValues( curve, i, out x, out lowVal, out y );
                        }
                        // otherwise, just access the values directly.  Avoiding the valueHandler for
                        // non-stacked types is an optimization to minimize overhead in case there are
                        // a large number of points.
                        else
                        {
                            x = points[i].X;
                            y = points[i].Y;
                        }

                        if ( x == PointPair.Missing || y == PointPair.Missing )
                            continue;

                        // Transform the user scale values to pixel locations
                        Axis xAxis = curve.GetXAxis( pane );
                        curX = xAxis.Scale.Transform( curve.IsOverrideOrdinal, i, x );
                        Axis yAxis = curve.GetYAxis( pane );
                        curY = yAxis.Scale.Transform( curve.IsOverrideOrdinal, i, y );

                        if ( curX < -1000000 || curY < -1000000 || curX > 1000000 || curY > 1000000 )
                            continue;

                        // Add the pixel value pair into the points array
                        // Two points are added for step type curves
                        // ignore step-type setting for smooth curves
                        if ( _isSmooth || index == 0 || this.StepType == StepType.NonStep )
                        {
                            arrPoints[index].X = curX;
                            arrPoints[index].Y = curY;
                        }
                        else if ( this.StepType == StepType.ForwardStep )
                        {
                            arrPoints[index].X = curX;
                            arrPoints[index].Y = lastY;
                            index++;
                            arrPoints[index].X = curX;
                            arrPoints[index].Y = curY;
                        }
                        else if ( this.StepType == StepType.RearwardStep )
                        {
                            arrPoints[index].X = lastX;
                            arrPoints[index].Y = curY;
                            index++;
                            arrPoints[index].X = curX;
                            arrPoints[index].Y = curY;
                        }

                        lastX = curX;
                        lastY = curY;
                        index++;

                    }

                }

                // Make sure there is at least one valid point
                if ( index == 0 )
                    return false;

                // Add an extra point at the end, since the smoothing algorithm requires it
                arrPoints[index] = arrPoints[index - 1];
                index++;

                count = index;
                return true;
            }
            else
            {
                return false;
            }
        }
Esempio n. 21
0
        /// <summary>
        /// Create a TextLabel for each bar in the GraphPane.
        /// Call this method only after calling AxisChange()
        /// </summary>
        /// <remarks>
        /// This method will go through the bars, create a label that corresponds to the bar value,
        /// and place it on the graph depending on user preferences.  This works for horizontal or
        /// vertical bars in clusters or stacks.</remarks>
        /// <param name="pane">The GraphPane in which to place the text labels.</param>
        /// <param name="isBarCenter">true to center the labels inside the bars, false to
        /// place the labels just above the top of the bar.</param>
        /// <param name="valueFormat">The double.ToString string format to use for creating
        /// the labels
        /// </param>
        private void CreateBarLabels( GraphPane pane, bool isBarCenter, string valueFormat )
        {
            bool isVertical = pane.BarSettings.Base == BarBase.X;

            // Make the gap between the bars and the labels = 2% of the axis range
            float labelOffset;
            if ( isVertical )
                labelOffset = (float) ( pane.YAxis.Scale.Max - pane.YAxis.Scale.Min ) * 0.02f;
            else
                labelOffset = (float) ( pane.XAxis.Scale.Max - pane.XAxis.Scale.Min ) * 0.02f;

            // keep a count of the number of BarItems
            int curveIndex = 0;

            // Get a valuehandler to do some calculations for us
            ValueHandler valueHandler = new ValueHandler( pane, true );

            // Loop through each curve in the list
            foreach ( CurveItem curve in pane.CurveList )
            {
                // work with BarItems only
                BarItem bar = curve as BarItem;
                if ( bar != null )
                {
                    IPointList points = curve.Points;

                    // Loop through each point in the BarItem
                    for ( int i=0; i<points.Count; i++ )
                    {
                        // Get the high, low and base values for the current bar
                        // note that this method will automatically calculate the "effective"
                        // values if the bar is stacked
                        double baseVal, lowVal, hiVal;
                        valueHandler.GetValues( curve, i, out baseVal, out lowVal, out hiVal );

                        // Get the value that corresponds to the center of the bar base
                        // This method figures out how the bars are positioned within a cluster
                        float centerVal = (float) valueHandler.BarCenterValue( bar,
                            bar.GetBarWidth( pane ), i, baseVal, curveIndex );

                        // Create a text label -- note that we have to go back to the original point
                        // data for this, since hiVal and lowVal could be "effective" values from a bar stack
                        string barLabelText	= ( isVertical ? points[i].Y : points[i].X ).ToString( valueFormat );

                        // Calculate the position of the label -- this is either the X or the Y coordinate
                        // depending on whether they are horizontal or vertical bars, respectively
                        float position;
                        if ( isBarCenter )
                            position = (float) (hiVal + lowVal) / 2.0f;
                        else
                            position = (float) hiVal + labelOffset;

                        // Create the new TextObj
                        TextObj label;
                        if ( isVertical )
                            label = new TextObj( barLabelText, centerVal, position );
                        else
                            label = new TextObj( barLabelText, position, centerVal );

                        // Configure the TextObj
                        label.Location.CoordinateFrame	= CoordType.AxisXYScale;
                        label.FontSpec.Size					= 12;
                        label.FontSpec.FontColor			= Color.Black;
                        label.FontSpec.Angle					= isVertical ? 90 : 0;
                        label.Location.AlignH				= isBarCenter ? AlignH.Center : AlignH.Left;
                        label.Location.AlignV				= AlignV.Center;
                        label.FontSpec.Border.IsVisible	= false;
                        label.FontSpec.Fill.IsVisible		= false;

                        // Add the TextObj to the GraphPane
                        pane.GraphObjList.Add( label );
                    }
                }
                curveIndex++;
            }
        }
Esempio n. 22
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="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>
        protected virtual void DrawSingleBar(Graphics g, GraphPane pane,
                                             CurveItem curve,
                                             int index, int pos, Axis baseAxis, Axis valueAxis,
                                             float barWidth, float 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.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;
            var 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 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._barSettings.Base == BarBase.X)
                    Draw(g, pane, pixSide, pixSide + barWidth, pixLowVal,
                         pixHiVal, scaleFactor, true,
                         curve.Points[index]);
                else
                    Draw(g, pane, pixLowVal, pixHiVal, pixSide, pixSide + barWidth,
                         scaleFactor, true,
                         curve.Points[index]);
            }
        }
Esempio n. 23
0
        private IPointList GetPoints(CurveItem curve, GraphPane pane)
        {
            IPointList points = curve.Points;
            ValueHandler valueHandler = new ValueHandler( pane, false );

            if (pane.LineType == LineType.Stack)
            {
                // Loop over each point in the curve
                for (int i = 0; i < points.Count; i++)
                {
                    double x, y, unused;
                    if (!valueHandler.GetValues(curve, i, out x, out unused, out y))
                    {
                        x = PointPair.Missing;
                        y = PointPair.Missing;
                    }
                    points[i].X = x;
                    points[i].Y = y;
                }
            }
            return points;
        }
Esempio n. 24
0
        private bool HandlePointValues(Point mousePt)
        {
            int iPt;
            GraphPane pane;
            object nearestObj;

            using (Graphics g = this.CreateGraphics()) {
                if (_masterPane.FindNearestPaneObject(mousePt,
                                                      g, out pane, out nearestObj, out iPt)) {
                    if (nearestObj is CurveItem && iPt >= 0) {
                        CurveItem curve = (CurveItem)nearestObj;
                        // Provide Callback for User to customize the tooltips
                        if (this.PointValueEvent != null) {
                            string label = this.PointValueEvent(this, pane, curve, iPt);
                            if (label != null && label.Length > 0) {
                                this.pointToolTip.SetToolTip(this, label);
                                this.pointToolTip.Active = true;
                            }
                            else
                                this.pointToolTip.Active = false;
                        }
                        else {
                            if (curve is PieItem) {
                                this.pointToolTip.SetToolTip(this,
                                                             ((PieItem)curve).Value.ToString(_pointValueFormat));
                            }
                            //							else if ( curve is OHLCBarItem || curve is JapaneseCandleStickItem )
                            //							{
                            //								StockPt spt = (StockPt)curve.Points[iPt];
                            //								this.pointToolTip.SetToolTip( this, ( (XDate) spt.Date ).ToString( "MM/dd/yyyy" ) + "\nOpen: $" +
                            //								spt.Open.ToString( "N2" ) +
                            //								"\nHigh: $" +
                            //								spt.High.ToString( "N2" ) + "\nLow: $" +
                            //								spt.Low.ToString( "N2" ) + "\nClose: $" +
                            //								spt.Close.ToString
                            //								( "N2" ) );
                            //							}
                            else {
                                PointPair pt = curve.Points[iPt];

                                if (pt.Tag is string)
                                    this.pointToolTip.SetToolTip(this, (string)pt.Tag);
                                else {
                                    double xVal, yVal, lowVal;
                                    ValueHandler valueHandler = new ValueHandler(pane, false);
                                    if ((curve is BarItem || curve is ErrorBarItem || curve is HiLowBarItem)
                                        && pane.BarSettings.Base != BarBase.X)
                                        valueHandler.GetValues(curve, iPt, out yVal, out lowVal, out xVal);
                                    else
                                        valueHandler.GetValues(curve, iPt, out xVal, out lowVal, out yVal);

                                    string xStr = MakeValueLabel(curve.GetXAxis(pane), xVal, iPt,
                                                                 curve.IsOverrideOrdinal);
                                    string yStr = MakeValueLabel(curve.GetYAxis(pane), yVal, iPt,
                                                                 curve.IsOverrideOrdinal);

                                    this.pointToolTip.SetToolTip(this, string.Format("({0}, {1})", xStr, yStr));

                                    //this.pointToolTip.SetToolTip( this,
                                    //	curve.Points[iPt].ToString( this.pointValueFormat ) );
                                }
                            }

                            this.pointToolTip.Active = true;
                        }
                    }
                    else
                        this.pointToolTip.Active = false;
                }
                else
                    this.pointToolTip.Active = false;

                //g.Dispose();
            }
            return false;
        }
Esempio n. 25
0
        protected override void DrawSingleBar(Graphics g, GraphPane pane, CurveItem curve,
            int index, int pos, Axis baseAxis, Axis valueAxis, float barWidth, float scaleFactor)
        {
            base.DrawSingleBar(g, pane, curve, index, pos, baseAxis, valueAxis, barWidth, scaleFactor);
            PointPair pointPair = curve.Points[index];
            ErrorTag errorTag = pointPair.Tag as ErrorTag;
            if (pointPair.IsInvalid || errorTag == null)
            {
                return;
            }

            double curBase, curLowVal, curHiVal;
            ValueHandler valueHandler = new ValueHandler(pane, false);
            valueHandler.GetValues(curve, index, out curBase, out curLowVal, out curHiVal);

            float pixBase = baseAxis.Scale.Transform(curve.IsOverrideOrdinal, index, curBase);
            double lowError = curHiVal - errorTag.Error;
            float pixLowError = valueAxis.Scale.Transform(lowError);
            float pixHiError = valueAxis.Scale.Transform(lowError + errorTag.Error*2);

            float clusterWidth = pane.BarSettings.GetClusterWidth();
            //float barWidth = curve.GetBarWidth( pane );
            float clusterGap = pane.BarSettings.MinClusterGap * barWidth;
            float barGap = barWidth * pane.BarSettings.MinBarGap;

            // 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.BarSettings.Base == BarBase.X)
            {
                if (barWidth >= 3 && errorTag.Error > 0)
                {
                    // Draw whiskers
                    float pixMidX = (float)Math.Round(pixSide + barWidth / 2);

                    // Line
                    g.DrawLine(ErrorPen, pixMidX, pixHiError, pixMidX, pixLowError);
                    if (barWidth >= PIX_TERM_WIDTH)
                    {
                        // Ends
                        float pixLeft = pixMidX - (float) Math.Round(PIX_TERM_WIDTH/2);
                        float pixRight = pixLeft + PIX_TERM_WIDTH - 1;
                        g.DrawLine(ErrorPen, pixLeft, pixHiError, pixRight, pixHiError);
                        g.DrawLine(ErrorPen, pixLeft, pixLowError, pixRight, pixLowError);
                    }
                }
            }
            else
            {
                if (barWidth >= 3 && errorTag.Error > 0)
                {
                    // Draw whiskers
                    float pixMidY = (float)Math.Round(pixSide + barWidth / 2) + 1;

                    // Line
                    g.DrawLine(ErrorPen, pixLowError, pixMidY, pixHiError, pixMidY);
                    if (barWidth >= PIX_TERM_WIDTH)
                    {
                        // Ends
                        float pixTop = pixMidY - (float) Math.Round(PIX_TERM_WIDTH/2);
                        float pixBottom = pixTop + PIX_TERM_WIDTH - 1;
                        g.DrawLine(ErrorPen, pixHiError, pixTop, pixHiError, pixBottom);
                        g.DrawLine(ErrorPen, pixLowError, pixTop, pixLowError, pixBottom);
                    }
                }
            }
        }
Esempio n. 26
0
		/// <summary>
		/// Create a <see cref="TextObj" /> for each bar in the <see cref="GraphPane" />.
		/// </summary>
		/// <remarks>
		/// This method will go through the bars, create a label that corresponds to the bar value,
		/// and place it on the graph depending on user preferences.  This works for horizontal or
		/// vertical bars in clusters or stacks, but only for <see cref="BarItem" /> types.  This method
		/// does not apply to <see cref="ErrorBarItem" /> or <see cref="HiLowBarItem" /> objects.
		/// Call this method only after calling <see cref="GraphPane.AxisChange()" />.
		/// </remarks>
		/// <param name="pane">The GraphPane in which to place the text labels.</param>
		/// <param name="isBarCenter">true to center the labels inside the bars, false to
		/// place the labels just above the top of the bar.</param>
		/// <param name="valueFormat">The double.ToString string format to use for creating
		/// the labels.
		/// </param>
		/// <param name="fontColor">The color in which to draw the labels</param>
		/// <param name="fontFamily">The string name of the font family to use for the labels</param>
		/// <param name="fontSize">The floating point size of the font, in scaled points</param>
		/// <param name="isBold">true for a bold font type, false otherwise</param>
		/// <param name="isItalic">true for an italic font type, false otherwise</param>
		/// <param name="isUnderline">true for an underline font type, false otherwise</param>
		public static void CreateBarLabels(GraphPane pane, bool isBarCenter, string valueFormat,
		                                   string fontFamily, float fontSize, Color fontColor, bool isBold, bool isItalic,
		                                   bool isUnderline)
		{
			bool isVertical = pane.BarSettings.Base == BarBase.X;

			// keep a count of the number of BarItems
			int curveIndex = 0;

			// Get a valuehandler to do some calculations for us
			ValueHandler valueHandler = new ValueHandler(pane, true);

			// Loop through each curve in the list
			foreach (CurveItem curve in pane.CurveList) {
				// work with BarItems only
				BarItem bar = curve as BarItem;
				if (bar != null) {
					IPointList points = curve.Points;

					// ADD JKB 9/21/07
					// The labelOffset should depend on whether the curve is YAxis or Y2Axis.
					// JHC - Generalize to any value axis
					// Make the gap between the bars and the labels = 1.5% of the axis range
					float labelOffset;

					Scale scale = curve.ValueAxis(pane).Scale;
					labelOffset = (float) (scale._max - scale._min)*0.015f;

					// Loop through each point in the BarItem
					for (int i = 0; i < points.Count; i++) {
						// Get the high, low and base values for the current bar
						// note that this method will automatically calculate the "effective"
						// values if the bar is stacked
						double baseVal, lowVal, hiVal;
						valueHandler.GetValues(curve, i, out baseVal, out lowVal, out hiVal);

						// Get the value that corresponds to the center of the bar base
						// This method figures out how the bars are positioned within a cluster
						float centerVal = (float) valueHandler.BarCenterValue(bar,
						                                                      bar.GetBarWidth(pane), i, baseVal, curveIndex);

						// Create a text label -- note that we have to go back to the original point
						// data for this, since hiVal and lowVal could be "effective" values from a bar stack
						string barLabelText = (isVertical ? points[i].Y : points[i].X).ToString(valueFormat);

						// Calculate the position of the label -- this is either the X or the Y coordinate
						// depending on whether they are horizontal or vertical bars, respectively
						float position;
						if (isBarCenter)
							position = (float) (hiVal + lowVal)/2.0f;
						else if (hiVal >= 0)
							position = (float) hiVal + labelOffset;
						else
							position = (float) hiVal - labelOffset;

						// Create the new TextObj
						TextObj label;
						if (isVertical)
							label = new TextObj(barLabelText, centerVal, position);
						else
							label = new TextObj(barLabelText, position, centerVal);

						label.FontSpec.Family = fontFamily;

						// Configure the TextObj

						// CHANGE JKB 9/21/07
						// CoordinateFrame should depend on whether curve is YAxis or Y2Axis.
						label.Location.CoordinateFrame =
							(isVertical && curve.IsY2Axis) ? CoordType.AxisXY2Scale : CoordType.AxisXYScale;

						label.FontSpec.Size = fontSize;
						label.FontSpec.FontColor = fontColor;
						label.FontSpec.IsItalic = isItalic;
						label.FontSpec.IsBold = isBold;
						label.FontSpec.IsUnderline = isUnderline;

						label.FontSpec.Angle = isVertical ? 90 : 0;
						label.Location.AlignH = isBarCenter
						                        	? AlignH.Center
						                        	: (hiVal >= 0 ? AlignH.Left : AlignH.Right);
						label.Location.AlignV = AlignV.Center;
						label.FontSpec.Border.IsVisible = false;
						label.FontSpec.Fill.IsVisible = false;

						// Add the TextObj to the GraphPane
						pane.GraphObjList.Add(label);
					}
					curveIndex++;
				}
			}
		}
Esempio n. 27
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="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>
        protected override 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;
            var 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 ||
                Double.IsNaN(curLowVal) ||
                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)
                    Draw(g, pane, pixSide, pixSide + barWidth, pixLowVal,
                         pixHiVal, scaleFactor, true,
                         curve.Points[index]);
                else
                    Draw(g, pane, pixLowVal, pixHiVal, pixSide, pixSide + barWidth,
                         scaleFactor, true,
                         curve.Points[index]);
            }
        }
        /// <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;
        }
Esempio n. 29
0
        /// <summary>
        /// Draw this <see cref="CurveItem"/> to the specified <see cref="Graphics"/>
        /// device as a symbol at each defined point.  The routine
        /// only draws the symbols; the lines are draw by the
        /// <see cref="Line.DrawCurve"/> method.  This method
        /// is normally only called by the Draw method of the
        /// <see cref="CurveItem"/> 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="LineItem"/> representing this
        /// curve.</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, GraphPane pane, LineItem curve, float scaleFactor)
        {
            float      tmpX, tmpY;
            double     curX, curY, lowVal;
            IPointList points = curve.Points;

            if (points != null && (_border.IsVisible || _fill.IsVisible))
            {
                SmoothingMode sModeSave = g.SmoothingMode;
                if (_isAntiAlias)
                {
                    g.SmoothingMode = SmoothingMode.HighQuality;
                }

                // For the sake of speed, go ahead and create a solid brush and a pen
                // If it's a gradient fill, it will be created on the fly for each symbol
                //SolidBrush	brush = new SolidBrush( this.fill.Color );

                using (Pen pen = _border.MakePen(pane.IsPenWidthScaled, scaleFactor))
                    using (GraphicsPath path = MakePath(g, scaleFactor))
                    {
                        RectangleF rect = path.GetBounds();

                        using (Brush brush = Fill.MakeBrush(rect))
                        {
                            var   valueHandler = new ValueHandler(pane, false);
                            Scale xScale       = pane.XAxis.Scale;
                            Scale yScale       = curve.GetYAxis(pane).Scale;

                            bool xIsLog = xScale.IsLog;
                            bool yIsLog = yScale.IsLog;

                            // Loop over each defined point
                            for (int i = 0; i < points.Count; i++)
                            {
                                // Get the user scale values for the current point
                                // use the valueHandler only for stacked types
                                if (pane.LineType == LineType.Stack)
                                {
                                    valueHandler.GetValues(curve, i, out curX, out lowVal, out curY);
                                }
                                // otherwise, just access the values directly.  Avoiding the valueHandler for
                                // non-stacked types is an optimization to minimize overhead in case there are
                                // a large number of points.
                                else
                                {
                                    curX = points[i].X;
                                    if (curve is StickItem)
                                    {
                                        curY = points[i].Z;
                                    }
                                    else
                                    {
                                        curY = points[i].Y;
                                    }
                                }

                                // 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 (curX != PointPair.Missing &&
                                    curY != PointPair.Missing &&
                                    !Double.IsNaN(curX) &&
                                    !Double.IsNaN(curY) &&
                                    !Double.IsInfinity(curX) &&
                                    !Double.IsInfinity(curY) &&
                                    (curX > 0 || !xIsLog) &&
                                    (!yIsLog || curY > 0.0))
                                {
                                    // Transform the user scale values to pixel locations
                                    tmpX = xScale.Transform(curve.IsOverrideOrdinal, i, curX);
                                    tmpY = yScale.Transform(curve.IsOverrideOrdinal, i, curY);

                                    // If the fill type for this symbol is a Gradient by value type,
                                    // the make a brush corresponding to the appropriate current value
                                    if (_fill.IsGradientValueType)
                                    {
                                        using (Brush tBrush = _fill.MakeBrush(rect, points[i]))
                                            DrawSymbol(g, tmpX, tmpY, path, pen, tBrush);
                                    }
                                    else
                                    {
                                        // Otherwise, the brush is already defined
                                        // Draw the symbol at the specified pixel location
                                        DrawSymbol(g, tmpX, tmpY, path, pen, brush);
                                    }
                                }
                            }
                        }
                    }

                g.SmoothingMode = sModeSave;
            }
        }