/// <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> /// 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 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 (GetType() != typeof(Axis)) { throw new XwPlotException ( "Clone not defined in derived type." ); } Axis a = new Axis (); DoClone (this, a); return a; }
/// <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 src, Axis dest) { dest.Reversed = src.Reversed; dest.Hidden = src.Hidden; dest.WorldMax = src.WorldMax; dest.WorldMin = src.WorldMin; dest.LineColor = src.LineColor; dest.TicksCrossAxis = src.TicksCrossAxis; dest.SmallTickSize = src.SmallTickSize; dest.LargeTickSize = src.LargeTickSize; dest.MinPhysicalLargeTickStep = src.MinPhysicalLargeTickStep; dest.TicksIndependentOfPhysicalExtent = src.TicksIndependentOfPhysicalExtent; dest.AutoScaleTicks = src.AutoScaleTicks; dest.TickScale = src.TickScale; dest.TicksAngle = src.TicksAngle; dest.HideTickText = src.HideTickText; dest.TickTextNextToAxis = src.TickTextNextToAxis; dest.FlipTickText = src.FlipTickText; dest.AutoScaleText = src.AutoScaleText; dest.FontScale = src.FontScale; dest.TickTextColor = src.TickTextColor; dest.TickTextFont = src.TickTextFont.WithScaledSize (1.0); dest.TickTextAngle = src.TickTextAngle; dest.Label = (string)src.Label.Clone(); dest.LabelColor = src.LabelColor; dest.LabelFont = src.LabelFont.WithScaledSize (1.0); dest.LabelOffset = src.LabelOffset; dest.LabelOffsetAbsolute = src.LabelOffsetAbsolute; dest.LabelOffsetScaled = src.LabelOffsetScaled; dest.NumberFormat = src.NumberFormat; }
protected void ClearAxisCache() { xAxis1Cache = null; xAxis2Cache = null; yAxis1Cache = null; yAxis2Cache = null; cached = false; }
/// <summary> /// Cache the current axes /// </summary> public void CacheAxes() { if (!cached) { if (XAxis1 != null) { xAxis1Cache = (Axis)XAxis1.Clone(); cached = true; } if (XAxis2 != null) { xAxis2Cache = (Axis)XAxis2.Clone(); cached = true; } if (YAxis1 != null) { yAxis1Cache = (Axis)YAxis1.Clone(); cached = true; } if (YAxis2 != null) { yAxis2Cache = (Axis)YAxis2.Clone(); cached = true; } } }
/// <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> /// Constructor /// </summary> /// <param name="a">Axis to construct from</param> public DateTimeAxis(Axis a) : base(a) { Init (); NumberFormat = null; }
/// <summary> /// OnButtonReleased method for AxisScale interaction /// </summary> public override bool OnButtonReleased(ButtonEventArgs args, PlotCanvas pc) { if (dragging) { dragging = false; axis = null; physicalAxis = null; lastPoint = new Point(); //pc.plotCursor = CursorType.LeftPointer; } return false; }
void Init() { drawables = new ArrayList (); xAxisPositions = new ArrayList (); yAxisPositions = new ArrayList (); zPositions = new ArrayList (); ordering = new SortedList (); PlotBackColor = Colors.White; TitleFont = Font.SystemSansSerifFont.WithSize (14); TitleColor = Colors.Black; Padding = 10; Title = ""; Legend = null; autoScaletitle = false; autoScaleAutoGeneratedAxes = false; XAxis1 = null; XAxis2 = null; YAxis1 = null; YAxis2 = null; pXAxis1Cache = null; pYAxis1Cache = null; pXAxis2Cache = null; pYAxis2Cache = null; axesConstraints = new ArrayList (); }
/// <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) { Axis = a; PhysicalMin = physicalMin; PhysicalMax = physicalMax; }
void DeterminePhysicalAxesToDraw(Rectangle bounds, Axis XAxis1, Axis XAxis2, Axis YAxis1, Axis YAxis2, out PhysicalAxis pXAxis1, out PhysicalAxis pXAxis2, out PhysicalAxis pYAxis1, out PhysicalAxis pYAxis2 ) { 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) ); double 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; } double 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; } // determine title size double scale = DetermineScaleFactor (bounds.Width, bounds.Height); Font scaled_font; if (AutoScaleTitle) { scaled_font = TitleFont.WithScaledSize (scale); } else { scaled_font = TitleFont; } Size titleSize; using (TextLayout layout = new TextLayout ()) { layout.Font = scaled_font; layout.Text = Title; titleSize = layout.GetSize (); }; double topIndent = Padding; 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 += titleSize.Height * 1.3; } } double rightIndent = Padding; if (!pYAxis2.Axis.Hidden) { // evaluate its bounding box Rectangle bb = pYAxis2.GetBoundingBox(); // finally determine its indentation from the right 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); }
void DetermineAxesToDraw(out Axis xAxis_1, out Axis xAxis_2, out Axis yAxis_1, out Axis yAxis_2) { xAxis_1 = XAxis1; xAxis_2 = XAxis2; yAxis_1 = YAxis1; yAxis_2 = YAxis2; if (XAxis1 == null) { if (XAxis2 == null) { throw new XwPlotException ("Error: No X-Axis specified"); } xAxis_1 = (Axis)XAxis2.Clone (); xAxis_1.HideTickText = true; xAxis_1.TicksAngle = -Math.PI / 2; } if (XAxis2 == null) { // don't need to check if XAxis1 == null, as case already handled above. xAxis_2 = (Axis)XAxis1.Clone (); xAxis_2.HideTickText = true; xAxis_2.TicksAngle = Math.PI / 2.0; } if (YAxis1 == null) { if (YAxis2 == null) { throw new XwPlotException ("Error: No Y-Axis specified"); } yAxis_1 = (Axis)YAxis2.Clone(); yAxis_1.HideTickText = true; yAxis_1.TicksAngle = Math.PI / 2.0; } if (YAxis2 == null) { // don't need to check if YAxis1 == null, as case already handled above. yAxis_2 = (Axis)YAxis1.Clone(); yAxis_2.HideTickText = true; yAxis_2.TicksAngle = -Math.PI / 2.0; } }
void UpdateAxes(bool recalculateAll) { if (drawables.Count != xAxisPositions.Count || drawables.Count != yAxisPositions.Count) { throw new XwPlotException("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) { XAxis1 = null; YAxis1 = null; XAxis2 = null; 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 (XAxis1 == null) { XAxis1 = p.SuggestXAxis(); if (XAxis1 != null) { XAxis1.TicksAngle = -Math.PI / 2.0; } } else { XAxis1.LUB(p.SuggestXAxis()); } if (XAxis1 != null) { XAxis1.MinPhysicalLargeTickStep = 50; if (AutoScaleAutoGeneratedAxes) { XAxis1.AutoScaleText = true; XAxis1.AutoScaleTicks = true; XAxis1.TicksIndependentOfPhysicalExtent = true; } else { XAxis1.AutoScaleText = false; XAxis1.AutoScaleTicks = false; XAxis1.TicksIndependentOfPhysicalExtent = false; } } } if (xap == XAxisPosition.Top) { if (XAxis2 == null) { XAxis2 = p.SuggestXAxis(); if (XAxis2 != null) { XAxis2.TicksAngle = Math.PI / 2.0; } } else { XAxis2.LUB(p.SuggestXAxis()); } if (XAxis2 != null) { XAxis2.MinPhysicalLargeTickStep = 50; if (AutoScaleAutoGeneratedAxes) { XAxis2.AutoScaleText = true; XAxis2.AutoScaleTicks = true; XAxis2.TicksIndependentOfPhysicalExtent = true; } else { XAxis2.AutoScaleText = false; XAxis2.AutoScaleTicks = false; XAxis2.TicksIndependentOfPhysicalExtent = false; } } } if (yap == YAxisPosition.Left) { if (YAxis1 == null) { YAxis1 = p.SuggestYAxis(); if (YAxis1 != null) { YAxis1.TicksAngle = Math.PI / 2.0; } } else { YAxis1.LUB(p.SuggestYAxis()); } if (YAxis1 != null) { if (AutoScaleAutoGeneratedAxes) { YAxis1.AutoScaleText = true; YAxis1.AutoScaleTicks = true; YAxis1.TicksIndependentOfPhysicalExtent = true; } else { YAxis1.AutoScaleText = false; YAxis1.AutoScaleTicks = false; YAxis1.TicksIndependentOfPhysicalExtent = false; } } } if (yap == YAxisPosition.Right) { if (YAxis2 == null) { YAxis2 = p.SuggestYAxis(); if (YAxis2 != null) { YAxis2.TicksAngle = -Math.PI / 2.0; } } else { YAxis2.LUB(p.SuggestYAxis()); } if (YAxis2 != null) { if (AutoScaleAutoGeneratedAxes) { YAxis2.AutoScaleText = true; YAxis2.AutoScaleTicks = true; YAxis2.TicksIndependentOfPhysicalExtent = true; } else { YAxis2.AutoScaleText = false; YAxis2.AutoScaleTicks = false; YAxis2.TicksIndependentOfPhysicalExtent = false; } } } } }
/// <summary> /// Sets the world extent of the current axis to be just large enough (Least Upper Bound) to /// encompass the current world extent of the axis, and the extent of the specified axis /// </summary> /// <param name="a">The other Axis instance.</param> public void LUB(Axis a) { if (a == null) { return; } // minima if (!double.IsNaN(a.WorldMin)) { if (double.IsNaN(WorldMin)) { WorldMin = a.WorldMin; } else { if (a.WorldMin < WorldMin) { WorldMin = a.WorldMin; } } } // maxima if (!double.IsNaN(a.WorldMax)) { if (double.IsNaN(WorldMax)) { WorldMax = a.WorldMax; } else { if (a.WorldMax > WorldMax) { WorldMax = a.WorldMax; } } } }
/// <summary> /// OnButtonPressed method for AxisScale interaction /// </summary> public override bool OnButtonPressed(ButtonEventArgs args, PlotCanvas pc) { // 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 scaling if (pc.PlotAreaBoundingBoxCache.Contains(args.X, args.Y)) { return false; } if (args.Button == PointerButton.Left) { // see if hit with axis. NB Only one axis object will be returned ArrayList objects = pc.HitTest (new Point(args.X, args.Y)); foreach (object o in objects) { if (o is Axis) { dragging = true; axis = (Axis)o; if (pc.PhysicalXAxis1Cache.Axis == axis) { physicalAxis = pc.PhysicalXAxis1Cache; //pc.plotCursor = CursorType.LeftRight; } else if (pc.PhysicalXAxis2Cache.Axis == axis) { physicalAxis = pc.PhysicalXAxis2Cache; //ps.plotCursor = CursorType.LeftRight; } else if (pc.PhysicalYAxis1Cache.Axis == axis) { physicalAxis = pc.PhysicalYAxis1Cache; //pc.plotCursor = CursorType.UpDown; } else if (pc.PhysicalYAxis2Cache.Axis == axis) { physicalAxis = pc.PhysicalYAxis2Cache; //pc.plotCursor = CursorType.UpDown; } startPoint = new Point (args.X, args.Y); lastPoint = startPoint; // evaluate focusRatio about which axis is expanded double x = startPoint.X - physicalAxis.PhysicalMin.X; double y = startPoint.Y - physicalAxis.PhysicalMin.Y; double r = Math.Sqrt(x*x + y*y); focusRatio = r/physicalAxis.PhysicalLength; return false; } } } return false; }
/// <summary> /// Copy constructor. /// </summary> /// <param name="src">The Axis to clone.</param> public Axis(Axis src ) { Axis.DoClone (src, this); }
/// <summary> /// Copy constructor /// </summary> /// <param name="a">The Axis to clone</param> public LinearAxis(Axis a) : base(a) { Init(); }