Cocoa Touch CorePlot散点图未显示

时间:2012-01-09 10:00:11

标签: objective-c ios xcode cocoa-touch core-plot

我一直在使用CorePlot绘制饼图,之前工作正常。我现在想要在已经存在的饼图下方的散点图中可视化数据。为此,我添加了一个InterfaceBuilder的新视图,与已经托管我的饼图的视图相同。我已将数据源和委托设置为self,并正确调用相应的委托方法。看似唯一不起作用的是在托管视图中实际显示图形。

这就是它的样子。上:工作饼图;底部:应该是我的散点图:

Top: the working pie chart; bottom: what should be my scatter plot.

散点图中唯一可见的是小矩形。

以下是相应的代码:

- (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!

2 个答案:

答案 0 :(得分:1)

一些观察结果:

  1. -initScatterPlotWithIdentifier:andLineWidth:andColor:中,散点图会添加到graph。不应该是graph2

  2. -numberForPlot:field:recordIndex:中,您必须检查字段参数 - switch语句运行良好。对于每个索引,此方法将被调用两次,一次使用field == CPTScatterPlotFieldX,一次使用field == CPTScatterPlotFieldY。你为这两个字段返回相同的值,所以即使你可以看到情节,它也会是一条对角线。

  3. axisLineWidth = 0.0f;您需要为散点图增加此值,以便显示轴线。

答案 1 :(得分:0)

@Eric Skroch:

感谢您的评论!

  1. 不,-initScatterPlotWithIdentifier:andLineWidth:andColor:MyPlotClass中的一种方法。成员graph与实现类中的变量无关。

  2. 我实际上是在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;
    

    }

  3. BTW:很抱歉,我将此评论放在单独的答案中,但评论字段不允许我输入多行代码块或超过一定数量字符的评论。