I have this grouped bar chart that can set to any number of bars in a group. It will first start with 2 bars in a group. Then if user clicks the button. it will add a new bar in the group. and click again. new bar again. and so on. my goal is to redraw the chart with new bar but the x-axis label must always be in the center of the grouped bar.
I always have a problem on the time when there are 5 bars.
Above, Feb is not centered on the 2nd grouped bar anymore.
Sample code in here:
https://github.com/PhilJay/MPAndroidChart/issues/3505
(I posted the question here too bec it seems that github is not maintained anymore)
In the code, the function resize is core of it that wants to reduce the width of the bars when new bars are added and at the same time increase the scale minima. But to no avail.
Need help
Check this sample grouped bar chart code.
public class MpAndroidGroupedBarChart extends AppCompatActivity {
BarChart mChart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mChart = (BarChart) findViewById(R.id.bar_chart);
mChart.setDrawBarShadow(false);
mChart.getDescription().setEnabled(false);
mChart.setPinchZoom(false);
mChart.setDrawGridBackground(false);
// empty labels so that the names are spread evenly
String[] labels = {"", "Name1", "Name2", "Name3", "Name4", "Name5", ""};
IAxisValueFormatter xAxisFormatter = new LabelFormatter(mChart, labels);
XAxis xAxis = mChart.getXAxis();
xAxis.setCenterAxisLabels(true);
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setGranularity(1f); // only intervals of 1 day
xAxis.setTextColor(Color.BLACK);
xAxis.setTextSize(12);
xAxis.setAxisLineColor(Color.WHITE);
xAxis.setAxisMinimum(1f);
xAxis.setValueFormatter(xAxisFormatter);
YAxis leftAxis = mChart.getAxisLeft();
leftAxis.setTextColor(Color.BLACK);
leftAxis.setTextSize(12);
leftAxis.setAxisLineColor(Color.WHITE);
leftAxis.setDrawGridLines(false);
leftAxis.setGranularity(2);
leftAxis.setLabelCount(8, true);
leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
mChart.getAxisRight().setEnabled(false);
mChart.getLegend().setEnabled(false);
float[] valOne = {10, 20, 30, 40, 50};
float[] valTwo = {60, 50, 40, 30, 20};
float[] valThree = {20, 10, 30, 60, 40};
float[] valFour = {40, 10, 60, 30, 10};
float[] valFive = {60, 50, 40, 30, 50};
ArrayList<BarEntry> barOne = new ArrayList<>();
ArrayList<BarEntry> barTwo = new ArrayList<>();
ArrayList<BarEntry> barThree = new ArrayList<>();
ArrayList<BarEntry> barFour = new ArrayList<>();
ArrayList<BarEntry> barFive = new ArrayList<>();
for (int i = 0; i < valOne.length; i++) {
barOne.add(new BarEntry(i, valOne[i]));
barTwo.add(new BarEntry(i, valTwo[i]));
barThree.add(new BarEntry(i, valThree[i]));
barFour.add(new BarEntry(i, valFour[i]));
barFive.add(new BarEntry(i, valFive[i]));
}
BarDataSet set1 = new BarDataSet(barOne, "barOne");
set1.setColor(Color.BLUE);
BarDataSet set2 = new BarDataSet(barTwo, "barTwo");
set2.setColor(Color.MAGENTA);
BarDataSet set3 = new BarDataSet(barThree, "barTwo");
set3.setColor(Color.RED);
BarDataSet set4 = new BarDataSet(barFour, "barTwo");
set4.setColor(Color.GREEN);
BarDataSet set5 = new BarDataSet(barFive, "barTwo");
set5.setColor(Color.LTGRAY);
set1.setHighlightEnabled(false);
set1.setDrawValues(false);
set2.setHighlightEnabled(false);
set2.setDrawValues(false);
set3.setHighlightEnabled(false);
set3.setDrawValues(false);
set4.setHighlightEnabled(false);
set4.setDrawValues(false);
set5.setHighlightEnabled(false);
set5.setDrawValues(false);
ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
dataSets.add(set1);
dataSets.add(set2);
dataSets.add(set3);
dataSets.add(set4);
dataSets.add(set5);
BarData data = new BarData(dataSets);
float groupSpace = 0.2f;
float barSpace = 0f;
float barWidth = 0.16f;
// (barSpace + barWidth) * 5 + groupSpace = 1
// multiplied by 5 because there are 5 five bars
// labels will be centered as long as the equation is satisfied
data.setBarWidth(barWidth);
// so that the entire chart is shown when scrolled from right to left
xAxis.setAxisMaximum(labels.length - 1.1f);
mChart.setData(data);
mChart.setScaleEnabled(false);
mChart.setVisibleXRangeMaximum(2f);
mChart.groupBars(1f, groupSpace, barSpace);
mChart.invalidate();
}
private class LabelFormatter implements IAxisValueFormatter {
String[] labels;
BarLineChartBase<?> chart;
LabelFormatter(BarLineChartBase<?> chart, String[] labels) {
this.chart = chart;
this.labels = labels;
}
#Override
public String getFormattedValue(float value, AxisBase axis) {
return labels[(int) value];
}
}
}
labels will be centered as long as this equation is satisfied
(barSpace + barWidth) * 5 + groupSpace = 1
multiplied by 5 because there are 5 five bars
RESULT
first you have to dynamically set the min and max value for x-axis
mChart.getXAxist().setAxisMinimum(0);
mChart.getXAxis().setAxisMaximum(0 +
barChart.getBarData().getGroupWidth(groupSpace, barSpace) * groupCount);
and then set it to center:
mChart.getXAxis().setCenterAxisLabels(true);
I have provided a detailed answer here:
set interval between x-axis labels: stackoverflow
I think the Label position is correct & the problem is with Bar position & Spacing.Please try the following method.
/**
* Group charts by specifying width & other properties externally
*
* #param dataSets Entire DataSet made
* #param data Bar Data created from datasets
* #see http://google.com
*/
private void setupChartGrouping(ArrayList<IBarDataSet> dataSets,
BarData data) {
if (dataSets.size() > 1) {
barChart.getXAxis().setCenterAxisLabels(true);
barChart.getBarData().setBarWidth(getBarWidth(dataSets.size()));
barChart.getXAxis().setAxisMinimum(-data.getBarWidth() / 2);
barChart.getXAxis().setAxisMaximum(dataSets.size());
barChart.groupBars(0, GROUPED_CHART_GROUP_SPACING, GROUPED_CHART_BAR_SPACING);
} else {
barChart.getXAxis().setCenterAxisLabels(false);
barChart.getXAxis().resetAxisMaximum();
barChart.getXAxis().resetAxisMinimum();
barChart.getAxisLeft().setDrawGridLines(false);
barChart.getXAxis().setDrawGridLines(false);
}
}
private static final float GROUPED_CHART_MAGICAL_NUMBER = 1.00f;
public static final float GROUPED_CHART_BAR_SPACING = 0.05f;
public static final float GROUPED_CHART_GROUP_SPACING = 0.20f;
/**
* Size would be ==> ((barSpace + barWidth) * no: of bars in a group) + groupSpace = 1.00
*
* #param barEntryCount No: of bars in a Group
* #return Width of a Single Bar in Chart
*/
public static float getBarWidth(int barEntryCount) {
return ((GROUPED_CHART_MAGICAL_NUMBER - GROUPED_CHART_GROUP_SPACING) / barEntryCount) - GROUPED_CHART_BAR_SPACING;
}
To align x axis at center of groupBarChart you need to fulfill the below formula
Formula :: (barWidth + barSpace)*count + groupSpace = 1 :-count= no of bars/groups
here:
barWdith = ??
barSpace = 0.05f
grouSpace = 0.44f
You can find the barWidth using below formula:
barWidth = (1 - groupSpace) /`enter code here` count - barSpace;
Related
I m using MPAndroidChart Combined Chart to display a Bar & Scatter chart. On click on points of Scatter Graph i m showing a custom marker which is as below :
public class YourMarkerView extends MarkerView {
private TextView tvContent;
private RelativeLayout mainbackground;
/**
* Constructor. Sets up the MarkerView with a custom layout resource.
*
* #param context
* #param layoutResource the layout resource to use for the MarkerView
*/
public YourMarkerView(Context context, int layoutResource) {
super(context, layoutResource);
tvContent = (TextView) findViewById(R.id.tvContent);
mainbackground = (RelativeLayout) findViewById(R.id.mainbackground);
}
// callbacks everytime the MarkerView is redrawn, can be used to update the
// content (user-interface)
#Override
public void refreshContent(Entry e, Highlight highlight) {
if(e!=null && e.getData()!=null){
Log.d("Yoyo",e.getData().toString());
mainbackground.setBackgroundColor(Color.parseColor(e.getData().toString().split(";")[1]));
tvContent.setText("" + e.getData().toString().split(";")[0]);
// this will perform necessary layouting
super.refreshContent(e, highlight);
}
}
private MPPointF mOffset;
#Override
public MPPointF getOffset() {
if(mOffset == null) {
// center the marker horizontally and vertically
mOffset = new MPPointF(-(getWidth() / 2), -getHeight());
}
return mOffset;
}
}
Below is code for Chart:
chart.getDescription().setEnabled(false);
chart.setBackgroundColor(Color.parseColor("#f9f9f9"));
chart.setDrawGridBackground(false);
chart.setDrawBarShadow(false);
chart.setHighlightFullBarEnabled(false);
// draw bars behind lines
chart.setDrawOrder(new CombinedChart.DrawOrder[]{
CombinedChart.DrawOrder.BAR, CombinedChart.DrawOrder.SCATTER
});
chart.getAxisRight().setEnabled(false);
chart.getAxisLeft().setEnabled(false);
chart.getXAxis().setEnabled(false);
Legend legend = chart.getLegend();
legend.setEnabled(false);
YourMarkerView mv = new YourMarkerView(myActivity, R.layout.custom_marker_view);
// Set the marker to the chart
mv.setChartView(chart);
chart.setMarker(mv);
chart.setDragEnabled(false);
chart.setScaleEnabled(false);
// force pinch zoom along both axis
chart.setPinchZoom(false);
// enable touch gestures
chart.setTouchEnabled(true);
CombinedData data = new CombinedData();
data.setData(generateBarData());
data.setData(generateScatterData());
chart.setData(data);
chart.invalidate();
private BarData generateBarData() {
ArrayList<BarEntry> entries1 = new ArrayList<>();
ArrayList<BarEntry> entries2 = new ArrayList<>();
for (int index = 0; index < count; index++) {
entries1.add(new BarEntry(0, getRandom(25, 25)));
// stacked
entries2.add(new BarEntry(0, new float[]{getRandom(13, 12), getRandom(13, 12)}));
}
BarDataSet set1 = new BarDataSet(entries1, "Bar 1");
set1.setColor(Color.rgb(60, 220, 78));
set1.setValueTextColor(Color.rgb(60, 220, 78));
set1.setValueTextSize(10f);
set1.setAxisDependency(YAxis.AxisDependency.LEFT);
BarDataSet set2 = new BarDataSet(entries2, "");
set2.setStackLabels(new String[]{"Stack 1", "Stack 2"});
set2.setColors(Color.rgb(61, 165, 255), Color.rgb(23, 197, 255));
set2.setValueTextColor(Color.rgb(61, 165, 255));
set2.setValueTextSize(10f);
set2.setAxisDependency(YAxis.AxisDependency.LEFT);
float groupSpace = 0.06f;
float barSpace = 0.02f; // x2 dataset
float barWidth = 0.45f; // x2 dataset
// (0.45 + 0.02) * 2 + 0.06 = 1.00 -> interval per "group"
BarData d = new BarData(set1, set2);
d.setBarWidth(barWidth);
// make this BarData object grouped
d.groupBars(0, groupSpace, barSpace); // start at x = 0
return d;
}
private ScatterData generateScatterData() {
ScatterData d = new ScatterData();
ArrayList<Integer> colors = new ArrayList<Integer>();
for (String color : details.getSequenceColors()) {
colors.add(Color.parseColor(color));
}
ArrayList<Entry> entries = new ArrayList<>();
for (float index = 0; index < count; index += 0.5f)
entries.add(new Entry(index + 0.25f, getRandom(10, 55),"title;"+colors.get(index)));
ScatterDataSet set = new ScatterDataSet(entries, "Scatter DataSet");
set.setDrawHorizontalHighlightIndicator(false);
set.setDrawVerticalHighlightIndicator(false);
set.setColors(colors);
set.setScatterShape(ScatterChart.ScatterShape.CIRCLE);
set.setScatterShapeSize(20f);
set.setDrawValues(false);
set.setValueTextSize(10f);
d.addDataSet(set);
return d;
}
details.getSequenceColors is simple pojo contains the list of colors. For each point on Scatter Graph i am setting different colors. I am setting ScatterShape.CIRCLE color and Marker Background color same on Scatter Graph. As per Draw order I am drawing the bar graph first then the scatter one. Issue here i am facing is When i click on area where no scatter points exist the marker background color and nearest scatter point color is different and it highlights Bar graph datapoint as well. Its doesnt show the exact marker on Scatter points not sure why. How can i make sure that the scatter Circle color and marker Background color will be always in sync for each data points?
Solved by Using Custom ScatterDataSet Class:
public class MyScatterDataSet extends ScatterDataSet {
static int currentIndex = 0;
public MyScatterDataSet(List<Entry> yVals, String label) {
super(yVals, label);
}
#Override
public int getColor(int index) {
int ret =super.getColor(currentIndex);
currentIndex+=1;
return ret;
}
}
I am working on a groupped Barchart using mpandroidchart library:
Code:
public void drawing_length(String length)
{
ArrayList<String> xx = new ArrayList<String>();
ArrayList<String> yy = new ArrayList<String>();
ArrayList<String> zz = new ArrayList<String>();
int L = 7;
if (length.equals("7days"))
{
L = 7;
}
if (length.equals("14days"))
{
L = 14;
}
if (length.equals("30days"))
{
L = 30;
}
if (L > x.size())
{
L = x.size();
}
for (int g=0; g<L; g++)
{
xx.add(x.get(g)); // newest first, oldest last
yy.add(y.get(g));
zz.add(z.get(g));
}
Collections.reverse(xx); //oldest first, newest last, i.e. sequential
Collections.reverse(yy);
Collections.reverse(zz);
setupGrouppedChart(xx,yy,zz);
}
public void setupGrouppedChart(ArrayList<String> x, ArrayList<String> y1, ArrayList<String> y2)
{
float barWidth;
float barSpace;
float groupSpace;
barWidth = 0.3f;
barSpace = 0f;
groupSpace = 0.4f;
ll_combined_chart.setVisibility(View.GONE);
ll_scatteredchart.setVisibility(View.GONE);
ll_groupped_barchart.setVisibility(View.VISIBLE);
chart_grouppedBar = (BarChart) findViewById(R.id.chart_grouppedBar);
chart_grouppedBar.getDescription().setEnabled(false);
chart_grouppedBar.setBackgroundColor(Color.TRANSPARENT);
chart_grouppedBar.setDrawGridBackground(false);
chart_grouppedBar.setPinchZoom(false);
chart_grouppedBar.setScaleEnabled(false);
chart_grouppedBar.setDrawBarShadow(false);
chart_grouppedBar.setDrawValueAboveBar(false);
chart_grouppedBar.setHighlightFullBarEnabled(false);
chart_grouppedBar.setHighlightPerDragEnabled(false);
chart_grouppedBar.setHighlightPerTapEnabled(false);
chart_grouppedBar.setDoubleTapToZoomEnabled(false);
chart_grouppedBar.getXAxis().setDrawGridLines(false);
chart_grouppedBar.getAxisLeft().setDrawGridLines(false);
chart_grouppedBar.getAxisRight().setDrawGridLines(false);
chart_grouppedBar.getAxisRight().setEnabled(false);
chart_grouppedBar.animateXY(800, 800);
chart_grouppedBar.getDescription().setText("This is testing Description");
chart_grouppedBar.setVisibleXRangeMaximum(14f);
Utilities.custom_toast(Stat.this, "Xsize=" + x.size(), "gone", "short");
final String[] x_name = new String[x.size()];
for (int j = 0; j <x.size(); j++)
{
String[] temp = x.get(j).split("-");
x_name[j] = temp[0] + "/" + temp[1];
}
XAxis xLabels = chart_grouppedBar.getXAxis();
xLabels.setPosition(XAxis.XAxisPosition.BOTTOM);
xLabels.setGranularity(1f);
xLabels.setValueFormatter(new IAxisValueFormatter()
{
#Override
public String getFormattedValue(float value, AxisBase axis)
{
return x_name[(int) value % x_name.length];
}
});
BarDataSet set1, set2;
ArrayList<BarEntry> valueSet1 = new ArrayList<>();
ArrayList<BarEntry> valueSet2 = new ArrayList<>();
for (int i = 0; i < x_name.length; i++)
{
float val1 = Float.parseFloat(y1.get(i));
BarEntry v1e1 = new BarEntry(i, val1);
valueSet1.add(v1e1);
float val2 = Float.parseFloat(y2.get(i));
BarEntry v1e2 = new BarEntry(i, val2);
valueSet2.add(v1e2);
}
if (chart_grouppedBar.getData() != null && chart_grouppedBar.getData().getDataSetCount() > 0)
{
set1 = (BarDataSet) chart_grouppedBar.getData().getDataSetByIndex(0);
set2 = (BarDataSet) chart_grouppedBar.getData().getDataSetByIndex(1);
set1.setValues(valueSet1);
set2.setValues(valueSet2);
chart_grouppedBar.getData().setHighlightEnabled(false);
chart_grouppedBar.groupBars(0, groupSpace, barSpace);
chart_grouppedBar.getData().notifyDataChanged();
chart_grouppedBar.notifyDataSetChanged();
}
else
{
set1 = new BarDataSet(valueSet1, "A");
set1.setColor(getResources().getColor(R.color.pink_light));
set2 = new BarDataSet(valueSet2, "B");
set2.setColor(getResources().getColor(R.color.purple1));
BarData data = new BarData(set1, set2);
//data.setValueFormatter(new LargeValueFormatter());
//data.setValueTypeface(mTfLight);
data.setValueFormatter(new MyValueFormatter());
chart_grouppedBar.setData(data);
chart_grouppedBar.getBarData().setBarWidth(barWidth);
chart_grouppedBar.getXAxis().setAxisMaximum(0 + chart_grouppedBar.getBarData().getGroupWidth(groupSpace, barSpace) * x_name.length);
chart_grouppedBar.getAxisLeft().setAxisMinimum(0);
chart_grouppedBar.getAxisLeft().setValueFormatter(new MyYAxisValueFormatter());
chart_grouppedBar.getData().setHighlightEnabled(false);
chart_grouppedBar.groupBars(0, groupSpace, barSpace);
chart_grouppedBar.invalidate(); // refresh
}
}
Screen capture:
Question:
The legend for the x-axis is shifted. How can it be adjusted?
There should be 9 entries but it is now only showing 7 entries. I suspect it is on the right but the screen cannot be scrolled to the right. The toast report the size is 9 correctly. How could the chart be scrollable?
The Y-axis is also wrong. The height of the bars do not match with the Y-axis.
Thank you.
Hard-Coded bar width is the problem.Find bar width dynamically like below
((1.00f- 0.20f) / barEntryCount) - 0.05f
where
0.05f -> Bar Spacing;
0.20f -> Group Spacing;
Please read this thread.
Regarding alignment of X Axis Labels (Question 1)
do like following
if (dataSets.size() > 1) {
barChart.getXAxis().setCenterAxisLabels(true);
else
barChart.getXAxis().setCenterAxisLabels(false);
Regarding the 2nd question
Please verify that your dataset count is 9.If you given 9 elements in dataset surly ,it will plot.Please check other view properties including view clipping.
For your 2nd question
How could the chart be scrollable?
chart_grouppedBar.setDragEnabled(true);
Reference link
For 3rd question
The Y-axis is also wrong. The height of the bars do not match with the
Y-axis.
try to set Min & Max value of axis and label count. For example:
chart_grouppedBar.getAxisLeft().setAxisMaxValue(MAX VALUE FROM YOUR DATASET);
chart_grouppedBar.getAxisLeft().setLabelCount(8, true);
reference link
I am using MPAndroidChart for plotting scatteredBarChart. The code is as follows:
Code:
public void setupScatteredBarChart(ArrayList<String> x, ArrayList<String> y1, ArrayList<String> y2 )
{
int maxYvalue = 0;
final String[] x_name = new String[x.size()];
for (int j = 0; j <x.size(); j++)
{
String[] temp = x.get(j).split("-");
x_name[j] = temp[0] + "/" + temp[1];
}
ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
for (int i = 0; i < x_name.length; i++)
{
float val1 = Float.parseFloat(y1.get(i));
float val2 = Float.parseFloat(y2.get(i));
yVals1.add(new BarEntry(i, new float[]{val1, val2},getResources().getDrawable(R.drawable.ic_launcher)));
float val_total = val1 + val2;
int I = (int) Math.ceil(val_total);
if (maxYvalue < I)
{
maxYvalue = I;
}
}
chart_scattered = (BarChart) findViewById(R.id.chart_scattered);
chart_scattered.setOnChartValueSelectedListener(Stat.this);
chart_scattered.getDescription().setEnabled(false);
chart_scattered.setMaxVisibleValueCount(40); // if more than 40 entries are displayed in the chart, no values will be drawn
chart_scattered.setPinchZoom(false); // scaling can now only be done on x- and y-axis separately
chart_scattered.setDrawGridBackground(false);
chart_scattered.setDrawBarShadow(false);
chart_scattered.setDrawValueAboveBar(false);
chart_scattered.setHighlightFullBarEnabled(false);
chart_scattered.setDoubleTapToZoomEnabled(false);
chart_scattered.setTouchEnabled(false);
chart_scattered.setFitBars(true);
chart_scattered.animateXY(800, 800);
chart_scattered.getAxisRight().setEnabled(false);
chart_scattered.getXAxis().setAxisMinimum(-0.5f); // adjust for showing first bar properly
// Left Y axis
YAxis leftAxis = chart_scattered.getAxisLeft(); // change the position of the y-labels
leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
chart_scattered.getAxisLeft().setLabelCount(maxYvalue + 1, true);
chart_scattered.getAxisLeft().setAxisMinValue(0f);
chart_scattered.getAxisLeft().setValueFormatter(new MyYAxisValueFormatter());
// Bottom X axis
XAxis xLabels = chart_scattered.getXAxis();
xLabels.setPosition(XAxis.XAxisPosition.BOTTOM);
xLabels.setAxisMinimum(0f);
xLabels.setGranularity(1f);
xLabels.setValueFormatter(new IAxisValueFormatter() {
#Override
public String getFormattedValue(float value, AxisBase axis) {
return x_name[(int) value % x_name.length];
}
});
Legend l = chart_scattered.getLegend();
l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
l.setDrawInside(false);
l.setFormSize(6f);
l.setFormToTextSpace(4f);
l.setXEntrySpace(6f);
BarDataSet set1;
if (chart_scattered.getData() != null && chart_scattered.getData().getDataSetCount() > 0)
{
set1 = (BarDataSet) chart_scattered.getData().getDataSetByIndex(0);
set1.setValues(yVals1);
chart_scattered.getData().notifyDataChanged();
chart_scattered.notifyDataSetChanged();
}
else
{
set1 = new BarDataSet(yVals1, "");
set1.setDrawIcons(false);
set1.setColors(getColors());
set1.setStackLabels(new String[]{"A", "B"});
ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
dataSets.add(set1);
BarData data = new BarData(dataSets);
data.setValueTextColor(Color.WHITE);
chart_scattered.setData(data);
}
chart_scattered.invalidate();
}
Screen Capture:
Question:
How could the first Bar to be showing properly? I have researched a lot and added the following to the code but is still not successful as showing in the screen capture above.
chart_scattered.getXAxis().setAxisMinimum(-0.5f);
chart_scattered.setFitBars(true);
As the date will go on increasing, could it set max 7 Bars and more than that, it has to be scrolled horizontally?
Thanks!
Question 1
remove this line from your code
xLabels.setAxisMinimum(0f);
will solve your problem.
Question 2
To only show the first 7 bars, use this..
chart_scattered.setVisibleXRangeMaximum(7f);
but this will not allow the user to scroll horizontally yet, if you want to enable scrolling, you'll have to remove this line from your code
chart_scattered.setTouchEnabled(false);
I am assuming you used the above line so the user can't highlight the bars. To keep that behavior, use this function..
chart_scattered.setHighlightPerTapEnabled(false);
mpandroidchart for my project,I want to the result just like the below image.I meet some question have long time. The first I want show the data is 11.23% ,but the project show 11.2% for me ,I can't find any way to change it ,please help me .The second I want to the legend is like the below image,but the legent of mpandroidchart-barchar no have description, how can I do? The third question is that I want to change y axis like the below image, I don't know if it realize?
![I want image]: http://i.stack.imgur.com/tuXhb.png
![My image now]: http://i.stack.imgur.com/NG9FB.png
public class BarChartActivity extends Activity {
private BarChart barChart;
private BarData data;
private BarDataSet dataSet;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bar_chart);
barChart = (BarChart) findViewById(R.id.barchart);
barChart.getAxisRight().setEnabled(false); // 隐藏右边的y轴
barChart.getXAxis().setPosition(XAxisPosition.BOTTOM);
barChart.setGridBackgroundColor(Color.WHITE); // 设置背景色
barChart.getXAxis().setDrawGridLines(false); // 隐藏网格竖线
YAxis yAxis = barChart.getAxisLeft(); // 得到y轴坐标
yAxis.setStartAtZero(false); // y轴是否从0开始
yAxis.mAxisMinimum = -20f;
yAxis.setLabelCount(10); // x轴横线的条数
yAxis.setAxisMinValue(-100f); // 设置最小值
yAxis.setAxisMaxValue(99f);
// yAxis.setSpaceTop(100);
// yAxis.setSpaceBottom(-100);
// barChart.setVisibleYRange(50f,null);
// barChart.getXAxis().enableGridDashedLine(400, 50, 0);
// barChart.getAxisLeft().resetAxisMaxValue(); //自动调整y轴的最大值
// legend.setLabels(new String[]{"你好","我好","大家好"});
barChart.getLegendRenderer();
barChart.getXAxis().setAxisLineColor(Color.BLUE); // 设置x轴线的颜色
barChart.getAxisLeft().setAxisLineColor(Color.GREEN); // 设置y轴线的颜色
barChart.getAxisLeft().setGridColor(Color.RED); // x轴线的颜色
barChart.getAxisLeft().setGridLineWidth(1f); // x轴网格线的宽度
barChart.getAxisLeft().setSpaceTop(150f);
barChart.getAxisLeft().setTextColor(Color.RED);// y坐标轴的上的刻度文字的颜色
// List<String> list = new ArrayList<String>();
// list.add("你好");
// list.add("你好1");
// list.add("你好2");
// barChart.getLegend().setLabels(list);
Legend legend = barChart.getLegend();
legend.setXEntrySpace(5f);
legend.setYEntrySpace(20f);
barChart.getXAxis().setSpaceBetweenLabels(5);
barChart.getXAxis().setYOffset(2f);
barChart.getAxisLeft().setValueFormatter(new PercentFormatter());
ArrayList<BarEntry> entries = new ArrayList<BarEntry>();// 显示的条目
ArrayList<String> xVals = new ArrayList<String>(); // 横坐标标签
float[] yValues = getYValues(90.23f, -2.84f, 9.21f);
for (int i = 0; i < 3; i++) {
entries.add(new BarEntry(yValues[i], i));
xVals.add(""); // 可以从这里取消x轴的坐标
}
int[] colors = new int[] { Color.rgb(90, 147, 229),
Color.rgb(247, 183, 48), Color.rgb(245, 70, 70) };
dataSet = new BarDataSet(entries, ""); // 原来是公司你利润报表
dataSet.setColors(colors);
dataSet.setBarSpacePercent(70f); // 设置柱子的宽度
dataSet.setValueFormatter(new PercentFormatter()); // 设置柱子上的数字百分数显示
dataSet.setValueTextColor(Color.BLUE); // 柱子上数字的颜色
data = new BarData(xVals, dataSet);
barChart.setData(data);
barChart.animateY(3000);
barChart.setDescription("");// 公司前半年财务报表(单位:万元)
barChart.getLegend().setPosition(LegendPosition.BELOW_CHART_CENTER); // 设置图例在正下方
barChart.getLegend().setStackSpace(50f); // 设置图例之间的距离
dataSet.setValueTextSize(28); // 设置柱子上数字的大小
}
public float[] getYValues(float x, float y, float z) {
return new float[] { x, y, z };
}
}
For number format you set ValueFormatter.
You can set Legend property like Style color, font etc using Legend.
To change Y axis negative use setStartAtZero(false);
I've been working with HorizontalBarChart MPAndroidChart a few days ago, and ran into an issue while trying to use a custom ValueFormatter which converts the time from milliseconds into 12h format time. (08:50 AM) But as you can see in the picture below, the value gets clipped...
Is there any possibility to set a padding for the chart on the right for the values to be visible?
Here's the code which configures the chart:
private void initializeChart() {
// Customize user interaction on chart
mHorizontalBarChart.setTouchEnabled(false);
mHorizontalBarChart.setPinchZoom(false);
mHorizontalBarChart.setDragEnabled(false);
// Customize chart's standard settings
mHorizontalBarChart.setDrawGridBackground(false);
mHorizontalBarChart.setDescription("");
mHorizontalBarChart.setHighlightEnabled(false);
mHorizontalBarChart.getLegend().setEnabled(false);
Paint infoPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
infoPaint.setTextAlign(Paint.Align.CENTER);
infoPaint.setTextSize(12f);
mHorizontalBarChart.setPaint(infoPaint, Chart.PAINT_INFO);
// Customize X axis
XAxis xAxis = mHorizontalBarChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setTextSize(12f);
xAxis.setDrawLabels(true);
xAxis.setDrawAxisLine(false);
xAxis.setDrawGridLines(false);
xAxis.setAvoidFirstLastClipping(true);
// Customize Y axis's
// Left
YAxis leftAxis = mHorizontalBarChart.getAxisLeft();
leftAxis.setDrawLabels(false);
leftAxis.setDrawAxisLine(false);
leftAxis.setDrawGridLines(false);
leftAxis.setDrawTopYLabelEntry(false);
// Right
YAxis rightAxis = mHorizontalBarChart.getAxisRight();
rightAxis.setDrawLabels(false);
rightAxis.setDrawAxisLine(false);
rightAxis.setDrawGridLines(false);
rightAxis.setDrawTopYLabelEntry(false);
}
And here's the code which populates it:
private void setChartData(float range) {
String[] daysOfWeek = new String[]{"MO", "TU", "WE", "TH", "FR", "SA", "SU"};
ArrayList<String> xVals = new ArrayList<String>();
for (int i = 0; i < daysOfWeek.length; i++) {
xVals.add(daysOfWeek[i]);
}
ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
for (int i = 0; i < daysOfWeek.length; i++) {
float mult = (range + 1);
float val = (float) (Math.random() * mult);
yVals1.add(new BarEntry(val, i));
}
BarDataSet set1 = new BarDataSet(yVals1, "DataSet");
set1.setBarSpacePercent(35f);
ArrayList<BarDataSet> dataSets = new ArrayList<BarDataSet>();
dataSets.add(set1);
BarData data = new BarData(xVals, dataSets);
data.setValueTextSize(10f);
data.setValueFormatter(new ValueFormatter() {
#Override
public String getFormattedValue(float value) {
return value + "some extra text";
}
});
mHorizontalBarChart.setData(data);
}
Any help is greatly appreciated.
Code is used from the examples provided by #Philipp Jahoda.
EDIT: BASED ON Philipp's answer:
I used setSpaceTop(float percent) to adjust the space for the values of the BarData.
// Customize Y axis's
// Left
YAxis leftAxis = mHorizontalBarChart.getAxisLeft();
leftAxis.setDrawLabels(false);
leftAxis.setDrawAxisLine(false);
leftAxis.setDrawGridLines(false);
leftAxis.setDrawTopYLabelEntry(false);
leftAxis.setSpaceTop(20); // use these to adjust space for the BarData values
// Right
YAxis rightAxis = mHorizontalBarChart.getAxisRight();
rightAxis.setDrawLabels(false);
rightAxis.setDrawAxisLine(false);
rightAxis.setDrawGridLines(false);
rightAxis.setDrawTopYLabelEntry(false);
rightAxis.setSpaceTop(20); // use these to adjust space for the BarData values
Code must be optimized though, this is just a quick test, but these suggestions worth tried out. Thanks again Philipp!
Read the documentation of the YAxis.
Focus on the following methods:
setAxisMaxValue(...) & setAxisMinValue(...)
setSpaceTop(...)
setSpaceBottom(...)
With them you can set the range / space of your axis.