public PhysicalToWorld ( Point p, bool clip ) : double | ||
p | Point | Physical point to find corresponding world value of. |
clip | bool | if true, returns a world position outside WorldMin / WorldMax /// range if this is closer to the axis line. If false, such values will /// be clipped to be either WorldMin or WorldMax as appropriate. |
Результат | double |
/// <summary> /// Draws the line plot using the Context and Physical Axes provided /// </summary> /// <param name="ctx">The Drawing Context with which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> /// <param name="drawShadow">If true draw the shadow for the line. If false, draw line.</param> public void DrawLineOrShadow(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis, bool drawShadow) { SequenceAdapter data = new SequenceAdapter (DataSource, DataMember, OrdinateData, AbscissaData); ITransform2D t = Transform2D.GetTransformer (xAxis, yAxis); int numberPoints = data.Count; if (data.Count == 0) { return; } ctx.Save (); ctx.SetLineWidth (lineWidth_); // clipping is now handled assigning a clip region in the // graphic object before this call if (numberPoints == 1) { Point physical = t.Transform (data[0]); if (drawShadow) { ctx.SetColor (shadowColor_); ctx.MoveTo (physical.X - 0.5 + ShadowOffset.X, physical.Y + ShadowOffset.Y); ctx.LineTo (physical.X + 0.5 + ShadowOffset.X, physical.Y + ShadowOffset.Y); ctx.Stroke (); } else { ctx.SetColor (lineColor_); ctx.MoveTo (physical.X-0.5, physical.Y); ctx.LineTo (physical.X+0.5, physical.Y); ctx.Stroke (); } } else { // prepare for clipping double leftCutoff = xAxis.PhysicalToWorld (xAxis.PhysicalMin, false); double rightCutoff = xAxis.PhysicalToWorld (xAxis.PhysicalMax, false); if (leftCutoff > rightCutoff) { Utils.Swap (ref leftCutoff, ref rightCutoff); } if (drawShadow) { // correct cut-offs double shadowCorrection = xAxis.PhysicalToWorld (ShadowOffset, false) - xAxis.PhysicalToWorld (new Point(0,0), false); leftCutoff -= shadowCorrection; rightCutoff -= shadowCorrection; } for (int i = 1; i < numberPoints; ++i) { // check to see if any values null. If so, then continue. double dx1 = data[i-1].X; double dx2 = data[i].X; double dy1 = data[i-1].Y; double dy2 = data[i].Y; if (Double.IsNaN(dx1) || Double.IsNaN(dy1) || Double.IsNaN(dx2) || Double.IsNaN(dy2)) { continue; } // do horizontal clipping here, to speed up if ((dx1 < leftCutoff && dx2 < leftCutoff) || (rightCutoff < dx1 && rightCutoff < dx2)) { continue; } // else draw line. Point p1 = t.Transform (data[i-1]); Point p2 = t.Transform (data[i]); // when very far zoomed in, points can fall ontop of each other, // and g.DrawLine throws an overflow exception if (p1.Equals(p2)) { continue; } if (drawShadow) { ctx.SetColor (shadowColor_); ctx.MoveTo (p1.X + ShadowOffset.X, p1.Y + ShadowOffset.Y); ctx.LineTo (p2.X + ShadowOffset.X, p2.Y + ShadowOffset.Y); ctx.Stroke (); } else { ctx.SetColor (lineColor_); ctx.MoveTo (p1.X, p1.Y); ctx.LineTo (p2.X, p2.Y); ctx.Stroke (); } } } ctx.Restore (); }
/// <summary> /// Draws the line plot on a GDI+ surface against the provided x and y axes. /// </summary> /// <param name="g">The GDI+ surface on which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> /// <param name="drawShadow">If true draw the shadow for the line. If false, draw line.</param> public void DrawLineOrShadow( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis, bool drawShadow ) { Pen shadowPen = null; if (drawShadow) { shadowPen = (Pen)this.Pen.Clone(); shadowPen.Color = this.ShadowColor; } SequenceAdapter data = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); ITransform2D t = Transform2D.GetTransformer( xAxis, yAxis ); int numberPoints = data.Count; if (data.Count == 0) { return; } // clipping is now handled assigning a clip region in the // graphic object before this call if (numberPoints == 1) { PointF physical = t.Transform( data[0] ); if (drawShadow) { g.DrawLine( shadowPen, physical.X - 0.5f + this.ShadowOffset.X, physical.Y + this.ShadowOffset.Y, physical.X + 0.5f + this.ShadowOffset.X, physical.Y + this.ShadowOffset.Y ); } else { g.DrawLine( Pen, physical.X-0.5f, physical.Y, physical.X+0.5f, physical.Y); } } else { // prepare for clipping double leftCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false); double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false); if (leftCutoff > rightCutoff) { Utils.Swap(ref leftCutoff, ref rightCutoff); } if (drawShadow) { // correct cut-offs double shadowCorrection = xAxis.PhysicalToWorld(ShadowOffset, false) - xAxis.PhysicalToWorld(new Point(0,0), false); leftCutoff -= shadowCorrection; rightCutoff -= shadowCorrection; } for (int i = 1; i < numberPoints; ++i) { // check to see if any values null. If so, then continue. double dx1 = data[i-1].X; double dx2 = data[i].X; double dy1 = data[i-1].Y; double dy2 = data[i].Y; if ( Double.IsNaN(dx1) || Double.IsNaN(dy1) || Double.IsNaN(dx2) || Double.IsNaN(dy2) ) { continue; } // do horizontal clipping here, to speed up if ((dx1 < leftCutoff || rightCutoff < dx1) && (dx2 < leftCutoff || rightCutoff < dx2)) { continue; } // else draw line. PointF p1 = t.Transform( data[i-1] ); PointF p2 = t.Transform( data[i] ); // when very far zoomed in, points can fall ontop of each other, // and g.DrawLine throws an overflow exception if (p1.Equals(p2)) continue; if (drawShadow) { g.DrawLine( shadowPen, p1.X + ShadowOffset.X, p1.Y + ShadowOffset.Y, p2.X + ShadowOffset.X, p2.Y + ShadowOffset.Y ); } else { g.DrawLine( Pen, p1.X, p1.Y, p2.X, p2.Y ); } } } }
/// <summary> /// Draws the step plot on a GDI+ surface against the provided x and y axes. /// </summary> /// <param name="g">The GDI+ surface on which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> public virtual void Draw(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis) { SequenceAdapter data = new SequenceAdapter(DataSource, DataMember, OrdinateData, AbscissaData); double leftCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false); double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false); for (int i = 0; i < data.Count; ++i) { PointD p1 = data[i]; if (Double.IsNaN(p1.X) || Double.IsNaN(p1.Y)) { continue; } PointD p2; PointD p3; if (i + 1 != data.Count) { p2 = data[i + 1]; if (Double.IsNaN(p2.X) || Double.IsNaN(p2.Y)) { continue; } p2.Y = p1.Y; p3 = data[i + 1]; } else { // Check that we are not dealing with a DataSource of 1 point. // This check is done here so it is only checked on the end // condition and not for every point in the DataSource. if (data.Count > 1) { p2 = data[i - 1]; } else { // TODO: Once log4net is set up post a message to the user that a step-plot of 1 really does not make any sense. p2 = p1; } double offset = p1.X - p2.X; p2.X = p1.X + offset; p2.Y = p1.Y; p3 = p2; } if (center_) { double offset = (p2.X - p1.X) / 2.0f; p1.X -= offset; p2.X -= offset; p3.X -= offset; } PointF xPos1 = xAxis.WorldToPhysical(p1.X, false); PointF yPos1 = yAxis.WorldToPhysical(p1.Y, false); PointF xPos2 = xAxis.WorldToPhysical(p2.X, false); PointF yPos2 = yAxis.WorldToPhysical(p2.Y, false); PointF xPos3 = xAxis.WorldToPhysical(p3.X, false); PointF yPos3 = yAxis.WorldToPhysical(p3.Y, false); // do horizontal clipping here, to speed up if ((p1.X < leftCutoff || p1.X > rightCutoff) && (p2.X < leftCutoff || p2.X > rightCutoff) && (p3.X < leftCutoff || p3.X > rightCutoff)) { continue; } if (!hideHorizontalSegments_) { if (scale_ != 1.0f) { float middle = (xPos2.X + xPos1.X) / 2.0f; float width = xPos2.X - xPos1.X; width *= scale_; g.DrawLine(Pen, (int)(middle - width / 2.0f), yPos1.Y, (int)(middle + width / 2.0f), yPos2.Y); } else { g.DrawLine(Pen, xPos1.X, yPos1.Y, xPos2.X, yPos2.Y); } } if (!hideVerticalSegments_) { g.DrawLine(Pen, xPos2.X, yPos2.Y, xPos3.X, yPos3.Y); } } }
/// <summary> /// Draws the step plot on a GDI+ surface against the provided x and y axes. /// </summary> /// <param name="g">The GDI+ surface on which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> public virtual void Draw( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis ) { SequenceAdapter data = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); double leftCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false); double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false); for (int i=0; i<data.Count; ++i) { PointD p1 = data[i]; if (Double.IsNaN(p1.X) || Double.IsNaN(p1.Y)) { continue; } PointD p2; PointD p3; if (i+1 != data.Count) { p2 = data[i+1]; if (Double.IsNaN(p2.X) || Double.IsNaN(p2.Y)) { continue; } p2.Y = p1.Y; p3 = data[i+1]; } else { // Check that we are not dealing with a DataSource of 1 point. // This check is done here so it is only checked on the end // condition and not for every point in the DataSource. if (data.Count > 1) { p2 = data[i - 1]; } else { // TODO: Once log4net is set up post a message to the user that a step-plot of 1 really does not make any sense. p2 = p1; } double offset = p1.X - p2.X; p2.X = p1.X + offset; p2.Y = p1.Y; p3 = p2; } if ( this.center_ ) { double offset = ( p2.X - p1.X ) / 2.0f; p1.X -= offset; p2.X -= offset; p3.X -= offset; } PointF xPos1 = xAxis.WorldToPhysical( p1.X, false ); PointF yPos1 = yAxis.WorldToPhysical( p1.Y, false ); PointF xPos2 = xAxis.WorldToPhysical( p2.X, false ); PointF yPos2 = yAxis.WorldToPhysical( p2.Y, false ); PointF xPos3 = xAxis.WorldToPhysical( p3.X, false ); PointF yPos3 = yAxis.WorldToPhysical( p3.Y, false ); // do horizontal clipping here, to speed up if ((p1.X < leftCutoff && p2.X < leftCutoff && p3.X < leftCutoff) || (p1.X > rightCutoff && p2.X > rightCutoff && p3.X > rightCutoff)) { continue; } if (!this.hideHorizontalSegments_) { if (scale_ != 1.0f) { float middle = (xPos2.X + xPos1.X) / 2.0f; float width = xPos2.X - xPos1.X; width *= this.scale_; g.DrawLine( Pen, (int)(middle-width/2.0f), yPos1.Y, (int)(middle+width/2.0f), yPos2.Y ); } else { g.DrawLine( Pen, xPos1.X, yPos1.Y, xPos2.X, yPos2.Y ); } } if (!this.hideVerticalSegments_) { g.DrawLine( Pen, xPos2.X, yPos2.Y, xPos3.X, yPos3.Y ); } } }
/// <summary> /// Draws the line plot on a GDI+ surface against the provided x and y axes. /// </summary> /// <param name="g">The GDI+ surface on which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> /// <param name="drawShadow">If true draw the shadow for the line. If false, draw line.</param> public void DrawLineOrShadow(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis, bool drawShadow) { Pen shadowPen = null; if (drawShadow) { shadowPen = (Pen)this.Pen.Clone(); shadowPen.Color = this.ShadowColor; } SequenceAdapter data = new SequenceAdapter(this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData); ITransform2D t = Transform2D.GetTransformer(xAxis, yAxis); int numberPoints = data.Count; if (data.Count == 0) { return; } // clipping is now handled assigning a clip region in the // graphic object before this call if (numberPoints == 1) { PointF physical = t.Transform(data[0]); if (drawShadow) { g.DrawLine(shadowPen, physical.X - 0.5f + this.ShadowOffset.X, physical.Y + this.ShadowOffset.Y, physical.X + 0.5f + this.ShadowOffset.X, physical.Y + this.ShadowOffset.Y); } else { g.DrawLine(Pen, physical.X - 0.5f, physical.Y, physical.X + 0.5f, physical.Y); } } else { // prepare for clipping double leftCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false); double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false); if (leftCutoff > rightCutoff) { Utils.Swap(ref leftCutoff, ref rightCutoff); } if (drawShadow) { // correct cut-offs double shadowCorrection = xAxis.PhysicalToWorld(ShadowOffset, false) - xAxis.PhysicalToWorld(new Point(0, 0), false); leftCutoff -= shadowCorrection; rightCutoff -= shadowCorrection; } for (int i = 1; i < numberPoints; ++i) { // check to see if any values null. If so, then continue. double dx1 = data[i - 1].X; double dx2 = data[i].X; double dy1 = data[i - 1].Y; double dy2 = data[i].Y; if (Double.IsNaN(dx1) || Double.IsNaN(dy1) || Double.IsNaN(dx2) || Double.IsNaN(dy2)) { continue; } // do horizontal clipping here, to speed up if ((dx1 < leftCutoff && dx2 < leftCutoff) || (rightCutoff < dx1 && rightCutoff < dx2)) { continue; } // else draw line. PointF p1 = t.Transform(data[i - 1]); PointF p2 = t.Transform(data[i]); // when very far zoomed in, points can fall ontop of each other, // and g.DrawLine throws an overflow exception if (p1.Equals(p2)) { continue; } if (drawShadow) { g.DrawLine(shadowPen, p1.X + ShadowOffset.X, p1.Y + ShadowOffset.Y, p2.X + ShadowOffset.X, p2.Y + ShadowOffset.Y); } else { g.DrawLine(Pen, p1.X, p1.Y, p2.X, p2.Y); } } } }
/// <summary> /// Draws the line plot on a GDI+ surface against the provided x and y axes. /// </summary> /// <param name="g">The GDI+ surface on which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> /// <param name="drawShadow">If true draw the shadow for the line. If false, draw line.</param> public void DrawLineOrShadow(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis, bool drawShadow) { Pen shadowPen = null; if (drawShadow) { shadowPen = (Pen)this.Pen.Clone(); shadowPen.Color = this.ShadowColor; } SequenceAdapter data = new SequenceAdapter(this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData); int numberPoints = data.Count; if (data.Count == 0) { return; } // clipping is now handled assigning a clip region in the // graphic object before this call if (numberPoints == 1) { PointF physical = Transform2D.GetTransformer(xAxis, yAxis).Transform(data[0]); if (drawShadow) { g.DrawLine(shadowPen, physical.X - 0.5f + this.ShadowOffset.X, physical.Y + this.ShadowOffset.Y, physical.X + 0.5f + this.ShadowOffset.X, physical.Y + this.ShadowOffset.Y); } else { g.DrawLine(Pen, physical.X - 0.5f, physical.Y, physical.X + 0.5f, physical.Y); } } else { // prepare for clipping double leftCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false); double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false); if (leftCutoff > rightCutoff) { double temp = leftCutoff; leftCutoff = rightCutoff; rightCutoff = temp; } if (drawShadow) { // correct cut-offs double shadowCorrection = xAxis.PhysicalToWorld(ShadowOffset, false) - xAxis.PhysicalToWorld(new Point(0, 0), false); leftCutoff -= shadowCorrection; rightCutoff -= shadowCorrection; } // determine which points to plot double tradingTimeOffset = 0; List <PointD> plotPoints = new List <PointD>(numberPoints); PointD d1 = data[0]; PointD d2 = d1; if ((d1.X >= leftCutoff) && (d1.X <= rightCutoff)) { plotPoints.Add(d1); } DateTime prevTime = (DateTime)((System.Data.DataTable) this.DataSource).Rows[0][(string)this.AbscissaData]; for (int i = 1; i < numberPoints; ++i) { // check to see if any values null. If so, then continue. d1 = d2; d2 = data[i]; if (Double.IsNaN(d1.X) || Double.IsNaN(d1.Y) || Double.IsNaN(d2.X) || Double.IsNaN(d2.Y)) { continue; } // Get the X axis offset to strip out the non-trading time d1.X -= tradingTimeOffset; DateTime nextTime = (DateTime)((System.Data.DataTable) this.DataSource).Rows[i][(string)this.AbscissaData]; if (nextTime.TimeOfDay < prevTime.TimeOfDay) { tradingTimeOffset += (double)(nextTime - prevTime).Ticks; } prevTime = nextTime; d2.X -= tradingTimeOffset; // do horizontal clipping here, to speed up if ((d1.X < leftCutoff && d2.X < leftCutoff) || (rightCutoff < d1.X && rightCutoff < d2.X)) { continue; } // Add a point to plot plotPoints.Add(d2); } // create a transform, which takes into account the skipped time PhysicalAxis shunkAxis = new PhysicalAxis(new DateTimeAxis(xAxis.Axis.WorldMin, xAxis.Axis.WorldMax - tradingTimeOffset), xAxis.PhysicalMin, xAxis.PhysicalMax); ITransform2D t = Transform2D.GetTransformer(shunkAxis, yAxis); // plot those points for (int i = 1; i < plotPoints.Count; i++) { // else draw line. PointF p1 = t.Transform(plotPoints[i - 1]); PointF p2 = t.Transform(plotPoints[i]); // when very far zoomed in, points can fall ontop of each other, // and g.DrawLine throws an overflow exception if (p1.Equals(p2)) { continue; } if (drawShadow) { g.DrawLine(shadowPen, p1.X + ShadowOffset.X, p1.Y + ShadowOffset.Y, p2.X + ShadowOffset.X, p2.Y + ShadowOffset.Y); } else { g.DrawLine(Pen, p1.X, p1.Y, p2.X, p2.Y); } } } }
/// <summary> /// Draws the step plot using a Drawing Context against the provided x and y axes. /// </summary> /// <param name="ctx">The Drawing Context with which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> public virtual void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis ) { SequenceAdapter data = new SequenceAdapter (DataSource, DataMember, OrdinateData, AbscissaData); double leftCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false); double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false); for (int i=0; i<data.Count; ++i) { Point p1 = data[i]; if (Double.IsNaN(p1.X) || Double.IsNaN(p1.Y)) { continue; } Point p2; Point p3; if (i+1 != data.Count) { p2 = data[i+1]; if (Double.IsNaN(p2.X) || Double.IsNaN(p2.Y)) { continue; } p2.Y = p1.Y; p3 = data[i+1]; } else { // Check that we are not dealing with a DataSource of 1 point. // This check is done here so it is only checked on the end // condition and not for every point in the DataSource. if (data.Count > 1) { p2 = data[i - 1]; } else { // TODO: Once log4net is set up post a message to the user that a step-plot of 1 really does not make any sense. p2 = p1; } double offset = p1.X - p2.X; p2.X = p1.X + offset; p2.Y = p1.Y; p3 = p2; } if (center_) { double offset = ( p2.X - p1.X ) / 2.0; p1.X -= offset; p2.X -= offset; p3.X -= offset; } Point xPos1 = xAxis.WorldToPhysical (p1.X, false); Point yPos1 = yAxis.WorldToPhysical (p1.Y, false); Point xPos2 = xAxis.WorldToPhysical (p2.X, false); Point yPos2 = yAxis.WorldToPhysical (p2.Y, false); Point xPos3 = xAxis.WorldToPhysical (p3.X, false); Point yPos3 = yAxis.WorldToPhysical (p3.Y, false); // do horizontal clipping here, to speed up if ((p1.X<leftCutoff && p2.X<leftCutoff && p3.X<leftCutoff) || (p1.X>rightCutoff && p2.X>rightCutoff && p3.X>rightCutoff)) { continue; } ctx.Save (); ctx.SetColor (Color); ctx.SetLineWidth (1); if (!this.hideHorizontalSegments_) { if (scale_ != 1) { double middle = (xPos2.X + xPos1.X) / 2; double width = xPos2.X - xPos1.X; width *= this.scale_; ctx.MoveTo (middle-width/2, yPos1.Y); ctx.LineTo (middle+width/2, yPos2.Y); } else { ctx.MoveTo (xPos1.X, yPos1.Y); ctx.LineTo (xPos2.X, yPos2.Y); } ctx.Stroke (); } if (!this.hideVerticalSegments_) { ctx.MoveTo (xPos2.X, yPos2.Y); ctx.LineTo (xPos3.X, yPos3.Y); ctx.Stroke (); } ctx.Restore (); } }
/// <summary> /// Draws the step plot on a GDI+ surface against the provided x and y axes. /// </summary> /// <param name="g">The GDI+ surface on which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> public virtual void Draw( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis ) { SequenceAdapter data = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); double leftCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false); double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false); for (int i=0; i<data.Count; ++i) { PointD p1 = data[i]; if (Double.IsNaN(p1.X) || Double.IsNaN(p1.Y)) { continue; } PointD p2; PointD p3; if (i+1 != data.Count) { p2 = data[i+1]; if (Double.IsNaN(p2.X) || Double.IsNaN(p2.Y)) { continue; } p2.Y = p1.Y; p3 = data[i+1]; } else { p2 = data[i-1]; double offset = p1.X - p2.X; p2.X = p1.X + offset; p2.Y = p1.Y; p3 = p2; } if ( this.center_ ) { double offset = ( p2.X - p1.X ) / 2.0f; p1.X -= offset; p2.X -= offset; p3.X -= offset; } PointF xPos1 = xAxis.WorldToPhysical( p1.X, false ); PointF yPos1 = yAxis.WorldToPhysical( p1.Y, false ); PointF xPos2 = xAxis.WorldToPhysical( p2.X, false ); PointF yPos2 = yAxis.WorldToPhysical( p2.Y, false ); PointF xPos3 = xAxis.WorldToPhysical( p3.X, false ); PointF yPos3 = yAxis.WorldToPhysical( p3.Y, false ); // do horizontal clipping here, to speed up if ((p1.X < leftCutoff || p1.X > rightCutoff ) && (p2.X < leftCutoff || p2.X > rightCutoff ) && (p3.X < leftCutoff || p3.X > rightCutoff ) ) { continue; } if (!this.hideHorizontalSegments_) { if (scale_ != 1.0f) { float middle = (xPos2.X + xPos1.X) / 2.0f; float width = xPos2.X - xPos1.X; width *= this.scale_; g.DrawLine( Pen, (int)(middle-width/2.0f), yPos1.Y, (int)(middle+width/2.0f), yPos2.Y ); } else { g.DrawLine( Pen, xPos1.X, yPos1.Y, xPos2.X, yPos2.Y ); } } if (!this.hideVerticalSegments_) { g.DrawLine( Pen, xPos2.X, yPos2.Y, xPos3.X, yPos3.Y ); } } }
/// <summary> /// Draws the scale division label on a GDI+ surface against the provided x and y axes. /// </summary> /// <param name="g">The GDI+ surface on which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> /// public void Draw(System.Drawing.Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis) { ArrayList yLargePositions = null; ArrayList ySmallPositions = null; yAxis.Axis.WorldTickPositions_FirstPass( yAxis.PhysicalMin, yAxis.PhysicalMax, out yLargePositions, out ySmallPositions ); // test if we have enough y ticks if (yLargePositions.Count <= this.YPosition) { if (yLargePositions.Count > 1) this.YPosition = yLargePositions.Count - 1; else return; } double minX = xAxis.PhysicalToWorld(xAxis.PhysicalMin,false); double maxX = xAxis.PhysicalToWorld(xAxis.PhysicalMax,false); double xOffset = this.XPosition; double xRef = xAxis.PhysicalMin.X; if (xOffset < 0) xRef = xAxis.PhysicalMax.X; if (xOffset < 1 && xOffset > 0) xOffset = (xAxis.PhysicalMax.X - xAxis.PhysicalMin.X) * this.XPosition; //*P8 P3*==*P2==*P4 // || // || // || *P7 // || // || // P5*==*P1==*P6 //Points for the main-line PointF p1 = new PointF(Convert.ToSingle(xRef + xOffset), 0.0f); PointF p2 = p1; PointF yTick1 = yAxis.WorldToPhysical((double)yLargePositions[yLargePositions.Count-this.YPosition],false); PointF yTick0 = yAxis.WorldToPhysical((double)yLargePositions[yLargePositions.Count-(this.YPosition+1)],false); p1.Y = yTick0.Y; p2.Y = yTick1.Y; //Points for the upper line PointF p3 = yTick1; PointF p4 = p3; p3.X = Convert.ToSingle(xRef + xOffset - 3); p4.X = Convert.ToSingle(xRef + xOffset + 3); //Points for the lower line PointF p5 = p3; PointF p6 = p4; p5.Y = yTick0.Y; p6.Y = yTick0.Y; //Label-point PointF p7 = p6; p7.Y = p7.Y + (p2.Y - p1.Y)/2; //Background-point PointF p8 = p3; p8.X = Convert.ToSingle((xRef + xOffset) - 14); double labelValue = (double)yLargePositions[yLargePositions.Count-this.YPosition] - (double)yLargePositions[yLargePositions.Count-(this.YPosition+1)]; StringBuilder label = new StringBuilder(); label.AppendFormat(this.NumberFormat, labelValue); float labelLength = g.MeasureString (label.ToString(), this.LabelFont).Width; float width = Convert.ToSingle((xRef + xOffset) + 14) - p8.X; float widthMin = (p7.X - p8.X) + labelLength + 2; if (widthMin > width) width = widthMin; float height = p1.Y-p2.Y; RectangleF bgRect = new RectangleF (p8.X, p8.Y, width, height); g.FillPath(this.BackgroundBrush, bgRect.RoundCorners(this.BackgroundCornerRadius)); g.DrawString(label.ToString(), this.LabelFont, this.ValueBrush, p7); g.DrawLine( this.LinePen, (int)p1.X, (int)p1.Y, (int)p2.X, (int)p2.Y ); g.DrawLine( this.LinePen, (int)p3.X, (int)p3.Y, (int)p4.X, (int)p4.Y ); g.DrawLine( this.LinePen, (int)p5.X, (int)p5.Y, (int)p6.X, (int)p6.Y ); }