MPAndroidChart x 轴日期/时间标签格式

Posted

技术标签:

【中文标题】MPAndroidChart x 轴日期/时间标签格式【英文标题】:MPAndroidChart x-axis date/time label formatting 【发布时间】:2017-04-09 18:01:36 【问题描述】:

背景

对于我应用中的一些图表,我使用的是 MPandroidChart 库。我的图表的所有水平轴都是基于时间的,它们可以跨越一整年、一个月、一周、一天或一个小时。它总是显示一个完整的时间段,例如 1 月至 12 月、周一至周日、0:00 - 24:00 等。轴的值始终是纪元时间戳(以秒为单位)。

要求

我希望 x 轴标签遵循以下规则:

月 1 日,如果是 跨度; 一天的开始,如果是跨度; 在任何整小时 (##:00)(不是全部),如果是跨度; 在小时跨度的任何5分钟点上。

问题

我可以设置 x 轴的granularity,这样可以确保两点之间的空间不小于粒度所说的,但这可能意味着(在一天跨度的情况下)第一个标签位于 1 :00am,第二个是凌晨 2:01,第三个是凌晨 3:16,因为这符合(最小)60 分钟的粒度。

当前不正确的情况,最好是[0:00, 3:00, 6:00, 9:00 ..]

问题

有没有办法控制x轴标签的定位来达到上面的效果?

【问题讨论】:

你让它工作了吗? 【参考方案1】:

我也做过同样的事情,试试这个,

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

在这个range 你的情况下。如果你想要一个月,那么有 12 个,如果是第 7 周等等。

interval 你通过了 1。

slot 你必须通过,识别你的数据,如月、年、日,我为此使用了枚举。

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;

见:http://prntscr.com/dbn62x

【讨论】:

如果我错了请纠正我,但这不只是改变显示值,而不是标签的实际位置。它显示了正确的值,但在(稍微)不正确的位置。 @Marcel50506 你能告诉我这个回复是否对你有用吗? @MeknessiHamida:不,它没有解决我的问题。正如我之前的评论中所说,它没有设置标签的正确位置。 @Marcel50506 你找到工作区还是死胡同? @MeknessiHamida:我认为这确实是一条死胡同。目前没有代码,因此无法确定。【参考方案2】:

一周中的几天我也遇到了类似的问题...

我的时间戳与你的格式相同,但是当它们被转换为条目的浮点数时,它们会失去太多的精度并给我不规则的间隔。

我以毫秒为单位的时间戳转换为以分钟为单位的时间戳,现在它可以完美运行

检查浮点转换不会影响您的精度,然后您可以从那里设置其余参数,使您的间隔定期

【讨论】:

【参考方案3】:

在最新版本的图表库中(截至 2021 年 8 月 25 日),您可以创建自己的 ValueFormatter 类型的格式化程序并覆盖您需要的函数。这段代码(在 Kotlin 中)覆盖了 getAxisLabel() 函数并基于毫秒时间戳构建了一个 HH:MM 日期字符串:

class XAxisTimeFormatter: ValueFormatter() 
    override fun getAxisLabel(value: Float, axis: AxisBase?): String 
        return SimpleDateFormat("HH:MM", Locale.getDefault()).format(Date(value.toLong()))
    

然后您可以使用新创建的类并将其应用于 X 轴:

...
yourChart.xAxis.valueFormatter = XAxisTimeFormatter()
...

【讨论】:

你能提供更多细节吗?我试过但没有为我工作。我想绘制类似于this 的图。还在***上询问***.com/questions/70952437/…

以上是关于MPAndroidChart x 轴日期/时间标签格式的主要内容,如果未能解决你的问题,请参考以下文章

在 MPAndroidChart 库中,如何在长时将 X 轴标签包装成两行?

MPAndroidChart:如何以固定间隔设置 x 轴标签

在 MPAndroidChart 中,如何将 X 轴标签分成两条线?对使用任何修改后的库不感兴趣

如何使用 Matplotlib 调整图形的 x 轴“日期”标签?

如何在python中更改日期时间数据的x轴刻度标签的频率

在Matplotlib x轴标签格式的日期时间