简体   繁体   English

核心图散点图y轴无法缩放以适合屏幕和图

[英]Core Plot ScatterPlot y-axis not scaling to fit screen and plot

I have been working on a set of graphs for my app and have a very specific problem with the ScatterPlot. 我一直在为我的应用程序处理一组图形,并且ScatterPlot有一个非常特定的问题。 I cannot get the y-axis or hight of the graph to re-scale to fit on screen. 我无法使图形的y轴或高轴重新缩放以适合屏幕大小。 I spent hours searching the web for an answer and the closest I've come is by following the raywenderlich.com tutorial. 我花了几个小时在网上搜索答案,而最近的是遵循raywenderlich.com教程。 But I still cannot seem to get my y-axis to compress so that the graph fits on screen. 但是我似乎仍然无法压缩我的y轴,以使图形适合屏幕显示。

Ideally I want the graph to resize dynamically based on the input data because the difference in the data plotted can vary from tens to hundreds. 理想情况下,我希望图形根据输入数据动态调整大小,因为绘制的数据差异可能在数十到数百之间变化。

Here is the code that I use to set up the graph: 这是我用来设置图形的代码:

-(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];
}

And here is where I create my arrays to test the graph: 这是我创建数组以测试图形的地方:

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];

The raywenderlich project compiles and runs perfectly with the desired y-axis perfectly scaled to fit on screen but mine does not but I cannot figure out what I'm missing. raywenderlich项目可以以理想的y轴进行编译和完美运行,并且可以完美缩放以适合屏幕大小,但是我的y轴没有,但是我无法弄清缺少的内容。 Any suggestions as to where I am going wrong will be massively appreciated. 任何关于我要去哪里的建议都将受到高度赞赏。 EDIT: Added Plot Config in response to comment... 编辑:响应评论添加了Plot Config ...

-(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;
}

Check your plot identifiers. 检查您的地块标识符。 You set the identifiers to one value when setting up the plots and compare them to some other value in the datasource. 设置图时,可以将标识符设置为一个值,并将其与数据源中的其他某个值进行比较。 That test is probably failing, which means every y-value for each plot is zero (0). 该测试可能会失败,这意味着每个图的每个y值均为零(0)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM