iPhone CorePlot饼图获取切片坐标

时间:2012-01-30 13:42:11

标签: iphone core-plot

我正在使用CorePlot来绘制PieChart。我想在切片上显示切片标签。有没有办法获取每个切片的坐标,然后设置保持文本标签的CPTLayer框架以调整切片的坐标?

到目前为止我在做什么:

-(CPRLayer*) datLabelForPlot(CPTPlot*)plot recordIndex:(NSUInteger)index {
  static CPTMutableTextStyle *textStyle = nil;
  NSString *string = @"Test";

    if ( !textStyle) {
        textStyle= [[CPTMutableTextStyle alloc] init];
        textStyle.color = [CPTColor whiteColor];
    }
    CPTLayer *layer = [[[CPTLayer alloc] initWithFrame:CGRectMake(50,50, 100, 20)]autorelease];
    CPTTextLayer *newLayer = nil;
    newLayer = [[[CPTTextLayer alloc] initWithText:string style:textStyle] autorelease];
    [layer addSublayer:newLayer];
    return layer;
}

但无论图层框架如何,标签始终显示在同一位置(图表外)。如何设置适当的图层框以在切片上显示文本?

以下是我想知道的观点的图像: piechart

2 个答案:

答案 0 :(得分:3)

您是否尝试将CPPieChart labelOffset属性设置为负值?可能它不能提供您所需的精确度,但它是一个简单的解决方案。

正偏移:

Positive Offset

负偏移:

enter image description here

答案 1 :(得分:0)

centerAnchor表示为绘图区域大小的一部分,因此您可以使用以下代码计算其像素位置(图片上的“O”点):

CPTPieChart *pieChart; // the pie chart
CGRect plotAreaBounds = pieChart.plotArea.bounds;
CGPoint anchor = pieChart.centerAnchor;
CGPoint centerPoint = CGPointMake(plotAreaBounds.origin.x + plotAreaBounds.size.width * anchor.x,
                                  plotAreaBounds.origin.y + plotAreaBounds.size.height * anchor.y);

您可以查看Core Plot source code,了解饼图如何计算标签的位置。此代码考虑了“爆炸”的切片,并将标签置于您称为“A”和“B”的点之间,由labelOffset偏移。如果数据源为切片返回缺失值(NAN),它会隐藏标签。 index对应于饼图切片的数据源索引。相关位是:

double currentWidth = [self cachedDoubleForField:CPTPieChartFieldSliceWidthNormalized recordIndex:index];
if ( isnan(currentWidth) ) {
    contentLayer.hidden = YES;
}
else {
    id<CPTPieChartDataSource> theDataSource = id<CPTPieChartDataSource>)self.dataSource;
    BOOL dataSourceProvidesRadialOffsets = [theDataSource respondsToSelector:@selector(radialOffsetForPieChart:recordIndex:)];
    CGFloat radialOffset = 0.0;
    if ( dataSourceProvidesRadialOffsets ) {
        radialOffset = [theDataSource radialOffsetForPieChart:self recordIndex:index];
    }

    CGFloat labelRadius = self.pieRadius + self.labelOffset + radialOffset;

    double startingWidth = 0.0;
    if ( index > 0 ) {
        startingWidth = [self cachedDoubleForField:CPTPieChartFieldSliceWidthSum recordIndex:index - 1];
    }
    CGFloat labelAngle = [self radiansForPieSliceValue:startingWidth + currentWidth / (CGFloat)2.0];

    label.displacement = CGPointMake( labelRadius * cos(labelAngle), labelRadius * sin(labelAngle) );
    contentLayer.hidden = NO;
}