Closed joshisunil-1983 closed 9 years ago
Set this "01/01/2001" and so on as an x-axis label, place your values to the correct x-indices
I have literally done this today. It's quite easy. Labels on the X Axis can be whatever strings. I converted a list of dates to my preferred format and set them as the X values like so: LineData lineData = new LineData(xValues);
. You then have to set values to corresponding indices, like @PhilJay said before.
@silviul Did you do that for Shazam? Or something else?
@PhilJay I'm just playing with the library. Not for Shazam.
I'm hoping for the exact function. Not only what I want date as string, but I hope the date label can be dynamically according to zoom gestures. For example, if I'm showing one year of data, I want the label as months but if I zoomed in and is only showing one month of data, then the label could be days. Is it possible to achieve this with overriding some methods?
Now possible:
Example formatter:
That seems to BE working only for the bar chart or am getting something wrong??
@Griffins The api just updated thoroughly and the documentation is out of date, as said here. This confuses me for the whole morning.
But I kind of like the new way, treating X and Left and Right Axis all the same. And if you want to show some special labels according to the data, on any axis, use the formatter. Just hope the new documentation will be out soon. @PhilJay
Hi. I have a list in Array of 480 date and time each day (timestamp). I would like to fix this in X axi, How can do it automatically (not typing one by one) I get in ansyncronic process it, if "labels" are fixed OnCreate, means it is filled before I get data later on ansyncronic task... Any code exemple to help me...
How to give two space between two bars in stacked bar.And total count on top of bar .I am using .PhilJay:MPAndroidChart:v3.0.0-beta1'.Please help me
Note: below solution was implemented using the following version:
compile 'com.github.PhilJay:MPAndroidChart:v3.0.0-beta1'
This workaround is based on the implementation of "DayAxisValueFormatter.java" suggested previously by @PhilJay. Final result looks like this:
Say, for example, we have this data set:
x | y |
---|---|
2016-01-01 15:00:00 GMT | 25 |
2016-01-01 22:00:00 GMT | 58 |
2016-01-02 08:00:00 GMT | 36 |
2016-01-02 14:00:00 GMT | 12 |
2016-01-02 19:00:00 GMT | 29 |
We would like to populate a MPAndroidChart LineChart instance with above date set but we can only do so using a float type in the form: Entry(float x, float y). One easy way to handle this obstacle is to convert all dates to timestamps to get this result:
x | y |
---|---|
1451660400 | 25 |
1451685600 | 58 |
1451721600 | 36 |
1451743200 | 12 |
1451761200 | 29 |
Now, it seems like we should be good to go but one final adjustment is still required. When I tried these huge x values, my chart became really slow especially when zooming in and out.
As a solution to this, we can further manipulate these x values by using this conversion:
Xnew = Xold - reference_timestamp
First timestamp in a sorted data set should be the minimum timestamp which can be perfectly used as a zero reference. In that case, if we apply this equation to our sorted data set such as:
reference_timestamp = 1451660400
we get this new data set:
x | y |
---|---|
0 | 25 |
25200 | 58 |
61200 | 36 |
82800 | 12 |
100800 | 29 |
We can even reduce these numbers by converting from seconds timestamps to minutes timestamps if that is really needed.
Make sure to keep reference_timestamp stored in a global variable so that you can retrieve your original timestamp when needed.
At this moment, your chart should be working smoothly but your x axis will show labels that has no meaning to your user. Let's add some meaning to our x axis by using this value formatter which provides a nice label to our dataset in hours and minutes (HH:mm): HourAxisValueFormatter.java
You can apply it in this way:
AxisValueFormatter xAxisFormatter = new HourAxisValueFormatter(referenceTimestamp);
XAxis xAxis = mChart.getXAxis();
xAxis.setValueFormatter(xAxisFormatter);
More details about MarkerView can be found here wiki.
Use MyMarkerView.java to show full date and time when a value is pressed. Implementation is easy just call setMakerView() like this:
MyMarkerView myMarkerView= new MyMarkerView(getApplicationContext(), R.layout.my_marker_view_layout, referenceTimestamp);
mChart.setMarkerView(myMarkerView);
R.layout.my_marker_view_layout is found here: custom_marker_view.xml and @drawable/marker2 is found here: marker2.png
hi yasir can you gave me some example?
Can you give an XML example of your MyMarkerView layout? I would like to know how you got the nice triangle at the bottom?
@gmkdev Please refer to my last comment. I revised the whole comment and provided more explanations.
@LeslieJG I added more details about MyMarkerView layout in my last comment. See last two lines. Best of luck.
@Yasir-Ghunaim I am doing exactly same but i want to ask why x -axis values do not start from zero. means why your first value is away from origin ? can we force it to start from origin for first value ?
@hammadtariqsahi Actually, my x-axis values start from 0 (refer to data set shown in the second step in my guide). The formatted (HH:mm) x values you are seeing in the provided screenshot are simply a result of a ValueFormatter that translates the converted timestamps (x values) to a more user friendly format.
Hi phil, I want to set dates to xAxis ,How can I achieve this?
i want to set dates to xaxis on the bar,how can i achieve this?
@ashwinipawar1710 You can format the SimpleDateFormat as you wish in @Yasir-Ghunaim ' s HourAxisValueFormatter like this where i show the date before the time.
public HourAxisValueFormatter(long referenceTimestamp) { this.referenceTimestamp = referenceTimestamp; this.mDataFormat = new SimpleDateFormat("dd-HH:mm", Locale.ENGLISH); this.mDate = new Date(); }
Dont mind the broken marker and generally poor design.
@PhilJay look at may captured codes. I am new with mpandroidchart library, I am currently developing an application with bar graphs. I want to set my xVal as dates. but it seems BarData is not accepting a string parameter. hope you response ASAP. Thank you and God bless
@PhilJay Is setting data in bar chart is different from linechart? I watched some tutorials and tried their codes, but it did not work with my project. I'm having an error with the parameter in BarData. when I removed the "labels" as parameter in BarData and left the "set" parameter, it properly works. and i tried it also with LineChart, LineData accepts 2 parameters. only in BarChart I am having a trouble. Please help me. Thanks!
@PhilJay please do notice me. ty
http://stackoverflow.com/questions/41716677/getting-error-in-implementing-dayaxisvalueformatter-using-mpandroidchart Please resolve this @PhilJay
@Yasir-Ghunaim As per the reference given by you for the time support on X-Axis(#789). I m using your solution exactly for Multi line chart. But the data on my X Axis is repetitive and not in the correct order. I am not sure why this is happening. I have already asked the question with the details of the data that i m using to plot the graph. Please look at the issue : #2775
It would be great if u can help me with the solution. Thanks
@Yasir-Ghunaim in your demonstration when you converted dates to Timestamps how do you pass them in the Entry method which requires float value ?
@Yasir-Ghunaim Thank you for the wonderful solution. But the methods in the MarkerView class in Phil's code has changed. How do I incorporate these changes in your code?
@DivyaBansal Could you point out which methods were changed as I am not keeping up with latest updates?
Alternatively, refer to this version that I initially used:
compile 'com.github.PhilJay:MPAndroidChart:v3.0.0-beta1'
and compare MarkerView methods in this version against latest version.
@Yasir-Ghunaim
How do I create a label for when I touch
the screen on one of the scales the values โโof the x and y axis appear? As the one that appears a value 50% and the date in LineChart?
Marker arrow was not consistent so I did it in alternate approach
Example with Android Toast
Steps
OnChartValueSelectedListener
public class APrioriResultActivity extends AppCompatActivity implements OnChartValueSelectedListener
OnChartValueSelectedListener
barChart.setOnChartValueSelectedListener(this);
and then implement onValueSelected
method to paint data on screen in whichever way you like ie- Toast, Snack bar, dialog, TextView etc
Toast mCurrentToast;
@Override
public void onValueSelected(Entry e, Highlight h) {
if (mCurrentToast != null) {
mCurrentToast.cancel();
}
mCurrentToast = Toast.makeText(this, "Support for" +
setEntries.get(Math.round(e.getX())) + " is " + e.getY(),
Toast.LENGTH_LONG);
mCurrentToast.show();
}
@Override
public void onNothingSelected() {
}
If anyone using compile 'com.github.PhilJay:MPAndroidChart:v3.0.2'
I made couple of changes in @Yasir-Ghunaim 's solution AxisValueFormatter is not there anymore so use this
HourAxisValueFormatter axisFormatter = new HourAxisValueFormatter(minTimeStamp); chart.getXAxis().setValueFormatter(axisFormatter);
package com.healthifyme.basic.diy_reports;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* Created by Abhishek on 08/06/17.
*/
public class HourAxisValueFormatter implements IAxisValueFormatter {
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();
}
/**
* Called when a value from an axis is to be formatted
* before being drawn. For performance reasons, avoid excessive calculations
* and memory allocations inside this method.
*/
@Override
public String getFormattedValue(float value, AxisBase axis) {
// convertedTimestamp = originalTimestamp - referenceTimestamp
long convertedTimestamp = (long) value;
// Retrieve original timestamp
long originalTimestamp = referenceTimestamp + convertedTimestamp;
// Convert timestamp to hour:minute
return getHour(originalTimestamp);
}
private String getHour(long timestamp) {
try {
mDate.setTime(timestamp * 1000);
return mDataFormat.format(mDate);
} catch (Exception ex) {
return "xx";
}
}
}
I have an implementation like this, but the problem is that the labels are not equally spaced. For example I want labels like '11:00' , '11:30' , '12:00', '12:30' ,etc and I'm getting 10:59 , 11:31, 12:04, 12:29, etc.
Any clue how to achieve this @Yasir-Ghunaim ?
Here is a capture of what I'm talking.
@adriamt I noticed this problem earlier but didn't know how to fix it. Based on several experiments, existing algorithm places labels at multiples of 100s, 1000s, 5000s which doesn't look nicely with seconds and minutes. I think one way would be to explore AxisBase and ComponentBase classes and see whether you can manipulate their algorithm so that labels are positioned at every an hour or at every multiple of 3600 (i.e. at 3600, 7200, etc).
Once you achieve that, you might want to provide an offset to this labeling mechanism so that if your reference timestamp doesn't start at the exact beginning of an hour, you could simply shift the multiples of 3600 to match your data set structure.
Workaround for putting dates [String] on XAxis, maintaining proportional spacing:
override getFormattedValue to build your Date from "value" and format it to whatever string you like ....... public class DateAxisValueFormatter implements IAxisValueFormatter { private String[] mValues; SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
public DateAxisValueFormatter(String[] values) { this.mValues = values; }
//@Override public String getFormattedValue(float value, AxisBase axis) { return sdf.format(new Date((long)value)); } } ......
How would you go about putting on the x axis the day and inbetween days the time in hh:mm ??
Is it possible to write date on X axis in two lines? For example like this: 2017 12.10
@gxlinda save the date string using " \n " between 2017 and 12.10
toFormatter.dateFormat = "hh:mm a \n dd/MM/yy"
is it possible to show the only month in xAxis? and set (highlighter) label when a user clicks nearby points.
yes it is possible, you can provide xAxis data Array to be displayed. myChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values:XaxisDataArray)
Where can I use xAxis data array
On Fri, Sep 28, 2018, 4:35 PM CG-Vivek notifications@github.com wrote:
yes it is possible, you can provide xAxis data Array to be displayed.
โ You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/PhilJay/MPAndroidChart/issues/789#issuecomment-425401755, or mute the thread https://github.com/notifications/unsubscribe-auth/AY20_hnJjEYtf3KS_xp_gyF9te6MqCksks5ufgJ-gaJpZM4FIO6X .
Can you help me, i have a probleme with date truncate, for exemple (06/09) and that is my code: public class CombinedChartAdria extends CombinedChart {
private CombinedChart mChart;
private ArrayList<Entry> entriesLine;
private ArrayList<BarEntry> entriesBar;
private List<ChartModel> chartModels;
private int positifColor, negatifColor;
private int mRadius;
public CombinedChartAdria(Context context) {
super(context);
}
public CombinedChartAdria(Context context, AttributeSet attrs) {
super(context, attrs);
mRadius = attrs.getAttributeIntValue("http://schemas.android.com/apk/res-auto", "rounded", 0);
}
public void initChart(final List<ChartModel> chartModels) {
this.chartModels = chartModels;
entriesLine = new ArrayList<>();
mChart = findViewById(R.id.chart);
mChart.setHighlightFullBarEnabled(false);
// draw bars behind lines
YAxis rightAxis = mChart.getAxisRight();
rightAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
rightAxis.setDrawLabels(false); // no axis labels
rightAxis.setDrawAxisLine(false); // no axis line
rightAxis.setDrawGridLines(false); // no grid lines
rightAxis.setTypeface(Utils.getTypeFaceRegular(this.getContext()));
rightAxis.setDrawZeroLine(true); // draw a zero line
rightAxis.setGridLineWidth(0.5f);
YAxis leftAxis = mChart.getAxisLeft();
leftAxis.setDrawLabels(true); // no axis labels
leftAxis.setDrawAxisLine(false); // no axis line
leftAxis.setDrawGridLines(false); // no grid lines
leftAxis.setTextSize(6f);
leftAxis.setTextColor(getResources().getColor(R.color.txtMainColor));
leftAxis.setTypeface(Utils.getTypeFaceRegular(this.getContext()));
leftAxis.setDrawZeroLine(true); // draw a zero line
leftAxis.setGridLineWidth(1f);
XAxis xAxis = mChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawLabels(true); // no axis labels
xAxis.setDrawAxisLine(false); // no axis line
xAxis.setDrawGridLines(false); // no grid lines
xAxis.setTextSize(6f);
xAxis.setTextColor(getResources().getColor(R.color.txtMainColor));
xAxis.setTypeface(Utils.getTypeFaceRegular(this.getContext()));
xAxis.setGranularity(1f);
xAxis.setLabelRotationAngle(-90);
xAxis.setCenterAxisLabels(false);
xAxis.setAxisMinimum(0);
xAxis.setGranularityEnabled(false);
xAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
return chartModels.get((int) value).getLabel();
}
});
xAxis.setLabelCount(chartModels.size());
CombinedData data = new CombinedData();
data.setData(generateLineData());
data.setData(generateBarData());
xAxis.setAxisMinimum(data.getXMin() - 0.5f);
xAxis.setAxisMaximum(data.getXMax() + 0.5f);
//mChart.setViewPortOffsets(-10f, 0f, 0f, -10f);
this.animateXY(1000, 1000);
Paint paint = this.getRenderer().getPaintRender();
int height = 200;
LinearGradient linGrad = new LinearGradient(0, 0, 0, height,
getResources().getColor(R.color.colorRedGradient),
getResources().getColor(R.color.colorGradient2),
Shader.TileMode.CLAMP);
paint.setShader(linGrad);
this.setData(data);
this.invalidate();
}
private LineData generateLineData() {
entriesLine = new ArrayList<>();
positifColor = getResources().getColor(R.color.colorBgDark);
negatifColor = getResources().getColor(R.color.graphBodyColor);
for (ChartModel chartModel : chartModels)
entriesLine.add(chartModel.getBarEntry());
final ArrayList<Integer> listColor = new ArrayList<>();
for (Entry entry : entriesLine) {
listColor.add(entry.getY() < 0 ? negatifColor : positifColor);
}
LineDataSet dataset = new LineDataSet(entriesLine, "label");
dataset.setDrawValues(false);
dataset.setDrawFilled(false);
dataset.setMode(LineDataSet.Mode.LINEAR); // Line type
dataset.setColors(listColor);
dataset.setCircleColor(positifColor);
dataset.setCircleRadius(1.5f);
dataset.setCircleColorHole(positifColor);
//dataset.setDrawCircles(false);
LineData data = new LineData(dataset);
return data;
}
private BarData generateBarData() {
entriesBar = new ArrayList<>();
positifColor = getResources().getColor(R.color.colorGradient2);
negatifColor = getResources().getColor(R.color.graphBodyColor);
for (ChartModel chartModel : chartModels) {
entriesBar.add(chartModel.getBarEntry());
}
final ArrayList<Integer> listColor = new ArrayList<>();
for (BarEntry barEntry : entriesBar) {
listColor.add(barEntry.getY() < 0 ? negatifColor : positifColor);
}
BarDataSet dataset = new BarDataSet(entriesBar, "label");
dataset.setDrawValues(false);
dataset.setColors(positifColor);
BarData data = new BarData(dataset);
data.setBarWidth(0.4f);
this.setDescription(null);
this.getLegend().setEnabled(false);
this.setTouchEnabled(false);
this.setScaleEnabled(false);
this.animateXY(1000, 1000);
Paint paint = this.getRenderer().getPaintRender();
int height = 200;
LinearGradient linGrad = new LinearGradient(0, 0, 0, height,
getResources().getColor(R.color.colorRedGradient),
getResources().getColor(R.color.colorGradient2),
Shader.TileMode.CLAMP);
paint.setShader(linGrad);
this.invalidate();
return data;
}
}
I am trying to draw dynamic line graph , where i will get temperature value from sensor , I need to draw time vs temperature graph . I have stuck in formatting x axis .
This method giving me the solution upto some extent while inserting value i am using
Calendar c = Calendar.getInstance();
SimpleDateFormat dateformat = new SimpleDateFormat("HHmm");
String hoursMins= dateformat.format(c.getTime());
setData(hoursmins,temperatureValue);
xAxis.setValueFormatter(new IAxisValueFormatter() {
private DecimalFormat mFormat= new DecimalFormat("#0.00");
@Override
public String getFormattedValue(float value, AxisBase axis) {
value= (float) value/100; //This is to splitup hours and minutes as it is combined 4 digit integer
return mFormat.format(value);
}
But the issue i am facing here is , as i am using DecimalFormat , the X-axis is taking values from 0.1 to 0.9 But i wil get time only up to 0.60 (which means 60 minutes) from 0.60 to 0.90 nothing will be plotted and that wont look good as gap between the hours. I have tried many solutions but none of those gave me the solution i wanted. Anyone please help me out to solve this.
it is possible to have 24 points on the abscissa?
Hi Arias yes you can have multiple points on the abscissa.
On Sun, Apr 21, 2019 at 9:38 PM Don Arias notifications@github.com wrote:
it is possible to have 24 points on the abscissa?
โ You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/PhilJay/MPAndroidChart/issues/789#issuecomment-485263296, or mute the thread https://github.com/notifications/unsubscribe-auth/AIQRBMOGXFLCMR54DH5KTALPRSGQ5ANCNFSM4BJA52LQ .
@CG-Vivek Ok thank you very much for your answer, I explain what I want to do but I do not know how to take to do that. I want to display the graphs by setting the hours of the day, but also in the last 7 days of the week and also the last 30 days
@CG-Vivek basically the user of my graph will have the choice to see the evolution of graph during the day, but also of the week, and also the month always with the same data
@DonGorias229 yes you can do this using MPCharts, i don't find any complexity what you want from me?
@CG-Vivek yes exactly I can do for a day but I do not know how to do it for the last 7 days and the last 30 days, can you help me?
find attached a catch for that of the day
@DonGorias229 sure can help you, if it's about iOS development.
I think that the formatting logic will be the same in Android as in iOS, explain me how to do in iOS that can help me in something
@DonGorias229 If you have control over data and can filter day/week/month data in iOS i just provide formatted data to xAixs LineChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values:xaxisData)
hi, i am using MPandroid chart in my app. i want to plot chart using values on y axis and date on x axis. I don't find any datetime axis in mp android chart. is there any way to plot x axis using date. i have values against date. i want to show the dates in (ddMMM-yy) format on x axis and the values on y axis. anyone can pass me the sample link for the same.
sample for data: Date(X axis) Value(Y axis) 01/01/2001 966.78 01/02/2001 666.78 01/03/2001 966.78 01/04/2001 966.78 01/05/2001 966.78 01/06/2001 966.78 01/07/2001 966.78
guide.