WISHY
WISHY

Reputation: 11999

Legends get cut off with pie chart in MPAndroidChart?

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

Upvotes: 2

Views: 2027

Answers (3)

adi
adi

Reputation: 708

I was using the same library and faced the same issue. To fix this issue, please follow below steps:

  1. Set properties for legends such as legend.setWordWrapEnabled(true) and legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT).
  2. Most important thing is, put 'setData' method of piechart at the end after setting all the properties of piechart.

Upvotes: -1

WISHY
WISHY

Reputation: 11999

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

Upvotes: 1

Abhishek Dutt
Abhishek Dutt

Reputation: 1437

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.

Upvotes: 3

Related Questions