web-dev-qa-db-fra.com

MPAndroidChart Formatage d'étiquette de date/heure sur l'axe x

Contexte

Pour certaines cartes de mon application, j'utilise la bibliothèque MPAndroidChart. Tous les axes horizontaux de mes graphiques sont basés sur le temps, ils peuvent couvrir une année complète, un mois, une semaine, une journée ou une heure. Il affiche toujours une période complète, c'est-à-dire janvier-décembre, lundi-dimanche, 0h00 - 24h00, etc. La valeur de l'axe est toujours le timbre de l'époque (en secondes).

Exigence

Je veux que les étiquettes de l'axe des x suivent ces règles:

  • at 1er du mois en cas de année span;
  • à début de journée en cas de mois ou semaine span;
  • sur tout heure complète (##: 00) (pas tous) en cas de jour span;
  • sur n'importe quel 5 minute point sur un heure span.

Problème

Je peux définir la variable granularity de l'axe des x, ce qui garantit qu'il n'y a pas moins d'espace entre deux points que la granularité, mais cela peut signifier que (dans le cas de la durée du jour), la première deuxième à 2h01 et le troisième à 3h16, car cela correspond à une granularité de (minimum) 60 minutes.

Situation incorrecte actuelle, qui serait idéalement quelque chose comme [0:00, 3:00, 6:00, 9:00 ..]

 Example of current situation

Question

Existe-t-il un moyen de contrôler le positionnement des étiquettes de l'axe des x pour obtenir les résultats ci-dessus?

8
Marcel50506

J'ai fait la même chose, essayez ceci,

 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));

dans cette range dans votre cas. Si vous voulez mois alors il y a 12, en cas de semaine 7 etc.

dans interval vous passez 1.

dans slot vous devez passer, l'identification de vos données comme le mois, l'année, le jour, j'ai utiliser enum pour cela.

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;
}

Voir: http://prntscr.com/dbn62x

4
Mehul Kabaria

J'ai eu un problème similaire avec les jours de la semaine ...

Mes horodatages étaient au même format que le vôtre, mais lorsqu'ils étaient convertis en flottants pour les entrées, ils perdaient trop de précision et me donnaient des intervalles irréguliers.

J'ai converti mes horodatages en millis à des horodatages en quelques minutes, et maintenant cela fonctionne parfaitement

vérifiez que la conversion de float ne gêne pas votre précision, et à partir de là, vous pourrez définir le reste des paramètres qui rendront vos intervalles réguliers

1
JCLaHoot