我一直在使用CorePlot绘制饼图,之前工作正常。我现在想要在已经存在的饼图下方的散点图中可视化数据。为此,我添加了一个InterfaceBuilder的新视图,与已经托管我的饼图的视图相同。我已将数据源和委托设置为self,并正确调用相应的委托方法。看似唯一不起作用的是在托管视图中实际显示图形。
这就是它的样子。上:工作饼图;底部:应该是我的散点图:
散点图中唯一可见的是小矩形。
以下是相应的代码:
- (id)init
{
// ...
sp1 = [[MyPlotClass alloc] initWithTheme:[CPTTheme themeNamed:kCPTPlainWhiteTheme]];
// the following returns an NSArray. Everything working as expected here.
pieChartData = [self getEMDTurnoverSums];
[pieChartData retain];
sp2 = [[MyPlotClass alloc] initWithTheme:[CPTTheme themeNamed:kCPTPlainWhiteTheme]];
// dito getEMDTurnoverSums
scatterPlotData = [self getEMDTurnoverData];
[scatterPlotData retain];
return self;
}
- (void)viewDidLoad
{
/*
* ------------------------
* Pie Chart
* ------------------------
*/
graph1 = [sp1 getPieChartGraphForView:graphView1];
CPTPieChart *pieChart = [sp1 initPieChartWithIdentifier:@"emd" andLineWidth:1.0f];
pieChart.dataSource = self;
pieChart.delegate = self;
CPTLegend *legend = [CPTLegend legendWithGraph:graph1];
legend.numberOfColumns = 1;
legend.numberOfRows = 3;
legend.cornerRadius = 5.0;
CPTMutableTextStyle *textStyle = [[[CPTMutableTextStyle alloc] init] autorelease];
textStyle.fontSize = 15.0;
legend.textStyle = textStyle;
graph1.legend = legend;
graph1.legendAnchor = CPTRectAnchorLeft;
graph1.legendDisplacement = CGPointMake(30.0, 30.0);
if (self.interfaceOrientation == UIDeviceOrientationLandscapeLeft ||
self.interfaceOrientation == UIDeviceOrientationLandscapeRight)
{
graphView1.frame = CGRectMake(5.0f, 500.0f, 750.0f, 510.0f);
}
[graph1 addPlot:pieChart];
[pieChart release];
/*
* ------------------------
* Scatter Plot
* ------------------------
*/
graph2 = [sp2 getScatterPlotGraphForView:graphView2];
CPTScatterPlot *scatterPlot = [sp2 initScatterPlotWithIdentifier:@"scatterPlot" andLineWidth:5.0f andColor:[CPTColor blackColor]];
scatterPlot.dataSource = self;
scatterPlot.delegate = self;
CPTLegend *scatterPlotLegend = [CPTLegend legendWithGraph:graph2];
scatterPlotLegend.numberOfColumns = 2;
scatterPlotLegend.numberOfRows = 3;
scatterPlotLegend.cornerRadius = 5.0;
// see PieChart
scatterPlotLegend.textStyle = textStyle;
graph2.legend = scatterPlotLegend;
graph2.legendAnchor = CPTRectAnchorLeft;
graph2.legendDisplacement = CGPointMake(30.0, 30.0);
if (self.interfaceOrientation == UIDeviceOrientationLandscapeLeft ||
self.interfaceOrientation == UIDeviceOrientationLandscapeRight)
{
graphView2.frame = CGRectMake(5.0f, 240.0f, 750.0f, 270.0f);
}
[graph2 addPlot:scatterPlot];
[scatterPlot release];
/*
* ------------------------
* END PLOTS
* ------------------------
*/
[super viewDidLoad];
}
委托方法:
- (NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
if ([(NSString *)plot.identifier isEqualToString:@"emd"]) {
NSLog(@"numberOfRecordsForPlot: emd: %i", [pieChartData count]);
return [pieChartData count];
} else if ([(NSString *)plot.identifier isEqualToString:@"scatterPlot"]) {
NSLog(@"numberOfRecordsForPlot: scatterPlot: %i", [scatterPlotData count]);
NSLog(@"numberOfRecordsForPlot: scatterPlot: %@", scatterPlotData);
return [scatterPlotData count];
}
return 0;
}
- (NSNumber *)numberForPlot:(CPTPlot *)plot
field:(NSUInteger)fieldEnum
recordIndex:(NSUInteger)index
{
if ([(NSString *)plot.identifier isEqualToString:@"emd"]) {
return [pieChartData objectAtIndex:index];
} else if ([(NSString *)plot.identifier isEqualToString:@"scatterPlot"]) {
NSDictionary *fieldMapping = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:
@"e_turnover",
@"m_turnover",
@"d_turnover",
@"na_turnover",
@"sum_turnover",
nil]
forKeys:[NSArray arrayWithObjects:
@"0",
@"1",
@"2",
@"3",
@"4",
nil]];
NSLog(@"scatterPlotData: %@", scatterPlotData);
NSLog(@"fieldMapping : %@", fieldMapping);
NSNumber *returnValue = [(NSDictionary *)[scatterPlotData objectAtIndex:index] objectForKey:
[fieldMapping objectForKey:
[NSString stringWithFormat:@"%i", fieldEnum]]];
NSLog(@"returnValue: %@", returnValue);
return returnValue;
}
return 0;
}
- (NSString *)legendTitleForPieChart:(CPTPieChart *)pieChart
recordIndex:(NSUInteger)index
{
switch (index) {
case 0:
return [NSString stringWithFormat:@"Easy Lines - %@ €", [self standardFormatNumber:(NSNumber *)[pieChartData objectAtIndex:0] asDecimal:NO]];
case 1:
return [NSString stringWithFormat:@"Medium Lines - %@ €", [self standardFormatNumber:(NSNumber *)[pieChartData objectAtIndex:1] asDecimal:NO]];
case 2:
return [NSString stringWithFormat:@"Difficult Lines - %@ €", [self standardFormatNumber:(NSNumber *)[pieChartData objectAtIndex:2] asDecimal:NO]];
default:
break;
}
return @"";
}
- (CPTFill *)sliceFillForPieChart:(CPTPieChart *)pieChart
recordIndex:(NSUInteger)index
{
switch (index) {
case 0:
return [CPTFill fillWithColor:[CPTColor greenColor]];
case 1:
return [CPTFill fillWithColor:[CPTColor yellowColor]];
case 2:
return [CPTFill fillWithColor:[CPTColor redColor]];
default:
break;
}
return [CPTFill fillWithColor:[CPTColor blackColor]];
}
以下是MyPlotClass.m中的代码:
#import "MyPlotClass.h"
@implementation MyPlotClass
@synthesize paddingLeft;
@synthesize paddingTop;
@synthesize paddingRight;
@synthesize paddingBottom;
@synthesize plotRangeXFrom;
@synthesize plotRangeXLength;
@synthesize plotRangeYFrom;
@synthesize plotRangeYLength;
@synthesize plotSpace;
@synthesize axisLineWidth;
@synthesize axisLineColor;
@synthesize minorTickLengthX;
@synthesize majorTickLengthX;
@synthesize minorTickLengthY;
@synthesize majorTickLengthY;
@synthesize majorIntervalLengthX;
@synthesize majorIntervalLengthY;
@synthesize labelOffsetX;
@synthesize labelOffsetY;
@synthesize minorTicksPerIntervalX;
@synthesize minorTicksPerIntervalY;
@synthesize pieChartRadius;
@synthesize pieChartStartAngle;
@synthesize pieChartSliceDirection;
- (id)init
{
return [self initWithTheme:[CPTTheme themeNamed:kCPTPlainWhiteTheme]];
}
- (MyPlotClass *)initWithTheme:(CPTTheme *)theme
{
graph = [[[CPTXYGraph alloc] initWithFrame:CGRectZero] retain];
[graph applyTheme:theme];
paddingLeft = 20.0;
paddingTop = 20.0;
paddingRight = 20.0;
paddingBottom = 20.0;
plotRangeXFrom = 0.0;
plotRangeXLength = 0.0;
plotRangeYFrom = 0.0;
plotRangeYLength = 0.0;
axisLineWidth = 0.0f;
axisLineColor = [CPTColor blackColor];
minorTickLengthX = 0.0f;
majorTickLengthX = 0.0f;
minorTickLengthY = 0.0f;
majorTickLengthY = 0.0f;
majorIntervalLengthX = 5.0f;
majorIntervalLengthY = 5.0f;
labelOffsetX = 3.0f;
labelOffsetY = 3.0f;
minorTicksPerIntervalX = 0;
minorTicksPerIntervalY = 0;
pieChartRadius = 100.0;
pieChartStartAngle = M_PI;
pieChartSliceDirection = CPTPieDirectionClockwise;
return self;
}
- (CPTXYGraph *)getScatterPlotGraphForView:(UIView *)view
{
CPTGraphHostingView *hostingView = (CPTGraphHostingView *)view;
hostingView.hostedGraph = graph;
graph.paddingLeft = paddingLeft;
graph.paddingTop = paddingTop;
graph.paddingRight = paddingRight;
graph.paddingBottom = paddingBottom;
plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(plotRangeXFrom)
length:CPTDecimalFromFloat(plotRangeXLength)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(plotRangeYFrom)
length:CPTDecimalFromFloat(plotRangeYLength)];
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineColor = axisLineColor;
axisLineStyle.lineWidth = axisLineWidth;
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
axisSet.xAxis.majorIntervalLength = [[NSNumber numberWithFloat:majorIntervalLengthX] decimalValue];
axisSet.xAxis.minorTicksPerInterval = minorTicksPerIntervalX;
axisSet.xAxis.majorTickLineStyle = axisLineStyle;
axisSet.xAxis.minorTickLineStyle = axisLineStyle;
axisSet.xAxis.axisLineStyle = axisLineStyle;
axisSet.xAxis.minorTickLength = minorTickLengthX;
axisSet.xAxis.majorTickLength = majorTickLengthX;
axisSet.xAxis.labelOffset = labelOffsetX;
axisSet.yAxis.majorIntervalLength = [[NSNumber numberWithInt:majorIntervalLengthY] decimalValue];
axisSet.yAxis.minorTicksPerInterval = minorTicksPerIntervalY;
axisSet.yAxis.majorTickLineStyle = axisLineStyle;
axisSet.yAxis.minorTickLineStyle = axisLineStyle;
axisSet.yAxis.axisLineStyle = axisLineStyle;
axisSet.yAxis.minorTickLength = minorTickLengthY;
axisSet.yAxis.majorTickLength = majorTickLengthY;
axisSet.yAxis.labelOffset = labelOffsetY;
return graph;
}
- (CPTXYGraph *)getPieChartGraphForView:(UIView *)view
{
CPTGraphHostingView *hostingView = (CPTGraphHostingView *)view;
hostingView.hostedGraph = graph;
graph.paddingLeft = paddingLeft;
graph.paddingTop = paddingTop;
graph.paddingRight = paddingRight;
graph.paddingBottom = paddingBottom;
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineColor = axisLineColor;
axisLineStyle.lineWidth = axisLineWidth;
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
axisSet.xAxis.majorIntervalLength = [[NSNumber numberWithFloat:majorIntervalLengthX] decimalValue];
axisSet.xAxis.minorTicksPerInterval = minorTicksPerIntervalX;
axisSet.xAxis.majorTickLineStyle = axisLineStyle;
axisSet.xAxis.minorTickLineStyle = axisLineStyle;
axisSet.xAxis.axisLineStyle = axisLineStyle;
axisSet.xAxis.minorTickLength = minorTickLengthX;
axisSet.xAxis.majorTickLength = majorTickLengthX;
axisSet.xAxis.labelOffset = labelOffsetX;
axisSet.yAxis.majorIntervalLength = [[NSNumber numberWithInt:majorIntervalLengthY] decimalValue];
axisSet.yAxis.minorTicksPerInterval = minorTicksPerIntervalY;
axisSet.yAxis.majorTickLineStyle = axisLineStyle;
axisSet.yAxis.minorTickLineStyle = axisLineStyle;
axisSet.yAxis.axisLineStyle = axisLineStyle;
axisSet.yAxis.minorTickLength = minorTickLengthY;
axisSet.yAxis.majorTickLength = majorTickLengthY;
axisSet.yAxis.labelOffset = labelOffsetY;
return graph;
}
- (CPTScatterPlot *)initScatterPlotWithIdentifier:(NSString *)identifier
{
return [self initScatterPlotWithIdentifier:identifier andLineWidth:3.0f andColor:[CPTColor blackColor]];
}
- (CPTScatterPlot *)initScatterPlotWithIdentifier:(NSString *)identifier
andLineWidth:(CGFloat)lineWidth
andColor:(CPTColor *)lineColor
{
CPTScatterPlot *scatterPlot = [[[CPTScatterPlot alloc]
initWithFrame:graph.defaultPlotSpace.accessibilityFrame]
autorelease];
scatterPlot.identifier = identifier;
CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle];
lineStyle.lineWidth = lineWidth;
lineStyle.lineColor = lineColor;
scatterPlot.dataLineStyle = lineStyle;
[graph addPlot:scatterPlot];
CPTPlotSymbol *greenCirclePlotSymbol = [CPTPlotSymbol ellipsePlotSymbol];
greenCirclePlotSymbol.fill = [CPTFill fillWithColor:[CPTColor greenColor]];
greenCirclePlotSymbol.size = CGSizeMake(2.0, 2.0);
scatterPlot.plotSymbol = greenCirclePlotSymbol;
return scatterPlot;
}
- (CPTPieChart *)initPieChartWithIdentifier:(NSString *)identifier
andLineWidth:(CGFloat)lineWidth
{
CPTPieChart *pieChart = [[[CPTPieChart alloc]
initWithFrame:graph.defaultPlotSpace.accessibilityFrame]
autorelease];
pieChart.identifier = identifier;
pieChart.pieRadius = pieChartRadius;
pieChart.startAngle = pieChartStartAngle;
pieChart.sliceDirection = pieChartSliceDirection;
// Prepare a radial overlay gradient for shading/gloss
CPTGradient *overlayGradient = [[[CPTGradient alloc] init] autorelease];
overlayGradient.gradientType = CPTGradientTypeRadial;
overlayGradient = [overlayGradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.0] atPosition:0.0];
overlayGradient = [overlayGradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.3] atPosition:0.9];
overlayGradient = [overlayGradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.7] atPosition:1.0];
pieChart.overlayFill = [CPTFill fillWithGradient:overlayGradient];
CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle];
lineStyle.lineWidth = lineWidth;
pieChart.borderLineStyle = lineStyle;
[graph addPlot:pieChart];
return pieChart;
}
- (void)dealloc
{
[super dealloc];
[graph release];
[plotSpace release];
}
@end
我花了好几个小时才解决这个问题。数据很好,委托方法被调用并返回正确的值。
TIA!
答案 0 :(得分:1)
一些观察结果:
在-initScatterPlotWithIdentifier:andLineWidth:andColor:
中,散点图会添加到graph
。不应该是graph2
?
在-numberForPlot:field:recordIndex:
中,您必须检查字段参数 - switch语句运行良好。对于每个索引,此方法将被调用两次,一次使用field
== CPTScatterPlotFieldX
,一次使用field
== CPTScatterPlotFieldY
。你为这两个字段返回相同的值,所以即使你可以看到情节,它也会是一条对角线。
axisLineWidth = 0.0f;
您需要为散点图增加此值,以便显示轴线。
答案 1 :(得分:0)
@Eric Skroch:
感谢您的评论!
不,-initScatterPlotWithIdentifier:andLineWidth:andColor:
是MyPlotClass
中的一种方法。成员graph
与实现类中的变量无关。
我实际上是在return语句中执行此操作。然而,我认为我为了优雅而牺牲了可读性。以下代码现在更加明显:
NSDictionary * curDict =(NSDictionary *)[scatterPlotData objectAtIndex:index];
switch(fieldEnum){
case 0:
return [curDict objectForKey:@"e_turnover"];
case 1:
return [curDict objectForKey:@"m_turnover"];
case 2:
return [curDict objectForKey:@"d_turnover"];
case 3:
return [curDict objectForKey:@"na_turnover"];
case 4:
return [curDict objectForKey:@"sum_turnover"];
default:
break;
}
BTW:很抱歉,我将此评论放在单独的答案中,但评论字段不允许我输入多行代码块或超过一定数量字符的评论。