Background
For some charts in my app, I'm using the MPAndroidChart library. All horizontal axis' of my graphs are time based, they can span a full year, a month, a week, a day or span one hour. It always shows a full period, so January-December, Monday-Sunday, 0:00 - 24:00 etc. The value of the axis is always the epoch-timestamp (in seconds).
Requirement
I want the x-axis labels to follow these rules:
Problem
I can set the granularity
of the x-axis, which makes sure there is no less space between two points then the granularity says, but that can mean that (in case of day span) the first label is at 1:00am, and the second at 2:01am and the third is at 3:16am, since that fits a granularity of (minimum) 60 minutes.
Current incorrect situation, which would ideally be something like [0:00, 3:00, 6:00, 9:00 ..]
Question
Is there a way to control the positioning of the x-axis labels to achieve the results above?
I have done same thing, Try this,
XAxis xAxis = mChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM_INSIDE);
xAxis.setDrawGridLines(false);
xAxis.setGranularity(1f); // only intervals of 1 day
xAxis.setTypeface(mTfLight);
xAxis.setTextSize(8);
xAxis.setTextColor(ContextCompat.getColor(this, R.color.colorYellow));
xAxis.setValueFormatter(new GraphXAxisValueFormatter(range, interval, slot));
in this range
in your case. If you want month then there is 12, in case of week 7 etc.
in interval
you pass 1.
in slot
you have to pass, identification of your data like month, year, day, i have use enum for this.
public class GraphXAxisValueFormatter implements IAxisValueFormatter {
private static int MINUTES_INTERVAL = 5;
private String[] mValues;
private int mInterval;
private SensorInterval.Interval mSlot;
public GraphXAxisValueFormatter(List<BinSensorData> range, int interval, SensorInterval.Interval slot) {
mValues = new String[range.size()];
mInterval = interval;
mSlot = slot;
Calendar calendar = Calendar.getInstance();
for (int i = 0; i < range.size(); i++) {
calendar.setTimeInMillis(range.get(i).getTime());
int unroundedMinutes = calendar.get(Calendar.MINUTE);
int mod = unroundedMinutes % MINUTES_INTERVAL;
calendar.add(Calendar.MINUTE, mod < 8 ? -mod : (MINUTES_INTERVAL - mod));
String s = "";
if (slot.equals(SensorInterval.Interval.HOUR) || slot.equals(SensorInterval.Interval.DAY))
s = Util.getTimeFromTimestamp(calendar.getTimeInMillis());
else if (slot.equals(SensorInterval.Interval.WEEK))
s = Util.getDayFromTimestamp(calendar.getTimeInMillis());
else if (slot.equals(SensorInterval.Interval.MONTH))
s = Util.getMonthFromTimestamp(calendar.getTimeInMillis());
else if (slot.equals(SensorInterval.Interval.YEAR))
s = Util.getYearFromTimestamp(calendar.getTimeInMillis());
Util.setLog("Time : "+s);
mValues[i] = s;
}
}
@Override
public String getFormattedValue(float value, AxisBase axis) {
Util.setLog("Value : "+ value);
if (value % mInterval == 0 && value >= 0) {
return mValues[(int) value % mValues.length];
} else
return "";
}
@Override
public int getDecimalDigits() {
return 0;
}