使用 MPAndroidChart 在条形图中的时间轴轴上绘制数据值

Plot data value on Timeline axis in Bar chart using MPAndroidChart

我想在类似于 iOS 的“健康”应用的 Android 应用中绘制条形图。

这是屏幕截图。

我尝试使用 MPAndroidChart 绘图。 我看过该库中给出的示例,但无法按照我的要求绘制。

我能够显示 1 年图表的条形图(第 2 个屏幕截图),因为它有 12 个数据点和 12 个 x 轴标签。 但是对于一日图,需要在x轴的2个标签之间显示条形。

也不明白我是如何在 x 轴上绘制 24 小时或任何其他时间长度及其值的。

有什么方法可以根据选定的选项卡将 X 轴设为时间轴或日期轴? X 轴标签将根据当前日期和时间动态变化。所以我不能设置固定的字符串数组,还需要映射值和 x 轴时序。 谁能帮忙画一下数据和时间轴?

您可以用与绘制月份相同的方式绘制日期时间,但您将拥有 24 个值而不是 12 个值(每次一个值)。唯一的区别是时间图只有 4 X-labels 而不是几个月的 12 个,并且它呈现时间:仅上午 12 点、上午 6 点、中午 12 点、下午 6 点,所有其他时间标签均为空值。 下面我将通过代码示例描述如何绘制和映射每个 Y-Value 及其对应的 X-Label:

1.Add BarChart 变成 Activity xml 布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.github.mikephil.charting.charts.BarChart
        android:id="@+id/barChart"
        android:layout_width="match_parent"
        android:layout_height="300dp" />

</RelativeLayout>

2.Get 对条形图的引用

mBarChart = findViewById(R.id.barChart);

3.Plot 使用以下函数的月份图表:

private void showMonthsBars(){

    //input Y data (Months Data - 12 Values)
    ArrayList<Double> valuesList = new ArrayList<Double>();
    valuesList.add((double)1800);
    valuesList.add((double)1600);
    valuesList.add((double)500);
    valuesList.add((double)1500);
    valuesList.add((double)900);
    valuesList.add((double)1700);
    valuesList.add((double)400);
    valuesList.add((double)2000);
    valuesList.add((double)2500);
    valuesList.add((double)3500);
    valuesList.add((double)3000);
    valuesList.add((double)1800);

    //prepare Bar Entries
    ArrayList<BarEntry> entries = new ArrayList<>();
    for (int i = 0; i < valuesList.size(); i++) {
        BarEntry barEntry = new BarEntry(i+1, valuesList.get(i).floatValue()); //start always from x=1 for the first bar
        entries.add(barEntry);
    }

    //initialize x Axis Labels (labels for 13 vertical grid lines)
    final ArrayList<String> xAxisLabel = new ArrayList<>();
    xAxisLabel.add("J"); //this label will be mapped to the 1st index of the valuesList
    xAxisLabel.add("F");
    xAxisLabel.add("M");
    xAxisLabel.add("A");
    xAxisLabel.add("M");
    xAxisLabel.add("J");
    xAxisLabel.add("J");
    xAxisLabel.add("A");
    xAxisLabel.add("S");
    xAxisLabel.add("O");
    xAxisLabel.add("N");
    xAxisLabel.add("D");
    xAxisLabel.add(""); //empty label for the last vertical grid line on Y-Right Axis

    //initialize xAxis
    XAxis xAxis = mBarChart.getXAxis();
    xAxis.enableGridDashedLine(10f, 10f, 0f);
    xAxis.setTextColor(Color.BLACK);
    xAxis.setTextSize(14);
    xAxis.setDrawAxisLine(true);
    xAxis.setAxisLineColor(Color.BLACK);
    xAxis.setDrawGridLines(true);
    xAxis.setGranularity(1f);
    xAxis.setGranularityEnabled(true);
    xAxis.setAxisMinimum(0 + 0.5f); //to center the bars inside the vertical grid lines we need + 0.5 step
    xAxis.setAxisMaximum(entries.size() + 0.5f); //to center the bars inside the vertical grid lines we need + 0.5 step
    xAxis.setLabelCount(xAxisLabel.size(), true); //draw x labels for 13 vertical grid lines
    xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    xAxis.setXOffset(0f); //labels x offset in dps
    xAxis.setYOffset(0f); //labels y offset in dps
    xAxis.setCenterAxisLabels(true);
    xAxis.setValueFormatter(new ValueFormatter() {
        @Override
        public String getFormattedValue(float value) {
            return xAxisLabel.get((int) value);
        }
    });

    //initialize Y-Right-Axis
    YAxis rightAxis = mBarChart.getAxisRight();
    rightAxis.setTextColor(Color.BLACK);
    rightAxis.setTextSize(14);
    rightAxis.setDrawAxisLine(true);
    rightAxis.setAxisLineColor(Color.BLACK);
    rightAxis.setDrawGridLines(true);
    rightAxis.setGranularity(1f);
    rightAxis.setGranularityEnabled(true);
    rightAxis.setAxisMinimum(0);
    rightAxis.setAxisMaximum(6000f);
    rightAxis.setLabelCount(4, true); //draw y labels (Y-Values) for 4 horizontal grid lines starting from 0 to 6000f (step=2000)
    rightAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);

    //initialize Y-Left-Axis
    YAxis leftAxis = mBarChart.getAxisLeft();
    leftAxis.setAxisMinimum(0);
    leftAxis.setDrawAxisLine(true);
    leftAxis.setLabelCount(0, true);
    leftAxis.setValueFormatter(new ValueFormatter() {
        @Override
        public String getFormattedValue(float value) {
            return "";
        }
    });

    //set the BarDataSet
    BarDataSet barDataSet = new BarDataSet(entries, "Months");
    barDataSet.setColor(Color.RED);
    barDataSet.setFormSize(15f);
    barDataSet.setDrawValues(false);
    barDataSet.setValueTextSize(12f);

    //set the BarData to chart
    BarData data = new BarData(barDataSet);
    mBarChart.setData(data);
    mBarChart.setScaleEnabled(false);
    mBarChart.getLegend().setEnabled(false);
    mBarChart.setDrawBarShadow(false);
    mBarChart.getDescription().setEnabled(false);
    mBarChart.setPinchZoom(false);
    mBarChart.setDrawGridBackground(true);
    mBarChart.invalidate();
}

或像下面这样绘制一天的 24 小时:

private void showDayHoursBars(){

    //input Y data (Day Hours - 24 Values)
    ArrayList<Double> valuesList = new ArrayList<Double>();
    valuesList.add((double)0);
    valuesList.add((double)0);
    valuesList.add((double)0);
    valuesList.add((double)0);
    valuesList.add((double)0);
    valuesList.add((double)0);
    valuesList.add((double)0);
    valuesList.add((double)100);
    valuesList.add((double)270);
    valuesList.add((double)430);
    valuesList.add((double)110);
    valuesList.add((double)30);
    valuesList.add((double)200);
    valuesList.add((double)180);
    valuesList.add((double)0);
    valuesList.add((double)140);
    valuesList.add((double)160);
    valuesList.add((double)0);
    valuesList.add((double)100);
    valuesList.add((double)0);
    valuesList.add((double)750);
    valuesList.add((double)1200);
    valuesList.add((double)10);
    valuesList.add((double)0);

    //initialize x Axis Labels (labels for 25 vertical grid lines)
    final ArrayList<String> xAxisLabel = new ArrayList<>();
    for(int i = 0; i < 24; i++){
        switch (i){
            case 0:
                xAxisLabel.add("12 AM"); //12AM - 5AM
                break;
            case 6:
                xAxisLabel.add("6"); //6AM - 11AM
                break;
            case 12:
                xAxisLabel.add("12 PM"); //12PM - 5PM
                break;
            case 18:
                xAxisLabel.add("6"); //6PM - 11PM
                break;
            default:
                xAxisLabel.add(String.format(Locale.US, "%02d", i)+":00");
                break;
        }
    }
    xAxisLabel.add(""); //empty label for the last vertical grid line on Y-Right Axis

    //prepare Bar Entries
    ArrayList<BarEntry> entries = new ArrayList<>();
    for (int i = 0; i < valuesList.size(); i++) {
        BarEntry barEntry = new BarEntry(i+1, valuesList.get(i).floatValue()); //start always from x=1 for the first bar
        entries.add(barEntry);
    }

    //initialize xAxis
    XAxis xAxis = mBarChart.getXAxis();
    xAxis.enableGridDashedLine(10f, 10f, 0f);
    xAxis.setTextColor(Color.BLACK);
    xAxis.setTextSize(14);
    xAxis.setDrawAxisLine(true);
    xAxis.setAxisLineColor(Color.BLACK);
    xAxis.setDrawGridLines(true);
    xAxis.setGranularity(1f);
    xAxis.setGranularityEnabled(true);
    xAxis.setAxisMinimum(0 + 0.5f); //to center the bars inside the vertical grid lines we need + 0.5 step
    xAxis.setAxisMaximum(entries.size() + 0.5f); //to center the bars inside the vertical grid lines we need + 0.5 step
    xAxis.setLabelCount(5, true); //show only 5 labels (5 vertical grid lines)
    xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    xAxis.setXOffset(0f); //labels x offset in dps
    xAxis.setYOffset(0f); //labels y offset in dps
    //xAxis.setCenterAxisLabels(true); //don't center the x labels as we are using a custom XAxisRenderer to set the label x, y position
    xAxis.setValueFormatter(new ValueFormatter() {
        @Override
        public String getFormattedValue(float value) {
            return xAxisLabel.get((int) value);
        }
    });

    //initialize Y-Right-Axis
    YAxis rightAxis = mBarChart.getAxisRight();
    rightAxis.setTextColor(Color.BLACK);
    rightAxis.setTextSize(14);
    rightAxis.setDrawAxisLine(true);
    rightAxis.setAxisLineColor(Color.BLACK);
    rightAxis.setDrawGridLines(true);
    rightAxis.setGranularity(1f);
    rightAxis.setGranularityEnabled(true);
    rightAxis.setAxisMinimum(0);
    rightAxis.setAxisMaximum(1500f);
    rightAxis.setLabelCount(4, true); //labels (Y-Values) for 4 horizontal grid lines
    rightAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);

    //initialize Y-Left-Axis
    YAxis leftAxis = mBarChart.getAxisLeft();
    leftAxis.setAxisMinimum(0);
    leftAxis.setDrawAxisLine(true);
    leftAxis.setLabelCount(0, true);
    leftAxis.setValueFormatter(new ValueFormatter() {
        @Override
        public String getFormattedValue(float value) {
            return "";
        }
    });

    //set the BarDataSet
    BarDataSet barDataSet = new BarDataSet(entries, "Hours");
    barDataSet.setColor(Color.RED);
    barDataSet.setFormSize(15f);
    barDataSet.setDrawValues(false);
    barDataSet.setValueTextSize(12f);

    //set the BarData to chart
    BarData data = new BarData(barDataSet);
    mBarChart.setData(data);
    mBarChart.setScaleEnabled(false);
    mBarChart.getLegend().setEnabled(false);
    mBarChart.setDrawBarShadow(false);
    mBarChart.getDescription().setEnabled(false);
    mBarChart.setPinchZoom(false);
    mBarChart.setDrawGridBackground(true);
    mBarChart.setXAxisRenderer(new XAxisRenderer(mBarChart.getViewPortHandler(), mBarChart.getXAxis(), mBarChart.getTransformer(YAxis.AxisDependency.LEFT)){
        @Override
        protected void drawLabel(Canvas c, String formattedLabel, float x, float y, MPPointF anchor, float angleDegrees) {
            //for 6AM and 6PM set the correct label x position based on your needs
            if(!TextUtils.isEmpty(formattedLabel) && formattedLabel.equals("6"))
                Utils.drawXAxisValue(c, formattedLabel, x+Utils.convertDpToPixel(5f), y+Utils.convertDpToPixel(1f), mAxisLabelPaint, anchor, angleDegrees);
            //for 12AM and 12PM set the correct label x position based on your needs
            else
                Utils.drawXAxisValue(c, formattedLabel, x+Utils.convertDpToPixel(20f), y+Utils.convertDpToPixel(1f), mAxisLabelPaint, anchor, angleDegrees);
        }
    });
    mBarChart.invalidate();
}

从上面的示例中,我使用了一些虚拟数据来显示 Y-Values 和 X-Values 之间的映射。 Month-Chart 和 Day-Chart 之间的一个主要区别是,在 Month-Chart 中,我使用 xAxis.setCenterAxisLabels(true); 将 x-labels 在每个 Bar 中居中,而在 Day-Chart 中,我已根据您的屏幕截图使用自定义 XAxisRenderer 将每个标签对齐到正确的 x,y 位置。

以下是上述代码的结果:

Months-BarChart:

DayHours-BarChart:

注意:这是用 com.github.PhilJay:MPAndroidChart:v3.1.0 测试的。

映射 X-Axis 时间戳与 Y-Value 的示例:

如果您已经有了 X-Axis 的时间戳,您可以将它们转换为适当的字符串标签值,该值将映射到 Y-Data 值的相应索引。

下面是一个示例,说明如何从时间戳开始绘制 Times-Graph,例如:27-02-2022 16:00。在这里,我使用 cal.setTimeInMillis() 将时间戳转换为日历对象,然后我使用此日历使用 cal.add(Calendar.HOUR_OF_DAY, 1); 获取循环中的新小时,该 cal.add(Calendar.HOUR_OF_DAY, 1); 用作 [=111 中的时间标签=] 以您希望在 X-Axis 中显示的格式喜欢 String dayHour = DateFormat.format("hh a", cal).toString().toUpperCase();。每个 Y-Data 值对应于 X-Axis 的适当索引。下面的例子从下午 4 点开始到下午 3 点来处理一天的 24 小时:

//input Y data (Day Hours - 24 Values)
ArrayList<Double> valuesList = new ArrayList<Double>();
valuesList.add((double)0);
valuesList.add((double)0);
valuesList.add((double)0);
valuesList.add((double)0);
valuesList.add((double)0);
valuesList.add((double)0);
valuesList.add((double)0);
valuesList.add((double)100);
valuesList.add((double)270);
valuesList.add((double)430);
valuesList.add((double)110);
valuesList.add((double)30);
valuesList.add((double)200);
valuesList.add((double)180);
valuesList.add((double)0);
valuesList.add((double)140);
valuesList.add((double)160);
valuesList.add((double)0);
valuesList.add((double)100);
valuesList.add((double)0);
valuesList.add((double)750);
valuesList.add((double)1200);
valuesList.add((double)10);
valuesList.add((double)0);

//in case you already have the timestamp for a day then do the following:
//convert the timestamp to calendar by using the cal.setTimeInMillis() and then use the Calendar to iterate the 24H using the cal.add(Calendar.HOUR_OF_DAY, 1);
//like the below example:

//get a dummy TimeStamp for 27-02-2022 16:00
Date date = new Date();
long dateTimeStamp = 0;
try {
    String strDate = "27-02-2022 16:00";
    date = new SimpleDateFormat("dd-MM-yyyy HH:mm", Locale.US).parse(strDate);
    if(date!=null) {
        dateTimeStamp = date.getTime();
    }
}catch (Exception e){}

//convert the above timestamp to Calendar using the cal.setTimeInMillis()
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(dateTimeStamp);
//this is the day from the above Calendar
String day = DateFormat.format("dd-MM-yyyy HH:mm", cal).toString(); //this is: 27-02-2022 16:00

//initialize x Axis Labels (labels for 25 vertical grid lines)
final ArrayList<String> xAxisLabel = new ArrayList<>();
//iterate all 24 hours to add the label for each time
for(int i = 0; i < 24; i++){
    //get current hour in format "hh a" which is eg: 12 AM, 01 AM, etc..
    String dayHour = DateFormat.format("hh a", cal).toString().toUpperCase();
    //get the hour 0-11 AM or 0-11 PM
    int hour = cal.get(Calendar.HOUR);
    //check if the above hour is AM or PM (0=AM, 1=PM)
    int amPm = cal.get(Calendar.AM_PM);
    //this is the current TimeStamp for the current working hour in the loop:
    long timeStamp = cal.getTimeInMillis();
    //add the dayHour String as the label you want to display in xAxis
    xAxisLabel.add(dayHour); //this will be mapped to the corresponding index of the valuesList (Y-Data List)
    //increment the Calendar.HOUR_OF_DAY plus +1 to go to the next hour in 24H format
    cal.add(Calendar.HOUR_OF_DAY, 1);
}
xAxisLabel.add(""); //empty label for the last vertical grid line on Y-Right Axis

完整代码如下:

private void showDayHoursBars() {

    //input Y data (Day Hours - 24 Values)
    ArrayList<Double> valuesList = new ArrayList<Double>();
    valuesList.add((double)0);
    valuesList.add((double)0);
    valuesList.add((double)0);
    valuesList.add((double)0);
    valuesList.add((double)0);
    valuesList.add((double)0);
    valuesList.add((double)0);
    valuesList.add((double)100);
    valuesList.add((double)270);
    valuesList.add((double)430);
    valuesList.add((double)110);
    valuesList.add((double)30);
    valuesList.add((double)200);
    valuesList.add((double)180);
    valuesList.add((double)0);
    valuesList.add((double)140);
    valuesList.add((double)160);
    valuesList.add((double)0);
    valuesList.add((double)100);
    valuesList.add((double)0);
    valuesList.add((double)750);
    valuesList.add((double)1200);
    valuesList.add((double)10);
    valuesList.add((double)0);

    //in case you already have the timestamp for a day then do the following:
    //convert the timestamp to calendar by using the cal.setTimeInMillis() and then use the Calendar to iterate the 24H using the cal.add(Calendar.HOUR_OF_DAY, 1);
    //like the below example:

    //get a dummy TimeStamp for 27-02-2022 16:00
    Date date = new Date();
    long dateTimeStamp = 0;
    try {
        String strDate = "27-02-2022 16:00";
        date = new SimpleDateFormat("dd-MM-yyyy HH:mm", Locale.US).parse(strDate);
        if(date!=null) {
            dateTimeStamp = date.getTime();
        }
    }catch (Exception e){}

    //convert the above timestamp to Calendar using the cal.setTimeInMillis()
    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(dateTimeStamp);
    //this is the day from the above Calendar
    String day = DateFormat.format("dd-MM-yyyy HH:mm", cal).toString(); //this is: 27-02-2022 16:00

    //initialize x Axis Labels (labels for 25 vertical grid lines)
    final ArrayList<String> xAxisLabel = new ArrayList<>();
    //iterate all 24 hours to add the label for each time
    for(int i = 0; i < 24; i++){
        //get current hour in format "hh a" which is eg: 12 AM, 01 AM, etc..
        String dayHour = DateFormat.format("hh a", cal).toString().toUpperCase();
        //get the hour 0-11 AM or 0-11 PM
        int hour = cal.get(Calendar.HOUR);
        //check if the above hour is AM or PM (0=AM, 1=PM)
        int amPm = cal.get(Calendar.AM_PM);
        //this is the current TimeStamp for the current working hour in the loop:
        long timeStamp = cal.getTimeInMillis();
        //add the dayHour String as the label you want to display in xAxis
        xAxisLabel.add(dayHour); //this will be mapped to the corresponding index of the valuesList (Y-Data List)
        //increment the Calendar.HOUR_OF_DAY plus +1 to go to the next hour in 24H format
        cal.add(Calendar.HOUR_OF_DAY, 1);
    }
    xAxisLabel.add(""); //empty label for the last vertical grid line on Y-Right Axis

    //prepare Bar Entries
    ArrayList<BarEntry> entries = new ArrayList<>();
    for (int i = 0; i < valuesList.size(); i++) {
        BarEntry barEntry = new BarEntry(i+1, valuesList.get(i).floatValue()); //start always from x=1 for the first bar
        entries.add(barEntry);
    }

    //initialize xAxis
    XAxis xAxis = mBarChart.getXAxis();
    xAxis.enableGridDashedLine(10f, 10f, 0f);
    xAxis.setTextColor(Color.BLACK);
    xAxis.setTextSize(14);
    xAxis.setDrawAxisLine(true);
    xAxis.setAxisLineColor(Color.BLACK);
    xAxis.setDrawGridLines(true);
    xAxis.setGranularity(1f);
    xAxis.setGranularityEnabled(true);
    xAxis.setAxisMinimum(0 + 0.5f); //to center the bars inside the vertical grid lines we need + 0.5 step
    xAxis.setAxisMaximum(entries.size() + 0.5f); //to center the bars inside the vertical grid lines we need + 0.5 step
    xAxis.setLabelCount(5, true); //show only 5 labels (5 vertical grid lines)
    xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    xAxis.setXOffset(0f); //labels x offset in dps
    xAxis.setYOffset(0f); //labels y offset in dps
    //xAxis.setCenterAxisLabels(true); //don't center the x labels as we are using a custom XAxisRenderer to set the label x, y position
    xAxis.setValueFormatter(new ValueFormatter() {
        @Override
        public String getFormattedValue(float value) {
            return xAxisLabel.get((int) value);
        }
    });

    //initialize Y-Right-Axis
    YAxis rightAxis = mBarChart.getAxisRight();
    rightAxis.setTextColor(Color.BLACK);
    rightAxis.setTextSize(14);
    rightAxis.setDrawAxisLine(true);
    rightAxis.setAxisLineColor(Color.BLACK);
    rightAxis.setDrawGridLines(true);
    rightAxis.setGranularity(1f);
    rightAxis.setGranularityEnabled(true);
    rightAxis.setAxisMinimum(0);
    rightAxis.setAxisMaximum(1500f);
    rightAxis.setLabelCount(4, true); //labels (Y-Values) for 4 horizontal grid lines
    rightAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);

    //initialize Y-Left-Axis
    YAxis leftAxis = mBarChart.getAxisLeft();
    leftAxis.setAxisMinimum(0);
    leftAxis.setDrawAxisLine(true);
    leftAxis.setLabelCount(0, true);
    leftAxis.setValueFormatter(new ValueFormatter() {
        @Override
        public String getFormattedValue(float value) {
            return "";
        }
    });

    //set the BarDataSet
    BarDataSet barDataSet = new BarDataSet(entries, "Hours");
    barDataSet.setColor(Color.RED);
    barDataSet.setFormSize(15f);
    barDataSet.setDrawValues(false);
    barDataSet.setValueTextSize(12f);

    //set the BarData to chart
    BarData data = new BarData(barDataSet);
    mBarChart.setData(data);
    mBarChart.setScaleEnabled(false);
    mBarChart.getLegend().setEnabled(false);
    mBarChart.setDrawBarShadow(false);
    mBarChart.getDescription().setEnabled(false);
    mBarChart.setPinchZoom(false);
    mBarChart.setDrawGridBackground(true);
    mBarChart.setXAxisRenderer(new XAxisRenderer(mBarChart.getViewPortHandler(), mBarChart.getXAxis(), mBarChart.getTransformer(YAxis.AxisDependency.LEFT)){
        @Override
        protected void drawLabel(Canvas c, String formattedLabel, float x, float y, MPPointF anchor, float angleDegrees) {
            //for 6AM and 6PM set the correct label x position based on your needs
            if(!TextUtils.isEmpty(formattedLabel) && formattedLabel.equals("6"))
                Utils.drawXAxisValue(c, formattedLabel, x+Utils.convertDpToPixel(5f), y+Utils.convertDpToPixel(1f), mAxisLabelPaint, anchor, angleDegrees);
                //for 12AM and 12PM set the correct label x position based on your needs
            else
                Utils.drawXAxisValue(c, formattedLabel, x+Utils.convertDpToPixel(20f), y+Utils.convertDpToPixel(1f), mAxisLabelPaint, anchor, angleDegrees);
        }
    });
    mBarChart.invalidate();
}

这是新的结果(下午 4 点到下午 3 点):

示例 2 映射 X-Axis 具有 Y-Values 的时间戳:

下面是另一个示例,说明如何将 X(时间戳)映射到 Y(值):

//prepare X,Y data
ArrayList<Double> valuesList = new ArrayList<Double>();
ArrayList<Long> xAxisLabel = new ArrayList<>();
for(int i = 0; i < 24; i++){
    valuesList.add((double)100+i); //y-values
    xAxisLabel.add(1645970400000L+i); //x-timestamps
}
xAxisLabel.add(0L); //empty x for the last vertical grid line on Y-Right Axis

//prepare Bar Entries
ArrayList<BarEntry> entries = new ArrayList<>();
for (int i = 0; i < valuesList.size(); i++) {
    BarEntry barEntry = new BarEntry(i+1, valuesList.get(i).floatValue()); //start always from x=1 for the first bar
    entries.add(barEntry);
}

并且根据上面的映射,您可以使用 setLabelCount 在 X-Axis 上呈现您希望的标签数量。例如:使用 xAxis.setLabelCount(xAxisLabel.size(), true); 您可以呈现 X-axis.

中的所有标签

回调 getFormattedValue(float value) 每次特定的 X-index 准备好在图形上呈现时都会被调用,因此您必须首先获取索引,然后您可以从中获取正确的时间戳如下例所示:

//initialize xAxis
XAxis xAxis = mBarChart.getXAxis();
xAxis.setLabelCount(xAxisLabel.size(), true); //show all the labels
xAxis.setValueFormatter(new ValueFormatter() {
    @Override
    public String getFormattedValue(float value) {
        int xIndex = (int) value;
        if(xIndex == xAxisLabel.size()-1)
            return "";
        Long timeStamp = xAxisLabel.get(xIndex);
        //here convert the timestamp to the appropriate String value
        return String.valueOf(timeStamp);
    }
});

下面是基于上述示例的所有标签的 X-Timestamps 结果。为了呈现如下图所示的标签,我还进行了以下更改:

xAxis.setLabelRotationAngle(90); //this rotates the x labels to 90 degrees
mBarChart.setXAxisRenderer(new XAxisRenderer(mBarChart.getViewPortHandler(), mBarChart.getXAxis(), mBarChart.getTransformer(YAxis.AxisDependency.LEFT)){
    @Override
    protected void drawLabel(Canvas c, String formattedLabel, float x, float y, MPPointF anchor, float angleDegrees) {
        Utils.drawXAxisValue(c, formattedLabel, x+Utils.convertDpToPixel(5f), y, mAxisLabelPaint, anchor, angleDegrees);
    }
});

时间戳结果:

X-Timestamps 每 10 秒水平滚动一次。每页有 10 个时间戳。

下面我将展示如何修改上述代码以处理 X-Y 映射以每 10 秒显示 X-Timestamps 的要点:

int visibleXValuesPerPage = 10;
    //get a dummy TimeStamp for 27-02-2022 16:00
    Date date = new Date();
    long dateTimeStamp = 0;
    try {
        String strDate = "27-02-2022 16:00";
        date = new SimpleDateFormat("dd-MM-yyyy HH:mm", Locale.US).parse(strDate);
        if(date!=null) {
            dateTimeStamp = date.getTime();
        }
    }catch (Exception e){}

    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(dateTimeStamp);
    
    ArrayList<Double> valuesList = new ArrayList<Double>();
    ArrayList<Long> xAxisLabel = new ArrayList<>();

    //1h = 3600 seconds
    //1d = 86400 seconds
    //1w = 604800 seconds
    int seconds = 3600;
    //the loop here is incremented by 10 seconds (i+=10)
    for(int i = 0; i < seconds; i+=10){
        String time = DateFormat.format("dd-MM-yyyy HH:mm:ss", cal).toString();
        long timeStamp = cal.getTimeInMillis();
        valuesList.add((double)i);
        xAxisLabel.add(timeStamp);
        cal.add(Calendar.SECOND, 10);
    }
    
    ArrayList<BarEntry> entries = new ArrayList<>();
    for (int i = 0; i < valuesList.size(); i++) {
        BarEntry barEntry = new BarEntry(i+1, valuesList.get(i).floatValue());
        entries.add(barEntry);
    }
    
    XAxis xAxis = mBarChart.getXAxis();
    xAxis.setAxisMinimum(0 + 0.5f);
    xAxis.setAxisMaximum(entries.size() + 0.5f);
    xAxis.setLabelCount(visibleXValuesPerPage, false);
    xAxis.setLabelRotationAngle(90);
    xAxis.setCenterAxisLabels(true);
    xAxis.setValueFormatter(new ValueFormatter() {
        @Override
        public String getFormattedValue(float value) {
            if (value >= 0)
            {
                int xIndex = (int)value;
                if (value > xAxisLabel.size()-1 && value <= xAxisLabel.size())
                    return "";
                if (xIndex < xAxisLabel.size())
                {
                    Long timeStamp = xAxisLabel.get(xIndex);
                    //here convert the timestamp to the appropriate String value
                    Calendar cal = Calendar.getInstance();
                    cal.setTimeInMillis(timeStamp);
                    String time = DateFormat.format("dd-MM-yyyy HH:mm:ss", cal).toString();
                    return String.valueOf(time);
                }
                return "";
            }
            return "";
        }
    });


    //set the BarData to chart
    mBarChart.setVisibleXRangeMaximum(visibleXValuesPerPage);
    mBarChart.invalidate();