Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add x axis as datetime label in MPAndroidChart?

I implemented line chart (MPAndroidChart library) for temperature report in my project.In X axis datetime should be plotted and Y axis temperature should be plotted.

I just added datetime as string in X axis label but it's collapsed. So please anyone guide me.

like image 525
Shanmugapriyan M Avatar asked Jan 02 '17 11:01

Shanmugapriyan M


3 Answers

Try the following.

To set the X Axis

 XAxis xAxis = mChart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setValueFormatter(new MyXAxisValueFormatter());
        xAxis.setLabelsToSkip(0);

Create a new class MyXAxisValueFormatter implement XAxisValueFormatter

public class MyXAxisValueFormatter implements XAxisValueFormatter {

@Override
public String getXValue(String dateInMillisecons, int index, ViewPortHandler viewPortHandler) {
    try {

        SimpleDateFormat sdf = new SimpleDateFormat("dd MMM");
        return sdf.format(new Date(Long.parseLong(dateInMillisecons)));

    } catch (Exception e) {

        return  dateInMillisecons;
    }
}

Hope this helps

like image 179
Sagar Patil Avatar answered Nov 18 '22 10:11

Sagar Patil


Using version 3.0+ of the MPAndroidChart:

Set formatter to the x axis (created below):

// Formatter to adjust epoch time to readable date
lineChart.xAxis.setValueFormatter(new LineChartXAxisValueFormatter());

Create a new class LineChartXAxisValueFormatter:

public class LineChartXAxisValueFormatter extends IndexAxisValueFormatter {

    @Override
    public String getFormattedValue(float value) {

        // Convert float value to date string
        // Convert from seconds back to milliseconds to format time  to show to the user
        long emissionsMilliSince1970Time = ((long) value) * 1000;

        // Show time in local version
        Date timeMilliseconds = new Date(emissionsMilliSince1970Time);
        DateFormat dateTimeFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault());

        return dateTimeFormat.format(timeMilliseconds);
    }
}

When the entries are added to the chartDataArray they are added in seconds, not milliseconds, to avoid potential precision issues with inputting as a float (i.e. milliseconds divided by 1000).

chartDataArray.add(new Entry(secondsSince1970Float, yValueFloat));

Happy coding!

like image 22
Ben Avatar answered Nov 18 '22 11:11

Ben


Further from @Ben's answer, if you are creating BarChart, and the time span of the bar is like an hour or a day, and you are supplying with millisecond or second data, you will end up getting the bars too thin to be visible. This is a bug posted in 2017 (https://github.com/PhilJay/MPAndroidChart/issues/2892) and remains unresolved to date unfortunately.

A workaround was proposed and it is to convert the millisecond values into your time span of the bar before setting then into BarEntry. My time span is a day, so I have the formatter as:

    static class BarChartXAxisValueFormatter extends IndexAxisValueFormatter {

    @Override
    public String getFormattedValue(float value) {

        // Convert float value to date string
        // Convert from days back to milliseconds to format time  to show to the user
        long emissionsMilliSince1970Time = TimeUnit.DAYS.toMillis((long)value);
        // Show time in local version
        Date timeMilliseconds = new Date(emissionsMilliSince1970Time);
        SimpleDateFormat dateTimeFormat = new SimpleDateFormat("MM-dd");

        return dateTimeFormat.format(timeMilliseconds);
    }
}

And I set the X axis with:

xAxis.setValueFormatter(new BarChartXAxisValueFormatter());

Then when setting the data to the bar, I have

new BarEntry(TimeUnit.MILLISECONDS.toDays((long)valX), valY).

like image 2
LeoXJ Avatar answered Nov 18 '22 10:11

LeoXJ