Core-Plot: вначале метки оси Y снаружи, но впоследствии внутри графика - PullRequest
2 голосов
/ 01 февраля 2012

Я использую Core-Plot 0.9, и у меня, казалось бы, странная проблема.У меня есть график XY с метками на оси Y.Когда график первоначально отображается, метки правильно расположены на отметках (фактически смещением 1,0) слева от самой оси, что является правильным.

Затем я выбираю новый набор данных для отображенияиспользуя UIPickerView, чтобы установить начальную точку оси X и восстановить график.На этой и на всех последующих регенерациях графика метки оси y отображаются внутри графика (справа от оси), а не на отметках (фактически сдвинутых вверх немного.

Я создаля думаю, что в левой части графика достаточно места для размещения меток оси Y. В частности, у меня есть следующий код:

graph.paddingLeft = 0.0;
graph.plotAreaFrame.paddingLeft = 25.0;

y.labelOffset = 1.0f;
y.labelAlignment = CPTAlignmentLeft;

Вот правильное представление оси Yнадписи при первоначальной загрузке.

http://www.msyapps.com/gifs/Correct.png

Вот неправильное представление надписей оси Y после прокрутки окна выбора средства выбора и восстановления графика.

http://www.msyapps.com/gifs/Incorrect.png

Ответы [ 2 ]

1 голос
/ 06 февраля 2012

У меня есть работоспособное решение, но оно нарушает обычно рекомендуемое действие для отображения оси Y.Примечания в приведенном ниже фрагменте кода указывают, где, по-моему, я отклонился от условных обозначений и где, по-моему, я добавил уникальное решение для фиксации оси Y на месте при последующем перерисовке графика.

#pragma mark - Choose returns to chart
- (IBAction)returnsToChart:(int)startPt andInteger:(int)endPt; { 
    contentArray1 = [[NSMutableArray alloc] initWithObjects:nil];
    dataContent = [[NSMutableArray alloc] initWithObjects:nil];
    int xPosition = 0;
    for (int i=startPt; i<endPt+1; ++i) {
        [dataContent addObject:[returnsAll objectAtIndex:i]];
        id x = [NSNumber numberWithFloat:xPosition];
        id y = [NSNumber numberWithFloat:[[returnsAll objectAtIndex:i] floatValue]];
        if ([[returnsAll objectAtIndex:i] isEqualToString:@""]) {
            [contentArray1 addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, @"x", @"", @"y", nil]];
        }
        else {
            [contentArray1 addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, @"x", y, @"y", nil]]; }
        xPosition = xPosition + 1;
    }

    dataForPlot = contentArray1;

    quarterlyReturnView.frame = CGRectMake(0.0f, 8.0f, 320.0f, 240.0f);    

    graph = [[CPTXYGraph alloc] initWithFrame:CGRectZero];    
    quarterlyReturnView.hostedGraph = graph;

    //paddingLeft leaves room for y-axis labels
    //paddingBottom must be set at zero otherwise and the space that must be added in order for the bottom-most label text to show will be handled by extending the length of the y-axis downward by a little bit
    graph.paddingLeft = 8.0;
    graph.paddingTop = 5.0;
    graph.paddingRight = 5.0;
    graph.paddingBottom = 0.0;

    //convention says that paddingLeft should be some number greater than zero
    //convention says that paddingBottom should be some number greater than zero, but if greater than zero, then each subsequent redrawing of plot results in a label shift upwards by the non-zero amount
    graph.plotAreaFrame.paddingLeft = 0.0;
    graph.plotAreaFrame.paddingTop = 5.0;
    graph.plotAreaFrame.paddingRight = 5.0;
    graph.plotAreaFrame.paddingBottom = 0.0;

    // Setup plot space
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;

    //this is where the magic happens...
    //I tweaked the percentage adjustments for the location as a function of the number of data points along the x-axis that had to be plotted
    //I settled on 8% plus and minus to provide room for the y-axis labels
    //this percentage is expressed as -0.08*(datacontent.count-1.0) and 1.08*(datacontent.count-1.0)
    //in other words, I put 8% on the left-hand side of the x-axis and made the whole x-axis 108% of the number of data points

    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(-0.08 * (dataContent.count-1.0)) length:CPTDecimalFromFloat(1.08 * (dataContent.count-1.0))];

    //Text styles
    CPTMutableTextStyle *axisTitleTextStyle = [CPTTextStyle textStyle];
    axisTitleTextStyle.fontName = @"Helvetica";
    axisTitleTextStyle.fontSize = 9.0;

    //Grid styles
    CPTMutableLineStyle *majorGridLineStyle = [CPTLineStyle lineStyle];
    majorGridLineStyle.lineWidth = 0.5f;

    //Axis styles
    CPTMutableLineStyle *axisLineStyle = [CPTLineStyle lineStyle];
    axisLineStyle.lineColor = [CPTColor blueColor];
    axisLineStyle.lineWidth = 1.0f;

    float maxNum = -100.0;
    float minNum = 100.0;
    float testMaxNum = 0.0;
    float testMinNum = 0.0;
    for (int i=0; i<[dataContent count]; ++i) {
        if ([[dataContent objectAtIndex:i] isEqualToString:@""]) { }
        else {
            testMaxNum = [[dataContent objectAtIndex:i] floatValue];
            if (maxNum < testMaxNum) { maxNum = testMaxNum; }
            testMinNum = [[dataContent objectAtIndex:i] floatValue];
            if (minNum > testMinNum) { minNum = testMinNum; } }
    }
    int maxInt = (maxNum + 1.0) / 1.0;
    float yMax = 1.0 * maxInt;
    int minInt = (minNum - 1.0) / 1.0;
    float yMin = 1.0 * minInt;

    //here is where the y-axis is stretched a bit to allow the labels to show unclipped
    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(yMin-0.2) length:CPTDecimalFromFloat(yMax-yMin+0.2)];

    // Axes (x is horizontal; y is vertical)
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
    CPTXYAxis *x = axisSet.xAxis;
    x.axisLineStyle = axisLineStyle;
    x.labelOffset = 1.0f;
    x.labelTextStyle = nil;
    x.majorTickLength = 5.0f;
    x.majorIntervalLength = CPTDecimalFromString(@"16");
    x.orthogonalCoordinateDecimal = CPTDecimalFromString(@"0");
    x.minorTicksPerInterval = 0;
    x.minorTickLength = 0.0f;
    x.tickDirection =CPTSignNone;
    x.visibleRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0) length:CPTDecimalFromFloat(dataContent.count-1.0)];

    CPTXYAxis *y = axisSet.yAxis;
    y.axisLineStyle = axisLineStyle;
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    [formatter setMaximumFractionDigits:0];
    y.labelFormatter = formatter;
    y.labelOffset = 2.0f;
    y.labelAlignment = CPTAlignmentLeft;
    y.labelTextStyle = axisTitleTextStyle;
    y.tickDirection = CPTSignNegative;    
    y.majorTickLength = 3.0f;    
    y.majorIntervalLength = CPTDecimalFromString(@"2");
    y.majorGridLineStyle = majorGridLineStyle;
    //y.gridLinesRange is needed because the x-axis has been stretched 8% as described above
    y.gridLinesRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0) length:CPTDecimalFromInt(dataContent.count-1)];
    y.minorTicksPerInterval = 1;
    y.minorTickLength = 2.0f;
    y.orthogonalCoordinateDecimal = CPTDecimalFromString(@"0");

    // Create plot area
    CPTScatterPlot *boundLinePlot = [[CPTScatterPlot alloc] init];
    CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle];
    lineStyle.miterLimit = 1.0f;
    lineStyle.lineWidth = 2.0f;
    lineStyle.lineColor = [CPTColor blueColor];
    boundLinePlot.dataLineStyle = lineStyle;
    boundLinePlot.dataSource = self;
    [graph addPlot:boundLinePlot];
    [boundLinePlot reloadData];
}
1 голос
/ 02 февраля 2012

Вы меняете свойство tickDirection?Вот что контролирует, на какой стороне находятся метки.

...