DateTime Issue in MPAndroidChart - android

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();
}

Related

How to get entries to match xAxis values MP line chart, Android

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"

Mountain Chart Logarithmic

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();
}
});

How to make the CombinedChart-BarChart average distributed on the x-axis?

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();
}

How to show labels on right and values to left side in HorizontalBarChart?

Drawing a horizontal bar chart using MPAndroidChart 3.0.2. the values are shown on the right of the bars. I could use setValueFormatter and use IAxisValueFormatter interface to display the labels on the right. But the values are not displayed now.
{
HorizontalBarChart barChart = (HorizontalBarChart) itemView.findViewById(R.id.barChart);
BarData data = new BarData();
ArrayList<BarEntry> valueSet1 = new ArrayList<>();
ArrayList<String> labels = new ArrayList<>();
labels.add("January");
labels.add("February");
labels.add("March");
labels.add("April");
labels.add("May");
labels.add("June");
ArrayList<String> ylabels = new ArrayList<>();
int dataCount=0;
for (int i=0;i<6;++i) {
BarEntry entry = new BarEntry(dataCount,(i+1)*2);
valueSet1.add(entry);
ylabels.add(" "+i);
dataCount++;
}
List<IBarDataSet> dataSets = new ArrayList<>();
BarDataSet bds = new BarDataSet(valueSet1, " ");
bds.setColors(ColorTemplate.MATERIAL_COLORS);
String[] xAxisLabels = labels.toArray(new String[0]);
String[] yAxisLabels = ylabels.toArray(new String[0]);
bds.setStackLabels(xAxisLabels);
dataSets.add(bds);
data.addDataSet(bds);
data.setDrawValues(true);
data.setBarWidth(0.4f);
XAxis xaxis = barChart.getXAxis();
xaxis.setDrawGridLines(false);
xaxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xaxis.setGranularityEnabled(true);
xaxis.setGranularity(1);
xaxis.setDrawLabels(true);
xaxis.setLabelCount(dataCount+1);
xaxis.setXOffset(10);
xaxis.setDrawAxisLine(false);
CategoryBarChartXaxisFormatter xaxisFormatter = new CategoryBarChartXaxisFormatter(xAxisLabels);
xaxis.setValueFormatter(xaxisFormatter);
YAxis yAxisLeft = barChart.getAxisLeft();
yAxisLeft.setEnabled(false);
YAxis yAxisRight = barChart.getAxisRight();
yAxisRight.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
yAxisRight.setDrawGridLines(false);
yAxisRight.setDrawAxisLine(false);
Legend legend = barChart.getLegend();
legend.setEnabled(false);
barChart.setFitBars(true);
barChart.setData(data);
barChart.setDescription(null);
}
public class CategoryBarChartXaxisFormatter implements IAxisValueFormatter {
private String[] mValues;
public CategoryBarChartXaxisFormatter(String[] values) {
this.mValues = values;
}
#Override
public String getFormattedValue(float value, AxisBase axis) {
int val = (int)value;
String label="";
if(val>=0 && val<mValues.length) {
label= mValues[val];
}
else {
label= "";
}
return label;
}
}
requirement is to display label strings on the right and a number on the left corresponding to each bar.
I did check some stack overflow and google it but didn't find anything that works so far.
i get this
but this is an example of my requirement
Do appreciate some help.
Thanks for your time
I implemented something similar just a few days back. Here's the code...
public class MainActivity extends AppCompatActivity {
protected HorizontalBarChart mChart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<String> labels = new ArrayList<>();
labels.add("January");
labels.add("February");
labels.add("March");
labels.add("April");
labels.add("May");
labels.add("June");
mChart = (HorizontalBarChart) findViewById(R.id.barChart);
mChart.setDrawBarShadow(false);
mChart.setDrawValueAboveBar(true);
mChart.getDescription().setEnabled(false);
mChart.setPinchZoom(false);
mChart.setDrawGridBackground(false);
XAxis xl = mChart.getXAxis();
xl.setPosition(XAxis.XAxisPosition.BOTTOM);
xl.setDrawAxisLine(true);
xl.setDrawGridLines(false);
CategoryBarChartXaxisFormatter xaxisFormatter = new CategoryBarChartXaxisFormatter(labels);
xl.setValueFormatter(xaxisFormatter);
xl.setGranularity(1);
YAxis yl = mChart.getAxisLeft();
yl.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
yl.setDrawGridLines(false);
yl.setEnabled(false);
yl.setAxisMinimum(0f);
YAxis yr = mChart.getAxisRight();
yr.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
yr.setDrawGridLines(false);
yr.setAxisMinimum(0f);
ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
for (int i = 0; i < 6; i++) {
yVals1.add(new BarEntry(i, (i+1)*10));
}
BarDataSet set1;
set1 = new BarDataSet(yVals1, "DataSet 1");
ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
dataSets.add(set1);
BarData data = new BarData(dataSets);
data.setValueTextSize(10f);
data.setBarWidth(.9f);
mChart.setData(data);
mChart.getLegend().setEnabled(false);
}
public class CategoryBarChartXaxisFormatter implements IAxisValueFormatter {
ArrayList<String> mValues;
public CategoryBarChartXaxisFormatter(ArrayList<String> values) {
this.mValues = values;
}
#Override
public String getFormattedValue(float value, AxisBase axis) {
int val = (int) value;
String label = "";
if (val >= 0 && val < mValues.size()) {
label = mValues.get(val);
} else {
label = "";
}
return label;
}
}
}
RESULT
Hope this helps.

No data appears on BarChart for X entries when you use y-values as floats

I have tried to add a BarChart in my Code, nothing appear when I launch my app.
The purpose of my code is that: when the user enter the start date (StartDate), end date (EndDate) and the product name, the graph should show the show price evolution during that period.
I have tried the code below, but nothing appear on the graph.
Please help to find the issue, or propose to me another code.
public class ResultProductStatisticsActivity extends AppCompatActivity {
private String mCategory;
private String mName;
private long mStartDate;
private long mEndDate;
private int mNumber = 0;
private ProgressBar mProgressBar;
private ArrayList<ShopDetail> mDetail = new ArrayList<ShopDetail>();
private ArrayList<Float> mPriceList = new ArrayList<Float>();
protected Typeface mTfLight;
private Typeface mTypeFaceLight;
private TextView mMontextViewtest;
private BarChart mChart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.result_product_statistics_activity);
mChart = (BarChart) findViewById(R.id.m_barchart);
// mChart.setOnChartValueSelectedListener(this);
mChart.setDrawBarShadow(false);
mChart.setDrawValueAboveBar(true);
mChart.setDescription("");
// if more than 60 entries are displayed in the chart, no values will be
// drawn
mChart.setMaxVisibleValueCount(60);
// scaling can now only be done on x- and y-axis separately
mChart.setPinchZoom(false);
mChart.setDrawGridBackground(false);
// mChart.setDrawYLabels(false);
AxisValueFormatter xAxisFormatter = new DayAxisValueFormatter(mChart);
XAxis xAxis = mChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setTypeface(mTfLight);
xAxis.setDrawGridLines(false);
xAxis.setGranularity(1f); // only intervals of 1 day
xAxis.setLabelCount(7);
xAxis.setValueFormatter(xAxisFormatter);
AxisValueFormatter custom = new MyAxisValueFormatter();
YAxis leftAxis = mChart.getAxisLeft();
leftAxis.setTypeface(mTfLight);
leftAxis.setLabelCount(8, false);
leftAxis.setValueFormatter(custom);
leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
leftAxis.setSpaceTop(15f);
leftAxis.setAxisMinValue(0f); // this replaces setStartAtZero(true)
YAxis rightAxis = mChart.getAxisRight();
rightAxis.setDrawGridLines(false);
rightAxis.setTypeface(mTfLight);
rightAxis.setLabelCount(8, false);
rightAxis.setValueFormatter(custom);
rightAxis.setSpaceTop(15f);
rightAxis.setAxisMinValue(0f); // this replaces setStartAtZero(true)
Legend l = mChart.getLegend();
l.setPosition(Legend.LegendPosition.BELOW_CHART_LEFT);
l.setForm(Legend.LegendForm.SQUARE);
l.setFormSize(9f);
l.setTextSize(11f);
l.setXEntrySpace(4f);
// l.setExtra(ColorTemplate.VORDIPLOM_COLORS, new String[] { "abc",
// "def", "ghj", "ikl", "mno" });
// l.setCustom(ColorTemplate.VORDIPLOM_COLORS, new String[] { "abc",
// "def", "ghj", "ikl", "mno" });
init();
mChart.setMarkerView(new XYMarkerView(this, xAxisFormatter));
}
private void init(){
mCategory = Myrecord.getSearchShopCategory(this);
mName = Myrecord.getSearchShopName(this);
mStartDate = Myrecord.getSearchStartTime(this);
mEndDate = Myrecord.getSearchEndTime(this);
if(mStartDate == -1){
mStartDate = Long.MIN_VALUE;
}
if(mEndDate == -1){
mEndDate = Long.MAX_VALUE;
}
Thread thread = new Thread(){
#Override
public void run() {
MyDB db = new MyDB(ResultProductStatisticsActivity.this);
ArrayList<MyDetail> detailList = db.getMyDetailByAll(mCategory, mName, -1, 0, -1);
for(int i = 0; i < detailList.size(); i ++){
MyDetail detail = detailList.get(i);
long date = detail.date;
if(date >= mStartDate && date <= mEndDate){
mPriceList.add(db.getPriceGoodsByOwnName("ALEVONS")+0f);
}
}
ResultProductStatisticsActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
setData(mPriceList);
}
});
}
};
thread.start();
}
private void setData(ArrayList<Float> mPriceList) {
mChart.getXAxis().setAxisMinValue(mStartDate);
mChart.getXAxis().setAxisMaxValue(mEndDate);
ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
for (int i = 0; i < mPriceList.size(); i++) {
yVals1.add(new BarEntry(i , mPriceList.get(i)));
}
BarDataSet set1;
if (mChart.getData() != null &&
mChart.getData().getDataSetCount() > 0) {
set1 = (BarDataSet) mChart.getData().getDataSetByIndex(0);
set1.setValues(yVals1);
mChart.getData().notifyDataChanged();
mChart.notifyDataSetChanged();
} else {
set1 = new BarDataSet(yVals1, "Evolution du prix produit");
set1.setColors(ColorTemplate.MATERIAL_COLORS);
ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
dataSets.add(set1);
BarData data = new BarData(dataSets);
data.setValueTextSize(10f);
data.setValueTypeface(mTfLight);
data.setBarWidth(0.9f);
mChart.setData(data);
}
}
}
A wild guess, without any more details provided: your're setting the x-axis min and max values to the start and end date. I'm guessing this is encoded in unix time, so you have something like 1470614400 and 1471219200.
Now looking at your data, it will start with 0 and go up to the number of prices you have in your price list (mPriceList.size()). So with 10 prices we'd have values at 0 through 9. However, since your x-axis starts at 1470614400, no data will be shown (although the axis, gridlines etc. should be visible).
So in order to fix your code (depending on how your price list is structured, this example assumes one price every hour), you'd need to change your code in setData to this:
for (int i = 0; i < mPriceList.size(); i++) {
yVals1.add(new BarEntry(mStartDate + i * 3600, mPriceList.get(i)));
}
If you have a list of dates associated with the price values, you can also simply do this:
for (int i = 0; i < mPriceList.size(); i++) {
yVals1.add(new BarEntry(mDateList.get(i), mPriceList.get(i)));
}
We the reply of(#TR4Android),
I have update my code such below and I can get the graph:
float start = 0f;
mChart.getXAxis().setAxisMinValue(start);
mChart.getXAxis().setAxisMaxValue(mPriceList.size());
for (int i = 0; i < mPriceList.size(); i++) {
yVals1.add(new BarEntry(i , mPriceList.get(i)));
}
But I have a bit issue with start date end date where each item has been bought. I have put each date in array list but I don't see how I can put it on xAxis. The Array list is :
private ArrayList<Long> mDateList = new ArrayList<Long>();
One example of mDateList value is 2016/08/13

Categories

Resources