带有重复图例的核心图条形图

时间:2012-12-10 22:13:26

标签: ios core-plot bar-chart

我正在使用核心图框架来创建带有图例的条形图。这一切都有效,除了图例复制了条形图每个部分中的列(请参阅随附的屏幕截图)。

enter image description here

我查看了核心情节类引用,但无法找到解决此问题的任何内容。我试图将CPTLegend属性numberOfColumns设置为1,将numberOfRows设置为3,并使图例在图例中显示适当数量的项目,但显示的数据不正确。

enter image description here enter image description here

下面是我用来构建条形图的代码。你们对我如何解决这个问题有什么建议吗?我假设这不是一个核心情节的错误,而是传说的限制,我希望有一个解决方法。

// Create barChart from theme
barChart = [[CPTXYGraph alloc] initWithFrame:CGRectZero];
CPTTheme *theme = [CPTTheme themeNamed:kCPTDarkGradientTheme];
[barChart applyTheme:theme];
chartView.hostedGraph = barChart;
barChart.plotAreaFrame.masksToBorder = NO;

barChart.paddingLeft = 60.0;
barChart.paddingTop = 10.0;
barChart.paddingRight = 0.0;
barChart.paddingBottom = 30.0;

//find max y
int maxY = 0;
NSMutableArray *maxDrillDownData = [chartData.drillDownData objectForKey:DRILLDOWN_EQUIPMENT_ALL_TYPE];
for (NSMutableArray *dataArray in maxDrillDownData) {
    maxY = dataArray.count>maxY?dataArray.count:maxY;
}

//add buffer
maxY = maxY+100;

// Add plot space for horizontal bar charts
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)barChart.defaultPlotSpace;
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromInt(maxY)];
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat(3.25)];

CPTXYAxisSet *axisSet = (CPTXYAxisSet *)barChart.axisSet;
CPTXYAxis *x = axisSet.xAxis;
x.axisLineStyle = nil;
x.majorTickLineStyle = nil;
x.minorTickLineStyle = nil;
x.majorIntervalLength = CPTDecimalFromString(@"1");
x.orthogonalCoordinateDecimal = CPTDecimalFromString(@"0");
x.titleLocation = CPTDecimalFromFloat(7.5f);
x.titleOffset = 55.0f;
x.labelOffset = 2.0;

// Define some custom labels for the data elements
x.labelRotation = M_PI/4;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
NSArray *customTickLocations = [NSArray arrayWithObjects:[NSDecimalNumber numberWithFloat:0.5], [NSDecimalNumber numberWithFloat:1.5], [NSDecimalNumber numberWithFloat:2.5], nil];
NSArray *xAxisLabels = (NSMutableArray *)[chartData.labels objectForKey:LABELS_EQUIPMENT_TYPE];
NSUInteger labelLocation = 0;
NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:[xAxisLabels count]];
for (NSNumber *tickLocation in customTickLocations) {
    CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText: [xAxisLabels objectAtIndex:labelLocation++] textStyle:x.labelTextStyle];
    newLabel.tickLocation = [tickLocation decimalValue];
    newLabel.offset = x.labelOffset;
    [customLabels addObject:newLabel];
    //[newLabel release];
}

x.axisLabels =  [NSSet setWithArray:customLabels];

CPTXYAxis *y = axisSet.yAxis;
y.axisLineStyle = nil;
y.majorTickLineStyle = nil;
y.minorTickLineStyle = nil;
y.majorIntervalLength = CPTDecimalFromString(@"50");
y.orthogonalCoordinateDecimal = CPTDecimalFromString(@"0");
y.title = (NSString *)[chartData.labels objectForKey:LABELS_Y_AXIS];
y.titleOffset = 45.0f;
y.titleLocation = CPTDecimalFromFloat(150.0f);

//identifiers
NSMutableArray *identifiers = (NSMutableArray *)[chartData.identifiers objectForKey:IDENTIFIER_EQUIPMENT_TYPE];

// First bar plot
CPTBarPlot *barPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor darkGrayColor] horizontalBars:NO];
barPlot.baseValue = CPTDecimalFromString(@"0");
barPlot.dataSource = self;
barPlot.barOffset = CPTDecimalFromFloat(-0.6f);
barPlot.barWidth = CPTDecimalFromFloat(.5);
barPlot.delegate = self;
barPlot.identifier = (NSString *)[identifiers objectAtIndex:0];
[barChart addPlot:barPlot toPlotSpace:plotSpace];

NSLog(@"barPlot.identifier: %@", barPlot.identifier);

// Second bar plot
barPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor blueColor] horizontalBars:NO];
barPlot.dataSource = self;
barPlot.barOffset = CPTDecimalFromFloat(-0.4f);
barPlot.barWidth = CPTDecimalFromFloat(.5);
barPlot.baseValue = CPTDecimalFromString(@"0");
barPlot.identifier = (NSString *)[identifiers objectAtIndex:1];
barPlot.delegate = self;
[barChart addPlot:barPlot toPlotSpace:plotSpace];

NSLog(@"barPlot.identifier: %@", barPlot.identifier);

//third bar plot
barPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor redColor] horizontalBars:NO];
barPlot.dataSource = self;
barPlot.barOffset = CPTDecimalFromFloat(-0.2f);
barPlot.barWidth = CPTDecimalFromFloat(.5);
barPlot.baseValue = CPTDecimalFromString(@"0");
barPlot.identifier = (NSString *)[identifiers objectAtIndex:2];
barPlot.delegate = self;
[barChart addPlot:barPlot toPlotSpace:plotSpace];

NSLog(@"barPlot.identifier: %@", barPlot.identifier);

// Add legend
CPTLegend *theLegend = [CPTLegend legendWithGraph:barChart];
theLegend.numberOfColumns = 3;
theLegend.numberOfRows = 1;
theLegend.fill = [CPTFill fillWithColor:[CPTColor whiteColor]];
theLegend.borderLineStyle = [CPTLineStyle lineStyle];
theLegend.cornerRadius = 5.0;

barChart.legend = theLegend;
barChart.legendAnchor = CPTRectAnchorTopRight;
barChart.legendDisplacement = CGPointMake(-10.0f, -20.0f);

感谢您的帮助!

2 个答案:

答案 0 :(得分:5)

确保您的绘图数据源中未实现以下任何方法:

-legendTitleForBarPlot:recordIndex:
-barFillForBarPlot:recordIndex:

如果存在这些方法中的任何一种,则图表会为每个条形创建图例条目,而不是为整个图形使用单个图例条目。

答案 1 :(得分:3)

我知道这是一个非常古老的问题,但所提供的答案对我没有任何帮助。所以我调查了一下并试图弄明白。在我看来,最好的解决方案是只为你的图例添加一个图而不是添加图。添加图表会将与图表关联的所有绘图添加到图例中。

CPTLegend *theLegend = [CPTLegend legendWithGraph:barChart];

替换为

NSMutableArray *legendPlots =[[NSMutableArray alloc] init];
[legendPlots addObject:barPlot];
CPTLegend *theLegend = [CPTLegend legendWithPlots:legendPlots];

我在一个图表中遇到了多个饼图相同的问题。这解决了我的问题。