Reputation: 1490
I'm using LineChart that uses 3 view modes; daily, monthly, and annual. The user may switch between those three. All those modes implement date based x-axis whose dataset is provided in milliseconds that is formatted into a specific date format.
I set the visible x range maximum to 6 entries, which means 6 days for daily mode, 6 month for monthly mode, and 6 years for annual mode. Initially, the chart is set to show in daily mode and the result goes as expected. After user switches to the monthly mode and then switches back to the daily mode, the chart seems to zoom according to x-range that was set to monthly mode. So it seems to zoom in to the level that is used by monthly mode. I have logged the last range and last minimum x value of each view modes and make sure that i have set the proper values for each of them.
Here, below is what i have done.
`
private void initChartData(int mode) {
chart = (LineChart) findViewById(R.id.chart);
List<Entry> entries = new ArrayList<Entry>();
Calendar cal = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
Date today = cal.getTime();
XAxis xAxis = chart.getXAxis();
xAxis.setGranularityEnabled(true);
xAxis.setGranularity(1f);
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
switch (mode) {
case daily:
cal2.add(Calendar.DAY_OF_MONTH, -30);
Date thirtyDaysAgo = cal2.getTime();
dataObjects = realm.where(AmalStat.class).greaterThan("date", thirtyDaysAgo).and().lessThan("date", today)
.findAll().sort("date", Sort.DESCENDING);
Utils.logd("maxgettime: " + maxdaily);
mindaily = dataObjects.get(dataObjects.size() - 1).getDate().getTime();
Utils.logd("dataObjects size: " + dataObjects.size());
int k = dataObjects.size() < 6 ? dataObjects.size() : 5;
for (AmalStat data : dataObjects) {
Utils.logd("time: " + data.getDate().getTime() + ", point: " + data.getPoint());
entries.add(new Entry(data.getDate().getTime(), data.getPoint()));
Utils.logd("k: " + k);
if (k == 0) {
mindaily = data.getDate().getTime();
Utils.logd("min ini: " + mindaily);
}
k--;
}
rangedaily = maxdaily - mindaily;
xAxis.setValueFormatter(new MyAxisValueFormatter(mode));
xAxis.setLabelCount(entries.size(), true);
break;
case monthly:
int month = cal.get(Calendar.MONTH) + 1;
cal.set(Calendar.DAY_OF_MONTH, 0);
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR));
cal.set(Calendar.MONTH, cal.get(Calendar.MONTH));
Date minDay = cal.getTime();
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR));
cal.set(Calendar.MONTH, cal.get(Calendar.MONTH));
Date maxDay = cal.getTime();
int year = cal2.get(Calendar.YEAR);
maxmonthly = maxDay.getTime();
minmonthly = minDay.getTime();
int j = 6;
xAxis.setLabelCount(6, true);
for (int i = month; i >= 0; i--) {
cal2.set(Calendar.MONTH, i - 1);
cal2.set(Calendar.YEAR, year);
cal2.set(Calendar.DAY_OF_MONTH, 1);
minDay = cal2.getTime();
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR));
cal.set(Calendar.MONTH, i - 1);
maxDay = cal.getTime();
SimpleDateFormat simpleDate = new SimpleDateFormat("dd/MM/yyyy");
String minDayText = simpleDate.format(minDay);
String maxDayText = simpleDate.format(maxDay);
Utils.logd(minDayText + " - " + maxDayText);
int wajibs = realm.where(AmalStat.class).greaterThan("date", minDay).and().lessThan("date", maxDay)
.sum("wajib").intValue();
int muakkads = realm.where(AmalStat.class).greaterThan("date", minDay).and().lessThan("date", maxDay)
.sum("muakkad").intValue();
int nonMuakkads = realm.where(AmalStat.class).greaterThan("date", minDay).and().lessThan("date", maxDay)
.sum("nonMuakkad").intValue();
int point = wajibs + muakkads + nonMuakkads;
entries.add(new Entry(cal2.getTimeInMillis(), point));
Utils.logd("i: " + i);
j--;
if (j == 0) {
Utils.logd("ini=" + i);
minmonthly = cal2.getTimeInMillis();
}
}
if (month < 12) {
for (int i = 12; i > month; i--) {
cal2.set(Calendar.MONTH, i - 1);
cal2.set(Calendar.YEAR, year - 1);
cal2.set(Calendar.DAY_OF_MONTH, 1);
int wajibs = realm.where(AmalStat.class).greaterThan("date", minDay).and().lessThan("date", maxDay)
.sum("wajib").intValue();
int muakkads = realm.where(AmalStat.class).greaterThan("date", minDay).and().lessThan("date", maxDay)
.sum("muakkad").intValue();
int nonMuakkads = realm.where(AmalStat.class).greaterThan("date", minDay).and().lessThan("date", maxDay)
.sum("nonMuakkad").intValue();
int point = wajibs + muakkads + nonMuakkads;
entries.add(new Entry(cal2.getTimeInMillis(), point));
Utils.logd("i: " + i);
j--;
if (j == 0) {
Utils.logd("itu=" + i);
minmonthly = cal2.getTimeInMillis();
}
}
}
rangemonthly = maxmonthly - minmonthly;
xAxis = chart.getXAxis();
xAxis.setValueFormatter(new MyAxisValueFormatter(mode));
break;
case annual:
break;
}
xAxis.setGranularityEnabled(true);
xAxis.setGranularity(1f);
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
Collections.sort(entries, new EntryXComparator());
LineDataSet dataSet = new LineDataSet(entries, "Label"); // add entries to dataset
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
dataSet.setColor(getColor(R.color.white));
dataSet.setValueTextColor(getColor(R.color.white)); // styling, ...
} else {
dataSet.setColor(getResources().getColor(R.color.white));
dataSet.setValueTextColor(getResources().getColor(R.color.white)); // styling, ...
}
LineData lineData = new LineData(dataSet);
chart.setDescription(null); // Hide the description
chart.getAxisLeft().setDrawLabels(false);
chart.getAxisLeft().setDrawGridLines(false);
chart.getXAxis().setDrawLabels(true);
chart.getXAxis().setEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
chart.getXAxis().setTextColor(getColor(R.color.white));
} else {
chart.getXAxis().setTextColor(getResources().getColor(R.color.white));
}
chart.getAxisRight().setDrawLabels(false);
chart.getAxisRight().setDrawGridLines(false);
chart.getAxisRight().setDrawAxisLine(false);
chart.getLegend().setEnabled(false); // Hide the legend
chart.setData(lineData);
chart.invalidate();
switch (mode) {
case daily:
Utils.logd(rangedaily + " " + maxdaily + " " + mindaily);
chart.setVisibleXRangeMaximum(rangedaily);
chart.moveViewToX(maxdaily);
break;
case monthly:
Utils.logd(rangemonthly + " " + maxmonthly + " " + minmonthly);
chart.setVisibleXRangeMaximum(rangemonthly);
chart.moveViewToX(maxmonthly);
break;
case annual:
}
chart.invalidate();
Utils.logd("akhir");
}`
Is this really an issue of MPAndroidChart library or might i ridiculously miss something?
Upvotes: 2
Views: 1473
Reputation: 1155
I had the same problem and what helped me is the following simple addition
chart.fitScreen();
that should go before
chart.setVisibleXRangeMaximum(rangemonthly);
chart.moveViewToX(maxmonthly);
Use this three lines each time you change your data set (and notify the chart) to make the chart show you n entries (or all of them in case there are less entries than expected) counting from the end.
I have discovered that chart.fitScreen()
same as chart.setVisibleXRange(rangedaily,rangedaily)
(suggested by @Coalcandy) dont give the desired effect every time. It depends on the chart sliding. If user after scrolling through the chart values clicks to display another data set while the chart's sliding animation is still on, then no desired effect will be achieved. The way to make sure the chart shows n entries counting from the end each time the data set is changed, add this line
chart.setDragDecelerationEnabled(false);
The drawback is the chart scrolling will not be so smooth.
Upvotes: 1
Reputation: 31
I had the same problem and solved it by using setVisibleXRange instead of setVisisbleXRangeMaximum.
Try using this:
chart.setVisibleXRange(rangedaily,rangedaily);
Upvotes: 3
Reputation: 3189
Change following code:
switch (mode) {
case daily:
Utils.logd(rangedaily + " " + maxdaily + " " + mindaily);
chart.setVisibleXRangeMaximum(rangedaily);
chart.moveViewToX(maxdaily);
break;
case monthly:
Utils.logd(rangemonthly + " " + maxmonthly + " " + minmonthly);
chart.setVisibleXRangeMaximum(rangemonthly);
chart.moveViewToX(maxmonthly);
break;
case annual:
}
To
switch (mode) {
case daily:
Utils.logd(rangedaily + " " + maxdaily + " " + mindaily);
chart.resetViewPortOffsets();
chart.setVisibleXRangeMaximum(rangedaily);
chart.moveViewToX(maxdaily);
chart.invalidate();
break;
case monthly:
Utils.logd(rangemonthly + " " + maxmonthly + " " + minmonthly);
chart.resetViewPortOffsets();
chart.setVisibleXRangeMaximum(rangemonthly);
chart.moveViewToX(maxmonthly);
chart.invalidate();
break;
case annual:
}
Upvotes: 0