Search code examples
androidchartsreal-timempandroidchart

DateTime in Xaxis Label not working correctly MPAndroidChart


I am creating Realtime Linechart using MPAndroidChart Library Example link Realtime chart is working fine, I am passing date to xAxis Label update all label same time image ScreenShot

I xAxis label shows 01:00:21 01:00:21 01:00:21 01:00:21

But I want xAxis Label is 01:00:21 01:00:22 01:00:23 01:00:24 Help me to solve the problem its save my life

My code below

public class MainActivity extends AppCompatActivity  {
    private LineChart chart;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("RealtimeLineChartActivity");
        chart = findViewById(R.id.chart1);
        chart.getLegend().setEnabled(false);
        chart.getDescription().setEnabled(true);
        chart.setBackgroundColor(Color.LTGRAY);
        LineData data = new LineData();
        chart.setData(data);

        Legend l = chart.getLegend();
        l.setForm(Legend.LegendForm.LINE);
        l.setTextColor(Color.WHITE);

        XAxis xl = chart.getXAxis();
        xl.setTextColor(Color.WHITE);
        xl.setPosition(XAxis.XAxisPosition.BOTTOM);
        xl.setValueFormatter(new MyXAxisValueFormatter());
        xl.setAvoidFirstLastClipping(true);
        xl.setEnabled(true);
        xl.setTextSize(15f);

        YAxis leftAxis = chart.getAxisLeft();
        leftAxis.setTextColor(Color.WHITE);
        leftAxis.setAxisMaximum(100f);
        leftAxis.setAxisMinimum(0f);
        leftAxis.setDrawGridLines(true);

        YAxis rightAxis = chart.getAxisRight();
        rightAxis.setEnabled(false);
    }
    private void addEntry() {

        LineData data = chart.getData();
        if (data != null) {
            ILineDataSet set = data.getDataSetByIndex(0);
            if (set == null) {
                set = createSet();
                data.addDataSet(set);
            }

            data.addEntry(new Entry(set.getEntryCount(), (float) (Math.random() * 40) + 30f), 0);
            data.notifyDataChanged();
            chart.notifyDataSetChanged();
            chart.setVisibleXRangeMaximum(4);
            chart.moveViewToX(data.getEntryCount());
        }
    }

    private LineDataSet createSet() {

        LineDataSet set = new LineDataSet(null, "Dynamic Data");
        set.setAxisDependency(YAxis.AxisDependency.LEFT);
        set.setValueTextColor(Color.WHITE);
        set.setValueTextSize(9f);
        set.setDrawValues(false);
        return set;
    }

    private Thread thread;
    private void feedMultiple() {

        if (thread != null)
            thread.interrupt();
        final Runnable runnable = new Runnable() {

            @Override
            public void run() {
                addEntry();
            }
        };
        thread = new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {

                    // Don't generate garbage runnables inside the loop.
                    runOnUiThread(runnable);

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        thread.start();
    }

    @Override
    protected void onStart() {
        feedMultiple();
        super.onStart();
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (thread != null) {
            thread.interrupt();
        }
    }

    public static class MyXAxisValueFormatter  implements IAxisValueFormatter {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            Date date = new Date();
            SimpleDateFormat formatter = new SimpleDateFormat("hh:mm:ss");
            return formatter.format(date);
        }

        @Override
        public int getDecimalDigits() {
            return 0;
        }

    }
}

Solution

  • it looks like the date instance is being created once and is used several times. i think you should use the value parameter in getFormattedValue callback to calculate the new x-axis value. you may define an initial date as a global variable and calculate the x-axis value by adding the value parameter on it.

    so the code must be something like this:

        final Date initialDate = new Date();
    
        public static class MyXAxisValueFormatter  implements IAxisValueFormatter {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                Calendar c = Calendar.getInstance();
                c.setTime(initialDate);
                c.add(Calendar.SECOND, Math.round(value));
                Date newDate = c.getTime();
                String formattedDate = new SimpleDateFormat("hh:mm:ss").format(newDate);
                return formattedDate;
            }
    
            @Override
            public int getDecimalDigits() {
                return 0;
            }
    
        }