achartengine - can't figure how to use dates as x axis - the file I save is empty
The code that deal with your file must be something like this (not compiled):
public void savefunc(){
List<String> myDate = new ArrayList<String>(); //To store the formatted dates
SimpleDateFormat thedate = new SimpleDateFormat("dd/MM/yyyy");
Date d=new Date(); //the current date
String sd = thedate.format(d); // sd contains "16/04/2013", the formatted date
myDate.add(sd);
double thedata=Double.parseDouble(value.getText().toString().trim());
mydata.add(thedata);
...
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
for (int i=0;i<mydate.size();i++){
bw.write(mydate.get(i)+","+mydata.get(i)+"\n");
}
}
public void readfunc(){
SimpleDateFormat thedate = new SimpleDateFormat("dd/MM/yyyy");
Date d;
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
do {
s = br.readLine();
if (s != null ){
String[] splitLine = s.split(","); //first substring is the formatted date
date.add(thedate.parse(splitLine[0])); //do something with exception
data.add(Double.parseDouble(splitLine[1]));
...
Hope it helps.
How to set date on x axis in Line Chart using AchartEngine?
These are basic changes i made in my code and it worked for me..
TimeSeries series2 = new TimeSeries("Protein");
for (int i = 0; i < x_axis.size(); i++) {
int y = Integer.parseInt(y1_axis.get(i));
// Adding y as protein value
series2.add(i + 1, y);
}
for (int i = 0; i < x_axis.size(); i++) {
renderer.addXTextLabel(i + 1, x_axis.get(i));
}
renderer.setXLabels(0);
TimeSeries vs XYSeries AchartEngine
The X axis have to share the same values if you really want the line charts be displayed together.
So you will either have to have all the charts X axis be date values or all of them be double values.
scatter plot with dates at x axis -- add custom labels on X axis
As told by Dan in his answer you can use renderer.addXTextLabel(x, "text");
to set x-axis labels.
In your case:: u made mistake at commented line ,
You where trying to add x-axis labels twice..
change it as shown below
TimeSeries series = new TimeSeries("Showing data");
for (int i=0;i<date_asDates.size();i++){
series.add(i,data.get(i)); // only this change ll work as u needed
}
UPDATE: Change Your code to following it wont crash on adding new data's
and if u want only points to be visible not linealong with point then change this ChartFactory.getLineChartIntent(getBaseContext(), dataset, mRenderer,"dd/MM/yyyy");
to ChartFactory.getScatterChartIntent(getBaseContext(), dataset, mRenderer,"dd/MM/yyyy");
MainActivity.java
package com.example.trying;
import java.io.BufferedWriter;
import java.io.File; // imports add all as before too
public class MainActivity extends Activity implements OnClickListener{
View savebtn;
View graphicsbtn;
EditText value,weight;
String filename = "mydata.csv";
public static List<String> dates_Strings = new ArrayList<String>();
public static List<Double> data = new ArrayList<Double>();
public static List<Date> date = new ArrayList<Date>();
List<Double> mydata=new ArrayList<Double>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
date.clear();
data.clear();
dates_Strings.clear();
//Set up click listeners
savebtn=(View) findViewById(R.id.savebtn);
savebtn.setOnClickListener(this);
graphicsbtn=(View) findViewById(R.id.graphicsbtn);
graphicsbtn.setOnClickListener(this);
value=(EditText) findViewById(R.id.enter_data);
}
//called when a button is clicked
public void onClick(View v) {
switch (v.getId()){
case R.id.savebtn:
savefunc();
break;
case R.id.graphicsbtn:
Intent i = new Intent(this,LineGraph.class);
startActivity(i);
break;
}
}
public void savefunc(){
SimpleDateFormat thedate = new SimpleDateFormat("dd/MM/yyyy");
Date d=new Date();
String formattedDate=thedate.format(d);
Log.d("tag","format"+formattedDate);
dates_Strings.add(formattedDate);
try{
double thedata=Double.parseDouble(value.getText().toString().trim());
mydata.add(thedata);
Log.d("tag","thedata :"+thedata);
} catch (NumberFormatException e){
String message="Sorry you did't type anything";
Toast toast = Toast.makeText(getBaseContext(), message,Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 100);
toast.show();
// Toast.makeText(getBaseContext(), "Sorry you did't type anything", Toast.LENGTH_SHORT).show();
}
File sdCard = Environment.getExternalStorageDirectory();
File directory = new File (sdCard, "MyFiles");
directory.mkdirs();
File file = new File(directory, filename);
FileOutputStream fos;
//saving them
try {
fos = new FileOutputStream(file);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
for (int i=0;i<mydata.size();i++){
bw.write(mydata.get(i)+","+dates_Strings.get(i)+"\n");
}
value.setText("");
bw.flush();
bw.close();
} catch (IOException e2) {
e2.printStackTrace();
}//catch
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
LineGraph.java
package com.example.trying;
import java.io.BufferedReader;
import java.io.File; // add all other imports
public class LineGraph extends MainActivity {
String filename = "mydata.csv";
private LinearLayout layout;
private GraphicalView mChartView;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.graph);
layout = (LinearLayout) findViewById(R.id.chart);
readfunc();
//trying to copy the dates_asString to date (Dates) in order to use them in TimeSeries
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
Date convertedDate;//=new Date();
try{
for (int k=0;k<dates_Strings.size();k++){
convertedDate = formatter.parse(dates_Strings.get(k));
date.add(convertedDate);
Log.d("line","convertedDate :"+convertedDate);
}
}catch (ParseException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
TimeSeries series = new TimeSeries("Showing data");
for (int i=0;i<dates_Strings.size();i++){
series.add(i,data.get(i)); //series.add(date.get(i),data.get(i));
}
XYMultipleSeriesDataset dataset=new XYMultipleSeriesDataset();
dataset.addSeries(series);
//renderer for decay
XYSeriesRenderer renderer =new XYSeriesRenderer();
renderer.setColor(Color.YELLOW);
renderer.setLineWidth(3);
renderer.setPointStyle(PointStyle.SQUARE);
XYMultipleSeriesRenderer mRenderer =new XYMultipleSeriesRenderer();
mRenderer.addSeriesRenderer(renderer);
mRenderer.setXTitle("Date");
mRenderer.setYTitle("Data");
mRenderer.setApplyBackgroundColor(true);
mRenderer.setBackgroundColor(Color.BLACK);
mRenderer.setMarginsColor(Color.BLACK);
mRenderer.setXRoundedLabels(false);
mRenderer.setShowCustomTextGrid(true);
mRenderer.setXLabels(0);
for (int i=0;i<date.size();i++){
mRenderer.addXTextLabel(i,dates_Strings.get(i));
}
//mChartView = ChartFactory.getTimeChartView(this, dataset, mRenderer,"dd/MM/yyyy");
//mChartView = ChartFactory.getScatterChartView(this, dataset, mRenderer);
//layout.addView(mChartView);
Intent intent= ChartFactory.getLineChartIntent(getBaseContext(), dataset, mRenderer,"dd/MM/yyyy");
startActivity(intent);
}
public void readfunc(){
SimpleDateFormat thedate = new SimpleDateFormat("dd/MM/yyyy");
Date d=new Date();
String formattedDate=thedate.format(d);
File sdCard = Environment.getExternalStorageDirectory();
File directory = new File (sdCard, "MyFiles");
File file = new File(directory, filename);
String s;
FileInputStream fis;
try {
fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
do {
s = br.readLine();
if (s != null ){
String[] splitLine = s.split(",");
data.add(Double.parseDouble(splitLine[0]));
//dates_Strings.add(thedate.parse(splitLine[1]));
dates_Strings.add(formattedDate);
}
} while (s != null );
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
how to implement TimeChart in achartengine with android
So you need a layout (main.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/chart"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" />
<LinearLayout
android:id="@+id/layXzoom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:orientation="horizontal"
android:padding="5dp" >
</LinearLayout>
</RelativeLayout>
and activity (TestgrafActivity.java):
package si.pd.testgraf;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.PointStyle;
import org.achartengine.chart.TimeChart;
import org.achartengine.model.TimeSeries;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.LinearLayout;
public class TestgrafActivity extends Activity {
/** Called when the activity is first created. */
private XYMultipleSeriesDataset mDataset;
private XYMultipleSeriesRenderer mRenderer;
List<double[]> values = new ArrayList<double[]>();
private GraphicalView mChartView;
private TimeSeries time_series;
// chart container
private LinearLayout layout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
layout = (LinearLayout) findViewById(R.id.chart);
// create dataset and renderer
mDataset = new XYMultipleSeriesDataset();
mRenderer = new XYMultipleSeriesRenderer();
mRenderer.setAxisTitleTextSize(16);
mRenderer.setChartTitleTextSize(20);
mRenderer.setLabelsTextSize(15);
mRenderer.setLegendTextSize(15);
mRenderer.setPointSize(3f);
XYSeriesRenderer r = new XYSeriesRenderer();
r.setColor(Color.GREEN);
r.setPointStyle(PointStyle.CIRCLE);
r.setFillPoints(true);
mRenderer.addSeriesRenderer(r);
mRenderer.setClickEnabled(true);
mRenderer.setSelectableBuffer(20);
mRenderer.setPanEnabled(true);
time_series = new TimeSeries("test");
mDataset.addSeries(time_series);
fillData();
mChartView = ChartFactory.getTimeChartView(this, mDataset, mRenderer,
"H:mm:ss");
layout.addView(mChartView);
}
private void fillData() {
long value = new Date().getTime() - 3 * TimeChart.DAY;
for (int i = 0; i < 100; i++) {
time_series.add(new Date(value + i * TimeChart.DAY / 4), i);
}
}
}
I didn't tested the code so maybe there are some errors. Just wanted that you get the picture.
I did test at home. If you give me an email, I can send you eclipse project.
Horizontal bar chart plotting issues using achartengine
The horizontal bar chart was developed more like an experiment. This is why there are some issues with it as described here.
It also seems like you are developing against version 1.0.0. I suggest you upgraded to the latest 1.1.0 version available here.
save user data during a day (the same day - many user data)
This is an AChartEngine issue indeed. The internal model used to be kept in ArrayList
s and these issues didn't exist. At some point there was a community effort to make AChartEngine faster with a lot of data points. At that point, the model started to use a Map
instead of an ArrayList
. This implementation prevented having the same X value added several times. However, in order to fix this, I add a very small value to X, if it already exists. In your example, the first value is 20/04/2013 00:00:00.0
, the second one is at 20/04/2013 00:00:00.001
and the third is 20/04/2013 00:00:00.002
.
Now, the solution to your problem is to have a wider range on the X axis.
renderer.setXAxisMax(someDate.getTime());
where someDate
can be something like 21/04/2013
.
Related Topics
How to Call Stopservice() Method of Service Class from the Calling Activity Class
Using Onclick Attribute in Layout Xml Causes a Nosuchmethodexception in Android Dialogs
Read Contents of a Url in Android
Which View Should Be Used for New Material Design Bottom Navigation
Android Facebook Authorization - Can Not Log in When Official Facebook App Is Installed
How to Import Contacts from Phonebook to Our Application
Should Accessing Sharedpreferences Be Done Off the UI Thread
How to Set Custom Typeface to Items in Navigationview
Loading All the Images from Gallery into the Application in Android
Implicit "Submit" After Hitting Done on the Keyboard at the Last Edittext
Getting Height of Text View Before Rendering to Layout
Android: Autocomplete Textview Similar to the Facebook App
Fragment Inner Class Should Be Static
Android Datepickerdialog: Set Min and Max Date for Selection