时间序列数据无法正确解释

时间:2014-07-23 19:47:33

标签: android jodatime androidplot

我正在尝试使用时间序列创建一个简单的折线图。问题是androidplot没有正确显示数组中的时间值,即日期已关闭。日期应该是:

  

2001年1月1日,2001年2月1日,2001年3月1日,2001年4月1日,2001年5月1日

但我得到了:

  

2001年1月1日,2001年1月30日,2001年3月1日,2001年3月31日,2001年5月1日

您可以从格式化调试信息中看到androidplot已解释的数据。我正在使用JodaTime。代码在这里:

public class VisualizeFragment extends Fragment {

    public static final String TAG = Config.PRE + VisualizeFragment.class.getSimpleName();

    private XYPlot plot;

    public VisualizeFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.simple_xy_plot_example, container, false);

        // initialize our XYPlot reference:
        plot = (XYPlot) v.findViewById(R.id.mySimpleXYPlot);

        // Create a couple arrays of y-values to plot:
        Number[] weights = {150, 180, 179, 170, 175};
        Number[] xyears = {
                978307200,  // 2001
                1009843200, // 2002
                1041379200, // 2003
                1072915200, // 2004
                1104537600  // 2005
        };
        Number[] years = {
                new DateTime(2001, 1, 1, 0, 0).getMillis() / 1000,
                new DateTime(2001, 2, 1, 0, 0).getMillis() / 1000,
                new DateTime(2001, 3, 1, 0, 0).getMillis() / 1000,
                new DateTime(2001, 4, 1, 0, 0).getMillis() / 1000,
                new DateTime(2001, 5, 1, 0, 0).getMillis() / 1000,
        };

        XYSeries series1 = new SimpleXYSeries(
                Arrays.asList(years),
                Arrays.asList(weights),
                "Weight");

        // Create a formatter to use for drawing a series using LineAndPointRenderer
        // and configure it from xml:
        LineAndPointFormatter series1Format = new LineAndPointFormatter();
        series1Format.setPointLabelFormatter(new PointLabelFormatter());
        series1Format.configure(getActivity().getApplicationContext(), R.xml.line_point_formatter_with_plf1);

        // add a new series' to the xyplot:
        plot.addSeries(series1, series1Format);

        // reduce the number of range labels
        //plot.setTicksPerRangeLabel(3);
        plot.getGraphWidget().setDomainLabelOrientation(-45);

        // draw a domain tick for each year:
        plot.setDomainStep(XYStepMode.SUBDIVIDE, years.length);


        plot.setDomainValueFormat(new Format() {

            // create a simple date format that draws on the year portion of our timestamp.
            // see http://download.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html
            // for a full description of SimpleDateFormat.
            private SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd");

            @Override
            public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {

                // because our timestamps are in seconds and SimpleDateFormat expects milliseconds
                // we multiply our timestamp by 1000:
                long timestamp = ((Number) obj).longValue() * 1000;
                Date date = new Date(timestamp);

                Log.d(TAG, "formatting date=" + new SimpleDateFormat("MMMM dd, yyyy").format(date));

                return dateFormat.format(date, toAppendTo, pos);
            }

            @Override
            public Object parseObject(String source, ParsePosition pos) {
                return null;

            }
        });


        return v;

    }


}

1 个答案:

答案 0 :(得分:1)

我认为问题在于你是统一细分你的域(XYStepMode.SUBDIVIDE),但因为你的xVals是epoch值,它们不是均匀分布的; 2001年1月1日至2001年2月1日之间的毫秒数与2001年2月1日至2001年3月1日之间的毫秒数不同,导致出现差异。

我建议使用i作为域值而不是epoch值,然后使用i在域值格式代码中查找正确的纪元值。这将涉及进行2次更改。首先,使用i作为你的f(x):

// I've just removed the 'years' param here, which tells SimpleXYSeries
// to use an implicit value of 'i' for getY(i).
XYSeries series1 = new SimpleXYSeries(Arrays.asList(weights),"Weight");

然后将格式化方法更改为:

@Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
    int i = ((Number) obj).intValue();
    Date date = years[i];
    Log.d(TAG, "formatting date=" + new SimpleDateFormat("MMMM dd, yyyy").format(date));
    return dateFormat.format(date, toAppendTo, pos);
}