My bar graph disappears when I switch my app to background and then again comes back to foreground.
It's like shown below :
||| || ||
So in the above picture I have gaps, that means when my app is in background core plot does not draw bar graph. Is it a limitation of core plot?
My main task is to draw one bar per second and I have done this, but it's not working while in background. Is there some other alternate option by which I can achieve this?
Here is what I tried:
I made my graph object nil and then tried it reloading when app again comes back to foreground. But it didn't work.
-(void)redrawGraphWhenApplicationEntersForeground
{
NSLog(@"reload graph");
NSLog(@"all plots : %@ , %@", [self.graph allPlots], plotArray);
DDLogInfo(@"relaod graph when entered in Foreground ");
// [self.data removeAllObjects];
//Create graph and set it as host view's graph
self.graph = nil;
[self.graph reloadDataIfNeeded];
}`
Here is my full code :
// Update is called by a timer ( of 10 second) , so that each second this method will be called and it will draw a bar.
- (void)update:(id)data1 withState:(NSInteger) type
{
switch (type) {
case ZAP_UPDATE:
if(curLinkType == DOWNLINK)
{
[self drawDownlinkGrpah];
}else if(curLinkType == UPLINK)
{
[self drawUplinkGrpah];
}
[gauge setValue:speedValue];
break;
case ZAP_DONE:
[self displayDone:type speedBps:speedBps pktLoss:pktLoss srcdst:[zap destinationAddress]];
onTap = false;
runningTime=0;
if(gauge != nil){
[gauge setValue:0];
}
{
NSArray *parameter = [NSArray arrayWithObjects: speed, unit, nil];
[self performSelector:@selector(stopGauge:) withObject:parameter afterDelay:0.2];
}
}
}
- (void)drawDownlinkGrpah {
DownlinCount++;
self.downlinkdata = [NSMutableArray array];
double position = DownlinCount*((4*10)/(double)durationval);
NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:position],BAR_POSITION,
[NSNumber numberWithDouble:speedBarValue],BAR_HEIGHT,
[UIColor orangeColor],COLOR,
nil];
[self.downlinkdata addObject:bar];
self.data = self.downlinkdata;
[self generateBarPlotForDownlink:YES];
}
- (void)drawUplinkGrpah {
UplinkCount++;
self.uplinkdata = [NSMutableArray array];
double position = UplinkCount*((4*10)/(double)durationval);
NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:position],BAR_POSITION,
[NSNumber numberWithDouble:speedBarValue],BAR_HEIGHT,
[UIColor orangeColor],COLOR,
nil];
[self.uplinkdata addObject:bar];
self.data = self.uplinkdata;
[self generateBarPlotForDownlink:NO];
}
- (NSInteger)getBarposition:(NSInteger)samplesize {
return (4*10)/samplesize;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)resetGraph:(UIImageView*) imageview {
for(UIView *view in imageview.subviews)
[view removeFromSuperview];
[imageview setImage:[UIImage imageNamed:@"graph_container"]];
}
#pragma mark -
-(void)appGoesinBackground
{
// NSLog(@"make nil graph");
// DDLogInfo(@"remove graph when entered in background ");
//
self.graph = nil;
// [self.data removeAllObjects];
[plotArray removeAllObjects]; // remove all data before entering to background
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(redrawGraphWhenApplicationEntersForeground)
name: UIApplicationDidBecomeActiveNotification
object: nil];
}
// redraw graph ..
-(void)redrawGraphWhenApplicationEntersForeground
{
NSLog(@"reload graph");
NSLog(@"all plots : %@ , %@", [self.graph allPlots], plotArray);
DDLogInfo(@"relaod graph when entered in Foreground ");
// [self.data removeAllObjects];
//Create graph and set it as host view's graph
// self.graph = nil;
//
for (CPTBarPlot *p in plotArray) {
// [self.graph addPlot:p];
[p reloadData];
}
}
#pragma mark - generate bar plot
- (void)generateBarPlotForDownlink:(BOOL)enabled
{
NSLog(@"generateBarPlotForDownlink >>>>>>");
//Create host view
self.hostingView = [[CPTGraphHostingView alloc] initWithFrame:CGRectMake(-35, -20, 128, 73)];
//Create graph and set it as host view's graph
self.graph = [[CPTXYGraph alloc] initWithFrame:self.downlinkImageView.frame];
self.graph.plotAreaFrame.masksToBorder = NO;
[self.hostingView setHostedGraph:self.graph];
if(enabled) // for downlink graph ..
{
self.downlinkImageView.image=nil;
[self.downlinkImageView addSubview:self.hostingView];
}
else{ // for uplink graph ..
self.uplinkImageView.image=nil;
[self.uplinkImageView addSubview:self.hostingView];
}
// Create bar plot and add it to the graph
CPTBarPlot *plot = [[CPTBarPlot alloc] init] ;
plot.dataSource = self;
plot.delegate = self;
//set axes ranges
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:
CPTDecimalFromFloat(AXIS_START)
length:CPTDecimalFromFloat((AXIS_END - AXIS_START)+1)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:
CPTDecimalFromFloat(AXIS_START)
length:CPTDecimalFromFloat(maxYRange)];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
axisSet.xAxis.majorIntervalLength = CPTDecimalFromFloat(1.0f);
axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(1.0f);
axisSet.xAxis.minorTickLength = 1.0f;
axisSet.yAxis.minorTickLength = 1.0f;
axisSet.hidden=YES;
axisSet.xAxis.labelingPolicy=CPTAxisLabelingPolicyNone;
axisSet.yAxis.labelingPolicy=CPTAxisLabelingPolicyNone;
float barwidht = (2*10.0)/(float)durationval;
NSString *inStr = [NSString stringWithFormat: @"%f", barwidht];
plot.barWidth = [[NSDecimalNumber decimalNumberWithString:inStr] // Need to change according sample // 1.5 for 10 , 0.75 for 20
decimalValue];
plot.barOffset = [[NSDecimalNumber decimalNumberWithString:@"5.0"]
decimalValue];
plot.barCornerRadius = 0.0;
// Remove bar outlines
CPTMutableLineStyle *borderLineStyle = [CPTMutableLineStyle lineStyle];
borderLineStyle.lineColor = [CPTColor clearColor];
plot.lineStyle = borderLineStyle;
plot.identifier = @"chocoplot";
[self.graph addPlot:plot];
// Add plot to array in case if app is moved to background state ..
[plotArray addObject:plot];
NSLog(@"plot : %@",plot);
NSLog(@"plot added ..%lu", (unsigned long)plotArray.count );
}
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
if ( [plot.identifier isEqual:@"chocoplot"] )
return [self.data count];
return 0;
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
if ( [plot.identifier isEqual:@"chocoplot"] )
{
NSDictionary *bar = [self.data objectAtIndex:index];
if(fieldEnum == CPTBarPlotFieldBarLocation)
return [bar valueForKey:BAR_POSITION];
else if(fieldEnum ==CPTBarPlotFieldBarTip)
return [bar valueForKey:BAR_HEIGHT];
}
return [NSNumber numberWithFloat:0];
}
-(CPTFill *)barFillForBarPlot:(CPTBarPlot *)barPlot
recordIndex:(NSUInteger)index
{
if ( [barPlot.identifier isEqual:@"chocoplot"] )
{
NSDictionary *bar = [self.data objectAtIndex:index];
CPTGradient *gradient = [CPTGradient gradientWithBeginningColor:[CPTColor redColor]
endingColor:[bar valueForKey:@"COLOR"]
beginningPosition:0.0 endingPosition:0.6 ];
[gradient setGradientType:CPTGradientTypeAxial];
[gradient setAngle:320.0];
CPTFill *fill = [CPTFill fillWithGradient:gradient];
return fill;
}
return [CPTFill fillWithColor:[CPTColor colorWithComponentRed:1.0 green:1.0 blue:1.0 alpha:1.0]];
}
Screenshot:
Here is the code that worked for me :
- (void)drawDownlinkGrpah {
NSLog(@"drawDownlinkGrpah CAlled");
DownlinCount++;
double position = DownlinCount*((4*10)/(double)durationval);
NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:position],BAR_POSITION,
[NSNumber numberWithDouble:speedBarValue],BAR_HEIGHT,
[UIColor orangeColor],COLOR,
nil];
[self.downlinkdata addObject:bar];
self.data = self.downlinkdata;
[self generateBarPlotForDownlink:YES];
}
#pragma mark - generate bar
- (void)generateBarPlotForDownlink:(BOOL)enabled
{
if(enabled)
{
self.downlinkImageView.image=nil;
if(![self.hostingView isDescendantOfView:self.downlinkImageView])
{
// Configure hosting view so that it appears from fresh ..
[self configureGraph];
[self.downlinkImageView addSubview:self.hostingView];
NSLog(@"hosting view added in downlink view ");
}
}
else
{
self.uplinkImageView.image=nil;
// if hosting view is not in uplink view
if(![self.hostingView isDescendantOfView:self.uplinkImageView])
{
// Configure hosting view so that it appears from fresh ..
[self configureGraph];
[self.uplinkImageView addSubview:self.hostingView];
NSLog(@"hosting view added in uplink view ");
}
}
//set axes ranges
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:
CPTDecimalFromFloat(AXIS_START)
length:CPTDecimalFromFloat((AXIS_END - AXIS_START)+1)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:
CPTDecimalFromFloat(AXIS_START)
length:CPTDecimalFromFloat(maxYRange)];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
axisSet.xAxis.majorIntervalLength = CPTDecimalFromFloat(1.0f);
axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(1.0f);
axisSet.xAxis.minorTickLength = 1.0f;
axisSet.yAxis.minorTickLength = 1.0f;
axisSet.hidden=YES;
axisSet.xAxis.labelingPolicy=CPTAxisLabelingPolicyNone;
axisSet.yAxis.labelingPolicy=CPTAxisLabelingPolicyNone;
// Create bar plot and add it to the graph
NSLog(@"plot created %ld", (long)durationval);
CPTBarPlot *plot = [[CPTBarPlot alloc] init] ;
plot.dataSource = self;
plot.delegate = self;
float barwidht = (2*10.0)/(float)durationval;
NSString *inStr = [NSString stringWithFormat: @"%f", barwidht]; //CPTDecimalFromDouble(2.0);
plot.barWidth = [[NSDecimalNumber decimalNumberWithString:inStr]
decimalValue];// Need to change according sample // 1.5 for 10 , 0.75 for 20
plot.barWidth = CPTDecimalFromDouble(barwidht);
plot.barOffset = [[NSDecimalNumber decimalNumberWithString:@"5.0"]
decimalValue];
plot.barCornerRadius = 0.0;
// Remove bar outlines
CPTMutableLineStyle *borderLineStyle = [CPTMutableLineStyle lineStyle];
borderLineStyle.lineColor = [CPTColor clearColor];
plot.lineStyle = borderLineStyle;
plot.identifier = @"chocoplot";
[self.graph addPlot:plot];
}
#pragma mark - core plot data source and delegate methods
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
if ( [plot.identifier isEqual:@"chocoplot"] )
return [self.data count];
return 0;
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
if ( [plot.identifier isEqual:@"chocoplot"] )
{
NSDictionary *bar = [self.data objectAtIndex:index];
if(fieldEnum == CPTScatterPlotFieldX)
return [bar valueForKey:BAR_POSITION];
else if(fieldEnum ==CPTScatterPlotFieldY)
return [bar valueForKey:BAR_HEIGHT];
}
return [NSNumber numberWithFloat:0];
}
drawDownlinkGraph
method would be called each second using a timer and it will call generateBarPlotForDownlink:
Method every second . And bar will be drawn each second on a real time basis even if APP is in background.