AChartEngine-Combined TimeChart and ScatterChart, X-Axis date

一世执手 提交于 2019-12-12 01:56:43

问题


I have created a graph where tamperatures are displayed in a timeChart. I needed to mark a few temperatures with different color, so I used a XYCombinedChart and added a ScatterChar with the temperatures I wanted to mark. It all worked well. The only problem is that, in order to make it work, I used milliseconds in ScatterCharts's XYSeries like shown below:

XYSeries pointSeries = new XYSeries("NotFromSensor");    
dataset.addSeries(pointSeries);    
int t = 0;    
for (t = 0; t < MainActivity.temps.size(); t++){    
    pointSeries.add(dt[t].getTime(), MainActivity.temps.get(t));    
}

The whole code of creating the graph is shown below:

public class DeviceGraphActivity extends Activity {
private XYMultipleSeriesDataset dataset, pointDataset ;
private XYMultipleSeriesRenderer mRenderer;
private XYSeriesRenderer renderer1, pointRenderer;

public GraphicalView getDeviceView(Context context, String title){
    dataset = new XYMultipleSeriesDataset();
    clearDataset();// a set with all the data that will be displayed on the graph
    mRenderer = new XYMultipleSeriesRenderer();//determines the variables of the overall graph        
    int i;
    System.out.println(ShowGraphActivity.flag);
    if(DeviceFilterActivity.checkedDevices.isEmpty()){
        if(ShowGraphActivity.flag == true){

            MainActivity.setXYValues("SELECT Temperature, Time FROM Temperatures WHERE Time BETWEEN " +
                    "'"+(MainActivity.yy1)+"-"+((MainActivity.mm1))+"-"+(MainActivity.dd1)+"' " +
                            "AND '"+(MainActivity.yy2)+"-"+((MainActivity.mm2))+"-"+((MainActivity.dd2))+"'");
            setData(false);
            MainActivity.setXYValues("SELECT Temperature, Time FROM Temperatures WHERE FromSensor = 0 AND Time BETWEEN " +
                    "'"+(MainActivity.yy1)+"-"+((MainActivity.mm1))+"-"+(MainActivity.dd1)+"' " +
                            "AND '"+(MainActivity.yy2)+"-"+((MainActivity.mm2))+"-"+((MainActivity.dd2))+"'");
            setData(true);

        }
        else{
            MainActivity.setXYValues("SELECT Temperature, Time FROM Temperatures");
            setData(false);
            MainActivity.setXYValues("SELECT Temperature, Time FROM Temperatures WHERE FromSensor = 0");
            setData(true);
        }
        renderer1 = new XYSeriesRenderer();
        renderer1.setLineWidth(3);//sets graph line's width
        renderer1.setChartValuesTextSize(20);//sets the size of the text on the char
        renderer1.setColor(Color.BLUE);//sets the color of the graph
        renderer1.setDisplayBoundingPoints(true);
        mRenderer.addSeriesRenderer(renderer1);//adds the renderer(1 graph) to the overall graph

        pointRenderer = new XYSeriesRenderer();
        pointRenderer.setLineWidth(3);//sets graph line's width
        pointRenderer.setChartValuesTextSize(20);//sets the size of the text on the char
        pointRenderer.setPointStyle(PointStyle.CIRCLE);
        pointRenderer.setColor(Color.RED);//sets the color of the graph
        pointRenderer.setDisplayBoundingPoints(true);
        mRenderer.addSeriesRenderer(pointRenderer);
    }
    else{
        for(i = 0; i < DeviceFilterActivity.checkedDevices.size(); i++){
            if(ShowGraphActivity.flag){
                MainActivity.setXYValues("SELECT Temperature, Time FROM Temperatures WHERE DeviceID = "+DeviceFilterActivity.checkedDevices.get(i).getId()+" AND Time BETWEEN " +
                    "'"+(MainActivity.yy1)+"-"+((MainActivity.mm1))+"-"+(MainActivity.dd1)+"' " +
                            "AND '"+(MainActivity.yy2)+"-"+((MainActivity.mm2))+"-"+((MainActivity.dd2))+"'");
                setData(i, false);
                MainActivity.setXYValues("SELECT Temperature, Time FROM Temperatures WHERE FromSensor = 0 AND DeviceID = "+DeviceFilterActivity.checkedDevices.get(i).getId()+" AND Time BETWEEN " +
                        "'"+(MainActivity.yy1)+"-"+((MainActivity.mm1))+"-"+(MainActivity.dd1)+"' " +
                                "AND '"+(MainActivity.yy2)+"-"+((MainActivity.mm2))+"-"+((MainActivity.dd2))+"'");
                setData(i,true);
            }
            else{
                MainActivity.setXYValues("SELECT Temperature, Time FROM Temperatures WHERE DeviceID = "+DeviceFilterActivity.checkedDevices.get(i).getId());
                setData(i, false);
                MainActivity.setXYValues("SELECT Temperature, Time FROM Temperatures WHERE FromSensor = 0 AND DeviceID = "+DeviceFilterActivity.checkedDevices.get(i).getId());
                setData(i, true);
            }
            renderer1 = new XYSeriesRenderer();
            renderer1.setLineWidth(3);//sets graph line's width
            renderer1.setChartValuesTextSize(20);//sets the size of the text on the chart
            renderer1.setColor(DeviceFilterActivity.checkedColors.get(i));//sets the color of the graph
            renderer1.setDisplayBoundingPoints(true);
            mRenderer.addSeriesRenderer(renderer1);//adds the renderer(1 graph) to the overall graph 

            pointRenderer = new XYSeriesRenderer();
            pointRenderer.setLineWidth(3);//sets graph line's width
            pointRenderer.setChartValuesTextSize(20);//sets the size of the text on the chart
            pointRenderer.setColor(Color.RED);//sets the color of the graph
            pointRenderer.setDisplayBoundingPoints(true);
            mRenderer.addSeriesRenderer(pointRenderer);
        }
    }


    mRenderer.setLabelsTextSize(20);
    mRenderer.setPanEnabled(true);
    mRenderer.setZoomEnabled(true);
    mRenderer.setZoomButtonsVisible(true);
    mRenderer.setYAxisMax(50);
    mRenderer.setYAxisMin(0);
    mRenderer.setShowGrid(true);
    mRenderer.setMargins(new int[] { 50, 50, 25, 22 });
    mRenderer.setLegendTextSize(25);
    // we show the grid
    mRenderer.setInScroll(true);
    mRenderer.setChartTitle(title);
    mRenderer.setChartTitleTextSize(30);

    //------------------------

    mRenderer.setClickEnabled(false);//the graph can't be clicked so that it can be refreshed as well as be zoomed in or out 
    mRenderer.setSelectableBuffer(10);

    //---------------------------

    String[] types = new String[]{ new String(TimeChart.TYPE), new String(ScatterChart.TYPE)};
    //return ChartFactory.getTimeChartView(context, dataset, mRenderer, "YYYY-MM-DD");
    return ChartFactory.getCombinedXYChartView(context, dataset, mRenderer, types);//return a graph depending on the above declarations, that will be used as a view in the previous activity
}

public void setData(boolean arePoints){//sets the temperatures and dates data that will be used on the graph
    Date[] dt = new Date[MainActivity.dates.size()]; 
    for (int k = 0; k< MainActivity.dates.size(); k++){
        GregorianCalendar gc = new GregorianCalendar(MainActivity.dates.get(k).getYy(),
                MainActivity.dates.get(k).getMM()-1,MainActivity.dates.get(k).getDd(),
                MainActivity.dates.get(k).getHh(),MainActivity.dates.get(k).getMm(),
                MainActivity.dates.get(k).getSs());
        dt[k] = gc.getTime();
    }   
    if(!arePoints){
        TimeSeries series = new TimeSeries("Temperature");
        dataset.addSeries(series);
        int t = 0;
        for (t = 0; t < MainActivity.temps.size(); t++){
            series.add(dt[t] , MainActivity.temps.get(t));
        }
    }
    else{
        XYSeries pointSeries = new XYSeries("NotFromSensor");
        dataset.addSeries(pointSeries);
        int t = 0;
        for (t = 0; t < MainActivity.temps.size(); t++){
            pointSeries.add(dt[t].getTime(), MainActivity.temps.get(t));
        }
    }


}

public void setData(int i,boolean arePoints){//sets the temperatures and dates data that will be used on the graph
    Date[] dt = new Date[MainActivity.dates.size()]; 
    for (int k = 0; k< MainActivity.dates.size(); k++){
        GregorianCalendar gc = new GregorianCalendar(MainActivity.dates.get(k).getYy(),
                MainActivity.dates.get(k).getMM()-1,MainActivity.dates.get(k).getDd(),
                MainActivity.dates.get(k).getHh(),MainActivity.dates.get(k).getMm(),
                MainActivity.dates.get(k).getSs());
        dt[k] = gc.getTime();
    }
    if(!arePoints){
        TimeSeries series = new TimeSeries("device "+DeviceFilterActivity.checkedDevices.get(i).getName());
        dataset.addSeries(series);
        int t = 0;
        for (t = 0; t < MainActivity.temps.size(); t++){
            series.add(dt[t] , MainActivity.temps.get(t));
        }
    }
    else{
        XYSeries pointSeries = new XYSeries("NotFromSensor");
        dataset.addSeries(pointSeries);
        int t = 0;
        for (t = 0; t < MainActivity.temps.size(); t++){
            pointSeries.add(dt[t].getTime() , MainActivity.temps.get(t));
        }
    }
}



public void clearDataset(){
    this.dataset.clear();
}

}

Obviously the chart shows the time in milliseconds. How can I use the X-Axis from the TimeChart and show the real dates?


回答1:


I just found a solution to this problem. It's a custom library, something like an extention to the original AChartEngine. It includes a class named CombinedTimeChart. It is the exact same as the CombinedXYChart, but you can set the x-axis with the proper dates, without having to manually set its labels. I provide a link to get the library:

https://github.com/hdodenhof/achartengine

Credits to the creator for his good work. I tested it and works just great. The only thing you have to do is import the whole project into your workspace (if using Eclipse) and the import it as a library into your project:

  • right click on your project name in Package Explorer.
  • Properties
  • Android
  • Add...
  • Choose the folder with the name of the imported project (achartengine-master)
  • Apply
  • OK

Now you are ready to use the library as you would have normally done with the original AChartEngine library. Remember to use the method ChartFactory.getCombinedTimeChartView(context, dataset, renderer, type) to get the chart with the choosen graphs.

I have seen many related questions around the forum with the answer "use CombinedXYChart with a LineChart and a ScatterChart", which is not a bad solution, but in my opinion the above is a better and easier way to create this kind of chart.

Hope it helps.



来源:https://stackoverflow.com/questions/27484327/achartengine-combined-timechart-and-scatterchart-x-axis-date

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!