PhilJay / MPAndroidChart

A powerful 🚀 Android chart view / graph view library, supporting line- bar- pie- radar- bubble- and candlestick charts as well as scaling, panning and animations.
Other
37.6k stars 9.02k forks source link

Entry(x,y) doesn't handle correctly x as milliseconds (unix time) #4024

Closed pwireless closed 6 years ago

pwireless commented 6 years ago

Entry(x,y) doesn't handle correctly x as milliseconds (unix time)

Did the following simple lines:

        long l1 = System.currentTimeMillis();
        long l2 = l1 + 500;
        Entry e1 = new Entry(l1, 10);
        Entry e2 = new Entry(l2, 10);
        long e1long = (long)e1.getX();
        long e2long = (long)e2.getX();
        Log.d("MEEE2", String.format(Locale.US, "l1 = %d -- e1long = %d,    l2 = %d -- e2long = %d", l1, e1long, l2, e2long));

and the result was :

l1 = 1525979109063 -- e1long = 1525979152384,
l2 = 1525979109563 -- e2long = 1525979152384

i.e. the Entry doesn't handle milliseconds correctly, due to the float being 32-bit FP format.

The LineChartTime class in the MPAndroidChart example, has the example with hours, which then converts to milliseconds in the value formatter. It would be great to have the example with milliseconds instead of hours, as it is more generic.

Entry should be able to accept correctly milliseconds.

A new Entry constructor would be ideal :

Entry e = new Entry(long x, float y);

(in the previous library versions, the addXValue would save the situation)

almic commented 6 years ago

This is a well known problem, and the only solution is to just not use such big numbers. There are better ways to handle times! Use smaller integer X and Y values, and apply the AxisValueFormatter and ValueFormatter classes. You can pass the original data set and map the times 1:1

Also, the suggestion to convert to double values is a contender to fixing this, although this method is still not the best solution. I would almost insist on allowing you to pass a Calendar or Date object—and let the DataSet class reformat them into intervals with simplified indexes—before letting developers get the renderer tangled up with huge double values.

As I always suggest to anyone having issues with big numbers in this library, cut them down into smaller and more meaningful values! Converting the base number 1802210870 into 1802 and then value format that into 1.8B or 2B is much better for the end-user! Same with dates and the developer, pass small indexes spaced according to your time interval, and use the formatter to turn them into meaningful dates and times by passing the original timestamps into it.

timusus commented 6 years ago

The solution is to represent chart values with Double instead of Float.

See #2891