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.
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'm trying to implement the real-time plot example from core-plot into my ios project, I keep getting [CPTPlotRange objCType]: unrecognized selector sent to instance which seems to be stopping the CPTAnimation for moving the graph to the newest values.
This is pretty much all of my code, and I cannot figure out why this issue occurs
-(id)initWithGraphView:(CPTGraphHostingView *) gView name:(NSString *)label {
self = [super init];
if(self) {
_graphView = gView;
CGRect bounds = _graphView.bounds;
_graph = [[CPTXYGraph alloc] initWithFrame:bounds];
_graphView.hostedGraph = _graph;
_currentIndex = 0;
_plotData = [[NSMutableArray alloc] initWithCapacity:kMaxDataPoints];
[_plotData removeAllObjects];
CPTMutableLineStyle *majorGridLineStyle = [CPTMutableLineStyle lineStyle];
majorGridLineStyle.lineWidth = 0.75;
majorGridLineStyle.lineColor = [[CPTColor colorWithGenericGray:CPTFloat(0.2)] colorWithAlphaComponent:CPTFloat(0.75)];
CPTMutableLineStyle *minorGridLineStyle = [CPTMutableLineStyle lineStyle];
minorGridLineStyle.lineWidth = 0.25;
minorGridLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:CPTFloat(0.1)];
// Axes
// X axis
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)_graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
x.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
x.orthogonalPosition = #0.0;
x.majorGridLineStyle = majorGridLineStyle;
x.minorGridLineStyle = minorGridLineStyle;
x.minorTicksPerInterval = 9;
x.title = #"X Axis";
NSNumberFormatter *labelFormatter = [[NSNumberFormatter alloc] init];
labelFormatter.numberStyle = NSNumberFormatterNoStyle;
x.labelFormatter = labelFormatter;
// Y axis
CPTXYAxis *y = axisSet.yAxis;
y.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
y.orthogonalPosition = #0.0;
y.majorGridLineStyle = majorGridLineStyle;
y.minorGridLineStyle = minorGridLineStyle;
y.minorTicksPerInterval = 3;
y.title = #"Y Axis";
y.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0];
// Rotate the labels by 45 degrees, just to show it can be done.
x.labelRotation = CPTFloat(M_PI_4);
// Create the plot
CPTScatterPlot *dataSourceLinePlot = [[CPTScatterPlot alloc] init];
dataSourceLinePlot.identifier = kPlotIdentifier;
dataSourceLinePlot.cachePrecision = CPTPlotCachePrecisionDouble;
dataSourceLinePlot.interpolation = CPTScatterPlotInterpolationCurved;
CPTMutableLineStyle *lineStyle = [dataSourceLinePlot.dataLineStyle mutableCopy];
lineStyle.lineWidth = 3.0;
lineStyle.lineColor = [CPTColor greenColor];
dataSourceLinePlot.dataLineStyle = lineStyle;
dataSourceLinePlot.dataSource = self;
[_graph addPlot:dataSourceLinePlot];
// Plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)_graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:#0.0 length:#(kMaxDataPoints - 2)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:#0.0 length:#1000000.0];
}
return self;
}
-(void)newData:(int)value
{
NSLog(#"adding, %i", value);
CPTGraph *theGraph = _graph;
CPTPlot *thePlot = [theGraph plotWithIdentifier:kPlotIdentifier];
if ( thePlot ) {
if ( self.plotData.count >= kMaxDataPoints ) {
[self.plotData removeObjectAtIndex:0];
[thePlot deleteDataInIndexRange:NSMakeRange(0, 1)];
}
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)_graph.defaultPlotSpace;
NSUInteger location = (self.currentIndex >= kMaxDataPoints ? self.currentIndex - kMaxDataPoints + 2 : 0);
CPTPlotRange *oldRange = [CPTPlotRange plotRangeWithLocation:#( (location > 0) ? (location - 1) : 0 )
length:#(kMaxDataPoints - 2)];
CPTPlotRange *newRange = [CPTPlotRange plotRangeWithLocation:#(location)
length:#(kMaxDataPoints - 2)];
[CPTAnimation animate:plotSpace
property:#"xRange"
fromPlotRange:oldRange
toPlotRange:newRange
duration:CPTFloat(1.0 / kFrameRate)];
self.currentIndex++;
[self.plotData addObject:#(value)];
[thePlot insertDataAtIndex:self.plotData.count - 1 numberOfRecords:1];
}
}
-(NSUInteger)numberOfRecordsForPlot:(nonnull CPTPlot *)plot
{
return _plotData.count;
}
-(nullable id)numberForPlot:(nonnull CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSNumber *num = nil;
switch ( fieldEnum ) {
case CPTScatterPlotFieldX:
num = #(index + _currentIndex - _plotData.count);
break;
case CPTScatterPlotFieldY:
num = _plotData[index];
break;
default:
break;
}
return num;
}
There was a bug in Core Plot 2.1 that caused this error when animating plot ranges. It's fixed on the master branch and will be in the next release.
In the meantime, you can pull the latest code from GitHub or point Cocoapods to the latest code on master rather than to a release package (pod 'CorePlot', :git => 'https://github.com/core-plot/core-plot.git').
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.
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.
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.