Home > Mobile >  Legends get cut off with pie chart in MPAndroidChart?
Legends get cut off with pie chart in MPAndroidChart?

Time:11-03

I am using MPAndroid chart library to show pie chart in my app The legends / chart description labels are not wrapping below one another I used pieChart.legend.isWordWrapEnabled=true but it doesn't work out

This is my xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".equity.EquityFragment">

<include
    android:id="@ id/pageTitleLayout"
    layout="@layout/page_title" />

<com.github.mikephil.charting.charts.PieChart
    android:id="@ id/pieChart"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@ id/pageTitleLayout" />
<include
    android:id="@ id/loader"
    layout="@layout/view_progress_loader"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>

And this is code

private fun createChart(chartData:List<EquityPieChart>){
    val pieEntry= chartData.map { PieEntry(it.equity,it.name) }
    val rnd = Random()
    val colors = mutableListOf<Int>()
    for (i in chartData.indices){
        colors.add(Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256)))
    }
    val dataSet=PieDataSet(pieEntry,getString(R.string.equity_title))
    dataSet.colors=colors
    binding.pieChart.data = PieData(dataSet)
    binding.pieChart.isDrawHoleEnabled=false
    binding.pieChart.legend.isWordWrapEnabled=true
    binding.pieChart.invalidate()

}

this is the UI i get in device

enter image description here

CodePudding user response:

The text of legends are too big to be fit inside the graph. One way is to keep them outside the graph. The following attribute can be added to achieve this job: setDrawInside()

Please use this code:

Legend l = pieChart.getLegend();
l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
l.setDrawInside(false);
l.setXEntrySpace(4f);
l.setYEntrySpace(0f);
l.setWordWrapEnabled(true);

This will set the legend outside the graph.

CodePudding user response:

I ended up doing like this with the help of flexboxlayout

XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".equity.EquityFragment">

<include
    android:id="@ id/pageTitleLayout"
    layout="@layout/page_title" />

<com.github.mikephil.charting.charts.PieChart
    android:id="@ id/pieChart"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintBottom_toTopOf="@ id/chartLabels"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@ id/pageTitleLayout" />

<com.google.android.flexbox.FlexboxLayout
    android:id="@ id/chartLabels"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:flexWrap="wrap"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent" />

<include
    android:id="@ id/loader"
    layout="@layout/view_progress_loader"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>

Legend layout

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="25dp"
android:padding="2dp">

<View
    android:id="@ id/legendBox"
    android:layout_width="10dp"
    android:layout_height="10dp"
    android:background="@color/primary_500"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintBottom_toBottomOf="@ id/legendTitle"
    app:layout_constraintTop_toTopOf="@ id/legendTitle"/>

<com.google.android.material.textview.MaterialTextView
    android:id="@ id/legendTitle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="12sp"
    tools:text="xxxxjdsfjsdfj"
    android:layout_marginStart="3dp"
    app:layout_constraintStart_toEndOf="@ id/legendBox"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
  </androidx.constraintlayout.widget.ConstraintLayout>

Kotlin code

 private fun createChart(chartData: List<EquityPieChart>) {
    val pieEntry = chartData.map { PieEntry(it.equity) }
    val rnd = Random()
    val colors = mutableListOf<Int>()
    for (i in chartData.indices) {
        colors.add(Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256)))
    }
    val dataSet = PieDataSet(pieEntry, getString(R.string.equity_title))
    dataSet.colors = colors
    dataSet.valueTextSize = 14f
    dataSet.setDrawValues(false)
    dataSet.valueTextColor = ContextCompat.getColor(requireContext(), android.R.color.white)
    binding.pieChart.data = PieData(dataSet)
    binding.pieChart.isDrawHoleEnabled = false
    binding.pieChart.description = Description().apply { text="" }
    binding.pieChart.invalidate()
    binding.pieChart.animateY(1400, Easing.EaseInOutQuad);
    binding.pieChart.legend.isEnabled = false
    creatChartLabels(colors,chartData)
}

private fun creatChartLabels(colors:List<Int>,chartData: List<EquityPieChart>){
    for (i in chartData.indices) {
        val view=ItemLegendBinding.inflate(layoutInflater)
        view.legendBox.setBackgroundColor(colors[i])
        view.legendTitle.text=chartData[i].name
        binding.chartLabels.addView(view.root)
    }
}

output

enter image description here

  • Related