AcharEngine making Date related graph - java

I am trying to make a plot of weight of an animal stored with soem specific date. I have Weight Class with two vars , Date and Weight.
Here is the code I am using.
else if (str.equals("Weight"))
{
mDbHelper.open();
wtArray = mDbHelper.getWeight();
mDbHelper.close();
TimeSeries diaSeries = new TimeSeries("Weight");
for ( int i =0; i <wtArray.size(); i++)
{
Weight wt = wtArray.get(i);
diaSeries.add(wt.date, wt.weight);
}
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
dataset.addSeries(diaSeries);
XYMultipleSeriesRenderer mrenderer = new XYMultipleSeriesRenderer();
XYSeriesRenderer renderer = new XYSeriesRenderer();
renderer.setColor(Color.RED);
renderer.setPointStyle(PointStyle.DIAMOND);
renderer.setFillPoints(true);
mrenderer.addSeriesRenderer(renderer);
graphLayout.addView(ChartFactory.getTimeChartView(this, dataset, mrenderer, "MM/dd/yyyy"));
}
The problem with this code is, it never shows anything on x Axis and no graph line is also displayed.
Secondly, What If I want to show data from specific date to another date? Like from Feb to March etc.?

I have used your code to build an example to compile and run for me. Please see the code below that displays a chart correctly. The code builds an Intent, so you will have to change the last line to build a View.
So, if you are really sure that you really put data into the model than you should check the layout. You are probably not adding the chart view to your layout correctly.
List<Date> wtArray = new ArrayList<Date>();
double[] weight = new double[] { 70, 71, 74, 73, 70, 71, 75, 76, 75, 73, 75, 73 };
for (int i = 0; i < 12; i++) {
wtArray.add(new Date(108, i, 1));
}
TimeSeries diaSeries = new TimeSeries("Weight");
for (int i = 0; i < wtArray.size(); i++) {
diaSeries.add(wtArray.get(i), weight[i]);
}
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
dataset.addSeries(diaSeries);
XYMultipleSeriesRenderer mrenderer = new XYMultipleSeriesRenderer();
XYSeriesRenderer renderer = new XYSeriesRenderer();
renderer.setColor(Color.RED);
renderer.setPointStyle(PointStyle.DIAMOND);
renderer.setFillPoints(true);
mrenderer.addSeriesRenderer(renderer);
return ChartFactory.getTimeChartIntent(context, dataset, mrenderer, "MM/dd/yyyy");

Related

JavaFX LineChart showing right result in one computer and wrong in other

So, we're doing a home assignment in Java and for UI i used JavaFX. So my program works, draws a linechart like a charm and no problem. When my classmate did the same thing, his didn't. Dude sent me his code, i ran it and in my computer everything was fine. What could cause something like that - linechart showing wrong in one computer and right in other?
The data is added to the chart in the same way, in my computer the data is shown in the way it's entered to the chart but in his computer it's in wrong order (the elements are sorted for some reason).
public LineChart createChart(ArrayList elements) throws PoleValitudErind{
//Elements entered or chosen, in the right order!
ArrayList fixedLst = new ArrayList();
int s = 0;
for (int i = 0; i<elements.size();i++){
s = (int) elements.get(i);
fixedLst.add(s);
}
String strStart = tf2.getText();
int intStart = 0;
try {
intStart = Integer.parseInt(strStart);
}
catch (NumberFormatException j){
throw new PoleValitudErind();
}
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
final LineChart<Number,Number> lineChart =
new LineChart<Number,Number>(xAxis,yAxis);
XYChart.Series series = new XYChart.Series();
series.setName("Radade vahetus");
//populating the series with data
series.getData().add(new XYChart.Data(intStart,0));
int counter = 1;
for (int j = 0;j<fixedLst.size();j++){
series.getData().add(new XYChart.Data(fixedLst.get(j),counter));
counter += 1;
}
//System.out.println(series.getData());
lineChart.getData().add(series);
lineChart.setMaxHeight(150);
return lineChart;
}

Showing total time in seconds on TimeSeries JFreeChart

I am using TimeSeries jfreechart to show network performance.I want to show total time passed in seconds but it showing only seconds from 0 to 59 and then reset seconds to 0 again.I have to show data for last 120 seconds.
Here is the code :
This function is used to create chart:
private JFreeChart createChart(XYDataset xydataset) {
result = ChartFactory.createTimeSeriesChart("admin0", "", "MBytes/S", xydataset, true, true, true);
TextTitle objTitle = new TextTitle("admin0", new Font("Verdana", Font.BOLD, 12));
result.setTitle(objTitle);
final XYPlot plot = result.getXYPlot();
plot.setDomainGridlinesVisible(true);
plot.setRangeGridlinesVisible(true);
plot.setBackgroundPaint(Color.WHITE);
plot.setRangeGridlinePaint(Color.GRAY);
plot.setDomainGridlinePaint(Color.GRAY);
DateAxis xaxis = (DateAxis)plot.getDomainAxis();
xaxis.setAutoRange(true); ////set true to move graph with time.
xaxis.setFixedAutoRange(120000.0);
xaxis.setTickUnit(new DateTickUnit(DateTickUnit.SECOND, 15, new SimpleDateFormat("ss")));
NumberAxis range = (NumberAxis) plot.getRangeAxis();///y-Axis
range.setRange(0.0, 1.0);
range.setTickUnit(new NumberTickUnit(0.2));
XYItemRenderer renderer = plot.getRenderer();
renderer.setSeriesPaint(0, Color.RED);
renderer.setSeriesPaint(1, Color.GREEN);
return result;
}
And here is the code for creating dataset:
private XYDataset createAdmin0DatasetTest() {
TimeSeriesCollection dataset = new TimeSeriesCollection();
try
{
if(performanceData != null)
{
long speed = 0;
double recieveRate = 0;
double sendRate = 0;
long timeinMilli = 0;
long devider = 4294967296l;
long snapTime = 0;
Vector admin0Vec = (Vector)this.performanceData.get("admin0");
if(admin0Vec != null && admin0Vec.size() > 0)
{
Vector innerVec = (Vector)admin0Vec.get(0);
recieveRate = Long.parseLong(innerVec.get(2).toString());
sendRate = Long.parseLong(innerVec.get(1).toString());
timeinMilli = Long.parseLong(innerVec.get(0).toString());
}catch(Exception ex)
{
System.out.println("Exception in adding same values");
}
for(int i = 1 ; i < admin0Vec.size() ; i++)
{
innerVec = (Vector)admin0Vec.get(i);
recieveRate = Long.parseLong(innerVec.get(2).toString());
sendRate = Long.parseLong(innerVec.get(1).toString());
timeinMilli = Long.parseLong(innerVec.get(0).toString());
try
{
this.adminRecieve.addOrUpdate(new Second(new Date(timeinMilli)), recieveRate);
this.adminSend.addOrUpdate(new Second(new Date(timeinMilli)), sendRate);
}catch(Exception ex)
{
System.out.println("Exception in adding same values");
//ex.printStackTrace();
}
}
dataset = new TimeSeriesCollection(this.adminRecieve);
dataset.addSeries(adminSend);
}
}
}catch(Exception ex)
{
ex.printStackTrace();
}
return dataset;
}
Please help me out
Hint:
You are using DateAxis for your domain axis and render it as seconds, so surely it will only display the seconds-part of the data without computing any totals. Moreover, it does not have to start at zero and will only display 120 seconds worth of data.
What you want is not a time series, i.e. numbers vs. time, but a data series of numbers vs. numbers (elapsed seconds). So construct it in that way and use NumberAxis for the domain.
Note: The above is for really showing the total elapsed time, e.g. for data between seconds 480 and 600 the labels will be for example 480, 500, 520, 540, 560, 580, 600 (i.e. total, as asked in the title, since some moment). If the question is to have static labels, e.g. -120, -100, -80, -60, -40, -20, 0, with moving data then setting ticks and labels on the axis needs to be done differently.

Creating a normal distribution graph with JFreeChart

I am trying to make a normal distribution graph using the JFreeChart library. I am successful if I try to get one area under the graph. However I did not find a way on how get 2 areas under the graph.
Here is the code for one side :
public GrafHujungKanan() {
Function2D normal = new NormalDistributionFunction2D(0.0, 1.0);
dataset = DatasetUtilities.sampleFunction2D(normal, -4, 4, 100,
"Normal");
XYSeries fLine = new XYSeries("fLine");
fLine.add(nilaiKritikal, 0);
fLine.add(4, 0);
((XYSeriesCollection) dataset).addSeries(fLine);
NumberAxis xAxis = new NumberAxis(null);
NumberAxis yAxis = new NumberAxis(null);
XYDifferenceRenderer renderer = new XYDifferenceRenderer();
xAxis.setRange(0, 5);
plot = new XYPlot(dataset, xAxis, yAxis, renderer);
chart = new JFreeChart(plot);
chart.removeLegend();
ChartPanel cp = new ChartPanel(chart);
this.add(cp);
}
Here is how it looks with the above code
And here is how I need it to look :
I already tried flipping the values with positive and negative. But instead the line of the graph turns green.
This is what I tried
public GrafDuaHujung() {
Function2D normal = new NormalDistributionFunction2D(0.0, 1.0);
dataset = DatasetUtilities.sampleFunction2D(normal, -4, 4, 100,
"Normal");
// line on right side
XYSeries fLine = new XYSeries("fLine");
fLine.add(2, 0);
fLine.add(4, 0);
((XYSeriesCollection) dataset).addSeries(fLine);
// line on left side
XYSeries dLine = new XYSeries("dLine");
dLine.add(-2, 0);
dLine.add(-4, 0);
((XYSeriesCollection) dataset).addSeries(dLine);
NumberAxis xAxis = new NumberAxis(null);
NumberAxis yAxis = new NumberAxis(null);
XYDifferenceRenderer renderer = new XYDifferenceRenderer();
xAxis.setRange(0, 5);
plot = new XYPlot(dataset, xAxis, yAxis, renderer);
chart = new JFreeChart(plot);
chart.removeLegend();
ChartPanel cp = new ChartPanel(chart);
this.add(cp);
}
Thank you for your answer.
You can use multiple datasets.
public GrafDuaHujung() {
Function2D normal = new NormalDistributionFunction2D(0.0, 1.0);
dataset = DatasetUtilities.sampleFunction2D(normal, -4, 4, 100, "Normal");
dataset2 = DatasetUtilities.sampleFunction2D(normal, -4, 4, 100, "Normal"); //New
// line on right side
XYSeries fLine = new XYSeries("fLine");
fLine.add(2, 0);
fLine.add(4, 0);
((XYSeriesCollection) dataset).addSeries(fLine);
// line on left side
XYSeries dLine = new XYSeries("dLine");
dLine.add(-2, 0);
dLine.add(-4, 0);
((XYSeriesCollection) dataset2).addSeries(dLine); //Changed
XYDifferenceRenderer renderer = new XYDifferenceRenderer();
plot = new XYPlot(); //New
plot.setDataset(0, dataset); //New
plot.setDataset(1, dataset2); //New
plot.setRenderer(renderer); //New
chart = new JFreeChart(plot);
chart.removeLegend();
ChartPanel cp = new ChartPanel(chart);
this.add(cp);
}

create bar chart by accessing data from 2 .csv files

.csv file 1 data:
sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line
HTTP Request1, 750 ,26339 ,22644 , 40210
HTTP Request2, 750 ,8280 ,4781 ,21016
.csv file 2 data:
sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line
HTTP Request1, 350 ,2539 ,2224 , 48410
HTTP Request4, 350 ,8736 ,9285 ,38217
I want to display bar graph, which should depict values of average from both files for each sampler label.
Here there are 2 average values in each file. there may be n number of values. in bar graph i want to display values of file 1 and file 2 in one graph only.
Please help me....
public JFreeChart createBarChartFromCSV() {
csv csvReader = new csv();
List<String[]> csvData1 = null;
List<String[]> csvData2 = null;
int indexOfAverage1 = 0;
int indexOfAverage2 = 0;
csvData1 = csvReader.getDataFromCSV1(csv.CSVFILENAME1);
csvData2 = csvReader.getDataFromCSV2(csv.CSVFILENAME2);
for(String[] columnArray : csvData1)
for(int i = 0; i< columnArray.length; i++)
if(columnArray[i].equalsIgnoreCase("average")){
enter code here
indexOfAverage1 = i;
break;
}
if(indexOfAverage1 == 0){
System.err.println("Error retrieving data from CSV File1 !!");
System.exit(0);
}
for(String[] columnArray : csvData2)
for(int j = 0; j< columnArray.length; j++)
if(columnArray[j].equalsIgnoreCase("average")){
indexOfAverage2 = j;
break;
}
if(indexOfAverage2 == 0){
System.err.println("Error retrieving data from CSV File2 !!");
System.exit(0);
}
JFreeChart barChart = generateBarChart(csvData1,csvData2, indexOfAverage1,indexOfAverage2);
return barChart;
}
private JFreeChart generateBarChart(List<String[]> csvData1,List<String[]> csvData2, int columnIndex1, int columnIndex2){
DefaultCategoryDataset dataSet = new DefaultCategoryDataset();
final String YAXIS_NAME = csvData1.get(0)[columnIndex1]; //value returned is "average"
final String XAXIS_NAME = csvData1.get(0)[0]; //value returned is "sampler_label"
for(int i = 1; i < csvData1.size() - 1; i++){
long averageValue1 = Long.parseLong(csvData1.get(i)[columnIndex1]);
String columnKey1 = csvData1.get(i)[0];
dataSet.setValue(averageValue1, YAXIS_NAME, columnKey1); // plot the graph
}
for(int j = 1; j< csvData2.size() - 1; j++){
long averageValue2 = Long.parseLong(csvData2.get(j)[columnIndex2]);
String columnKey2 = csvData2.get(j)[0];
dataSet.setValue(averageValue2, YAXIS_NAME, columnKey2); // plot the graph
}
System.out.println("created");
JFreeChart chart = ChartFactory.createBarChart("Comparison between the average of 2 values", XAXIS_NAME, YAXIS_NAME, dataSet, PlotOrientation.VERTICAL, true, true, false);
final CategoryPlot plot = chart.getCategoryPlot();
chart.setBackgroundPaint(Color.white);
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
BarRenderer renderer=new BarRenderer();
System.out.print( "set the range axis to display integers only...");
final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
System.out.print( "disable bar outlines...");
renderer = (BarRenderer) plot.getRenderer();
renderer.setDrawBarOutline(false);
renderer.setMaximumBarWidth(0.10);
System.out.print( "set up gradient paints for series...");
final GradientPaint gp0 = new GradientPaint(
0.0f, 0.0f, Color.blue,
0.0f, 0.0f, Color.lightGray
);
final GradientPaint gp1 = new GradientPaint(
0.0f, 0.0f, Color.green,
0.0f, 0.0f, Color.lightGray
);
renderer.setSeriesPaint(0, gp0);
renderer.setSeriesPaint(1, gp1);
return chart;
}

Are multiple stacked Bar charts possible using Achartengine?

I tried adding another set of values to the demo example of stacked bar charts with achartengine, but the new values introduced by me don't appear on the chart. Is Stacking bars limited to two bars?
public Intent getIntent(Context context) {
String[] titles = new String[] { "Good", "Defect", "Repair" };
List<double[]> values = new ArrayList<double[]>();
values.add(new double[] { 14230, 12300, 1424, 15240, 15900, 19200,
22030, 21200, 19500, 15500, 12060, 14000 });
values.add(new double[] { 14230, 12300, 14240, 15244, 15900, 19200,
22030, 21200, 19500, 15500, 12600, 14000 });
values.add(new double[] { 5230, 7300, 9240, 10540, 7900, 9200, 12030,
11200, 9500, 10500, 11600, 13500 });
int[] colors = new int[] { Color.GREEN, Color.YELLOW, Color.RED };
XYMultipleSeriesRenderer renderer = buildBarRenderer(colors);
setChartSettings(renderer, "Machine Efficiency Rates",
"Machine", "NET produce", 0.5, 12.5, 0, 24000, Color.GRAY,
Color.LTGRAY);
renderer.getSeriesRendererAt(0).setDisplayChartValues(true);
renderer.getSeriesRendererAt(1).setDisplayChartValues(true);
renderer.getSeriesRendererAt(2).setDisplayChartValues(true);
renderer.setXLabels(12);
renderer.setYLabels(5);
renderer.setXLabelsAlign(Align.LEFT);
renderer.setYLabelsAlign(Align.LEFT);
renderer.setPanEnabled(true, false);
renderer.setZoomEnabled(true);
renderer.setZoomRate(1.1f);
renderer.setBarSpacing(0.5f);
return ChartFactory.getBarChartIntent(context,
buildBarDataset(titles, values), renderer, Type.STACKED);
}
There is a misunderstanding in the way AChartEngine displays stacked bar charts. It doesn't really stack them, but displays them one over the other. This means that you will want to always add the bigger values first then the smaller and so on as it renders the first series, the second one above the first and so on.
UPDATE: As of version 1.2.0, there is the new HEAP stacked bar charts, which are displayed in the manner you need.
I could not find a good answer. However, you can use the getCombinedXYChartIntent
to create a multiple stacked bars.
I use the CombinedTemperatureChart as a template and modified to achieve this.
The initial raw code is this
package org.achartengine.chartdemo.demo.chart;
import java.util.ArrayList;
import java.util.List;
import org.achartengine.ChartFactory;
import org.achartengine.chart.BarChart;
import org.achartengine.chart.BubbleChart;
import org.achartengine.chart.CubicLineChart;
import org.achartengine.chart.LineChart;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.model.XYValueSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Paint.Align;
/**
* Combined temperature demo chart.
*/
public class CombinedTemperatureChart extends AbstractDemoChart {
/**
* Returns the chart name.
*
* #return the chart name
*/
public String getName() {
return "Combined temperature";
}
/**
* Returns the chart description.
*
* #return the chart description
*/
public String getDesc() {
return "The average temperature in 2 Greek islands, water temperature and sun shine hours (combined chart)";
}
/**
* Executes the chart demo.
*
* #param context the context
* #return the built intent
*/
public Intent execute(Context context) {
String[] titles = new String[] { "Crete Air Temperature", "Skiathos Air Temperature" };
List<double[]> x = new ArrayList<double[]>();
for (int i = 0; i < titles.length; i++) {
x.add(new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 });
}
List<double[]> values = new ArrayList<double[]>();
values.add(new double[] { 12.3, 12.5, 13.8, 16.8, 20.4, 24.4, 26.4, 26.1, 23.6, 20.3, 17.2, 13.9 });
values.add(new double[] { 9, 10, 11, 15, 19, 23, 26, 25, 22, 18, 13, 10 });
int[] colors = new int[] { Color.GREEN, Color.rgb(200, 150, 0) };
PointStyle[] styles = new PointStyle[] { PointStyle.CIRCLE, PointStyle.DIAMOND };
XYMultipleSeriesRenderer renderer = buildRenderer(colors, styles);
//renderer.setPointSize(5.5f);
int length = renderer.getSeriesRendererCount();
for (int i = 0; i < length; i++) {
XYSeriesRenderer r = (XYSeriesRenderer) renderer.getSeriesRendererAt(i);
r.setDisplayChartValues(true);
r.setChartValuesTextSize(25);
//r.setLineWidth(2);
r.setFillPoints(true);
}
setChartSettings(renderer, "Weather data", "Month", "Temperature", -1, 12.5, 0, 40,
Color.LTGRAY, Color.LTGRAY);
renderer.setXLabels(12);
renderer.setYLabels(10);
renderer.setShowGrid(true);
renderer.setXLabelsAlign(Align.RIGHT);
renderer.setYLabelsAlign(Align.RIGHT);
renderer.setZoomButtonsVisible(true);
renderer.setPanLimits(new double[] { -10, 20, -10, 40 });
renderer.setZoomLimits(new double[] { -10, 20, -10, 40 });
XYValueSeries sunSeries = new XYValueSeries("Sunshine hours");
sunSeries.add(0.5, 17);
sunSeries.add(1.5, 18);
sunSeries.add(2.5, 19);
sunSeries.add(3.5, 19);
sunSeries.add(4.5, 20.8);
sunSeries.add(5.5, 24.9);
sunSeries.add(6.5, 26);
sunSeries.add(7.5, 27.8);
sunSeries.add(8.5, 28.4);
sunSeries.add(9.5, 25.5);
sunSeries.add(10.5, 23.5);
sunSeries.add(11.5, 19.5);
XYSeriesRenderer lightRenderer = new XYSeriesRenderer();
lightRenderer.setColor(Color.YELLOW);
XYSeries waterSeries = new XYSeries("Water Temperature");
waterSeries.add(0.5, 16);
waterSeries.add(1.5, 15);
waterSeries.add(2.5, 16);
waterSeries.add(3.5, 17);
waterSeries.add(4.5, 20);
waterSeries.add(5.5, 23);
waterSeries.add(6.5, 25);
waterSeries.add(7.5, 25.5);
waterSeries.add(8.5, 26.5);
waterSeries.add(9.5, 24);
waterSeries.add(10.5, 22);
waterSeries.add(11.5, 18);
renderer.setBarSpacing(2);
renderer.setBarWidth(2);
XYSeriesRenderer waterRenderer = new XYSeriesRenderer();
waterRenderer.setColor(Color.argb(250, 0, 210, 250));
XYMultipleSeriesDataset dataset = buildDataset(titles, x, values);
dataset.addSeries(0, sunSeries);
dataset.addSeries(1, waterSeries);
renderer.setBarWidth(0.5f);
renderer.addSeriesRenderer(lightRenderer);
renderer.addSeriesRenderer(waterRenderer);
waterRenderer.setDisplayChartValues(true);
waterRenderer.setChartValuesTextSize(25);
lightRenderer.setDisplayChartValues(true);
lightRenderer.setChartValuesTextSize(25);
String[] types = new String[] { BarChart.TYPE, BarChart.TYPE, BarChart.TYPE, BarChart.TYPE };
Intent intent = ChartFactory.getCombinedXYChartIntent(context, dataset, renderer, types,
"Weather parameters");
return intent;
}
}
I hope someone still need this, it take a some time figure it out.
Unfortunately, I don't have the points to paste an image.

Categories