Customize Android AChartEngine PieChart (show text inside chart)

852 Views Asked by At

Is there a way to update the text inside a Pie Chart (generated through the achartEngine API). I want to show the percentage there. In the picture below, I have it updated manually (i.e. 60%, 30% and 10%) to show you.

Image1

I could not find relevant method in the SimpleSeriesRenderer class. Here is the code I am using.

CategorySeries categorySeries = new CategorySeries("Chart");

for (int i = 0; i < series.size(); i++) {
    categorySeries.add(series.get(i), series_data.get(i));
}

DefaultRenderer defaultRenderer = new DefaultRenderer();

defaultRenderer.setBackgroundColor(Color.BLACK);
defaultRenderer.setShowLabels(true);
defaultRenderer.setShowLegend(true);
defaultRenderer.setShowTickMarks(true);
defaultRenderer.setLabelsTextSize(40f);
defaultRenderer.setLegendTextSize(40f);
defaultRenderer.setApplyBackgroundColor(true);

for (int i = 0; i < series_data.size(); i++) {

    SimpleSeriesRenderer simpleSeriesRenderer = new SimpleSeriesRenderer();
    simpleSeriesRenderer.setColor(  chartColor[i]);
    defaultRenderer.addSeriesRenderer(simpleSeriesRenderer);
}
1

There are 1 best solutions below

2
Andrii Omelchenko On BEST ANSWER

You can create custom class, which extends PieChart and override it's drawLabel() (and may be draw()) method:

public class AdvancedPieChart extends PieChart {

   @Override
   protected void drawLabel(Canvas canvas, String labelText, DefaultRenderer renderer, List<RectF> prevLabelsBounds, int centerX, int centerY, float shortRadius, float longRadius, float currentAngle, float angle, int left, int right, int color, Paint paint, boolean line, boolean display) {
      // do what You want with Label text, e.g. just
      canvas.drawText(labelText, xLabel, yLabel, paint);
   }

}

and use your AdvancedPieChart class instead of "standard" PieChart.

Update:

For example, this implementation:

public class AdvancedPieChart extends PieChart {

    public AdvancedPieChart(CategorySeries dataset, DefaultRenderer renderer) {
        super(dataset, renderer);
    }


    @Override
    protected void drawLabel(Canvas canvas, String labelText, DefaultRenderer renderer, List<RectF> prevLabelsBounds, int centerX, int centerY, float shortRadius, float longRadius, float currentAngle, float angle, int left, int right, int color, Paint paint, boolean line, boolean display) {
        super.drawLabel(canvas, labelText, renderer, prevLabelsBounds, centerX, centerY, shortRadius, longRadius, currentAngle, angle, left, right, color, paint, line, display);

        String additionalText = "Hello";
        Paint textPaint = new Paint();
        textPaint.setColor(Color.WHITE);
        textPaint.setTextSize(18 * Resources.getSystem().getDisplayMetrics().densityDpi / 160f);
        textPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
        Rect bounds = new Rect();
        textPaint.getTextBounds(additionalText, 0, additionalText.length(), bounds);
        canvas.drawText(additionalText, this.mCenterX - bounds.width() / 2, this.mCenterY - bounds.height() / 3, textPaint);
    }
}

draw text "Hello" in the center of chart:

AdvancedPieChart screenshot

Layout (activity_main.xml) for that:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:id="@+id/activity_main"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="ua.com.omelchenko.chartapplication.MainActivity">

    <RelativeLayout
        android:id="@+id/chart_holder"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </RelativeLayout>

</RelativeLayout>

(of course You don't need nested layouts)

and MainActivity.java is:

public class MainActivity extends AppCompatActivity {

    private RelativeLayout mPieChartHolder;
    private GraphicalView mChartView;
    private PieChart mPieChart;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String[] names = new String[] { "Category 1", "Category 2", "Category 3" };
        double[] values = { 20, 30, 50 };
        int[] colors = { Color.RED, Color.GREEN, Color.BLUE };

        CategorySeries categorySeries = new CategorySeries("Pie Chart");
        for (int i = 0; i < names.length; i++) {
            categorySeries.add(names[i], values[i]);
        }

        DefaultRenderer defaultRenderer = new DefaultRenderer();
        for (int i = 0; i < values.length; i++) {
            SimpleSeriesRenderer seriesRenderer = new SimpleSeriesRenderer();
            seriesRenderer.setColor(colors[i]);
            defaultRenderer.setBackgroundColor(Color.BLACK);
            defaultRenderer.setLabelsTextSize(20f);
            defaultRenderer.setLegendTextSize(20f);
            defaultRenderer.setApplyBackgroundColor(true);
            defaultRenderer.addSeriesRenderer(seriesRenderer);
        }

        mPieChart = new AdvancedPieChart(categorySeries, defaultRenderer);
        mChartView = new GraphicalView(this, mPieChart);

        mPieChartHolder = (RelativeLayout) findViewById(R.id.chart_holder);
        mPieChartHolder.addView(mChartView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT));
    }

}

(of course it's just demo).

And if You press Ctrl+LeftMouseButton when mouse pointer is on PieChart word in AndroidStudio 2.0 and above You can find many interesting things about inner organization of PieChart, for example coordinates of pies centers etc.