Andrei Herford
Andrei Herford

Reputation: 18729

iOS Core Plot: Adjust y axis padding to label size

I have spent the last couple of days to use Core Plot for the first time. It took me some some figure out how it works but I could realize almost all features I was looking for. But for one thing I did not find a solution:

I am using a XY-Plot with labels on both axes. The plotAreaFrame has a left padding to shift the plotArea to the right and create some free space for the y axis labels. This works fine as long as the labels are not to big, e.g. for values up to 100. But if the y values become bigger, eg. 10.0000, the padding is not enough to show the complete label.

Of course I could just use a higher padding but this would waste space if I have only small y values.

Is there any way to autosize the padding according to the labels?

Upvotes: 2

Views: 2080

Answers (3)

zubko
zubko

Reputation: 1797

I've used the proposed solution by Yohst first. But then I realized that sometimes bigger number for the maximum range won't result in a bigger label, for example when the Y value is time (as on the screenshot below).

So I iterated over the labels of the axis to find the maximum width of the label and to set it as graph's left padding:

CPTXYAxisSet *axisSet = (CPTXYAxisSet *)_graph.axisSet;
CPTXYAxis *yAxis = axisSet.yAxis;
[yAxis relabel];
CGFloat maxLabelWidth = 0;
for (CPTAxisLabel *label in yAxis.axisLabels) {
  maxLabelWidth = MAX(maxLabelWidth, label.contentLayer.bounds.size.width);
}
_graph.plotAreaFrame.paddingLeft = /* extra padding + */ maxLabelWidth;
// force update axes because of the new padding
[axisSet relabelAxes];
[axisSet setNeedsLayout];

Upvotes: 1

Yohst
Yohst

Reputation: 1902

Andrei,

I realize this is an old question but perhaps this is a useful thought to you or others. I wonder if you can do a bit better than just guessing the padding size you need. How about this code snippet:

// set up the Y axis
float minY = 0;
float maxY = 100;      // just some max value
float tickLength = 10; // just a pleasing value
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(minY) length:CPTDecimalFromFloat(maxY)];

// set up the line style for y axis
CPTMutableLineStyle * lineStyle = [CPTLineStyle lineStyle];
lineStyle.lineColor = [CPTColor blackColor];
lineStyle.lineWidth = 2.0f;  // just picked a pleasing value

// set up the y axis
axisSet = [[CPTXYAxisSet alloc]init];
axisSet.yAxis.majorTickLength = tickLength;

// Now you can determine the size of the rectangle needed to display axis and labels by getting
// the axis font and measureing how many pixels were needed to draw the maximum Y axis label.

UIFont * font = [UIFont fontWithName:axisSet.yAxis.labelTextStyle.fontName size:axisSet.yAxis.labelTextStyle.fontSize];
NSString * maxYLabel = [axisSet.xAxis.labelFormatter stringFromNumber:[NSNumber numberWithDouble:plotSpace.yRange.maxLimitDouble] ];
CGSize textSize = [maxYLabel sizeWithFont:font];

// The offset you are looking for can now be computed by:
textSize.width + axisSet.yAxis.majorTickLength + axisSet.yAxis.labelOffset;

Anyway, I haven't testing the code above but the concept should apply I think...

Upvotes: 5

Andrei Herford
Andrei Herford

Reputation: 18729

After getting no answer here I looked all over the web but found no answer there either. The solution which now works for me is just checking the current range of the Y axis, look how many digits the value have and calculate the necessary width manually: number_of_digits * width_per_digit + fixed_padding

Of course this is only an estimation. But it is better that a fixed padding wich is too big for small numbers and too small for large number...

Upvotes: 2

Related Questions