0

基本上,我有这个类,用于在 CorePlot 条形图中显示数据:

#import "BarChartViewController.h"
#import "AppDelegate.h"
#import "Project.h"
#import "Currency.h"
#import "TotalValueCalculator.h"

#define BAR_POSITION @"POSITION"
#define BAR_HEIGHT @"HEIGHT"
#define COLOR @"COLOR"
#define CATEGORY @"CATEGORY"

#define AXIS_START 0

@interface BarChartViewController ()

@end

@implementation BarChartViewController
{
    int count;
}

@synthesize data;
@synthesize graph;
@synthesize hostingView;
@synthesize graphType;

//Finds the maximum value from an array of ints
int findMax (int numbers[], int N){
    int max = numbers[0];
    for (int i = 0; i < N; i++)
        if(max<numbers[i]) max = numbers[i];

    return max;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

    }

    return self;
}


- (void) generateBarPlot
{
    //Create host view
    self.hostingView = [[CPTGraphHostingView alloc] 
                        initWithFrame:[[UIScreen mainScreen]bounds]];
    [self.view addSubview:self.hostingView];

    //Create graph and set it as host view's graph
    self.graph = [[CPTXYGraph alloc] initWithFrame:self.hostingView.bounds];
    [self.hostingView setHostedGraph:self.graph];

    //set graph padding and theme
    self.graph.plotAreaFrame.paddingTop = 20.0f;
    self.graph.plotAreaFrame.paddingRight = 20.0f;
    self.graph.plotAreaFrame.paddingBottom = 170.0f;
    self.graph.plotAreaFrame.paddingLeft = 70.0f;
    [self.graph applyTheme:[CPTTheme themeNamed:kCPTDarkGradientTheme]];

    //set axes ranges
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(AXIS_START) length:CPTDecimalFromFloat(50)];

    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:
                        CPTDecimalFromFloat(AXIS_START)
                                                    length:CPTDecimalFromFloat((axisEnd - AXIS_START)+5)];

    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
    //set axes' title, labels and their text styles
    CPTMutableTextStyle *textStyle = [CPTMutableTextStyle textStyle];
    textStyle.fontName = @"Helvetica";
    textStyle.fontSize = 14;
    textStyle.color = [CPTColor whiteColor];

    if (graphType == @"TotalProject"){
        axisSet.xAxis.title = @"Project Name";
    }
    else if (graphType == @"TotalCategory"){
        axisSet.xAxis.title = @"Category Name";
    }
    else if (graphType == @"TotalCurrency"){
        axisSet.xAxis.title = @"Currency Name";
    }

    else if (graphType == @"DistanceTravelled"){
        axisSet.xAxis.title = @"Project";
    }
    else if (graphType == @"FuelCostProject"){
        axisSet.xAxis.title = @"Project";
    }
    else if (graphType == @"FuelCostCurrency"){
        axisSet.xAxis.title = @"Currency";
    }

    axisSet.yAxis.title = @"Total Value";
    axisSet.xAxis.titleTextStyle = textStyle;
    axisSet.yAxis.titleTextStyle = textStyle;
    axisSet.xAxis.titleOffset = 50.0f;
    axisSet.yAxis.titleOffset = 50.0f;
    axisSet.xAxis.labelTextStyle = textStyle;
    axisSet.xAxis.labelOffset = 3.0f;
    axisSet.yAxis.labelTextStyle = textStyle;
    axisSet.yAxis.labelOffset = 3.0f;
    //set axes' line styles and interval ticks
    CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle];
    lineStyle.lineColor = [CPTColor whiteColor];
    lineStyle.lineWidth = 3.0f;
    axisSet.xAxis.axisLineStyle = lineStyle;
    axisSet.yAxis.axisLineStyle = lineStyle;
    axisSet.xAxis.majorTickLineStyle = lineStyle;
    axisSet.yAxis.majorTickLineStyle = lineStyle;
    //Set x axis tick length to 0 as there is no data on the x axis
    axisSet.xAxis.majorIntervalLength = CPTDecimalFromFloat(0.0f);

    if (axisEnd <= 400){
        axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(25.0f);
    }
    else if (axisEnd <= 900){
        axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(50.0f);
    }
    else if (axisEnd <= 1300){
        axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(75.0f);
    }
    else if (axisEnd <= 1800){
        axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(100.0f);
    }
    else if (axisEnd <= 2300){
        axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(125.0f);
    }
    else if (axisEnd <= 2800){
        axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(150.0f);
    }
    else if (axisEnd <= 3300){
        axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(175.0f);
    }
    else if (axisEnd <= 3500){
        axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(200.0f);
    }
    else {
        axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(300.0f);
    }

    axisSet.xAxis.majorTickLength = 7.0f;
    axisSet.yAxis.majorTickLength = 7.0f;
    axisSet.xAxis.minorTickLineStyle = lineStyle;
    axisSet.yAxis.minorTickLineStyle = lineStyle;
    axisSet.xAxis.minorTicksPerInterval = 1;
    axisSet.yAxis.minorTicksPerInterval = 1;
    axisSet.xAxis.minorTickLength = 5.0f;
    axisSet.yAxis.minorTickLength = 5.0f;

    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
    [numberFormatter setMaximumFractionDigits:2];
    [numberFormatter setPositiveFormat:@"###0.00"];    
    axisSet.yAxis.labelFormatter = numberFormatter;

    int initialTickLocation = 9;
    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    NSMutableArray *customTickLocations = [[NSMutableArray alloc] init];
    NSMutableArray *xAxisLabels = [[NSMutableArray alloc] init];

    if (graphType == @"TotalProject"){
        for (int i = 0; i < [appDelegate.projects count]; i++){

            //CHANGE THESE NUMBERS TO CHANGE POSITIONS OF THE LABELS
                [customTickLocations addObject:[NSNumber numberWithInt:initialTickLocation]];
                initialTickLocation = initialTickLocation + 7;
                [xAxisLabels addObject:[[appDelegate.projects objectAtIndex:i] name]];
        }
    }
    else if (graphType == @"TotalCategory"){
        for (int i = 0; i < [appDelegate.categories count]; i++){
            //CHANGE THESE NUMBERS TO CHANGE POSITIONS OF THE LABELS
            [customTickLocations addObject:[NSNumber numberWithInt:initialTickLocation]];
            initialTickLocation = initialTickLocation + 7;
            [xAxisLabels addObject:[[appDelegate.categories objectAtIndex:i] name]];
        }
    }
    else if (graphType == @"TotalCurrency"){
        for (int i = 0; i < [appDelegate.currencies count]; i++){
            //CHANGE THESE NUMBERS TO CHANGE POSITIONS OF THE LABELS
            [customTickLocations addObject:[NSNumber numberWithInt:initialTickLocation]];
            initialTickLocation = initialTickLocation + 7;
            [xAxisLabels addObject:[[appDelegate.currencies objectAtIndex:i] shortName]];
        }
    }

    else if (graphType == @"DistanceTravelled"){
        for (int i = 0; i < [appDelegate.projects count]; i++){
            //CHANGE THESE NUMBERS TO CHANGE POSITIONS OF THE LABELS
            [customTickLocations addObject:[NSNumber numberWithInt:initialTickLocation]];
            initialTickLocation = initialTickLocation + 7;
            [xAxisLabels addObject:[[appDelegate.projects objectAtIndex:i] name]];
        }
    }
    else if (graphType == @"FuelCostProject"){
        for (int i = 0; i < [appDelegate.projects count]; i++){
            //CHANGE THESE NUMBERS TO CHANGE POSITIONS OF THE LABELS
            [customTickLocations addObject:[NSNumber numberWithInt:initialTickLocation]];
            initialTickLocation = initialTickLocation + 7;
            [xAxisLabels addObject:[[appDelegate.projects objectAtIndex:i] name]];
        }
    }
    else if (graphType == @"FuelCostCurrency"){
        for (int i = 0; i < [appDelegate.currencies count]; i++){
            //CHANGE THESE NUMBERS TO CHANGE POSITIONS OF THE LABELS
            [customTickLocations addObject:[NSNumber numberWithInt:initialTickLocation]];
            initialTickLocation = initialTickLocation + 7;
            [xAxisLabels addObject:[[appDelegate.currencies objectAtIndex:i] shortName]];
        }
    }

    axisSet.xAxis.labelRotation = M_PI/4;
    axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyNone;

    NSUInteger labelLocation = 0;
    NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:[xAxisLabels count]];
    for (NSNumber *tickLocation in customTickLocations){
        CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText:[xAxisLabels objectAtIndex:labelLocation++] textStyle:axisSet.xAxis.labelTextStyle];
        newLabel.tickLocation = [tickLocation decimalValue];
        newLabel.offset = axisSet.xAxis.labelOffset + axisSet.xAxis.majorTickLength;
        newLabel.rotation = M_PI / 4;
        [customLabels addObject:newLabel];
    }
    axisSet.xAxis.axisLabels = [NSSet setWithArray:customLabels];

    // Create bar plot and add it to the graph
    CPTBarPlot *plot = [[CPTBarPlot alloc] init] ;
    plot.dataSource = self;
    plot.delegate = self;
    plot.barWidth = [[NSDecimalNumber decimalNumberWithString:@"5.0"]
                     decimalValue];
    plot.barOffset = [[NSDecimalNumber decimalNumberWithString:@"10.0"]
                      decimalValue];
    plot.barCornerRadius = 5.0;
    // Remove bar outlines
    CPTMutableLineStyle *borderLineStyle = [CPTMutableLineStyle lineStyle];
    borderLineStyle.lineColor = [CPTColor clearColor];
    plot.lineStyle = borderLineStyle;
    // Identifiers are handy if you want multiple plots in one graph
    plot.identifier = @"projectTotals";
    [self.graph addPlot:plot];
}

-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
    return [self.data count];
}

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
    NSDictionary *bar = [self.data objectAtIndex:index];

    if(fieldEnum == CPTBarPlotFieldBarLocation){
        NSLog(@"Position: %@", [bar valueForKey:BAR_POSITION]);
        return [bar valueForKey:BAR_POSITION];
    }
    else{ 
        NSLog(@"Height: %@", [bar valueForKey:BAR_HEIGHT]);
        return [bar valueForKey:BAR_HEIGHT];
    }

}

-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index
{

    CPTMutableTextStyle *textStyle = [CPTMutableTextStyle textStyle];
    textStyle.fontName = @"Helvetica";
    textStyle.fontSize = 12;
    textStyle.color = [CPTColor whiteColor];

    NSDictionary *bar = [self.data objectAtIndex:index];
    //Here we want to display the value for that day, not the name of the day
    CPTTextLayer *label = [[CPTTextLayer alloc] initWithText:[NSString stringWithFormat:@"%0.2f", [[bar valueForKey:BAR_HEIGHT] floatValue]]];
    label.textStyle =textStyle;

    return label;

}

-(CPTFill *)barFillForBarPlot:(CPTBarPlot *)barPlot
                  recordIndex:(NSUInteger)index
{
    NSDictionary *bar = [self.data objectAtIndex:index];
    CPTGradient *gradient = [CPTGradient gradientWithBeginningColor:[CPTColor whiteColor]
                                                        endingColor:[bar valueForKey:@"COLOR"]
                                                  beginningPosition:0.0 endingPosition:0.3 ];
    [gradient setGradientType:CPTGradientTypeAxial];
    [gradient setAngle:320.0]; 

    CPTFill *fill = [CPTFill fillWithGradient:gradient];

    return fill;
}

- (void)dealloc
{

}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.data = [NSMutableArray array];

    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    count = [appDelegate.projects count];
    int catCount = [appDelegate.categories count];
    int currencyCount = [appDelegate.currencies count];

    int bar_heights[count];
    NSString *categories[count];
    int catBar_heights[catCount];
    NSString *catCategories[catCount];
    int currencyBar_heights[currencyCount];
    NSString *currencyCategories[currencyCount];

    if ([graphType isEqualToString:@"TotalProject"])
    {
                for (int i = 0; i < count; i++)
                {
                    TotalValueCalculator *calc = [[TotalValueCalculator alloc] initWithString:[[appDelegate.projects objectAtIndex:i] name]];
                    NSString *totalValueString = [calc compareProject];
                    float totalValue = [totalValueString floatValue];

                    bar_heights[i] = totalValue;
                    NSLog(@"---%0.2f", totalValue);
                    categories[i] = [[appDelegate.projects objectAtIndex:i] name];
                }

                axisEnd = findMax(bar_heights, count) + ((findMax(bar_heights, count)) / 10);

                UIColor *colors[] = {
                    [UIColor colorWithRed:139/255.0 green:198/255.0 blue:63/255.0 alpha:1], 
                    nil};

                for (int i = 0; i < [appDelegate.projects count] ; i++){
                    int position = i*7; //Bars will be 7 pts away from each other
                    float height = bar_heights[i];
                    NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
                                         [NSDecimalNumber numberWithFloat:position],BAR_POSITION,
                                         [NSDecimalNumber numberWithFloat:height],BAR_HEIGHT,
                                         colors[0],COLOR,
                                         categories[i],CATEGORY,
                                         nil];
                    NSLog(@"^^^^^^^^^^^^^%@", [NSDecimalNumber numberWithFloat:height]);
                    [self.data addObject:bar];

                }

    }
    else if ([graphType isEqualToString:@"TotalCategory"])
    {
        for (int i = 0; i < catCount; i++)
        {
            TotalValueCalculator *calc = [[TotalValueCalculator alloc] initWithString:[[appDelegate.categories objectAtIndex:i] name]];
            NSString *totalValueString = [calc compareCategory];
            double totalValue = [totalValueString doubleValue];

            catBar_heights[i] = totalValue;
            catCategories[i] = [[appDelegate.categories objectAtIndex:i] name];
        }

        axisEnd = findMax(catBar_heights, catCount) + ((findMax(catBar_heights, catCount)) / 10);

        UIColor *colors[] = {
            [UIColor colorWithRed:236/255.0 green:139/255.0 blue:34/255.0 alpha:1], 
            nil};

        for (int i = 0; i < [appDelegate.categories count] ; i++){
            double position = i*7; //Bars will be 7 pts away from each other
            double height = catBar_heights[i];

            NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithDouble:position],BAR_POSITION,
                                 [NSNumber numberWithDouble:height],BAR_HEIGHT,
                                 colors[0],COLOR,
                                 catCategories[i],CATEGORY,
                                 nil];
            [self.data addObject:bar];

        }

    }
    else if ([graphType isEqualToString:@"TotalCurrency"])
    {

        for (int i = 0; i < currencyCount; i++)
        {
            TotalValueCalculator *calc = [[TotalValueCalculator alloc] initWithString:[[appDelegate.currencies objectAtIndex:i] shortName]];
            NSString *totalValueString = [calc compareCurrency];
            double totalValue = [totalValueString doubleValue];

            currencyBar_heights[i] = totalValue;
            currencyCategories[i] = [[appDelegate.currencies objectAtIndex:i] shortName];
        }

        axisEnd = findMax(currencyBar_heights, currencyCount) + ((findMax(currencyBar_heights, currencyCount)) / 10);

        UIColor *colors[] = {
            [UIColor colorWithRed:236/255.0 green:139/255.0 blue:34/255.0 alpha:1], 
            nil};

        for (int i = 0; i < [appDelegate.currencies count] ; i++){
            double position = i*7; //Bars will be 7 pts away from each other
            double height = currencyBar_heights[i];

            NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithDouble:position],BAR_POSITION,
                                 [NSNumber numberWithDouble:height],BAR_HEIGHT,
                                 colors[0],COLOR,
                                 currencyCategories[i],CATEGORY,
                                 nil];
            [self.data addObject:bar];

        }

    }
    else if ([graphType isEqualToString:@"DistanceTravelled"])
    {

        for (int i = 0; i < count; i++)
        {
            TotalValueCalculator *calc = [[TotalValueCalculator alloc] initWithString:[[appDelegate.projects objectAtIndex:i] name]];
            NSString *totalValueString = [calc compareProjectDistance];
            double totalValue = [totalValueString doubleValue];

            bar_heights[i] = totalValue;
            categories[i] = [[appDelegate.projects objectAtIndex:i] name];
        }

        axisEnd = findMax(bar_heights, count) + ((findMax(bar_heights, count)) / 10);

        UIColor *colors[] = {
            [UIColor colorWithRed:236/255.0 green:139/255.0 blue:34/255.0 alpha:1], 
            nil};

        for (int i = 0; i < [appDelegate.projects count] ; i++){
            double position = i*7; //Bars will be 7 pts away from each other
            double height = bar_heights[i];

            NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithDouble:position],BAR_POSITION,
                                 [NSNumber numberWithDouble:height],BAR_HEIGHT,
                                 colors[0],COLOR,
                                 categories[i],CATEGORY,
                                 nil];
            [self.data addObject:bar];

        }

    }
    else if ([graphType isEqualToString:@"FuelCostProject"])
    {

        for (int i = 0; i < count; i++)
        {
            TotalValueCalculator *calc = [[TotalValueCalculator alloc] initWithString:[[appDelegate.projects objectAtIndex:i] name]];
            NSString *totalValueString = [calc compareProjectFuel];
            double totalValue = [totalValueString doubleValue];

            bar_heights[i] = totalValue;
            categories[i] = [[appDelegate.projects objectAtIndex:i] name];
        }

        axisEnd = findMax(bar_heights, count) + ((findMax(bar_heights, count)) / 10);

        UIColor *colors[] = {
            [UIColor colorWithRed:236/255.0 green:139/255.0 blue:34/255.0 alpha:1], 
            nil};

        for (int i = 0; i < [appDelegate.projects count] ; i++){
            double position = i*7; //Bars will be 7 pts away from each other
            double height = bar_heights[i];

            NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithDouble:position],BAR_POSITION,
                                 [NSNumber numberWithDouble:height],BAR_HEIGHT,
                                 colors[0],COLOR,
                                 categories[i],CATEGORY,
                                 nil];
            [self.data addObject:bar];

        }

    }
    else if ([graphType isEqualToString:@"FuelCostCurrency"])
    {

        for (int i = 0; i < currencyCount; i++)
        {
            TotalValueCalculator *calc = [[TotalValueCalculator alloc] initWithString:[[appDelegate.currencies objectAtIndex:i] shortName]];
            NSString *totalValueString = [calc compareCurrencyFuel];
            double totalValue = [totalValueString doubleValue];

            currencyBar_heights[i] = totalValue;
            currencyCategories[i] = [[appDelegate.currencies objectAtIndex:i] shortName];
        }

        axisEnd = findMax(currencyBar_heights, currencyCount) + ((findMax(currencyBar_heights, currencyCount)) / 10);

        UIColor *colors[] = {
            [UIColor colorWithRed:236/255.0 green:139/255.0 blue:34/255.0 alpha:1], 
            nil};

        for (int i = 0; i < [appDelegate.currencies count] ; i++){
            double position = i*7; //Bars will be 7 pts away from each other
            double height = currencyBar_heights[i];

            NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithDouble:position],BAR_POSITION,
                                 [NSNumber numberWithDouble:height],BAR_HEIGHT,
                                 colors[0],COLOR,
                                 currencyCategories[i],CATEGORY,
                                 nil];
            [self.data addObject:bar];

        }

    }

            [self generateBarPlot];

}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

我知道那里有很多,但我一生都无法弄清楚如何让这个条形图显示浮点值(对于条形高度)?我在这上面花了很多时间,现在我开始绝望了。

有谁知道如何做到这一点?图表接收的值肯定是浮点值。

任何帮助都将不胜感激..

非常感谢,

杰克

4

1 回答 1

1

中的bar_heights数组-viewDidLoad声明为int. 由于数据值在放入您传递给绘图数据源的字典结构之前存储在这里,因此值的任何小数部分都会丢失。

于 2012-07-25T01:00:56.583 回答