I am struggling to get a line chart correctly. I have data in Firestore database and from there I am trying to display temperature readings in a line chart. I am using the latest version of Mp line chart. I am trying to get the temperature values in Celsius to YAxis and the time in HH:mm format to the xAxis. I have tried this in mane ways and googled different ways to do this and I just can't get it right. Either the values don't show at all or the values show but in the wrong spot of the xAxis. also I can't get the yAxis showing correctly. Someone has asked about that here already and the answer was to put the ofset "60, 0 50, 60" but that don't work for me.
For the main issue I am currently trying to use the HourAxisValueFormatter which was instructed in GitHub. There is documentation of it but I can't understand how to get it working. I am new to Android an To Mp library so that is why it is difficult.
Below my activity code and the HourAxisValueFormatter
public class TempHistoryActivity extends AppCompatActivity {
private LineChart mChart;
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private ArrayList<Integer> tempItemList;
private ArrayList<Long> timeList, convertedTimes;
private ArrayList<Date> dateList;
private Long reference;
private CollectionReference collectionReference = db.collection("whtitem");
private Toolbar toolbar;
private FirebaseAuth firebaseAuth;
private FirebaseAuth.AuthStateListener authStateListener;
private FirebaseUser user;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_temp_history);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
firebaseAuth = FirebaseAuth.getInstance();
user = firebaseAuth.getCurrentUser();
tempItemList = new ArrayList<>();
timeList = new ArrayList<>();
dateList = new ArrayList<>();
convertedTimes = new ArrayList<>();
mChart = findViewById(R.id.tempLineChart);
mChart.setTouchEnabled(true);
mChart.setPinchZoom(true);
Marker mv = new Marker(getApplicationContext(), R.layout.custom_marker_view);
mv.setChartView(mChart);
mChart.setMarker(mv);
mChart.setViewPortOffsets(60, 0, 50, 90);
mChart.setExtraLeftOffset(40);
retrieveDayDataFromDatabase();
}
private void retrieveDayDataFromDatabase() {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Date currentDate = calendar.getTime();
Calendar cals = Calendar.getInstance();
cals.add(Calendar.DAY_OF_YEAR, +1);
Date tomorrow = cals.getTime();
collectionReference.whereEqualTo("userId", WhtApi.getInstance()
.getUserId())
.orderBy("date", Query.Direction.ASCENDING)
.startAt(currentDate)
.endAt(tomorrow)
.get()
.addOnSuccessListener(queryDocumentSnapshots -> {
if (!queryDocumentSnapshots.isEmpty()){
dateList.clear();
tempItemList.clear();
for (QueryDocumentSnapshot whtitems : queryDocumentSnapshots) {
WhtItem whtItem = whtitems.toObject(WhtItem.class);
dateList.add(whtItem.getDate());
tempItemList.add(whtItem.getTemperature());
Log.d("temps", "retrieveDayDataFromDatabase: " + tempItemList);
}
Calendar cal = Calendar.getInstance();
for (int i = 0; i < dateList.size(); i++){
Date date = dateList.get(i);
Long time = Long.valueOf(date.getTime());
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
//String time = DateFormat.format("HH:mm", dateList.get(i)).toString();
/* cal.setTime(dateList.get(i));
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
String t = hour +":"+minute+0;
Log.d("st", "retrieveDayDataFromDatabase: " + t);
DecimalFormatSymbols symbol = new DecimalFormatSymbols();
symbol.setDecimalSeparator(':');
DecimalFormat decimalFormat = new DecimalFormat("0.##");
NumberFormat format = NumberFormat.getInstance(Locale.US);
format.setMaximumFractionDigits(3);
format.setMinimumFractionDigits(3);
float time = 0;
try {
time = decimalFormat.parse(t).floatValue();
Log.d("timef", "retrieveDayDataFromDatabase: " + time);
} catch (ParseException e) {
e.printStackTrace();
}
Float newValue = new Float(format.format(time));
BigDecimal decimal = new BigDecimal(t).setScale(2);
Log.d("decimal", "retrieveDayDataFromDatabase: " + decimal);*/
timeList.add(time);
}
renderDayData();
}else {
Toast.makeText(TempHistoryActivity.this, "Ei lämpötilakirjauksia vielä", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(e -> Toast.makeText(TempHistoryActivity.this, "Tapahtui virhe dataa haettaessa", Toast.LENGTH_SHORT).show());
}
public void renderDayData() {
Collections.sort(timeList);
for (int i = 0; i<timeList.size(); i++){
reference = timeList.get(0);
Long Xnew = (timeList.get(1)) - reference;
convertedTimes.add(Xnew);
Log.d("converted", "renderDayData: "+ convertedTimes);
}
LimitLine llXAxis = new LimitLine(10f, "Index 10");
llXAxis.setLineWidth(4f);
llXAxis.enableDashedLine(10f, 10f, 0f);
llXAxis.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_BOTTOM);
llXAxis.setTextSize(10f);
XAxis xAxis = mChart.getXAxis();
xAxis.setValueFormatter(new HourAxisValueFormatter(reference));
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.enableGridDashedLine(10f, 10f, 0f);
xAxis.setAxisMinimum(0f);
xAxis.setAxisMaximum(10f);
xAxis.setTextColor(ContextCompat.getColor(this, R.color.colorPrimary));
xAxis.setGranularity(1f);
xAxis.setDrawLimitLinesBehindData(true);
LimitLine ll1 = new LimitLine(33f, "Lämpöraja 33°C");
ll1.setLineWidth(4f);
ll1.enableDashedLine(10f, 10f, 0f);
ll1.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_TOP);
ll1.setTextSize(15f);
ll1.setTextColor(ContextCompat.getColor(this, R.color.colorPrimary));
YAxis leftAxis = mChart.getAxisLeft();
leftAxis.setValueFormatter(new IndexAxisValueFormatter(getTemperature()));
leftAxis.enableGridDashedLine(10f, 10f, 0f);
leftAxis.removeAllLimitLines();
leftAxis.addLimitLine(ll1);
leftAxis.setDrawZeroLine(false);
leftAxis.setAxisMinimum(0f);
leftAxis.setAxisMaximum(100f);
leftAxis.setDrawLimitLinesBehindData(false);
leftAxis.setDrawGridLines(true);
leftAxis.setTextColor(ContextCompat.getColor(this, R.color.colorPrimary));
mChart.getAxisRight().setEnabled(false);
mChart.invalidate();
setDayData();
}
public ArrayList<String> getDate(){
ArrayList<String> label = new ArrayList<>();
for(int i=0; i<dateList.size(); i++){
String date = DateFormat.format("dd.MM.", dateList.get(i)).toString();
label.add(date);
}return label;
}
public ArrayList<String> getTime(){
ArrayList<String> times = new ArrayList<>();
for(int i=0; i<values.length; i++){
times.add( values[i]);
}return times;
}
public ArrayList<String> getTemperature(){
ArrayList<String> temps = new ArrayList<>();
for(int i=0; i < tempItemList.size(); i++){
String temp = tempItemList.get(i) + "°C";
temps.add(temp);
Log.d("templist", "getTemperature: " + temps);
}return temps;
}
private void setDayData() {
ArrayList<Entry> values = new ArrayList<>();
values.clear();
for (int i =0 ; i < timeList.size(); i++){
values.add(new Entry(i, tempItemList.get(i)));
Log.d("list", "setDayData: " + timeList.get(i));
Log.d("values", "setData: " + values);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Collections.sort(values, new EntryXComparator());
}
LineDataSet set1;
if (mChart.getData() != null &&
mChart.getData().getDataSetCount() > 0) {
set1 = (LineDataSet) mChart.getData().getDataSetByIndex(0);
set1.setValues(values);
mChart.getData().notifyDataChanged();
mChart.notifyDataSetChanged();
} else {
set1 = new LineDataSet(values, "Lämpötiladata");
set1.setDrawIcons(false);
set1.enableDashedLine(10f, 5f, 0f);
set1.enableDashedHighlightLine(10f, 5f, 0f);
set1.setColor(ContextCompat.getColor(this, R.color.colorPrimary));
set1.setCircleColor(ContextCompat.getColor(this, R.color.colorPrimary));
set1.setLineWidth(1f);
set1.setCircleRadius(3f);
set1.setDrawCircleHole(false);
set1.setValueTextSize(9f);
set1.setDrawFilled(true);
set1.setFormLineWidth(1f);
set1.setFormLineDashEffect(new DashPathEffect(new float[]{10f, 5f}, 0f));
set1.setFormSize(15.f);
if (Utils.getSDKInt() >= 18) {
Drawable drawable = ContextCompat.getDrawable(this, R.drawable.gradient);
set1.setFillDrawable(drawable);
} else {
set1.setFillColor(ContextCompat.getColor(this, R.color.colorPrimary));
}
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
dataSets.add(set1);
LineData data = new LineData(dataSets);
mChart.setData(data);
Description description = new Description();
description.setText("");
mChart.setDescription(description);
mChart.invalidate();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.profile:
if (user != null && firebaseAuth != null) {
startActivity(new Intent(TempHistoryActivity.this, ProfileActivity.class));
//finish();
}
break;
case R.id.mainpage:
if (user != null && firebaseAuth != null) {
startActivity(new Intent(TempHistoryActivity.this, MainPageActivity.class));
//finish();
}
break;
case R.id.temp_history:
if (user != null && firebaseAuth != null) {
startActivity(new Intent(TempHistoryActivity.this, TempHistoryActivity.class));
//finish();
}
break;
case R.id.pulse_history:
if (user != null && firebaseAuth!=null) {
startActivity(new Intent(TempHistoryActivity.this, PulseHistoryActivity.class));
//finish();
}
break;
case R.id.time_in_temp_history:
if (user != null && firebaseAuth != null) {
startActivity(new Intent(TempHistoryActivity.this, TimeTempActivity.class));
//finish();
}
break;
case R.id.action_signout:
//signout
if (user != null && firebaseAuth != null) {
firebaseAuth.signOut();
startActivity(new Intent(TempHistoryActivity.this, MainActivity.class));
//finish();
}
break;
}
return super.onOptionsItemSelected(item);
}
}
public class HourAxisValueFormatter extends ValueFormatter
{
private long referenceTimestamp; // minimum timestamp in your data set
private DateFormat mDataFormat;
private Date mDate;
public HourAxisValueFormatter(long referenceTimestamp) {
this.referenceTimestamp = referenceTimestamp;
this.mDataFormat = new SimpleDateFormat("HH:mm", Locale.ENGLISH);
this.mDate = new Date();
}
#Override
public String getFormattedValue(float value){
// convertedTimestamp = originalTimestamp - referenceTimestamp
long convertedTimestamp = (int) value;
// Retrieve original timestamp
long originalTimestamp = referenceTimestamp + convertedTimestamp;
// Convert timestamp to hour:minute
return getHour(originalTimestamp);
}
public int getDecimalDigits()
{
return 0;
}
private String getHour(long timestamp){
try{
mDate.setTime(timestamp*1000);
return mDataFormat.format(mDate);
}
catch(Exception ex){
return "xx";
}
}
}
Here is my output atm
output
and this is what I am trying to get
enter image description here
I want the xAxis values to be "07:00, 08:00, 09:00, 10:00, 11:00, 12:00, 13:00, 14:00, 15:00, 16:00, 17:00"
Related
I toke as example this https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/LineChartTime.java
I adjusted to my needs. The problem is that for plotting data in X axis it need a float number and converting from long to float there is lost of datas. The trick in the example is to convert milliseconds time in HOURLY so there isn't lost of data but i need to convert to DAILY, I tried but couldn't get the results
I've tried to change TimeUnit.HOURS.toMillis((long) value); to TimeUnit.DAYS.toMillis((long) value); and I added timeInHours = TimeUnit.DAYS.toMillis(mDate.getTime());
public class ChartDailyActivity extends AppCompatActivity {
private LineChart chart;
DBOpenHelper mDB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chart_daily);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setChart();
}
public void setChart(){
chart = findViewById(R.id.chart1);
XAxis xAxis = chart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.TOP_INSIDE);
xAxis.setTextSize(10f);
xAxis.setTextColor(Color.WHITE);
xAxis.setDrawAxisLine(false);
xAxis.setDrawGridLines(true);
xAxis.setTextColor(Color.rgb(255, 192, 56));
xAxis.setCenterAxisLabels(true);
//xAxis.setSpaceMin(1000f*60f*60f*24f);
xAxis.setValueFormatter(new IAxisValueFormatter() {
private final SimpleDateFormat mFormat = new SimpleDateFormat("dd/MM/yy", Locale.ITALIAN);
#Override
public String getFormattedValue(float value, AxisBase axis) {
long millis = TimeUnit.DAYS.toMillis((long) value);
return mFormat.format(new Date(millis));
}
});
mDB = new DBOpenHelper(this);
YAxis leftAxis = chart.getAxisLeft();
leftAxis.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
leftAxis.setTextColor(ColorTemplate.getHoloBlue());
leftAxis.setDrawGridLines(true);
leftAxis.setGranularityEnabled(true);
leftAxis.setAxisMinimum(0f);
leftAxis.setAxisMaximum((float) mDB.queryMaxTotaleBevuto());
leftAxis.setYOffset(-9f);
leftAxis.setTextColor(Color.rgb(255, 192, 56));
YAxis rightAxis = chart.getAxisRight();
rightAxis.setEnabled(false);
setData();
}
private void setData() {
ArrayList<Entry> values = new ArrayList<>();
ArrayList xList = new ArrayList<Integer>();
ArrayList yList = new ArrayList<String>();
DBOpenHelper mDB = new DBOpenHelper(this);
xList = mDB.queryTotaleBevutoData();
yList = mDB.queryTotaleBevuto();
float flX, flY;
int intX, intY;
for(int x=0; x<xList.size(); x++){
String givenDateString = (String)xList.get(x);
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy");
long timeInHours = 0;
try {
Date mDate = sdf.parse(givenDateString);
//Log.d("XLOGGIN:", "Date = " + givenDateString );
timeInHours = TimeUnit.DAYS.toMillis(mDate.getTime());
//timeInMilliseconds = mDate.getTime();
} catch (ParseException e) {
e.printStackTrace();
}
intX = (int)timeInHours;
intY = (int)yList.get(x);
flX = (float)intX;
flY = (float)intY;
/*
Log.d("XLOGGIN:Long", Long.toString(timeInMilliseconds));
Log.d("XLOGGIN:intX", Integer.toString(intX));
Log.d("XLOGGIN:flX", Float.toString(flX));
*/
values.add(new Entry(flX, flY));
}
// create a dataset and give it a type
LineDataSet set1 = new LineDataSet(values, "Drinked ml/Day");
set1.setAxisDependency(YAxis.AxisDependency.LEFT);
set1.setColor(ColorTemplate.getHoloBlue());
set1.setValueTextColor(ColorTemplate.getHoloBlue());
set1.setLineWidth(1.5f);
set1.setDrawCircles(false);
set1.setDrawValues(false);
set1.setFillAlpha(65);
set1.setFillColor(ColorTemplate.getHoloBlue());
set1.setHighLightColor(Color.rgb(244, 117, 117));
set1.setDrawCircleHole(false);
// create a data object with the data sets
LineData data = new LineData(set1);
data.setValueTextColor(Color.WHITE);
data.setValueTextSize(9f);
// set data
chart.setData(data);
}
}
The chart plots bad datetime (all dates are 01/01/1970) and the line is a orizzontal line
You are not converting your timestamp into a day equivalent. This is how you should do it (during setData()):
try {
Date mDate = sdf.parse(givenDateString);
//Log.d("XLOGGIN:", "Date = " + givenDateString );
timeInDays = TimeUnit.MILLISECONDS.toDays(mDate.getTime());
//timeInMilliseconds = mDate.getTime();
} catch (ParseException e) {
e.printStackTrace();
}
I'm trying to create a mountain chart using SciChart, but I need to create using Logarithmic, I tried the below code, but dont change chart and missing YAxis label.
I change the demo SciChart to it:
public class MountainChartFragment extends ExampleBaseFragment {
#BindView(R.id.chart)
SciChartSurface surface;
private double selectedLogBase = 10d;
#Override
protected int getLayoutId() {
return R.layout.example_single_chart_fragment;
}
#Override
protected void initExample() {
//final IAxis xBottomAxis = sciChartBuilder.newDateAxis().withGrowBy(0.1d, 0.1d).build();
final IAxis xBottomAxis = sciChartBuilder.newDateAxis().withGrowBy(0.1d, 0.1d).build();
final IAxis yRightAxis = sciChartBuilder.newLogarithmicNumericAxis().withScientificNotation(ScientificNotation.LogarithmicBase).withLogarithmicBase(selectedLogBase).withGrowBy(0.1d, 0.1d).build();
//final IAxis yRightAxis = sciChartBuilder.newNumericAxis().withGrowBy(0.1d, 0.1d).build();
final PriceSeries priceData = DataManager.getInstance().getPriceDataIndu(getActivity());
final IXyDataSeries<Date, Double> dataSeries = sciChartBuilder.newXyDataSeries(Date.class, Double.class).build();
dataSeries.append(priceData.getDateData(), priceData.getCloseData());
final FastMountainRenderableSeries rSeries = sciChartBuilder.newMountainSeries()
.withZeroLine(0.001)
.withDataSeries(dataSeries)
.withStrokeStyle(0xAAFFC9A8, 1f, true)
.withAreaFillLinearGradientColors(0xAAFF8D42, 0x88090E11)
.build();
UpdateSuspender.using(surface, new Runnable() {
#Override
public void run() {
Collections.addAll(surface.getXAxes(), xBottomAxis);
Collections.addAll(surface.getYAxes(), yRightAxis);
Collections.addAll(surface.getRenderableSeries(), rSeries);
Collections.addAll(surface.getChartModifiers(), sciChartBuilder.newModifierGroupWithDefaultModifiers().build());
sciChartBuilder.newAnimator(rSeries).withWaveTransformation().withInterpolator(new DecelerateInterpolator()).withDuration(3000).withStartDelay(350).start();
}
});
}
}
But dont worked
There are no labels because default TickProvider implementation for LogarithmicNumericAxis can't generate any ticks for auto calculated VisibleRange which is set for YAxis ( it has next values - Min = 10460.814629837885, Max = 13048.710993563885) The nearest values which which would satisfy LogBase = 10 would be 10000 and then 100000 and data set of example lies between these two values so TickProvider returns zero values to render.
In this case there are two possible workarounds:
Try to pick up some other LogBase value;
Set some alternative TickProvider implementation for YAxis (e.g. you can try to use TickProvider for NumericAxis or create your own implementation):
yRightAxis.setTickProvider(new NumericTickProvider());
I change the code and worked well. This is my code:
xAxis = sciChartBuilder.newNumericAxis().withGrowBy(0.1d, 0.1d).withVisibleRange(1.1, 2.7).build();
yAxis = generateLogarithmicAxis();
//yAxis = sciChartBuilder.newNumericAxis().withGrowBy(0.1d, 0.1d).build();
//yAxis.setTickProvider(new NumericTickProvider());
final SimpleDateFormat formatDate = new SimpleDateFormat("yyyyMMdd");
String data1 = "20190401";
Date date1 = null;
Calendar c = Calendar.getInstance();
final IXyDataSeries<Date, Double> dataSeries = sciChartBuilder.newXyDataSeries(Date.class, Double.class).build();
try {
date1 = formatDate.parse(data1);
for(int i = 0 ; i<1000 ; i+=10){
double random = Math.random() * 100.0 + 5;
dataSeries.append(date1, random);
c.setTime(date1);
c.add(Calendar.DATE, 1);
date1 = c.getTime();
}
} catch (ParseException e) {
e.printStackTrace();
}
final FastLineRenderableSeries rSeries = sciChartBuilder.newLineSeries().withZeroLine(0.01d).withDataSeries(dataSeries).withStrokeStyle(0xFF279B27, 1f, true).build();
UpdateSuspender.using(surface, new Runnable() {
#Override
public void run() {
Collections.addAll(surface.getXAxes(), xAxis);
Collections.addAll(surface.getYAxes(), yAxis);
Collections.addAll(surface.getRenderableSeries(), rSeries);
Collections.addAll(surface.getChartModifiers(), sciChartBuilder.newModifierGroupWithDefaultModifiers().build());
sciChartBuilder.newAnimator(rSeries).withSweepTransformation().withInterpolator(new DecelerateInterpolator()).withDuration(3000).withStartDelay(350).start();
}
});
I use MpAndroidChart-CombinedChart in my project,but I met a problem,please look the follow screenshot.
As you saw,the X axis right part didn't filled.In other words,I want set the bar space,but I can't.
I try barData.setBarWidth(0.4f),it didn't work,it will make the bar width Larger,but it will not make bar space lager.
public static void initCombinedChart(List<FieldFragment.CombinedBean> list, CombinedChart combinedChart) {
if (list == null || list.size() == 0) return;
combinedChart.setPinchZoom(false);
combinedChart.setDragEnabled(false);
combinedChart.setTouchEnabled(false);
combinedChart.getLegend().setEnabled(false);
combinedChart.getDescription().setEnabled(false);
XAxis xAxis = combinedChart.getXAxis();
xAxis.setDrawGridLines(false);
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setYOffset(5);
xAxis.setAvoidFirstLastClipping(true);
YAxis leftYAxis = combinedChart.getAxisLeft();
leftYAxis.setLabelCount(6, true);
leftYAxis.setDrawAxisLine(false);
leftYAxis.setDrawGridLines(true);
leftYAxis.setGridColor(Color.parseColor("#DDDDDD"));
leftYAxis.setXOffset(10f);
leftYAxis.setAxisMinimum(0);
leftYAxis.setSpaceBottom(0);
leftYAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
YAxis rightYAxis = combinedChart.getAxisRight();
rightYAxis.setSpaceBottom(0);
rightYAxis.setDrawAxisLine(false);
rightYAxis.setDrawGridLines(true);
rightYAxis.setAxisMinimum(0);
rightYAxis.setXOffset(10);
rightYAxis.setLabelCount(6, true);
rightYAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
List<Entry> lineEntries = new ArrayList<>();
List<BarEntry> barEntries = new ArrayList<>();
List<String> xValues = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
lineEntries.add(new Entry(i, list.get(i).getRightYValue()));
barEntries.add(new BarEntry(i, list.get(i).getLeftYValue()));
xValues.add(list.get(i).getxValue());
}
xAxis.setValueFormatter(new IAxisValueFormatter() {
#Override
public String getFormattedValue(float value, AxisBase axisBase) {
try {
int position = (int) value;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = dateFormat.parse(xValues.get(position));
SimpleDateFormat format = new SimpleDateFormat("MM.dd");
return format.format(date);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
});
// 折线数据
LineDataSet lineDataSet = new LineDataSet(lineEntries, "");
lineDataSet.setDrawValues(false);
lineDataSet.setDrawCircles(false);
lineDataSet.setLineWidth(3f);
lineDataSet.setColor(Color.parseColor("#00c2bd"));
lineDataSet.setMode(LineDataSet.Mode.HORIZONTAL_BEZIER);
lineDataSet.setDrawFilled(true); //这个不要忘了
lineDataSet.setFillColor(Color.parseColor("#00c2bd"));
lineDataSet.setFillAlpha(50);
lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
List<ILineDataSet> lineDataSets = new ArrayList<>();
lineDataSets.add(lineDataSet);
LineData lineData = new LineData(lineDataSets);
// 柱子数据
BarDataSet barDataSet = new BarDataSet(barEntries, "");
barDataSet.setDrawValues(false);
barDataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);
barDataSet.setColor(Color.parseColor("#1490ee"));
BarData barData = new BarData(barDataSet);
barData.setBarWidth(0.4f); //值越大柱子越宽
// 解决bar显示不全问题
float barWidth = barData.getBarWidth() / 2;
xAxis.setAxisMinimum(-barWidth);
xAxis.setAxisMaximum(xValues.size() - barWidth);
CombinedData combinedData = new CombinedData();
combinedData.setData(lineData);
combinedData.setData(barData);
combinedChart.setData(combinedData);
combinedChart.invalidate();
}
Please help me with the code for generating a combined Line and bar graph with mpandroidchartlibrary-2-2-4.
Please find the Code
main.java
for (int win = 0; win < sprintArray.length; win++) {
labels.add(win, window_List.get(win));
System.out.println("WINDOW LIST VALUE IN CHART" + window_List.get(win).toString());
}
for (int window = 0; window < sprintArray.length; window++) {
float wc_entry = Float.parseFloat(workcompleted_list.get(window).toString());
float wr_entry = Float.parseFloat(workremaining_list.get(window).toString());
float wa_entry = Float.parseFloat(workadded_List.get(window).toString());
System.out.println("WC VALUE"+workcompleted_list);
System.out.println("WR VALUE"+workremaining_list);
System.out.println("WA VALUE"+workadded_List);
wc_group.add(new BarEntry(window+3,wc_entry));
wr_group.add(new BarEntry(window+3,wr_entry));
wa_group.add(new BarEntry(window+3,wa_entry));
}
BarDataSet barDataSet1 = new BarDataSet(wc_group, "Work Completed");
barDataSet1.setColor(Color.rgb(217, 227, 184));
barDataSet1.setDrawValues(false);
BarDataSet barDataSet2 = new BarDataSet(wr_group, "Work Remaining");
barDataSet2.setColor(Color.rgb(107, 161, 202));
barDataSet2.setDrawValues(false);
BarDataSet barDataSet3 = new BarDataSet(wa_group, "Work Added");
barDataSet3.setColor(Color.rgb(77, 124, 159));
barDataSet3.setDrawValues(false);
final BarData data = new BarData(barDataSet1);
data.addDataSet(barDataSet2);
data.addDataSet(barDataSet3);
data.setBarWidth(0.45f);
barChart.setData(data);
barChart.setNoDataText("No Data Found!!!");
barChart.setNoDataTextColor(Color.YELLOW);
barChart.setFitBars(true);
barChart.animateY(2000);
barChart.setDrawGridBackground(false);
barChart.setDrawBorders(true);
barChart.getAxisRight().setEnabled(false);
barChart.setDescription(null);
barChart.getAxisLeft().setStartAtZero(true);
barChart.setVisibleXRange(2,10);
barChart.getAxisRight().setStartAtZero(true);
barChart.groupBars(2,0.72f,0.04f);
XAxis xAxis = barChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setTextSize(8);
barChart.getXAxis().setValueFormatter(new IndexAxisValueFormatter(labels)); //labels list have values "original estimate,1,2,3,4,5"
xAxis.setLabelCount(labels.size());
xAxis.setDrawGridLines(false);
xAxis.setAxisLineColor(Color.BLACK);
xAxis.setAxisLineColor(Color.rgb(255, 51, 153));
barChart.setDrawValueAboveBar(false);
YAxis yAxis = barChart.getAxisLeft();
yAxis.setDrawAxisLine(false);
yAxis.setDrawGridLines(false);
yAxis.setLabelCount(5);
}
IndexAxisValueFormatter.java
this is uded to set the labels
public class IndexAxisValueFormatter implements IAxisValueFormatter {
private String[] mValues = new String[] {};
private int mValueCount = 0;
#Override
public String getFormattedValue(float value, AxisBase axis) {
int index = Math.round(value);
if (index < 0 || index >= mValueCount || index != (int)value)
return "";
return mValues[index];
}
public IndexAxisValueFormatter() {
}
public IndexAxisValueFormatter(String[] values) {
if (values != null)
setValues(values);
}
public IndexAxisValueFormatter(Collection<String> values) {
if (values != null)
setValues(values.toArray(new String[values.size()]));
}
public String[] getValues()
{
return mValues;
}
public void setValues(String[] values)
{
if (values == null)
values = new String[] {};
this.mValues = values;
this.mValueCount = values.length;
}
}
When i run this code only "4 and 5 " labels are displayed on the chart in reverse order. cannot see remaining labels
Why You don't use v3.0.2?
Visit this link, there is example how to do combined chart.
https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CombinedChartActivity.java
I'm finding it a bit difficult to figure out how to implement time in the X Axis of a graph in Android?
This is my code:
for (int i = 0; i < listSize; i++)
{
String[] onlyReading = mData.get(i).getReading().split(" ");
readingList[i] = Double.parseDouble(onlyReading[0]);
String date = mData.get(i).getUnFormatedDate();
String[] temp = date.split(" ");
String[] dateTemp = null;
String[] timeTemp = null;
if(temp.length > 0)
{
dateTemp = temp[0].trim().split("-");
timeTemp = temp[1].trim().split(":");
Date dateObj = new Date();
String year = "0";
if(dateTemp != null)
{
dateObj.setDate(Integer.parseInt(dateTemp[0]));
dateObj.setMonth(Integer.parseInt(dateTemp[1]) - 1);
year = dateTemp[2].trim();
if(dateTemp[2].trim().length() == 4)
{
year = dateTemp[2].substring(2, 4);
}
dateObj.setYear(Integer.parseInt(year)+100);
}
if(timeTemp != null)
{
calendar = new GregorianCalendar(Integer.parseInt(year) + 2000, Integer.parseInt(dateTemp[1]) - 1, Integer.parseInt(dateTemp[0]), Integer.parseInt(timeTemp[0]), Integer.parseInt(timeTemp[1]));
}
dateObj = new Date(calendar.getTimeInMillis());
dateList[i] = dateObj;
}
}
if(dateList.length > 0)
{
//dates.clear();
//values.clear();
//readingData.clear();
//readingDate.clear();
GraphViewData[] data = new GraphViewData[dateList.length];
LineGraphView graphView = new LineGraphView(
getActivity() // context
, "" // heading
);
for (int i = 0; i < listSize; i++)
{
data[i] = new GraphViewData(Double.valueOf(i), readingList[i]);
}
GraphViewSeries exampleSeries = new GraphViewSeries(data);
graphView.addSeries(exampleSeries);
graphView.setDrawBackground(false);
((LineGraphView) graphView).setDrawDataPoints(true);
graphView.getGraphViewStyle().setGridColor(0);
graphView.getGraphViewStyle().setHorizontalLabelsColor(Color.WHITE);
graphView.getGraphViewStyle().setVerticalLabelsColor(Color.WHITE);
graphView.getGraphViewStyle().setNumHorizontalLabels(5);
graphView.getGraphViewStyle().setNumVerticalLabels(5);
graphView.setManualYAxisBounds(400, 0);
mGraphParent.addView(graphView);
}
}
Even though I add the Y axis values, I'm not able to figure out how to add time values to the X-axis?
I know it is an old question, but I solved by using DefaultLabelFormatter().
graphView.getGridLabelRenderer().setLabelFormatter(new DefaultLabelFormatter() {
#Override
public String formatLabel(double value, boolean isValueX) {
if (isValueX) {
Format formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return formatter.format(value);
}
return super.formatLabel(value, isValueX);
}
});
Based on the following video:
https://www.youtube.com/watch?v=xt8gx7Z7yJU
the trick is to just convert the time to seconds or milliseconds (unix time) and you it as X-value.
There's an example on the GraphView-Demos project. Take a look at:
https://github.com/jjoe64/GraphView-Demos/blob/master/src/com/jjoe64/graphviewdemos/CustomLabelFormatterActivity.java#L68
I had the same issue. The easiest method was to convert Time into milliseconds. Using a Gregorian Calendar might be more helpful as the methods in Date are deprecated.
Calendar cal=new GregorianCalendar(2014,6,12,9,30,0);
data[i]=new GraphViewData(cal.getTimeInMillis,VALUE);
Then set the CustomLabelFormatter.
graphView.setCustomLabelFormatter(new CustomLabelFormatter() {
#Override
public String formatLabel(double value, boolean isValueX) {
// TODO Auto-generated method stub
if (isValueX) {
Date d = new Date((long) (value));
return (dateFormat.format(d));
}
return "" + (int) value;
}
});
Time/Date appears in the format specified in dateFormat.