private void DrawValueLabels(SKCanvas canvas, SKSize itemSize, Dictionary <ChartEntry, SKRect> valueLabelSizes) { ValueLabelOption valueLabelOption = ValueLabelOption; if (ValueLabelOption == ValueLabelOption.TopOfChart && Series.Count() > 1) { valueLabelOption = ValueLabelOption.TopOfElement; } if (valueLabelOption == ValueLabelOption.TopOfElement || valueLabelOption == ValueLabelOption.OverElement) { foreach (var pps in pointsPerSerie) { var entries = pps.Key.Entries.ToArray(); for (int i = 0; i < pps.Value.Count; i++) { var entry = entries[i]; if (!string.IsNullOrEmpty(entry.ValueLabel)) { var drawedPoint = pps.Value.ElementAt(i); SKPoint point; YPositionBehavior yPositionBehavior = YPositionBehavior.None; var valueLabelSize = valueLabelSizes[entry]; if (valueLabelOption == ValueLabelOption.TopOfElement) { point = new SKPoint(drawedPoint.X, drawedPoint.Y - (PointSize / 2) - (Margin / 2)); if (ValueLabelOrientation == Orientation.Vertical) { yPositionBehavior = YPositionBehavior.UpToElementHeight; } } else { if (ValueLabelOrientation == Orientation.Vertical) { yPositionBehavior = YPositionBehavior.UpToElementMiddle; } else { yPositionBehavior = YPositionBehavior.DownToElementMiddle; } point = new SKPoint(drawedPoint.X, drawedPoint.Y); } DrawHelper.DrawLabel(canvas, ValueLabelOrientation, yPositionBehavior, itemSize, point, entry.ValueLabelColor.WithAlpha((byte)(255 * AnimationProgress)), valueLabelSize, entry.ValueLabel, ValueLabelTextSize, Typeface, AllowValueLabelOverflow); } } } } }
internal static void DrawLabel(SKCanvas canvas, Orientation orientation, YPositionBehavior yPositionBehavior, SKSize itemSize, SKPoint point, SKColor color, SKRect bounds, string text, float textSize, SKTypeface typeface, bool allowOverflow) { using (new SKAutoCanvasRestore(canvas)) { using (var paint = new SKPaint()) { paint.TextSize = textSize; paint.IsAntialias = true; paint.Color = color; paint.IsStroke = false; paint.Typeface = typeface; if (orientation == Orientation.Vertical) { var y = point.Y; switch (yPositionBehavior) { case YPositionBehavior.UpToElementHeight: y -= bounds.Width; break; case YPositionBehavior.UpToElementMiddle: y -= bounds.Width / 2; break; case YPositionBehavior.DownToElementMiddle: y += bounds.Width / 2; break; case YPositionBehavior.None: default: break; } canvas.RotateDegrees(90); canvas.Translate(y, -point.X + (bounds.Height / 2)); } else { if (!allowOverflow) { if (bounds.Width > itemSize.Width) { text = text.Substring(0, Math.Min(3, text.Length)); paint.MeasureText(text, ref bounds); } if (bounds.Width > itemSize.Width) { text = text.Substring(0, Math.Min(1, text.Length)); paint.MeasureText(text, ref bounds); } } var y = point.Y; switch (yPositionBehavior) { case YPositionBehavior.UpToElementHeight: y -= bounds.Height; break; case YPositionBehavior.UpToElementMiddle: y -= bounds.Height / 2; break; case YPositionBehavior.DownToElementMiddle: y += bounds.Height / 2; break; case YPositionBehavior.None: default: break; } canvas.Translate(point.X - (bounds.Width / 2), y); } canvas.DrawText(text, 0, 0, paint); } } }
internal static void DrawLabel(SKCanvas canvas, Orientation orientation, YPositionBehavior yPositionBehavior, SKSize itemSize, SKPoint point, SKColor color, SKRect bounds, string text, float textSize, SKTypeface typeface, float margin) { using (new SKAutoCanvasRestore(canvas)) { using (var paint = new SKPaint()) { paint.TextSize = textSize; paint.IsAntialias = true; paint.Color = color; paint.IsStroke = false; paint.Typeface = typeface; if (orientation == Orientation.Vertical) { var y = point.Y; switch (yPositionBehavior) { case YPositionBehavior.UpToElementHeight: y -= bounds.Width; break; case YPositionBehavior.UpToElementMiddle: y -= bounds.Width / 2; break; case YPositionBehavior.DownToElementMiddle: y += bounds.Width / 2; break; case YPositionBehavior.DownToElementHeight: y += bounds.Width * 2; break; } // TODO: this needs to clamp to inside the control (top/bottom edges) canvas.RotateDegrees(90); canvas.Translate(y, -point.X + (bounds.Height / 2)); } else { // if no passed in size of the element we are drawing a label against, skip truncating the label if (!itemSize.IsEmpty) { if (bounds.Width > itemSize.Width) { text = text.Substring(0, Math.Min(3, text.Length)); paint.MeasureText(text, ref bounds); } if (bounds.Width > itemSize.Width) { text = text.Substring(0, Math.Min(1, text.Length)); paint.MeasureText(text, ref bounds); } } var x = point.X - bounds.Width / 2; var y = point.Y; switch (yPositionBehavior) { case YPositionBehavior.UpToElementHeight: y -= bounds.Height; break; case YPositionBehavior.UpToElementMiddle: y -= bounds.Height / 2; break; case YPositionBehavior.DownToElementMiddle: y += bounds.Height / 2; break; case YPositionBehavior.DownToElementHeight: y += bounds.Height * 2; break; } // clamp to inside the control (left/right edges) float clampRight = canvas.LocalClipBounds.Width - margin, clampBottom = canvas.LocalClipBounds.Height - margin; if (x < margin) { x = margin / 2; } if (x + bounds.Width > clampRight) { x = clampRight - bounds.Width; } // also on the y axis if (y < margin) { y = margin; } if (y + bounds.Height > clampBottom) { y = clampBottom; } canvas.Translate(x, y); } canvas.DrawText(text, 0, 0, paint); } } }
internal static YPositionBehavior ComputeEntryYPositionBehavior( ChartEntry entry, YPositionBehavior defaultBehaviour) { return(entry.ValueLabelYPositionBehavior.GetValueOrDefault(defaultBehaviour)); }