How to Customize Chart Labels for Mpandroidchart Library

How to customize chart labels for mpandroidchart library

Use version greater than or equal to 3.0.1 of library and add below lines to your code:

XAxis xAxis = chart.getXAxis();
xAxis.setValueFormatter(new IndexAxisValueFormatter(getXAxisValues()));

Create following method also:

private ArrayList<String> getXAxisValues()
{
ArrayList<String> labels = new ArrayList<String> ();

labels.add( "SUN");
labels.add( "MON");
labels.add( "TUE");
labels.add( "WED");
labels.add( "THU");
labels.add( "FRI");
labels.add( "SAT");
return labels;
}

Custom label indicators on xAxis in MpAndroidChart

I solved the first issue:

internal class IndicatorAxisRenderer(
viewPortHandler: ViewPortHandler,
xAxis: XAxis,
trans: Transformer
) : XAxisRenderer(viewPortHandler, xAxis, trans) {

private var indicatorWidth = 1f
private var indicatorHeight = 1f

private fun getXLabelPositions(): FloatArray {
var i = 0
val positions = FloatArray(mXAxis.mEntryCount * 2)
val centeringEnabled = mXAxis.isCenterAxisLabelsEnabled
while (i < positions.size) {
if (centeringEnabled) {
positions[i] = mXAxis.mCenteredEntries[i / 2]
} else {
positions[i] = mXAxis.mEntries[i / 2]
}
positions[i + 1] = 0f
i += 2
}
mTrans.pointValuesToPixel(positions)
return positions
}

override fun renderAxisLine(c: Canvas?) {
super.renderAxisLine(c)
val positions = getXLabelPositions()
var i = 0
while (i < positions.size) {
val x = positions[i]
if (mViewPortHandler.isInBoundsX(x)) {
val y = mViewPortHandler.contentBottom()
c?.drawLine(
x, y,
x, y + indicatorHeight,
mAxisLinePaint
)
}
i += 2
}
}

fun setIndicatorSize(width: Float, height: Float) {
this.indicatorWidth = width
this.indicatorHeight = height
}
}

This code renders indicator lines on top of the xAxis.

How to set X axis labels in MP Android Chart (Bar Graph)?

You just make a simple list of string like this :

final ArrayList<String> xAxisLabel = new ArrayList<>();
xAxisLabel.add("Mon");
xAxisLabel.add("Tue");
xAxisLabel.add("Wed");
xAxisLabel.add("Thu");
xAxisLabel.add("Fri");
xAxisLabel.add("Sat");
xAxisLabel.add("Sun");

Then you do this :

    XAxis xAxis = chart.getXAxis();
xAxis.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
return xAxisLabel.get((int) value);

}
});

Hope this helps.

Custom x-axis labelling in MPAndroid Chart

Nevermind, I was able to achieve this by using an older version of MPAndroidChart library and it worked like a charm.

MPAndroidChart - Adding labels to bar chart

Updated Answer (MPAndroidChart v3.0.1)

Being such a commonly used feature, v3.0.1 of the library added the IndexAxisValueFormatter class exactly for this purpose, so it's just one line of code now:

mBarChart.getXAxis().setValueFormatter(new IndexAxisValueFormatter(labels));

The ProTip from the original answer below still applies.

Original Answer (MPAndroidChart v3.0.0)

With v3.0.0 of the library there is no direct way of setting labels for the bars, but there's a rather decent workaround that uses the ValueFormatter interface.

Create a new formatter like this:

public class LabelFormatter implements IAxisValueFormatter {
private final String[] mLabels;

public LabelFormatter(String[] labels) {
mLabels = labels;
}

@Override
public String getFormattedValue(float value, AxisBase axis) {
return mLabels[(int) value];
}
}

Then set this formatter to your x-axis (assuming you've already created a String[] containing the labels):

mBarChart.getXAxis().setValueFormatter(new LabelFormatter(labels));

ProTip: if you want to remove the extra labels appearing when zooming into the bar chart, you can use the granularity feature:

XAxis xAxis = mBarChart.getXAxis();
xAxis.setGranularity(1f);
xAxis.setGranularityEnabled(true);

MPAndroidChart - Piechart - custom label lines

This is by no means easy to achieve. To decouple the lines from the chart, you can use valueLinePart1OffsetPercentage and play with line part lengths. But to get the chart to draw dots at the end of lines, you need a custom renderer. Here's one:

class CustomPieChartRenderer(pieChart: PieChart, val circleRadius: Float)
: PieChartRenderer(pieChart, pieChart.animator, pieChart.viewPortHandler) {

override fun drawValues(c: Canvas) {
super.drawValues(c)

val center = mChart.centerCircleBox

val radius = mChart.radius
var rotationAngle = mChart.rotationAngle
val drawAngles = mChart.drawAngles
val absoluteAngles = mChart.absoluteAngles

val phaseX = mAnimator.phaseX
val phaseY = mAnimator.phaseY

val roundedRadius = (radius - radius * mChart.holeRadius / 100f) / 2f
val holeRadiusPercent = mChart.holeRadius / 100f
var labelRadiusOffset = radius / 10f * 3.6f

if (mChart.isDrawHoleEnabled) {
labelRadiusOffset = (radius - radius * holeRadiusPercent) / 2f
if (!mChart.isDrawSlicesUnderHoleEnabled && mChart.isDrawRoundedSlicesEnabled) {
rotationAngle += roundedRadius * 360 / (Math.PI * 2 * radius).toFloat()
}
}

val labelRadius = radius - labelRadiusOffset

val dataSets = mChart.data.dataSets

var angle: Float
var xIndex = 0

c.save()
for (i in dataSets.indices) {
val dataSet = dataSets[i]
val sliceSpace = getSliceSpace(dataSet)
for (j in 0 until dataSet.entryCount) {
angle = if (xIndex == 0) 0f else absoluteAngles[xIndex - 1] * phaseX
val sliceAngle = drawAngles[xIndex]
val sliceSpaceMiddleAngle = sliceSpace / (Utils.FDEG2RAD * labelRadius)
angle += (sliceAngle - sliceSpaceMiddleAngle / 2f) / 2f

if (dataSet.valueLineColor != ColorTemplate.COLOR_NONE) {
val transformedAngle = rotationAngle + angle * phaseY
val sliceXBase = cos(transformedAngle * Utils.FDEG2RAD.toDouble()).toFloat()
val sliceYBase = sin(transformedAngle * Utils.FDEG2RAD.toDouble()).toFloat()
val valueLinePart1OffsetPercentage = dataSet.valueLinePart1OffsetPercentage / 100f
val line1Radius = if (mChart.isDrawHoleEnabled) {
(radius - radius * holeRadiusPercent) * valueLinePart1OffsetPercentage + radius * holeRadiusPercent
} else {
radius * valueLinePart1OffsetPercentage
}
val px = line1Radius * sliceXBase + center.x
val py = line1Radius * sliceYBase + center.y

if (dataSet.isUsingSliceColorAsValueLineColor) {
mRenderPaint.color = dataSet.getColor(j)
}
c.drawCircle(px, py, circleRadius, mRenderPaint)
}

xIndex++
}
}
MPPointF.recycleInstance(center)
c.restore()
}
}

This custom renderer extends the default pie chart renderer. I basically just copied the code from PieChartRenderer.drawValues method, converted it to Kotlin, and removed everything that wasn't needed. I only kept the logic needed to determine the position of the points at the end of lines.

I tried to reproduce the image you showed:


val chart: PieChart = view.findViewById(R.id.pie_chart)
chart.setExtraOffsets(40f, 0f, 40f, 0f)

// Custom renderer used to add dots at the end of value lines.
chart.renderer = CustomPieChartRenderer(chart, 10f)

val dataSet = PieDataSet(listOf(
PieEntry(40f),
PieEntry(10f),
PieEntry(10f),
PieEntry(15f),
PieEntry(10f),
PieEntry(5f),
PieEntry(5f),
PieEntry(5f)
), "Pie chart")

// Chart colors
val colors = listOf(
Color.parseColor("#4777c0"),
Color.parseColor("#a374c6"),
Color.parseColor("#4fb3e8"),
Color.parseColor("#99cf43"),
Color.parseColor("#fdc135"),
Color.parseColor("#fd9a47"),
Color.parseColor("#eb6e7a"),
Color.parseColor("#6785c2"))
dataSet.colors = colors
dataSet.setValueTextColors(colors)

// Value lines
dataSet.valueLinePart1Length = 0.6f
dataSet.valueLinePart2Length = 0.3f
dataSet.valueLineWidth = 2f
dataSet.valueLinePart1OffsetPercentage = 115f // Line starts outside of chart
dataSet.isUsingSliceColorAsValueLineColor = true

// Value text appearance
dataSet.yValuePosition = PieDataSet.ValuePosition.OUTSIDE_SLICE
dataSet.valueTextSize = 16f
dataSet.valueTypeface = Typeface.DEFAULT_BOLD

// Value formatting
dataSet.valueFormatter = object : ValueFormatter() {
private val formatter = NumberFormat.getPercentInstance()

override fun getFormattedValue(value: Float) =
formatter.format(value / 100f)
}
chart.setUsePercentValues(true)

dataSet.selectionShift = 3f

// Hole
chart.isDrawHoleEnabled = true
chart.holeRadius = 50f

// Center text
chart.setDrawCenterText(true)
chart.setCenterTextSize(20f)
chart.setCenterTextTypeface(Typeface.DEFAULT_BOLD)
chart.setCenterTextColor(Color.parseColor("#222222"))
chart.centerText = "Center\ntext"

// Disable legend & description
chart.legend.isEnabled = false
chart.description = null

chart.data = PieData(dataSet)

Again, not very straightforward. I hope you like Kotlin! You can move most of that configuration code to a subclass if you need it often. Here's the result:

Sample Image

I'm not a MPAndroidChart expert. In fact, I've used it only once, and that was 2 years ago. But if you do your research, you can find a solution most of the time. Luckily, MPAndroidChart is a very customizable.

change text of yAxis labels in MPAndroidChart

Yes, there is. Take a look at the AxisValueFormatter interface.

Basically that interface allows you to format the labels in any way you want, even with some kind of logic, like 50 - 100 = "good", ...



Related Topics



Leave a reply



Submit