Am working with coreplot for creating bar-chart .Bar-chart is getting displayed but its upside down..X-axis starts at the top of the screen instead of being at the bottom of the screen..and even X-Axis isn't visible..It looks as if bars in the chart are hanging :(....How do I change its position and make it proper and even make x-Axis visible???
Here is my code:
- (void)viewDidLoad {
[super viewDidLoad];
[self generateDataSamples];
double xAxisStart = 0;
double xAxisLength = 14;
double yAxisStart = 0;
// double yAxisLength = [[samples valueForKeyPath:#"#max.Y_VAL"] doubleValue];
double yAxisLength = 190.0;
CPGraphHostingView *hostingView = [[CPGraphHostingView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:hostingView];
CPXYGraph *graph = [[CPXYGraph alloc] initWithFrame:self.view.bounds];
hostingView.hostedGraph = graph;
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromDouble(xAxisStart)
length:CPDecimalFromDouble(xAxisLength+1)];
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromDouble(yAxisStart)
length:CPDecimalFromDouble(yAxisLength+3)];
CPBarPlot *plot = [[CPBarPlot alloc] initWithFrame:CGRectZero];
plot.plotRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromDouble(0.0)
length:CPDecimalFromDouble(xAxisLength-5)];
plot.barOffset = CPDecimalFromDouble(1.5);
plot.dataSource = self;
[graph addPlot:plot];
[plot release];
[graph release];
[hostingView release];
}
Thank U
Add some padding to the plot area frame to make the axes visible:
graph.plotAreaFrame.paddingTop = 20.0;
graph.plotAreaFrame.paddingBottom = 50.0;
graph.plotAreaFrame.paddingLeft = 50.0;
graph.plotAreaFrame.paddingRight = 20.0;
I'm not sure why the graph would appear upside down. Does the hosting view's superview have any transforms applied to it?
Related
I'm using core plot for line graph.in the scatter graph i'm getting some blank space around the scatter graph.as you can see the screen shot(in debug mode) my graph plot area is covered by empty space.How can i remove it?
Initialising host view
self.hostView = [(CPTGraphHostingView *) [CPTGraphHostingView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height-10)];
self.hostView.backgroundColor = [UIColor clearColor];;
self.hostView.allowPinchScaling = NO;
[self addSubview:self.hostView];
Initializing graph
graph = [[CPTXYGraph alloc] initWithFrame:self.hostView.bounds];
[graph applyTheme:[CPTTheme themeNamed:kCPTPlainWhiteTheme]];
self.hostView.hostedGraph = graph;
EDIT
graph.plotAreaFrame.PaddingLeft = 55.0f;
graph.plotAreaFrame.PaddingRight = 15.0f;
graph.plotAreaFrame.PaddingTop = 10.0f;
graph.plotAreaFrame.paddingBottom = 28.0;
These are the paddings i have provided.
The graph starts with 20 pixels of padding on each edge but that's easy to change:
graph.PaddingLeft = 0.0;
graph.PaddingTop = 0.0;
graph.PaddingRight = 0.0;
graph.PaddingBottom = 0.0;
I'm experiencing some problems with CorePlot. I try to plot multiple scatterPlots into one graph. Which works as expected but when I start scrolling or zooming the graph the whole app increases it's memory usage up to 900MB an crashes. I think I have to do some object releasing but I don't know how. Basically I plot each line with a different plot identifier and put the according data into the datasource.
Here is what I got: (In this example code I just reduced the axe ranges with static values for testing purposes.)
- (void)setupGraph {
// Create graph from theme
self.graph = [[CPTXYGraph alloc] initWithFrame:self.scatterPlotView.bounds];
self.graph.plotAreaFrame.masksToBorder = NO;
self.scatterPlotView.hostedGraph = self.graph;
CPTTheme *theme = [CPTTheme themeNamed:kCPTPlainBlackTheme];
[self.graph applyTheme:theme];
self.graph.paddingLeft = 0.0;
self.graph.paddingTop = 0.0;
self.graph.paddingRight = 0.0;
self.graph.paddingBottom = 0.0;
// Setup plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
plotSpace.allowsUserInteraction = YES;
plotSpace.delegate = self;
plotSpace.globalXRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(30)];
plotSpace.globalYRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(15)];
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(10)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(15)];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
CPTXYAxis *y = axisSet.yAxis;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
y.labelingPolicy = CPTAxisLabelingPolicyNone;
}
This method loads my data and draws the scatterplots
- (void)loadSignals {
//Data loading logic goes here nothing special just one array for each plot
for (Signal *sig in [signals allValues]) {
[self constructScatterPlot:sig.name];
}
}];
This is where the drawing happens:
- (void)constructScatterPlot:(NSString *)identifier {
CPTScatterPlot *dataSourceLinePlot = [[CPTScatterPlot alloc] init];
CPTMutableLineStyle *lineStyle = [dataSourceLinePlot.dataLineStyle mutableCopy];
CPTScatterPlot *boundLinePlot = [[CPTScatterPlot alloc] init];
boundLinePlot.identifier = identifier;
lineStyle = [boundLinePlot.dataLineStyle mutableCopy];
lineStyle.miterLimit = 1.0;
lineStyle.lineWidth = 1.0;
lineStyle.lineColor = [CPTColor redColor];
boundLinePlot.dataLineStyle = lineStyle;
boundLinePlot.dataSource = self;
boundLinePlot.cachePrecision = CPTPlotCachePrecisionDouble;
boundLinePlot.interpolation = CPTScatterPlotInterpolationStepped;
[self.graph addPlot:boundLinePlot];
}
...and this is where the datasource gets it's values:
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSString *plotIdent = (NSString *) plot.identifier;
if (![plotIdent isEqualToString:self.currentIdent]) {
self.countPlot++;
self.currentIdent = plotIdent;
}
Signal *newSig = [self.signals objectForKey:plotIdent];
Value * newValue = [newSig valueAtTime:index];
NSNumber *number = [NSNumber numberWithInteger:[newValue.value integerValue]];
if ( fieldEnum == CPTScatterPlotFieldY ) {
return number;
}
if ( fieldEnum == CPTScatterPlotFieldX ) {
return [NSNumber numberWithInteger:index];
}
return nil;
}
So first of all I'd like to know if this is the correct way of drawing multiple plots (up to 40 in my case) into one graph? If so, what could I do to optimize my plot performance?
The output should look like this:
I found this use
"try setting collapsesLayers to YES on the hosting view"
Application get stuck when drawing nearly 40 Scatter Plots using Core Plot in IPad
Each plot is a CALayer that covers the entire plot area of the graph, so with 40 of them you may be using up most of the available video memory. If they all use the same line style, you can plot all of the lines on the same plot and save some memory that way. Insert an extra data point between the line segments and return nil or #(NAN) from the datasource to break the line.
CPTXYGraph *graph = [[CPTXYGraph alloc]initWithFrame:self.hostingView.frame];
graph.borderColor = [CPTColor whiteColor].cgColor;
graph.paddingTop = 0.0f;
graph.paddingRight = 0.0f;
graph.paddingLeft = 0.0f;
graph.paddingBottom = 0.0f;
self.hostingView.hostedGraph = graph;
graph.axisSet = nil;
//Apply for theme to graph
self.graphTheme = [CPTTheme themeNamed:kCPTPlainWhiteTheme];
[graph applyTheme:self.graphTheme];
[graph release];
CPTPieChart *pieChart = [[CPTPieChart alloc]init];
pieChart.identifier = #"OverView";
pieChart.dataSource = self;
pieChart.sliceDirection = CPTPieDirectionClockwise;
pieChart.pieRadius = ((self.hostingView.frame.size.height / 2) - 5);
pieChart.startAngle = M_PI;
CPTGraph *tempGraph = self.hostingView.hostedGraph;
[tempGraph addPlot:pieChart];
[pieChart release];
For this code i am getting black colored border ,i thought that is due to graph axisSet but i don't how to remove.
If what you're talking about is the border box that appears around the entire graph, I would say use this code after the statement [graph applyTheme:self.graphTheme];:
graph.plotAreaFrame.borderLineStyle = nil;
This removes the border completely from the graph area.
I have a parent view with 6 UIViews to which I add my core-plot charts (This is working fine but only every second chart displays for some reason!)
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
if(!chartVC1){
chartVC1 = [[ChartVC alloc] initWithIdentifier:#"plot1"];
//[chartVC1 setKPlotIdentifier:#"plot1"];
[chartVC1.view setFrame:self.Panel1.frame];
}
[self.Panel1 addSubview:chartVC1.view];
if(!chartVC3){
chartVC3 = [[ChartVC alloc] initWithIdentifier:#"plot2"];
[chartVC3.view setFrame:self.Panel3.frame];
}
[self.Panel3 addSubview:chartVC3.view];
if(!chartVC2){
chartVC2 = [[ChartVC alloc] initWithIdentifier:#"plot3"];
[chartVC2.view setFrame:self.Panel2.frame];
}
[self.Panel2 addSubview:chartVC2.view];
if(!chartVC4){
chartVC4 = [[ChartVC alloc] initWithIdentifier:#"plot4"];
[chartVC4.view setFrame:self.Panel4.frame];
}
[self.Panel4 addSubview:chartVC4.view];
if(!chartVC5){
chartVC5 = [[ChartVC alloc] initWithIdentifier:#"plot5"];
[chartVC5.view setFrame:self.Panel5.frame];
}
[self.Panel5 addSubview:chartVC5.view];
if(!chartVC6){
chartVC6 = [[ChartVC alloc] initWithIdentifier:#"plot6"];
[chartVC6.view setFrame:self.Panel6.frame];
}
[self.Panel6 addSubview:chartVC6.view];
}
Here is some of my code for the class ChartVC
-(void)renderInLayer
{
CPTXYGraph *graph = [[[CPTXYGraph alloc] initWithFrame:self.view.bounds] autorelease];
[self addGraph:graph toHostingView:self.view];
[self applyTheme:nil toGraph:graph withDefault:[CPTTheme themeNamed:kCPTDarkGradientTheme]];
//[self setTitleDefaultsForGraph:graph withBounds:self.view.bounds];
//[self setPaddingDefaultsForGraph:graph withBounds:self.view.bounds];
graph.plotAreaFrame.paddingTop = -20.0;
graph.plotAreaFrame.paddingRight = -20.0;
graph.plotAreaFrame.paddingBottom = -20.0;
graph.plotAreaFrame.paddingLeft = -20.0;
graph.plotAreaFrame.plotArea.frame = self.view.bounds;
graph.backgroundColor = [[UIColor whiteColor] CGColor];
// Grid line styles
CPTMutableLineStyle *majorGridLineStyle = [CPTMutableLineStyle lineStyle];
majorGridLineStyle.lineWidth = 0.75;
majorGridLineStyle.lineColor = [[CPTColor colorWithGenericGray:0.2] colorWithAlphaComponent:0.75];
CPTMutableLineStyle *minorGridLineStyle = [CPTMutableLineStyle lineStyle];
minorGridLineStyle.lineWidth = 0.25;
minorGridLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:0.1];
// Axes
// X axis
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
x.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
x.orthogonalCoordinateDecimal = CPTDecimalFromUnsignedInteger(0);
x.majorGridLineStyle = majorGridLineStyle;
x.minorGridLineStyle = minorGridLineStyle;
x.minorTicksPerInterval = 9;
//x.title = #"X Axis";
//x.titleOffset = 35.0;
NSNumberFormatter *labelFormatter = [[NSNumberFormatter alloc] init];
labelFormatter.numberStyle = NSNumberFormatterNoStyle;
x.labelFormatter = labelFormatter;
[labelFormatter release];
// Y axis
CPTXYAxis *y = axisSet.yAxis;
y.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
y.orthogonalCoordinateDecimal = CPTDecimalFromUnsignedInteger(0);
y.majorGridLineStyle = majorGridLineStyle;
y.minorGridLineStyle = minorGridLineStyle;
y.minorTicksPerInterval = 3;
//y.labelOffset = 5.0;
//y.title = #"Y Axis";
//y.titleOffset = 30.0;
y.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0];
// Rotate the labels by 45 degrees, just to show it can be done.
x.labelRotation = M_PI * 0.25;
// Create the plot
CPTScatterPlot *dataSourceLinePlot1 = [[[CPTScatterPlot alloc] init] autorelease];
dataSourceLinePlot1.identifier = [self kPlotIdentifier];
//NSLog(#"set identifier: %#", [self kPlotIdentifier]);
dataSourceLinePlot1.cachePrecision = CPTPlotCachePrecisionDouble;
CPTMutableLineStyle *lineStyle1 = [[dataSourceLinePlot1.dataLineStyle mutableCopy] autorelease];
lineStyle1.lineWidth = 1.0;
lineStyle1.lineColor = [CPTColor redColor];
dataSourceLinePlot1.dataLineStyle = lineStyle1;
dataSourceLinePlot1.dataSource = self;
[graph addPlot:dataSourceLinePlot1];
// Plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromUnsignedInteger(0) length:CPTDecimalFromUnsignedInteger(kMaxDataPoints - 1)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromUnsignedInteger(0) length:CPTDecimalFromUnsignedInteger(100)];
}
I would think the issue was my own fault if only the 1st chart displayed but because every second chart displays it doesn't make any sense to me..
My only guess is it is some sort of timing issue but I debugged it and delayed the creation of each chart and it made no difference..
I even removed the 3rd, 5th charts to see if the others now rendered but the same 3 charts that did not display previously were still not visible which really threw me off.. (ie. only the 1st chart displayed out of the 4 enabled!)
Any help on this much appreciated...
I may just use the code from the Apple Developer Library that renders the accelerometer data as it is very lightweight to support 6 charts on a screen at one time without issue...
Core-Plot just doesn't seem up to the task I guess...
You didn't say which graphs aren't showing up, but since it's always the same ones, I suspect there's an issue with the view hierarchy. Try changing
`[chartVC1.view setFrame:self.Panel1.frame];`
to
`[chartVC1.view setFrame:self.Panel1.bounds];`
for each graph.
I'm having some trouble with the axis labels. It seems my custom labels aren't visible outside of the plot area. Looking at the Design Overview for core plot, the axis labels should be outside of the plot area. Any ideas on how I can make them visible outside the plot area?
The code/image below shows how the labels only show within the plot area. If I change the label offset to a positive number, the labels do not show at all. I'm using Core Plot 0.9 with iOS 5.
Thanks in advance!
CPTTheme *theme = [CPTTheme themeNamed:kCPTPlainWhiteTheme];
graph = [[theme newGraph] retain];;
CPTGraphHostingView *hostingView = (CPTGraphHostingView *)self.view;
hostingView.hostedGraph = graph;
graph.paddingLeft = 40.0;
graph.paddingTop = 40.0;
graph.paddingRight = 40.0;
graph.paddingBottom = 40.0;
graph.masksToBorder = NO;
// ... setup axis
axisSet.yAxis.majorIntervalLength = CPTDecimalFromInt(0);
axisSet.yAxis.minorTicksPerInterval = 0;
axisSet.yAxis.labelingPolicy = CPTAxisLabelingPolicyNone;
// if this number is negative, the labels show,
// if it is positive, that is outside the plot area, the labels are hidden.
axisSet.yAxis.labelOffset = -20;
// ... setup labels
NSMutableArray *labels = [NSMutableArray array];
for (int i = 0; i < reportData.rowCount; ++i) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[NSString stringWithFormat:#"Test Row %i", i] textStyle:labelStyle];
label.tickLocation = CPTDecimalFromInt(i);
label.offset = axisSet.yAxis.labelOffset;
label.alignment = CPTAlignmentLeft;
[labels addObject:label];
[label release];
}
axisSet.yAxis.axisLabels = [NSSet setWithArray:labels];
Set some padding on the plot area frame in addition to or instead of the graph itself.
graph.plotAreaFrame.paddingTop = 20.0;
graph.plotAreaFrame.paddingBottom = 50.0;
graph.plotAreaFrame.paddingLeft = 50.0;
graph.plotAreaFrame.paddingRight = 50.0;
This code is from the axis demo in the Plot Gallery example app.
I was having exactly the same problem and tried every solution I could find online for this with no success.
Finally I got it to work by turning off the border masking, like this:
graph.plotAreaFrame.masksToBorder = NO;