/// <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> public void Draw(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis) { SequenceAdapter dataTop = new SequenceAdapter(this.DataSource, this.DataMember, this.OrdinateDataTop, this.AbscissaData); SequenceAdapter dataBottom = new SequenceAdapter(this.DataSource, this.DataMember, this.OrdinateDataBottom, this.AbscissaData); ITransform2D t = Transform2D.GetTransformer(xAxis, yAxis); for (int i = 0; i < dataTop.Count; ++i) { PointF physicalBottom = t.Transform(dataBottom[i]); PointF physicalTop = t.Transform(dataTop[i]); if (physicalBottom != physicalTop) { Rectangle r = new Rectangle((int)(physicalBottom.X - BarWidth / 2), (int)physicalTop.Y, (int)BarWidth, (int)(physicalBottom.Y - physicalTop.Y)); g.FillRectangle(this.rectangleBrush_.Get(r), r); g.DrawRectangle(borderPen_, r); } } }
/// <summary> /// Draw the filled region /// </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) { ITransform2D t = Transform2D.GetTransformer(xAxis, yAxis); Brush b = brush_; if (b == null) { b = areaBrush_.Get(new Rectangle(xAxis.PhysicalMin.X, yAxis.PhysicalMax.Y, xAxis.PhysicalLength, yAxis.PhysicalLength)); } if (hl1_ != null && hl2_ != null) { PointF[] points = new PointF[4]; points[0] = t.Transform(xAxis.Axis.WorldMin, hl1_.OrdinateValue); points[1] = t.Transform(xAxis.Axis.WorldMax, hl1_.OrdinateValue); points[2] = t.Transform(xAxis.Axis.WorldMax, hl2_.OrdinateValue); points[3] = t.Transform(xAxis.Axis.WorldMin, hl2_.OrdinateValue); g.FillPolygon(b, points); } else if (vl1_ != null && vl2_ != null) { PointF[] points = new PointF[4]; points[0] = t.Transform(vl1_.AbscissaValue, yAxis.Axis.WorldMin); points[1] = t.Transform(vl1_.AbscissaValue, yAxis.Axis.WorldMax); points[2] = t.Transform(vl2_.AbscissaValue, yAxis.Axis.WorldMax); points[3] = t.Transform(vl2_.AbscissaValue, yAxis.Axis.WorldMin); g.FillPolygon(b, points); } else if (lp1_ != null && lp2_ != null) { SequenceAdapter a1 = new SequenceAdapter(lp1_.DataSource, lp1_.DataMember, lp1_.OrdinateData, lp1_.AbscissaData); SequenceAdapter a2 = new SequenceAdapter(lp2_.DataSource, lp2_.DataMember, lp2_.OrdinateData, lp2_.AbscissaData); int count = a1.Count + a2.Count; PointF[] points = new PointF[count]; for (int i = 0; i < a1.Count; ++i) { points[i] = t.Transform(a1[i]); } for (int i = 0; i < a2.Count; ++i) { points[i + a1.Count] = t.Transform(a2[a2.Count - i - 1]); } g.FillPolygon(b, points); } else { throw new FlorenceException("One of bounds was set to null"); } }
/// <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 { // Ensure that we do not go outside of the graphics capabilities if ((Math.Abs(p1.X) + Math.Abs(p2.X)) < 0x4000007F && (Math.Abs(p1.Y) + Math.Abs(p2.Y)) < 0x4000007F) { g.DrawLine(Pen, p1.X, p1.Y, p2.X, p2.Y); } } } } }