将当前时间(以毫秒为单位)传递给MPChart会将其分解

时间:2017-09-14 08:26:51

标签: android mpandroidchart

我试过搞清楚这一点,但它并没有加起来。数据没有按预期显示。

首先我生成虚拟数据。这是异步完成的,因为我需要在调用System.currentTimeMillis之间留出时间来获得它们之间的间隔。 (看看这里糟糕的代码,这只是发布中不会出现的调试数据。考虑到ANR,在主线程上使用Thread.sleep是一个坏主意)

public class AsyncGeneration extends AsyncTask<String, String, String>{
    public AsyncGeneration() {
        super();
    }
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }
    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
    }
    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
    }
    @Override
    protected void onCancelled(String s) {
        super.onCancelled(s);
    }
    @Override
    protected void onCancelled() {
        super.onCancelled();
    }
    @Override
    protected String doInBackground(String... strings) {
        while(root == null) {
            try {
                Thread.sleep(200);
            }catch(InterruptedException e){}
        }
        List<Entry> rdata = new ArrayList<>();
        for(int i = 1; i < 30; i++){
            try{
                Thread.sleep(200);
            }catch(Exception e){
                //IGNORE
            }

            float time = System.currentTimeMillis();
            Log.e("GChart", "Timex: " + time);
            Session s = new Session(r.nextInt(5000), time);//Replace time with the index in the for-loop and it works for some reason
            rdata.add(new Entry(s.getXValue(), s.getYValue()));
            Log.e("GChart", "Timey: " + s.getXValue());
        }

        final List<Entry> entries = rdata;
        OverviewFragment.this.getActivity().runOnUiThread(() ->{

            LineDataSet data = new LineDataSet(entries, "Distance");
            data.setCircleColor(Color.parseColor("#FF0000"));
            LineData lineData = new LineData(data);
            tab1chart.setData(lineData);

            tab1chart.invalidate(); // refresh

            tab1chart.getXAxis().setValueFormatter(new DateFormatter());
            tab1chart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
            tab1chart.getXAxis().setTextSize(10f);
            tab1chart.getXAxis().setTextColor(Color.RED);
            tab1chart.getXAxis().setDrawAxisLine(true);
            tab1chart.getXAxis().setDrawGridLines(true);
            tab1chart.getAxisLeft().setValueFormatter(new DistanceValueFormatter());
            tab1chart.getAxisLeft().setDrawGridLines(true);
            Log.v("Chart", "Chart data loaded and invalidated");//This prints

        });
        return null;
    }
}

到目前为止,一切看起来都很好。数据被放入图表中,没有例外,没有崩溃。

当图表呈现时,单个数据点显示在图表的最左侧。我生成30个数据点,一个显示出来。

问题#1:只显示一个数据点。

问题#2稍微困难一些。底部的整个X轴消失。 X轴消失,当缩放时,Y轴及其文本也消失。这很难解释,所以这是一个截图:

Single data point

Single data point, X and Y axis missing

值得一提的是,如果我在for循环中传递i作为时间,它会按预期显示:所有轴都到位,缩放不会破坏任何内容。

(浮点值可以采用与Longs相同的值,除了它们还有小数。)

另外,我格式化数据:

public class DateFormatter implements IAxisValueFormatter {
    SimpleDateFormat formatter;

    public DateFormatter(){
        formatter = new SimpleDateFormat("dd/MM/yy, HH:mm");
    }

    @Override
    public String getFormattedValue(float value, AxisBase axis) {
        //This method is never called. Nothing is returned
        if(axis instanceof XAxis) {
            String formatted = formatter.format(new Date((long) value));
            Log.d("Formatter", "Formatted \"" + value + "\" to \"" + formatted + "\".");
            return formatted;
        }
        return "Not supported";
    }
}

删除格式化程序不会改变任何内容,轴仍然消失。缩放仍然会打破Y轴。

所以我的问题是:我该如何解决这个问题?当我以毫秒为单位传递当前时间时,我不明白为什么图表不起作用(我用调试输出检查了值,浮点数可以处理它)。我之前得到了一些调试输出,最终停止了所有显示传递给格式化程序的值是值&lt; 2000.我不能再复制这个了,但

图表本身似乎没有被破坏,但是从触摸事件看起来每个点都被推入相同的X坐标但只有一个点呈现。当我触摸图表时,橙色线显示指示数据点的位置。它会弹出不可见的点。

当我将for循环索引作为X值传递时,它按预期工作,格式化程序工作正常(除了它显示1970年的日期这一事实,但它被计为1毫秒到纪元,所以这是期待的)

我在格式化日期时也看了this。当我尝试传递自纪元以来的毫秒数时,图表就会停止工作。

我正在使用MPChart v 3.0.2,使用Java 8编译Android 26,并运行Android Studio 3.0 beta 2

至于布局,它只是一个包含LineChart的LinearLayout。

这应该可行,但是当我以某种原因以毫秒为单位传递当前时间时,它会中断。传递任何其他数据(只要数字不是那么大)工作正常。

这两张图片不是图表的样子。 X轴应该是可见的,但由于某种原因,它不会伴随大量的数据。

1 个答案:

答案 0 :(得分:3)

这是Android MPCharthave a read this thread)的已知问题。 MPChart支持的时间序列图表 - 您可以将时间(millis)设置为每小时图表的X值。

但是太多的连续数据(点)将无法在折线图中正确绘制。由于某些性能限制,Entry对象将仅接受浮点值。

所以,保持第一个值作为参考,并从参考值&amp;中减去每个上升值。除以一些常数(比如说1000)。所以,你X value设定就像10,20,30 ......&amp;等等。

Axis Value formatter中执行反向逻辑以正确呈现X Axis标签(请参阅代码段)。

lineChart.getXAxis().setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {

                SimpleDateFormat format2 = new SimpleDateFormat("HH:mm:ss");
                return format2.format(new Date(firstTimeStamp + ((long) value) * 1000L));

            }

        });