user6304988
user6304988

Reputation: 25

Display multiple lines of text in Oxyplot TextAnnotation

I'm working on an Android app utilizing xamarin and the oxyplot library. I ran into a problem where I cannot add multiple lines of text in TextAnnotation. I tried the following options:

  var sb = new StringBuilder();
  sb.Append("Line1");
  sb.AppendLine(); // which is equal to Append(Environment.NewLine);
  sb.Append("\n");
  sb.Append("\r\n");
  sb.Append(System.Environment.NewLine);
  sb.Append("Line2");

and added it like so to the TextAnnotation text object:

        var textAnnotation1 = new TextAnnotation();
        textAnnotation1.Text = sb.ToString();
        textAnnotation1.Background = OxyColors.White;
        textAnnotation1.TextColor = OxyColors.Black;
        textAnnotation1.FontSize = 18;
        textAnnotation1.TextPosition = new DataPoint(4,_vericalLineYaxis);
        plotModel.Annotations.Add(textAnnotation1);

but all to avail.

My goal is to have the text appear like so:

Line 1
Line 2

Currently it's appearing as:

Line 1 Line2

Any help would be much appreciated.

Upvotes: 0

Views: 948

Answers (1)

SushiHangover
SushiHangover

Reputation: 74134

Multi-line Annotations is not currently supported on the Android platform.

OxyPlot is invoking Android.Canvas.DrawText and that function does not support text wrapping, it is a fairly low-level primitive drawing routine.

If you feel like mod'ing the source, this could be done by using a static layout vs. the current canvas.DrawText.

Something like this would get you started (but is untested):

public void DrawText (string text, float x, float y, Paint paint) 
{
    TextPaint textPaint = new TextPaint();
    StaticLayout textLayout = new StaticLayout(text, textPaint, canvas.getWidth(), Alignment.ALIGN_NORMAL, 1.0f, 0.0f, False);
    canvas.Save();
    canvas.Translate(x, y);
    textLayout.Draw(canvas);
    canvas.Restore();
}

FYI: Oxyplot's SVG renderer manually handles multi-line text by string splitting on "\r\n" and rendering a separate element for each line so the same thing could be done for the Android instead of using a StaticLayout (slower performance wise, but easy to mod/test):

var lines = Regex.Split(text, "\r\n");
if (valign == VerticalAlignment.Bottom)
{
    for (var i = lines.Length - 1; i >= 0; i--)
    {
        var line = lines[i];
        var size = this.MeasureText(line, fontFamily, fontSize, fontWeight);
        this.w.WriteText(p, line, c, fontFamily, fontSize, fontWeight, rotate, halign, valign);

        p += new ScreenVector(Math.Sin(rotate / 180.0 * Math.PI) * size.Height, Math.Cos(rotate / 180.0 * Math.PI) * size.Height);
    }
}

Upvotes: 1

Related Questions