0%

Android开发 aChartEngine 动态加载报表数据,动态改变Y轴最大最小值

最近的项目需要显示统计报表,完全自己画太费时间,搜索了一下,找到了aChartEngine。项目主页:http://code.google.com/p/achartengine/,而美工给我的图是这样的: achartengine, 显然,下载编译好的jar包不能满足我的需求,所以我下的是源代码,稍稍做了些小修改。 现在我们的需求是这样:数据比较多,每天一条,一年就是365条,不可能一起都显示出来,用户可以左右拉拖动来查看之前的和之后的数据,就是动态加载报表的数据,还有一点,纵座标,我这里的温度是体温,一般不会差距很大,但是如果是其他的,例如体重,人和人的差距就很大了,所以,纵座标的范围也需要动态控制,另外,我们的项目不允许缩放报表。 在拖动Chart的时候,会触发PanListener的panApplied方法,所以,我们只要在这个方法里,取到当前的横座标的取值范围,再根据这个范围去数据库查找数据,然后把数据加入XYMultipleSeriesDataset里,就可以了,至于Y座标的范围,可以查询数据库,取出横座标范围内的最大值和最小值。

final GraphicalView chartView=temperatureChart.getView();
        layout_chart.addView(chartView);

        
        chartView.addPanListener(new PanListener() {
            
            @Override
            public void panApplied() {
                // TODO Auto-generated method stub
                double[] range=chartView.getRange();
                Date maxDate=new Date();
                Date minDate=new Date();
                maxDate.setTime((long)range[1]+1000*60*60*24*2);
                minDate.setTime((long)range[0]-1000*60*60*24*2);
                temperatureChart.loadData(minDate,maxDate);
            }
           });

temperatureChart是一个继续自AbstractChart的类的实例。这里的AbstractChart并非org.achartengine.chart.AbstractChart,而是官方Demo里的org.achartengine.chartdemo.demo.chart.AbstractChart. 解释一下,我这里的时间为什么要最小值减两天,最大值加两天,这是因为当用户手指离开屏幕,最后一次执行panApplied方法后,UI是不会更改的,当用户再次把手指放到屏幕上,触发org.achartengine.TouchHandler里的方法时,才会重新绘图,更新UI,所以如果读取的范围不大一点,用户最终看到的是上一次panApplied方法执行后的结果,而不是最后一次,导致左右边会有空白,没有数据。其实更好的方法,应该是改源码,增加个类似Adapter的notifyDataSetChanged()方法,通知更新UI,但是稍稍复杂点。 GraphicalView里的getRange方法,功能是获取横纵座标的范围:

  /**
   * 获取表横纵座标的范围,返回的数组,4个值分别为
   * x最小值,x最大值,y最小值,y最大值
   * @return
   */
  public double[] getRange()
  {
      double[] range=new double[4];
      XYMultipleSeriesRenderer renderer=(XYMultipleSeriesRenderer)mRenderer;
      range[0]=renderer.getXAxisMin();
      range[1]=renderer.getXAxisMax();
      range[2]=renderer.getYAxisMin();
      range[3]=renderer.getYAxisMax();
      
      return range;
  }

loadData方法:

    /**
     * 载入指定时期的数据
     * @param start
     * @param end
     */
    public void loadData(Date start, Date end) {
        dataset.removeAllSeries();
        List signList = healthDB.getSignList(HealthSigns.TEMPERATURE, start, end);
        TimeSeries series = new TimeSeries("体温变化曲线");
        for (HealthSigns sign : signList) {
            series.add(sign.getDate(), sign.getData());
        }
        dataset.addSeries(series);
        
        
        float yAxisMax=healthDB.getMaxIn(HealthSigns.TEMPERATURE, start, end);
        float yAxisMin=healthDB.getMinIn(HealthSigns.TEMPERATURE, start, end);
        renderer.setYAxisMax(yAxisMax);
        renderer.setYAxisMin(yAxisMin);
    }