How do I know what margins to use in an AChartEngine chart to prevent the y-axis labels from being displayed outside the chart when it is set to fill a layout? Can I automatically resize the chart so that the y-axis labels always are visible, even if they contain more than 2-3 digits?
/Markus
You cannot do this automatically, but you can tweak the values until it looks good. You can also rotate the labels when you have several digits values.
This is what I used to deal with Y axis labels that can have differing numbers of digits. Find your max Y value, round it to an int, convert to string and then count the length of the string. The length of the string can be used to calculate a value for the Left margin.
//**** Find max y value of dataset
Ymax = getMaxValue(U_Limit);
if(Ymax < 10){
Ymax = 10;
}else{
Ymax = Ymax*1.1;
}
//**** Find int value of number of digits in max y value
int PLAY_FACTOR = text_label_size*.5 // you may have to play around with this value
int leftMargin = (Double.toString(Math.round(Ymax)).length())*PLAY_FACTOR;
int margins[] = { 26, leftMargin, botMargin, 14 }; // Top,Left,Bottom,Right
renderer.setMargins(margins);
Found a better solution, if you use setYLabelsVerticalPadding with a negative value you can move a little bit down the label... in this way the upper Y label will be visible no matter what.
Hope it helps.
Related
I've been struggling with this for a while now, but I can't find a way to have an x axis, with its labels, lie at the position y = 0. This is important when I have both positive and negative values- I don't want to put the axis at the defaults given by AndroidMPChart (TOP, BOTTOM, BOTH_SIDED, TOP_INSIDE, BOTTOM_INSIDE), as none of these apply.
I have managed to edit the xAxisRenderer, and have been able to pass the ratio of my maxY value to my minY value, hoping to manually find the position to set the axis. The issue with this, however, is that I need the position of the highest Y bar and lowest Y bar. I can find the position of the lowest Y bar no problem, using mViewPortHandler.contentBottom(), but using
mViewPortHandler.contentTop() does not give me the top of the Y bar for some reason.
List<Float> floatList = new ArrayList<>();
floatList.add(0f);
floatList.add(mViewPortHandler.contentTop());
floatList.add(mViewPortHandler.offsetTop()+mViewPortHandler.getScaleY());
floatList.add(mViewPortHandler.getContentCenter().y);
floatList.add(mViewPortHandler.contentBottom());
floatList.add(mViewPortHandler.getChartHeight());
if (mDebug) {
for (int i=0; i<floatList.size(); i++) {
Paint paint = new Paint();
paint.setColor(getRandomColorInColorFormPrintString("i = " + i));
paint.setStrokeWidth(3);
c.drawLine(mViewPortHandler.contentLeft()+15*i,
floatList.get(i), mViewPortHandler.contentRight()+15*i,
floatList.get(i), paint);
}
}
Notice how contentBottom (yellow) nails the bottom of the bar, but content top and offset top (pink/red) are not accurate in finding the top of the content. I've tried this with many different values, contentBottom is consistently accurate, whereas contentTop/offsetTop are not, and are not offset by the height of the value label (I already tried this as well).
All I really need is a dynamic way to set the position of the x axis right between positive and negative values. I am so surprised that this option doesn't come with Android MP Charts. If it does, please let me know if I am overcomplicating things.
If there is no way to set this through Android MP Charts, please let me know if you know what I'm doing wrong in trying to get the top of the Y bar.
This is how I solved the problem--
in the renderAxisLine function =>
MPPointD pos = mTrans.getPixelForValues(0f, 0f);
c.drawLine(mViewPortHandler.contentLeft(),
(float)pos.y, mViewPortHandler.contentRight(),
(float)pos.y, mAxisLinePaint);
I am using MPAndroidChart to display my charts, in the barchart it displays some values perfectly but for some other values, the bar is visible and can be highlighted but its value is not visible.
Any clue please on how to fix this ?
This is a picture to clarify what I am saying. The red areas is where the bar is visible but not its value.
Before setting the data (sorry I couldn't find the data in your question):
graph.setVisibleYRangeMaximum(barDataSet.getYMax() + 20, YAxis.AxisDependency.LEFT);
replacing 20 with the height of your custom layout.
I've had the same problem and this is how I've solved it.
float maxValue = barSet.getYMax();
int extraSpace = (int) (maxValue / (yVals.size() + 3));
chart.getAxisLeft().mAxisMaximum = (int) maxValue + (extraSpace < 1 ? 1 : extraSpace);
yVals is the list of Y axis values, while you can play with +3 so the whole chart view seems OK according to your layout.
Id like to achive someting like this where more negative values appear below less negative. Is it possible for bars to start in other place than 0.
chart.getAxisLeft().setInverted(true);
does not do what i want.
How it should look
You can control the span of Y axis by two functions from AxisBase:
public void setAxisMinimum(float min)
public void setAxisMaximum(float max)
Just iterate through values, choose minimum and maximum values and set Y axis min and max values:
In the case of provided example:
mChart.getAxisLeft().setAxisMinimum(-112f);
mChart.getAxisLeft().setAxisMaximum(-12f);
I using the 2.0.8 release of MPAndroidChart
I have a problem when the y-values are all zero, and the bars are not shown in the BarChart.
I checked the sample project:
Unchanged code:
Just changing for all values of y are zero in the line 260, with
yVals1.add(new BarEntry(0, i));
but this happens:
And the same happens in my project, when some bars have nonzero values, all bars are displayed, like this:
but when all the bars are zero, no bars are shown and only one label is shown on the x-axis
How to fix this?
I need the chart display all values even the values of 'y' are all zero.
i was getting the same kind of problem as you.
i have a bar chart, when all the y values are 0, the bar won't show at all.
but if there is at least one y value that isn't 0, the bar will showed up even the rest of the y values is 0.
so i think this is a bug from MPAndroidChart.
but i found a way to tweak it a little bit.
you need to set the fixed max axis value, when all the y values are 0.
here is the code to set the fixed max axis value :
leftAxis.setAxisMaxValue(100f);
by doing that, when all the y values are 0, you will set max axis value to 100, but you can set it to other value as long as the max axis value is not 0, and the bar chart will shown even if all the y values are 0.
hope it will fix your problem
Good day, i have a slight issue. i have created my own Labels on the Y-Axis with the following code below, but they are so clustered together, How can i space them out?.
Here is my code:
renderer.setYLabels(0);
//value_value is an array which would use as the labels for the y axis
int value_size = value_value.length;
int m = 0;
//int add = value_size/10;
int add = largest_size/10; // largest_size is the biggest value in the array value_value
for(int i=0; i< 10; i++){
if(m > value_value.length){
break;
}
renderer.addYTextLabel((double)i, value_value[m].toString(), 1);
m+=add;
}
P.S: from the api docs, there is a 3rd parameter "int scale" which i thought would help me space out the margins but i never seem to use it correctly. if i put any value there, i get a NullPointerException. What does it really do and how to use it?
Any help will be highly appreciated. Thank you.
My Graph:
Adding custom labels can be tricky because you always have to make sure you are not overlapping them. You should add only as many as needed to avoid overlapping. You can also listen for pan and zoom events and update the custom labels accordingly.
The scale parameter is useful when you have multiple Y axis scales. If you don't have then you don't need to use the parameter.