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.
Related
I'm working on the axisLabels and need to make the labels side by side with no space in between. However it seems the labels are autosized to the text. Is there a way to set the width of the labels?
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.weightHistoryChart.axisSet;
CPTXYAxis *x = axisSet.xAxis;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
NSArray *customTickLocations = [NSArray arrayWithObjects:#1.0, #3.0, #5.0, nil];
NSMutableSet *customLabels = [NSMutableSet setWithCapacity:3];
for ( NSNumber *tickLocation in customTickLocations ) {
CPTTextLayer *layer = [[CPTTextLayer alloc] initWithText:#"label"];
CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithContentLayer:layer];
newLabel.tickLocation = tickLocation;
newLabel.offset = 0;
[newLabel.contentLayer setBackgroundColor:[UIColor lightGrayColor].CGColor];
[customLabels addObject:newLabel];
}
x.axisLabels = customLabels;
With space:
Remove space:
You can set the left and right padding on the CPTTextLayer to leave extra space on the sides around the text. However, if all you want is a solid rectangle behind the labels, it might look better to add a layer annotation behind the labels.
I'm experiencing some problems with CorePlot. I try to plot multiple scatterPlots into one graph. Which works as expected but when I start scrolling or zooming the graph the whole app increases it's memory usage up to 900MB an crashes. I think I have to do some object releasing but I don't know how. Basically I plot each line with a different plot identifier and put the according data into the datasource.
Here is what I got: (In this example code I just reduced the axe ranges with static values for testing purposes.)
- (void)setupGraph {
// Create graph from theme
self.graph = [[CPTXYGraph alloc] initWithFrame:self.scatterPlotView.bounds];
self.graph.plotAreaFrame.masksToBorder = NO;
self.scatterPlotView.hostedGraph = self.graph;
CPTTheme *theme = [CPTTheme themeNamed:kCPTPlainBlackTheme];
[self.graph applyTheme:theme];
self.graph.paddingLeft = 0.0;
self.graph.paddingTop = 0.0;
self.graph.paddingRight = 0.0;
self.graph.paddingBottom = 0.0;
// Setup plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
plotSpace.allowsUserInteraction = YES;
plotSpace.delegate = self;
plotSpace.globalXRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(30)];
plotSpace.globalYRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(15)];
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(10)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(15)];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
CPTXYAxis *y = axisSet.yAxis;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
y.labelingPolicy = CPTAxisLabelingPolicyNone;
}
This method loads my data and draws the scatterplots
- (void)loadSignals {
//Data loading logic goes here nothing special just one array for each plot
for (Signal *sig in [signals allValues]) {
[self constructScatterPlot:sig.name];
}
}];
This is where the drawing happens:
- (void)constructScatterPlot:(NSString *)identifier {
CPTScatterPlot *dataSourceLinePlot = [[CPTScatterPlot alloc] init];
CPTMutableLineStyle *lineStyle = [dataSourceLinePlot.dataLineStyle mutableCopy];
CPTScatterPlot *boundLinePlot = [[CPTScatterPlot alloc] init];
boundLinePlot.identifier = identifier;
lineStyle = [boundLinePlot.dataLineStyle mutableCopy];
lineStyle.miterLimit = 1.0;
lineStyle.lineWidth = 1.0;
lineStyle.lineColor = [CPTColor redColor];
boundLinePlot.dataLineStyle = lineStyle;
boundLinePlot.dataSource = self;
boundLinePlot.cachePrecision = CPTPlotCachePrecisionDouble;
boundLinePlot.interpolation = CPTScatterPlotInterpolationStepped;
[self.graph addPlot:boundLinePlot];
}
...and this is where the datasource gets it's values:
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSString *plotIdent = (NSString *) plot.identifier;
if (![plotIdent isEqualToString:self.currentIdent]) {
self.countPlot++;
self.currentIdent = plotIdent;
}
Signal *newSig = [self.signals objectForKey:plotIdent];
Value * newValue = [newSig valueAtTime:index];
NSNumber *number = [NSNumber numberWithInteger:[newValue.value integerValue]];
if ( fieldEnum == CPTScatterPlotFieldY ) {
return number;
}
if ( fieldEnum == CPTScatterPlotFieldX ) {
return [NSNumber numberWithInteger:index];
}
return nil;
}
So first of all I'd like to know if this is the correct way of drawing multiple plots (up to 40 in my case) into one graph? If so, what could I do to optimize my plot performance?
The output should look like this:
I found this use
"try setting collapsesLayers to YES on the hosting view"
Application get stuck when drawing nearly 40 Scatter Plots using Core Plot in IPad
Each plot is a CALayer that covers the entire plot area of the graph, so with 40 of them you may be using up most of the available video memory. If they all use the same line style, you can plot all of the lines on the same plot and save some memory that way. Insert an extra data point between the line segments and return nil or #(NAN) from the datasource to break the line.
Am trying to plot a simple statistics using Core Plot in an iPhone App. I initially used the labeling policy as CPTAxisLabelingPolicyAutomatic for both the axes, and the grid lines appeared fine as here :
You can see that the graph has both vertical and horizontal grid lines. Then, I changed the labeling policy to
axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyNone;
axisSet.yAxis.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
NSUInteger labelLocation = 0;
NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:xAxisLabels.count];
CPTMutableTextStyle *textStyle = [[CPTMutableTextStyle alloc] init];
textStyle.color = [CPTColor lightGrayColor];
for (NSNumber *tickLocation in customTickLocations) {
CPTAxisLabel *newLabel = [[CPTAxisLabel alloc]
initWithText:[NSString stringWithFormat:#"%#",(NSDate *)[xAxisLabels objectAtIndex:labelLocation++]] textStyle:textStyle];
newLabel.tickLocation = [tickLocation decimalValue];
newLabel.rotation = 25.0;
newLabel.offset = 10.0;
[customLabels addObject:newLabel];
}
axisSet.xAxis.axisLabels = [NSSet setWithArray:customLabels];
But, since when I added custom labeling for X-Axis, the X-Axis grid lines (i.e. the vertical ones) are not appearing. Only horizontal grid lines are seen, as you can see in the below screenshot from the App :
The CPTAxisLabelingPolicyNone labeling policy does not create any labels or tick marks. You need to create sets of locations and set the majorTickLocations and/or minorTickLocations.
Here's some sample code from the Plot Gallery example app:
NSSet *majorTickLocations = [NSSet setWithObjects:[NSDecimalNumber zero],
[NSDecimalNumber numberWithUnsignedInteger:30],
[NSDecimalNumber numberWithUnsignedInteger:50],
[NSDecimalNumber numberWithUnsignedInteger:85],
[NSDecimalNumber numberWithUnsignedInteger:100],
nil];
xAxis.majorTickLocations = majorTickLocations;
The tick locations are often the same as the label locations, but they don't have to be.
Thank you, #Erik Skroch ! What worked for me was a simple change in the labeling policy from
axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyNone;
to
axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyFixedInterval;
This was instigated by your statement :
"The CPTAxisLabelingPolicyNone labeling policy does not create any labels or tick marks."
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'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;