Display both negative and positive horizontal in a single bar chart - ios

I want to display horizontal bar chart... in it.. positive bar chart will animate from left to right and negative bar will animate from right to left..
i also attached my two different types of array...1 for positive and 1 for negative
When i run this code... negative bar value look like mirror effect...and for positive value, it use two color in each bar...
please help me to solve it..
if you can find anything wrong in code.. then please let me know
i attach two images also.. 1 for negative and 1 for positive
and ya, you can see that how values are display in negative bar...i also need to solve it also..
sampleArray:
<__NSArrayM 0xbae0940>(
{
x = 0;
y = "97.71425628662109";
},
{
x = 0;
y = "-70.55500793457031";
}
)
sampleArray:
<__NSArrayM 0x12a295a0>(
{
x = 0;
y = "97.71425628662109";
},
{
x = 0;
y = "450.6826171875";
}
)
Here is my whole code...
CPTGraphHostingView *hostingView = [[CPTGraphHostingView alloc] initWithFrame:CGRectMake(200, 100, 300, 300)];
hostingView.hostedGraph = self.barChart;
[self addSubview:hostingView];
plotSpace = (CPTXYPlotSpace *) self.barChart.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(-200.0f) length:CPTDecimalFromDouble(650.0f)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(00.0f) length:CPTDecimalFromDouble(400.0f)];
- (void) animateNow
{
CPTBarPlot *barPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor orangeColor] horizontalBars:YES];
// define the plot range - between LTM and NEW, diffrence is 200
barPlot.plotRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0) length:CPTDecimalFromDouble(200)];//xAxisLength
// LTM will display at 100th point and NEW will display at 300th coz of 200 range
barPlot.barOffset = CPTDecimalFromFloat(100.00f);
barPlot.baseValue = CPTDecimalFromString(#"0");
barPlot.borderColor = [[UIColor clearColor]CGColor];
barPlot.lineStyle = nil;
// Width of the each bar
barPlot.barWidth = CPTDecimalFromFloat(30.0f);
barPlot.cornerRadius = 1.0f;
barPlot.dataSource = self;
// transform.scale.x for horizontal bar growth
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:#"transform.scale.x"];
if([[[self.sampleArray objectAtIndex:0]valueForKey:Y_VAL]floatValue] < 0)
{
anim.toValue = [NSNumber numberWithFloat:-1.0];
anim.fromValue = [NSNumber numberWithFloat:0.0f];
}
else
{
anim.toValue = [NSNumber numberWithFloat:1.0];
anim.fromValue = [NSNumber numberWithFloat:0.0f];
}
[anim setDuration:2.0f];
anim.toValue = [NSNumber numberWithFloat:1.0];
anim.fromValue = [NSNumber numberWithFloat:0.0f];
anim.removedOnCompletion = NO;
anim.delegate = self;
anim.fillMode = kCAFillModeForwards;
barPlot.anchorPoint = CGPointMake(0.0, 0.0);
[barPlot addAnimation:anim forKey:#"grow"];
[self.barChart addPlot:barPlot toPlotSpace:plotSpace ];
}
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
/* if([plot.identifier isEqual:#"LTM"])
return [self.sampleArray count]; */
// return [self.sampleArray count];
return [self.sampleArray count];
}
-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index
{
NSDictionary *bar;
CPTTextLayer *label;
if([plot.identifier isEqual:#"LTM"])
{
bar = [self.sampleArray objectAtIndex:0];
label = [[CPTTextLayer alloc] initWithText:[NSString stringWithFormat:#"%.02f", [[bar valueForKey:Y_VAL]floatValue]]];
}
else if([plot.identifier isEqual:#"NEW"])
{
bar = [self.sampleArray objectAtIndex:1];
label = [[CPTTextLayer alloc] initWithText:[NSString stringWithFormat:#"%.02f", [[bar valueForKey:Y_VAL]floatValue]]]; }
else
{
return nil;
}
float dataLabelOffset;
if([[self.sampleArray objectAtIndex:index]valueForKey:Y_VAL]> 0)
{
dataLabelOffset = -5.0f;
}
else
{
dataLabelOffset = 10.0f;
}
plot.labelOffset = dataLabelOffset;
NSLog(#"Offset = %f",plot.labelOffset);
// label.textStyle = textStyle;
return label;
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSDictionary *sample = [self.sampleArray objectAtIndex:index];
if (fieldEnum == CPTScatterPlotFieldX)
{
return [sample valueForKey:X_VAL];
}
else
{
return [sample valueForKey:Y_VAL];
}
}
-(CPTFill *)barFillForBarPlot:(CPTBarPlot *)barPlot recordIndex:(NSUInteger)index
{
CPTColor *color = nil;
// Index = 0, for LTM and Index = 1 for NEW.
NSLog(#"%#",barPlot.identifier);
switch ( index )
{
case 0:
color = [CPTColor colorWithComponentRed:147.0/255.0 green:149.0/255.0 blue:152.0/255.0 alpha:1.0];
break;
case 1:
color = [CPTColor colorWithComponentRed:255.0/255.0 green:160.0/255.0 blue:47.0/255.0 alpha:1.0];
break;
default:
break;
}
CPTGradient *fillGradient = [CPTGradient gradientWithBeginningColor:color endingColor:color];
return [CPTFill fillWithGradient:fillGradient];
}

When setting up the plots, don't use the plotRange or barOffset. You'll get better drawing performance if you use a solid color fill instead of a gradient (your gradient had the same start and end colors).
- (void) animateNow
{
CPTBarPlot *barPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor orangeColor] horizontalBars:YES];
barPlot.lineStyle = nil;
barPlot.barWidth = CPTDecimalFromFloat(30.0f);
barPlot.cornerRadius = 1.0f;
barPlot.dataSource = self;
CPTColor *color = [CPTColor colorWithComponentRed:147.0/255.0 green:149.0/255.0 blue:152.0/255.0 alpha:1.0];
barPlot.fill = [CPTFill fillWithColor:color];
CPTBarPlot *barPlot1 = [CPTBarPlot tubularBarPlotWithColor:[CPTColor blueColor] horizontalBars:YES];
barPlot1.barWidth = CPTDecimalFromFloat(30.0f);
barPlot1.lineStyle = nil;
barPlot1.cornerRadius = 1.0f;
barPlot1.dataSource = self;
CPTColor *color1 = [CPTColor colorWithComponentRed:255.0/255.0 green:160.0/255.0 blue:47.0/255.0 alpha:1.0];
barPlot1.fill = [CPTFill fillWithColor:color1];
barPlot.identifier = #"LTM";
[self.barChart addPlot:barPlot toPlotSpace:plotSpace ];
barPlot1.identifier = #"NEW";
[self.barChart addPlot:barPlot1 toPlotSpace:plotSpace ];
}
With plots configured this way, the plot space setup is simpler:
plotSpace = (CPTXYPlotSpace *) self.barChart.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0) length:CPTDecimalFromDouble(450.0)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(-0.5) length:CPTDecimalFromDouble(1.0)];
I'm assuming you want a single horizontal bar built using two plots to get the different colors. If so, here is how I would write the datasource methods:
// datasource
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
return 1;
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSDictionary *sample = nil;
if([plot.identifier isEqual:#"LTM"])
{
sample = self.sampleArray[0];
}
else if([plot.identifier isEqual:#"NEW"])
{
sample = self.sampleArray[1];
}
switch (fieldEnum) {
case CPTBarPlotFieldBarLocation:
return #(index);
break;
case CPTBarPlotFieldBarTip:
return sample[Y_VAL];
break;
}
return nil;
}
Note the plot field identifiers are bar plot location and tip rather than the scatter plot enum values. With a horizontal bar plot, the location values are along the y-axis and the tip and base are on the x-axis.

Related

core Plot:Decrease distance between bar in bar graph ios

i am plotting 2 data set on bar graph and i want them to be like histogram ,so can anyone guide me to the solution asap.
i have 2 datasets(google and Apple)in 1 datasets.I am not getting any spaces between bars of 1 dataset but i am getting too much spacing between 2 datasets.
here is my code,
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
return [[[CPDStockPriceStore sharedInstance] datesInWeek] count];
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
if ((fieldEnum == CPTBarPlotFieldBarTip) && (index < [[[CPDStockPriceStore sharedInstance] datesInWeek] count]))
{
if ([plot.identifier isEqual:CPDTickerSymbolAAPL])
{
NSLog(#"apple index:%#",[[[CPDStockPriceStore sharedInstance] weeklyPrices:CPDTickerSymbolAAPL] objectAtIndex:index]);
return [[[CPDStockPriceStore sharedInstance] weeklyPrices:CPDTickerSymbolAAPL] objectAtIndex:index];
}
else if ([plot.identifier isEqual:CPDTickerSymbolGOOG])
{
NSLog(#"google index:%#",[[[CPDStockPriceStore sharedInstance] weeklyPrices:CPDTickerSymbolGOOG] objectAtIndex:index]);
return [[[CPDStockPriceStore sharedInstance] weeklyPrices:CPDTickerSymbolGOOG] objectAtIndex:index];
}
}
return [NSDecimalNumber numberWithUnsignedInteger:index];
-(void)viewDidLoad
{
[super viewDidLoad];
[self initPlot];
}
#pragma mark - Chart behavior
-(void)initPlot
{
self.hostView.allowPinchScaling = YES;
[self configureGraph];
[self configurePlots];
[self configureAxes];
graphData=[[CPDStockPriceStore sharedInstance] weeklyPrices:CPDTickerSymbolAAPL];
NSLog(#"google:%#",graphData);
}
-(void)configureGraph {
// 1 - Create the graph
CPTGraph *graph = [[CPTXYGraph alloc] initWithFrame:self.hostView.bounds];
graph.plotAreaFrame.masksToBorder = NO;
self.hostView.hostedGraph = graph;
// 2 - Configure the graph
[graph applyTheme:[CPTTheme themeNamed:kCPTPlainWhiteTheme]];
graph.paddingBottom = 30.0f;
graph.paddingLeft = 30.0f;
graph.paddingTop = -1.0f;
graph.paddingRight = -5.0f;
CGFloat xMin = 0.0f;
CGFloat xMax = [[[CPDStockPriceStore sharedInstance] datesInWeek] count];
CGFloat yMin = 0.0f;
CGFloat yMax = 800.0f; // should determine dynamically based on max price
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(xMin) length:CPTDecimalFromFloat(xMax)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(yMin) length:CPTDecimalFromFloat(yMax)];
}
-(void)configurePlots
{
// 1 - Set up the three plots
self.aaplPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor colorWithComponentRed:105.0f/255.0f green:252.0f/255.0f blue:144.0f/255.0f alpha:1.0] horizontalBars:NO];
self.aaplPlot.identifier = CPDTickerSymbolAAPL;
self.googPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor colorWithComponentRed:103.0f/255.0f green:103.0f/255.0f blue:103.0f/255.0f alpha:1.0] horizontalBars:NO];
self.googPlot.identifier = CPDTickerSymbolGOOG;
// 2 - Set up line style
CPTMutableLineStyle *barLineStyle = [[CPTMutableLineStyle alloc] init];
barLineStyle.lineColor = [CPTColor lightGrayColor];
barLineStyle.lineWidth = 0.5;
// 3 - Add plots to graph
CPTGraph *graph = self.hostView.hostedGraph;
CGFloat barX = CPDBarInitialX;
NSArray *plots =[NSArray arrayWithObjects:self.aaplPlot, self.googPlot, nil];
for (CPTBarPlot *plot in plots)
{
plot.dataSource = self;
plot.delegate = self;
plot.barWidth = CPTDecimalFromDouble(CPDBarWidth);
plot.barOffset = CPTDecimalFromDouble(barX);
plot.lineStyle = barLineStyle;
[graph addPlot:plot toPlotSpace:graph.defaultPlotSpace];
barX += CPDBarWidth;
}
}
-(void)configureAxes
{
// 1 - Configure styles
CPTMutableTextStyle *axisTitleStyle = [CPTMutableTextStyle textStyle];
axisTitleStyle.color = [CPTColor whiteColor];
axisTitleStyle.fontName = #"Helvetica-Bold";
axisTitleStyle.fontSize = 12.0f;
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 2.0f;
axisLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:1];
// 2 - Get the graph's axis set
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) self.hostView.hostedGraph.axisSet;
// 3 - Configure the x-axis
axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyNone;
axisSet.xAxis.title = #"Days of Week (Mon - Fri)";
axisSet.xAxis.titleTextStyle = axisTitleStyle;
axisSet.xAxis.titleOffset = 10.0f;
axisSet.xAxis.axisLineStyle = axisLineStyle;
// 4 - Configure the y-axis
axisSet.yAxis.labelingPolicy = CPTAxisLabelingPolicyNone;
axisSet.yAxis.title = #"Price";
axisSet.yAxis.titleTextStyle = axisTitleStyle;
axisSet.yAxis.titleOffset = 5.0f;
axisSet.yAxis.axisLineStyle = axisLineStyle;
}
-(void)hideAnnotation:(CPTGraph *)graph
{
if ((graph.plotAreaFrame.plotArea) && (self.priceAnnotation)) {
[graph.plotAreaFrame.plotArea removeAnnotation:self.priceAnnotation];
self.priceAnnotation = nil;
}
}
With CPDBarWidth = 0.15, two bars take up only 30% of the space between successive bar locations. Increase the barWidth to reduce the space between neighboring bars.

Objective C Core Plot Fixed Y Axis for Bar Graph

I'm trying to create a class that I can use to create bar, pie, and line graphs using the Core Plot library for an iOS application. I want to create some standardization in this class so that I only have to change a few options for each view controller that inherits my graph class. I have the pie graphs working the way I want, but I'm having issues with the bar graphs. I want a bar graph that is horizontal and where the Y axis is fixed for each plot based on how many plots there are.
Code:
enum
{
PieGraph = 0,
LineGraph,
BarGraph
};
Graph.h:
#import "CorePlot-CocoaTouch.h"
#import "BaseViewController.h"
CPTGraphHostingView *hostView;
CPTTheme *selectedTheme;
/*************** graphing options *******************/
int graphType;
int fillPercentage;
CGFloat xMax;
CGFloat yMax;
NSString *graphTitle;
NSString *xAxisTitle;
NSString *yAxisTitle;
BOOL graphOnBottom;
#interface Graph : BaseViewController<CPTPlotDataSource, UIActionSheetDelegate, CPTBarPlotDataSource, CPTBarPlotDelegate>
/*************** Methods *****************/
// graphing methods
-(void)initPlot;
-(void)configureHost;
-(void)configureGraph;
-(void)configureChart;
-(void)configureLegend;
-(void)configurePlots;
-(void)configureAxes;
#end
Graph.m:
#import "Graph.h"
#implementation Graph
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self initPlot];
}
/************************ Methods *************************/
// initialize the entire graph plot
-(void)initPlot
{
[self configureHost];
[self configureGraph];
if (graphType == PieGraph)
{
[self configureChart];
[self configureLegend];
}
else if (graphType == BarGraph)
{
[self configurePlots];
[self configureAxes];
}
}
// configure the host
-(void)configureHost
{
CGRect parentRect = self.view.bounds;
int maxHeight = (parentRect.size.height - 55);
int height = (maxHeight - ((100 - fillPercentage) * maxHeight / 100));
int yPosition;
if (graphOnBottom) yPosition = (maxHeight - height + 55);
else yPosition = 55;
parentRect = CGRectMake(parentRect.origin.x, yPosition, parentRect.size.width, height);
hostView = [(CPTGraphHostingView *) [CPTGraphHostingView alloc] initWithFrame:parentRect];
hostView.allowPinchScaling = NO;
[self.view addSubview:hostView];
}
// configure the graph
-(void)configureGraph
{
CPTGraph *graph = [[CPTXYGraph alloc] initWithFrame:hostView.bounds];
hostView.hostedGraph = graph;
if (graphType == PieGraph)
{
graph.paddingLeft = 0.0f;
graph.paddingTop = 0.0f;
graph.paddingRight = 0.0f;
graph.paddingBottom = 0.0f;
graph.axisSet = nil;
}
else if (graphType == BarGraph)
{
graph.plotAreaFrame.masksToBorder = NO;
if ([xAxisTitle isEqualToString:#""]) graph.paddingBottom = 0.0f;
else graph.paddingBottom = 30.0f;
if ([yAxisTitle isEqualToString:#""]) graph.paddingLeft = 0.0f;
else graph.paddingLeft = 30.0f;
graph.paddingTop = 0.0f;
graph.paddingRight = 0.0f;
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromCGFloat(0.0f) length:CPTDecimalFromCGFloat(xMax)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromCGFloat(0.0f) length:CPTDecimalFromCGFloat(yMax)];
}
else if (graphType == LineGraph)
{
}
CPTMutableTextStyle *textStyle = [CPTMutableTextStyle textStyle];
textStyle.color = [CPTColor blackColor];
textStyle.fontName = #"Helvetica-Bold";
textStyle.fontSize = 12.0f;
graph.title = graphTitle;
graph.titleTextStyle = textStyle;
graph.titlePlotAreaFrameAnchor = CPTRectAnchorTop;
selectedTheme = [CPTTheme themeNamed:kCPTPlainWhiteTheme];
[graph applyTheme:selectedTheme];
}
// configure the chart
-(void)configureChart
{
CPTGraph *graph = hostView.hostedGraph;
CPTGradient *overlayGradient = [[CPTGradient alloc] init];
overlayGradient.gradientType = CPTGradientTypeRadial;
overlayGradient = [overlayGradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.0] atPosition:0.9];
overlayGradient = [overlayGradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.4] atPosition:1.0];
CPTPieChart *pieChart = [[CPTPieChart alloc] init];
pieChart.dataSource = self;
pieChart.delegate = self;
pieChart.pieRadius = (hostView.bounds.size.height * 0.7) / 2.5;
pieChart.identifier = graph.title;
pieChart.startAngle = M_PI_4;
pieChart.sliceDirection = CPTPieDirectionClockwise;
pieChart.overlayFill = [CPTFill fillWithGradient:overlayGradient];
[graph addPlot:pieChart];
}
// configure plots
-(void)configurePlots
{
CPTGraph *graph = hostView.hostedGraph;
if (graphType == BarGraph)
{
CPTMutableLineStyle *barLineStyle = [[CPTMutableLineStyle alloc] init];
barLineStyle.lineColor = [CPTColor lightGrayColor];
barLineStyle.lineWidth = 0.5;
CPTBarPlot *bar = [CPTBarPlot tubularBarPlotWithColor:[CPTColor redColor] horizontalBars:YES];
bar.dataSource = self;
bar.delegate = self;
bar.barWidth = CPTDecimalFromFloat(2.5f);
bar.barOffset = CPTDecimalFromFloat(2.5f);
bar.identifier = #"redBar";
bar.lineStyle = barLineStyle;
CPTBarPlot *bar2 = [CPTBarPlot tubularBarPlotWithColor:[CPTColor greenColor] horizontalBars:YES];
bar2.dataSource = self;
bar2.delegate = self;
bar2.barWidth = CPTDecimalFromFloat(2.5f);
bar2.barOffset = CPTDecimalFromFloat(2.5f);
bar2.identifier = #"greenBar";
bar2.lineStyle = barLineStyle;
[graph addPlot:bar toPlotSpace:graph.defaultPlotSpace];
[graph addPlot:bar2 toPlotSpace:graph.defaultPlotSpace];
}
else if (graphType == LineGraph)
{
}
}
// configure axes
-(void)configureAxes
{
if (graphType == BarGraph)
{
CPTMutableTextStyle *axisTitleStyle = [CPTMutableTextStyle textStyle];
axisTitleStyle.color = [CPTColor blackColor];
axisTitleStyle.fontName = #"Helvetica-Bold";
axisTitleStyle.fontSize = 12.0f;
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 2.0f;
axisLineStyle.lineColor = [[CPTColor blackColor] colorWithAlphaComponent:1];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) hostView.hostedGraph.axisSet;
axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyNone;
axisSet.xAxis.title = xAxisTitle;
axisSet.xAxis.titleTextStyle = axisTitleStyle;
axisSet.xAxis.titleOffset = 5.0f;
axisSet.xAxis.axisLineStyle = axisLineStyle;
axisSet.yAxis.labelingPolicy = CPTAxisLabelingPolicyNone;
axisSet.yAxis.title = yAxisTitle;
axisSet.yAxis.titleTextStyle = axisTitleStyle;
axisSet.yAxis.titleOffset = 5.0f;
axisSet.yAxis.axisLineStyle = axisLineStyle;
}
else if (graphType == LineGraph)
{
}
}
// configure the legend
-(void)configureLegend
{
CPTGraph *graph = hostView.hostedGraph;
CPTLegend *legend = [CPTLegend legendWithGraph:graph];
legend.numberOfColumns = 1;
legend.fill = [CPTFill fillWithColor:[CPTColor whiteColor]];
legend.borderLineStyle = [CPTLineStyle lineStyle];
legend.cornerRadius = 5.0;
graph.legend = legend;
graph.legendAnchor = CPTRectAnchorBottomLeft;
//CGFloat legendPadding = -(self.view.bounds.size.width / 8);
graph.legendDisplacement = CGPointMake(3.0, 3.0);
}
#end
And finally the view controller class I am testing all of this on:
TestView.h:
#import "Graph.h"
NSArray *channel;
int offline;
int online;
#interface TestView : Graph
/*************** Methods *****************/
// back button
- (IBAction)backButtonClicked:(id)sender;
// handle view load
-(void) handleViewLoad;
// set arrays
-(void)setArrays;
#end
TestView.m:
#import "TestView.h"
#interface TestView ()
#end
#implementation TestView
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self handleViewLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)backButtonClicked:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
/*************** graph things ****************/
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
return 1;
}
-(NSNumber*)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)idx
{
int returnVal = 0;
NSLog([NSString stringWithFormat:#"idx: %d", idx]);
/*switch (idx)
{
case 0:
for (int x = 0; x < [channel count]; x++)
{
if ([channel[x] integerValue] == 20) returnVal ++;
}
offline = returnVal;
return [NSNumber numberWithInt:returnVal];
break;
case 1:
for (int x = 0; x < [channel count]; x++)
{
if ([channel[x] integerValue] != 20) returnVal ++;
}
online = returnVal;
return [NSNumber numberWithInt:returnVal];
break;
}*/
if ([plot.identifier isEqual:#"greenBar"])
{
for (int x = 0; x < [channel count]; x++)
{
if ([channel[x] integerValue] != 20) returnVal ++;
}
online = returnVal;
return [NSNumber numberWithInt:returnVal];
}
else if ([plot.identifier isEqual:#"redBar"])
{
for (int x = 0; x < [channel count]; x++)
{
if ([channel[x] integerValue] == 20) returnVal ++;
}
offline = returnVal;
return [NSNumber numberWithInt:returnVal];
}
return 0;
}
-(CPTLayer*)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)idx
{
/*switch (idx)
{
case 0:
return [[CPTTextLayer alloc] initWithText:[NSString stringWithFormat:#"Offline: %d", offline]];
break;
default:
return [[CPTTextLayer alloc] initWithText:[NSString stringWithFormat:#"Online: %d", online]];
break;
}*/
if ([plot.identifier isEqual:#"greenBar"])
{
return [[CPTTextLayer alloc] initWithText:[NSString stringWithFormat:#"Online: %d", online]];
}
else if ([plot.identifier isEqual:#"redBar"])
{
return [[CPTTextLayer alloc] initWithText:[NSString stringWithFormat:#"Offline: %d", offline]];
}
return nil;
}
-(NSString*)legendTitleForPieChart:(CPTPieChart*)pieChart recordIndex:(NSUInteger)idx
{
switch (idx)
{
case 0:
return #"Offline";
break;
default:
return #"Online";
break;
}
return #"";
}
// handle view load
-(void)handleViewLoad
{
session = [BaseViewController getSession];
[self setArrays];
graphType = BarGraph;
fillPercentage = 50;
graphOnBottom = NO;
graphTitle = #"Coordinators Online/Offline";
xAxisTitle = #"Number of Devices";
yAxisTitle = #"";
xMax = (CGFloat)([channel count] + ([channel count] * 0.30f));
yMax = (CGFloat)([channel count] + ([channel count] * 0.30f));
[self initPlot];
}
// set arrays
-(void)setArrays
{
channel = [Json extractCoordinatorChannel:session];
}
#end
Here are some examples of what my graphs look like:
As you can see, the issue is that both the x and y axes are changing based on the value. I need only the x axis to change, and the y axis to be fixed for each plot.
The datasource should check the fieldEnum parameter to see which data field (bar location or bar tip) is being requested.
switch ( fieldEnum ) {
case CPTBarPlotFieldBarLocation:
returnVal = /* y value */;
break;
case CPTBarPlotFieldBarTip:
returnVal = /* x value */;
break;
default:
break;
}

Correct way to set bar width in coreplot?

My bar heights seem to shrink and grow as more data is added to my graph. Is it possible to fix it so that it stays the same (say 10px tall) each time?
Here's what I think is the relevant code:
#define kBarHeight 10
-(void)configurePlots {
CPTBarPlot *countryPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor colorWithComponentRed:19/255.0 green:221/255.0 blue:187/255.0 alpha:1] horizontalBars:YES];
countryPlot.identifier = #"CountryPlot";
CPTBarPlot *timeZonePlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor colorWithComponentRed:30/255.0 green:33/255.0 blue:36/255.0 alpha:1] horizontalBars:YES];
timeZonePlot.identifier = #"TimeZonePlot";
CPTMutableLineStyle *barLineStyle = [[CPTMutableLineStyle alloc] init];
barLineStyle.lineColor = [CPTColor lightGrayColor];
barLineStyle.lineWidth = 0.5;
CPTGraph *countryGraph = self.countryGraph.hostedGraph;
CPTGraph *timeZoneGraph = self.timeZoneGraph.hostedGraph;
countryPlot.dataSource = self;
countryPlot.delegate = self;
countryPlot.barWidth = CPTDecimalFromDouble(kBarHeight);
countryPlot.baseValue = CPTDecimalFromString(#"0");
countryPlot.lineStyle = barLineStyle;
countryPlot.barOffset = CPTDecimalFromFloat(0.25f);
countryPlot.labelOffset = -10.0;
[countryGraph addPlot:countryPlot toPlotSpace:countryGraph.defaultPlotSpace];
timeZonePlot.dataSource = self;
timeZonePlot.delegate = self;
timeZonePlot.baseValue = CPTDecimalFromString(#"0");
timeZonePlot.barWidth = CPTDecimalFromDouble(kBarHeight);
timeZonePlot.lineStyle = barLineStyle;
timeZonePlot.labelOffset = -10.0;
timeZonePlot.barOffset = CPTDecimalFromFloat(0.25f);
[timeZoneGraph addPlot:timeZonePlot toPlotSpace:timeZoneGraph.defaultPlotSpace];
}
//Setting the ranges - possibly the incorrect part?
CPTXYPlotSpace *countryPlotSpace = (CPTXYPlotSpace *) countryGraph.defaultPlotSpace;
CSGeoStat *stat = (CSGeoStat *) self.countryData[self.countryData.count-1];
countryPlotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0) length:CPTDecimalFromFloat(stat.count * 1.1)];
countryPlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(-20.0) length:CPTDecimalFromFloat([self.countryData count]*kBarHeight*1.5)];
CPTXYPlotSpace *timeZonePlotSpace = (CPTXYPlotSpace *) timeZoneGraph.defaultPlotSpace;
stat = (CSGeoStat *) self.timeZoneData[self.timeZoneData.count-1];
timeZonePlotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0) length:CPTDecimalFromFloat(stat.count * 1.1)];
timeZonePlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(-20.0) length:CPTDecimalFromFloat([self.timeZoneData count]*kBarHeight*1.5)];
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
NSNumber *num = #0;
//Bars are horizontal, too!
switch (fieldEnum) {
case CPTBarPlotFieldBarTip:
if ([plot.identifier isEqual:#"CountryPlot"]) {
num = [NSNumber numberWithInteger:[self.countryData[index] count]];
} else {
num = [NSNumber numberWithInteger:[self.timeZoneData[index] count]];
}
break;
default:
num = [NSNumber numberWithInteger:(index*(kBarHeight+3)) + kBarHeight/2 ];
break;
}
return num;
}
Try this:
countryPlot.barWidthsAreInViewCoordinates = YES;
countryPlot.barWidths = 10.0;
The first line tells Core Plot to use view coordinates rather than plot coordinates.

Any special considerations for using horizontal bar chart bars

I've been trying to make a horizontal bar chart using CorePlot in iOS.
I'm trying to find documentation but I cant seem to find anything good for this area. What else do I need to change if I make the bars horizontal? Is it simply a display things, or do I need to change data too?
These would be
xRange, yRange
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index implementation
Here's what I have so far...
#pragma mark -
#pragma mark - Chart behavior
-(void)initPlot {
[self configureGraph];
[self configurePlots];
[self configureAxes];
}
-(void)configureGraph {
CPTGraph *countryGraph = [[CPTXYGraph alloc] initWithFrame:self.countryGraph.bounds];
CPTGraph *timeZoneGraph = [[CPTXYGraph alloc] initWithFrame:self.timeZoneGraph.bounds];
countryGraph.plotAreaFrame.masksToBorder = NO;
timeZoneGraph.plotAreaFrame.masksToBorder = NO;
self.countryGraph.hostedGraph = countryGraph;
self.timeZoneGraph.hostedGraph = timeZoneGraph;
CPTXYPlotSpace *countryPlotSpace = (CPTXYPlotSpace *) countryGraph.defaultPlotSpace;
countryPlotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0) length:CPTDecimalFromFloat([self.countryData[0] count])];
countryPlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0) length:CPTDecimalFromFloat([self.countryData count]*50)];
CPTXYPlotSpace *timeZonePlotSpace = (CPTXYPlotSpace *) timeZoneGraph.defaultPlotSpace;
timeZonePlotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0) length:CPTDecimalFromFloat([self.timeZoneData[0] count])];
timeZonePlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0) length:CPTDecimalFromFloat([self.timeZoneData count]*50)];
}
-(void)configurePlots {
CPTBarPlot *countryPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor colorWithComponentRed:19/255.0 green:221/255.0 blue:187/255.0 alpha:1] horizontalBars:YES];
countryPlot.identifier = #"CountryPlot";
CPTBarPlot *timeZonePlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor colorWithComponentRed:30/255.0 green:33/255.0 blue:36/255.0 alpha:1] horizontalBars:YES];
timeZonePlot.identifier = #"TimeZonePlot";
CPTMutableLineStyle *barLineStyle = [[CPTMutableLineStyle alloc] init];
barLineStyle.lineColor = [CPTColor whiteColor];
barLineStyle.lineWidth = 1.0;
CPTGraph *countryGraph = self.countryGraph.hostedGraph;
CPTGraph *timeZoneGraph = self.timeZoneGraph.hostedGraph;
countryPlot.dataSource = self;
countryPlot.delegate = self;
countryPlot.barWidth = CPTDecimalFromDouble(20);
countryPlot.baseValue = CPTDecimalFromString(#"0");
countryPlot.lineStyle = barLineStyle;
countryPlot.barOffset = CPTDecimalFromFloat(0.25f);
[countryGraph addPlot:countryPlot toPlotSpace:countryGraph.defaultPlotSpace];
timeZonePlot.dataSource = self;
timeZonePlot.delegate = self;
timeZonePlot.baseValue = CPTDecimalFromString(#"0");
timeZonePlot.barWidth = CPTDecimalFromDouble(20);
timeZonePlot.lineStyle = barLineStyle;
timeZonePlot.barOffset = CPTDecimalFromFloat(0.25f);
[timeZoneGraph addPlot:timeZonePlot toPlotSpace:timeZoneGraph.defaultPlotSpace];
}
-(void)configureAxes {
CPTMutableTextStyle *axisTitleStyle = [CPTMutableTextStyle textStyle];
axisTitleStyle.color = [CPTColor whiteColor];
axisTitleStyle.fontName = #"Helvetica-Bold";
axisTitleStyle.fontSize = 12.0f;
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 2.0f;
axisLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:1];
CPTXYAxisSet *countryAxisSet = (CPTXYAxisSet *) self.countryGraph.hostedGraph.axisSet;
CPTXYAxis *x = countryAxisSet.xAxis;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
x.axisLineStyle = axisLineStyle;
x.majorIntervalLength = CPTDecimalFromString(#"20");
CPTXYAxis *y = countryAxisSet.yAxis;
y.labelingPolicy = CPTAxisLabelingPolicyNone;
y.axisLineStyle = axisLineStyle;
y.majorIntervalLength = CPTDecimalFromString(#"50");
CPTXYAxisSet *timeZoneAxisSet = (CPTXYAxisSet *) self.timeZoneGraph.hostedGraph.axisSet;
CPTXYAxis *x2 = timeZoneAxisSet.xAxis;
x2.labelingPolicy = CPTAxisLabelingPolicyNone;
x2.axisLineStyle = axisLineStyle;
x2.majorIntervalLength = CPTDecimalFromString(#"20");
CPTXYAxis *y2 = timeZoneAxisSet.yAxis;
y2.labelingPolicy = CPTAxisLabelingPolicyNone;
y2.axisLineStyle = axisLineStyle;
y2.majorIntervalLength = CPTDecimalFromString(#"50");
}
#pragma mark - CPTPlotDataSource methods
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot {
NSUInteger num = 0;
if ([plot.identifier isEqual:#"CountryPlot"]) {
num = self.countryData.count;
} else {
num = self.timeZoneData.count;
}
return num;
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
NSNumber *num = #0;
switch (fieldEnum) {
case CPTBarPlotFieldBarTip:
if ([plot.identifier isEqual:#"CountryPlot"]) {
num = [NSNumber numberWithInteger:[self.countryData[index] count]];
} else {
num = [NSNumber numberWithInteger:[self.timeZoneData[index] count]];
}
break;
default:
num = [NSNumber numberWithInteger:index];
break;
}
return num;
}
Here's what it makes
And I'd prefer that the bars would be stacked up on top of each other with a small separation.... so what have I missed?
Set barsAreHorizontal to YES on the bar plot to make horizontal bars. Everything else is the same except the bar locations are now on the y-axis and the bar tip and base values are on the x-axis.

Enable x-Axis (Horizontal) scroll in coreplot

I am using code from this link . And currently If I have 50 bar columns or 150 bar columns then the labels below is compressed and I would like to have horizontal scroll on x-Axis instead of having compressed x-Axis.
I have tried this:
plotSpace.xRange = CPTPlotRangeplotRangeWithLocation:CPTDecimalFromInt(-1)length:CPTDecimalFromInt(50)];
Attaching code from the file :
#import "GraphView.h"
#implementation GraphView
- (void)generateData
{
NSMutableDictionary *dataTemp = [[NSMutableDictionary alloc] init];
//Array containing all the dates that will be displayed on the X axis
dates = [NSArray arrayWithObjects:#"2012-05-01", #"2012-05-02", #"2012-05-03",
#"2012-05-04", #"2012-05-05", #"2012-05-06", #"2012-05-07", nil];
//Dictionary containing the name of the two sets and their associated color
//used for the demo
sets = [NSDictionary dictionaryWithObjectsAndKeys:[UIColor blueColor], #"Plot 1",
[UIColor redColor], #"Plot 2",
[UIColor greenColor], #"Plot 3", nil];
//Generate random data for each set of data that will be displayed for each day
//Numbers between 1 and 10
for (NSString *date in dates) {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSString *set in sets) {
NSNumber *num = [NSNumber numberWithInt:arc4random_uniform(10)+1];
[dict setObject:num forKey:set];
}
[dataTemp setObject:dict forKey:date];
}
data = [dataTemp copy];
[dataTemp release];
NSLog(#"%#", data);
}
- (void)generateLayout
{
//Create graph from theme
graph = [[CPTXYGraph alloc] initWithFrame:CGRectZero];
[graph applyTheme:[CPTTheme themeNamed:kCPTStocksTheme]];
self.hostedGraph = graph;
graph.plotAreaFrame.masksToBorder = NO;
graph.paddingLeft = 0.0f;
graph.paddingTop = 0.0f;
graph.paddingRight = 0.0f;
graph.paddingBottom = 0.0f;
CPTMutableLineStyle *borderLineStyle = [CPTMutableLineStyle lineStyle];
borderLineStyle.lineColor = [CPTColor whiteColor];
borderLineStyle.lineWidth = 2.0f;
graph.plotAreaFrame.borderLineStyle = borderLineStyle;
graph.plotAreaFrame.paddingTop = 10.0;
graph.plotAreaFrame.paddingRight = 10.0;
graph.plotAreaFrame.paddingBottom = 80.0;
graph.plotAreaFrame.paddingLeft = 70.0;
//Add plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.delegate = self;
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0)
length:CPTDecimalFromInt(10 * sets.count)];
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(-1)
length:CPTDecimalFromInt(8)];
//Grid line styles
CPTMutableLineStyle *majorGridLineStyle = [CPTMutableLineStyle lineStyle];
majorGridLineStyle.lineWidth = 0.75;
majorGridLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:0.1];
CPTMutableLineStyle *minorGridLineStyle = [CPTMutableLineStyle lineStyle];
minorGridLineStyle.lineWidth = 0.25;
minorGridLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:0.1];
//Axes
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
//X axis
CPTXYAxis *x = axisSet.xAxis;
x.orthogonalCoordinateDecimal = CPTDecimalFromInt(0);
x.majorIntervalLength = CPTDecimalFromInt(1);
x.minorTicksPerInterval = 0;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
x.majorGridLineStyle = majorGridLineStyle;
x.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0];
//X labels
int labelLocations = 0;
NSMutableArray *customXLabels = [NSMutableArray array];
for (NSString *day in dates) {
CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText:day textStyle:x.labelTextStyle];
newLabel.tickLocation = [[NSNumber numberWithInt:labelLocations] decimalValue];
newLabel.offset = x.labelOffset + x.majorTickLength;
newLabel.rotation = M_PI / 4;
[customXLabels addObject:newLabel];
labelLocations++;
[newLabel release];
}
x.axisLabels = [NSSet setWithArray:customXLabels];
//Y axis
CPTXYAxis *y = axisSet.yAxis;
y.title = #"Value";
y.titleOffset = 50.0f;
y.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
y.majorGridLineStyle = majorGridLineStyle;
y.minorGridLineStyle = minorGridLineStyle;
y.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0];
//Create a bar line style
CPTMutableLineStyle *barLineStyle = [[[CPTMutableLineStyle alloc] init] autorelease];
barLineStyle.lineWidth = 1.0;
barLineStyle.lineColor = [CPTColor whiteColor];
CPTMutableTextStyle *whiteTextStyle = [CPTMutableTextStyle textStyle];
whiteTextStyle.color = [CPTColor whiteColor];
//Plot
BOOL firstPlot = YES;
for (NSString *set in [[sets allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)]) {
CPTBarPlot *plot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor blueColor] horizontalBars:NO];
plot.lineStyle = barLineStyle;
CGColorRef color = ((UIColor *)[sets objectForKey:set]).CGColor;
plot.fill = [CPTFill fillWithColor:[CPTColor colorWithCGColor:color]];
if (firstPlot) {
plot.barBasesVary = NO;
firstPlot = NO;
} else {
plot.barBasesVary = YES;
}
plot.barWidth = CPTDecimalFromFloat(0.8f);
plot.barsAreHorizontal = NO;
plot.dataSource = self;
plot.identifier = set;
[graph addPlot:plot toPlotSpace:plotSpace];
}
//Add legend
CPTLegend *theLegend = [CPTLegend legendWithGraph:graph];
theLegend.numberOfRows = sets.count;
theLegend.fill = [CPTFill fillWithColor:[CPTColor colorWithGenericGray:0.15]];
theLegend.borderLineStyle = barLineStyle;
theLegend.cornerRadius = 10.0;
theLegend.swatchSize = CGSizeMake(15.0, 15.0);
whiteTextStyle.fontSize = 13.0;
theLegend.textStyle = whiteTextStyle;
theLegend.rowMargin = 5.0;
theLegend.paddingLeft = 10.0;
theLegend.paddingTop = 10.0;
theLegend.paddingRight = 10.0;
theLegend.paddingBottom = 10.0;
graph.legend = theLegend;
graph.legendAnchor = CPTRectAnchorTopLeft;
graph.legendDisplacement = CGPointMake(80.0, -10.0);
}
- (void)createGraph
{
//Generate data
[self generateData];
//Generate layout
[self generateLayout];
}
- (void)dealloc
{
[data release];
[super dealloc];
}
#pragma mark - CPTPlotDataSource methods
- (NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
return dates.count;
}
- (double)doubleForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
double num = NAN;
//X Value
if (fieldEnum == 0) {
num = index;
}
else {
double offset = 0;
if (((CPTBarPlot *)plot).barBasesVary) {
for (NSString *set in [[sets allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)]) {
if ([plot.identifier isEqual:set]) {
break;
}
offset += [[[data objectForKey:[dates objectAtIndex:index]] objectForKey:set] doubleValue];
}
}
//Y Value
if (fieldEnum == 1) {
num = [[[data objectForKey:[dates objectAtIndex:index]] objectForKey:plot.identifier] doubleValue] + offset;
}
//Offset for stacked bar
else {
num = offset;
}
}
//NSLog(#"%# - %d - %d - %f", plot.identifier, index, fieldEnum, num);
return num;
}
#pragma mark - CPTBarPlotDelegate methods
-(void)barPlot:(CPTBarPlot *)plot barWasSelectedAtRecordIndex:(NSUInteger)index {
NSLog(#"barWasSelectedAtRecordIndex %d", index);
}
#end
to get scrolling you need to set the globalXRange on the plotspace to be the entire range, and set the xRange will be the visible area.
for example a globalXRange of 0-150, and a xRange of 0-50. then you could scroll up to view the 51-150 range.

Resources