I'm having some trouble with the axis labels. It seems my custom labels aren't visible outside of the plot area. Looking at the Design Overview for core plot, the axis labels should be outside of the plot area. Any ideas on how I can make them visible outside the plot area?
The code/image below shows how the labels only show within the plot area. If I change the label offset to a positive number, the labels do not show at all. I'm using Core Plot 0.9 with iOS 5.
Thanks in advance!
CPTTheme *theme = [CPTTheme themeNamed:kCPTPlainWhiteTheme];
graph = [[theme newGraph] retain];;
CPTGraphHostingView *hostingView = (CPTGraphHostingView *)self.view;
hostingView.hostedGraph = graph;
graph.paddingLeft = 40.0;
graph.paddingTop = 40.0;
graph.paddingRight = 40.0;
graph.paddingBottom = 40.0;
graph.masksToBorder = NO;
// ... setup axis
axisSet.yAxis.majorIntervalLength = CPTDecimalFromInt(0);
axisSet.yAxis.minorTicksPerInterval = 0;
axisSet.yAxis.labelingPolicy = CPTAxisLabelingPolicyNone;
// if this number is negative, the labels show,
// if it is positive, that is outside the plot area, the labels are hidden.
axisSet.yAxis.labelOffset = -20;
// ... setup labels
NSMutableArray *labels = [NSMutableArray array];
for (int i = 0; i < reportData.rowCount; ++i) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[NSString stringWithFormat:#"Test Row %i", i] textStyle:labelStyle];
label.tickLocation = CPTDecimalFromInt(i);
label.offset = axisSet.yAxis.labelOffset;
label.alignment = CPTAlignmentLeft;
[labels addObject:label];
[label release];
}
axisSet.yAxis.axisLabels = [NSSet setWithArray:labels];
Set some padding on the plot area frame in addition to or instead of the graph itself.
graph.plotAreaFrame.paddingTop = 20.0;
graph.plotAreaFrame.paddingBottom = 50.0;
graph.plotAreaFrame.paddingLeft = 50.0;
graph.plotAreaFrame.paddingRight = 50.0;
This code is from the axis demo in the Plot Gallery example app.
I was having exactly the same problem and tried every solution I could find online for this with no success.
Finally I got it to work by turning off the border masking, like this:
graph.plotAreaFrame.masksToBorder = NO;
Related
I'm using core plot for line graph.in the scatter graph i'm getting some blank space around the scatter graph.as you can see the screen shot(in debug mode) my graph plot area is covered by empty space.How can i remove it?
Initialising host view
self.hostView = [(CPTGraphHostingView *) [CPTGraphHostingView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height-10)];
self.hostView.backgroundColor = [UIColor clearColor];;
self.hostView.allowPinchScaling = NO;
[self addSubview:self.hostView];
Initializing graph
graph = [[CPTXYGraph alloc] initWithFrame:self.hostView.bounds];
[graph applyTheme:[CPTTheme themeNamed:kCPTPlainWhiteTheme]];
self.hostView.hostedGraph = graph;
EDIT
graph.plotAreaFrame.PaddingLeft = 55.0f;
graph.plotAreaFrame.PaddingRight = 15.0f;
graph.plotAreaFrame.PaddingTop = 10.0f;
graph.plotAreaFrame.paddingBottom = 28.0;
These are the paddings i have provided.
The graph starts with 20 pixels of padding on each edge but that's easy to change:
graph.PaddingLeft = 0.0;
graph.PaddingTop = 0.0;
graph.PaddingRight = 0.0;
graph.PaddingBottom = 0.0;
I have created a CPTScatterPlot, with custom Xaxislabels defined.
var axisSet = (CPTXYAxisSet) graph.AxisSet;
// Label x with a fixed interval policy
var x = axisSet.XAxis;
x.LabelingPolicy = CPTAxisLabelingPolicy.None;
x.MinorTicksPerInterval = 4;
x.PreferredNumberOfMajorTicks = 8;
x.MajorGridLineStyle = major;
x.MinorGridLineStyle = minor;
x.Title = "X Axis";
x.TitleOffset = -30;
x.LabelOffset = 15.0f;
NSMutableArray customLabels = new NSMutableArray (dataToPlot.Count);
foreach (PointF pt in dataToPlot) {
string xlabel = pt.X.ToString ().PadLeft (6, '0');
CPTTextStyle tstyle = new CPTTextStyle ();
tstyle.Color = CPTColor.WhiteColor;
tstyle.FontSize = 15;
CPTAxisLabel newLabel = new CPTAxisLabel (xlabel, tstyle);
newLabel.TickLocation = NSDecimalNumber.FromUInt32(uint.Parse(pt.X.ToString())).NSDecimalValue;
newLabel.Offset = 3.0f;
newLabel.Rotation = (float)Math.PI/2f;
customLabels.Add (newLabel);
}
x.AxisLabels = new NSSet(customLabels);
This code works fine, but all the axis labels are overlapped. How to remove the overlapping and display only specific labels in the visible range?
Also how to reload the xaxis when user zooms in or zooms out.
Kindly help, I am struck with this.
Thanks
srrin
There is no automatic label overlap-removal built into Core Plot right now. You'll need to do it yourself based on the size and number of labels. Use a plot space delegate to monitor changes in the plot space and update the tick locations and labels as needed when the plot range changes.
Im trying to draw a donut pie chart on ios with core-plot, with one chart inside of another. Each slice has the same width, but the slices are color coded. I'm trying to place a colored dot in the center of each slice, but I can't figure out how to get the position of the dots correct.
I've managed to get them roughly centered using the labelOffset property of the pie chart.(currently im using a label offset of -35, determined by trial and error). But I can't mange to get them exactly centered, and in the innermost graph they can end up far enough off that they are in the wrong slice.
I have tried setting the rectAnchor property of the text layer, and the padding, but neither one seems to have any effect.
Code for creating the plots:
CGFloat startAngle = [self degreesToRadians:90 + ((360 / [self.dangerRoseData numberOfSectors]) /2.0)];
NSInteger levels = [self.dangerRoseData numberOfLevels];
for(int i = 0; i < levels; i++){
CGFloat radiusD = (i + 1.0)/ levels;
CGFloat radius = MIN(radiusD * (graphHostingView.frame.size.height - 2 * graph.paddingLeft) / 2.8,
radiusD * (graphHostingView.frame.size.width - 2 * graph.paddingTop) / 2.8);
CPTPieChart *lastPie = [plots lastObject];
CGFloat innerRadius;
if(lastPie != nil)
innerRadius = lastPie.pieRadius;
else
innerRadius = 0;
CPTPieChart *piePlot = [[CPTPieChart alloc] init];
piePlot.backgroundColor = [UIColor clearColor].CGColor;
piePlot.dataSource = self;
piePlot.delegate = self;
piePlot.pieRadius = radius;
piePlot.pieInnerRadius = innerRadius;
piePlot.identifier = [self.dangerRoseData nameForLevel:i];
piePlot.borderLineStyle = lineStyle;
piePlot.startAngle = startAngle;
piePlot.sliceDirection = CPTPieDirectionClockwise;
piePlot.labelOffset = -35;//brute force trial and error
piePlot.labelRotationRelativeToRadius = NO;//new property after 1.0
[graph addPlot:piePlot];
[plots addObject:piePlot];
}
and for the labels:
-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index{
....
CPTMutableTextStyle *textStyle = [[CPTMutableTextStyle alloc] init];
textStyle.color = color;
textStyle.fontSize = 36;
CPTTextLayer *label = [[CPTTextLayer alloc] initWithText:#"•" style:textStyle];
return label;
}
I Tried updating to the newest version of core-plot, which adds a new property to CPTPiePlot labelRotationRelativeToRadius which seems like it ought to be the answer to this problem, but it's not. With the new version im not able to get the dots positioned anywhere close to the correct spot.
Am I missing something with positioning the labels?
Am I using totally the wrong approach to putting the dots in the slices?
Well, I decided to give a try using images instead of text labels, and the positioning works just fine, it doesn't seem to be at all erratic like text labels.
In order to be able to fit the dots in the inner most pie I also had to change the sizes, so instead of taking up equal amounts of the total radius, the inner pie takes twice the space of the rest.
Code for generating the plots:
NSInteger levels = [self.dangerRoseData numberOfLevels];
for(int i = 0; i < levels; i++){
CPTPieChart *lastPie = [plots lastObject];
CGFloat innerRadius;
if(lastPie != nil)
innerRadius = lastPie.pieRadius;
else
innerRadius = 0;
CGFloat ringThickness;
ringThickness = ( (graphHostingView.frame.size.width - 2 * graph.paddingTop) / ((levels + 1) * 2) ) * .85;
if(i == 0)//make the inner circle twice the thickness of the rings
ringThickness += ringThickness;
CGFloat radius = innerRadius + ringThickness;
int labelOffset = -14;
if(i == 0)
labelOffset = -15;
CPTPieChart *piePlot = [[CPTPieChart alloc] init];
piePlot.backgroundColor = [UIColor clearColor].CGColor;
piePlot.dataSource = self;
piePlot.delegate = self;
piePlot.pieRadius = radius;
piePlot.pieInnerRadius = innerRadius;
piePlot.identifier = [self.dangerRoseData nameForLevel:i];
piePlot.borderLineStyle = lineStyle;
piePlot.startAngle = startAngle;
piePlot.sliceDirection = CPTPieDirectionClockwise;
piePlot.labelOffset = labelOffset;
[graph addPlot:piePlot];
[plots addObject:piePlot];
}
and for the labels:
-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index
{
...
CPTImageLayer *layer = [[CPTImageLayer alloc] initWithImage:[UIImage imageNamed:filename]];
layer.anchorPoint = CGPointMake(0.5, 0.5);
return layer;
}
Note that the CPTImageLayer is an addition to the standard core-plot to reduce the complexity of using image
I think i found a bug similar to issue 104
I have a bar graph. My axis is fixed with constraint and i use padding left on my plot area and custom label for my X axis.
It is import to show the last bars so my xRange starts on the end with the code below
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat([[posicoes lastObject] floatValue]) length:CPTDecimalFromFloat(tipoEscalaGrafico*60*13)];
Everything works perfectly except from the label.
On the print bellow you can see the problem
http://3.bp.blogspot.com/-BLWrnrZ1MZY/T8aMqEc3PzI/AAAAAAAAAG8/sXhIgvuuj_0/s1600/Captura+de+Tela+2012-05-30+às+18.05.01.png
The label doesn't respect the padding.
If i scroll the graph then it respect the padding as the screen bellow
http://1.bp.blogspot.com/-uvFem8xERAo/T8aMmaLRl2I/AAAAAAAAAG0/DZx_UwCcmbA/s1600/Captura+de+Tela+2012-05-30+às+18.05.01+(2).png
I have a class that inherits from CPTXYGraph and i did the method below to add custom labl=els
-(void)setarLabelsEixoX:(NSArray *)labels naPosicao:(NSArray *)posicaoLabels;{
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.axisSet;
CPTXYAxis *x = axisSet.xAxis;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
NSUInteger labelLocation = 0;
NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:[labels count]];
for ( NSNumber *tickLocation in posicaoLabels ) {
CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText:[labels objectAtIndex:labelLocation++] textStyle:x.labelTextStyle];
newLabel.tickLocation = [tickLocation decimalValue];
newLabel.offset = x.labelOffset;
newLabel.alignment = CPTAlignmentCenter;
[customLabels addObject:newLabel];
}
axisSet.xAxis.majorTickLocations = (NSSet*)posicaoLabels;
x.axisLabels = [NSSet setWithArray:customLabels];
}
I did a little testing with the latest Core Plot code. I don't see an issue. Did you verify that the tick location of the errant label was actually outside the plot range? What version of Core Plot are you using?
I am using Core Plot alpha release 0.2 and generating a plot with custom labels. The labels are appearing in the correct location but I have no tick marks. I have tried every combination of these settings:
x.majorIntervalLength = [[NSDecimalNumber decimalNumberWithString:#"5"] decimalValue];
x.minorTicksPerInterval = 0;
x.majorTickLineStyle = lineStyle;
x.minorTickLineStyle = lineStyle;
x.axisLineStyle = lineStyle;
x.minorTickLength = 5.0f;
x.majorTickLength = 7.0f;
x.tickDirection=CPSignNegative;
I've also added padding to the bottom of the graph using:
graph.plotAreaFrame.paddingBottom=10.0;
which has the effect of moving the X axis 'up' but no tick marks are visible. This seems like it should be pretty simple, generate a tick mark at the location of the custom label. But I don't see any way to do it.
Ideas?
**** Here's the code I'm using to generate the labels and tick marks, with no luck *
for (int i = 0; i < [xAxisLabels count]; i++) {
NSDictionary * labelDict = [xAxisLabels objectAtIndex:i];
NSString *label=[labelDict valueForKey:#"element"];
NSNumber *offset=[labelDict valueForKey:#"x"];
float location=[offset floatValue]*multiplier;
CPAxisLabel *newLabel = [[CPAxisLabel alloc] initWithText: label textStyle:labelStyle];
newLabel.tickLocation = CPDecimalFromFloat(location);
newLabel.offset = x.labelOffset + x.majorTickLength;
[customTicks addObject:[NSDecimalNumber decimalNumberWithDecimal:CPDecimalFromFloat(location)]];
[customLabels addObject:newLabel];
[newLabel release];
}
x.axisLabels = [NSSet setWithArray:customLabels];
[x setMinorTickLocations:[NSSet setWithArray:customTicks]];
[x setMajorTickLocations:[NSSet setWithArray:customTicks]];
[customTicks release];
With CPAxisLabelingPolicyNone you need to provide the tick locations (minorTickLocations and majorTickLocations), too.