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.
Related
I am developing a project using Core-Plot with Objective-C. The client asks to create a line chart (using Scatter Plot for this) where plots the number of ocurrencies x the time.
Well, after study for almost a week, this isn't working. My dots aren't connected and I don't know why.
This blue line should've been connected, since it is one plot.
Here is my code:
-(void)renderInLayer:(CPTGraphHostingView *)layerHostingView withTheme:(CPTTheme *)theme animated:(BOOL)animated{
CPTGraph *graph = [[CPTXYGraph alloc] initWithFrame:bounds];
[self addGraph:graph toHostingView:layerHostingView];
[self applyTheme:theme toGraph:graph withDefault:[CPTTheme themeNamed:kCPTDarkGradientTheme]];
graph.paddingTop = 20.0;
graph.paddingRight = 20.0;
graph.paddingLeft = 20.0;
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.allowsUserInteraction = YES;
plotSpace.delegate = self;
CPTMutableLineStyle *axesLineStyle = [CPTMutableLineStyle lineStyle];
axesLineStyle.lineWidth = 1.0f;
axesLineStyle.miterLimit = 1.0f;
axesLineStyle.lineColor = [CPTColor grayColor];
CPTTextStyle *labelTextStyle = [CPTTextStyle textStyleWithAttributes:#{ NSForegroundColorAttributeName: BoardGraphValueColor, NSFontAttributeName: BoardGraphValueFont}];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
NSNumberFormatter * axisFormat = [[NSNumberFormatter alloc] init];
[axisFormat setNumberStyle:NSNumberFormatterNoStyle];
CPTXYAxis *x = axisSet.xAxis;{
x.visibleRange = [CPTPlotRange plotRangeWithLocation:#(-1.0) length:#(100)];
x.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
x.majorIntervalLength = #2;
x.minorTicksPerInterval = 1;
x.majorTickLineStyle = axesLineStyle;
x.minorTickLineStyle = axesLineStyle;
x.axisLineStyle = axesLineStyle;
x.plotSpace = plotSpace;
x.labelTextStyle = labelTextStyle;
x.labelFormatter = axisFormat;
x.labelOffset = 5.0;
}
CPTXYAxis *y = axisSet.yAxis;{
y.visibleRange = [CPTPlotRange plotRangeWithLocation:#(-1.0) length:#(200)];
y.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
y.majorIntervalLength = #30;
y.minorTicksPerInterval = 6;
y.majorTickLineStyle = axesLineStyle;
y.minorTickLineStyle = axesLineStyle;
y.axisLineStyle = axesLineStyle;
y.plotSpace = plotSpace;
y.labelTextStyle = labelTextStyle;
y.labelFormatter = axisFormat;
y.labelOffset = 5.0;
}
graph.axisSet.axes = #[x, y];
CPTMutableLineStyle *lineStyle = [[CPTMutableLineStyle alloc] init];
lineStyle.lineWidth = 2.0;
CPTScatterPlot *scatterLinePlot = [[CPTScatterPlot alloc] init];
scatterLinePlot.areaBaseValue = #(0.0);
scatterLinePlot.identifier = #(1);
scatterLinePlot.title = #"Title";
lineStyle.lineColor = [CPTColor blueColor];
scatterLinePlot.dataLineStyle = lineStyle;
scatterLinePlot.histogramOption = self.histogramOption;
scatterLinePlot.areaBaseValue = #(0);
scatterLinePlot.delegate = self;
scatterLinePlot.plotSymbolMarginForHitDetection = 5.0;
scatterLinePlot.dataSource = self;
[graph addPlot:scatterLinePlot];
CPTPlotRange *globalYRange = [CPTPlotRange plotRangeWithLocation:#0.0
length:#12.0];
plotSpace.globalYRange = globalYRange;
[plotSpace scaleToFitEntirePlots:[graph allPlots]];}
This is the code for create just one plot, but I need to create six. I did a loop but it is working that way too.
Here's the datasource:
-(NSUInteger)numberOfRecordsForPlot:(nonnull CPTPlot *)plot{
return [self.plotData objectAtIndex:0].count;}
-(NSNumber *)numberForPlot:(nonnull CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index{
NSNumber *num = nil;
NSString *key;
NSArray *currentDataPoint;
NSString *plotIdentifier = (NSString *)plot.identifier;
if ([plotIdentifier isEqual:#(1)]){
currentDataPoint = [self.plotData objectAtIndex:0];
} else if ([plotIdentifier isEqual:#(2)]){
currentDataPoint = [self.plotData objectAtIndex:1];
} else if ([plotIdentifier isEqual:#(3)]){
currentDataPoint = [self.plotData objectAtIndex:2];
} else if ([plotIdentifier isEqual:#(4)]){
currentDataPoint = [self.plotData objectAtIndex:3];
} else if ([plotIdentifier isEqual:#(5)]){
currentDataPoint = [self.plotData objectAtIndex:4];
} else if ([plotIdentifier isEqual:#(6)]){
currentDataPoint = [self.plotData objectAtIndex:5];
}
if (fieldEnum == CPTScatterPlotFieldX) {
return #(index);
} else if (fieldEnum == CPTScatterPlotFieldY) {
key = #"count";
int number = [[[currentDataPoint objectAtIndex:index] valueForKey:key] intValue];
NSLog(#"Y value for index %lu is %d", index, number);
num = [[currentDataPoint objectAtIndex:index] valueForKey:key];
return num;}
return num;
}
What am I doing wrong?
PS: Well, another bug is the color of the bar chart. Each of this should have a different color, but it doesn't work too. The colors provided is that for the legends.
Thanks in advance.
To change the bar color for each bar, implement the -barFillForBarPlot:recordIndex: method in the datasource and return the correct fill for each index. You can also set the border line style for each bar (e.g., to use a different color) with the -barLineStyleForBarPlot:recordIndex: datasource method.
It looks like the data line is getting clipped outside the visible area. Make sure the plot data is available from the datasource when you call -scaleToFitEntirePlots:.
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.
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.
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.
I have a chart with 2 bar plots (Example: A and B).
For each hour i have 2 bar plots.
When i set the legend, i get swatch and text for every hour and bar
plot.
Example: In my chart have 4 hours then my legend will be like this
A A A A
B B B B
And i only want
A B
Because on every hour, the bars means the same.
How can i do this ??
I have tried everything to make this happen but no success till now....
Bellow is my
// CPTLegend *theLegend = [CPTLegend legendWithGraph:barChart];
CPTLegend *theLegend = [CPTLegend legendWithPlots:[NSArray arrayWithObjects:[barChart plotAtIndex:0],[barChart plotAtIndex:1], nil]];
theLegend.numberOfRows = 1;
theLegend.numberOfColumns = 2;//[horas count] +1 / 2;
//theLegend.fill = [CPTFill fillWithColor:[CPTColor colorWithGenericGray:0.15]];
//theLegend.borderLineStyle = barLineStyle;
theLegend.cornerRadius = 10.0;
theLegend.swatchSize = CGSizeMake(15, 15);
//whiteTextStyle.fontSize = 16.0;
//theLegend.textStyle = whiteTextStyle;
theLegend.rowMargin = 10.0;
theLegend.paddingLeft = 12.0;
theLegend.paddingTop = 12.0;
theLegend.paddingRight = 12.0;
theLegend.paddingBottom = 12.0;
//theLegend.equalColumns = YES;
//theLegend.equalRows = YES;
theLegend.delegate = self;
barChart.legend = theLegend;
-(NSString *)legendTitleForBarPlot:(CPTBarPlot *)barPlot recordIndex:(NSUInteger)index{
if ( [barPlot.identifier isEqual:#"Embarque"] ) {
if (index == 0)
{
return #"Embarque";
}else {
return #"";
}
}else {
if (index == 0)
{
return #"Desembarque";
}else {
return #"";
}
}
}
-(BOOL)legend:(CPTLegend *)legend shouldDrawSwatchAtIndex:(NSUInteger)index forPlot:(CPTPlot *)plot inRect:(CGRect)rect inContext:(CGContextRef)context{
if (index == 0) {
return YES;
}else{
return NO;
}
}
Don't implement the -legendTitleForBarPlot:recordIndex: method unless you want a separate label for each bar. Use the title property to set a single legend title for the plot.
The -legend:shouldDrawSwatchAtIndex:forPlot:inRect:inContext: method is only needed if you want to change the default swatch drawing in some way.
-(void) exibirGraficoEmbarqueDescarga {
// Create barChart from theme
barChart = [[CPTXYGraph alloc] initWithFrame:CGRectZero];
CPTTheme *theme = [CPTTheme themeNamed:kCPTPlainWhiteTheme];
[barChart applyTheme:theme];
//CPTGraphHostingView *hostingView = (CPTGraphHostingView *)self.view;
//hostingView.hostedGraph = barChart;
barChart.delegate = self;
if (chartView == nil)
{
chartView = [[CPTGraphHostingView alloc] initWithFrame:CGRectMake(-15, 30, 350, 320)];
// chartView = [[CPTGraphHostingView alloc] initWithFrame:CGRectMake(0, 35, 510, 280)];
[self.view addSubview:chartView];
}
chartView.hostedGraph = barChart;
// Border
barChart.plotAreaFrame.borderLineStyle = nil;
barChart.plotAreaFrame.cornerRadius = 0.0f;
// Paddings
barChart.paddingLeft = 0.0f;
barChart.paddingRight = 0.0f;
barChart.paddingTop = 0.0f;
barChart.paddingBottom = 0.0f;
barChart.plotAreaFrame.paddingLeft = 70.0;
barChart.plotAreaFrame.paddingTop = 20.0;
barChart.plotAreaFrame.paddingRight = 20.0;
barChart.plotAreaFrame.paddingBottom = 80.0;
// Graph title
barChart.title = #"Embarque / Descarga";
CPTMutableTextStyle *textStyle = [CPTTextStyle textStyle];
textStyle.color = [CPTColor grayColor];
textStyle.fontSize = 16.0f;
textStyle.textAlignment = CPTTextAlignmentCenter;
barChart.titleTextStyle = textStyle;
barChart.titleDisplacement = CGPointMake(1.0f, -20.0f);
barChart.titlePlotAreaFrameAnchor = CPTRectAnchorTop;
// Add plot space for horizontal bar charts
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)barChart.defaultPlotSpace;
Apoio *apoio = [[Apoio alloc] init];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat([apoio retornaMaiorDadosGrafico:qtdEmb :qtdDesc])];
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat(16.0f)];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)barChart.axisSet;
CPTXYAxis *x = axisSet.xAxis;
CPTMutableLineStyle *marcacaoLineStyle = [CPTLineStyle lineStyle];
marcacaoLineStyle.lineColor = [CPTColor lightGrayColor];
marcacaoLineStyle.lineWidth = 1;
x.axisLineStyle = marcacaoLineStyle;
x.majorTickLineStyle = marcacaoLineStyle;
x.minorTickLineStyle = marcacaoLineStyle;
x.majorIntervalLength = CPTDecimalFromString(#"5");
x.orthogonalCoordinateDecimal = CPTDecimalFromString(#"0");
//x.title = #"Horas";
//x.titleLocation = CPTDecimalFromFloat(15.0f);
//x.titleOffset = 55.0f;
// Define some custom labels for the data elements
x.labelingPolicy = CPTAxisLabelingPolicyNone;
NSArray *customTickLocations = posicao;//[NSArray arrayWithObjects:[NSDecimalNumber numberWithFloat:0.7], [NSDecimalNumber numberWithFloat:2.7], [NSDecimalNumber numberWithFloat:4.7], nil];
NSArray *xAxisLabels = horas;//[NSArray arrayWithObjects:#"10", #"11", #"12", nil];
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; //+ x.majorTickLength;
[customLabels addObject:newLabel];
}
x.axisLabels = [NSSet setWithArray:customLabels];
CPTXYAxis *y = axisSet.yAxis;
y.axisLineStyle = marcacaoLineStyle;
y.majorTickLineStyle = marcacaoLineStyle;
y.minorTickLineStyle = marcacaoLineStyle;
y.majorIntervalLength = CPTDecimalFromInt([apoio retornaMaiorDadosGrafico:qtdEmb :qtdDesc]/7); //CPTDecimalFromString(#"5");
y.orthogonalCoordinateDecimal = CPTDecimalFromString(#"0");
y.title = #"Containers";
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:0];
y.labelFormatter = formatter;
CPTMutableLineStyle *majorGridLineStyle = [CPTMutableLineStyle lineStyle];
majorGridLineStyle.lineWidth = 0.75;
majorGridLineStyle.lineColor = [CPTColor lightGrayColor ];
y.majorGridLineStyle = majorGridLineStyle ;
y.preferredNumberOfMajorTicks = 10;
CPTMutableTextStyle *EixostextStyle = [CPTTextStyle textStyle];
EixostextStyle.fontSize = 12.0f;
y.labelTextStyle = EixostextStyle;
x.labelTextStyle = EixostextStyle;
// Embaque
CPTBarPlot *barPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor darkGrayColor] horizontalBars:NO];
barPlot.baseValue = CPTDecimalFromString(#"0");
barPlot.dataSource = self;
barPlot.delegate = self;
barPlot.barOffset = CPTDecimalFromFloat(0.25f);
barPlot.identifier = #"Embarque";
barPlot.title = #"Embarque";
barPlot.labelOffset = 0;
[barChart addPlot:barPlot toPlotSpace:plotSpace];
//Descarga
CPTBarPlot *barPlot2 = [CPTBarPlot tubularBarPlotWithColor:[CPTColor blueColor] horizontalBars:NO];
barPlot2.baseValue = CPTDecimalFromString(#"0");
barPlot2.dataSource = self;
barPlot2.delegate = self;
//barPlot2.barOffset = CPTDecimalFromFloat(25f);
barPlot2.identifier = #"Descarga";
barPlot2.title = #"Descarga";
barPlot2.labelOffset = 0;
[barChart addPlot:barPlot2 toPlotSpace:plotSpace];
CPTLegend *theLegend = [CPTLegend legendWithGraph:barChart];
theLegend.numberOfRows = 1;
theLegend.numberOfColumns = 2;
theLegend.cornerRadius = 10.0;
theLegend.swatchSize = CGSizeMake(15, 15);
//whiteTextStyle.fontSize = 16.0;
//theLegend.textStyle = whiteTextStyle;
theLegend.rowMargin = 10.0;
theLegend.paddingLeft = 12.0;
theLegend.paddingTop = 12.0;
theLegend.paddingRight = 12.0;
theLegend.paddingBottom = 12.0;
//theLegend.equalColumns = YES;
//theLegend.equalRows = YES;
barChart.legend = theLegend;
}
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot{
return [horas count];}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSDecimalNumber *num = nil;
if ( [plot isKindOfClass:[CPTBarPlot class]] ) {
switch ( fieldEnum ) {
case CPTBarPlotFieldBarLocation:
if ( [plot.identifier isEqual:#"Embarque"] ) {
num = (NSDecimalNumber *)[NSDecimalNumber numberWithUnsignedInteger:index*2];
} else{
num = (NSDecimalNumber *)[NSDecimalNumber numberWithUnsignedInteger:(index*2+1)];
}
break;
case CPTBarPlotFieldBarTip:
if ( [plot.identifier isEqual:#"Embarque"] ) {
num = [qtdEmb objectAtIndex:index];
} else{
num = [qtdDesc objectAtIndex:index];
}
break;
}
}
return num;
}
-(CPTFill *)barFillForBarPlot:(CPTBarPlot *)barPlot recordIndex:(NSUInteger)index
{
if ( [barPlot.identifier isEqual:#"Embarque"] ) {
return [CPTFill fillWithColor:[CPTColor colorWithComponentRed:(175/255.0 ) green:(238/255.0) blue:(238/255.0) alpha:1.0]];
}
if ( [barPlot.identifier isEqual:#"Descarga"] ) {
return [CPTFill fillWithColor:[CPTColor colorWithComponentRed:(255./255.0 ) green:(228.0/255.0) blue:(181.0/255.0) alpha:1.0]];
}
}
-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index
{
int valor;
if ( [plot.identifier isEqual:#"Embarque"] )
{
valor = [qtdEmb objectAtIndex:index];
}else{
valor = [qtdDesc objectAtIndex:index];
}
CPTTextLayer *newLayer = [[CPTTextLayer alloc] initWithText:[[NSString alloc] initWithFormat:#"%#",valor]];
CPTMutableTextStyle *estiloTexto = [[CPTMutableTextStyle alloc] init];
estiloTexto.color = [CPTColor blackColor];
estiloTexto.fontSize = 10;
newLayer.textStyle = estiloTexto;
return newLayer;
}