【问题标题】:GraphView: rotating horizontal date labels, specifying a fixed size of the viewport and aligning the bullet points with the date labelsGraphView:旋转水平日期标签,指定固定大小的视口并将项目符号与日期标签对齐
【发布时间】:2015-02-21 04:04:09
【问题描述】:

这是一个由 3 部分组成的问题。

1) 首先,是否可以旋转水平 X 值。目前,当我试图在 X 轴(2015 年 4 月 1 日、2015 年 4 月 2 日等)上显示一个月中的所有天时,它们都会聚集在一起,变得不可读。 有没有办法旋转 X 轴标签使其垂直?


2) 要设置视口,文档建议使用:

graphview.getViewport().setScalable(true);
graphview.getViewport().setScrollable(true);

// To set a fixed manual viewport use this:
// set manual X bounds
graph.getViewport().setXAxisBoundsManual(true);
graph.getViewport().setMinX(0.5);
graph.getViewport().setMaxX(3.5);

// set manual Y bounds
graph.getViewport().setYAxisBoundsManual(true);
graph.getViewport().setMinY(3.5);
graph.getViewport().setMaxY(8);

但是,getViewport().setMinX(...) 函数需要双精度,而不是日期。 有没有办法滚动视口以一次显示 3-5 个日期?

代码 2):

GraphView graph = (GraphView) graphView.findViewById(R.id.graph);

DataPoint[] stockArr = new DataPoint[dplist.size()];
stockArr = dplist.toArray(stockArr);

LineGraphSeries<DataPoint> series = new LineGraphSeries<DataPoint>(stockArr);
graph.addSeries(series);
graph.setTitle("TEST GRAPH");

// set date label formatter
graph.getGridLabelRenderer().setLabelFormatter(new DateAsXAxisLabelFormatter(context));

graph.getViewport().setScalable(true);
graph.getViewport().setScrollable(true);
graph.getGridLabelRenderer().setNumHorizontalLabels(data.size()-1); // Approx 28-30

graph.getViewport().setXAxisBoundsManual(true);
graph.getViewport().setMinX(firstDate.getTime());
graph.getViewport().setMaxX(lastDate.getTime());

3) 有没有办法将项目符号与日期标签对齐?我用以下代码修改了我的 X 标签。但是,即使在更改之前,项目符号似乎也没有排列好。在下图中,1/1 应该是第一个点,1/2 应该是第二个点,1/3 应该是第三个点。有什么想法吗?

代码 3):

graph.getGridLabelRenderer().setLabelFormatter(new DateAsXAxisLabelFormatter(context) {

    @Override
    public String formatLabel(double value, boolean isValueX) {
        if (isValueX) {
            // show normal x values
            Calendar c = Calendar.getInstance();
            // set time in milliseconds
            c.setTimeInMillis(((long)value));
            int mYear = c.get(Calendar.YEAR);
            int mMonth = c.get(Calendar.MONTH);
            int mDay = c.get(Calendar.DAY_OF_MONTH);

            System.out.println((mMonth+1) + "/" + mDay);
            // Return Month/Day
            return (mMonth+1) + "/" + mDay;
            //return super.formatLabel(newDate.toString(), isValueX);
        } else {
            // show currency for y values
            return super.formatLabel(value, isValueX);
        }
    }
});

【问题讨论】:

    标签: java android graph android-graphview


    【解决方案1】:

    1) 当前不支持旋转标签。这已经是一个问题,但我不能说什么时候会实施。你可以在这里观看: https://github.com/jjoe64/GraphView/issues/293

    如果您想自己实现它,您将在此代码点执行此操作 - 它应该相对简单: https://github.com/jjoe64/GraphView/blob/master/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java#L934

    2) 视口需要双精度,如果您想使用日期,您必须通过date.getTime() 将日期转换为以毫秒为单位的 unix 时间纪元。

    如果我理解您,您希望一次显示 3 天的时间跨度。因此,您必须将水平标签的数量设置为 3,并将视口的大小设置为 3 天。应该这样做:

    graph.getViewport().setXAxisBoundsManual(true);
    graph.getGridLabelRenderer().setNumHorizontalLabels(3);
    graph.getViewport().setMinX(firstDate.getTime());
    graph.getViewport().setMaxX(firstDate.getTime() + 3*24*60*60*1000); // + 3 days
    

    【讨论】:

    • 嗨 jjoe64。我实施了您的 2) 响应中指定的更改。窗口现在确实显示 3 并且似乎工作得很好。我提出了第三个问题,如果你能看一下。它处理将点与它们的标签对齐。
    • 项目符号位于输入数据的位置,未与网格对齐
    【解决方案2】:

    来晚了,但为此事增添了一些亮点:

    1) 虽然“x labels rendered at an angle”的问题仍然存在,但现在有可能。

    使用 GraphView 4.2.2 测试。假设 graph 是您的 GraphView 对象:

    graph.getGridLabelRenderer().setHorizontalLabelsAngle(90);
    

    在某些情况下,135° 的角度允许以 更紧凑和优雅的方式。


    2) 看看@appsthatmatter 的answer

    如果您继续第 3) 点,您必须根据 3) 的最后部分调整@appsthatmatter 的答案:“如果您愿意指定视口的固定大小..."

    graph.getGridLabelRenderer().setNumHorizontalLabels(3);
    graph.getViewport().setXAxisBoundsManual(true);
    graph.getViewport().setMinX(getDaysSinceEpoch(firstDate));
    graph.getViewport().setMaxX(getDaysSinceEpoch(firstDate) + 3); // + 3 days
    

    3) 因为您想在 X 轴(2015 年 4 月 1 日、2015 年 4 月 2 日等)上显示一个月中的 ... ),我建议您使用自 Epoch 以来的天数,而不是像 java.util.Date#getTime() 返回的毫秒数。所以要表示的数据之间没有中间值。

    这意味着:

    • 您不能使用以下方法初始化 DataPoint

      new DataPoint(date, value);
      

      相反,您应该使用如下内容:

      new DataPoint(getDaysSinceEpoch(date), value);
      

      getDaysSinceEpoch(...) 接收日期并返回自 1970 年 1 月 1 日 00:00:00 GMT(纪元)以来的天数,此 Date 对象表示。使用Joda Time

      private int getDaysSinceEpoch(Date date) {
          return Days.daysBetween(new LocalDate(0), new LocalDate(date.getTime())).getDays();
      }
      
    • 你不能使用DateAsXAxisLabelFormatter

      相反,您必须实现自己的LabelFormatter

      graph.getGridLabelRenderer().setLabelFormatter(new DefaultLabelFormatter() {
          @Override
          public String formatLabel(double value, boolean isValueX) {
              return isValueX
                      ? getFormattedDate((int) value, "M/d")
                      : super.formatLabel(value, isValueX);
          }
      });
      

      getFormattedDate(...) 接收自 Epoch 以来的天数,以及描述日期格式的模式,并返回格式化的日期。使用Joda Time

      private String getFormattedDate(int daysSinceEpoch, String pattern) {
          return new LocalDate(0).plusDays(daysSinceEpoch).toString(pattern);
      }
      
    • 您应该按照Use dates as labels 的建议禁用“将边界四舍五入为易于阅读的数字”功能。

      设置true,评论或干脆删除这一行:

      // graph.getGridLabelRenderer().setHumanRounding(false);
      
    • 如果你想指定一个固定大小的视口,使用:

      graph.getViewport().setMinX(...);
      graph.getViewport().setMaxX(...);
      

      您不能使用 date.getTime() 将日期转换为自 Epoch 以来的毫秒数。

      相反,您必须使用上述getDaysSinceEpoch(...) 功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-18
      相关资源
      最近更新 更多