public override void DrawContent(SKCanvas canvas, int width, int height) { var total = Series.Count(); if (total > 0) { var captionHeight = Series.First().Max(x => { var result = 0.0f; var hasLabel = !string.IsNullOrEmpty(x.Label); var hasValueLabel = !string.IsNullOrEmpty(x.ValueLabel); if (hasLabel || hasValueLabel) { var hasOffset = hasLabel && hasValueLabel; var captionMargin = LabelTextSize * 0.60f; var space = hasOffset ? captionMargin : 0; if (hasLabel) { result += LabelTextSize; } if (hasValueLabel) { result += LabelTextSize; } } return(result); }); var center = new SKPoint(width / 2, height / 2); var radius = ((Math.Min(width, height) - (2 * Margin)) / 2) - captionHeight; var rangeAngle = (float)((Math.PI * 2) / total); var startAngle = (float)Math.PI; var nextEntry = Series.First().First(); var nextAngle = startAngle; var nextPoint = GetPoint(nextEntry.Value, center, nextAngle, radius); DrawBorder(canvas, center, radius); for (int i = 0; i < total; i++) { var angle = nextAngle; var entry = nextEntry; var point = nextPoint; var nextIndex = (i + 1) % total; nextAngle = startAngle + (rangeAngle * nextIndex); nextEntry = Series.First().ElementAt(nextIndex); nextPoint = GetPoint(nextEntry.Value, center, nextAngle, radius); // Border center bars using (var paint = new SKPaint() { Style = SKPaintStyle.Stroke, StrokeWidth = BorderLineSize, Color = BorderLineColor, IsAntialias = true, }) { var borderPoint = GetPoint(MaxValue, center, angle, radius); canvas.DrawLine(point.X, point.Y, borderPoint.X, borderPoint.Y, paint); } // Values points and lines using (var paint = new SKPaint() { Style = SKPaintStyle.Stroke, StrokeWidth = BorderLineSize, Color = entry.Color.WithAlpha((byte)(entry.Color.Alpha * 0.75f)), PathEffect = SKPathEffect.CreateDash(new[] { BorderLineSize, BorderLineSize * 2 }, 0), IsAntialias = true, }) { var amount = Math.Abs(entry.Value - AbsoluteMinimum) / ValueRange; canvas.DrawCircle(center.X, center.Y, radius * amount, paint); } canvas.DrawGradientLine(center, entry.Color.WithAlpha(0), point, entry.Color.WithAlpha((byte)(entry.Color.Alpha * 0.75f)), LineSize); canvas.DrawGradientLine(point, entry.Color, nextPoint, nextEntry.Color, LineSize); canvas.DrawPoint(point, entry.Color, PointSize, PointMode); // Labels var labelPoint = GetPoint(MaxValue, center, angle, radius + LabelTextSize + (PointSize / 2)); var alignment = SKTextAlign.Left; if ((Math.Abs(angle - (startAngle + Math.PI)) < Epsilon) || (Math.Abs(angle - Math.PI) < Epsilon)) { alignment = SKTextAlign.Center; } else if (angle > (float)(startAngle + Math.PI)) { alignment = SKTextAlign.Right; } canvas.DrawCaptionLabels(entry.Label, entry.TextColor, entry.ValueLabel, entry.Color, LabelTextSize, labelPoint, alignment); } } }
public override void DrawContent(SKCanvas canvas, int width, int height) { var total = this.Entries?.Count() ?? 0; if (total > 0) { var captionHeight = this.Entries.Max(x => { var result = 0.0f; var hasLabel = !string.IsNullOrEmpty(x.Label); var hasValueLabel = !string.IsNullOrEmpty(x.ValueLabel); if (hasLabel || hasValueLabel) { var hasOffset = hasLabel && hasValueLabel; var captionMargin = this.LabelTextSize * 0.60f; var space = hasOffset ? captionMargin : 0; if (hasLabel) { result += this.LabelTextSize; } if (hasValueLabel) { result += this.LabelTextSize; } } return(result); }); var center = new SKPoint(width / 2, height / 2); var radius = ((Math.Min(width, height) - (2 * Margin)) / 2) - captionHeight; var rangeAngle = (float)((Math.PI * 2) / total); var startAngle = (float)Math.PI; var nextEntry = this.Entries.First(); var nextAngle = startAngle; var nextPoint = this.GetPoint(nextEntry.Value * this.AnimationProgress, center, nextAngle, radius); this.DrawBorder(canvas, center, radius); using (var clip = new SKPath()) { clip.AddCircle(center.X, center.Y, radius); for (int i = 0; i < total; i++) { var angle = nextAngle; var entry = nextEntry; var point = nextPoint; var nextIndex = (i + 1) % total; nextAngle = startAngle + (rangeAngle * nextIndex); nextEntry = this.Entries.ElementAt(nextIndex); nextPoint = this.GetPoint(nextEntry.Value * this.AnimationProgress, center, nextAngle, radius); canvas.Save(); canvas.ClipPath(clip); // Border center bars using (var paint = new SKPaint() { Style = SKPaintStyle.Stroke, StrokeWidth = this.BorderLineSize, Color = this.BorderLineColor, IsAntialias = true, }) { var borderPoint = this.GetPoint(this.MaxValue, center, angle, radius); canvas.DrawLine(point.X, point.Y, borderPoint.X, borderPoint.Y, paint); } // Values points and lines using (var paint = new SKPaint() { Style = SKPaintStyle.Stroke, StrokeWidth = this.BorderLineSize, Color = entry.Color.WithAlpha((byte)(entry.Color.Alpha * 0.75f * this.AnimationProgress)), PathEffect = SKPathEffect.CreateDash(new[] { this.BorderLineSize, this.BorderLineSize * 2 }, 0), IsAntialias = true, }) { var amount = Math.Abs(entry.Value - this.AbsoluteMinimum) / this.ValueRange; canvas.DrawCircle(center.X, center.Y, radius * amount, paint); } canvas.DrawGradientLine(center, entry.Color.WithAlpha(0), point, entry.Color.WithAlpha((byte)(entry.Color.Alpha * 0.75f)), this.LineSize); canvas.DrawGradientLine(point, entry.Color, nextPoint, nextEntry.Color, this.LineSize); canvas.DrawPoint(point, entry.Color, this.PointSize, this.PointMode); canvas.Restore(); // Labels var labelPoint = new SKPoint(0, radius + this.LabelTextSize + (this.PointSize / 2)); var rotation = SKMatrix.MakeRotation(angle); labelPoint = center + rotation.MapPoint(labelPoint); var alignment = SKTextAlign.Left; if ((Math.Abs(angle - (startAngle + Math.PI)) < Epsilon) || (Math.Abs(angle - Math.PI) < Epsilon)) { alignment = SKTextAlign.Center; } else if (angle > (float)(startAngle + Math.PI)) { alignment = SKTextAlign.Right; } canvas.DrawCaptionLabels(entry.Label, entry.TextColor, entry.ValueLabel, entry.Color.WithAlpha((byte)(255 * this.AnimationProgress)), this.LabelTextSize, labelPoint, alignment, base.Typeface, out var _); } } } }