Using NGraphics w/ NControl you can create a "vector" version of your "completeness meter" without creating platform renderers or needing to add libraries like Skia to your project.
Note: SkiaSharp and other native 2d/3d libraries are great, but add an lot of overhead to an app and if you do not need all their features then the bloat (app size, memory usage, initialization time, etc...) is not worth it (IMHO).
re: https://github.com/praeclarum/NGraphics
I stripped down a MultiSegmentProgressControl that I did to show you the basics of the arc drawing. The full version that I did allows you to add and animate multiple segments, displaying percentages, break-out segments on touch, etc...
Using NControl you can create composite controls with touch elements, so it is up to you on how far you need to take it.
re: https://github.com/chrfalch/NControl

public class MultiSegmentProgressControl2 : NControlView
{
double ringWidth = 50;
double ringInnerWidth = 100;
SolidBrush redBush = new SolidBrush(Colors.Red);
RadialGradientBrush redSegmentBrush = new RadialGradientBrush(
new Point(0.5, 0.5),
new Size(.75, .75),
Colors.LightGray,
Colors.Red);
SolidBrush blueBush = new SolidBrush(Colors.Blue);
RadialGradientBrush blueSegmentBrush = new RadialGradientBrush(
new Point(0.5, 0.5),
new Size(.75, .75),
Colors.LightGray,
Colors.Green);
Tuple<double, double> _redSegment;
public Tuple<double, double> RedSegment { get { return _redSegment; } set { _redSegment = value; Invalidate(); } }
Tuple<double, double> _greenSegment;
public Tuple<double, double> GreenSegment { get { return _greenSegment; } set { _greenSegment = value; Invalidate(); } }
public override void Draw(ICanvas canvas, Rect rect)
{
canvas.FillEllipse(rect.TopLeft, rect.Size, Colors.Gray);
var n = rect;
n.X += ringWidth;
n.Y = n.X;
n.Width -= ringWidth * 2;
n.Height = n.Width;
var i = n;
canvas.FillEllipse(n.TopLeft, n.Size, Colors.LightGray);
n.X += ringInnerWidth;
n.Y = n.X;
n.Width -= ringInnerWidth * 2;
n.Height = n.Width;
canvas.FillEllipse(n.TopLeft, n.Size, Colors.White);
var r = rect.Width / 2;
DrawSegment(canvas, rect, ringWidth, redBush, r, _redSegment.Item1, _redSegment.Item2);
DrawSegment(canvas, i, ringInnerWidth, redSegmentBrush, r - ringWidth, _redSegment.Item1, _redSegment.Item2);
DrawSegment(canvas, rect, ringWidth, blueBush, r, _greenSegment.Item1, _greenSegment.Item2);
DrawSegment(canvas, i, ringInnerWidth, blueSegmentBrush, r - ringWidth, _greenSegment.Item1, _greenSegment.Item2);
}
void DrawSegment(ICanvas canvas, Rect rect, double width, Brush brush, double r, double s, double f)
{
canvas.DrawPath(new PathOp[]{
new MoveTo(SegmentEdgePoint(rect.Center, r, s)),
new ArcTo(new Size(rect.Height / 2, rect.Width / 2), false, true, SegmentEdgePoint(rect.Center, r, f)),
new LineTo(SegmentEdgePoint(rect.Center, r - width, f)),
new ArcTo(new Size(r, r), false, false, SegmentEdgePoint(rect.Center, r - width, s)),
new LineTo(SegmentEdgePoint(rect.Center, r, s)),
new ClosePath()
}, null, brush);
}
Point SegmentEdgePoint(Point c, double r, double d)
{
return new Point(
c.X + r * Math.Cos(d * Math.PI / 180),
c.Y + r * Math.Sin(d * Math.PI / 180)
);
}
}
When using NGraphics I highly recommend using the NGraphics.Editoror a Xamarin' WorkBook to interactively design your control:
