public override void Draw(CGRect rect) { base.Draw(rect); _highTemps = null; _lowTemps = null; _hourlyTemps = null; if (Forecasts.Count == 0 || Hourly.Count == 0) { return; } graphRect = new CGRect(rect.X + padding, rect.Y + padding, rect.Width - (padding * 2), rect.Height - (padding * 2)); var days = Hourly.GroupBy(h => h.FCTTIME.mday).Select(g => g.First().FCTTIME.weekday_name_abbrev).ToList(); var dayCount = hourly ? days.Count : Forecasts.Count; var xAxisScale = (graphRect.Width + padding / 2) / dayCount; inset = xAxisScale / 2; var highest = (nfloat)(hourly ? HourlyTemps.Max() : HighTemps.Max()); var lowest = (nfloat)(hourly ? HourlyTemps.Min() : LowTemps.Min()); scaleHigh = NMath.Round(highest, MidpointRounding.AwayFromZero); scaleLow = lowest < 0 ? NMath.Round(lowest, MidpointRounding.AwayFromZero) : NMath.Round(lowest); var rangePadding = Settings.UomTemperature.IsImperial() ? scalePadding : (scalePadding / 2); scaleHigh += rangePadding; scaleLow -= rangePadding; scaleRange = scaleHigh - scaleLow; var scaleIncrement = scaleRange / dividerCount; scaleX = (graphRect.Width - inset) / (hourly ? HourlyTemps.Count : Forecasts.Count); scaleY = graphRect.Height / dividerCount; nfloat x, y; using (CGContext ctx = UIGraphics.GetCurrentContext()) { // Draw x and y axis using (UIColor color = UIColor.White) { color.SetStroke(); ctx.SetLineWidth(1); using (CGPath p = new CGPath()) { p.MoveToPoint(graphRect.GetMinX(), graphRect.GetMaxY()); p.AddLines(new [] { new CGPoint(graphRect.GetMinX(), graphRect.GetMinY()), new CGPoint(graphRect.GetMinX(), graphRect.GetMaxY()), new CGPoint(graphRect.GetMaxX(), graphRect.GetMaxY()) }); ctx.AddPath(p); ctx.DrawPath(CGPathDrawingMode.Stroke); } } // Draw horizontal gridlines using (UIColor color = UIColor.Black.ColorWithAlpha(0.08f)) { for (int i = 1; i < dividerCount; i += 2) { y = (i + 1) * scaleY; color.SetFill(); ctx.FillRect(new CGRect(graphRect.GetMinX(), graphRect.GetMaxY() - y, graphRect.Width, scaleY)); ctx.StrokePath(); } } drawLines(); // Draw y-axis labels nfloat yStep = scaleLow; ctx.SaveState(); ctx.TranslateCTM(0, rect.Height); ctx.ScaleCTM(1, -1); for (int i = 0; i <= dividerCount; i++) { y = padding + (i * scaleY); var step = NMath.Round(yStep).ToString(); drawLabel(ctx, rect, y, padding - 6, UITextAlignment.Right, step, false, true); yStep += scaleIncrement; } // Draw x-axis labels for (int i = 0; i < dayCount; i++) { x = padding + (i * xAxisScale); drawLabel(ctx, rect, padding - 6, x, UITextAlignment.Left, hourly ? days [i] : Forecasts [i]?.date?.weekday_short, false); } ctx.RestoreState(); } }
public override void Draw(Canvas canvas) { base.Draw(canvas); if (!scaled) { density = Resources.DisplayMetrics.Density; padding *= density; lineWidth *= density; fontSize *= density; scaled = true; } _highTemps = null; _lowTemps = null; _hourlyTemps = null; if (Forecasts.Count == 0 || Hourly.Count == 0) { return; } graphRect = new RectF(padding, padding, canvas.Width - padding, canvas.Height - padding); // CGRect (rect.X + padding, rect.Y + padding, rect.Width - (padding * 2), rect.Height - (padding * 2)); System.Diagnostics.Debug.WriteLine($"lineWidth = {lineWidth}"); System.Diagnostics.Debug.WriteLine($"canvas.Width = {canvas.Width}"); System.Diagnostics.Debug.WriteLine($"canvas.Height = {canvas.Height}"); System.Diagnostics.Debug.WriteLine($"graphRect.Width() = {graphRect.Width ()}"); System.Diagnostics.Debug.WriteLine($"graphRect.Height() = {graphRect.Height ()}"); System.Diagnostics.Debug.WriteLine($"graphRect.Left = {graphRect.Left}"); System.Diagnostics.Debug.WriteLine($"graphRect.Top = {graphRect.Top}"); System.Diagnostics.Debug.WriteLine($"graphRect.Right = {graphRect.Right}"); System.Diagnostics.Debug.WriteLine($"graphRect.Bottom = {graphRect.Bottom}"); var days = Hourly.GroupBy(h => h.FCTTIME.mday).Select(g => g.First().FCTTIME.weekday_name_abbrev).ToList(); var dayCount = hourly ? days.Count : Forecasts.Count; var xAxisScale = (graphRect.Width() + padding / 2) / dayCount; inset = xAxisScale / 2; var highest = (float)(hourly ? HourlyTemps.Max() : HighTemps.Max()); var lowest = (float)(hourly ? HourlyTemps.Min() : LowTemps.Min()); scaleHigh = (float)Math.Round(highest, MidpointRounding.AwayFromZero); scaleLow = lowest < 0 ? (float)Math.Round(lowest, MidpointRounding.AwayFromZero) : (float)Math.Round(lowest); var rangePadding = Settings.UomTemperature.IsImperial() ? scalePadding : (scalePadding / 2); scaleHigh += rangePadding; scaleLow -= rangePadding; scaleRange = scaleHigh - scaleLow; var scaleIncrement = scaleRange / dividerCount; scaleX = (graphRect.Width() - inset) / (hourly ? HourlyTemps.Count : Forecasts.Count); scaleY = graphRect.Height() / dividerCount; float x, y; var white = Color.White; // Draw x and y axis var paint = new Paint(); paint.Color = white; paint.StrokeWidth = 1; using (Path path = new Path()) { path.MoveTo(graphRect.Left, graphRect.Top); path.LineTo(graphRect.Left, graphRect.Bottom); path.LineTo(graphRect.Right, graphRect.Bottom); paint.SetStyle(Paint.Style.Stroke); canvas.DrawPath(path, paint); } Color translucentBlack = Color.Argb(20, 0, 0, 0); paint.Color = translucentBlack; paint.SetStyle(Paint.Style.Fill); // Draw horizontal gridlines for (int i = 1; i < dividerCount; i += 2) { y = graphRect.Bottom - ((i + 1) * scaleY); using (RectF grid = new RectF(padding, y, graphRect.Right, y + scaleY)) canvas.DrawRect(grid, paint); } drawLines(canvas, paint); float labelPadding = 6 * density; float yStep = scaleLow; // Draw y-axis labels for (int i = dividerCount; i >= 0; i--) { y = padding + (i * scaleY); var step = Math.Round(yStep).ToString(); drawLabel(canvas, graphRect.Left - labelPadding, y, Paint.Align.Right, step, true); yStep += scaleIncrement; } // Draw x-axis labels for (int i = 0; i < dayCount; i++) { x = padding + (i * xAxisScale); drawLabel(canvas, x, graphRect.Bottom + labelPadding, Paint.Align.Left, hourly ? days [i] : Forecasts [i]?.date?.weekday_short); } }