Example #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ZoomState"/> class. 
 /// Construct a <see cref="ZoomState"/> object from the scale ranges settings contained in the specified <see cref="GraphPane"/>.
 /// </summary>
 /// <param name="pane">
 /// The <see cref="GraphPane"/> from which to obtain the scale range values.
 /// </param>
 /// <param name="type">
 /// A <see cref="StateType"/> enumeration that indicates whether this saved RequestState is from a pan or zoom.
 /// </param>
 public ZoomState(GraphPane pane, StateType type)
 {
     this._xAxis = new ScaleState(pane.XAxis);
     this._x2Axis = new ScaleState(pane.X2Axis);
     this._yAxis = new ScaleStateList(pane.YAxisList);
     this._y2Axis = new ScaleStateList(pane.Y2AxisList);
     this._type = type;
 }
Example #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ValueHandler"/> class. 
 /// Basic constructor that saves a reference to the parent
 /// <see cref="GraphPane"/> object.
 /// </summary>
 /// <param name="pane">
 /// The parent <see cref="GraphPane"/> object.
 /// </param>
 /// <param name="initialize">
 /// A <see cref="bool"/> flag to indicate whether or not the drawing variables should be initialized.  Initialization is not required if this is part of
 /// a ZedGraph internal draw operation (i.e., its in the middle of a call to <see cref="GraphPane.Draw"/>).  Otherwise, you should initialize to make
 /// sure the drawing variables are configured.  true to do an initialization, false otherwise.
 /// </param>
 public ValueHandler(GraphPane pane, bool initialize)
 {
     this._pane = pane;
     if (initialize)
     {
         // just create a dummy image, which results in a full draw operation
         using (Image image = pane.GetImage())
         {
         }
     }
 }
Example #3
0
 /// <summary>
 /// Gets a flag indicating if the X axis is the independent axis for this <see cref="CurveItem"/>
 /// </summary>
 /// <param name="pane">
 /// The parent <see cref="GraphPane"/> of this <see cref="CurveItem"/>.
 /// </param>
 /// <value>
 /// true if the X axis is independent, false otherwise
 /// </value>
 /// <returns>
 /// The <see cref="bool"/>.
 /// </returns>
 internal override bool IsXIndependent(GraphPane pane)
 {
     return true;
 }
Example #4
0
        /// <summary>
        /// Draw a legend key entry for this <see cref="LineItem"/> at the specified location
        /// </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="rect">
        /// The <see cref="RectangleF"/> struct that specifies the location for the legend key
        /// </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 override void DrawLegendKey(Graphics g, GraphPane pane, RectangleF rect, float scaleFactor)
        {
            // Draw a sample curve to the left of the label text
            int xMid = (int)(rect.Left + rect.Width / 2.0F);
            int yMid = (int)(rect.Top + rect.Height / 2.0F);

            // RectangleF rect2 = rect;
            // rect2.Y = yMid;
            // rect2.Height = rect.Height / 2.0f;
            this._line.Fill.Draw(g, rect);

            this._line.DrawSegment(g, pane, rect.Left, yMid, rect.Right, yMid, scaleFactor);

            // Draw a sample symbol to the left of the label text
            this._symbol.DrawSymbol(g, pane, xMid, yMid, scaleFactor, false, null);
        }
Example #5
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="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 DrawCurveOriginal(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;
            float minY = pane.Chart.Rect.Top;
            float maxY = pane.Chart.Rect.Bottom;

            using (Pen pen = source.GetPen(pane, scaleFactor))
            {
                if (points != null && !this._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 = PointPairBase.Missing;
                                curY = PointPairBase.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 == PointPairBase.Missing || curY == PointPairBase.Missing || double.IsNaN(curX) || double.IsNaN(curY)
                            || double.IsInfinity(curX) || 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 && 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)
                                    {
                                        this.InterpolatePoint(g, pane, curve, lastPt, scaleFactor, pen, lastX, lastY, tmpX, tmpY);
                                    }
                                    else if (!isOut)
                                    {
                                        if (!curve.IsSelected && this._gradientFill.IsGradientValueType)
                                        {
                                            using (Pen tPen = this.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
                                {
                                    this.InterpolatePoint(g, pane, curve, lastPt, scaleFactor, pen, lastX, lastY, tmpX, tmpY);
                                }
                            }

                            lastPt = curPt;
                            lastX = tmpX;
                            lastY = tmpY;
                            lastBad = false;

                            // lastOut = isOut;
                        }
                    }
                }
            }
        }
Example #6
0
        /// <summary>
        /// Close off a <see cref="GraphicsPath"/> that defines a curve
        /// </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 screen pixel coordinates representing the current curve.
        /// </param>
        /// <param name="count">
        /// The number of points contained in the "arrPoints" parameter.
        /// </param>
        /// <param name="yMin">
        /// The Y axis value location where the X axis crosses.
        /// </param>
        /// <param name="path">
        /// The <see cref="GraphicsPath"/> class that represents the curve.
        /// </param>
        public void CloseCurve(GraphPane pane, CurveItem curve, PointF[] arrPoints, int count, double yMin, GraphicsPath path)
        {
            // For non-stacked lines, the fill area is just the area between the curve and the X axis
            if (pane.LineType != LineType.Stack)
            {
                // Determine the current value for the bottom of the curve (usually the Y value where
                // the X axis crosses)
                float yBase;
                Axis yAxis = curve.GetYAxis(pane);
                yBase = yAxis.Scale.Transform(yMin);

                // Add three points to the path to move from the end of the curve (as defined by
                // arrPoints) to the X axis, from there to the start of the curve at the X axis,
                // and from there back up to the beginning of the curve.
                path.AddLine(arrPoints[count - 1].X, arrPoints[count - 1].Y, arrPoints[count - 1].X, yBase);
                path.AddLine(arrPoints[count - 1].X, yBase, arrPoints[0].X, yBase);
                path.AddLine(arrPoints[0].X, yBase, arrPoints[0].X, arrPoints[0].Y);
            }

            // For stacked line types, the fill area is the area between this curve and the curve below it
            else
            {
                PointF[] arrPoints2;
                int count2;

                float tension = this._isSmooth ? this._smoothTension : 0f;

                // Find the next lower curve in the curveList that is also a LineItem type, and use
                // its smoothing properties for the lower side of the filled area.
                int index = pane.CurveList.IndexOf(curve);
                if (index > 0)
                {
                    CurveItem tmpCurve;
                    for (int i = index - 1; i >= 0; i--)
                    {
                        tmpCurve = pane.CurveList[i];
                        if (tmpCurve is LineItem)
                        {
                            tension = ((LineItem)tmpCurve).Line.IsSmooth ? ((LineItem)tmpCurve).Line.SmoothTension : 0f;
                            break;
                        }
                    }
                }

                // Build another points array consisting of the low points (which are actually the points for
                // the curve below the current curve)
                this.BuildLowPointsArray(pane, curve, out arrPoints2, out count2);

                // Add the new points to the GraphicsPath
                path.AddCurve(arrPoints2, 0, count2 - 2, tension);
            }
        }
Example #7
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[(this._stepType == 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 == PointPairBase.Missing || y == PointPairBase.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 (this._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;
            }

            return false;
        }
Example #8
0
        /// <summary>
        /// This method just handles the case where one or more of the coordinates are outrageous, or GDI+ threw an exception.  This method attempts to correct
        /// the outrageous coordinates by interpolating them to a point (along the original line) that lies at the edge of the ChartRect so that GDI+ will handle
        /// it properly.  GDI+ will throw an exception, or just plot the data incorrectly if the coordinates are too large (empirically, this appears to be when
        /// the coordinate value is greater than 5,000,000 or less than -5,000,000).  Although you typically would not see coordinates like this, if you
        /// repeatedly zoom in on a ZedGraphControl, eventually all your points will be way outside the bounds of the plot.
        /// </summary>
        /// <param name="g">
        /// The g.
        /// </param>
        /// <param name="pane">
        /// The pane.
        /// </param>
        /// <param name="curve">
        /// The curve.
        /// </param>
        /// <param name="lastPt">
        /// The last Pt.
        /// </param>
        /// <param name="scaleFactor">
        /// The scale Factor.
        /// </param>
        /// <param name="pen">
        /// The pen.
        /// </param>
        /// <param name="lastX">
        /// The last X.
        /// </param>
        /// <param name="lastY">
        /// The last Y.
        /// </param>
        /// <param name="tmpX">
        /// The tmp X.
        /// </param>
        /// <param name="tmpY">
        /// The tmp Y.
        /// </param>
        private void InterpolatePoint(
            Graphics g, 
            GraphPane pane, 
            CurveItem curve, 
            PointPair lastPt, 
            float scaleFactor, 
            Pen pen, 
            float lastX, 
            float lastY, 
            float tmpX, 
            float tmpY)
        {
            try
            {
                RectangleF chartRect = pane.Chart._rect;

                // try to interpolate values
                bool lastIn = chartRect.Contains(lastX, lastY);
                bool curIn = chartRect.Contains(tmpX, tmpY);

                // If both points are outside the ChartRect, make a new point that is on the LastX/Y
                // side of the ChartRect, and fall through to the code that handles lastIn == true
                if (!lastIn)
                {
                    float newX, newY;

                    if (Math.Abs(lastX) > Math.Abs(lastY))
                    {
                        newX = lastX < 0 ? chartRect.Left : chartRect.Right;
                        newY = lastY + (tmpY - lastY) * (newX - lastX) / (tmpX - lastX);
                    }
                    else
                    {
                        newY = lastY < 0 ? chartRect.Top : chartRect.Bottom;
                        newX = lastX + (tmpX - lastX) * (newY - lastY) / (tmpY - lastY);
                    }

                    lastX = newX;
                    lastY = newY;
                }

                if (!curIn)
                {
                    float newX, newY;

                    if (Math.Abs(tmpX) > Math.Abs(tmpY))
                    {
                        newX = tmpX < 0 ? chartRect.Left : chartRect.Right;
                        newY = tmpY + (lastY - tmpY) * (newX - tmpX) / (lastX - tmpX);
                    }
                    else
                    {
                        newY = tmpY < 0 ? chartRect.Top : chartRect.Bottom;
                        newX = tmpX + (lastX - tmpX) * (newY - tmpY) / (lastY - tmpY);
                    }

                    tmpX = newX;
                    tmpY = newY;
                }

                /*
                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 );
                */
                if (!curve.IsSelected && this._gradientFill.IsGradientValueType)
                {
                    using (Pen tPen = this.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
            {
            }
        }
Example #9
0
        /// <summary>
        /// Draw a tic mark at the specified single position.  This includes the inner, outer, cross and opposite tic marks as required.
        /// </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="pen">
        /// Graphic <see cref="Pen"/> with which to draw the tic mark.
        /// </param>
        /// <param name="pixVal">
        /// The pixel location of the tic mark on this
        /// <see cref="Axis"/>
        /// </param>
        /// <param name="topPix">
        /// The pixel value of the top of the axis border
        /// </param>
        /// <param name="shift">
        /// The number of pixels to shift this axis, based on the value of <see cref="Axis.Cross"/>.  A positive value is into the ChartRect relative to the
        /// default axis position.
        /// </param>
        /// <param name="scaledTic">
        /// The scaled size of a minor tic, in pixel units
        /// </param>
        internal void Draw(Graphics g, GraphPane pane, Pen pen, float pixVal, float topPix, float shift, float scaledTic)
        {
            // draw the outside tic
            if (this.IsOutside)
            {
                g.DrawLine(pen, pixVal, shift, pixVal, shift + scaledTic);
            }

            // draw the cross tic
            if (this._isCrossOutside)
            {
                g.DrawLine(pen, pixVal, 0.0f, pixVal, scaledTic);
            }

            // draw the inside tic
            if (this.IsInside)
            {
                g.DrawLine(pen, pixVal, shift, pixVal, shift - scaledTic);
            }

            // draw the inside cross tic
            if (this._isCrossInside)
            {
                g.DrawLine(pen, pixVal, 0.0f, pixVal, -scaledTic);
            }

            // draw the opposite tic
            if (this.IsOpposite)
            {
                g.DrawLine(pen, pixVal, topPix, pixVal, topPix + scaledTic);
            }
        }
Example #10
0
        /// <summary>
        /// Go through the list of <see cref="PointPair"/> data values for this <see cref="CurveItem"/>
        /// and determine the minimum and maximum values in the data.
        /// </summary>
        /// <param name="xMin">
        /// The minimum X value in the range of data
        /// </param>
        /// <param name="xMax">
        /// The maximum X value in the range of data
        /// </param>
        /// <param name="yMin">
        /// The minimum Y value in the range of data
        /// </param>
        /// <param name="yMax">
        /// The maximum Y value in the range of data
        /// </param>
        /// <param name="ignoreInitial">
        /// ignoreInitial is a boolean value that affects the data range that is considered for the automatic scale ranging (see
        /// <see cref="GraphPane.IsIgnoreInitial"/>).  If true, then initial data points where the Y value is zero are not included when automatically
        /// determining the scale <see cref="Scale.Min"/>,
        /// <see cref="Scale.Max"/>, and <see cref="Scale.MajorStep"/> size.  All data after the first non-zero Y value are included.
        /// </param>
        /// <param name="isBoundedRanges">
        /// Determines if the auto-scaled axis ranges will subset the data points based on any manually set scale range values.
        /// </param>
        /// <param name="pane">
        /// A reference to the <see cref="GraphPane"/> object that is the parent or owner of this object.
        /// </param>
        /// <seealso cref="GraphPane.IsBoundedRanges"/>
        public virtual void GetRange(
            out double xMin, 
            out double xMax, 
            out double yMin, 
            out double yMax, 
            bool ignoreInitial, 
            bool isBoundedRanges, 
            GraphPane pane)
        {
            // The lower and upper bounds of allowable data for the X values.  These
            // values allow you to subset the data values.  If the X range is bounded, then
            // the resulting range for Y will reflect the Y values for the points within the X
            // bounds.
            double xLBound = double.MinValue;
            double xUBound = double.MaxValue;
            double yLBound = double.MinValue;
            double yUBound = double.MaxValue;

            // initialize the values to outrageous ones to start
            xMin = yMin = double.MaxValue;
            xMax = yMax = double.MinValue;

            Axis yAxis = this.GetYAxis(pane);
            Axis xAxis = this.GetXAxis(pane);
            if (yAxis == null || xAxis == null)
            {
                return;
            }

            if (isBoundedRanges)
            {
                xLBound = xAxis._scale._lBound;
                xUBound = xAxis._scale._uBound;
                yLBound = yAxis._scale._lBound;
                yUBound = yAxis._scale._uBound;
            }

            bool isZIncluded = this.IsZIncluded(pane);
            bool isXIndependent = this.IsXIndependent(pane);
            bool isXLog = xAxis.Scale.IsLog;
            bool isYLog = yAxis.Scale.IsLog;
            bool isXOrdinal = xAxis.Scale.IsAnyOrdinal;
            bool isYOrdinal = yAxis.Scale.IsAnyOrdinal;
            bool isZOrdinal = (isXIndependent ? yAxis : xAxis).Scale.IsAnyOrdinal;

            // Loop over each point in the arrays
            // foreach ( PointPair point in this.Points )
            for (int i = 0; i < this.Points.Count; i++)
            {
                PointPair point = this.Points[i];

                double curX = isXOrdinal ? i + 1 : point.X;
                double curY = isYOrdinal ? i + 1 : point.Y;
                double curZ = isZOrdinal ? i + 1 : point.Z;

                bool outOfBounds = curX < xLBound || curX > xUBound || curY < yLBound || curY > yUBound
                                   || (isZIncluded && isXIndependent && (curZ < yLBound || curZ > yUBound))
                                   || (isZIncluded && !isXIndependent && (curZ < xLBound || curZ > xUBound)) || (curX <= 0 && isXLog)
                                   || (curY <= 0 && isYLog);

                // ignoreInitial becomes false at the first non-zero
                // Y value
                if (ignoreInitial && curY != 0 && curY != PointPairBase.Missing)
                {
                    ignoreInitial = false;
                }

                if (!ignoreInitial && !outOfBounds && curX != PointPairBase.Missing && curY != PointPairBase.Missing)
                {
                    if (curX < xMin)
                    {
                        xMin = curX;
                    }

                    if (curX > xMax)
                    {
                        xMax = curX;
                    }

                    if (curY < yMin)
                    {
                        yMin = curY;
                    }

                    if (curY > yMax)
                    {
                        yMax = curY;
                    }

                    if (isZIncluded && isXIndependent && curZ != PointPairBase.Missing)
                    {
                        if (curZ < yMin)
                        {
                            yMin = curZ;
                        }

                        if (curZ > yMax)
                        {
                            yMax = curZ;
                        }
                    }
                    else if (isZIncluded && curZ != PointPairBase.Missing)
                    {
                        if (curZ < xMin)
                        {
                            xMin = curZ;
                        }

                        if (curZ > xMax)
                        {
                            xMax = curZ;
                        }
                    }
                }
            }
        }
Example #11
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 abstract bool GetCoords(GraphPane pane, int i, out string coords);
Example #12
0
        /// <summary>
        /// Calculate the width of each bar, depending on the actual bar type
        /// </summary>
        /// <param name="pane">
        /// The pane.
        /// </param>
        /// <returns>
        /// The width for an individual bar, in pixel units
        /// </returns>
        public float GetBarWidth(GraphPane pane)
        {
            // Total axis width =
            // npts * ( nbars * ( bar + bargap ) - bargap + clustgap )
            // cg * bar = cluster gap
            // npts = max number of points in any curve
            // nbars = total number of curves that are of type IsBar
            // bar = bar width
            // bg * bar = bar gap
            // therefore:
            // totwidth = npts * ( nbars * (bar + bg*bar) - bg*bar + cg*bar )
            // totwidth = bar * ( npts * ( nbars * ( 1 + bg ) - bg + cg ) )
            // solve for bar
            float barWidth;

            if (this is ErrorBarItem)
            {
                barWidth = ((ErrorBarItem)this).Bar.Symbol.Size * pane.CalcScaleFactor();
            }

            // 			else if ( this is HiLowBarItem && pane._barSettings.Type != BarType.ClusterHiLow )
            // 				barWidth = (float) ( ((HiLowBarItem)this).Bar.GetBarWidth( pane,
            // 						((HiLowBarItem)this).BaseAxis(pane), pane.CalcScaleFactor() ) );
            // 				barWidth = (float) ( ((HiLowBarItem)this).Bar.Size *
            // 						pane.CalcScaleFactor() );
            else
            {
                // BarItem or LineItem
                // For stacked bar types, the bar width will be based on a single bar
                float numBars = 1.0F;
                if (pane._barSettings.Type == BarType.Cluster)
                {
                    numBars = pane.CurveList.NumClusterableBars;
                }

                float denom = numBars * (1.0F + pane._barSettings.MinBarGap) - pane._barSettings.MinBarGap + pane._barSettings.MinClusterGap;
                if (denom <= 0)
                {
                    denom = 1;
                }

                barWidth = pane.BarSettings.GetClusterWidth() / denom;
            }

            if (barWidth <= 0)
            {
                return 1;
            }

            return barWidth;
        }
Example #13
0
 /// <summary>
 /// Draw a legend key entry for this <see cref="CurveItem"/> at the specified location. This abstract base method passes through to
 /// <see cref="BarItem.DrawLegendKey"/> or
 /// <see cref="LineItem.DrawLegendKey"/> to do the rendering.
 /// </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="rect">
 /// The <see cref="RectangleF"/> struct that specifies the location for the legend key
 /// </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 abstract void DrawLegendKey(Graphics g, GraphPane pane, RectangleF rect, float scaleFactor);
Example #14
0
 /// <summary>
 /// Do all rendering associated with this <see cref="CurveItem"/> to the specified
 /// <see cref="Graphics"/> device.  This method is normally only called by the Draw method of the parent <see cref="CurveList"/>
 /// collection 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="pos">
 /// The ordinal position of the current <see cref="Bar"/>
 /// 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 abstract void Draw(Graphics g, GraphPane pane, int pos, float scaleFactor);
Example #15
0
        /// <summary>
        /// Returns a reference to the <see cref="Axis"/> object that is the "base" (independent axis) from which the values are drawn. 
        /// </summary>
        /// <param name="pane">
        /// The pane.
        /// </param>
        /// <remarks>
        /// This property is determined by the value of <see cref="BarSettings.Base"/> for
        /// <see cref="BarItem"/>, <see cref="ErrorBarItem"/>, and <see cref="HiLowBarItem"/>
        /// types.  It is always the X axis for regular <see cref="LineItem"/> types. Note that the <see cref="BarSettings.Base"/> setting can override the
        /// <see cref="IsY2Axis"/> and <see cref="YAxisIndex"/> settings for bar types (this is because all the bars that are clustered together must share the
        /// same base axis).
        /// </remarks>
        /// <seealso cref="BarBase"/>
        /// <seealso cref="ValueAxis"/>
        /// <returns>
        /// The <see cref="Axis"/>.
        /// </returns>
        public virtual Axis BaseAxis(GraphPane pane)
        {
            BarBase barBase;

            if (this is BarItem || this is ErrorBarItem || this is HiLowBarItem)
            {
                barBase = pane._barSettings.Base;
            }
            else
            {
                barBase = this._isX2Axis ? BarBase.X2 : BarBase.X;
            }

            if (barBase == BarBase.X)
            {
                return pane.XAxis;
            }

            if (barBase == BarBase.X2)
            {
                return pane.X2Axis;
            }

            if (barBase == BarBase.Y)
            {
                return pane.YAxis;
            }

            return pane.Y2Axis;
        }
Example #16
0
        /// <summary>
        /// Draw the this <see cref="CurveItem"/> to the specified <see cref="Graphics"/>
        /// device using the specified smoothing property (<see cref="Line.SmoothTension"/>). The routine draws the line segments and the area fill (if any, see
        /// <see cref="FillType"/>; the symbols are drawn by the <see cref="Symbol.Draw"/> method.  This method is normally only called by the Draw method of
        /// the
        /// <see cref="CurveItem"/> object.  Note that the <see cref="StepType"/> property is ignored for smooth lines (e.g., when <see cref="Line.IsSmooth"/>
        /// is true).
        /// </summary>
        /// <param name="g">
        /// A graphic device object to be drawn into.  This is normally e.Graphics from the PaintEventArgs argument to the Paint() method.
        /// </param>
        /// <param name="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 DrawSmoothFilledCurve(Graphics g, GraphPane pane, CurveItem curve, float scaleFactor)
        {
            Line source = this;
            if (curve.IsSelected)
            {
                source = Selection.Line;
            }

            PointF[] arrPoints;
            int count;
            IPointList points = curve.Points;

            if (this.IsVisible && !this.Color.IsEmpty && points != null && this.BuildPointsArray(pane, curve, out arrPoints, out count) && count > 2)
            {
                float tension = this._isSmooth ? this._smoothTension : 0f;

                // Fill the curve if needed
                if (this.Fill.IsVisible)
                {
                    Axis yAxis = curve.GetYAxis(pane);

                    using (GraphicsPath path = new GraphicsPath(FillMode.Winding))
                    {
                        path.AddCurve(arrPoints, 0, count - 2, tension);

                        double yMin = yAxis._scale._min < 0 ? 0.0 : yAxis._scale._min;
                        this.CloseCurve(pane, curve, arrPoints, count, yMin, path);

                        RectangleF rect = path.GetBounds();
                        using (Brush brush = source._fill.MakeBrush(rect))
                        {
                            if (pane.LineType == LineType.Stack && yAxis.Scale._min < 0 && this.IsFirstLine(pane, curve))
                            {
                                float zeroPix = yAxis.Scale.Transform(0);
                                RectangleF tRect = pane.Chart._rect;
                                tRect.Height = zeroPix - tRect.Top;
                                if (tRect.Height > 0)
                                {
                                    Region reg = g.Clip;
                                    g.SetClip(tRect);
                                    g.FillPath(brush, path);
                                    g.SetClip(pane.Chart._rect);
                                }
                            }
                            else
                            {
                                g.FillPath(brush, path);
                            }

                            // brush.Dispose();
                        }

                        // restore the zero line if needed (since the fill tends to cover it up)
                        yAxis.FixZeroLine(g, pane, scaleFactor, rect.Left, rect.Right);
                    }
                }

                // If it's a smooth curve, go ahead and render the path.  Otherwise, use the
                // standard drawcurve method just in case there are missing values.
                if (this._isSmooth)
                {
                    using (Pen pen = this.GetPen(pane, scaleFactor))
                    {
                        // Stroke the curve
                        g.DrawCurve(pen, arrPoints, 0, count - 2, tension);

                        // pen.Dispose();
                    }
                }
                else
                {
                    this.DrawCurve(g, pane, curve, scaleFactor);
                }
            }
        }
Example #17
0
        /// <summary>
        /// Render the <see cref="Line"/>'s as vertical sticks (from a <see cref="StickItem"/>) 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"/> 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 DrawSticks(Graphics g, GraphPane pane, CurveItem curve, float scaleFactor)
        {
            Line source = this;
            if (curve.IsSelected)
            {
                source = Selection.Line;
            }

            Axis yAxis = curve.GetYAxis(pane);
            Axis xAxis = curve.GetXAxis(pane);

            float basePix = yAxis.Scale.Transform(0.0);
            using (Pen pen = source.GetPen(pane, scaleFactor))
            {
                for (int i = 0; i < curve.Points.Count; i++)
                {
                    PointPair pt = curve.Points[i];

                    if (pt.X != PointPairBase.Missing && pt.Y != PointPairBase.Missing && !double.IsNaN(pt.X) && !double.IsNaN(pt.Y)
                        && !double.IsInfinity(pt.X) && !double.IsInfinity(pt.Y) && (!xAxis._scale.IsLog || pt.X > 0.0)
                        && (!yAxis._scale.IsLog || pt.Y > 0.0))
                    {
                        float pixY = yAxis.Scale.Transform(curve.IsOverrideOrdinal, i, pt.Y);
                        float pixX = xAxis.Scale.Transform(curve.IsOverrideOrdinal, i, pt.X);

                        if (pixX >= pane.Chart._rect.Left && pixX <= pane.Chart._rect.Right)
                        {
                            if (pixY > pane.Chart._rect.Bottom)
                            {
                                pixY = pane.Chart._rect.Bottom;
                            }

                            if (pixY < pane.Chart._rect.Top)
                            {
                                pixY = pane.Chart._rect.Top;
                            }

                            if (!curve.IsSelected && this._gradientFill.IsGradientValueType)
                            {
                                using (Pen tPen = this.GetPen(pane, scaleFactor, pt)) g.DrawLine(tPen, pixX, pixY, pixX, basePix);
                            }
                            else
                            {
                                g.DrawLine(pen, pixX, pixY, pixX, basePix);
                            }
                        }
                    }
                }
            }
        }
Example #18
0
 /// <summary>
 /// The get pen.
 /// </summary>
 /// <param name="pane">
 /// The pane.
 /// </param>
 /// <param name="scaleFactor">
 /// The scale factor.
 /// </param>
 /// <returns>
 /// The <see cref="Pen"/>.
 /// </returns>
 internal Pen GetPen(GraphPane pane, float scaleFactor)
 {
     return new Pen(this._color, pane.ScaledPenWidth(this._penWidth, scaleFactor));
 }
Example #19
0
        /// <summary>
        /// The is first line.
        /// </summary>
        /// <param name="pane">
        /// The pane.
        /// </param>
        /// <param name="curve">
        /// The curve.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        private bool IsFirstLine(GraphPane pane, CurveItem curve)
        {
            CurveList curveList = pane.CurveList;

            for (int j = 0; j < curveList.Count; j++)
            {
                CurveItem tCurve = curveList[j];

                if (tCurve is LineItem && tCurve.IsY2Axis == curve.IsY2Axis && tCurve.YAxisIndex == curve.YAxisIndex)
                {
                    return tCurve == curve;
                }
            }

            return false;
        }
Example #20
0
        /// <summary>
        /// Setup the Transform Matrix to handle drawing of this <see cref="Y2Axis"/>
        /// </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="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 override void SetTransformMatrix(Graphics g, GraphPane pane, float scaleFactor)
        {
            // Move the origin to the BottomRight of the ChartRect, which is the left
            // side of the Y2 axis (facing from the label side)
            g.TranslateTransform(pane.Chart._rect.Right, pane.Chart._rect.Bottom);

            // rotate so this axis is in the left-right direction
            g.RotateTransform(-90);
        }
Example #21
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[(this._stepType == 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 == PointPairBase.Missing || y == PointPairBase.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 (this._isSmooth || index == 0 || this.StepType == StepType.NonStep)
                        {
                            arrPoints[index].X = curX;
                            arrPoints[index].Y = curY;
                        }
                        else if (this.StepType == StepType.ForwardStep || this.StepType == StepType.ForwardSegment)
                        {
                            arrPoints[index].X = curX;
                            arrPoints[index].Y = lastY;
                            index++;
                            arrPoints[index].X = curX;
                            arrPoints[index].Y = curY;
                        }
                        else if (this.StepType == StepType.RearwardStep || this.StepType == StepType.RearwardSegment)
                        {
                            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;
            }

            return false;
        }
Example #22
0
 /*
         override internal bool IsCrossed( GraphPane pane )
         {
             return !this.crossAuto && this.cross > pane.YAxis.Min && this.cross < pane.YAxis.Max;
         }
 */
 /// <summary>
 /// Gets the "Cross" axis that corresponds to this axis.
 /// </summary>
 /// <remarks>
 /// The cross axis is the axis which determines the of this Axis when the
 /// <see cref="Axis.Cross">Axis.Cross</see> property is used.  The cross axis for any <see cref="XAxis"/> or <see cref="X2Axis"/>
 /// is always the primary <see cref="YAxis"/>, and the cross axis for any <see cref="YAxis"/> or <see cref="Y2Axis"/> is always the primary
 /// <see cref="XAxis"/>.
 /// </remarks>
 /// <param name="pane">
 /// A reference to the <see cref="GraphPane"/> object that is the parent or owner of this object.
 /// </param>
 /// <returns>
 /// The <see cref="Axis"/>.
 /// </returns>
 public override Axis GetCrossAxis(GraphPane pane)
 {
     return pane.YAxis;
 }
Example #23
0
        /// <summary>
        /// Do all rendering associated with this <see cref="Line"/> to the specified
        /// <see cref="Graphics"/> device.  This method is normally only called by the Draw method of the parent <see cref="LineItem"/> object.
        /// </summary>
        /// <param name="g">
        /// A graphic device object to be drawn into.  This is normally e.Graphics from the PaintEventArgs argument to the Paint() method.
        /// </param>
        /// <param name="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, CurveItem curve, float scaleFactor)
        {
            // If the line is being shown, draw it
            if (this.IsVisible)
            {
                // How to handle fill vs nofill?
                // if ( isSelected )
                // 	GraphPane.Default.SelectedLine.
                SmoothingMode sModeSave = g.SmoothingMode;
                if (this._isAntiAlias)
                {
                    g.SmoothingMode = SmoothingMode.HighQuality;
                }

                if (curve is StickItem)
                {
                    this.DrawSticks(g, pane, curve, scaleFactor);
                }
                else if (this.IsSmooth || this.Fill.IsVisible)
                {
                    this.DrawSmoothFilledCurve(g, pane, curve, scaleFactor);
                }
                else
                {
                    this.DrawCurve(g, pane, curve, scaleFactor);
                }

                g.SmoothingMode = sModeSave;
            }
        }
Example #24
0
 /// <summary>
 /// Setup the Transform Matrix to handle drawing of this <see cref="XAxis"/>
 /// </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="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 override void SetTransformMatrix(Graphics g, GraphPane pane, float scaleFactor)
 {
     // Move the origin to the BottomLeft of the ChartRect, which is the left
     // side of the X axis (facing from the label side)
     g.TranslateTransform(pane.Chart._rect.Left, pane.Chart._rect.Bottom);
 }
Example #25
0
        /// <summary>
        /// Do all rendering associated with this <see cref="LineItem"/> to the specified
        /// <see cref="Graphics"/> device.  This method is normally only called by the Draw method of the parent <see cref="CurveList"/>
        /// collection 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="pos">
        /// The ordinal position of the current <see cref="Bar"/>
        /// 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 override void Draw(Graphics g, GraphPane pane, int pos, float scaleFactor)
        {
            if (this._isVisible)
            {
                this.Line.Draw(g, pane, this, scaleFactor);

                this.Symbol.Draw(g, pane, this, scaleFactor, this.IsSelected);
            }
        }
Example #26
0
        /// <summary>
        /// Calculate the "shift" size, in pixels, in order to shift the axis from its default location to the value specified by
        /// <see cref="Axis.Cross"/>.
        /// </summary>
        /// <param name="pane">
        /// A reference to the <see cref="GraphPane"/> object that is the parent or owner of this object.
        /// </param>
        /// <returns>
        /// The shift amount measured in pixels
        /// </returns>
        internal override float CalcCrossShift(GraphPane pane)
        {
            double effCross = this.EffectiveCrossValue(pane);

            if (!this._crossAuto)
            {
                return pane.YAxis.Scale.Transform(effCross) - pane.YAxis.Scale._maxPix;
            }

            return 0;
        }
Example #27
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 >= this._points.Count)
            {
                return false;
            }

            PointPair pt = this._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 = this.GetYAxis(pane);
            Axis xAxis = this.GetXAxis(pane);

            PointF pixPt = new PointF(xAxis.Scale.Transform(this._isOverrideOrdinal, i, x), yAxis.Scale.Transform(this._isOverrideOrdinal, i, y));

            if (!pane.Chart.Rect.Contains(pixPt))
            {
                return false;
            }

            float halfSize = this._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;
        }
Example #28
0
 /// <summary>
 /// Determines if this <see cref="Axis"/> object is a "primary" one.
 /// </summary>
 /// <remarks>
 /// The primary axes are the <see cref="XAxis"/> (always), the first
 /// <see cref="YAxis"/> in the <see cref="GraphPane.YAxisList"/>
 /// (<see cref="CurveItem.YAxisIndex"/> = 0),  and the first
 /// <see cref="Y2Axis"/> in the <see cref="GraphPane.Y2AxisList"/>
 /// (<see cref="CurveItem.YAxisIndex"/> = 0).  Note that
 /// <see cref="GraphPane.YAxis"/> and <see cref="GraphPane.Y2Axis"/>
 /// always reference the primary axes.
 /// </remarks>
 /// <param name="pane">
 /// A reference to the <see cref="GraphPane"/> object that is the parent or owner of this object.
 /// </param>
 /// <returns>
 /// true for a primary <see cref="Axis"/> (for the <see cref="XAxis"/>, this is always true), false otherwise
 /// </returns>
 internal override bool IsPrimary(GraphPane pane)
 {
     return this == pane.XAxis;
 }
Example #29
0
 /// <summary>
 /// Gets a flag indicating if the Z data range should be included in the axis scaling calculations.
 /// </summary>
 /// <param name="pane">
 /// The parent <see cref="GraphPane"/> of this <see cref="CurveItem"/>.
 /// </param>
 /// <value>
 /// true if the Z data are included, false otherwise
 /// </value>
 /// <returns>
 /// The <see cref="bool"/>.
 /// </returns>
 internal override bool IsZIncluded(GraphPane pane)
 {
     return false;
 }
Example #30
0
 /// <summary>
 /// Render a single <see cref="Line"/> segment 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="x1">
 /// The x position of the starting point that defines the line segment in screen pixel units
 /// </param>
 /// <param name="y1">
 /// The y position of the starting point that defines the line segment in screen pixel units
 /// </param>
 /// <param name="x2">
 /// The x position of the ending point that defines the line segment in screen pixel units
 /// </param>
 /// <param name="y2">
 /// The y position of the ending point that defines the line segment in screen pixel units
 /// </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 DrawSegment(Graphics g, GraphPane pane, float x1, float y1, float x2, float y2, float scaleFactor)
 {
     if (this._isVisible && !this.Color.IsEmpty)
     {
         using (Pen pen = this.GetPen(pane, scaleFactor))
         {
             g.DrawLine(pen, x1, y1, x2, y2);
         }
     }
 }