/// <summary> /// Copy Constructor /// </summary> /// <param name="a">construct a TradingDateTimeAxis based on this provided axis.</param> public TradingDateTimeAxis(Axis a) : base(a) { Init(); if (a is TradingDateTimeAxis) DoClone((TradingDateTimeAxis)a, this); else if (a is DateTimeAxis) DoClone((DateTimeAxis)a, this); else { DoClone(a, this); this.NumberFormat = null; } }
/// <summary> /// MouseDown method for AxisDrag interaction /// </summary> /// <param name="X">mouse X position</param> /// <param name="Y">mouse Y position</param> /// <param name="keys">mouse and keyboard modifiers</param> /// <param name="ps">the InteractivePlotSurface2D</param> public override bool DoMouseDown(int X, int Y, Modifier keys, InteractivePlotSurface2D ps) { // if the mouse is inside the plot area [the tick marks may be here, // and are counted as part of the axis], then don't invoke drag. if (ps.PlotAreaBoundingBoxCache.Contains(X, Y)) { return false; } if ((keys & Modifier.Button1) != 0) { // see if hit with axis. NB Only one axis object will be returned ArrayList objects = ps.HitTest(new Point(X, Y)); foreach (object o in objects) { if (o is Florence.Axis) { dragging_ = true; axis_ = (Axis)o; if (ps.PhysicalXAxis1Cache.Axis == axis_) { physicalAxis_ = ps.PhysicalXAxis1Cache; ps.plotCursor = CursorType.LeftRight; } else if (ps.PhysicalXAxis2Cache.Axis == axis_) { physicalAxis_ = ps.PhysicalXAxis2Cache; ps.plotCursor = CursorType.LeftRight; } else if (ps.PhysicalYAxis1Cache.Axis == axis_) { physicalAxis_ = ps.PhysicalYAxis1Cache; ps.plotCursor = CursorType.UpDown; } else if (ps.PhysicalYAxis2Cache.Axis == axis_) { physicalAxis_ = ps.PhysicalYAxis2Cache; ps.plotCursor = CursorType.UpDown; } startPoint_ = new Point(X, Y); // don't combine these - Mono lastPoint_ = startPoint_; // bug #475205 prior to 2.4 // evaluate focusRatio about which axis is expanded float x = startPoint_.X - physicalAxis_.PhysicalMin.X; float y = startPoint_.Y - physicalAxis_.PhysicalMin.Y; double r = Math.Sqrt(x * x + y * y); focusRatio_ = r / physicalAxis_.PhysicalLength; return false; } } } return false; }
/// <summary> /// MouseUp method for AxisDrag interaction /// </summary> /// <param name="X">mouse X position</param> /// <param name="Y"> mouse Y position</param> /// <param name="keys"> mouse and keyboard modifiers</param> /// <param name="ps">the InteractivePlotSurface2D</param> public override bool DoMouseUp(int X, int Y, Modifier keys, InteractivePlotSurface2D ps) { if (dragging_) { dragging_ = false; axis_ = null; physicalAxis_ = null; lastPoint_ = new Point(); ps.plotCursor = CursorType.LeftPointer; } return false; }
/// <summary> /// Construct /// </summary> /// <param name="a">The axis this is a physical representation of.</param> /// <param name="physicalMin">the physical position of the world minimum axis value.</param> /// <param name="physicalMax">the physical position of the world maximum axis value.</param> public PhysicalAxis( Axis a, Point physicalMin, Point physicalMax ) { this.Axis = a; this.PhysicalMin = physicalMin; this.PhysicalMax = physicalMax; }
/// <summary> /// Copy constructor /// </summary> /// <param name="a">The Axis to clone.</param> /// <remarks>TODO: [review notes] I don't think this will work as desired.</remarks> public PiAxis( Axis a ) : base(a) { Init(); }
/// <summary> /// Sets axes to be those saved in the cache. /// </summary> public void SetOriginalDimensions() { if (xAxis1ZoomCache_ != null) { this.XAxis1 = xAxis1ZoomCache_; this.XAxis2 = xAxis2ZoomCache_; this.YAxis1 = yAxis1ZoomCache_; this.YAxis2 = yAxis2ZoomCache_; xAxis1ZoomCache_ = null; xAxis2ZoomCache_ = null; yAxis1ZoomCache_ = null; yAxis2ZoomCache_ = null; } }
/// <summary> /// Copy constructor /// </summary> /// <param name="a">The Axis to clone</param> public LinearAxis( Axis a ) : base(a) { Init(); }
/// <summary> /// Copy constructor. /// </summary> /// <param name="a">The Axis to clone.</param> public Axis( Axis a ) { Axis.DoClone( a, this ); }
/// <summary> /// Sets the world extent of the current axis to be just large enough /// to encompas the current world extent of the axis, and the world /// extent of the passed in axis /// </summary> /// <param name="a">The other Axis instance.</param> public void LUB( Axis a ) { if (a == null) { return; } // mins if (!double.IsNaN(a.worldMin_)) { if (double.IsNaN(worldMin_)) { WorldMin = a.WorldMin; } else { if (a.WorldMin < WorldMin) { WorldMin = a.WorldMin; } } } // maxs. if (!double.IsNaN(a.worldMax_)) { if (double.IsNaN(worldMax_)) { WorldMax = a.WorldMax; } else { if (a.WorldMax > WorldMax) { WorldMax = a.WorldMax; } } } }
private void DetermineAxesToDraw( out Axis xAxis1, out Axis xAxis2, out Axis yAxis1, out Axis yAxis2 ) { xAxis1 = this.xAxis1_; xAxis2 = this.xAxis2_; yAxis1 = this.yAxis1_; yAxis2 = this.yAxis2_; if (this.xAxis1_ == null) { if (this.xAxis2_ == null) { throw new FlorenceException( "Error: No X-Axis specified" ); } xAxis1 = (Axis)this.xAxis2_.Clone(); xAxis1.HideTickText = true; xAxis1.TicksAngle = -(float)Math.PI / 2.0f; } if (this.xAxis2_ == null) { // don't need to check if xAxis1_ == null, as case already handled above. xAxis2 = (Axis)this.xAxis1_.Clone(); xAxis2.HideTickText = true; xAxis2.TicksAngle = (float)Math.PI / 2.0f; } if (this.yAxis1_ == null) { if (this.yAxis2_ == null) { throw new FlorenceException( "Error: No Y-Axis specified" ); } yAxis1 = (Axis)this.yAxis2_.Clone(); yAxis1.HideTickText = true; yAxis1.TicksAngle = (float)Math.PI / 2.0f; } if (this.yAxis2_ == null) { // don't need to check if yAxis1_ == null, as case already handled above. yAxis2 = (Axis)this.yAxis1_.Clone(); yAxis2.HideTickText = true; yAxis2.TicksAngle = -(float)Math.PI / 2.0f; } }
private void DeterminePhysicalAxesToDraw( Rectangle bounds, Axis xAxis1, Axis xAxis2, Axis yAxis1, Axis yAxis2, out PhysicalAxis pXAxis1, out PhysicalAxis pXAxis2, out PhysicalAxis pYAxis1, out PhysicalAxis pYAxis2 ) { System.Drawing.Rectangle cb = bounds; pXAxis1 = new PhysicalAxis( xAxis1, new Point( cb.Left, cb.Bottom ), new Point( cb.Right, cb.Bottom ) ); pYAxis1 = new PhysicalAxis( yAxis1, new Point( cb.Left, cb.Bottom ), new Point( cb.Left, cb.Top ) ); pXAxis2 = new PhysicalAxis( xAxis2, new Point( cb.Left, cb.Top), new Point( cb.Right, cb.Top) ); pYAxis2 = new PhysicalAxis( yAxis2, new Point( cb.Right, cb.Bottom ), new Point( cb.Right, cb.Top ) ); int bottomIndent = padding_; if (!pXAxis1.Axis.Hidden) { // evaluate its bounding box Rectangle bb = pXAxis1.GetBoundingBox(); // finally determine its indentation from the bottom bottomIndent = bottomIndent + bb.Bottom - cb.Bottom; } int leftIndent = padding_; if (!pYAxis1.Axis.Hidden) { // evaluate its bounding box Rectangle bb = pYAxis1.GetBoundingBox(); // finally determine its indentation from the left leftIndent = leftIndent - bb.Left + cb.Left; } int topIndent = padding_; float scale = this.DetermineScaleFactor( bounds.Width, bounds.Height ); int titleHeight; if (this.AutoScaleTitle) { titleHeight = Utils.ScaleFont(titleFont_, scale).Height; } else { titleHeight = titleFont_.Height; } //count number of new lines in title. int nlCount = 0; for (int i=0; i<title_.Length; ++i) { if (title_[i] == '\n') nlCount += 1; } titleHeight = (int)( ((float)nlCount*0.75 + 1.0f) * (float)titleHeight); if (!pXAxis2.Axis.Hidden) { // evaluate its bounding box Rectangle bb = pXAxis2.GetBoundingBox(); topIndent = topIndent - bb.Top + cb.Top; // finally determine its indentation from the top // correct top indendation to take into account plot title if (title_ != "" ) { topIndent += (int)(titleHeight * 1.3f); } } int rightIndent = padding_; if (!pYAxis2.Axis.Hidden) { // evaluate its bounding box Rectangle bb = pYAxis2.GetBoundingBox(); // finally determine its indentation from the right rightIndent = (int)(rightIndent + bb.Right-cb.Right); } // now we have all the default calculated positions and we can proceed to // "move" the axes to their right places // primary axes (bottom, left) pXAxis1.PhysicalMin = new Point( cb.Left+leftIndent, cb.Bottom-bottomIndent ); pXAxis1.PhysicalMax = new Point( cb.Right-rightIndent, cb.Bottom-bottomIndent ); pYAxis1.PhysicalMin = new Point( cb.Left+leftIndent, cb.Bottom-bottomIndent ); pYAxis1.PhysicalMax = new Point( cb.Left+leftIndent, cb.Top+topIndent ); // secondary axes (top, right) pXAxis2.PhysicalMin = new Point( cb.Left+leftIndent, cb.Top+topIndent ); pXAxis2.PhysicalMax = new Point( cb.Right-rightIndent, cb.Top+topIndent ); pYAxis2.PhysicalMin = new Point( cb.Right-rightIndent, cb.Bottom-bottomIndent ); pYAxis2.PhysicalMax = new Point( cb.Right-rightIndent, cb.Top+topIndent ); }
private void UpdateAxes( bool recalculateAll ) { if (drawables_.Count != xAxisPositions_.Count || drawables_.Count != yAxisPositions_.Count) { throw new FlorenceException("plots and axis position arrays our of sync"); } int position = 0; // if we're not recalculating axes using all iplots then set // position to last one in list. if (!recalculateAll) { position = drawables_.Count - 1; if (position < 0) position = 0; } if (recalculateAll) { this.xAxis1_ = null; this.yAxis1_ = null; this.xAxis2_ = null; this.yAxis2_ = null; } for (int i = position; i < drawables_.Count; ++i) { // only update axes if this drawable is an IPlot. if (!(drawables_[i] is IPlot)) continue; IPlot p = (IPlot)drawables_[i]; XAxisPosition xap = (XAxisPosition)xAxisPositions_[i]; YAxisPosition yap = (YAxisPosition)yAxisPositions_[i]; if (xap == XAxisPosition.Bottom) { if (this.xAxis1_ == null) { this.xAxis1_ = p.SuggestXAxis(); if (this.xAxis1_ != null) { this.xAxis1_.TicksAngle = -(float)Math.PI / 2.0f; } } else { this.xAxis1_.LUB(p.SuggestXAxis()); } if (this.xAxis1_ != null) { this.xAxis1_.MinPhysicalLargeTickStep = 50; if (this.AutoScaleAutoGeneratedAxes) { this.xAxis1_.AutoScaleText = true; this.xAxis1_.AutoScaleTicks = true; this.xAxis1_.TicksIndependentOfPhysicalExtent = true; } else { this.xAxis1_.AutoScaleText = false; this.xAxis1_.AutoScaleTicks = false; this.xAxis1_.TicksIndependentOfPhysicalExtent = false; } } } if (xap == XAxisPosition.Top) { if (this.xAxis2_ == null) { this.xAxis2_ = p.SuggestXAxis(); if (this.xAxis2_ != null) { this.xAxis2_.TicksAngle = (float)Math.PI / 2.0f; } } else { this.xAxis2_.LUB(p.SuggestXAxis()); } if (this.xAxis2_ != null) { this.xAxis2_.MinPhysicalLargeTickStep = 50; if (this.AutoScaleAutoGeneratedAxes) { this.xAxis2_.AutoScaleText = true; this.xAxis2_.AutoScaleTicks = true; this.xAxis2_.TicksIndependentOfPhysicalExtent = true; } else { this.xAxis2_.AutoScaleText = false; this.xAxis2_.AutoScaleTicks = false; this.xAxis2_.TicksIndependentOfPhysicalExtent = false; } } } if (yap == YAxisPosition.Left) { if (this.yAxis1_ == null) { this.yAxis1_ = p.SuggestYAxis(); if (this.yAxis1_ != null) { this.yAxis1_.TicksAngle = (float)Math.PI / 2.0f; } } else { this.yAxis1_.LUB(p.SuggestYAxis()); } if (this.yAxis1_ != null) { if (this.AutoScaleAutoGeneratedAxes) { this.yAxis1_.AutoScaleText = true; this.yAxis1_.AutoScaleTicks = true; this.yAxis1_.TicksIndependentOfPhysicalExtent = true; } else { this.yAxis1_.AutoScaleText = false; this.yAxis1_.AutoScaleTicks = false; this.yAxis1_.TicksIndependentOfPhysicalExtent = false; } } } if (yap == YAxisPosition.Right) { if (this.yAxis2_ == null) { this.yAxis2_ = p.SuggestYAxis(); if (this.yAxis2_ != null) { this.yAxis2_.TicksAngle = -(float)Math.PI / 2.0f; } } else { this.yAxis2_.LUB(p.SuggestYAxis()); } if (this.yAxis2_ != null) { if (this.AutoScaleAutoGeneratedAxes) { this.yAxis2_.AutoScaleText = true; this.yAxis2_.AutoScaleTicks = true; this.yAxis2_.TicksIndependentOfPhysicalExtent = true; } else { this.yAxis2_.AutoScaleText = false; this.yAxis2_.AutoScaleTicks = false; this.yAxis2_.TicksIndependentOfPhysicalExtent = false; } } } } }
private void Init() { drawables_ = new ArrayList(); xAxisPositions_ = new ArrayList(); yAxisPositions_ = new ArrayList(); zPositions_ = new ArrayList(); ordering_ = new SortedList(); try { FontFamily fontFamily = new FontFamily("Arial"); TitleFont = new Font(fontFamily, 14, FontStyle.Regular, GraphicsUnit.Pixel); } catch (System.ArgumentException) { throw new FlorenceException("Error: Arial font is not installed on this system"); } padding_ = 10; title_ = ""; autoScaleTitle_ = false; autoScaleAutoGeneratedAxes_ = false; xAxis1_ = null; xAxis2_ = null; yAxis1_ = null; yAxis2_ = null; pXAxis1Cache_ = null; pYAxis1Cache_ = null; pXAxis2Cache_ = null; pYAxis2Cache_ = null; titleBrush_ = new SolidBrush( Color.Black ); plotBackColor_ = Color.White; outerBackColor = null; this.legend_ = null; smoothingMode_ = System.Drawing.Drawing2D.SmoothingMode.None; axesConstraints_ = new ArrayList(); }
/// <summary> /// Copy constructor /// </summary> /// <param name="a">The Axis to clone.</param> /// <remarks>TODO: [review notes] I don't think this will work as desired.</remarks> public LabelAxis( Axis a ) : base(a) { Init(); }
/// <summary> /// Copy Constructor /// </summary> /// <param name="a">The Axis to clone.</param> public LogAxis(Axis a) : base(a) { Init(); }
/// <summary> /// Helper method for Clone. Does all the copying - can be called by derived /// types so they don't need to implement this part of the copying themselves. /// also useful in constructor of derived types that takes Axis class. /// </summary> protected static void DoClone( Axis b, Axis a ) { // value items a.autoScaleText_ = b.autoScaleText_; a.autoScaleTicks_ = b.autoScaleTicks_; a.worldMax_ = b.worldMax_; a.worldMin_ = b.worldMin_; a.tickTextNextToAxis_ = b.tickTextNextToAxis_; a.hidden_ = b.hidden_; a.hideTickText_ = b.hideTickText_; a.reversed_ = b.reversed_; a.ticksAngle_ = b.ticksAngle_; a.ticksLabelAngle_ = b.ticksLabelAngle_; a.minPhysicalLargeTickStep_ = b.minPhysicalLargeTickStep_; a.ticksIndependentOfPhysicalExtent_ = b.ticksIndependentOfPhysicalExtent_; a.largeTickSize_ = b.largeTickSize_; a.smallTickSize_ = b.smallTickSize_; a.ticksCrossAxis_ = b.ticksCrossAxis_; a.labelOffset_ = b.labelOffset_; a.labelOffsetAbsolute_ = b.labelOffsetAbsolute_; a.labelOffsetScaled_ = b.labelOffsetScaled_; // reference items. a.tickTextFont_ = (Font)b.tickTextFont_.Clone(); a.label_ = (string)b.label_.Clone(); if (b.numberFormat_ != null) { a.numberFormat_ = (string)b.numberFormat_.Clone(); } else { a.numberFormat_ = null; } a.labelFont_ = (Font)b.labelFont_.Clone(); a.linePen_ = (Pen)b.linePen_.Clone(); a.tickTextBrush_ = (Brush)b.tickTextBrush_.Clone(); a.labelBrush_ = (Brush)b.labelBrush_.Clone(); a.FontScale = b.FontScale; a.TickScale = b.TickScale; }
/// <summary> /// Caches the current axes /// </summary> public void CacheAxes() { if (xAxis1ZoomCache_ == null && xAxis2ZoomCache_ == null && yAxis1ZoomCache_ == null && yAxis2ZoomCache_ == null) { if (this.XAxis1 != null) { xAxis1ZoomCache_ = (Axis)this.XAxis1.Clone(); } if (this.XAxis2 != null) { xAxis2ZoomCache_ = (Axis)this.XAxis2.Clone(); } if (this.YAxis1 != null) { yAxis1ZoomCache_ = (Axis)this.YAxis1.Clone(); } if (this.YAxis2 != null) { yAxis2ZoomCache_ = (Axis)this.YAxis2.Clone(); } } }
/// <summary> /// Deep copy of Axis. /// </summary> /// <remarks> /// This method includes a check that guards against derived classes forgetting /// to implement their own Clone method. If Clone is called on a object derived /// from Axis, and the Clone method hasn't been overridden by that object, then /// the test this.GetType == typeof(Axis) will fail. /// </remarks> /// <returns>A copy of the Axis Class</returns> public virtual object Clone() { // ensure that this isn't being called on a derived type. If that is the case // then the derived type didn't override this method as it should have. if (this.GetType() != typeof(Axis)) { throw new FlorenceException( "Clone not defined in derived type." ); } Axis a = new Axis(); DoClone( this, a ); return a; }
protected void ClearAxisCache() { xAxis1ZoomCache_ = null; yAxis1ZoomCache_ = null; xAxis2ZoomCache_ = null; yAxis2ZoomCache_ = null; }
/// <summary> /// Constructor /// </summary> /// <param name="a">Axis to construct from</param> public DateTimeAxis( Axis a ) : base(a) { this.Init(); this.NumberFormat = null; }