Is there supposed to be animation when I have an updated set of data values, and then updating the chart with them values and calling chart.notifyDataSetChanged in MPAndroidChart?
I would assume the effect would be similar to the bar growing in length or reducing in length accordingly, but it simply just snaps to the value.
Code:
if (m_chartHourlySales.getData() != null &&
m_chartHourlySales.getData().getDataSetCount() > 0)
{
set1 = (BarDataSet)m_chartHourlySales.getData().getDataSetByIndex(0);
set1.setValues(values.value);
m_chartHourlySales.getData().notifyDataChanged();
m_chartHourlySales.notifyDataSetChanged();
} else {
set1 = new BarDataSet(values.value, getResources().getString(R.string.total_sales_figures_for_each_hour));
set1.setValueFormatter(new ValueFormatter() {
#Override public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler)
{
return NumberFormat.getCurrencyInstance(Locale.getDefault()).format(value);
}
});
set1.setValueTextColor(Color.WHITE);
ArrayList<IBarDataSet> dataSets = new ArrayList<>();
dataSets.add(set1);
BarData data = new BarData(dataSets);
data.setValueTextSize(10f);
data.setBarWidth(barWidth.value);
m_chartHourlySales.moveViewToX(0);
m_chartHourlySales.setData(data);
m_chartHourlySales.setVisibleXRangeMaximum(17*20);
m_chartHourlySales.setVisibleXRangeMinimum(17*6);
m_chartHourlySales.moveViewToX(0);
}
m_chartHourlySales.invalidate();
m_chartHourlySales.refreshDrawableState();
Related
I've used the BarChart provided by MPAndroidChart library to display a bar graph.
When there is data for more than one values on the x-axis (in this case the date), the output is shown as expected. However, when there is data for only a single date, for some reason that date is displayed twice on the x-axis.
I would like to prevent one of the values from being displayed. Below is the code that is displayed the results in the image.
private void showBarGraph(List<Object> response) {
barChart.setNoDataText(getResources().getString(R.string.sorry_data_not_available));
barChart.clear();
if(response.size()>0) {
int highestValue = response != null && response.size() > 0 ? response.size() : 0;
barChart.getAxisLeft().setAxisMaximum(highestValue);
barChart.getAxisLeft().setAxisMinimum(0);
barChart.animateY(1000);
List<BarEntry> entries = new ArrayList<>();
List<String> xAxisValues = new ArrayList<>();
if (response != null) {
for (int i = 0; i < respones.size(); i++) {
entries.add(new BarEntry(i, response.get(i).getCount(), ContextCompat.getColor(getActivity(), R.color.graph)));
xAxisValues.add(response.get(i).getTimekey());
}
barChart.getAxisLeft().setLabelCount(highestValue > 10 ? 10 : highestValue, false);
barChart.getXAxis().setLabelCount(response.size() <= 12 ? response.size() : 12, false);
if (response.size() >= 4) {
barChart.getXAxis().setLabelRotationAngle(-45);
} else {
barChart.getXAxis().setLabelRotationAngle(0);
}
}
IndexAxisValueFormatter xAxisValueFormatter = new IndexAxisValueFormatter(xAxisValues);
barChart.getXAxis().setValueFormatter(xAxisValueFormatter);
BarXYMarkerView xymv = new BarXYMarkerView(getActivity(), xAxisValueFormatter);
// Set the marker to the chart
xymv.setChartView(barChart);
barChart.setMarker(xymv);
BarDataSet set = new BarDataSet(entries, null);
set.setDrawValues(false);
List<Integer> graphColors = new ArrayList<>();
graphColors.add(ContextCompat.getColor(getActivity(), R.color.graph));
set.setColors(graphColors);
BarData data = new BarData(set);
barChart.setData(data);
barChart.invalidate();
}
}
The code is good for data with entries on multiple dates. Can someone guide me on how I can prevent the duplicate date value when there is data for only one date.
I am working with a project which is using MPAndroidChart library which makes me really crazy, I want to remove it.
The problem is I have created a custom ValueFormatter and I can't understand where these values come from, all are wrong.
private void setData() {
for (int i = 1; i <= 10; i++) {
Entry entry = new Entry(i, i);
values.add(entry);
}
IAxisValueFormatter valueFormatter = new myValueFormatter();
XAxis xAxis = mChart.getXAxis();
xAxis.setValueFormatter(valueFormatter);
LineDataSet set1 = new LineDataSet(values, "DataSet 1");
ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
dataSets.add(set1); // add the datasets
// create a data object with the datasets
LineData data = new LineData(dataSets);
// set data
mChart.setData(data);
}
custom formatter class:
I have an array which has 1,2,3,4,5,6,7,8,9,10 values
but I get 2,4,6,8,10 values in getFormattedValue method.
public classmyValueFormatter implements IAxisValueFormatter {
#Override
public String getFormattedValue(float value, AxisBase axis) {
System.out.println(value); //Here I get odd values where they come from I don't know.
}
}
Well, generally that's how library is written. Have a look here:
https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRenderer.java#L205
String label = mXAxis.getValueFormatter().getFormattedValue(mXAxis.mEntries[i / 2], mXAxis);
Author's intention was probably to give more spacing between labels. If you think this is a bug, submit issue to library's repository on Github.
Does anybody have an idea on how to make this: my app image look like this: how it should be?
My question is: how to make each line of the Horizontal Bar Chart fill between the two lines?
for (Iterator<Map.Entry<String, Float>> iterator = structuredData.entrySet().iterator(); iterator.hasNext();) {
Map.Entry<String, Float> entry = iterator.next();
//i*10 => starting position of the bar
horizontalBarChartArr.add(new BarEntry((i*10), entry.getValue()));
names.add(entry.getKey());
i++;
}
XAxis xAxis = horizontalBarChart.getXAxis();
xAxis.setValueFormatter(new IAxisValueFormatter() {
#Override
public String getFormattedValue(float value, AxisBase axis) {
return names.get((int)value % names.size());
}
});
xAxis.setDrawGridLines(true);
xAxis.setDrawAxisLine(true);
BarDataSet barDataSet = new BarDataSet(horizontalBarChartArr, "Day Expenses");
barDataSet.setColors(Color.RED);
BarData data = new BarData(barDataSet);
data.setBarWidth(9f);
horizontalBarChart.setDoubleTapToZoomEnabled(false);
Description a = new Description();
a.setText("");
horizontalBarChart.setDescription(a);
horizontalBarChart.invalidate();
horizontalBarChart.animateY(1200);
horizontalBarChart.setData(data);
Check this example to your case:
https://github.com/ddanny/achartengine
It´s Automatically exported from code.google.com/p/achartengine
I have a small problem. I'm trying to make a listView of BarCharts, where xAxis represents categories, and yAxis - cost.
Here is my data.
entry
entries.add(new BarEntry(xAxis, cost, categoryName));
xAxis is just a position in chart, I put category name as 3rd parameter. Then I put it in array list of BarData
ArrayList<BarData> months = new ArrayList<>();
BarDataSet set = new BarDataSet(entries, monthName);
ArrayList<IBarDataSet> dataSets = new ArrayList<>();
dataSets.add(set);
BarData barData = new BarData(dataSets);
months.add(barData);
Then in adapter I set value formatter
BarData data = getItem(position);
...
xAxis.setValueFormatter(new MyValueFormatter(data.getDataSetByIndex(0)));
and in MyValueFormatter I'm trying to get category name from entry and set it as xAxis value.
public class MyValueFormatter implements IAxisValueFormatter {
private IBarDataSet mDataSet;
public StatisticByMonthValueFormatter(IBarDataSet data) {
mDataSet = data;
}
#Override
public String getFormattedValue(float value, AxisBase axis) {
return (String) mDataSet.getEntryForIndex((int) value).getData();
}
}
This woks, but sometimes when I'm scrolling list view I get
java.lang.IndexOutOfBoundsException: Invalid index 4, size is 2.
I know, that bug in the getFormattedValue method in MyValueFormatter, but i don't understand how can I fix this, or how implement this in the right way?
DataSet#getEntryForIndex(int index)
is the wrong method to call here. Entry in a DataSet are stored in a backing array and this method will get the Entry at that index in the backing array. This doesn't always correspond to the Entry for that x-value (the x-value on the chart). Hence, the IndexOutOfBoundsException.
You would want to do something this instead:
return (String) mDataSet.getEntryXPos(float value).getData();
See the javadoc for DataSet for further explanation
Just started using the MPAndroidChart version 3.0.0 beta and i have created a project that can show my values in a bar chart. My question is where do i add and display labels.
Each Bar should have its own label eg. "Flue", "Cheese" etc at the bottom. Not sure what function does this, am actively searching and reading the Docs/Wiki but no joy currently.
Depending on your preferences, you can use the data property of an Entry to store the label and then return it in your IAxisValueFormatter implementation:
public class LabelValueFormatter implements IAxisValueFormatter {
private final DataSet mData;
public LabelValueFormatter(DataSet data) {
mData = data;
}
#Override
public String getFormattedValue(float value, AxisBase axis) {
// return the entry's data which represents the label
return (String) mData.getEntryForXPos(value, DataSet.Rounding.CLOSEST).getData();
}
}
This approach allows you to use the Entry constructor (or BarEntry in this case) to add the labels, which can improve the readability of your code:
ArrayList<BarEntry> entries = new ArrayList<>();
for (int i = 0; i < length; i++) {
// retrieve x-value, y-value and label
entries.add(new BarEntry(x, y, label));
}
BarDataSet dataSet = new BarDataSet(entries, "description");
BarData data = new BarData(dataSet);
mBarChart.setData(data);
mBarChart.getXAxis().setValueFormatter(new LabelValueFormatter(data));
Also check out this answer for more information and an alternative approach on using labels with the BarChart and the new 3.0.0 version of the library.