Formatting a date and time stamp using the MPAndroidChart axis

Background

For some graphs in my application, I use the MPAndroidChart library. All the horizontal axes of my graphs are time-based, they can cover a full year, month, week, day or one hour circle. It always shows the full period, so from January to December, from Monday to Sunday, from 0:00 to 24:00, etc. The axis value is always a time stamp (in seconds).

Demand

I want the x-axis labels to follow the following rules:

  • on the 1st of the month in the case of the year ;
  • at the beginning of the day in the case of a month or a week ;
  • at any full hour (##: 00) (do not strain everything) in case of a span day ;
  • at any 5 minute point in an hour .

Problem

I can set the granularity the x axis, which guarantees that there will be less space between the two points than the granularity says, but this may mean that (in the case of the daytime span) the first mark is 1:00 am and the second at 2:01 am and the third at 3:16 in the morning, as this corresponds to a granularity (minimum) of 60 minutes.

The current incorrect situation, which ideally would be something like [0:00, 3:00, 6:00, 9:00 ..]

An example of the current situation

Question

Is there a way to control the positioning of the X axis labels to achieve the results above?

+6
source share
2 answers

I did the same, try

  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 need a month, then 12, in the case of week 7, etc.

in interval you pass 1.

in slot you need to pass the identification of your data, such as month, year, day, I use the enumeration 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; } 

See: http://prntscr.com/dbn62x

+3
source

I had a similar problem with the days of the week ...

My timestamps were in the same format as yours, but when they were converted to record floats, they would lose too much accuracy and give me irregular intervals.

I converted my millisecond timestamps to timestamps in minutes, and now it works great

make sure the float conversion doesn't mess with your accuracy, and from there you can set other parameters that will make your intervals regular

0
source

Source: https://habr.com/ru/post/1012647/


All Articles