CorePlot ScatterPlot labelingPolicy
CorePlot ScatterPlot labelingPolicy
我正在使用 CorePlot 绘制几个月内的平均价格。
这就是我想要实现的目标
我已经能够制作这个
很明显图表绘制不正确。
这是我在 viewController 中用来设置图形并绘制它的代码。
- (void)viewDidLoad {
[super viewDidLoad];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
NSDictionary *jsonDataDictionary;
// Can be done async with loading timers
NSURL *url = [NSURL URLWithString:
@"http://greyloft.com/analytics/query.php?project=PARC%20VISTA&area=1200&months=5"];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if (urlData) {
NSError *error=nil;
jsonDataDictionary = [NSJSONSerialization JSONObjectWithData:urlData
options:kNilOptions
error:&error];
// We receive the order of the months in reverse order in the json i.e. most recent first.
// e.g. Feb-15, Jan-15, Dec-14 and so on
// We need to show plotting in reverse order on x axis effectively needing to reverse the array.
NSArray *reverseAvgRentals = [[jsonDataDictionary objectForKey:@"results"] objectForKey:@"average"];
_averageRentals = [[reverseAvgRentals reverseObjectEnumerator] allObjects];
_transactions = [[jsonDataDictionary objectForKey:@"results"] objectForKey:@"transactions"];
_months = [[NSMutableArray alloc] init];
_rentals = [[NSMutableArray alloc] init];
for (NSDictionary *rental in _averageRentals) {
[_months addObject:[rental objectForKey:@"month"]];
[_rentals addObject:[rental objectForKey:@"average"]];
}
// KVC to find min/max in an array
_minRental = _maxRental = 0;
_minRental = [[_rentals valueForKeyPath:@"@min.intValue"] intValue];
_maxRental = [[_rentals valueForKeyPath:@"@max.intValue"] intValue];
}}
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot {
return [_months count];
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
NSNumber *num = [[NSNumber alloc] init];
if (fieldEnum == CPTScatterPlotFieldX) {
// Simply return index as we want to return number for each month
num = [NSNumber numberWithInt:index+1];
} else {
num = [[_averageRentals objectAtIndex:index] valueForKey:@"average"];
}
return num;
}
-(void)initPlot {
[self configureHost];
[self configureGraph];
[self configurePlots];
[self configureAxes];
}
-(void)configureHost {
self.graphHostView = [(CPTGraphHostingView *) [CPTGraphHostingView alloc] initWithFrame:self.graphContainerView.bounds];
self.graphHostView.allowPinchScaling = YES;
[self.graphContainerView addSubview:self.graphHostView];
}
-(void)configureGraph {
// Create the graph
CPTGraph *graph = [[CPTXYGraph alloc] initWithFrame:self.graphHostView.bounds];
[graph applyTheme:nil];
self.graphHostView.hostedGraph = graph;
[graph.plotAreaFrame setPaddingLeft:30.0f];
[graph.plotAreaFrame setPaddingBottom:30.0f];
[graph.plotAreaFrame setPaddingTop:10.0f];
}
-(void)configurePlots {
// Get graph and plot space
CPTGraph *graph = self.graphHostView.hostedGraph;
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
// 2 - Create the plot
CPTScatterPlot *rentPlot = [[CPTScatterPlot alloc] init];
rentPlot.dataSource = self;
rentPlot.identifier = @"Rent";
[graph addPlot:rentPlot toPlotSpace:plotSpace];
// 3 - Set up plot space
CGFloat xMin = 0.0f;
CGFloat xMax = [_months count];
CGFloat yMin = _minRental;
CGFloat yMax = _maxRental;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(xMin)
length:CPTDecimalFromFloat(xMax)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(yMin)
length:CPTDecimalFromFloat(yMax)];
[plotSpace scaleToFitPlots:[graph allPlotSpaces]];
CPTMutablePlotRange *xRange = [plotSpace.xRange mutableCopy];
CPTMutablePlotRange *yRange = [plotSpace.yRange mutableCopy];
[xRange expandRangeByFactor:CPTDecimalFromDouble(1.4)];
[yRange expandRangeByFactor:CPTDecimalFromDouble(3.0)];
plotSpace.xRange = xRange;
plotSpace.yRange = yRange;
// 4 - Create styles and symbols
//CPTColor *orangeColor = [CPTColor colorWithComponentRed:239.0f green:92.0f blue:94.0f alpha:1.0f];
CPTColor *orangeColor = [CPTColor orangeColor];
CPTMutableLineStyle *lineStyle = [rentPlot.dataLineStyle mutableCopy];
lineStyle.lineWidth = 2.5f;
lineStyle.lineColor = orangeColor;
rentPlot.dataLineStyle = lineStyle;
CPTMutableLineStyle *symbolLineStyle = [CPTMutableLineStyle lineStyle];
symbolLineStyle.lineWidth = 2.5f;
symbolLineStyle.lineColor = orangeColor;
CPTPlotSymbol *symbol = [CPTPlotSymbol ellipsePlotSymbol];
symbol.fill = [CPTFill fillWithColor:[CPTColor colorWithComponentRed:248.0f
green:244.0f
blue:251.0f
alpha:1.0f]];
symbol.lineStyle = symbolLineStyle;
symbol.size = CGSizeMake(11.0f, 11.0f);
rentPlot.plotSymbol = symbol;
}
-(void)configureAxes {
// 1 - Create styles
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 0.0f;
CPTMutableTextStyle *axisTextStyle = [[CPTMutableTextStyle alloc] init];
axisTextStyle.color = [CPTColor grayColor];
axisTextStyle.fontName = @"Ubuntu-Bold";
axisTextStyle.fontSize = 14.0f;
CPTMutableLineStyle *majorGridLineStyle = [CPTMutableLineStyle lineStyle];
majorGridLineStyle.lineWidth = 0.75;
majorGridLineStyle.lineColor = [CPTColor lightGrayColor];
// 2 - Get axis set
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) self.graphHostView.hostedGraph.axisSet;
// 3 - Configure x-axis
CPTXYAxis *x = axisSet.xAxis;
x.axisLineStyle = axisLineStyle;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
x.majorIntervalLength = CPTDecimalFromDouble(1.0);
x.orthogonalCoordinateDecimal = CPTDecimalFromDouble(0.0);
x.preferredNumberOfMajorTicks = 6;
x.labelOffset = 50.0f;
x.labelTextStyle = axisTextStyle;
x.majorTickLineStyle = nil;
x.minorTickLineStyle = nil;
NSMutableSet *xLabelSet = [NSMutableSet setWithCapacity:[_months count]];
NSMutableSet *xLocationSet = [NSMutableSet setWithCapacity:[_months count]];
int location = 0;
for (NSString *month in _months) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:month textStyle:x.labelTextStyle];
label.tickLocation = CPTDecimalFromInt(location++);
[xLabelSet addObject:label];
[xLocationSet addObject:[NSNumber numberWithInteger:location]];
}
x.axisLabels = xLabelSet;
x.majorTickLocations = xLocationSet;
// 4 - Configure y-axis
CPTXYAxis *y = axisSet.yAxis;
y.axisLineStyle = axisLineStyle;
y.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
y.orthogonalCoordinateDecimal = CPTDecimalFromDouble(-0.1);
y.preferredNumberOfMajorTicks = 6;
y.majorGridLineStyle = majorGridLineStyle;
y.labelTextStyle = axisTextStyle;
y.majorTickLineStyle = nil;
y.minorTickLineStyle = nil;
}
我不明白 CorePlot 如何获取提供的数据并将其转换为所需的数据集。
有什么建议吗?
如我在上面的评论中所述,绘图范围采用 location
和 length
,如 NSRange
。您可以使用位置的最小值和长度的 max - min
。
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromCGFloat(yMin)
length:CPTDecimalFromCGFloat(yMax - yMin)];
对于涵盖 1,500 到 4,000 的范围示例,请使用 1,500 作为位置,使用 2,500(4,000 - 1,500)作为长度。
我正在使用 CorePlot 绘制几个月内的平均价格。
这就是我想要实现的目标
我已经能够制作这个
很明显图表绘制不正确。
这是我在 viewController 中用来设置图形并绘制它的代码。
- (void)viewDidLoad {
[super viewDidLoad];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
NSDictionary *jsonDataDictionary;
// Can be done async with loading timers
NSURL *url = [NSURL URLWithString:
@"http://greyloft.com/analytics/query.php?project=PARC%20VISTA&area=1200&months=5"];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if (urlData) {
NSError *error=nil;
jsonDataDictionary = [NSJSONSerialization JSONObjectWithData:urlData
options:kNilOptions
error:&error];
// We receive the order of the months in reverse order in the json i.e. most recent first.
// e.g. Feb-15, Jan-15, Dec-14 and so on
// We need to show plotting in reverse order on x axis effectively needing to reverse the array.
NSArray *reverseAvgRentals = [[jsonDataDictionary objectForKey:@"results"] objectForKey:@"average"];
_averageRentals = [[reverseAvgRentals reverseObjectEnumerator] allObjects];
_transactions = [[jsonDataDictionary objectForKey:@"results"] objectForKey:@"transactions"];
_months = [[NSMutableArray alloc] init];
_rentals = [[NSMutableArray alloc] init];
for (NSDictionary *rental in _averageRentals) {
[_months addObject:[rental objectForKey:@"month"]];
[_rentals addObject:[rental objectForKey:@"average"]];
}
// KVC to find min/max in an array
_minRental = _maxRental = 0;
_minRental = [[_rentals valueForKeyPath:@"@min.intValue"] intValue];
_maxRental = [[_rentals valueForKeyPath:@"@max.intValue"] intValue];
}}
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot {
return [_months count];
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
NSNumber *num = [[NSNumber alloc] init];
if (fieldEnum == CPTScatterPlotFieldX) {
// Simply return index as we want to return number for each month
num = [NSNumber numberWithInt:index+1];
} else {
num = [[_averageRentals objectAtIndex:index] valueForKey:@"average"];
}
return num;
}
-(void)initPlot {
[self configureHost];
[self configureGraph];
[self configurePlots];
[self configureAxes];
}
-(void)configureHost {
self.graphHostView = [(CPTGraphHostingView *) [CPTGraphHostingView alloc] initWithFrame:self.graphContainerView.bounds];
self.graphHostView.allowPinchScaling = YES;
[self.graphContainerView addSubview:self.graphHostView];
}
-(void)configureGraph {
// Create the graph
CPTGraph *graph = [[CPTXYGraph alloc] initWithFrame:self.graphHostView.bounds];
[graph applyTheme:nil];
self.graphHostView.hostedGraph = graph;
[graph.plotAreaFrame setPaddingLeft:30.0f];
[graph.plotAreaFrame setPaddingBottom:30.0f];
[graph.plotAreaFrame setPaddingTop:10.0f];
}
-(void)configurePlots {
// Get graph and plot space
CPTGraph *graph = self.graphHostView.hostedGraph;
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
// 2 - Create the plot
CPTScatterPlot *rentPlot = [[CPTScatterPlot alloc] init];
rentPlot.dataSource = self;
rentPlot.identifier = @"Rent";
[graph addPlot:rentPlot toPlotSpace:plotSpace];
// 3 - Set up plot space
CGFloat xMin = 0.0f;
CGFloat xMax = [_months count];
CGFloat yMin = _minRental;
CGFloat yMax = _maxRental;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(xMin)
length:CPTDecimalFromFloat(xMax)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(yMin)
length:CPTDecimalFromFloat(yMax)];
[plotSpace scaleToFitPlots:[graph allPlotSpaces]];
CPTMutablePlotRange *xRange = [plotSpace.xRange mutableCopy];
CPTMutablePlotRange *yRange = [plotSpace.yRange mutableCopy];
[xRange expandRangeByFactor:CPTDecimalFromDouble(1.4)];
[yRange expandRangeByFactor:CPTDecimalFromDouble(3.0)];
plotSpace.xRange = xRange;
plotSpace.yRange = yRange;
// 4 - Create styles and symbols
//CPTColor *orangeColor = [CPTColor colorWithComponentRed:239.0f green:92.0f blue:94.0f alpha:1.0f];
CPTColor *orangeColor = [CPTColor orangeColor];
CPTMutableLineStyle *lineStyle = [rentPlot.dataLineStyle mutableCopy];
lineStyle.lineWidth = 2.5f;
lineStyle.lineColor = orangeColor;
rentPlot.dataLineStyle = lineStyle;
CPTMutableLineStyle *symbolLineStyle = [CPTMutableLineStyle lineStyle];
symbolLineStyle.lineWidth = 2.5f;
symbolLineStyle.lineColor = orangeColor;
CPTPlotSymbol *symbol = [CPTPlotSymbol ellipsePlotSymbol];
symbol.fill = [CPTFill fillWithColor:[CPTColor colorWithComponentRed:248.0f
green:244.0f
blue:251.0f
alpha:1.0f]];
symbol.lineStyle = symbolLineStyle;
symbol.size = CGSizeMake(11.0f, 11.0f);
rentPlot.plotSymbol = symbol;
}
-(void)configureAxes {
// 1 - Create styles
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 0.0f;
CPTMutableTextStyle *axisTextStyle = [[CPTMutableTextStyle alloc] init];
axisTextStyle.color = [CPTColor grayColor];
axisTextStyle.fontName = @"Ubuntu-Bold";
axisTextStyle.fontSize = 14.0f;
CPTMutableLineStyle *majorGridLineStyle = [CPTMutableLineStyle lineStyle];
majorGridLineStyle.lineWidth = 0.75;
majorGridLineStyle.lineColor = [CPTColor lightGrayColor];
// 2 - Get axis set
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) self.graphHostView.hostedGraph.axisSet;
// 3 - Configure x-axis
CPTXYAxis *x = axisSet.xAxis;
x.axisLineStyle = axisLineStyle;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
x.majorIntervalLength = CPTDecimalFromDouble(1.0);
x.orthogonalCoordinateDecimal = CPTDecimalFromDouble(0.0);
x.preferredNumberOfMajorTicks = 6;
x.labelOffset = 50.0f;
x.labelTextStyle = axisTextStyle;
x.majorTickLineStyle = nil;
x.minorTickLineStyle = nil;
NSMutableSet *xLabelSet = [NSMutableSet setWithCapacity:[_months count]];
NSMutableSet *xLocationSet = [NSMutableSet setWithCapacity:[_months count]];
int location = 0;
for (NSString *month in _months) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:month textStyle:x.labelTextStyle];
label.tickLocation = CPTDecimalFromInt(location++);
[xLabelSet addObject:label];
[xLocationSet addObject:[NSNumber numberWithInteger:location]];
}
x.axisLabels = xLabelSet;
x.majorTickLocations = xLocationSet;
// 4 - Configure y-axis
CPTXYAxis *y = axisSet.yAxis;
y.axisLineStyle = axisLineStyle;
y.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
y.orthogonalCoordinateDecimal = CPTDecimalFromDouble(-0.1);
y.preferredNumberOfMajorTicks = 6;
y.majorGridLineStyle = majorGridLineStyle;
y.labelTextStyle = axisTextStyle;
y.majorTickLineStyle = nil;
y.minorTickLineStyle = nil;
}
我不明白 CorePlot 如何获取提供的数据并将其转换为所需的数据集。
有什么建议吗?
如我在上面的评论中所述,绘图范围采用 location
和 length
,如 NSRange
。您可以使用位置的最小值和长度的 max - min
。
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromCGFloat(yMin)
length:CPTDecimalFromCGFloat(yMax - yMin)];
对于涵盖 1,500 到 4,000 的范围示例,请使用 1,500 作为位置,使用 2,500(4,000 - 1,500)作为长度。