Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

isianto

macrumors regular
Original poster
Feb 12, 2007
108
0
Indonesia
'm trying to graph multiple plot in one graph. When I know how many plot I want to graph, I can doit. The problem arise when I need to graph many plot based on core data entity.For example, if the core data entity has 5 count, then I need to draw 5 plots in one graph. I've successfully set up the plot, as you can see in the picture. https://www.flickr.com/photos/45474162@N05/13514560393/lightbox/

This is the setup code for the scatter plot and data

Code:
-(void)renderInLayer:(CPTGraphHostingView *)layerHostingView withTheme:(CPTTheme *)theme animated:(BOOL)animated
{
    CGRect frame1 = CGRectMake(10,150,300,250);
    FESubView = [[CPTGraphHostingView alloc]initWithFrame:frame1];
    FESubView.allowPinchScaling = YES;
    [self.view addSubview:FESubView];


#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
    CGRect bounds = layerHostingView.bounds;
#else
    CGRect bounds = NSRectToCGRect(layerHostingView.bounds);
#endif

    CPTGraph *graph = [[CPTXYGraph alloc] initWithFrame:bounds];
    [graph applyTheme:[CPTTheme themeNamed:kCPTDarkGradientTheme]];
    FESubView.hostedGraph = graph;
    graph.title = @"Fuel Economy Graph";
    CPTMutableTextStyle *titleStyle = [CPTMutableTextStyle textStyle];
    titleStyle.color = [CPTColor whiteColor];
    titleStyle.fontName = @"Helvetica-Bold";
    titleStyle.fontSize = 14.0f;
    graph.titleTextStyle = titleStyle;
    graph.titlePlotAreaFrameAnchor = CPTRectAnchorTop;
    graph.titleDisplacement = CGPointMake(0.0f, 10.0f);

    // 4 - Set padding for plot area
    [graph.plotAreaFrame setPaddingLeft:40.0f];
    [graph.plotAreaFrame setPaddingBottom:65.0f];
    [graph.plotAreaFrame setPaddingTop:3.0f];
    [graph.plotAreaFrame setPaddingRight:3.0f];

    // Setup scatter plot space
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
    NSTimeInterval xLow       = 0.0f;
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(xLow) length:CPTDecimalFromFloat(oneDay * 10)];
    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(5.0) length:CPTDecimalFromFloat(10.0f)];

    //symbol

    CPTMutablePlotRange *xRange = [plotSpace.xRange mutableCopy];
    [xRange expandRangeByFactor:CPTDecimalFromCGFloat(1)];

    plotSpace.allowsUserInteraction = YES;

    // Create a plot that uses the data source method
    CPTMutableTextStyle *feLabelStyle = [CPTMutableTextStyle textStyle];
    feLabelStyle.fontSize = 10;
    feLabelStyle.color = [CPTColor whiteColor];

    NSArray *cptColors = [[NSArray alloc]initWithObjects:[CPTColor blueColor],[CPTColor yellowColor],[CPTColor greenColor],[CPTColor orangeColor],[CPTColor whiteColor], nil];
    [self fetchVehicleModel];


    int counts = [self.fullVehicleData count];
    int i;
    for (i = 0; i < counts; i++)
    {
        CPTScatterPlot *dataSourceLinePlot = [[CPTScatterPlot alloc] init];
        dataSourceLinePlot.identifier = [[self.fullVehicleData valueForKey:@"vModel"] objectAtIndex:i];
       CPTColor *feColor = cptColors[i];
        CPTMutableLineStyle *feLineStyle = [dataSourceLinePlot.dataLineStyle mutableCopy];
        feLineStyle.lineWidth = 2.5;
        feLineStyle.lineColor = feColor;
        dataSourceLinePlot.dataLineStyle = feLineStyle;
       CPTMutableLineStyle *feSymbolLineStyle = [CPTMutableLineStyle lineStyle];
        feSymbolLineStyle.lineColor = feColor;
        CPTPlotSymbol *feSymbol = [CPTPlotSymbol ellipsePlotSymbol];
        feSymbol.fill = [CPTFill fillWithColor:feColor];
        feSymbol.lineStyle = feSymbolLineStyle;
        feSymbol.size = CGSizeMake(6.0f, 6.0f);
        dataSourceLinePlot.plotSymbol = feSymbol;
        //CPTTextStyle *test = [CPTTextStyle textStyle];
        //test.fontSize = 12;
        CPTMutableTextStyle *feLabelStyle1 = [CPTMutableTextStyle textStyle];
        feLabelStyle1.fontSize = 10;
        feLabelStyle1.color = [CPTColor whiteColor];
        dataSourceLinePlot.labelTextStyle = feLabelStyle;
        //    
        dataSourceLinePlot.dataSource = self;
        dataSourceLinePlot.title = [[self.fullVehicleData valueForKey:@"vModel"] objectAtIndex:i];

        [graph addPlot:dataSourceLinePlot];
        CPTColor *areaColor = [CPTColor colorWithComponentRed:0.3
                                                        green:1.0 + i
                                                         blue:0.3
                                                        alpha:0.3];
        CPTGradient *areaGradient = [CPTGradient gradientWithBeginningColor:areaColor
                                                                endingColor:[CPTColor clearColor]];
        areaGradient.angle = -90.0f;
        CPTFill *areaGradientFill = [CPTFill fillWithGradient:areaGradient];
        dataSourceLinePlot.areaFill = areaGradientFill;
        dataSourceLinePlot.areaBaseValue = CPTDecimalFromString(@"1.75");
        CPTMutableTextStyle *axisTextStyle = [[CPTMutableTextStyle alloc] init];
        axisTextStyle.color = [CPTColor whiteColor];
        axisTextStyle.fontName = @"Helvetica-Bold";
        axisTextStyle.fontSize = 8.0f;

        // Axes
        CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
        CPTXYAxis *x          = axisSet.xAxis;
        x.majorIntervalLength         = CPTDecimalFromFloat(oneDay);
        x.orthogonalCoordinateDecimal = CPTDecimalFromString(@"5");
        x.minorTicksPerInterval       = 0;
        x.labelTextStyle = axisTextStyle;

        dateFormatter = [self setDateFormatter];
        CPTTimeFormatter *timeFormatter = [[CPTTimeFormatter alloc] initWithDateFormatter:dateFormatter];
        timeFormatter.referenceDate = _refDate;

        x.labelFormatter            = timeFormatter;
        x.labelRotation            = M_PI / 4;
        x.tickLabelDirection = CPTSignPositive;
        x.tickDirection = CPTSignPositive;
        x.labelOffset = -50;

        CPTXYAxis *y = axisSet.yAxis;
        y.majorIntervalLength         = CPTDecimalFromString(@"5.0");
        y.minorTicksPerInterval       = 10;
        y.orthogonalCoordinateDecimal = CPTDecimalFromString(@"5");


        graph.legend = [CPTLegend legendWithGraph:graph];
        graph.legend.borderLineStyle = x.axisLineStyle;
        graph.legend.fill = [CPTFill fillWithColor:[CPTColor darkGrayColor]];
        graph.legend.cornerRadius = 5.0;
        graph.legend.swatchSize = CGSizeMake(20, 20);
        graph.legendAnchor = CPTRectAnchorBottom;
        graph.legend.textStyle = axisTextStyle;
        graph.legendDisplacement = CGPointMake(2.40, 8.0);
    }
}
This is for generating data:

Code:
-(void)generateData
{

    if ( !plotData ) {

        NSDateComponents *dateComponents = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit  | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit     ) fromDate:[[self.fullTransaction valueForKey:@"tDate" ] objectAtIndex:0]];
        _refDate = [gregorian dateFromComponents:dateComponents];

        NSDate *dataDate = [[NSDate alloc]init];

        NSDateComponents *comps;

        int days;

        // Add some data
        NSMutableArray *newData = [NSMutableArray array];
       // NSMutableArray *newData1 = [NSMutableArray array];
        NSUInteger i;
        NSArray *array1 = nil;
        NSMutableArray *carArray = [NSMutableArray arrayWithArray:array1];
        //NSUInteger
                NSLog(@"model count is: %lu",(unsigned long)[[self.fullVehicleData valueForKey:@"vModel"] count]);
        for (int vecCount = 0; vecCount < [[self.fullVehicleData valueForKey:@"vModel"] count]; vecCount ++)
        {
            NSString *make = [[self.fullVehicleData valueForKey:@"vMake"] objectAtIndex:vecCount];
            NSString *model = [[self.fullVehicleData valueForKey:@"vModel"] objectAtIndex:vecCount];
            NSArray *array = [self filterArraybyMake:make andWithModel:model];

            [carArray addObjectsFromArray:array];
            NSLog(@"car Array are: %@",carArray);
            //}

        }

        for ( i = 0; i < [[self.fullTransaction valueForKey:@"tDate"]count]; i++ )
        {
            //Calculate days difference between dataDate and RefDate
            dataDate = [[self.fullTransaction valueForKey:@"tDate"]objectAtIndex:i];
            NSLog(@"RefDate is: %@",_refDate);
            NSLog(@"DateDate is: %@",dataDate);
            comps = [gregorian components:NSDayCalendarUnit fromDate:_refDate toDate:dataDate  options:0];
            days = [comps day] + 1;

            NSTimeInterval x = oneDay *days;

            int counts = [carArray count];
            id y;
            //id z;

            if (i < counts)
            {
                y = [[carArray valueForKey:@"tFuelEconomy" ] objectAtIndex:i];
            }
            else
                y = NULL;

           [newData addObject:
             [NSDictionary dictionaryWithObjectsAndKeys:
              [NSDecimalNumber numberWithFloat:x], [NSNumber numberWithInt:CPTScatterPlotFieldX],
              y, [NSNumber numberWithInt:CPTScatterPlotFieldY],
              nil]];
        }
        plotData = newData;
        newData = nil;
    }
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
    switch (fieldEnum)
    {
        case CPTScatterPlotFieldX:
        {
            NSDecimalNumber *num = [[plotData objectAtIndex:index] objectForKey:[NSNumber numberWithInt:fieldEnum]];
            return num;
        }
        case CPTScatterPlotFieldY:
        {
            NSLog(@"Plot identifier = %@",plot.identifier);
            int identifier = 0;
            for (identifier =0;identifier < [self.fullVehicleData count];identifier ++)
            {
                NSLog(@"identifier from coredata is: %@",[[self.fullVehicleData valueForKey:@"vModel"]objectAtIndex:identifier]);
                if ([plot.identifier isEqual:[[self.fullVehicleData valueForKey:@"vModel"]objectAtIndex:identifier]])
                {
                    NSDecimalNumber *num = [[plotData objectAtIndex:index] objectForKey:[NSNumber numberWithInt:fieldEnum]];
                    NSLog(@"num is %@",num);
                    return num;
                }
            }
        }

    }
    return nil;
}
Problems: For this core plot, based on the core data entity has 2 counts. That's why I need to 2 plots in the graph, if you see the legend of the plot, it seems that I have successfully prepare for 2 plots.

problem is, when I do checking for the identifier, in the
Code:
(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index, I always got the second plot.identifier value.
How to fix this?

Thanks

Regards,
 
Last edited by a moderator:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.