I'm trying to layout my barchart nicely. I'd like to have no more than 10 horizontal bars all anchored to the top with a set bar width and bar spacing.
#define kBarHeight 20
#define kBarSpacing 8
myPlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt([self.data count]*(kBarHeight+kBarSpacing)) length:CPTDecimalFromInt([self.data count]*(kBarHeight+kBarSpacing) * -1)];
The negatives is because I'm trying also to get this effect
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
NSNumber *num = @0;
switch (fieldEnum) {
case CPTBarPlotFieldBarTip:
if ([plot.identifier isEqual:@"dataset1"]) {
num = [NSNumber numberWithInteger:[self.dataSet1[index] count]];
} else {
num = [NSNumber numberWithInteger:[self.dataSet2[index] count]];
}
break;
default:
num = [NSNumber numberWithInteger:(index*(kBarHeight + kBarSpacing)) + kBarHeight/2 ];
break;
}
return num;
}
I thought the above would work, but all the bars are on top of eachother near the bottom of the chart, and cut off half way but they're still evenly spaced and not listening to the bar spacing value I'm setting. . Thoughts?
Edit: Full graph set up:
#pragma mark -
#pragma mark - Chart behavior
-(void)initPlot {
[self configureGraph];
[self configurePlots];
[self configureAxes];
}
-(void)configureGraph {
CPTGraph *dataSet2Graph = [[CPTXYGraph alloc] initWithFrame:self.dataSet2Graph.bounds];
CPTGraph *dataSet1Graph = [[CPTXYGraph alloc] initWithFrame:self.dataSet1Graph.bounds];
dataSet2Graph.plotAreaFrame.masksToBorder = NO;
dataSet1Graph.plotAreaFrame.masksToBorder = NO;
dataSet2Graph.paddingLeft = 150.0;
dataSet1Graph.paddingLeft = 150.0;
self.dataSet2Graph.hostedGraph = dataSet2Graph;
self.dataSet1Graph.hostedGraph = dataSet1Graph;
CPTXYPlotSpace *dataSet2PlotSpace = (CPTXYPlotSpace *) dataSet2Graph.defaultPlotSpace;
CSGeoStat *stat = (CSGeoStat *) self.dataSet2Data[0]; //Biggest dataSet2 count
dataSet2PlotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0) length:CPTDecimalFromFloat(stat.count * 1.1)];
dataSet2PlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt([self.dataSet2Data count]) length:CPTDecimalFromInt(-1 * [self.dataSet2Data count])];
CPTXYPlotSpace *dataSet1PlotSpace = (CPTXYPlotSpace *) dataSet1Graph.defaultPlotSpace;
stat = (CSGeoStat *) self.dataSet1Data[0]; //Biggest tz count
dataSet1PlotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0) length:CPTDecimalFromFloat(stat.count * 1.1)];
dataSet1PlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt([self.dataSet1Data count]*(kBarHeight+kBarSpacing)) length:CPTDecimalFromInt([self.dataSet1Data count]*(kBarHeight+kBarSpacing) * -1)];
[self.dataSet2Graph setFrame:CGRectMake(self.dataSet2Graph.frame.origin.x,
self.dataSet2Graph.frame.origin.y,
self.dataSet2Graph.frame.size.width,
(int)([self.dataSet2Data count]*(kBarHeight+kBarSpacing)*1.2))];
[self.dataSet1Graph setFrame:CGRectMake(self.dataSet1Graph.frame.origin.x,
self.dataSet1Graph.frame.origin.y,
self.dataSet1Graph.frame.size.width,
(int)([self.dataSet1Data count]*(kBarHeight+kBarSpacing)*1.2))];
}
-(void)configurePlots {
CPTBarPlot *dataSet2Plot = [[CPTBarPlot alloc] init];
dataSet2Plot.barsAreHorizontal = YES;
dataSet2Plot.barCornerRadius = CPTFloat(1.0);
dataSet2Plot.identifier = @"CountryPlot";
dataSet2Plot.fill = [CPTFill fillWithColor:[CPTColor colorWithComponentRed:19/255 green:221/255 blue:187/255 alpha:1]];
CPTBarPlot *dataSet1Plot = [[CPTBarPlot alloc] init];
dataSet1Plot.barsAreHorizontal = YES;
dataSet1Plot.barCornerRadius = CPTFloat(1.0);
dataSet1Plot.identifier = @"TimeZonePlot";
dataSet1Plot.fill = [CPTFill fillWithColor:[CPTColor colorWithComponentRed:19/255 green:221/255 blue:188/255 alpha:1]];
CPTMutableLineStyle *barLineStyle = [[CPTMutableLineStyle alloc] init];
barLineStyle.lineColor = [CPTColor clearColor];
barLineStyle.lineWidth = 0.5;
CPTGraph *dataSet2Graph = self.dataSet2Graph.hostedGraph;
CPTGraph *dataSet1Graph = self.dataSet1Graph.hostedGraph;
dataSet2Plot.dataSource = self;
dataSet2Plot.delegate = self;
dataSet2Plot.barWidth = CPTDecimalFromDouble(kBarHeight);
dataSet2Plot.barWidthsAreInViewCoordinates = YES;
dataSet2Plot.baseValue = CPTDecimalFromString(@"0");
dataSet2Plot.lineStyle = barLineStyle;
dataSet2Plot.barOffset = CPTDecimalFromFloat(0.25f);
dataSet2Plot.labelOffset = -5.0;
[dataSet2Graph addPlot:dataSet2Plot toPlotSpace:dataSet2Graph.defaultPlotSpace];
dataSet1Plot.dataSource = self;
dataSet1Plot.delegate = self;
dataSet1Plot.baseValue = CPTDecimalFromString(@"0");
dataSet1Plot.barWidth = CPTDecimalFromDouble(kBarHeight);
dataSet1Plot.barWidthsAreInViewCoordinates = YES;
dataSet1Plot.lineStyle = barLineStyle;
dataSet1Plot.labelOffset = -5.0;
dataSet1Plot.barOffset = CPTDecimalFromFloat(0.25f);
[dataSet1Graph addPlot:dataSet1Plot toPlotSpace:dataSet1Graph.defaultPlotSpace];
}
-(void)configureAxes {
CPTXYAxisSet *dataSet2AxisSet = (CPTXYAxisSet *) self.dataSet2Graph.hostedGraph.axisSet;
CPTXYAxis *x = dataSet2AxisSet.xAxis;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
x.axisLineStyle = nil;
CPTXYAxis *y = dataSet2AxisSet.yAxis;
y.labelingPolicy = CPTAxisLabelingPolicyNone;
y.axisLineStyle = nil;
NSMutableArray *customLabels = [[NSMutableArray alloc]init];
[self.dataSet2Data enumerateObjectsUsingBlock:^(CSGeoStat *stat, NSUInteger idx, BOOL *stop) {
NSString *labelText = stat.term;
CPTMutableTextStyle *textStyle = [y.labelTextStyle mutableCopy];
textStyle.color = [CPTColor whiteColor];
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:labelText textStyle:textStyle];
label.tickLocation = CPTDecimalFromInt((idx*(kBarHeight + kBarSpacing)) + kBarHeight/2);
label.offset = y.labelOffset + y.majorTickLength;
label.rotation = M_PI * 2;
[customLabels addObject:label];
}];
y.axisLabels = [NSSet setWithArray:customLabels];
CPTXYAxisSet *dataSet1AxisSet = (CPTXYAxisSet *) self.dataSet1Graph.hostedGraph.axisSet;
CPTXYAxis *x2 = dataSet1AxisSet.xAxis;
x2.labelingPolicy = CPTAxisLabelingPolicyNone;
x2.axisLineStyle = nil;
CPTXYAxis *y2 = dataSet1AxisSet.yAxis;
y2.labelingPolicy = CPTAxisLabelingPolicyNone;
y2.axisLineStyle = nil;
NSMutableArray *customLabels2 = [[NSMutableArray alloc]init];
[self.dataSet1Data enumerateObjectsUsingBlock:^(CSGeoStat *stat, NSUInteger idx, BOOL *stop) {
NSString *labelText = stat.term;
CPTMutableTextStyle *textStyle = [y2.labelTextStyle mutableCopy];
textStyle.color = [CPTColor whiteColor];
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:labelText textStyle:textStyle];
label.tickLocation = CPTDecimalFromInt((idx*(kBarHeight + kBarSpacing)) + kBarHeight/2);
label.offset = y2.labelOffset + y2.majorTickLength;
label.rotation = M_PI * 2;
[customLabels2 addObject:label];
}];
y2.axisLabels = [NSSet setWithArray:customLabels2];
}
yRangeof the two plot spaces are different. Is that intentional? - Eric Skroch