I am working on two different charts, one is a RadarChart that compares the scores of all "categories" in an "assessment" to other "assessments", and a grouped BarChart that allows the user to select "categories" in an "assessment" and compare them to other "assessments". The data is pulled from Firebase and the DatabaseReferences are stored in an ArrayList. My RadarChart uses the following code and displays the following result:
ArrayList<RadarDataSet> dataSets = new ArrayList<>();
ArrayList<IRadarDataSet> allDataSets = new ArrayList<>();
for(int i = 0; i < assessmentKeys.size(); i++) {
final ArrayList<RadarEntry> radarEntries = new ArrayList<>();
final int trackerIndex = i;
dataSets.add(trackerIndex, new RadarDataSet(radarEntries, assessmentName.get(i)) );
mAssessmentCategoryRefs.get(i).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
for(DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Category category = postSnapshot.getValue(Category.class);
radarEntries.add(new RadarEntry((float)category.getCategoryScore(), category.getNumber() - 1));
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Random random = new Random();
int randomR = random.nextInt(256);
int randomG = random.nextInt(256);
int randomB = random.nextInt(256);
dataSets.get(trackerIndex).setColor(Color.rgb(randomR, randomG, randomB));
dataSets.get(trackerIndex).setFillColor(Color.rgb(randomR, randomG, randomB));
dataSets.get(trackerIndex).setDrawFilled(true);
allDataSets.add(dataSets.get(trackerIndex));
}
RadarData data = new RadarData(allDataSets);
Because RadarEntry, BarEntry, BarDataSet, RadarDataSet, IBarDataSet, and IRadarDataSet all share parent classes between them, I assumed that I would be able to load data into a grouped BarChart in the same manner that I did with the RadarChart. For a proof of concept, I used the following code to verify that it will work before attempting to pull from Firebase:
final ArrayList<BarDataSet> dataSets = new ArrayList<>();
ArrayList<IBarDataSet> allDataSets = new ArrayList<>();
for(int j = 0; j < assessmentKeys.size(); j++ ) {
final int jTracker = j;
final ArrayList<BarEntry> entries = new ArrayList<>();
dataSets.add(j, new BarDataSet(entries, assessmentName.get(j)));
Log.d("Received_Data", "Getting data for " + assessmentName.get(j));
for(int k = 0; k < categoryNames.size(); k++) {
entries.add(new BarEntry(k, k+1));
}
Random random = new Random();
int randomR = random.nextInt(256);
int randomG = random.nextInt(256);
int randomB = random.nextInt(256);
dataSets.get(j).setColor(Color.rgb(randomR, randomG, randomB));
allDataSets.add(dataSets.get(j));
}
This produced this chart:
When I add code to pull from firebase, something weird happens that does not happen with the RadarChart:
final ArrayList<BarDataSet> dataSets = new ArrayList<>();
ArrayList<IBarDataSet> allDataSets = new ArrayList<>();
for(int j = 0; j < assessmentKeys.size(); j++ ) {
final int jTracker = j;
final ArrayList<BarEntry> entries = new ArrayList<>();
dataSets.add(j, new BarDataSet(entries, assessmentName.get(j)));
Log.d("Received_Data", "Getting data for " + assessmentName.get(j));
for(int k = 0; k < categoryNames.size(); k++) {
final String categoryName = categoryNames.get(k);
final int kTracker = k;
mAssessmentCategoryRefs.get(jTracker).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
for(DataSnapshot postSnapShot : dataSnapshot.getChildren()) {
Category category = postSnapShot.getValue(Category.class);
if(categoryName.equals(category.getName())) {
entries.add(new BarEntry(kTracker, (float)category.getCategoryScore()));
Log.d(TAG, "Added " + category.getName() + " to entries");
} else {
Log.d(TAG, "Skipped " + category.getName());
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Random random = new Random();
int randomR = random.nextInt(256);
int randomG = random.nextInt(256);
int randomB = random.nextInt(256);
dataSets.get(j).setColor(Color.rgb(randomR, randomG, randomB));
allDataSets.add(dataSets.get(j));
}
BarData data = new BarData(allDataSets);
mBarChart.setData(data);
data.notifyDataChanged();
mBarChart.notifyDataSetChanged();
mBarChart.invalidate();
The data is not charted, even though my logs show that it correctly skips categories that dont match a selected name and adds the category's score if it does.
What is the cause of this? At first I thought that it may be due to the async nature of the data being pulled from firebase, but if that were the case, my RadarChart would experience the same issue. As far as I can tell the only real difference between RadarEntry and BarEntry is that the index is the second argument in a RadarEntry but the first in a BarEntry.The entries are loaded into the DataSet in the same manner, the DataSets are loaded into the ArrayList<IBarDataSet> in the same manner, yet for some reason one works and the other does not. Does anyone know what the issue is? Is this a bug with MPAndroidChart's explicit BarEntry?
I found a work around. First, I had to create an initialization method that is called in onCreate():
private Map<String, Map<String, Float>> assessmentData = new HashMap<>();
private void initAssessmentData() {
for(int i = 0; i < assessmentKeys.size(); i++) {
final Map<String, Float> categoryNameScore = new HashMap<>();
mAssessmentCategoryRefs.get(i).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
for(DataSnapshot postSnapShot : dataSnapshot.getChildren()) {
Category category = postSnapShot.getValue(Category.class);
categoryNameScore.put(category.getName(), (float) category.getCategoryScore());
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
assessmentData.put(assessmentKeys.get(i), categoryNameScore);
}
}
Then to put the data into the graph I just had to change my code to this:
final ArrayList<BarDataSet> dataSets = new ArrayList<>();
ArrayList<IBarDataSet> allDataSets = new ArrayList<>();
final BarData data = new BarData(allDataSets);
for(int j = 0; j < assessmentKeys.size(); j++ ) {
final int jTracker = j;
final ArrayList<BarEntry> entries = new ArrayList<>();
dataSets.add(j, new BarDataSet(entries, assessmentName.get(j)));
Log.d("Received_Data", "Getting data for " + assessmentName.get(j));
for(String key : assessmentData.keySet()) {
if(key.equals(assessmentKeys.get(j))) {
Map<String, Float> categoryData = assessmentData.get(key);
for(String key2 : categoryData.keySet()) {
if(categoryNames.contains(key2)) {
entries.add(new BarEntry(categoryNames.indexOf(key2), categoryData.get(key2)));
}
}
}
}
Random random = new Random();
int randomR = random.nextInt(256);
int randomG = random.nextInt(256);
int randomB = random.nextInt(256);
dataSets.get(j).setColor(Color.rgb(randomR, randomG, randomB));
allDataSets.add(dataSets.get(j));
data.notifyDataChanged();
mBarChart.notifyDataSetChanged();
mBarChart.invalidate();
Related
I want to display my CountValue from the database given below in a piechart. I saved the CountValue in an ArrayList finalCount and I dont know why am I getting the last value only of the arrayList in the piechart and not all the value.
Here's my code
for (QueryDocumentSnapshot snapshot : Objects.requireNonNull(task.getResult())) {
String value1 = snapshot.getString("QuestionName");
q_tv1.setText("Poll: " + value1);
ArrayList<String> CountValue = (ArrayList<String>) snapshot.get("CountValue");
Log.d(Tag, "output for des: " + CountValue);
List<String> noOfOptions = (List<String>) snapshot.get("Options");
Log.d(Tag, "output for option: " + noOfOptions);
ArrayList<String> finalCount=(ArrayList<String>) snapshot.get("CountValue");
int size = noOfOptions.size();
Log.d(Tag, "size: " + size);
for (int i = 0; i <= size-1; i++) {
String op = noOfOptions.get(i);
String n = finalCount.get(i);
n1 = Integer.parseInt(String.valueOf(n));
Log.d(Tag, "i->>: " + n1);
ArrayList<PieEntry> visitors = new ArrayList<>();
visitors.add(new PieEntry(n1, op));
PieDataSet pieDataSet = new PieDataSet(visitors, "Answer");
pieDataSet.setColors(ColorTemplate.COLORFUL_COLORS);
pieDataSet.setValueTextColor(Color.BLACK);
pieDataSet.setValueTextSize(16f);
PieData pieData = new PieData(pieDataSet);
pieChart.setData(pieData);
pieChart.getDescription().setEnabled(false);
pieChart.setCenterText("Answer");
pieChart.animate();
}
}
Here's my database
In the code, I converted String n to int n1 which has the finalCount values which is [10,15] but I'm only getting 15 in the piechart and the last option name
ArrayList<PieEntry> visitors = new ArrayList<>();
visitors.add(new PieEntry(n1, op));
My output screenshot looks like this, as you can see only 15 is displayed and not 10 and 15 both
ArrayList<PieEntry> visitors = new ArrayList<>();
visitors.add(new PieEntry(n1, op));
Add ArrayList<PieEntry> visitors = new ArrayList<>(); top of the for loop.
ArrayList<PieEntry> visitors = new ArrayList<>();
for (int i = 0; i <= size-1; i++) {
//code goes here
visitors.add(new PieEntry(n1, op));
//code goes here
}
I have been using realm about more than a years, in many cases realm is good choice to construct Android database instead using SQLite. I have been using realm for one-one, one-many relationship and good for it. But, a moment a good. I discover realm NOT update my existing data in ONE-MANY relationship. This what i have done.
This code for populate skeleton data or a unit test
private void initData() {
List<PackModel> packs = new ArrayList<>();
for (int i = 0; i < 1; i++) {
PackModel packModel = new PackModel();
packModel.id = i;
packModel.name = "Pack " + new Random().nextInt(100);
List<FoodModel> foods = new ArrayList<>();
for (int j = 0; j < 3; j++) {
FoodModel foodModel = new FoodModel();
foodModel.id = 0; // i set primary key 0, so in list should be 3 but when insert should be JUST one
foodModel.packId = i;
foodModel.name = "Food " + new Random().nextInt(100);
foodModel.stock = new Random().nextInt(100);
foodModel.price = new Random().nextInt(100);
foodModel.image = "hrrp";
foodModel.calorie = new Random().nextInt(100);
foodModel.createTime = System.nanoTime();
foods.add(foodModel);
}
packModel.foods.addAll(foods);
packs.add(packModel);
}
insertdb(packs);
}
As you see a List of PackModel, and each PackModel have their food items.
So, i write in Realm like below code.
private void insertdb(final List<PackModel> items) {
new AsyncTask<Void, Void, List<PackObject>>() {
#Override
protected List<PackObject> doInBackground(Void... params) {
final List<PackObject> packsObject = new ArrayList<>();
for (int i = 0; i < items.size(); i++) {
PackObject packObject = new PackObject();
packObject.id = items.get(i).id;
packObject.name = items.get(i).name;
List<FoodObject> foodsObject = new ArrayList<>();
for (int j = 0; j < items.get(i).foods.size(); j++) {
FoodObject foodObject = new FoodObject();
foodObject.id = items.get(i).foods.get(j).id;
foodObject.name = items.get(i).foods.get(j).name;
foodObject.createdTime = items.get(i).foods.get(j).createTime;
foodsObject.add(foodObject);
}
packObject.foods.addAll(foodsObject);
packsObject.add(packObject);
}
Realm realm = Realm.getInstance(RealmApplication.getRealmConfiguration());
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(packsObject);
}
});
return realm.copyFromRealm(realm.where(PackObject.class).findAll());
}
#Override
protected void onPostExecute(List<PackObject> items) {
super.onPostExecute(items);
Log.d("Test", "");
}
}.execute();
}
I got multiple FoodObject in each PackObject, what i am wrong here? i also use realm.beginTransaction. realm.beginTransaction is just a same like execute*, the difference just execute* are thread safe.
i also use realm.insertOrUpdate(obj), but just have same result.
NOTE: I have read realm documentation about it. So dont judge me not read their documentation.
this my repot for the code https://github.com/radityagumay/realm-bug
Thanks
I am using MPAndroidChart2.2.5 to draw charts in my project,which contains 2 group of BarDataand 1 group of LineData.When I use the BarData in Barchart,the bars shows well.But when I use the same BarData in CombinedChart,the position of the bars differs.Here's my activity.
Here's a screenshot:
.
public class CombinedChartActivity extends BaseActivity {
private CombinedChart combinedChart;
private BarChart barChart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_combined_chart);
combinedChart = (CombinedChart) findViewById(R.id.chart);
barChart = (BarChart) findViewById(R.id.barChart);
initChart(combinedChart);
initChart(barChart);
barChart.setData(getBarData());
CombinedData combinedData = new CombinedData();
combinedData.setXVals(getXVals());
combinedData.setData(getLineData());
combinedData.setData(getBarData());
combinedChart.setData(combinedData);
}
private void initChart(BarLineChartBase barLineChartBase) {
barLineChartBase.setDescription("");
barLineChartBase.getAxisLeft().setEnabled(false);
barLineChartBase.getAxisRight().setEnabled(false);
barLineChartBase.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
barLineChartBase.getXAxis().setGridColor(R.color.white);
barLineChartBase.getXAxis().setAvoidFirstLastClipping(true);
barLineChartBase.setBackgroundColor(Color.WHITE);
}
private BarData getBarData() {
List<IBarDataSet> iBarDataSets = new ArrayList<>();
ArrayList<BarEntry> barEntries = new ArrayList<>();
for (int i = 0; i < 7; i++) {
BarEntry barEntry = new BarEntry(i + 1, i);
barEntries.add(barEntry);
}
BarDataSet barDataSet = new BarDataSet(barEntries, "Bar1");
barDataSet.setColor(Color.rgb(60, 220, 78));
barDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
ArrayList<BarEntry> barEntries2 = new ArrayList<>();
for (int i = 0; i < 7; i++) {
BarEntry barEntry = new BarEntry((float) (i + Math.random() * 10), i);
barEntries2.add(barEntry);
}
BarDataSet barDataSet1 = new BarDataSet(barEntries2, "Bar2");
barDataSet1.setColor(R.color.level_3);
barDataSet1.setAxisDependency(YAxis.AxisDependency.RIGHT);
iBarDataSets.add(barDataSet);
iBarDataSets.add(barDataSet1);
BarData barData = new BarData(getXVals(), iBarDataSets);[![enter image description here][1]][1]
return barData;
}
private LineData getLineData() {
ArrayList<Entry> entries = new ArrayList<>();
for (int i = 0; i < 7; i++) {
Entry entry = new Entry((float) (Math.random() * 10), i);
entries.add(entry);
}
List<ILineDataSet> iLineDataSets = new ArrayList<>();
LineDataSet lds1 = new LineDataSet(entries, "Line");
lds1.setLineWidth(0.2f);
lds1.setColor(R.color.level_3);
lds1.setDrawFilled(true);
lds1.setFillAlpha(150);
lds1.setFillColor(R.color.level_2);
lds1.setDrawValues(false);
lds1.setHighlightEnabled(true);
lds1.setDrawHorizontalHighlightIndicator(false);
lds1.setHighLightColor(R.color.white);
lds1.setDrawCubic(true);
lds1.setDrawCircles(true);
lds1.setCircleColor(R.color.white);
lds1.setCircleColorHole(R.color.theme_orange);
lds1.setAxisDependency(YAxis.AxisDependency.LEFT);
iLineDataSets.add(lds1);
LineData lineData = new LineData(getXVals(), iLineDataSets);
return lineData;
}
private List<String> getXVals() {
ArrayList<String> xVals = new ArrayList<>();
xVals.add("Monday");
xVals.add("Tuesday");
xVals.add("Wednesday");
xVals.add("Thursday");
xVals.add("Friday");
xVals.add("Saturday");
xVals.add("Sunday");
return xVals;
}
}
I use same BarData in both charts.What causes the difference.How can I make the bars in Combinedchart show as in the Barchart?
I'm trying to follow this guide:
https://github.com/PhilJay/MPAndroidChart/wiki/Setting-Data
It has the line of code:
LineData data = new LineData(xVals, dataSets);
When I tried it in my AndroidStudio, the LineData() constructor only takes 1 argument instead of 2 arguments as shown in the guide.
Anyone know how to initialize with the new version of MPAndroidChart ?
I have the following in my gradle setting:
compile 'com.github.PhilJay:MPAndroidChart:v3.0.0-beta1'
Maybe I should drop to 2.2.5 ?
Update
Yes, I changed gradle to use 2.2.5 and now LineData() constructor has multiple parameters as expected.
Docs needs updating for version 3.0.
in this version
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'
try it
public class MainActivity extends AppCompatActivity {
private LineChart lc;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
public int ran() {
Random ran = new Random();
int i = ran.nextInt(199);
return i;
}
public int ran2() {
Random ran = new Random();
int i = ran.nextInt(49);
return i;
}
public void initData() {
lc.setExtraOffsets(12,50,24,0); //padding
setDescription("two lines example");
lc.animateXY(500, 0);
setLegend();
setYAxis();
setXAxis();
setChartData();
}
public void setLegend() {
Legend legend = lc.getLegend();
legend.setForm(Legend.LegendForm.LINE);
legend.setFormSize(20);
legend.setTextSize(20f);
legend.setFormLineWidth(1);
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
legend.setTextColor(Color.BLACK);
}
public void setDescription(String descriptionStr) {
Description description = new Description();
description.setText(descriptionStr);
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
Paint paint = new Paint();
paint.setTextSize(20);
float x = outMetrics.widthPixels - Utils.convertDpToPixel(12);
float y = Utils.calcTextHeight(paint, descriptionStr) + Utils.convertDpToPixel(12);
description.setPosition(x, y);
lc.setDescription(description);
}
public void setYAxis() {
final YAxis yAxisLeft = lc.getAxisLeft();
yAxisLeft.setAxisMaximum(200);
yAxisLeft.setAxisMinimum(0);
yAxisLeft.setGranularity(10);
yAxisLeft.setTextSize(12f);
yAxisLeft.setTextColor(Color.BLACK);
yAxisLeft.setValueFormatter(new IAxisValueFormatter() {
#Override
public String getFormattedValue(float value, AxisBase axis) {
return value == yAxisLeft.getAxisMinimum() ? (int) value + "" : (int) value +"";
}
});
lc.getAxisRight().setEnabled(false);
}
public void setXAxis() {
XAxis xAxis = lc.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setLabelCount(20);
xAxis.setTextColor(Color.BLACK);
xAxis.setTextSize(12f);
xAxis.setGranularity(1);
xAxis.setAxisMinimum(0);
xAxis.setAxisMaximum(100);
xAxis.setValueFormatter(new IAxisValueFormatter() {
#Override
public String getFormattedValue(float value, AxisBase axis) {
return value == 0 ? "example" : (int) value + "";
}
});
}
public void setChartData() {
List<Entry> yVals1 = new ArrayList<>();
for (int i = 0; i < 100; i++) {
int j = ran();
yVals1.add(new Entry(1 + i,j));
}
List<Entry> yVals2 = new ArrayList<>();
for (int i = 0; i < 100; i++) {
int j = ran2();
yVals2.add(new Entry(1 + i,j));
}
LineDataSet lineDataSet1 = new LineDataSet(yVals1, "ex1");
lineDataSet1.setValueTextSize(20);
lineDataSet1.setDrawCircleHole(true);
lineDataSet1.setColor(Color.MAGENTA);
lineDataSet1.setMode(LineDataSet.Mode.LINEAR);
lineDataSet1.setDrawCircles(true);
lineDataSet1.setCubicIntensity(0.15f);
lineDataSet1.setCircleColor(Color.MAGENTA);
lineDataSet1.setLineWidth(1);
LineDataSet lineDataSet2 = new LineDataSet(yVals2, "ex2");
lineDataSet2.setValueTextSize(20);
lineDataSet2.setDrawCircleHole(true);
lineDataSet2.setColor(Color.BLUE);
lineDataSet2.setMode(LineDataSet.Mode.LINEAR);
lineDataSet2.setDrawCircles(true);
lineDataSet2.setCubicIntensity(0.15f);
lineDataSet2.setCircleColor(Color.BLUE);
lineDataSet2.setLineWidth(1);
.
.
.
ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
dataSets.add(lineDataSet1);
dataSets.add(lineDataSet2);
LineData lineData = new LineData(dataSets);
lc.setVisibleXRangeMaximum(5);
lc.setScaleXEnabled(true);
lc.setData(lineData);
}
and like this.
Version 3.0 is initialized like so:
LineChart lineChart = new LineChart(context);
lineChart.setMinimumHeight(ToolBox.dpToPixels(context, 300));
lineChart.setMinimumWidth(ToolBox.getScreenWidth());
ArrayList<Entry> yVals = new ArrayList<>();
for(int i = 0; i < frigbot.getEquipment().getTemperatures().size(); i++)
{
Temperature temperature = frigbot.getEquipment().getTemperatures().get(i);
yVals.add(new Entry(
i, temperature.getValue().floatValue()
));
}
LineDataSet dataSet = new LineDataSet(yVals, "graph name");
dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
dataSet.setCubicIntensity(0.2f);
LineData data = new LineData(dataSet);
lineChart.setData(data);
It appears we can't specify custom horizontal labels, LineChart itself will automatically generate the horizontal and vertical axis labelling.
i have a graph view to implement an analysis graph
All the x-axis and y-axis data is get from the sqlite db data to show the output
x-axis is showing date
y-axis is showing weight
but I have no idea to implement them out, I am stuck,
below is my code but its wrong and I haven't completed yet, can someone help me to solve and build
DBHelperNote connect = new DBHelperNote(getActivity());
SQLiteDatabase db = connect.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM weight;",null);
String[] weight = new String[cursor.getCount()];
int i = 0;
while(cursor.moveToNext()){
d = cursor.getString(cursor.getColumnIndex("weightnum"));
weight[i] = d;
i++;
}
String[] date = new String[cursor.getCount()];
int r = 0;
while(cursor.moveToNext()){
e = cursor.getString(cursor.getColumnIndex("date"));
date[r] = e;
r++;
}
GraphView line_graph = (GraphView) contentView.findViewById(R.id.graph);
LineGraphSeries<DataPoint> line_series =
new LineGraphSeries<DataPoint>(new DataPoint[] {
>> here "while" getting error
while ( a!=weight.length) {
new DataPoint(Integer.parseInt(weight[i]), Integer.parseInt(date[i]));
i++;
}
}
);
line_graph.addSeries(line_series);
line_series.setDrawDataPoints(true);
line_series.setDataPointsRadius(10);
line_series.setOnDataPointTapListener(new OnDataPointTapListener() {
#Override
public void onTap(Series series, DataPointInterface dataPoint) {
Toast.makeText(getActivity(), "Series: On Data Point clicked: " + dataPoint, Toast.LENGTH_SHORT).show();
}
});
Hmn, it might be an error with the data type in their example they use a double instead of an int.
http://www.android-graphview.org/documentation/category/live-chart
private DataPoint[] generateData() {
int count = 30;
DataPoint[] values = new DataPoint[count];
for (int i=0; i<count; i++) {
double x = i;
double f = mRand.nextDouble()*0.15+0.3;
double y = Math.sin(i*f+2) + mRand.nextDouble()*0.3;
DataPoint v = new DataPoint(x, y);
values[i] = v;
}
return values;