核心图:y 轴标签最初位于外部,但随后位于图内部

发布于 2025-01-02 07:33:09 字数 956 浏览 2 评论 0原文

我正在使用 Core-Plot 0.9,并且遇到了一个看似奇怪的问题。我有一个 XY 图,y 轴上有标签。最初显示绘图时,标签正确定位在轴本身左侧的刻度线(实际上偏移 1.0)上,这是正确的。

然后,我使用 UIPickerView 选择要显示的一组新数据,以设置 x 轴起点并重新生成绘图。在该绘图以及所有后续的绘图中,y 轴标签显示在绘图内部(轴的右侧),而不是在刻度线上(实际上向上移动了一点)。

我已经创建了我认为足够的空间 如下:

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

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

这是初始加载时 y 轴标签的正确表示。

在图的左侧包含 y 轴标签,我的代码 .sstatic.net/ykMG2.png" rel="nofollow noreferrer">
(来源:msyapps.com

这是不正确的滚动左侧选取器视图并重新生成绘图后 y 轴标签的表示。


(来源:msyapps.com

I'm using Core-Plot 0.9 and have a seemingly peculiar problem. I have an X-Y plot with labels on the y-axis. When the plot is initially displayed, the labels are correctly positioned on the tick marks (actually offset 1.0) to the left of the axis itself, which is correct.

Then, I select a new set of data to display using a UIPickerView to set the x-axis starting point and regenerate the plot. On this and all subsequent regenerations of the plot, the y-axis labels show up inside the plot (to the right of the axis) and not on the tick marks (actually shifted upwards a bit.

I have created what I think is enough room on the left hand side of the plot to contain the y-axis labels. In particular, I have code as follows:

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

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

Here is the correct representation of the y-axis labels on initial loading.


(source: msyapps.com)

Here is the incorrect representation of the y-axis labels after scrolling the picker view on the left and regenerating the plot.


(source: msyapps.com)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

極樂鬼 2025-01-09 07:33:09

您是否正在更改 tickDirection 属性?这就是控制标签位于哪一侧的原因。

Are you changing the tickDirection property? That's what controls which side the labels are on.

孤城病女 2025-01-09 07:33:09

我有一个可行的解决方案,但它违反了显示 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];
}

I have a workable solution, but it violates the commonly recommended action for displaying the y-axis. The annotations in the code snippet below indicates where I think I deviated from conventions and where I think I have added a unique solution for fixing the y-axis in place on subsequent redrawing of plot.

#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];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文