Megi Fernanda
Megi Fernanda

Reputation: 273

How to set String value of xAxis in MPAndroidChart?

I want to make Line Chart Graph, but i have problem to show value string in xAxis, im used Library Github from MPAndroidChart to LineChart. Please help me how to add String Value and actually to much question i want ask

private void drawLineChartLine(){

        private float[] yDataL = {40, 60, 70, 80};
        private String[] xDataL = {"Week 1", "Week 1" , "Week 3" , "Week 4"};


        ArrayList<Entry> yEntrys = new ArrayList<>();

        final ArrayList<String> xEntrys = new ArrayList<>();

        for(int i = 0; i < yDataL.length; i++){
            yEntrys.add(new Entry(yDataL[i] ,i));
        }

        for(int i = 1; i < xDataL.length; i++){
            xEntrys.add(xDataL[i]);
        }

        //create the data set
        LineDataSet lineDataset = new LineDataSet(yEntrys, "assa");

        XAxis xAxis = lineChart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setDrawGridLines(false);


        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                return xEntrys.get((int) value);
            }
        });

        LineData lineData = new LineData(lineDataset);
        lineChart.setData(lineData);
        lineChart.invalidate();
}

i got error

Invalid index 40, size is 6

in Code

xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                return xEntrys.get((int) value);
            }
        });

Upvotes: 17

Views: 35355

Answers (10)

Anshul1507
Anshul1507

Reputation: 549

According to the new update v3.1.0 IAxisValueFormatter method is deprecated.

So with the use of com.github.mikephil.charting.formatter.IndexAxisValueFormatter we can show month list in x-Axis

private List<Entry> getIncomeEntries() {
    ArrayList<Entry> incomeEntries = new ArrayList<>();

    incomeEntries.add(new Entry(1, 11300));
    incomeEntries.add(new Entry(2, 1390));
    incomeEntries.add(new Entry(3, 1190));
    incomeEntries.add(new Entry(4, 7200));
    incomeEntries.add(new Entry(5, 4790));
    incomeEntries.add(new Entry(6, 4500));
    incomeEntries.add(new Entry(7, 8000));
    incomeEntries.add(new Entry(8, 7034));
    incomeEntries.add(new Entry(9, 4307));
    incomeEntries.add(new Entry(10, 8762));
    incomeEntries.add(new Entry(11, 4355));
    incomeEntries.add(new Entry(12, 6000));

  return incomeEntries.subList(0, 12);
}

In Oncreate method

ArrayList<ILineDataSet> dataSets = new ArrayList<>();
List<String> xAxisValues = new ArrayList<>(Arrays.asList("Jan", "Feb", "March", "April", "May", "June","July", "August", "September", "October", "November", "Decemeber"));
List<Entry> incomeEntries = getIncomeEntries();
dataSets = new ArrayList<>();
LineDataSet set1;

set1 = new LineDataSet(incomeEntries, "Income");
set1.setColor(Color.rgb(65, 168, 121));
set1.setValueTextColor(Color.rgb(55, 70, 73));
set1.setValueTextSize(10f);
set1.setMode(LineDataSet.Mode.CUBIC_BEZIER);
dataSets.add(set1);

//customization
LineChart mLineGraph = findByViewId(R.id.line_chart);
mLineGraph.setTouchEnabled(true);
mLineGraph.setDragEnabled(true);
mLineGraph.setScaleEnabled(false);
mLineGraph.setPinchZoom(false);
mLineGraph.setDrawGridBackground(false);
mLineGraph.setExtraLeftOffset(15);
mLineGraph.setExtraRightOffset(15);
//to hide background lines
mLineGraph.getXAxis().setDrawGridLines(false);
mLineGraph.getAxisLeft().setDrawGridLines(false);
mLineGraph.getAxisRight().setDrawGridLines(false);

//to hide right Y and top X border
YAxis rightYAxis = mLineGraph.getAxisRight();
rightYAxis.setEnabled(false);
YAxis leftYAxis = mLineGraph.getAxisLeft();
leftYAxis.setEnabled(false);
XAxis topXAxis = mLineGraph.getXAxis();
topXAxis.setEnabled(false);


XAxis xAxis = mLineGraph.getXAxis();
xAxis.setGranularity(1f);
xAxis.setCenterAxisLabels(true);
xAxis.setEnabled(true);
xAxis.setDrawGridLines(false);
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);

set1.setLineWidth(4f);
set1.setCircleRadius(3f);
set1.setDrawValues(false);
set1.setCircleHoleColor(getResources().getColor(R.color.pie_color_4));
set1.setCircleColor(getResources().getColor(R.color.pie_color_4));

//String setter in x-Axis
mLineGraph.getXAxis().setValueFormatter(new com.github.mikephil.charting.formatter.IndexAxisValueFormatter(xAxisValues));

LineData data = new LineData(dataSets);
mLineGraph.setData(data);
mLineGraph.animateX(2000);
mLineGraph.invalidate();
mLineGraph.getLegend().setEnabled(false);
mLineGraph.getDescription().setEnabled(false);

Upvotes: 21

冷暖自知
冷暖自知

Reputation: 1

//修改X轴内容成字符日期 xAxis.setValueFormatter(new IndexAxisValueFormatter(date));

Upvotes: 0

Delark
Delark

Reputation: 1323

I had this exact problem and I will try to explain why this is not a "problem" to begin with.

My original answer is here: https://github.com/PhilJay/MPAndroidChart/issues/2693#issuecomment-991307401

The problem is a misunderstanding of what the (graph)Line Chart is doing in this particular scenario.

The issue is that with previous instances of the chart, especially types of charts in which NO X VALUES are inserted into the graph, the expected behavior of the x-axis format, is to place an X tooltip exactly below the place where the point/bar/segment is placed.

Because the formatted value is strictly defined by the point/bar/segment immediately above(or bellow depending on were you choose to), the method will give you a float that (can) should be used as index.

This behavior changes completely when you provide an x float value.

Now the Data (maybe a String you provided) CANNOT BE RETRIVED WITH ANY INDEX, and will only serve as a bubble for your point tooltip (if you choose to touch it). End of the story.

The X axis on the other hand, will show tooltips at random points (not really random, as they can be somewhat defined by some inputs) that WILL NOT MATCH the points delivered to the graph BUT will remain on its scale non the less. This means that the float values delivered by the method will NOT BE INDICES SINCE THEY ARE NOT SUPPOSED TO MATCH those of the collection of entries provided, and if they somehow do, it would be a complete coincidence.

This means that you must know BEFOREHAND:

  1. What your X axis margins will be MAX(where it ends) and MIN(where it starts)
  2. How exactly ANY of the points within those margins you set, will get parsed on to a String.

After a proper function has been fore-(seen/saw), it is up to the getFormattedValue() function to deliver any formatted float it may deem proper that is within the range you first defined, (this decision will depend of course on some other values set by the user).

Upvotes: 0

marko
marko

Reputation: 457

In version 3.1.0 you have to override getAxisLabel(), the deprecated method getFormattedValue(float, AxisBase) is never called. Kotlin example:

class MyFormatter : ValueFormatter() {

    override fun getAxisLabel(value: Float, axis: AxisBase): String {
        return "ABC"
    }
}

Upvotes: 4

chart.xAxis.valueFormatter = IndexAxisValueFormatter(list_of_labels)

Upvotes: 0

Sans Cloud
Sans Cloud

Reputation: 1

The methods mentioned aboves seems to be deprecated.

 xAxis.setValueFormatter(new ValueFormatter() {
            @Override
            public String getFormattedValue(float value) {
               // return the string va
                return  your_string_basedon_value_as_index;
            }
        });

Upvotes: 0

Gayathri
Gayathri

Reputation: 249

Here the easy method to dynamic string label (XAxis),

XAxis xAxis = lineChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setValueFormatter(new IndexAxisValueFormatter(getAreaCount));

public ArrayList<String> getAreaCount() {

            ArrayList<String> label = new ArrayList<>();
            for (int i = 0; i < areaList.size(); i++)
                label.add(areaList.get(i).getTopicName());
            return label;
        }

Upvotes: 6

Arjun G
Arjun G

Reputation: 646

public class IndexAxisValueFormatter extends ValueFormatter
{
    private String[] mValues = new String[] {};
private int mValueCount = 0;

/**
 * An empty constructor.
 * Use `setValues` to set the axis labels.
 */
public IndexAxisValueFormatter() {
}

/**
 * Constructor that specifies axis labels.
 *
 * @param values The values string array
 */
public IndexAxisValueFormatter(String[] values) {
    if (values != null)
        setValues(values);
}

/**
 * Constructor that specifies axis labels.
 *
 * @param values The values string array
 */
public IndexAxisValueFormatter(Collection<String> values) {
    if (values != null)
        setValues(values.toArray(new String[values.size()]));
}

@Override
public String getFormattedValue(float value, AxisBase axisBase) {
    int index = Math.round(value);

    if (index < 0 || index >= mValueCount || index != (int)value)
        return "";

    return mValues[index];
}

public String[] getValues()
{
    return mValues;
}

public void setValues(String[] values)
{
    if (values == null)
        values = new String[] {};

    this.mValues = values;
    this.mValueCount = values.length;
}
}

Add the below code in the method where you are trying to display Bar Chart.

final String[] weekdays = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; // Your List / array with String Values For X-axis Labels

// Set the value formatter 
XAxis xAxis = chart.getXAxis();
xAxis.setValueFormatter(new IndexAxisValueFormatter(weekdays));

It Solved! Happy Coding.

Upvotes: 11

Ness Tyagi
Ness Tyagi

Reputation: 2028

Simple implentation

            XAxis xAxis = mChart.getXAxis();
            xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
            xAxis.setDrawGridLines(true);
            xAxis.setGranularity(1f);
            xAxis.setGranularityEnabled(true);
            final String xVal[]={"Val1","Val2","Val3"};
            xAxis.setValueFormatter(new IAxisValueFormatter() {
                @Override
                public String getFormattedValue(float value, AxisBase axis) {
                    return xVal[(int) value-1]; // xVal is a string array
                }

            });

Upvotes: 3

R. Zag&#243;rski
R. Zag&#243;rski

Reputation: 20258

You're accessing ArrayList index that is way out of bounds, because you are trying to use value as an index. You need to find index of value to return it.

xAxis.setValueFormatter(new IAxisValueFormatter() {
    @Override
    public String getFormattedValue(float value, AxisBase axis) {
       for (int i = 0 ; i < yEntrys.size(); ++i) {
           if (yEntrys.get(i).equals(value)) {
               return xEntrys.get(i);
           }
       }
       return null;
    }
});

Upvotes: 2

Related Questions