/// <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 ();
}