当前位置: 首页 > 知识库问答 >
问题:

MPAndreidChart:在日期格式化上为午夜(00:00)提供合理的网格和标签

楚昊明
2023-03-14

问题:

MPAndroidChart可以很好地计算十进制值的网格和标签位置,但对于日期/时间轴则不然。

我想有标签的位置,以正确的午夜例如与x轴范围4天:

[26.1-00h, 27.1-00h, 28.1-00h,29.1-00h, 30.1-00h]

或者如果范围仅为2天:

[26.1-00h, 26.1-12h, 27.1-00h, 27.1-12h,28.1-00h]

等。

我所尝试的:

>

使用setAxis最小值()和setAxisMaximum()将Chart min和max更正为午夜时间戳。

玩不同的值缩放。

将粒度设置为一整天,但随后数据点会从其原始位置捕捉到顶点位置。

网格原点和行间距的计算似乎是在类Axis渲染器的computeAxisValue()中完成的,但是这个类不能重载(?)

有没有办法在不更改库的情况下控制x轴标签的位置?

共有1个答案

晏和风
2023-03-14

回答我自己的问题:

  1. 添加Date格式以及缩放常量:
    private static final long MS_PER_XSCALE = 1000 * 60; // scale to minute resolution
    private static final long XSCALE_ONE_DAY = 60 * 24; // one day

    private final SimpleDateFormat xAxisDataFormat_DD_MMM_H = new SimpleDateFormat("dd.MMM'_'H'h'", Locale.ENGLISH);
    private final SimpleDateFormat xAxisDataFormat_DD_MMM = new SimpleDateFormat("dd.MMM", Locale.ENGLISH);
    private static final long TIMEOFFSET = TimeZone.getDefault().getRawOffset();
        chart.setXAxisRenderer(new DateXAxisRenderer(chart.getViewPortHandler(), chart.getXAxis(), chart.getTransformer(null)));
        chart.getXAxis().setValueFormatter(new ValueFormatter() {
            @Override
            public String getFormattedValue(float value) {
                if ((int) value / XSCALE_ONE_DAY * XSCALE_ONE_DAY == value)
                    return xAxisDataFormat_DD_MMM.format(new Date((long) value * MS_PER_XSCALE - TIMEOFFSET));
                else
                    return xAxisDataFormat_DD_MMM_H.format(new Date((long) value  * MS_PER_XSCALE - TIMEOFFSET));
            }
        });
 class DateXAxisRenderer extends XAxisRenderer {
        public DateXAxisRenderer(ViewPortHandler viewPortHandler, XAxis xAxis, Transformer trans) {
            super(viewPortHandler, xAxis, trans);
        }

        @Override
        protected void computeAxisValues(float min, float max) {
            int day_fraction[] = {1,2,3,4,6,8,12,24};
            float interval=0;
            int labelCount=0;
            float xMin = min;
            float xMax = max;

            xMax -= xMax % XSCALE_ONE_DAY;
            xMin += XSCALE_ONE_DAY - (xMin % XSCALE_ONE_DAY);
            int days = (int) ((xMax - xMin) / XSCALE_ONE_DAY);
            float days_interval = days / 3;
            if (days_interval > 0) {
                interval = days_interval * XSCALE_ONE_DAY;
                labelCount = (int) ((xMax - xMin) / interval);
            }

            if (days_interval == 0 || labelCount<3) {
                int i = day_fraction.length-1;
                do {
                    xMax = max - max % (XSCALE_ONE_DAY / day_fraction[i]);
                    xMin = min + (XSCALE_ONE_DAY / day_fraction[i] - (min % (XSCALE_ONE_DAY / day_fraction[i])));
                    labelCount = (int) ((xMax - xMin) / (XSCALE_ONE_DAY / day_fraction[i]));
                } while (labelCount > 4 && i-- > 0);
                interval = (xMax - xMin) / labelCount;
            }

            if (labelCount == 0 /*|| range <= 0 || Double.isInfinite(range)*/) {
                mAxis.mEntries = new float[]{};
                mAxis.mCenteredEntries = new float[]{};
                mAxis.mEntryCount = 0;
                return;
            }

            labelCount++;   // add last label
            //Timber.i("corrected min:" + xMin + ", max:" + xMax + ", interval:" + interval + ", labelcount:" + labelCount);

            mAxis.mEntries = new float[labelCount];
            float v = xMin;
            for (int i = 0; i < labelCount; i++) {
                mAxis.mEntries[i] = v;
                Timber.i("Label " + i + " at:" + mAxis.mEntries[i] + " day:" + mAxis.mEntries[i] / XSCALE_ONE_DAY);
                v += interval;
            }

            //mAxis.setLabelCount(labelCount);
            //mAxis.setGranularityEnabled(false);
            mAxis.mEntryCount = labelCount;
        }
    }

就这样!

备注:这是很好的范围,这是天到分钟,但如果你需要几年,几个月或几秒钟,你必须适应格式化程序以及实现的computeAxisValues()它相应。

 类似资料:
  • 我试图用Java Apache POI库从Excel单元格中获取日期。 该字段包含日期30.1.2019年12:00:00,我选择作为该单元格的格式字符串。当我使用apache POI在Excel工作表上循环时,它报告调用类型为并返回值43495.5。

  • 问题内容: 我尝试通过以下方式转换此日期: 但是我得到了: 问题答案: “ -0500”是UTC的偏移量,采用RFC822格式。您只想要,没有。 下表列出了Android 文档 : 符号:Z 含义:时区(RFC 822) 种类:(时区) 范例::-0800 :GMT-08:00 :-08:00 当然,我也将亲自指定语言环境:这是一种机器可读格式,而不是面向人类的格式,因此我通常会指定:

  • 我想在MySQL中允许零日期。我已将更改为。 我已经在中更改了它。 然而,当我尝试插入数据时,我得到了错误, 数据截断:不正确的datetime值:“0000-00-00 00:00:00” MySQL版本为5.7.18。 这方面的任何想法都将大有帮助。

  • 问题内容: 我最近接手了一个十年前创建的旧项目。它使用MySQL 5.1。 除其他外,我需要将默认字符集从latin1更改为utf8。 例如,我有这样的表: 我设置了自己的Mac来进行此工作。不用考虑太多,我运行了“ brew install mysql”,它安装了MySQL 5.7。所以我有一些版本冲突。 我下载了此数据库的副本并将其导入。 如果我尝试运行这样的查询: 我收到此错误: 我以为可以

  • 问题内容: 我需要在数据库上更改一些值。 我忘记为表格设置可空值,并且默认情况下将其设置为0000-00-00 00:00:00。 现在,我需要将该值转换为。 字段类型为“日期时间”。 我该怎么做? 我尝试使用典型的方法,但是它不起作用。 问题答案: 您首先需要将该列设置为可空: 然后更新值:

  • 本文向大家介绍MySQL 8.0.13设置日期为0000-00-00 00:00:00时出现的问题解决,包括了MySQL 8.0.13设置日期为0000-00-00 00:00:00时出现的问题解决的使用技巧和注意事项,需要的朋友参考一下 刚开始学习数据库操作,今天存数据时发现,保存的时候报错(Error 1292: Incorrect datetime value: '0000-00-00' f