I am starting to use the MPAndroidChart
library to build a StackedBarChart
showing three y values. Here is the code:
public class Plot
{
final Context context;
final BarData data;
private int count;
public StackedBarPlot(Context context)
{
this.context = context;
data = setData();
}
protected BarData setData()
{
final List<BarEntry> entries = new ArrayList<>();
for (DatabaseEntry entry : entryList)
{
final float total = (float) entry.getTotal();
final float[] y = {100 * entry.getN1() / total,
100 * entry.getN2() / total, 100 * entry.getN3() / total};
entries.add(new BarEntry(/*long*/entry.getDate(), y));
}
count = entries.size();
final BarDataSet dataset = new BarDataSet(entries, null);
dataset.setColors(new int[]{R.color.green, R.color.blue, R.color.red}, context);
dataset.setStackLabels(labels);
dataset.setDrawValues(true);
dataset.setVisible(true);
final BarData data = new BarData(dataset);
data.setBarWidth(0.9f);
return data;
}
public BarChart getChart(int id, View view)
{
final BarChart chart = (BarChart) view.findViewById(id);
chart.getAxisRight().setEnabled(false);
chart.getAxisLeft().setEnabled(false);
final Legend legend = chart.getLegend();
legend.setDrawInside(true);
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
final XAxis xAxis = chart.getXAxis();
xAxis.setValueFormatter(dateFormatter);
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setLabelCount(count);
chart.getDescription().setEnabled(false);
chart.setData(data);
chart.setFitBars(true);
chart.invalidate();
return chart;
}
private final IAxisValueFormatter dateFormatter = new IAxisValueFormatter()
{
@Override
public String getFormattedValue(float value, AxisBase axis)
{
return new DateTime((long) value).toString(context.getString("E, MMM d"));
}
};
}
Then in my Fragment
, I call:
public class MyFragment extends Fragment
{
private Plot plot;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
plot = new Plot(getActivity());
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
{
final View view = inflater.inflate(R.layout.fragment, parent, false);
plot.getChart(R.id.chart, view);
return view;
}
}
And in MainActivity.java
getFragmentManager().beginTransaction().replace(R.id.content, fragment).commit();
main_activity.xml
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/navigation"/>
</android.support.v4.widget.DrawerLayout>
fragment.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<com.github.mikephil.charting.charts.BarChart
android:id="@+id/chart"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
The problem is the bars are not rendering correctly. I can see values but the bars are not displaying in the chart. Any advice?
This is not an error in the library like some of the previous posts have suggested. Probably you are just misunderstanding how the width of each bar is determined like I did at first.
I was using a long, millisecond time-stamp for my x-axis on my bar chart. I realized that by default MPAndroidChart sets the width of a bar to 0.85f. Think about what this means. My first time-stamp was 1473421800000f and the next was 1473508200000f: a difference of 86400000f! Now how could I expect to see a bar that is 0.85f wide when there is 86400000f between each pair of observations?? To fix this problem you need to do something like the following:
barData.setBarWidth(0.6f * widthBetweenObservations);
So the above sets the width of a bar to equal 60% of the distance between observations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With