0

GraphViewController と AppController の 2 つのクラスがあります。AppController (デリゲート) は、GraphViewController のデータソース プロトコルを実装します。私が抱えている問題は、これらのメソッドが GraphViewController によって呼び出されないことです。

ただし、GraphViewController のデータソースを self に設定し、プロトコル メソッドを GraphViewController に残すと (CorePlot で提供される CorePlot の例のように)、reloadData または setNeedsDisplay メソッドを呼び出さなくてもすべて正常に動作します。

問題はビューの設定ではありません。テーマと軸はうまく描かれていますが、プロットが欠けているだけです。

非常によく似た質問に対して提供された回答のどれも、私の特定の問題を解決しませんでした。私が見逃しているのはほんの小さなことだと思います(または願っています)が、それを見つけることができません。

以下の 2 つのクラスのソースを参照してください。ああ、ちなみに、これは iOS ではなく OS-X 用です。

GraphViewController.h:

#import <Cocoa/Cocoa.h>
#import <CorePlot/CorePlot.h>

@interface GraphViewController : NSObject{

    IBOutlet CPTGraphHostingView *graphHostingViewOutlet;
    CPTXYGraph *graph;
}

@property (weak) id<CPTPlotDataSource> delegate;

@end

GraphViewController.m:

#import "GraphViewController.h"

@implementation GraphViewController

@synthesize delegate;

-(void)awakeFromNib {

    [super awakeFromNib];

    // create graph
    graph = [(CPTXYGraph *)[CPTXYGraph alloc] initWithFrame:CGRectZero];

    // apply theme to graph
    [graph applyTheme:[CPTTheme themeNamed:kCPTPlainWhiteTheme]];

    // connect graph to host view
    graphHostingViewOutlet.hostedGraph = graph;

    // get a pointer to the default plot space of the graph
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;

    // setup axes limits
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(-0.2f) length:CPTDecimalFromFloat(1.2f)];
    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(-0.2f) length:CPTDecimalFromFloat(1.2f)];

    // get a pointer to the axis set of the graph
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;

    // get the x axis element of the axis set and set propertys for x axis
    CPTXYAxis *x = axisSet.xAxis;
    x.majorIntervalLength = CPTDecimalFromFloat(0.2f);

    // get the y axis element of the axis set and set propertys for y axis
    CPTXYAxis *y = axisSet.yAxis;
    y.majorIntervalLength = CPTDecimalFromFloat(0.2f);

    // create a new plot
    CPTScatterPlot *dataSourceLinePlot = [[CPTScatterPlot alloc] init];

    // set the identifier for the plot
    dataSourceLinePlot.identifier = @"ThePlot";

    // set data source for plot
    dataSourceLinePlot.dataSource = delegate;

    // add the plot to the graph
    [graph addPlot:dataSourceLinePlot];

}

@end

AppController.h:

#import <Foundation/Foundation.h>
#import "GraphViewController.h"
#import <CorePlot/CorePlot.h>

@interface AppController : NSObject <CPTPlotDataSource>

@property (weak) GraphViewController *graphViewController;

- (IBAction)doSomething:(id)sender; // connected to a button

@end

AppController.m:

#import "AppController.h"

@implementation AppController{

    NSArray *_plotData;

}

@synthesize graphViewController = _graphViewController;

-(void)awakeFromNib {

    [super awakeFromNib];

    [_graphViewController setDelegate:self];

    // create data array
    NSMutableArray *newData = [NSMutableArray array];

    for (NSUInteger i = 0; i < 20; i++ ) {

        // create random y values
        id y = [NSDecimalNumber numberWithFloat: rand() / (float)RAND_MAX];

        [newData addObject: [NSDictionary dictionaryWithObjectsAndKeys:

                             [NSDecimalNumber  numberWithFloat:0.05 * i],      // x object
                             [NSNumber numberWithInt:CPTScatterPlotFieldX],    // key
                             y,                                                // y object
                             [NSNumber numberWithInt:CPTScatterPlotFieldY],    // key
                             nil]];
    } // end of for

    _plotData = newData;
}

- (IBAction)doSomething:(id)sender{ // connected to a working button

    NSLog(@"Button was pressed.");

    // tell the graphViewController to reload its data from its delegate (me), but how?

    // this does not work: [[NSNotificationCenter defaultCenter] postNotificationName:@"CPTGraphNeedsRedrawNotification" object:nil];

}

// implementation of delegate methods

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
    NSDecimalNumber *num = [[_plotData objectAtIndex:index] objectForKey:[NSNumber numberWithLongLong:fieldEnum]];
    NSLog(@"numberForPlot was called, num is %@",num);
    return num;
}

-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
    NSLog(@"numberForPlot was called.");
    return _plotData.count;
}

@end

バグが見つかったら、私が投稿したソースが他の人にとって簡単なプロトタイプとして役立つことを願っています.

4

2 に答える 2

1

プロットを構成するときにdelegateが設定されていることを確認してください。-[GraphViewController awakeFromNib]このクラスがアプリ コントローラーの前に初期化される場合、まだ設定されません。delegate修正は、新しい値をプロット データソースにも設定するプロパティのカスタム セッターを追加することです。

于 2012-08-01T23:40:46.703 に答える
0

ここで私自身の質問に答えるつもりはありません (私はまだ問題の解決策を持っていません) が、同じことをしようとしている人々へのヒントがあります:

別のクラスからバインディングを使用してデータをプロットするクラスにデータをフィードする別の方法があります。(コア データ) エンティティ (つまり、dataToPlot) を NSArrayController にバインドし、プロット クラスでタイプ NSArrayController の IBOutlet を定義し、IB を使用して ArrayController (plotData にバインドされている) をその IBOutlet に接続できます。これは私にとってはうまくいき、エラーが発生しにくく、よりエレガントなアプローチのようです。

これを設定するために必要な手順は、この coreplot-group スレッドで詳しく説明されています。

于 2012-08-01T15:31:00.940 に答える