I have a chart with 2 bar plots (Example: A and B).
For each hour i have 2 bar plots.
When i set the legend, i get swatch and text for every hour and bar
plot.
Example: In my chart have 4 hours then my legend will be like this
A A A A
B B B B
And i only want
A B
Because on every hour, the bars means the same.
How can i do this ??
I have tried everything to make this happen but no success till now....
Bellow is my
// CPTLegend *theLegend = [CPTLegend legendWithGraph:barChart];
CPTLegend *theLegend = [CPTLegend legendWithPlots:[NSArray arrayWithObjects:[barChart plotAtIndex:0],[barChart plotAtIndex:1], nil]];
theLegend.numberOfRows = 1;
theLegend.numberOfColumns = 2;//[horas count] +1 / 2;
//theLegend.fill = [CPTFill fillWithColor:[CPTColor colorWithGenericGray:0.15]];
//theLegend.borderLineStyle = barLineStyle;
theLegend.cornerRadius = 10.0;
theLegend.swatchSize = CGSizeMake(15, 15);
//whiteTextStyle.fontSize = 16.0;
//theLegend.textStyle = whiteTextStyle;
theLegend.rowMargin = 10.0;
theLegend.paddingLeft = 12.0;
theLegend.paddingTop = 12.0;
theLegend.paddingRight = 12.0;
theLegend.paddingBottom = 12.0;
//theLegend.equalColumns = YES;
//theLegend.equalRows = YES;
theLegend.delegate = self;
barChart.legend = theLegend;
-(NSString *)legendTitleForBarPlot:(CPTBarPlot *)barPlot recordIndex:(NSUInteger)index{
if ( [barPlot.identifier isEqual:#"Embarque"] ) {
if (index == 0)
{
return #"Embarque";
}else {
return #"";
}
}else {
if (index == 0)
{
return #"Desembarque";
}else {
return #"";
}
}
}
-(BOOL)legend:(CPTLegend *)legend shouldDrawSwatchAtIndex:(NSUInteger)index forPlot:(CPTPlot *)plot inRect:(CGRect)rect inContext:(CGContextRef)context{
if (index == 0) {
return YES;
}else{
return NO;
}
}
Don't implement the -legendTitleForBarPlot:recordIndex: method unless you want a separate label for each bar. Use the title property to set a single legend title for the plot.
The -legend:shouldDrawSwatchAtIndex:forPlot:inRect:inContext: method is only needed if you want to change the default swatch drawing in some way.
-(void) exibirGraficoEmbarqueDescarga {
// Create barChart from theme
barChart = [[CPTXYGraph alloc] initWithFrame:CGRectZero];
CPTTheme *theme = [CPTTheme themeNamed:kCPTPlainWhiteTheme];
[barChart applyTheme:theme];
//CPTGraphHostingView *hostingView = (CPTGraphHostingView *)self.view;
//hostingView.hostedGraph = barChart;
barChart.delegate = self;
if (chartView == nil)
{
chartView = [[CPTGraphHostingView alloc] initWithFrame:CGRectMake(-15, 30, 350, 320)];
// chartView = [[CPTGraphHostingView alloc] initWithFrame:CGRectMake(0, 35, 510, 280)];
[self.view addSubview:chartView];
}
chartView.hostedGraph = barChart;
// Border
barChart.plotAreaFrame.borderLineStyle = nil;
barChart.plotAreaFrame.cornerRadius = 0.0f;
// Paddings
barChart.paddingLeft = 0.0f;
barChart.paddingRight = 0.0f;
barChart.paddingTop = 0.0f;
barChart.paddingBottom = 0.0f;
barChart.plotAreaFrame.paddingLeft = 70.0;
barChart.plotAreaFrame.paddingTop = 20.0;
barChart.plotAreaFrame.paddingRight = 20.0;
barChart.plotAreaFrame.paddingBottom = 80.0;
// Graph title
barChart.title = #"Embarque / Descarga";
CPTMutableTextStyle *textStyle = [CPTTextStyle textStyle];
textStyle.color = [CPTColor grayColor];
textStyle.fontSize = 16.0f;
textStyle.textAlignment = CPTTextAlignmentCenter;
barChart.titleTextStyle = textStyle;
barChart.titleDisplacement = CGPointMake(1.0f, -20.0f);
barChart.titlePlotAreaFrameAnchor = CPTRectAnchorTop;
// Add plot space for horizontal bar charts
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)barChart.defaultPlotSpace;
Apoio *apoio = [[Apoio alloc] init];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat([apoio retornaMaiorDadosGrafico:qtdEmb :qtdDesc])];
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat(16.0f)];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)barChart.axisSet;
CPTXYAxis *x = axisSet.xAxis;
CPTMutableLineStyle *marcacaoLineStyle = [CPTLineStyle lineStyle];
marcacaoLineStyle.lineColor = [CPTColor lightGrayColor];
marcacaoLineStyle.lineWidth = 1;
x.axisLineStyle = marcacaoLineStyle;
x.majorTickLineStyle = marcacaoLineStyle;
x.minorTickLineStyle = marcacaoLineStyle;
x.majorIntervalLength = CPTDecimalFromString(#"5");
x.orthogonalCoordinateDecimal = CPTDecimalFromString(#"0");
//x.title = #"Horas";
//x.titleLocation = CPTDecimalFromFloat(15.0f);
//x.titleOffset = 55.0f;
// Define some custom labels for the data elements
x.labelingPolicy = CPTAxisLabelingPolicyNone;
NSArray *customTickLocations = posicao;//[NSArray arrayWithObjects:[NSDecimalNumber numberWithFloat:0.7], [NSDecimalNumber numberWithFloat:2.7], [NSDecimalNumber numberWithFloat:4.7], nil];
NSArray *xAxisLabels = horas;//[NSArray arrayWithObjects:#"10", #"11", #"12", nil];
NSUInteger labelLocation = 0;
NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:[xAxisLabels count]];
for ( NSNumber *tickLocation in customTickLocations ) {
CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText:[xAxisLabels objectAtIndex:labelLocation++] textStyle:x.labelTextStyle];
newLabel.tickLocation = [tickLocation decimalValue];
newLabel.offset = x.labelOffset; //+ x.majorTickLength;
[customLabels addObject:newLabel];
}
x.axisLabels = [NSSet setWithArray:customLabels];
CPTXYAxis *y = axisSet.yAxis;
y.axisLineStyle = marcacaoLineStyle;
y.majorTickLineStyle = marcacaoLineStyle;
y.minorTickLineStyle = marcacaoLineStyle;
y.majorIntervalLength = CPTDecimalFromInt([apoio retornaMaiorDadosGrafico:qtdEmb :qtdDesc]/7); //CPTDecimalFromString(#"5");
y.orthogonalCoordinateDecimal = CPTDecimalFromString(#"0");
y.title = #"Containers";
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:0];
y.labelFormatter = formatter;
CPTMutableLineStyle *majorGridLineStyle = [CPTMutableLineStyle lineStyle];
majorGridLineStyle.lineWidth = 0.75;
majorGridLineStyle.lineColor = [CPTColor lightGrayColor ];
y.majorGridLineStyle = majorGridLineStyle ;
y.preferredNumberOfMajorTicks = 10;
CPTMutableTextStyle *EixostextStyle = [CPTTextStyle textStyle];
EixostextStyle.fontSize = 12.0f;
y.labelTextStyle = EixostextStyle;
x.labelTextStyle = EixostextStyle;
// Embaque
CPTBarPlot *barPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor darkGrayColor] horizontalBars:NO];
barPlot.baseValue = CPTDecimalFromString(#"0");
barPlot.dataSource = self;
barPlot.delegate = self;
barPlot.barOffset = CPTDecimalFromFloat(0.25f);
barPlot.identifier = #"Embarque";
barPlot.title = #"Embarque";
barPlot.labelOffset = 0;
[barChart addPlot:barPlot toPlotSpace:plotSpace];
//Descarga
CPTBarPlot *barPlot2 = [CPTBarPlot tubularBarPlotWithColor:[CPTColor blueColor] horizontalBars:NO];
barPlot2.baseValue = CPTDecimalFromString(#"0");
barPlot2.dataSource = self;
barPlot2.delegate = self;
//barPlot2.barOffset = CPTDecimalFromFloat(25f);
barPlot2.identifier = #"Descarga";
barPlot2.title = #"Descarga";
barPlot2.labelOffset = 0;
[barChart addPlot:barPlot2 toPlotSpace:plotSpace];
CPTLegend *theLegend = [CPTLegend legendWithGraph:barChart];
theLegend.numberOfRows = 1;
theLegend.numberOfColumns = 2;
theLegend.cornerRadius = 10.0;
theLegend.swatchSize = CGSizeMake(15, 15);
//whiteTextStyle.fontSize = 16.0;
//theLegend.textStyle = whiteTextStyle;
theLegend.rowMargin = 10.0;
theLegend.paddingLeft = 12.0;
theLegend.paddingTop = 12.0;
theLegend.paddingRight = 12.0;
theLegend.paddingBottom = 12.0;
//theLegend.equalColumns = YES;
//theLegend.equalRows = YES;
barChart.legend = theLegend;
}
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot{
return [horas count];}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSDecimalNumber *num = nil;
if ( [plot isKindOfClass:[CPTBarPlot class]] ) {
switch ( fieldEnum ) {
case CPTBarPlotFieldBarLocation:
if ( [plot.identifier isEqual:#"Embarque"] ) {
num = (NSDecimalNumber *)[NSDecimalNumber numberWithUnsignedInteger:index*2];
} else{
num = (NSDecimalNumber *)[NSDecimalNumber numberWithUnsignedInteger:(index*2+1)];
}
break;
case CPTBarPlotFieldBarTip:
if ( [plot.identifier isEqual:#"Embarque"] ) {
num = [qtdEmb objectAtIndex:index];
} else{
num = [qtdDesc objectAtIndex:index];
}
break;
}
}
return num;
}
-(CPTFill *)barFillForBarPlot:(CPTBarPlot *)barPlot recordIndex:(NSUInteger)index
{
if ( [barPlot.identifier isEqual:#"Embarque"] ) {
return [CPTFill fillWithColor:[CPTColor colorWithComponentRed:(175/255.0 ) green:(238/255.0) blue:(238/255.0) alpha:1.0]];
}
if ( [barPlot.identifier isEqual:#"Descarga"] ) {
return [CPTFill fillWithColor:[CPTColor colorWithComponentRed:(255./255.0 ) green:(228.0/255.0) blue:(181.0/255.0) alpha:1.0]];
}
}
-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index
{
int valor;
if ( [plot.identifier isEqual:#"Embarque"] )
{
valor = [qtdEmb objectAtIndex:index];
}else{
valor = [qtdDesc objectAtIndex:index];
}
CPTTextLayer *newLayer = [[CPTTextLayer alloc] initWithText:[[NSString alloc] initWithFormat:#"%#",valor]];
CPTMutableTextStyle *estiloTexto = [[CPTMutableTextStyle alloc] init];
estiloTexto.color = [CPTColor blackColor];
estiloTexto.fontSize = 10;
newLayer.textStyle = estiloTexto;
return newLayer;
}
Related
I'm trying to display a line using a ScatterPlot on Bar plot, which is horizontal. It does work for vertical bar plots, but not for the horizontal one.
This is the source code:
-(id)init
{
if ( (self = [super init]) ) {
self.section = kBarPlots;
self.isOneBarPlot = TRUE;
}
return self;
}
-(void)generateData
{
[[BPDatabaseController sharedController] dataForTopFiveObservationPeriodIncidents:^(NSArray *resultArray) {
self.plotData = resultArray;
FilterManager *fm = [FilterManager sharedInstance];
self.isOneBarPlot = fm.filterPendingIncidents; //is responsible for showing the legend correctly
[self renderInLayer:self.defaultLayerHostingView withTheme:self.theme animated:YES];
[super generateData];
}];
}
-(void)renderInLayer:(CPTGraphHostingView *)layerHostingView withTheme:(CPTTheme *)theme animated:(BOOL)animated
{
CGRect bounds = layerHostingView.bounds;
CPTGraph *graph = [[CPTXYGraph alloc] initWithFrame:bounds];
[self addGraph:graph toHostingView:layerHostingView];
[self applyTheme:theme toGraph:graph withDefault:nil];
[self setTitleDefaultsForGraph:graph withBounds:bounds];
[self setPaddingDefaultsForGraph:graph withBounds:bounds];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
graph.paddingLeft = 0.0f;
}else{
graph.paddingLeft = 65.0f;
}
graph.paddingRight = 0.0f;
NSNumberFormatter *format = [[NSNumberFormatter alloc] init];
[format setNumberStyle:NSNumberFormatterNoStyle];
// Create bar plot
CPTBarPlot *barPlot = [[CPTBarPlot alloc] init];
barPlot.lineStyle = [[CPTTheme themeNamed:kCPTDarkBlueTheme] axisLineStyle:kBarLineStyle];
barPlot.barWidth = CPTDecimalFromFloat(0.60f); // bar is 75% of the available space
barPlot.barCornerRadius = 0.0;
barPlot.barsAreHorizontal = YES;
barPlot.dataSource = self;
barPlot.identifier = kBarPlotPending;
barPlot.delegate = self;
barPlot.fill = [[CPTTheme themeNamed:kCPTDarkBlueTheme] barFillForBarPlotOfType:kHorizontalRed];
barPlot.labelTextStyle = [[CPTTheme themeNamed:kCPTDarkBlueTheme] barTextStyle];
barPlot.labelFormatter = format;
barPlot.labelOffset = 1.0;
barPlot.anchorPoint = CGPointMake(0.0, 0.0);
[barPlot addAnimation:[self plotAnimationWithKeyPath:#"transform.scale.x"] forKey:#"someKey"];
if(!self.isOneBarPlot){
[graph addPlot:barPlot];
}
// Create bar plot
CPTBarPlot *barPlot2 = [[CPTBarPlot alloc] init];
barPlot2.lineStyle = [[CPTTheme themeNamed:kCPTDarkBlueTheme] axisLineStyle:kBarLineStyle];;
barPlot2.barWidth = CPTDecimalFromFloat(0.60f); // bar is 75% of the available space
barPlot2.barCornerRadius = 0.0;
barPlot2.barsAreHorizontal = YES;
barPlot2.dataSource = self;
barPlot2.identifier = kBarPlotOfficial;
barPlot2.delegate = self;
barPlot2.labelFormatter = format;
barPlot2.fill = [[CPTTheme themeNamed:kCPTDarkBlueTheme] barFillForBarPlotOfType:kHorizontalBlue];
barPlot2.anchorPoint = CGPointMake(0.0, 0.0);
barPlot2.labelTextStyle = [[CPTTheme themeNamed:kCPTDarkBlueTheme] barTextStyle];
if(!self.isOneBarPlot){
barPlot2.labelOffset = -1.0;
}
[graph addPlot:barPlot2];
[barPlot2 addAnimation:[self plotAnimationWithKeyPath:#"transform.scale.x"] forKey:#"someKey"];
// make the bars thinner if only one data set is available
if ([self.plotData count] == 1) {
barPlot.barWidthScale = kBarWithScaleOneItem;
barPlot2.barWidthScale = kBarWithScaleOneItem;
}
if ([self.plotData count] > 0) {
// Plot space
CPTMutablePlotRange *barRange = [[barPlot plotRangeEnclosingBars] mutableCopy];
[barRange expandRangeByFactor:CPTDecimalFromDouble(1.05)];
CPTXYPlotSpace *barPlotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
barPlotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat([self calculateDatasourcePeak])];
barPlotSpace.yRange = barRange;
CPTScatterPlot *targetLinePlot = [[CPTScatterPlot alloc] init];
targetLinePlot.identifier = kBarPlotTarget;
targetLinePlot.title = NSLocalizedString(kBarPlotTarget, nil);
CPTMutableLineStyle *barLineStyleTarget = [[CPTMutableLineStyle alloc] init];
barLineStyleTarget.lineWidth = 2.0;
barLineStyleTarget.lineColor = [CPTColor grayColor];
targetLinePlot.dataLineStyle = barLineStyleTarget;
targetLinePlot.dataSource = self;
[graph addPlot:targetLinePlot toPlotSpace:barPlotSpace];
[self configureAxis:graph];
[self createDarkBackgroundPlot:graph isHorizontal:TRUE];
}else{
self.emtyPlot.alpha = 1.0;
// Create axes
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis *y = axisSet.yAxis;
{
y.majorIntervalLength = CPTDecimalFromInteger(0);
y.axisLineStyle = nil;
y.labelingPolicy = CPTAxisLabelingPolicyNone;
y.labelTextStyle = nil;
y.majorTickLineStyle = nil;
y.minorTickLineStyle = nil;
y.axisConstraints = [CPTConstraints constraintWithLowerOffset:7.0];
}
CPTXYAxis *x = axisSet.xAxis;
{
x.majorIntervalLength = CPTDecimalFromInteger(0);
x.axisConstraints = [CPTConstraints constraintWithLowerOffset:8.0];
x.axisLineStyle = nil;
x.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
x.majorTickLineStyle = nil;
x.minorTickLineStyle = nil;
x.labelTextStyle = nil;
}
}
}
-(void)configureAxis:(CPTGraph *)graph{
[super configureAxis:graph];
NSNumberFormatter *format = [[NSNumberFormatter alloc] init];
[format setNumberStyle:NSNumberFormatterNoStyle];
//legend
CPTLegend *theLegend = [CPTLegend legendWithGraph:graph];
theLegend.borderLineStyle = [[CPTTheme themeNamed:kCPTDarkBlueTheme] axisLineStyle:kBarLineStyle];
theLegend.cornerRadius = 0.0;
theLegend.swatchSize = CGSizeMake(16.0, 16.0);
theLegend.textStyle = [[CPTTheme themeNamed:kCPTDarkBlueTheme] barTextStyle];
theLegend.numberOfRows = 1;
graph.legend = theLegend;
graph.legendAnchor = CPTRectAnchorBottom;
graph.legendDisplacement = CGPointMake(0.0, 0.0);
// Create axes
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis *y = axisSet.yAxis;
{
y.majorIntervalLength = CPTDecimalFromInteger(1);
y.axisLineStyle = [[CPTTheme themeNamed:kCPTDarkBlueTheme] axisLineStyle:kYAxisLineStyle];
y.labelingPolicy = CPTAxisLabelingPolicyNone;
y.orthogonalCoordinateDecimal = CPTDecimalFromInteger(1);
y.labelTextStyle = [[CPTTheme themeNamed:kCPTDarkBlueTheme] barTextStyle];
y.axisConstraints = [CPTConstraints constraintWithLowerOffset:5.0];
}
NSMutableSet *yAxisLegend = [NSMutableSet set];
for (int i = 0; i < self.plotData.count; i++) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[self addLineBreakToString:(NSString*)[[self.plotData objectAtIndex:i] objectForKey:kResultLabel] ]textStyle:[[CPTTheme themeNamed:kCPTDarkBlueTheme] barTextStyle]];
label.tickLocation = CPTDecimalFromInteger(i);
[yAxisLegend addObject:label];
}
y.axisLabels = yAxisLegend;
CPTXYAxis *x = axisSet.xAxis;
{
x.majorIntervalLength = CPTDecimalFromInteger(1);
x.axisConstraints = [CPTConstraints constraintWithLowerOffset:8.0];
x.axisLineStyle = [[CPTTheme themeNamed:kCPTDarkBlueTheme] axisLineStyle:kXAxisLineStyle];
x.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
x.majorTickLineStyle = nil;
x.minorTickLineStyle = nil;
//x.labelFormatter = format;
x.orthogonalCoordinateDecimal = CPTDecimalFromInteger(-1);
x.labelTextStyle = [[CPTTheme themeNamed:kCPTDarkBlueTheme] barTextStyle];
x.labelOffset = 5.0f;
}
}
#pragma mark -
#pragma mark Plot Data Source Methods
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
return self.plotData.count;
}
-(NSArray *)numbersForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndexRange:(NSRange)indexRange
{
NSArray *nums = [super numbersForPlot:plot field:fieldEnum recordIndexRange:indexRange];
if (!nums) {
switch ( fieldEnum ) {
case CPTBarPlotFieldBarLocation:
nums = [NSMutableArray arrayWithCapacity:indexRange.length];
for ( NSUInteger i = indexRange.location; i < NSMaxRange(indexRange); i++ ) {
[(NSMutableArray *)nums addObject : #(i)];
}
break;
case CPTBarPlotFieldBarTip: {
if ([plot.identifier isEqual:kBarPlotTarget]) {
nums = [NSMutableArray arrayWithCapacity:indexRange.length];
for ( NSUInteger i = indexRange.location; i < NSMaxRange(indexRange); i++ ) {
[(NSMutableArray *)nums addObject:#(100)];
}
}else{
NSString *dataKey = nil;
if ([plot.identifier isEqual:kBarPlotOfficial]) {
dataKey = kResultOfficial;
}
else {
dataKey = kResultSum;
}
nums = [NSMutableArray arrayWithCapacity:indexRange.length];
for ( NSUInteger i = indexRange.location; i < NSMaxRange(indexRange); i++ ) {
NSNumber *number = [[self.plotData objectAtIndex:i] objectForKey:dataKey];
[(NSMutableArray *)nums addObject : number];
}
}
break;
}
default:
break;
}
}
return nums;
}
-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)idx
{
CPTTextLayer *textLayer = (id)[NSNull null];;
NSNumber *number = nil;
if ([plot.identifier isEqual:kBarPlotPending]) {
number = [[self.plotData objectAtIndex:idx] objectForKey:kResultSum];
}
else if ([plot.identifier isEqual:kBarPlotOfficial]) {
NSNumber *officialNumber = [[self.plotData objectAtIndex:idx] objectForKey:kResultOfficial];
NSNumber *pendingNumber = [[self.plotData objectAtIndex:idx] objectForKey:kResultSum];
CGFloat maxNumber = [self calculateDatasourcePeak];
// 1.) if the max peak it to high and the current value to low the
// official is not shown correclty (not enough space) => do not show it
// 2.) do not show the official if its the same number as pending
if (!(maxNumber > 100 && [officialNumber intValue] < 50) && ([officialNumber intValue] != [pendingNumber intValue])) {
number = officialNumber;
}
}
if ([number intValue] > 0) {
textLayer = [[CPTTextLayer alloc] initWithText:[number stringValue] style:[[CPTTheme themeNamed:kCPTDarkBlueTheme] barTextStyle]];
}
return textLayer;
}
#pragma mark - CPTBarPlot delegate methods
-(void)plot:(CPTPlot *)plot dataLabelWasSelectedAtRecordIndex:(NSUInteger)index
{
NSLog(#"Data label for '%#' was selected at index %d.", plot.identifier, (int)index);
}
The legend on the bottom does show that there should be a target line, but no one is displayed
Different plot types use different datasource field enumerations. Bar plots will use CPTBarPlotFieldBarLocation and CPTBarPlotFieldBarTip. Scatter plots like the target line plot will use CPTScatterPlotFieldX and CPTScatterPlotFieldY. Make sure the datasource is checking the right field enum values for each plot.
My Issues is as follows:
I'm trying to graph two data sets (One is in Feet and one is in degrees) in such a way that they can be compared (they do share a common x-axis value).
As you can see my data seems to be interlaced correctly but I'm having trouble getting the yAxises to behave as I'd like. I would like the X-Axis Max/Min to actually line up with both Y-Axises. My code is as follows:
- (void)initPlot {
[self loadCoreData];
[self configureHost];
[self configureGraph];
[self configurePlots];
[self configureAxes];
}
- (void)configureHost {
self.hostView = [(CPTGraphHostingView *) [CPTGraphHostingView alloc] initWithFrame:self.view.bounds];
self.hostView.allowPinchScaling = YES;
[self.view addSubview:self.hostView];
}
- (void)configureGraph {
// 1 - Create the graph
CPTGraph *graph = [[CPTXYGraph alloc] initWithFrame:self.hostView.bounds];
[graph applyTheme:[CPTTheme themeNamed:kCPTDarkGradientTheme]];
self.hostView.hostedGraph = graph;
// 2 - Set graph title
NSString *title = [NSString stringWithFormat:#"Altitude Plot [%# to %#]", self.flightRecording.originAirport, self.flightRecording.destinationAirport];
graph.title = title;
// 3 - Create and set text style
CPTMutableTextStyle *titleStyle = [CPTMutableTextStyle textStyle];
titleStyle.color = [CPTColor whiteColor];
titleStyle.fontName = #"Helvetica-Bold";
titleStyle.fontSize = 16.0f;
graph.titleTextStyle = titleStyle;
graph.titlePlotAreaFrameAnchor = CPTRectAnchorTop;
graph.titleDisplacement = CGPointMake(0.0f, -20.0f);
// 4 - Set padding for plot area
float padding = 10.0f;
[graph.plotAreaFrame setPaddingLeft:padding];
[graph.plotAreaFrame setPaddingBottom:50.0f];
[graph.plotAreaFrame setPaddingRight:padding];
[graph.plotAreaFrame setPaddingTop:padding];
// 5 - Enable user interactions for plot space
altSpace= (CPTXYPlotSpace *) graph.defaultPlotSpace;
altSpace.allowsUserInteraction = NO;
rollSpace = [[CPTXYPlotSpace alloc] init];
rollSpace.allowsUserInteraction = NO;
[self.hostView.hostedGraph addPlotSpace:rollSpace];
//
// pitchSpace = [[CPTXYPlotSpace alloc] init];
// pitchSpace.allowsUserInteraction = NO;
// [self.hostView.hostedGraph addPlotSpace:pitchSpace];
//
//
// slipSpace = [[CPTXYPlotSpace alloc] init];
// slipSpace.allowsUserInteraction = NO;
// [self.hostView.hostedGraph addPlotSpace:slipSpace];
//
//
// gSpace = [[CPTXYPlotSpace alloc] init];
// gSpace.allowsUserInteraction = NO;
// [self.hostView.hostedGraph addPlotSpace:gSpace];
}
- (void)configurePlots {
// 1 - Get graph and plot space
CPTGraph *graph = self.hostView.hostedGraph;
// 2 - Create the three plots
// Custom AHRS Plot
CPTScatterPlot *ahrsAltPlot = [[CPTScatterPlot alloc] init];
ahrsAltPlot.dataSource = self;
ahrsAltPlot.identifier = #"AHRSALT";
CPTColor *ahrsAltColor = [CPTColor yellowColor];
[graph addPlot:ahrsAltPlot toPlotSpace:altSpace];
CPTScatterPlot *rollPlot = [[CPTScatterPlot alloc] init];
rollPlot.dataSource = self;
rollPlot.identifier = #"ROLL";
CPTColor *rollColor = [CPTColor greenColor];
[graph addPlot:rollPlot toPlotSpace:rollSpace];
// 3 - Set up plot space
CPTMutablePlotRange *xRange = [altSpace.xRange mutableCopy];
xRange=[CPTMutablePlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f ) length:CPTDecimalFromFloat(maxEpoch + 300.0f )];
// [xRange expandRangeByFactor:CPTDecimalFromCGFloat(1.1f)];
altSpace.xRange = xRange;
CPTMutablePlotRange *yRange = [altSpace.yRange mutableCopy];
yRange = [CPTMutablePlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat(maxAlt)];
[yRange expandRangeByFactor:CPTDecimalFromCGFloat(1.2f)];
altSpace.yRange = yRange;
rollSpace.xRange = xRange;
CPTMutablePlotRange *yRangeRoll =[CPTMutablePlotRange plotRangeWithLocation:CPTDecimalFromFloat(0 ) length:CPTDecimalFromFloat(40 )];
[yRangeRoll expandRangeByFactor:CPTDecimalFromCGFloat(1.2f)];
rollSpace.yRange = yRangeRoll;
[altSpace scaleToFitPlots:[NSArray arrayWithObjects:ahrsAltPlot, nil] ];
[rollSpace scaleToFitPlots:[NSArray arrayWithObjects:rollPlot, nil] ];
[rollSpace setYRange:yRangeRoll];
// 4 - Create styles and symbols
// AHRS Style
CPTMutableLineStyle *ahrsLineStyle = [ahrsAltPlot.dataLineStyle mutableCopy];
ahrsLineStyle.lineWidth = 2.5;
ahrsLineStyle.lineColor = [CPTColor blueColor];
ahrsAltPlot.dataLineStyle = ahrsLineStyle;
}
- (void)configureAxes {
// 1 - Create styles
CPTMutableTextStyle *axisTitleStyle = [CPTMutableTextStyle textStyle];
axisTitleStyle.color = [CPTColor whiteColor];
axisTitleStyle.fontName = #"Helvetica-Bold";
axisTitleStyle.fontSize = 12.0f;
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 2.0f;
axisLineStyle.lineColor = [CPTColor whiteColor];
CPTMutableTextStyle *axisTextStyle = [[CPTMutableTextStyle alloc] init];
axisTextStyle.color = [CPTColor whiteColor];
axisTextStyle.fontName = #"Helvetica-Bold";
axisTextStyle.fontSize = 11.0f;
CPTMutableLineStyle *tickLineStyle = [CPTMutableLineStyle lineStyle];
tickLineStyle.lineColor = [CPTColor whiteColor];
tickLineStyle.lineWidth = 2.0f;
CPTMutableLineStyle *gridLineStyle = [CPTMutableLineStyle lineStyle];
tickLineStyle.lineColor = [CPTColor blackColor];
tickLineStyle.lineWidth = 1.0f;
// 2 - Get axis set
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) self.hostView.hostedGraph.axisSet;
// 3 - Configure x-axis
CPTAxis *x = axisSet.xAxis;
x.title = #"Flight Time";
x.titleTextStyle = axisTitleStyle;
x.titleOffset = 15.0f;
x.axisLineStyle = axisLineStyle;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
x.labelTextStyle = axisTextStyle;
x.majorTickLineStyle = axisLineStyle;
x.majorTickLength = 4.0f;
x.tickDirection = CPTSignNegative;
NSMutableSet *xLabels = [NSMutableSet new];
NSMutableSet *xLocations = [NSMutableSet new];
NSInteger i = 0;
for (i; i < maxEpoch; i += 600) {
int hour = i / (68 * 60);
int min = i / 60;
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[NSString stringWithFormat:#"%02d:%02d", hour, min] textStyle:x.labelTextStyle];
CGFloat location = i++;
label.tickLocation = CPTDecimalFromCGFloat(location);
label.offset = x.majorTickLength;
if (label) {
[xLabels addObject:label];
[xLocations addObject:[NSNumber numberWithInteger:i]];
}
}
x.axisLabels = xLabels;
x.majorTickLocations = xLocations;
// 4 - Configure y-axis
CPTAxis *y = axisSet.yAxis;
y.title = #"Altitude in Feet";
y.titleTextStyle = axisTitleStyle;
y.titleOffset = 20.0f;
y.axisLineStyle = axisLineStyle;
y.majorGridLineStyle = gridLineStyle;
y.labelingPolicy = CPTAxisLabelingPolicyNone;
y.labelTextStyle = axisTextStyle;
y.labelOffset = 21.0f;
y.majorTickLineStyle = axisLineStyle;
y.majorTickLength = 20.0f;
y.minorTickLength = 10.0f;
y.tickDirection = CPTSignNegative;
// Axis #2
CPTXYAxis *yRoll = [[CPTXYAxis alloc] init];
yRoll.title = #"Degrees";
// Styling
yRoll.titleTextStyle = axisTitleStyle;
yRoll.labelTextStyle = axisTextStyle;
yRoll.axisLineStyle = axisLineStyle;
yRoll.majorTickLineStyle = axisLineStyle;
yRoll.plotSpace = rollSpace;
yRoll.delegate = self;
yRoll.labelingPolicy = CPTAxisLabelingPolicyNone;
yRoll.coordinate = CPTCoordinateY;
yRoll.tickDirection = CPTSignNone;
yRoll.separateLayers = NO;
yRoll.tickDirection = CPTSignNegative;
yRoll.labelOffset = 21.0f;
yRoll.axisConstraints = [CPTConstraints constraintWithLowerOffset:40.0];
yRoll.orthogonalCoordinateDecimal = CPTDecimalFromFloat(0.0f);
NSMutableSet *rollLabels = [NSMutableSet new];
NSMutableSet *rollLocations = [NSMutableSet new];
for (int i =0; i <= 40; i+= 5) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[NSString stringWithFormat:#"%02d˚", (i - 20)] textStyle:yRoll.labelTextStyle];
CGFloat location = i;
label.tickLocation = CPTDecimalFromCGFloat(location);
label.offset = -16.0f;
if (label) {
[rollLabels addObject:label];
[rollLocations addObject:[NSNumber numberWithInteger:i]];
}
}
yRoll.axisLabels = rollLabels;
yRoll.majorTickLocations = rollLocations;
NSInteger majorIncrement = 500;
NSInteger minorIncrement = 100;
CGFloat yMax = maxAlt; // should determine dynamically based on max price
NSMutableSet *yLabels = [NSMutableSet set];
NSMutableSet *yMajorLocations = [NSMutableSet set];
NSMutableSet *yMinorLocations = [NSMutableSet set];
for (NSInteger j = minorIncrement; j <= yMax; j += minorIncrement) {
NSUInteger mod = j % majorIncrement;
if (mod == 0) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[NSString stringWithFormat:#"%i ft", j] textStyle:y.labelTextStyle];
NSDecimal location = CPTDecimalFromInteger(j);
label.tickLocation = location;
label.offset = -y.majorTickLength - y.labelOffset;
if (label) {
[yLabels addObject:label];
}
[yMajorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:location]];
} else {
[yMinorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:CPTDecimalFromInteger(j)]];
}
}
// Position the y2 axis
// y2.axisConstraints = [CPTConstraints constraintWithUpperOffset:40.0];
axisSet.yAxis.axisConstraints = [CPTConstraints constraintWithUpperOffset:40.0];
y.axisLabels = yLabels;
y.majorTickLocations = yMajorLocations;
y.minorTickLocations = yMinorLocations;
self.hostView.hostedGraph.axisSet.axes = [NSArray arrayWithObjects:x,y,yRoll,nil];
// Position floating YAxis
// y2.axisConstraints = [CPTConstraints constraintWithUpperOffset:150.0];
}
EDIT::
I tried adding the following lines and they did nothing either
y.orthogonalCoordinateDecimal = CPTDecimalFromFloat(0.0f);
x.orthogonalCoordinateDecimal = CPTDecimalFromFloat(0.0f);
I seem to be making progress actually: It appears that if I remove
yAxis2.axisConstraints = [CPTConstraints constraintWithLowerOffset:40.0];
Then my axis actually seems to pin to the x-axis (although its off the screen) now but its a start.
Problem Solved:
I had some conflicting directives going on.
In order to achieve what I needed I had to use the two calls:
yAxis2.orthogonalCoordinateDecimal = CPTDecimalFromFloat(0.0f);
y.orthogonalCoordinateDecimal = CPTDecimalFromFloat(maxEpoch); // maximum X value
x.orthogonalCoordinateDecimal = CPTDecimalFromFloat(0.0f);
Then in order to make sure everything could be seen correctly I had to play with the padding values:
float padding = 50.0f;
[graph.plotAreaFrame setPaddingLeft:padding];
[graph.plotAreaFrame setPaddingBottom:50.0f];
[graph.plotAreaFrame setPaddingRight:padding];
[graph.plotAreaFrame setPaddingTop:padding];
And I had to remove all the constraints that were messing with things:
// yAxis2.axisConstraints = [CPTConstraints constraintWithLowerOffset:40.0];
// y.axisConstraints = [CPTConstraints constraintWithUpperOffset:150.0];
I have the following code below to display two Y axes (one on the right and one on the left). I would like to be able to plot to each graph per a different data set (mapping to the same X value). I can't seem to get two CPTXYPlotSpaces to display at the same time. How would I go about this so I can plot to two different Plot Spaces and see the graphed lines at the same time.
-(void)configureHost
{
CGRect bounds = self.view.bounds;
bounds.size.height = bounds.size.height;
self.hostView = [[CPTGraphHostingView alloc] initWithFrame:bounds];
self.hostView.allowPinchScaling = YES;
[self.view addSubview:self.hostView];
}
-(void)configureGraph
{
self.graph = [[CPTXYGraph alloc] initWithFrame:self.hostView.bounds];
[self.graph applyTheme:[CPTTheme themeNamed:kCPTPlainWhiteTheme]];
self.hostView.hostedGraph = self.graph;
self.graph.paddingLeft = 20.0;
self.graph.paddingTop = 20.0;
self.graph.paddingRight = 20.0;
self.graph.paddingBottom = 20.0;
}
NSString *const kPlot1 = #"Plot 1";
NSString *const kPlot2 = #"Plot 2";
-(void)configurePlots
{
CGRect bounds = self.hostView.bounds;
self.plotSpace1 = (CPTXYPlotSpace *) self.graph.defaultPlotSpace;
self.plotSpace1.allowsUserInteraction = NO;
self.scatterPlot1 = [[CPTScatterPlot alloc]init];
self.scatterPlot1.identifier = kPlot1;
self.scatterPlot1.dataSource = self;
[self.graph addPlot:self.scatterPlot1 toPlotSpace:self.plotSpace1];
self.scatterPlot2 = [[CPTScatterPlot alloc]init];
self.scatterPlot2.identifier = kPlot2;
self.scatterPlot2.dataSource =self;
[self.graph addPlot:self.scatterPlot2 toPlotSpace:self.plotSpace2];
[self.plotSpace1 scaleToFitPlots:#[self.scatterPlot1, self.scatterPlot2]];
[self.plotSpace2 scaleToFitPlots:#[self.scatterPlot1, self.scatterPlot2]];
CPTGraph *graph = self.hostView.hostedGraph;
graph.plotAreaFrame.fill = [CPTFill fillWithColor:[CPTColor whiteColor]];
[self setTitleDefaultsForGraph:graph withBounds:bounds];
[self setPaddingDefaultsForGraph:graph withBounds:bounds];
graph.plotAreaFrame.paddingTop = 20.0;
graph.plotAreaFrame.paddingBottom = 50.0;
graph.plotAreaFrame.paddingLeft = 50.0;
graph.plotAreaFrame.paddingRight = 50.0;
graph.plotAreaFrame.cornerRadius = 10.0;
graph.plotAreaFrame.masksToBorder = NO;
graph.plotAreaFrame.axisSet.borderLineStyle = [CPTLineStyle lineStyle];
// Setup plot space
self.plotSpace1.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0) length:CPTDecimalFromDouble(10.0)];
self.plotSpace1.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0) length:CPTDecimalFromDouble(10.0)];
self.plotSpace2 = [[CPTXYPlotSpace alloc] init];
self.plotSpace2.xRange = self.plotSpace1.xRange;
self.plotSpace2.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0) length:CPTDecimalFromDouble(10.0)];
[graph addPlotSpace:self.plotSpace2];
}
-(void)setPaddingDefaultsForGraph:(CPTGraph *)graph withBounds:(CGRect)bounds
{
// CGFloat boundsPadding = round( bounds.size.width / CPTFloat(20.0) ); // Ensure that padding falls on an integral pixel
//
// graph.paddingLeft = boundsPadding;
//
// if ( graph.titleDisplacement.y > 0.0 ) {
// graph.paddingTop = graph.titleTextStyle.fontSize * 2.0;
// }
// else {
// graph.paddingTop = boundsPadding;
// }
//
// graph.paddingRight = boundsPadding;
// graph.paddingBottom = boundsPadding;
graph.paddingTop = 0.0f;
graph.paddingBottom = 0.0f;
graph.paddingLeft = 0.0f;
graph.paddingRight = 0.0f;
}
-(void)setTitleDefaultsForGraph:(CPTGraph *)graph withBounds:(CGRect)bounds
{
graph.title = self.title;
CPTMutableTextStyle *textStyle = [CPTMutableTextStyle textStyle];
textStyle.color = [CPTColor grayColor];
textStyle.fontName = #"Helvetica-Bold";
textStyle.fontSize = round( bounds.size.height / CPTFloat(20.0) );
graph.titleTextStyle = textStyle;
graph.titleDisplacement = CPTPointMake( 0.0, textStyle.fontSize * CPTFloat(1.5) );
graph.titlePlotAreaFrameAnchor = CPTRectAnchorTop;
}
-(void)configureAxis
{
CPTGraph *graph = self.hostView.hostedGraph;
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
// Line styles
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 3.0;
axisLineStyle.lineCap = kCGLineCapRound;
// Text styles
CPTMutableTextStyle *axisTitleTextStyle = [CPTMutableTextStyle textStyle];
axisTitleTextStyle.fontName = #"Helvetica-Bold";
axisTitleTextStyle.fontSize = 14.0;
CPTXYAxis *x = axisSet.xAxis;
x.orthogonalCoordinateDecimal = CPTDecimalFromDouble(0.0);//Where the Y Axis meets the X axis
x.majorIntervalLength = CPTDecimalFromDouble(1.5);//Interval for X Axis
x.minorTicksPerInterval = 4;
x.tickDirection = CPTSignNone;
x.axisLineStyle = axisLineStyle;
x.majorTickLength = 12.0;
x.majorTickLineStyle = axisLineStyle;
x.minorTickLength = 8.0;
x.title = #"X Axis";
x.titleTextStyle = axisTitleTextStyle;
x.titleOffset = 25.0;
x.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0];
// Label y with an automatic labeling policy.
axisLineStyle.lineColor = [CPTColor greenColor];
CPTXYAxis *y = axisSet.yAxis;
y.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
y.minorTicksPerInterval = 9;
y.tickDirection = CPTSignNegative;
y.axisLineStyle = axisLineStyle;
y.majorTickLength = 6.0;
y.majorTickLineStyle = axisLineStyle;
y.minorTickLength = 4.0;
y.title = #"Y Axis";
y.titleTextStyle = axisTitleTextStyle;
y.titleOffset = 30.0;
// Label y2 with an equal division labeling policy.
axisLineStyle.lineColor = [CPTColor orangeColor];
CPTXYAxis *y2 = [[CPTXYAxis alloc] init];
y2.coordinate = CPTCoordinateY;
y2.plotSpace = self.plotSpace2;
y2.orthogonalCoordinateDecimal = CPTDecimalFromDouble(10.0);//Where the Y Axis meets the X axis
y2.labelingPolicy = CPTAxisLabelingPolicyEqualDivisions;
y2.preferredNumberOfMajorTicks = 6;
y2.minorTicksPerInterval = 9;
y2.tickDirection = CPTSignPositive;
y2.axisLineStyle = axisLineStyle;
y2.majorTickLength = 6.0;
y2.majorTickLineStyle = axisLineStyle;
y2.minorTickLength = 4.0;
y2.title= #"Y2 Axis";
y2.titleTextStyle = axisTitleTextStyle;
y2.titleOffset = 30.0;
// Add the y2 axis to the axis set
graph.axisSet.axes = #[x, y, y2];
}
#pragma mark CPTPlotDataSource
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
if ( [(NSString *)plot.identifier isEqualToString:kPlot1] ) {
return 10;
}
else if ( [(NSString *)plot.identifier isEqualToString:kPlot2] ) {
return 5;
} else {
return 0;
}
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)idx
{
switch (fieldEnum) {
case CPTScatterPlotFieldX:
if ([plot.identifier isEqual:kPlot1]) {
return [NSNumber numberWithUnsignedInt:idx];
break;
}else if ([plot.identifier isEqual:kPlot2]){
return [NSNumber numberWithUnsignedInt:idx];
break;
}
case CPTScatterPlotFieldY:
if ([plot.identifier isEqual:kPlot1]) {
return #(idx *2);
} else if ([plot.identifier isEqual:kPlot2]) {
return #(idx +2);
}
}
return 0;
}
You're (re-)initializing plotSpace2 after you scale it. Move the call to [self.plotSpace2 scaleToFitPlots:...] after setting up the plot space.
I created a core plot graph, have one x-axis, two y-axis, now, I want to have two lines and first use the first y-axis, second use the second y-axis, but it doesn't work. Who can guide me?
- (void)viewDidLoad
{
[super viewDidLoad];
graph = [[CPTXYGraph alloc] initWithFrame:CGRectMake(10, 100, 300, 300)];
// graph.backgroundColor = [CPTColor clearColor].cgColor;
CPTTheme * theme = [CPTTheme themeNamed:kCPTPlainWhiteTheme];
[graph applyTheme:theme];
CPTGraphHostingView * hostingView = [[CPTGraphHostingView alloc] initWithFrame:CGRectMake(10, 100, 300, 300)];
hostingView.hostedGraph = graph;
[self.view addSubview:hostingView];
[hostingView release];
graph.fill = [CPTFill fillWithColor:[CPTColor clearColor]];
// Plot area
// graph.plotAreaFrame.fill = [CPTFill fillWithColor:[CPTColor clearColor]];
graph.plotAreaFrame.paddingTop = 10;
graph.plotAreaFrame.paddingBottom = 50;
graph.plotAreaFrame.paddingLeft = 20.0;
graph.plotAreaFrame.paddingRight = 20.0;
graph.plotAreaFrame.cornerRadius = 10.0;
graph.plotAreaFrame.masksToBorder = NO;
// graph.plotAreaFrame.axisSet.borderLineStyle = [CPTLineStyle lineStyle];
graph.plotAreaFrame.plotArea.fill = [CPTFill fillWithColor:[CPTColor clearColor]];
// Setup plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(1) length:CPTDecimalFromDouble(7)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(53.0) length:CPTDecimalFromDouble(4)];
// Line styles
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 3.0;
axisLineStyle.lineCap = kCGLineCapRound;
// Label x axis with a fixed interval policy
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
x.separateLayers = YES;//
x.orthogonalCoordinateDecimal = CPTDecimalFromDouble(53);
x.majorIntervalLength = CPTDecimalFromDouble(1);
x.minorTicksPerInterval = 1;
x.tickDirection = CPTSignNegative;
x.axisLineStyle = axisLineStyle;
x.majorTickLength = 2.0;
x.majorTickLineStyle = axisLineStyle;
// Label y with an automatic labeling policy.
axisLineStyle.lineColor = [CPTColor greenColor];
CPTXYAxis *y = axisSet.yAxis;
y.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
y.separateLayers = YES;//
y.minorTicksPerInterval = 0;
y.tickDirection = CPTSignNegative;
y.orthogonalCoordinateDecimal = CPTDecimalFromDouble(1.0);
y.axisLineStyle = axisLineStyle;
y.majorTickLength = 6.0;
y.majorTickLineStyle = axisLineStyle;
// Label y2 with an equal division labeling policy.
axisLineStyle.lineColor = [CPTColor orangeColor];
CPTXYPlotSpace * plotSpace2 = [[CPTXYPlotSpace alloc] init];
plotSpace2.xRange = plotSpace.xRange;
plotSpace2.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(1) length:CPTDecimalFromFloat(5)];
[graph addPlotSpace:plotSpace2];
CPTXYAxis *y2 = [[[CPTXYAxis alloc] init] autorelease];
y2.coordinate = CPTCoordinateY;
y2.plotSpace = plotSpace2;
y2.orthogonalCoordinateDecimal = CPTDecimalFromDouble(8.0);
y2.labelingPolicy = CPTAxisLabelingPolicyAutomatic;//
y2.separateLayers = NO;
y2.preferredNumberOfMajorTicks = 0;
y2.minorTicksPerInterval = 0;
y2.tickDirection = CPTSignPositive;
y2.axisLineStyle = axisLineStyle;
y2.majorTickLength = 6.0;
y2.majorTickLineStyle = axisLineStyle;
y2.minorTickLength = 4.0;
y2.titleOffset = 30.0;
//
CPTMutableLineStyle * lineStyle1 = [[CPTMutableLineStyle lineStyle] retain];
lineStyle1.lineWidth = 3.0f;
lineStyle1.lineColor = [CPTColor blueColor];
dataSourceLinePlot1 = [[CPTScatterPlot alloc] init];
dataSourceLinePlot1.identifier = #"1plot";
CPTPlotSymbol *plotSymbol1 = [CPTPlotSymbol ellipsePlotSymbol];
plotSymbol1.size = CGSizeMake(10, 10);
plotSymbol1.fill = [CPTFill fillWithColor:[CPTColor redColor]];
plotSymbol1.lineStyle = lineStyle1;
CPTMutableShadow *shadow1 = [CPTMutableShadow shadow];
shadow1.shadowColor = [CPTColor blueColor];
shadow1.shadowBlurRadius = 10.0;
dataSourceLinePlot1.shadow = shadow1;
dataSourceLinePlot1.plotSymbol = plotSymbol1;
dataSourceLinePlot1.dataLineStyle = lineStyle1;
dataSourceLinePlot1.dataSource = self;
[graph addPlot:dataSourceLinePlot1];
//-----------------------------------
CPTMutableLineStyle * lineStyle2 = [[CPTMutableLineStyle lineStyle] retain];
lineStyle2.lineWidth = 3.0f;
lineStyle2.lineColor = [CPTColor greenColor];
dataSourceLinePlot2 = [[CPTScatterPlot alloc] init];
dataSourceLinePlot2.identifier = #"2plot";
CPTPlotSymbol * plotSymbol2 = [CPTPlotSymbol ellipsePlotSymbol];
plotSymbol2.size = CGSizeMake(10, 10);
plotSymbol2.fill = [CPTFill fillWithColor:[CPTColor redColor]];
plotSymbol2.lineStyle = lineStyle2;
CPTMutableShadow *shadow2 = [CPTMutableShadow shadow];
shadow2.shadowColor = [CPTColor greenColor];
shadow2.shadowBlurRadius = 10.0;
dataSourceLinePlot2.shadow = shadow2;
dataSourceLinePlot2.plotSymbol = plotSymbol2;
dataSourceLinePlot2.dataLineStyle = lineStyle2;
dataSourceLinePlot2.dataSource = self;
[graph addPlot:dataSourceLinePlot2];
// Add the y2 axis to the axis set
graph.axisSet.axes = [NSArray arrayWithObjects:x, y, y2, nil];
dataArray1 = [[NSMutableArray alloc] init];
dataArray2 = [[NSMutableArray alloc] init];
for(int i=0; i< 7; i++){
float a = (float)(random()%40 + 530) / 10;
[dataArray1 addObject:[NSNumber numberWithFloat:a]];
}
for (int i = 0; i < 7; i++) {
// float a = (float)(random()%40 + 530) / 10;
[dataArray2 addObject:[NSNumber numberWithFloat:4]];
}
NSLog(#"array1 = %#,array2 = %#",dataArray1,dataArray2);
}
there is my delegate:
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
NSLog(#"%d",[dataArray1 count]);
if ([[plot identifier] isEqual:#"1plot"]) {
return [dataArray1 count];
}
return [dataArray2 count];
}
- (NSNumber *) numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
if(fieldEnum == CPTScatterPlotFieldY){
if ([[plot identifier] isEqual:#"1plot"]) {
return [dataArray1 objectAtIndex:index];
}else{
return [dataArray2 objectAtIndex:index];
}
}else{
return [NSNumber numberWithFloat:index];
}
}
You are setting the datasource delegate to self before the arrays have any data put into them. You need to either initialize the array earlier or call [graph reloadData];
I am using code from this link . And currently If I have 50 bar columns or 150 bar columns then the labels below is compressed and I would like to have horizontal scroll on x-Axis instead of having compressed x-Axis.
I have tried this:
plotSpace.xRange = CPTPlotRangeplotRangeWithLocation:CPTDecimalFromInt(-1)length:CPTDecimalFromInt(50)];
Attaching code from the file :
#import "GraphView.h"
#implementation GraphView
- (void)generateData
{
NSMutableDictionary *dataTemp = [[NSMutableDictionary alloc] init];
//Array containing all the dates that will be displayed on the X axis
dates = [NSArray arrayWithObjects:#"2012-05-01", #"2012-05-02", #"2012-05-03",
#"2012-05-04", #"2012-05-05", #"2012-05-06", #"2012-05-07", nil];
//Dictionary containing the name of the two sets and their associated color
//used for the demo
sets = [NSDictionary dictionaryWithObjectsAndKeys:[UIColor blueColor], #"Plot 1",
[UIColor redColor], #"Plot 2",
[UIColor greenColor], #"Plot 3", nil];
//Generate random data for each set of data that will be displayed for each day
//Numbers between 1 and 10
for (NSString *date in dates) {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSString *set in sets) {
NSNumber *num = [NSNumber numberWithInt:arc4random_uniform(10)+1];
[dict setObject:num forKey:set];
}
[dataTemp setObject:dict forKey:date];
}
data = [dataTemp copy];
[dataTemp release];
NSLog(#"%#", data);
}
- (void)generateLayout
{
//Create graph from theme
graph = [[CPTXYGraph alloc] initWithFrame:CGRectZero];
[graph applyTheme:[CPTTheme themeNamed:kCPTStocksTheme]];
self.hostedGraph = graph;
graph.plotAreaFrame.masksToBorder = NO;
graph.paddingLeft = 0.0f;
graph.paddingTop = 0.0f;
graph.paddingRight = 0.0f;
graph.paddingBottom = 0.0f;
CPTMutableLineStyle *borderLineStyle = [CPTMutableLineStyle lineStyle];
borderLineStyle.lineColor = [CPTColor whiteColor];
borderLineStyle.lineWidth = 2.0f;
graph.plotAreaFrame.borderLineStyle = borderLineStyle;
graph.plotAreaFrame.paddingTop = 10.0;
graph.plotAreaFrame.paddingRight = 10.0;
graph.plotAreaFrame.paddingBottom = 80.0;
graph.plotAreaFrame.paddingLeft = 70.0;
//Add plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.delegate = self;
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0)
length:CPTDecimalFromInt(10 * sets.count)];
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(-1)
length:CPTDecimalFromInt(8)];
//Grid line styles
CPTMutableLineStyle *majorGridLineStyle = [CPTMutableLineStyle lineStyle];
majorGridLineStyle.lineWidth = 0.75;
majorGridLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:0.1];
CPTMutableLineStyle *minorGridLineStyle = [CPTMutableLineStyle lineStyle];
minorGridLineStyle.lineWidth = 0.25;
minorGridLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:0.1];
//Axes
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
//X axis
CPTXYAxis *x = axisSet.xAxis;
x.orthogonalCoordinateDecimal = CPTDecimalFromInt(0);
x.majorIntervalLength = CPTDecimalFromInt(1);
x.minorTicksPerInterval = 0;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
x.majorGridLineStyle = majorGridLineStyle;
x.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0];
//X labels
int labelLocations = 0;
NSMutableArray *customXLabels = [NSMutableArray array];
for (NSString *day in dates) {
CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText:day textStyle:x.labelTextStyle];
newLabel.tickLocation = [[NSNumber numberWithInt:labelLocations] decimalValue];
newLabel.offset = x.labelOffset + x.majorTickLength;
newLabel.rotation = M_PI / 4;
[customXLabels addObject:newLabel];
labelLocations++;
[newLabel release];
}
x.axisLabels = [NSSet setWithArray:customXLabels];
//Y axis
CPTXYAxis *y = axisSet.yAxis;
y.title = #"Value";
y.titleOffset = 50.0f;
y.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
y.majorGridLineStyle = majorGridLineStyle;
y.minorGridLineStyle = minorGridLineStyle;
y.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0];
//Create a bar line style
CPTMutableLineStyle *barLineStyle = [[[CPTMutableLineStyle alloc] init] autorelease];
barLineStyle.lineWidth = 1.0;
barLineStyle.lineColor = [CPTColor whiteColor];
CPTMutableTextStyle *whiteTextStyle = [CPTMutableTextStyle textStyle];
whiteTextStyle.color = [CPTColor whiteColor];
//Plot
BOOL firstPlot = YES;
for (NSString *set in [[sets allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)]) {
CPTBarPlot *plot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor blueColor] horizontalBars:NO];
plot.lineStyle = barLineStyle;
CGColorRef color = ((UIColor *)[sets objectForKey:set]).CGColor;
plot.fill = [CPTFill fillWithColor:[CPTColor colorWithCGColor:color]];
if (firstPlot) {
plot.barBasesVary = NO;
firstPlot = NO;
} else {
plot.barBasesVary = YES;
}
plot.barWidth = CPTDecimalFromFloat(0.8f);
plot.barsAreHorizontal = NO;
plot.dataSource = self;
plot.identifier = set;
[graph addPlot:plot toPlotSpace:plotSpace];
}
//Add legend
CPTLegend *theLegend = [CPTLegend legendWithGraph:graph];
theLegend.numberOfRows = sets.count;
theLegend.fill = [CPTFill fillWithColor:[CPTColor colorWithGenericGray:0.15]];
theLegend.borderLineStyle = barLineStyle;
theLegend.cornerRadius = 10.0;
theLegend.swatchSize = CGSizeMake(15.0, 15.0);
whiteTextStyle.fontSize = 13.0;
theLegend.textStyle = whiteTextStyle;
theLegend.rowMargin = 5.0;
theLegend.paddingLeft = 10.0;
theLegend.paddingTop = 10.0;
theLegend.paddingRight = 10.0;
theLegend.paddingBottom = 10.0;
graph.legend = theLegend;
graph.legendAnchor = CPTRectAnchorTopLeft;
graph.legendDisplacement = CGPointMake(80.0, -10.0);
}
- (void)createGraph
{
//Generate data
[self generateData];
//Generate layout
[self generateLayout];
}
- (void)dealloc
{
[data release];
[super dealloc];
}
#pragma mark - CPTPlotDataSource methods
- (NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
return dates.count;
}
- (double)doubleForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
double num = NAN;
//X Value
if (fieldEnum == 0) {
num = index;
}
else {
double offset = 0;
if (((CPTBarPlot *)plot).barBasesVary) {
for (NSString *set in [[sets allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)]) {
if ([plot.identifier isEqual:set]) {
break;
}
offset += [[[data objectForKey:[dates objectAtIndex:index]] objectForKey:set] doubleValue];
}
}
//Y Value
if (fieldEnum == 1) {
num = [[[data objectForKey:[dates objectAtIndex:index]] objectForKey:plot.identifier] doubleValue] + offset;
}
//Offset for stacked bar
else {
num = offset;
}
}
//NSLog(#"%# - %d - %d - %f", plot.identifier, index, fieldEnum, num);
return num;
}
#pragma mark - CPTBarPlotDelegate methods
-(void)barPlot:(CPTBarPlot *)plot barWasSelectedAtRecordIndex:(NSUInteger)index {
NSLog(#"barWasSelectedAtRecordIndex %d", index);
}
#end
to get scrolling you need to set the globalXRange on the plotspace to be the entire range, and set the xRange will be the visible area.
for example a globalXRange of 0-150, and a xRange of 0-50. then you could scroll up to view the 51-150 range.