2

アプリの一連のグラフに取り組んでおり、ScatterPlot に非常に具体的な問題があります。画面に収まるようにグラフの y 軸または高さを再スケーリングすることができません。私は何時間もかけて答えを求めて Web を検索しましたが、最も近いのは raywenderlich.com のチュートリアルに従うことでした。しかし、グラフが画面に収まるようにy軸を圧縮することはまだできないようです。

理想的には、プロットされたデータの違いは数十から数百に及ぶ可能性があるため、入力データに基づいてグラフのサイズを動的に変更する必要があります。

グラフを設定するために使用するコードは次のとおりです。

-(void)configureAxes{
     // 1 - Create styles
    CPTMutableTextStyle *axisTitleStyle = [CPTMutableTextStyle textStyle];
    axisTitleStyle.color = [CPTColor whiteColor];
    axisTitleStyle.fontName = @"Helvetica-Bold";
    axisTitleStyle.fontSize = 12.0f;
    CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
    axisLineStyle.lineWidth = 2.0f;
    axisLineStyle.lineColor = [CPTColor whiteColor];
    CPTMutableTextStyle *axisTextStyle = [[CPTMutableTextStyle alloc] init];
    axisTextStyle.color = [CPTColor whiteColor];
    axisTextStyle.fontName = @"Helvetica-Bold";
    axisTextStyle.fontSize = 11.0f;
    CPTMutableLineStyle *tickLineStyle = [CPTMutableLineStyle lineStyle];
    tickLineStyle.lineColor = [CPTColor whiteColor];
    tickLineStyle.lineWidth = 2.0f;
    CPTMutableLineStyle *gridLineStyle = [CPTMutableLineStyle lineStyle];
    tickLineStyle.lineColor = [CPTColor blackColor];
    tickLineStyle.lineWidth = 1.0f;
    // 2 - Get axis set
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *) self.hostView.hostedGraph.axisSet;
    // 3 - Configure x-axis
    CPTAxis *x = axisSet.xAxis;
    x.title = @"Date";
    x.titleTextStyle = axisTitleStyle;
    x.titleOffset = 15.0f;
    x.axisLineStyle = axisLineStyle;
    x.labelingPolicy = CPTAxisLabelingPolicyNone;
    x.labelTextStyle = axisTextStyle;
    x.majorTickLineStyle = axisLineStyle;
    x.majorTickLength = 4.0f;
    x.tickDirection = CPTSignNegative;

    //This next line gets the number of records in the array for the date axes
    CGFloat dateCount = [timesTest count];
    NSMutableSet *xLabels = [NSMutableSet setWithCapacity:dateCount];
    NSMutableSet *xLocations = [NSMutableSet setWithCapacity:dateCount];

    //Now we build an array of dates to label the axes
    NSInteger i = 0;
    //for (NSString *date in [[CPDStockPriceStore sharedInstance] datesInMonth]) {
    for (NSString *date in datesTest) {
        CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:date  textStyle:x.labelTextStyle];
        CGFloat location = i++;
        label.tickLocation = CPTDecimalFromCGFloat(location);
        label.offset = x.majorTickLength;
        if (label) {
            [xLabels addObject:label];
            [xLocations addObject:[NSNumber numberWithFloat:location]];
        }
    }
    x.axisLabels = xLabels;
    x.majorTickLocations = xLocations;

    // 4 - Configure y-axis
    CPTAxis *y = axisSet.yAxis;
    y.title = @"Time";
    y.titleTextStyle = axisTitleStyle;
    y.titleOffset = -40.0f;
    y.axisLineStyle = axisLineStyle;
    y.majorGridLineStyle = gridLineStyle;
    y.labelingPolicy = CPTAxisLabelingPolicyNone;
    y.labelTextStyle = axisTextStyle;
    y.labelOffset = 16.0f;
    y.majorTickLineStyle = axisLineStyle;
    y.majorTickLength = 4.0f;
    y.minorTickLength = 2.0f;
    y.tickDirection = CPTSignPositive;
    NSInteger majorIncrement = 100;
    NSInteger minorIncrement = 50;
    CGFloat yMax = 700.0f;  // should determine dynamically based on max time
    NSMutableSet *yLabels = [NSMutableSet set];
    NSMutableSet *yMajorLocations = [NSMutableSet set];
    NSMutableSet *yMinorLocations = [NSMutableSet set];
    for (NSInteger j = minorIncrement; j <= yMax; j += minorIncrement) {
        NSUInteger mod = j % majorIncrement;
        if (mod == 0) {
            CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[NSString stringWithFormat:@"%i", j] textStyle:y.labelTextStyle];
            NSDecimal location = CPTDecimalFromInteger(j);
            label.tickLocation = location;
            label.offset = -y.majorTickLength - y.labelOffset;
            if (label) {
                [yLabels addObject:label];
            }
            [yMajorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:location]];
        } else {
            [yMinorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:CPTDecimalFromInteger(j)]];
        }
    }
    y.axisLabels = yLabels;
    y.majorTickLocations = yMajorLocations;
    y.minorTickLocations = yMinorLocations;

}


#pragma mark - CPTPlotDataSource methods
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot {
    return [timesTest count];
}

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
    //NSInteger valueCount = [[[CPDStockPriceStore sharedInstance] datesInMonth] count];
    NSInteger valueCount = [timesTest count];
    switch (fieldEnum) {
        case CPTScatterPlotFieldX:
            if (index < valueCount) {
                return [NSNumber numberWithUnsignedInteger:index];
            }
            break;

        case CPTScatterPlotFieldY:
            if ([plot.identifier isEqual:pbTest] == YES) {
                return [pbTest objectAtIndex:index];
            } else if ([plot.identifier isEqual:rollAvgTest] == YES) {
                return [rollAvgTest objectAtIndex:index];
            } else if ([plot.identifier isEqual:timesTest] == YES) {
                return [timesTest objectAtIndex:index];
            }
            break;
    }
    return [NSDecimalNumber zero];
}

そして、グラフをテストするために配列を作成する場所は次のとおりです。

datesTest = [NSArray arrayWithObjects:@"4/27",
                                            @"4/28",
                                            @"4/29",
                                            nil];

        timesTest = [NSArray arrayWithObjects:
                     [NSDecimalNumber numberWithFloat:601.1],
                     [NSDecimalNumber numberWithFloat:614.4],
                     [NSDecimalNumber numberWithFloat:607.3],
                     nil];

        pbTest = [NSArray arrayWithObjects:
                     [NSDecimalNumber numberWithFloat:601.1],
                     [NSDecimalNumber numberWithFloat:601.1],
                     [NSDecimalNumber numberWithFloat:601.1],
                     nil];

        rollAvgTest = [NSArray arrayWithObjects:
                     [NSDecimalNumber numberWithFloat:602.1],
                     [NSDecimalNumber numberWithFloat:613.4],
                     [NSDecimalNumber numberWithFloat:605.3],
                     nil];

raywenderlich プロジェクトは、目的の y 軸が画面に収まるように完全にスケーリングされてコンパイルおよび実行されますが、私のものはそうではありませんが、何が欠けているのかわかりません。私がどこで間違っているかについての提案は大歓迎です。編集:コメントに応じてプロット構成を追加しました...

-(void)configurePlots{
    // 1 - Get graph and plot space
    CPTGraph *graph = self.hostView.hostedGraph;
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
    // 2 - Create the three plots
    // FIRST PLOT is Personal Best - pbPlot
    // SECOND PLOT is Rolling Average - rollAvgPlot
    // THIRD PLOT is Individual swims - swimssPlot

    //Plot 1 - Peronal Best
    CPTScatterPlot *pbPlot = [[CPTScatterPlot alloc] init];
    pbPlot.dataSource = self;
    NSString *pbID = [[NSString alloc] initWithFormat:@"pbID"];
    pbPlot.identifier = pbID;
    CPTColor *pbColor = [CPTColor redColor];
    [graph addPlot:pbPlot toPlotSpace:plotSpace];

    //Plot 2 - Rolling Average
    CPTScatterPlot *rollAvgPlot = [[CPTScatterPlot alloc] init];
    rollAvgPlot.dataSource = self;
    NSString *rollAvgID = [[NSString alloc] initWithFormat:@"rollAvgID"];
    rollAvgPlot.identifier = rollAvgID;
    CPTColor *rollAvgColor = [CPTColor greenColor];
    [graph addPlot:rollAvgPlot toPlotSpace:plotSpace];

    //Plot 3 - Actual Swim Times
    CPTScatterPlot *swimsPlot = [[CPTScatterPlot alloc] init];
    swimsPlot.dataSource = self;
    NSString *timesID = [[NSString alloc] initWithFormat:@"timesID"];
    swimsPlot.identifier = timesID;
    CPTColor *swimsColor = [CPTColor blueColor];
    [graph addPlot:swimsPlot toPlotSpace:plotSpace];

    // 3 - Set up plot space
    //[plotSpace scaleToFitPlots:[NSArray arrayWithObjects:pbPlot, rollAvgPlot, swimsPlot, nil]];
    [plotSpace scaleToFitPlots:[NSArray arrayWithObjects:swimsPlot, nil]];
    CPTMutablePlotRange *xRange = [plotSpace.xRange mutableCopy];
    [xRange expandRangeByFactor:CPTDecimalFromCGFloat(1.1f)];
    plotSpace.xRange = xRange;
    CPTMutablePlotRange *yRange = [plotSpace.yRange mutableCopy];
    [yRange expandRangeByFactor:CPTDecimalFromCGFloat(1.2f)];
    plotSpace.yRange = yRange;

    // 4 - Create styles and symbols
    CPTMutableLineStyle *pbLineStyle = [pbPlot.dataLineStyle mutableCopy];
    pbLineStyle.lineWidth = 2.5;
    pbLineStyle.lineColor = pbColor;
    pbPlot.dataLineStyle = pbLineStyle;
    CPTMutableLineStyle *pbSymbolLineStyle = [CPTMutableLineStyle lineStyle];
    pbSymbolLineStyle.lineColor = pbColor;
    CPTPlotSymbol *pbSymbol = [CPTPlotSymbol ellipsePlotSymbol];
    pbSymbol.fill = [CPTFill fillWithColor:pbColor];
    pbSymbol.lineStyle = pbSymbolLineStyle;
    pbSymbol.size = CGSizeMake(6.0f, 6.0f);
    pbPlot.plotSymbol = pbSymbol;

    CPTMutableLineStyle *rollAvgLineStyle = [rollAvgPlot.dataLineStyle mutableCopy];
    rollAvgLineStyle.lineWidth = 1.0;
    rollAvgLineStyle.lineColor = rollAvgColor;
    rollAvgPlot.dataLineStyle = rollAvgLineStyle;
    CPTMutableLineStyle *rollAvgSymbolLineStyle = [CPTMutableLineStyle lineStyle];
    rollAvgSymbolLineStyle.lineColor = rollAvgColor;
    CPTPlotSymbol *rollAvgSymbol = [CPTPlotSymbol starPlotSymbol];
    rollAvgSymbol.fill = [CPTFill fillWithColor:rollAvgColor];
    rollAvgSymbol.lineStyle = rollAvgSymbolLineStyle;
    rollAvgSymbol.size = CGSizeMake(6.0f, 6.0f);
    rollAvgPlot.plotSymbol = rollAvgSymbol;

    CPTMutableLineStyle *swimsLineStyle = [swimsPlot.dataLineStyle mutableCopy];
    swimsLineStyle.lineWidth = 2.0;
    swimsLineStyle.lineColor = swimsColor;
    swimsPlot.dataLineStyle = swimsLineStyle;
    CPTMutableLineStyle *swimsSymbolLineStyle = [CPTMutableLineStyle lineStyle];
    swimsSymbolLineStyle.lineColor = swimsColor;
    CPTPlotSymbol *swimsSymbol = [CPTPlotSymbol diamondPlotSymbol];
    swimsSymbol.fill = [CPTFill fillWithColor:swimsColor];
    swimsSymbol.lineStyle = swimsSymbolLineStyle;
    swimsSymbol.size = CGSizeMake(6.0f, 6.0f);
    swimsPlot.plotSymbol = swimsSymbol;
}
4

1 に答える 1

1

プロット識別子を確認してください。プロットを設定するときに識別子を 1 つの値に設定し、それらをデータソース内の他の値と比較します。そのテストはおそらく失敗しています。つまり、各プロットのすべての y 値はゼロ (0) です。

于 2012-11-01T00:34:53.387 に答える