我尝试使用条形图上的ScatterPlot显示一条线,该线是水平的。它适用于垂直条形图,但不适用于水平条形图。
这是源代码:
-(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);
}
底部的图例确实显示应该有一条目标线,但不会显示任何人
答案 0 :(得分:0)
不同的绘图类型使用不同的数据源字段枚举。条形图将使用CPTBarPlotFieldBarLocation
和CPTBarPlotFieldBarTip
。像目标线图一样的散点图将使用CPTScatterPlotFieldX
和CPTScatterPlotFieldY
。确保数据源正在检查每个图的右侧字段枚举值。