This code shows the labels surrounded by white boxes (central picture), and I can't seem to find a solution to remove them.
<telerikChart:RadPieChart.Series> <telerikChart:PieSeries ItemsSource="{Binding Data}" ShowLabels="True"> <telerikChart:PieSeries.ValueBinding> <telerikChart:PropertyNameDataPointBinding PropertyName="Value"/> </telerikChart:PieSeries.ValueBinding> </telerikChart:PieSeries> </telerikChart:RadPieChart.Series>
6 Answers, 1 is accepted
There is currently no option from Xamarin.Forms to set the label template. In this particular case, what you're reporting is only on Android.
To customize this, you'll need to create a custom renderer and access the native Android Chart's properties in the renderer. You can see how to create a customized native label-renderer (different than a Xamarin.Forms renderer) here the native chart's labels here in the native control's documentation.
Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Hi Lance,
Thanks for your answer.
I am working on a native control, but there is absolutely no example in code of a Pie chart in samples without these white boxes around the labels.
I tried to set the LabelStrokeColor to transparent, but the boxes are still there.
I tried to do a custom renderer, but no example of a LabelRenderer on a Pie Chart.
My code is not working as it doesn't show the labels at all: the dataPoint.LayoutSlot has value of (0,0,0,0) .
Here is my code:
public class CustomLabelRenderer : BaseLabelRenderer
{
private string labelFormat = "{0}";
private TextPaint paint = new TextPaint();
private Paint strokePaint = new Paint();
private Paint fillPaint = new Paint();
private float labelMargin = 10.0f;
private float labelPadding = 20.0f;
public CustomLabelRenderer(ChartSeries owner)
: base(owner)
{
this.strokePaint.SetStyle(Paint.Style.Stroke);
this.strokePaint.Color = Color.White;
this.strokePaint.StrokeWidth = 2;
this.fillPaint.Color = Color.ParseColor("#F5413F");
this.paint.TextSize = 35.0f;
this.paint.Color = Color.White;
}
public override void RenderLabel(Canvas canvas,
Com.Telerik.Widget.Chart.Engine.ElementTree.ChartNode relatedLabelNode)
{
PieDataPoint dataPoint =
relatedLabelNode.JavaCast<PieDataPoint>();
RadRect dataPointSlot = dataPoint.LayoutSlot;
double val = dataPoint.Value;
string labelText = string.Format(labelFormat, (int)val);
StaticLayout textInfo = this.CreateTextInfo(labelText, dataPoint);
this.RenderLabel(canvas, dataPointSlot, labelText, textInfo);
}
private StaticLayout CreateTextInfo(string labelText,
PieDataPoint dataPoint)
{
return new StaticLayout(labelText,
0,
labelText.Length,
this.paint,
(int)Math.Round((float)dataPoint.LayoutSlot.Width),
Layout.Alignment.AlignCenter,
1.0f,
1.0f,
false);
}
private void RenderLabel(Canvas canvas, RadRect dataPointSlot,
string labelText, StaticLayout textBounds)
{
RectF labelBounds = new RectF();
float height = textBounds.Height + this.labelPadding * 2;
float top = (float)dataPointSlot.GetY() - this.labelMargin - height;
labelBounds.Set(
(float)dataPointSlot.GetX(),
top,
(float)dataPointSlot.Right,
top + height);
canvas.DrawRect(
labelBounds.Left,
labelBounds.Top,
labelBounds.Right,
labelBounds.Bottom,
this.fillPaint);
canvas.DrawRect(
labelBounds.Left,
labelBounds.Top,
labelBounds.Right,
labelBounds.Bottom,
this.strokePaint);
canvas.DrawText(
(string) labelText,
(float)dataPointSlot.GetX() + (float)(dataPointSlot.Width / 2.0) -
textBounds.GetLineWidth(0) / 2.0f,
labelBounds.CenterY() + textBounds.GetLineBottom(0) -
textBounds.GetLineBaseline(0),
paint);
}
}
Try inheriting from a higher-level label renderer. Instead of BaseLabelRenderer, use a PieSeriesLabelRenderer and set the LableStrokePaint.
Also check out some of the available overrides to see what else you might want to access in the lifecycle, I left a few in my code for you to see what I mean.
Example
class
CustomPieSeriesLabelRenderer : PieSeriesLabelRenderer
{
private
readonly
Paint strokePaint =
new
Paint();
protected
CustomPieSeriesLabelRenderer(IntPtr javaReference, JniHandleOwnership transfer)
:
base
(javaReference, transfer)
{
}
public
CustomPieSeriesLabelRenderer(PieSeries p0)
:
base
(p0)
{
}
public
override
void
RenderLabel(Canvas canvas, ChartNode node)
{
this
.strokePaint.Color = Color.Transparent;
LabelStrokePaint = strokePaint;
base
.RenderLabel(canvas, node);
}
protected
override
void
DrawLabelText(Canvas canvas,
string
text,
float
p2,
float
p3)
{
base
.DrawLabelText(canvas, text, p2, p3);
}
protected
override
void
DrawLabelBackground(Canvas canvas, Path path,
int
p2)
{
base
.DrawLabelBackground(canvas, path, p2);
}
protected
override
Paint GetLabelFillPaint(
int
p0)
{
return
base
.GetLabelFillPaint(p0);
}
}
Then, make sure you're setting the series's LabelRenderer property with an instance of your custom label renderer:
PieSeries pieSeries =
new
PieSeries();
pieSeries.LabelRenderer =
new
CustomPieSeriesLabelRenderer(pieSeries);
pieSeries.ShowLabels =
true
;
Demo
I've attached a demo for you. Note it uses 26.1.0.1, if you don't have it installed just use the code from MainActivity.cs.
Here's the result at runtime:
I hope this helps get you up and running!
Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Thanks for your answer.
It works perfectly with the PieSeriesLabelRenderer !
Regards
Hi, I'm trying to do this using xamarin.forms. I can create the CustomPieSeriesLabelRenderer you made in my android project, but how do i set the renderer of my PieSeries in my StandardLib (shared project). While in my Standard Lib, the PieSeries doesn't have a LabelRenderer property. I tried using this line :
[assembly: ExportRenderer(typeof(Telerik.XamarinForms.Chart.PieSeries), typeof(CustomPieSeriesLabelRenderer))]
over my name space in my CustomPieSeriesLabelRenderer class but it doesn't seem to work for now. Do you have some advice?
When in a shared project (not PCL or .NET Standard), you need to use ifdefs to differentiate between which platform the shared renderer is being compiled for (see this StackOverflow post).
If you're not seeing a LabelRenderer property, then the PieSeries object is likely incorrectly pointing to Com.Telerik.Widget.Chart.Visualization.PieChart instead of Telerik.XamarinForms.Chart namespace. The PieSeries class name exists in both namespaces.
If you're still having trouble, please open a Support Ticket (you have a Priority Support license) and attach your project (or full code) so that I can investigate directly.
Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik