/// <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); if (lineDash != null) { ctx.SetLineDash (0, lineDash); } 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 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); if (lineDash != null) { ctx.SetLineDash(0, lineDash); } 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 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); ctx.Save(); ctx.SetColor(Color); ctx.SetLineWidth(1); 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 { p2 = p1; } double offset = p1.X - p2.X; p2.X = p1.X + offset; p2.Y = p1.Y; p3 = p2; } if (centre) { 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; } 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 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); ctx.Save (); ctx.SetColor (Color); ctx.SetLineWidth (1); 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 { p2 = p1; } double offset = p1.X - p2.X; p2.X = p1.X + offset; p2.Y = p1.Y; p3 = p2; } if (centre) { 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; } 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 (); }