I'm trying to create a graph for each user that is added into my app. This graph will display the day in this format 21 Dec 2012 on the x-axis and numbers from 30 to 30000. Say this is day 1, the user adds their calorie per hour burn rate and I want that info put into the graph. The next day, I want them to be able to calculate their calorie per hour rate and store that into the graph as well. Sort of like appending it to the graph.
public class Graph extends Activity{
private XYMultipleSeriesDataset mDataset;
private XYMultipleSeriesRenderer mRenderer;
List<double[]> values = new ArrayList<double[]>();
private GraphicalView mChartView;
private TimeSeries time_series;
String gotCal;
Double[] thisDou;
Double convert;
Date date;
// chart container
private LinearLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
layout = (LinearLayout) findViewById(R.id.chart);
SharedPreferences calStuff = getSharedPreferences("Calories", 0);
if (calStuff != null) {
gotCal = calStuff.getString("This Cal", null);
System.out.println(gotCal);
}
convert = Double.parseDouble(gotCal);
// 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.setFillPoints(true);
r.setPointStyle(PointStyle.DIAMOND);
//r.fillPoints(true);
r.setFillBelowLine(true);
mRenderer.addSeriesRenderer(r);
mRenderer.setZoomButtonsVisible(true);
mRenderer.setXTitle("Date");
mRenderer.setYTitle("Calories Burned Per Hour");
//mRenderer.setClickEnabled(true);
r.setDisplayChartValues(true);
mRenderer.setSelectableBuffer(20);
mRenderer.setApplyBackgroundColor(true);
mRenderer.setBackgroundColor(Color.BLACK);
mRenderer.setGridColor(Color.CYAN);
//mRenderer.setChartTitle("LOOOOOL");
//mRenderer.setYLabels(12);
mRenderer.setPanEnabled(true, true);
//mRenderer.setPanEnabled(true);
time_series = new TimeSeries("test");
mDataset.addSeries(time_series);
fillData();
//time_series.add(date, Double.parseDouble(gotCal));
mChartView = ChartFactory.getTimeChartView(this, mDataset, mRenderer,
"dd MMM yyyy");
if (mChartView == null)
mChartView.repaint();
layout.addView(mChartView);
}
private void fillData() {
long value = new Date().getTime() - 3 * TimeChart.DAY;
for (int i = 0; i < gotCal.length(); i += convert) {
//date = new Date(value + i * TimeChart.DAY / 31);
time_series.add(new Date(value + i * TimeChart.DAY / 20), i);
}
}
It only works for one user, so when I try to access the graph from a different user which has different info, there's no graph, why is that? Also, how can I save the graph specifically to that user? Any help is highly appreciated, thank you.
Related
I have a bar graph where I basically limit my screen to 12 bars, however, because the values are small, I want to allow users to zoom in to see the values better. What happens is the following, if my last bar of the graph is not visible, then, no bar is visible, however, if the last bar is in the frame, then the zoom works normal and the graph does not disappear.
See some examples in these images, first, the full normal chart:
Standard Graph
All Still visible
Now, I'm going to zoom in on my graph a little bit, notice that the labels start to disappear as the last bar is out of view:
Labels auto hide on zoom in
At that moment, if I zoom in to the point that the last bar leaves the view, the whole graph disappears from the view, no bar is displayed for me, it will only be displayed again if my last bar returns to view:
All bar hide now
My important code quotes:
XAxis xAxis = barsWeight.getXAxis(); // barsWeight is BarChart
xAxis.setPosition(XAxis.XAxisPosition.TOP);
xAxis.setDrawGridLines(false);
xAxis.setGranularity(0f);
xAxis.setLabelCount(11);
xAxis.setAxisMinimum(0f);
ArrayList<String> monthList= new ArrayList<>();
monthList.add("JAN");
monthList.add("FEV");
monthList.add("MAR");
monthList.add("ABR");
monthList.add("MAI");
monthList.add("JUN");
monthList.add("JUL");
monthList.add("AGO");
monthList.add("SET");
monthList.add("OUT");
monthList.add("NOV");
monthList.add("DEZ");
xAxis.setValueFormatter(new IndexAxisValueFormatter(monthList));
Basically what I do in addition is to add a Bar Data to my Bar Chart, my Bar Data contains a single Bar Data Set that contains an array of BarEntry
Any suspicion as to why the visualization disappears if the last bar entry is not visible in the graph?
Add data:
private void setDataBar( ArrayList<BarEntry> dadosPeso, BarChart barrasGraf, boolean isKg){
BarDataSet barDataSet;
if(barrasGraf.getData() != null && barrasGraf.getData().getDataSetCount() > 0){
barDataSet = (BarDataSet) barrasGraf.getData().getDataSetByIndex(0);
barDataSet.setValues(dadosPeso);
barDataSet.setColors(ColorTemplate.JOYFUL_COLORS);
if(isKg){
barrasGraf.getBarData().setValueFormatter(new IndexAxisValueFormatter() {
#Override
public String getFormattedValue(float value) {
DecimalFormat df = new DecimalFormat("#.##");
return df.format(value) + " Kg";
}
});
}else{
barrasGraf.getBarData().setValueFormatter(new IndexAxisValueFormatter() {
#Override
public String getFormattedValue(float value) {
DecimalFormat df = new DecimalFormat("#.##");
return df.format(value) + " #";
}
});
}
barrasGraf.getData().notifyDataChanged();
barrasGraf.notifyDataSetChanged();
}else{
barDataSet = new BarDataSet(dadosPeso, "Pesagens para cada data");
barDataSet.setColors(ColorTemplate.JOYFUL_COLORS);
barDataSet.setDrawIcons(false);
ArrayList<IBarDataSet> dataSets = new ArrayList<>();
dataSets.add(barDataSet);
BarData dadosBarra = new BarData(dataSets);
dadosBarra.setValueTextSize(15f);
dadosBarra.setValueTextColor(Color.BLACK);
if(isKg) {
dadosBarra.setValueFormatter(new IndexAxisValueFormatter() {
#Override
public String getFormattedValue(float value) {
DecimalFormat df = new DecimalFormat("#.##");
return df.format(value) + " Kg";
}
});
}else{
dadosBarra.setValueFormatter(new IndexAxisValueFormatter() {
#Override
public String getFormattedValue(float value) {
DecimalFormat df = new DecimalFormat("#.##");
return df.format(value) + " #";
}
});
}
dadosBarra.setBarWidth(.9f);
barrasGraf.setData(dadosBarra);
}
}
I have a Barchart with 4 bars which are grouped into 2 groups using MPAndroidChart library.
This works so far. Now i want to display a title above each group. This is my current output (as you can see, the titles are not showed above each group).
My code:
_overviewBarChart.setPinchZoom(false);
_overviewBarChart.getDescription().setEnabled(false);
_overviewBarChart.setDrawValueAboveBar(true);
_overviewBarChart.getXAxis().setCenterAxisLabels(true);
_overviewBarChart.getXAxis().setAxisMinimum(0);
_overviewBarChart.getXAxis().setDrawGridLines(false);
private void updateOverviewBarChart() {
//Init calorie needs bars
BarEntry todayCalorieNeedsBarEntry = new BarEntry(0, _calorieEntry.getTarget());
BarEntry yesterdayCalorieNeedsBarEntry = new BarEntry(0, 0);
if (_yesterdayCalorieEntry != null)
yesterdayCalorieNeedsBarEntry = new BarEntry(0, _yesterdayCalorieEntry.getTarget());
ArrayList<BarEntry> calorieNeedsBarEntries = new ArrayList<>();
calorieNeedsBarEntries.add(todayCalorieNeedsBarEntry);
calorieNeedsBarEntries.add(yesterdayCalorieNeedsBarEntry);
//Init consumed calories bars
BarEntry todayConsumedCaloriesBarEntry = new BarEntry(1, _calorieEntry.getConsumed());
BarEntry yesterdayConsumedCaloriesBarEntry = new BarEntry(1, 0);
if (_yesterdayCalorieEntry != null)
yesterdayConsumedCaloriesBarEntry = new BarEntry(1, _yesterdayCalorieEntry.getConsumed());
ArrayList<BarEntry> consumedCaloriesBarEntries = new ArrayList<>();
consumedCaloriesBarEntries.add(todayConsumedCaloriesBarEntry);
consumedCaloriesBarEntries.add(yesterdayConsumedCaloriesBarEntry);
//Init BarDataSets
BarDataSet calorieNeedsBarDataSet = new BarDataSet(calorieNeedsBarEntries, getString(R.string.fragment_main_calorieneeds));
calorieNeedsBarDataSet.setColor(Color.parseColor("#26A69A"));
BarDataSet consumedCaloriesBarDataSet = new BarDataSet(consumedCaloriesBarEntries, getString(R.string.fragment_main_consumed));
consumedCaloriesBarDataSet.setColor(Color.parseColor("#E53935"));
//Init BarData, group BarEntrys, set group titles
BarData barData = new BarData(calorieNeedsBarDataSet, consumedCaloriesBarDataSet);
barData.setValueTextSize(14);
barData.setBarWidth(0.2f);
barData.groupBars(0, 0.15f, 0.1f);
ArrayList<String> groupTitles = new ArrayList<String>();
groupTitles.add(getString(R.string.fragment_main_today));
groupTitles.add(getString(R.string.fragment_main_yesterday));
_overviewBarChart.getXAxis().setValueFormatter(new IndexAxisValueFormatter(groupTitles));// new BarChartStringFormatter(groupTitles));
//Set data, redraw BarChart
_overviewBarChart.setData(barData);
_overviewBarChart.invalidate();
}
Can you see what i'm doing wrong?
Finally i found the solution for my problem.
First you have to add this two lines of code (note: The parameters can vary for your requirements):
_overviewBarChart.getXAxis().setGranularity(1f);
_overviewBarChart.getXAxis().setAxisMaximum(2);
My mistake was that the default XAxis is to finely granulated (0.1, 0.2, 0.3 ...). So IndexAxisValueFormatter applies the group title to each XAxis step. setGranularity resolves this. Finally setAxisMaximum is used to restrict the amount of steps on the XAxis (previous was 3 so the title showed 3 times).
And then change...
barData.groupBars(0, 0.15f, 0.1f);
to this (note: The parameters can vary for your requirements)..
barData.groupBars(0, 0.45f, 0.1f);
Result:
I am having some problem when trying to populate data to line chart using ACHartEngine library in Android. Basically I am trying to create a line chart with x-axis from Jan-Dec no matter the amount of the particular month:
As from the x-axis, there is Jan - Dec although some of the months were with 0 amount. My problem now is I only managed to plot a graph with the months with amount. Let's say currently my database have these records:
So basically my graph will only have Jun, Aug and Sep instead of Jan - Dec.
Here is how I set up my line chart:
private void openTotalMonthlyChart() {
int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
// Creating an XYSeries for Expenses
XYSeries expensesSeries = new XYSeries("Expenses");
// Adding data to Expense Series
for (int i = 0; i < trans_list.size(); i++) {
expensesSeries.add(x[i], trans_list.get(i).getAmount());
}
// Creating a dataset to hold each series
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
// Adding Expenses Series to the dataset
dataset.addSeries(expensesSeries);
// Creating XYSeriesRenderer to customize expensesSeries
XYSeriesRenderer expensesRenderer = new XYSeriesRenderer();
expensesRenderer.setColor(Color.rgb(124, 181, 236));
expensesRenderer.setPointStyle(PointStyle.CIRCLE);
expensesRenderer.setFillPoints(true);
expensesRenderer.setLineWidth(2);
expensesRenderer.setDisplayChartValues(true);
// Creating a XYMultipleSeriesRenderer to customize the whole chart
XYMultipleSeriesRenderer multiRenderer = new XYMultipleSeriesRenderer();
multiRenderer.setXLabels(0);
multiRenderer.setChartTitle("Total Monthly Expenses");
multiRenderer.setXTitle("");
multiRenderer.setYTitle("Amount");
multiRenderer.setZoomButtonsVisible(true);
for (int j = 0; j < trans_list.size(); j++) {
multiRenderer.addXTextLabel(j + 1, trans_list.get(j).getDate());
}
multiRenderer.addSeriesRenderer(expensesRenderer);
// Get the component from XML file
RelativeLayout chartContainer = (RelativeLayout) totalMonthlyView
.findViewById(R.id.chart_totalMonthly);
// Creating a Line Chart
chartOverall = ChartFactory.getLineChartView(getActivity(), dataset,
multiRenderer);
// Adding the Line Chart to the RelativeLayout
chartContainer.addView(chartOverall);
}
And my database SQL statement which return the data as the second image above:
public ArrayList<TransactionRecModel> getTotalMonthly() {
try {
String sql = "SELECT SUM(amount) AS total, SUBSTR(date,4,2) AS Month FROM transactionRec WHERE type = 'W' GROUP BY Month";
Cursor mCur = mDb.rawQuery(sql, null);
Log.e(TAG, "Data Grab RECORD Success");
if (mCur.getCount() != 0) {
if (mCur.moveToFirst()) {
do {
TransactionRecModel trm = new TransactionRecModel();
trm.setAmount(mCur.getInt(mCur.getColumnIndex("total")));
trm.setDate(mCur.getString(mCur.getColumnIndex("Month")));
transList.add(trm);
} while (mCur.moveToNext());
}
}
return transList;
} catch (SQLException mSQLException) {
throw mSQLException;
}
}
I wonder is there any way to do this? Thanks in advance and sorry for my poor grammar.
You can use MathHelper.NULL_VALUE for the values that you want to be skipped. See the sensor values chart AChartEngine example to see how to do this.
How exclude one or two day from jfreechart? I have input date without saturday and chart without saturday, but in axis there all date.
I have all added item on screen. How viewing <= 100 item on screen and if scrolling to right item add more.
UPDATE:
I make CandleChart, used JfreeChart library.
Between 12 and 14 days chart should not be interrupted.
This is string:
One or few day is maybe off-time.
12.10.2012 19:00 1.2951 1.296 1.2947 1.2956
12.10.2012 20:00 1.2956 1.296 1.295 1.2954
**12.10.2012 21:00 1.2955 1.2959 1.2948 1.2949**
**14.10.2012 22:00 1.2952 1.296 1.2948 1.2953**
14.10.2012 23:00 1.2955 1.2955 1.2942 1.2947
This is code:
static TimeSeries t1 = new TimeSeries("");
RegularTimePeriod day = new Day();
RegularTimePeriod hour = new Hour();
private static OHLCDataset createPriceDataset(String FILENAME_SD)
{
OHLCSeries s1 = new OHLCSeries(FILENAME_SD);
if (!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
}
File sdPath = Environment.getExternalStorageDirectory();
sdPath = new File(sdPath.getAbsolutePath() + "/" + DIR_SD);
File sdFile = new File(sdPath, FILENAME_SD);
try {
BufferedReader in = new BufferedReader(new FileReader(sdFile));
DateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm");
String inputLine;
in.readLine();
while ((inputLine = in.readLine()) != null) {
String[] data = inputLine.split("\\s+");
Date date = df.parse(data[0] + " " + data[1]);
double open = Double.parseDouble( data[2] );
double high = Double.parseDouble( data[3] );
double low = Double.parseDouble( data[4] );
double close = Double.parseDouble( data[5] );
// double volume = Double.parseDouble( st.nextToken() );
//double adjClose = Double.parseDouble( st.nextToken() );
s1.add(new Hour(date), open, high, low, close);
t1.add(new Hour(date), open);
}
in.close();
}
catch (Exception e) {
e.printStackTrace();
}
OHLCSeriesCollection dataset = new OHLCSeriesCollection();
dataset.addSeries(s1);
return dataset;
}
Also, diagram zoom depends on how mach string in file. How drawing candles no more than 100 on screen?
This is chart from file with many strings:
This is chart from file with few strings:
If it's particularly candlestick you want to do this with, I do not believe that JFreechart class supports it. You could use Box And Whisker to imitate the behavior while using category based data. For the charts you've shown the axis represents continuous data, categorical axis are for discrete data.
Example code is shown here:
http://www.java2s.com/Code/Java/Chart/JFreeChartBoxAndWhiskerDemo.htm
With that you can choose your own discrete points to be represented on the graph.
If it's for anything other than candlesticks, Graham was right and DefaultCategoryDataset would be more useful:
http://www.jfree.org/jfreechart/api/javadoc/org/jfree/data/category/DefaultCategoryDataset.html
I've created a timetable app, which allows the user to enter data and then view it.However if the user enters an entry, on a day and time where there already is one, my emulator crashes(forces a close).
Basically I'm pulling back data to a linear layout- which contains 10 TextViews, each representing the times 9-15.
Here's the code:
public void addMondayGrid() {
// TODO Auto-generated method stub
for (int index = 0; index < info.mon.size(); index++) {
// int entryId = info.monIds.get(index);
int time = info.monTimes.get(index);
int id = info.monIds.get(index);
int duration = info.monDuration.get(index);
String dayOfWeek = "mon";
timeId = getResources().getIdentifier("mon" + time, "id",
getPackageName());
if (duration == 1) {
SpannableString text = new SpannableString(info.mon.get(index));
setEntryColour(text);
final TextView textV = (TextView) findViewById(timeId);
textV.setTextSize(10);
textV.setText(text, BufferType.SPANNABLE);
textV.setId(id);
deleteGridEntry(textV);
} else {
longerDuration(time, index, id, info.mon, dayOfWeek);
}
}
}
The thing is is works fine as long as there isn't two entries for the same day and time, eg. monday at 9 oclock.
Anyone have any ideas?I'm quite new to this and any help would be much appreciated!
I have to reference the id this way as there are too many ids to reference any other way,is there not a simple way to overwrite the old textView with new data pulled back from the database? I want the id to be the same one as that is the textView I want to deal with, but it just keeps crashing, is it something to do with instances?
change:
final TextView textV = (TextView) findViewById(timeId);
to:
final TextView textV = (TextView) findViewById(R.id.timeId);