//============================================================================ //ZedGraph Class Library - A Flexible Line Graph/Bar Graph Library in C# //Copyright ?2006 John Champion // //This library is free software; you can redistribute it and/or //modify it under the terms of the GNU Lesser General Public //License as published by the Free Software Foundation; either //version 2.1 of the License, or (at your option) any later version. // //This library is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //Lesser General Public License for more details. // //You should have received a copy of the GNU Lesser General Public //License along with this library; if not, write to the Free Software //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //============================================================================= #region Using directives using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Text; using System.Runtime.Serialization; using System.Security.Permissions; #endregion namespace DrawGraph { /// /// Encapsulates a Japanese CandleStick curve type that displays a vertical (or horizontal) /// line displaying the range of data values at each sample point, plus a filled bar /// signifying the opening and closing value for the sample. /// /// For this type to work properly, your must contain /// objects, rather than ordinary types. /// This is because the type actually displays 5 data values /// but the only stores 3 data values. The /// stores , , /// , , and /// members. /// For a JapaneseCandleStick chart, the range between opening and closing values /// is drawn as a filled bar, with the filled color different /// () for the case of /// /// higher than , and /// /// for the reverse. The width of the bar is controlled /// by the property, which is specified in /// points (1/72nd inch), and scaled according to . /// The candlesticks are drawn horizontally or vertically depending on the /// value of , which is a /// enum type. /// John Champion /// $Revision: 3.5 $ $Date: 2007/04/16 00:03:02 $ [Serializable] public class JapaneseCandleStickItem : CurveItem, ICloneable, ISerializable { #region Fields /// /// Private field that stores a reference to the /// class defined for this . Use the public /// property to access this value. /// /// private JapaneseCandleStick _stick; #endregion #region Properties /// /// Gets a reference to the class defined /// for this . /// public JapaneseCandleStick Stick { get { return _stick; } } /// /// Gets a flag indicating if the X axis is the independent axis for this /// /// The parent of this . /// /// true if the X axis is independent, false otherwise override internal bool IsXIndependent( GraphPane pane ) { return pane._barSettings.Base == BarBase.X; } /// /// Gets a flag indicating if the Z data range should be included in the axis scaling calculations. /// /// /// IsZIncluded is true for objects, since the Y and Z /// values are defined as the High and Low values for the day. /// The parent of this . /// /// true if the Z data are included, false otherwise override internal bool IsZIncluded( GraphPane pane ) { return true; } #endregion #region Constructors /// /// Create a new , specifying only the legend label. /// /// The label that will appear in the legend. public JapaneseCandleStickItem( string label ) : base( label ) { _stick = new JapaneseCandleStick(); } /// /// Create a new using the specified properties. /// /// The label that will appear in the legend. /// An of double precision values that define /// the Date, Close, Open, High, and Low values for the curve. Note that this /// should contain items rather /// than items. /// public JapaneseCandleStickItem( string label, IPointList points ) : base( label, points ) { _stick = new JapaneseCandleStick(); } /// /// The Copy Constructor /// /// The object from which to copy public JapaneseCandleStickItem( JapaneseCandleStickItem rhs ) : base( rhs ) { _stick = rhs._stick.Clone(); } /// /// Implement the interface in a typesafe manner by just /// calling the typed version of /// /// A deep copy of this object object ICloneable.Clone() { return this.Clone(); } /// /// Typesafe, deep-copy clone method. /// /// A new, independent copy of this class public JapaneseCandleStickItem Clone() { return new JapaneseCandleStickItem( this ); } #endregion #region Serialization /// /// Current schema value that defines the version of the serialized file /// public const int schema2 = 10; /// /// Constructor for deserializing objects /// /// A instance that defines the serialized data /// /// A instance that contains the serialized data /// protected JapaneseCandleStickItem( SerializationInfo info, StreamingContext context ) : base( info, context ) { // The schema value is just a file version parameter. You can use it to make future versions // backwards compatible as new member variables are added to classes int sch = info.GetInt32( "schema2" ); _stick = (JapaneseCandleStick) info.GetValue( "stick", typeof( JapaneseCandleStick ) ); } /// /// Populates a instance with the data needed to serialize the target object /// /// A instance that defines the serialized data /// A instance that contains the serialized data [SecurityPermissionAttribute( SecurityAction.Demand, SerializationFormatter = true )] public override void GetObjectData( SerializationInfo info, StreamingContext context ) { base.GetObjectData( info, context ); info.AddValue( "schema2", schema2 ); info.AddValue( "stick", _stick ); } #endregion #region Methods /// /// Do all rendering associated with this to the specified /// device. This method is normally only /// called by the Draw method of the parent /// collection object. /// /// /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// /// /// A reference to the object that is the parent or /// owner of this object. /// /// The ordinal position of the current /// curve. /// /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent object using the /// method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// override public void Draw( Graphics g, GraphPane pane, int pos, float scaleFactor ) { if ( _isVisible ) { _stick.Draw( g, pane, this, this.BaseAxis( pane ), this.ValueAxis( pane ), scaleFactor ); } } /// /// Draw a legend key entry for this at the specified location /// /// /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// /// /// A reference to the object that is the parent or /// owner of this object. /// /// The struct that specifies the /// location for the legend key /// /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent object using the /// method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// override public void DrawLegendKey( Graphics g, GraphPane pane, RectangleF rect, float scaleFactor ) { float pixBase, pixHigh, pixLow, pixOpen, pixClose; if ( pane._barSettings.Base == BarBase.X ) { pixBase = rect.Left + rect.Width / 2.0F; pixHigh = rect.Top; pixLow = rect.Bottom; pixOpen = pixHigh + rect.Height / 3; pixClose = pixLow - rect.Height / 3; } else { pixBase = rect.Top + rect.Height / 2.0F; pixHigh = rect.Right; pixLow = rect.Left; pixOpen = pixHigh - rect.Width / 3; pixClose = pixLow + rect.Width / 3; } Axis baseAxis = BaseAxis( pane ); float halfSize = _stick.GetBarWidth( pane, baseAxis, scaleFactor ); using ( Pen pen = new Pen( _stick.Color, _stick._width ) ) { _stick.Draw( g, pane, pane._barSettings.Base == BarBase.X, pixBase, pixHigh, pixLow, pixOpen, pixClose, halfSize, scaleFactor, pen, _stick.RisingFill, _stick.RisingBorder, null ); } } /// /// Determine the coords for the rectangle associated with a specified point for /// this /// /// The to which this curve belongs /// The index of the point of interest /// A list of coordinates that represents the "rect" for /// this point (used in an html AREA tag) /// true if it's a valid point, false otherwise override public bool GetCoords( GraphPane pane, int i, out string coords ) { coords = string.Empty; if ( i < 0 || i >= _points.Count ) return false; Axis valueAxis = ValueAxis( pane ); Axis baseAxis = BaseAxis( pane ); float halfSize = _stick.Size * pane.CalcScaleFactor(); PointPair pt = _points[i]; double date = pt.X; double high = pt.Y; double low = pt.Z; if ( !pt.IsInvalid3D && ( date > 0 || !baseAxis._scale.IsLog ) && ( ( high > 0 && low > 0 ) || !valueAxis._scale.IsLog ) ) { float pixBase, pixHigh, pixLow; pixBase = baseAxis.Scale.Transform( _isOverrideOrdinal, i, date ); pixHigh = valueAxis.Scale.Transform( _isOverrideOrdinal, i, high ); pixLow = valueAxis.Scale.Transform( _isOverrideOrdinal, i, low ); // Calculate the pixel location for the side of the bar (on the base axis) float pixSide = pixBase - halfSize; // Draw the bar if ( baseAxis is XAxis || baseAxis is X2Axis ) coords = String.Format( "{0:f0},{1:f0},{2:f0},{3:f0}", pixSide, pixLow, pixSide + halfSize * 2, pixHigh ); else coords = String.Format( "{0:f0},{1:f0},{2:f0},{3:f0}", pixLow, pixSide, pixHigh, pixSide + halfSize * 2 ); return true; } return false; } #endregion } }