I started with core-plot now and came to some problems. I followed the tutorial from this page: http://www.switchonthecode.com/tutorials/using-core-plot-in-an-iphone-application
and completed with the instructions from this page: http://code.google.com/p/core-plot/wiki/UsingCorePlotInApplications (such as -all_load).
But I still have some problems, I get the following errors:
error: incompatible type for argument 1 of 'setMajorIntervalLength:'
error: request for member 'axisLabelOffset' in something not a structure or union
error: incompatible type for argument 1 of 'setMajorIntervalLength:'
error: request for member 'axisLabelOffset' in something not a structure or union
error: request for member 'bounds' in something not a structure or union
error: request for member 'defaultPlotSymbol' in something not a structure or union
error: request for member 'bounds' in something not a structure or union
Anyone who knows what I am doing wrong?
This is my code:
- (void)viewDidLoad {
[super viewDidLoad];
graph = [[CPXYGraph alloc] initWithFrame: self.view.bounds];
CPLayerHostingView *hostingView = (CPLayerHostingView *)self.view;
hostingView.hostedLayer = graph;
graph.paddingLeft = 20.0;
graph.paddingTop = 20.0;
graph.paddingRight = 20.0;
graph.paddingBottom = 20.0;
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-6)
length:CPDecimalFromFloat(12)];
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-5)
length:CPDecimalFromFloat(30)];
CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
CPLineStyle *lineStyle = [CPLineStyle lineStyle];
lineStyle.lineColor = [CPColor blackColor];
lineStyle.lineWidth = 2.0f;
axisSet.xAxis.majorIntervalLength = [NSDecimalNumber decimalNumberWithString:#"5"];
axisSet.xAxis.minorTicksPerInterval = 4;
axisSet.xAxis.majorTickLineStyle = lineStyle;
axisSet.xAxis.minorTickLineStyle = lineStyle;
axisSet.xAxis.axisLineStyle = lineStyle;
axisSet.xAxis.minorTickLength = 5.0f;
axisSet.xAxis.majorTickLength = 7.0f;
axisSet.xAxis.axisLabelOffset = 3.0f;
axisSet.yAxis.majorIntervalLength = [NSDecimalNumber decimalNumberWithString:#"5"];
axisSet.yAxis.minorTicksPerInterval = 4;
axisSet.yAxis.majorTickLineStyle = lineStyle;
axisSet.yAxis.minorTickLineStyle = lineStyle;
axisSet.yAxis.axisLineStyle = lineStyle;
axisSet.yAxis.minorTickLength = 5.0f;
axisSet.yAxis.majorTickLength = 7.0f;
axisSet.yAxis.axisLabelOffset = 3.0f;
CPScatterPlot *xSquaredPlot = [[[CPScatterPlot alloc]
initWithFrame:graph.defaultPlotSpace.bounds] autorelease];
xSquaredPlot.identifier = #"X Squared Plot";
xSquaredPlot.dataLineStyle.lineWidth = 1.0f;
xSquaredPlot.dataLineStyle.lineColor = [CPColor redColor];
xSquaredPlot.dataSource = self;
[graph addPlot:xSquaredPlot];
CPPlotSymbol *greenCirclePlotSymbol = [CPPlotSymbol ellipsePlotSymbol];
greenCirclePlotSymbol.fill = [CPFill fillWithColor:[CPColor greenColor]];
greenCirclePlotSymbol.size = CGSizeMake(2.0, 2.0);
xSquaredPlot.defaultPlotSymbol = greenCirclePlotSymbol;
CPScatterPlot *xInversePlot = [[[CPScatterPlot alloc]
initWithFrame:graph.defaultPlotSpace.bounds] autorelease];
xInversePlot.identifier = #"X Inverse Plot";
xInversePlot.dataLineStyle.lineWidth = 1.0f;
xInversePlot.dataLineStyle.lineColor = [CPColor blueColor];
xInversePlot.dataSource = self;
[graph addPlot:xInversePlot];
}
The example you're pointing to is out of date and no longer matches the current API for the Core Plot framework. I'd suggest starting with the sample applications that ship with the framework (in the examples directory), as we've kept those updated to match any API changes.
For example axisLabelOffset has been renamed to labelOffset, defaultPlotSymbol no longer exists (you set the plotSymbol property on a CPPlot instance), the plot space no longer has a bounds property, and you no longer need to use -initWithFrame: for the CPPlot instances.
Again, just use the sample applications that ship with the framework as a template, and work from there. We haven't reached a 1.0 release yet, so the API will change as we stabilize and enhance the framework.
you are getting the incompatible type error because majorIntervalLength expects a NSDecimal and you are returning a NSDecimalNumber. see if this works for those errors:
axisSet.xAxis.majorIntervalLength = [[NSDecimalNumber decimalNumberWithString:#"5"] decimalValue];
for the others are you including the header files somewhere?
set the header search and other link (Users..../framework & -ObjC respectively)
I guess you are providing Absolute path. If you go through the corePlot Documentation you shall see that they have clearly mentioned "You should give relative path at Header Search path Field"
to learn what is a relative path follow,
"http://webdesign.about.com/od/beginningtutorials/a/aa040502a.htm"
get full path of core-plot thru terminal command "mdfind" as below.
In terminal type, mdfind -name coreplot
will get full path name.
Take full path and insert in HEADERS SEARCH PATH
along with above... add -Objc to "Othetr Linker Flags" and add Quartz frame work in "Link Binary With Libraries"
It will WORK :)
ive done the following:
1) added #import "CorePlot-CocoaTouch.h"
2) added the : UIViewController to the .h vc file
3) added the exact same code from CPTest app
4) added the coreplot-cocoatouch framework to my project, set the dependency in target settings, set the header search and other link (Users..../framework & -ObjC respectively) in project settings, added the QuartzCore framework and when i compile i get:
import "CorePlot-CocoaTouch.h" NO SUCH FILE OR DIRECTORY....
i dont understand why its not finding the header files...
Related
i was just browsing the classes for an hour and cant find it! i started with searching the example of the AAPLot project.
i changed the graph a bit and was expecting to find all settings in the CPTTradingRangePlot class but it´s not there.
there are a lot of properties which i can change, but i can´t find the background settings in any of the classes.
could anybody give me a hint?
// OHLC plot
CPTMutableLineStyle *whiteLineStyle = [CPTMutableLineStyle lineStyle];
whiteLineStyle.lineColor = [CPTColor whiteColor];
whiteLineStyle.lineWidth = 1.0f;
CPTTradingRangePlot *ohlcPlot = [[[CPTTradingRangePlot alloc] initWithFrame:graph.bounds] autorelease];
ohlcPlot.identifier = #"OHLC";
ohlcPlot.lineStyle = whiteLineStyle;
ohlcPlot.barWidth = 4.0f;
ohlcPlot.increaseFill = [(CPTFill *)[CPTFill alloc] initWithColor:[CPTColor greenColor]];
ohlcPlot.decreaseFill = [(CPTFill *)[CPTFill alloc] initWithColor:[CPTColor redColor]];
CPTMutableTextStyle *whiteTextStyle = [CPTMutableTextStyle textStyle];
whiteTextStyle.color = [CPTColor whiteColor];
whiteTextStyle.fontSize = 12.0;
ohlcPlot.labelTextStyle = whiteTextStyle;
ohlcPlot.labelOffset = 5.0;
ohlcPlot.stickLength = 2.0f;
ohlcPlot.dataSource = self;
ohlcPlot.plotStyle = CPTTradingRangePlotStyleCandleStick;
[graph addPlot:ohlcPlot];
Here's a very simple example. This:
CPTColor *your_color = [CPTColor colorWithComponentRed:1 green:0 blue:0 alpha:1];
your_graph.fill = [CPTFill fillWithColor:your_color];
will turn your graph's background red. But as Eric Skroch said, you may want to do this...
your_graph.plotAreaFrame.fill = [CPTFill fillWithColor:your_color];
and / or this...
your_graph.plotAreaFrame.plotArea.fill = [CPTFill fillWithColor:your_color];
depending on the result you want to achieve.
Backgrounds in Core Plot are set using CPTFill objects similar to the increaseFill and decreaseFill in your code sample. Depending on the look you want to achieve, you need to set the fill on graph, graph.plotAreaFrame, and/or graph.plotAreaFrame.plotArea. The axis demo in the Mac version of CPTTestApp uses fills in all three areas so you can see the different parts.
You may set it in xAxis or yAxis using CPTColor.
axisSet.yAxis.alternatingBandFills = [NSArray arrayWithObjects:[CPTColor redColor],
[CPTColor whiteColor], [CPTColor purpleColor], nil];
i finally found it by myself. the background of the chart is managed by a theme. there are several theme files in the folder theme of the core-plot library and one of them is CPTStocksTheme. The CPTStocksTheme creates a blue gradient background which can be changed there.
I'm using Core-Plot for a trend chart in an iPhone app and haven't found how to customize the background. I can create a theme using the built-in themes, like kCPPlainWhiteTheme, but how can I change them? or create a new one?
What i basically need to do is make the background transparent.
EDIT / UPDATE
I jus tested this code but it doesn't seem to work:
//CPTheme *theme = [CPTheme themeNamed:kCPPlainWhiteTheme];
CPTheme *theme = [[CPTheme alloc]init];
chartTrend5 = (CPXYGraph *)[theme newGraph];
chartView.hostedGraph = chartTrend5;
chartTrend5.paddingLeft = 0.0;
chartTrend5.paddingTop = 0.0;
chartTrend5.paddingRight = 0.0;
chartTrend5.paddingBottom = 0.0;
chartTrend5.fill = nil;
chartTrend5.borderLineStyle = nil;
chartView.hostedGraph.fill = nil;
chartTrend5PlotSpace = (CPXYPlotSpace *)chartTrend5.defaultPlotSpace;
chartTrend5PlotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0)
length:CPDecimalFromFloat(5)];
// range is 0-125, but since the frame heights is 90,
// we need to convert the points to this adjusted scale. The factor is 0.72 => (90/125)
chartTrend5PlotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0)
length:CPDecimalFromFloat(90)];
CPXYAxisSet *axisSet = (CPXYAxisSet *)chartTrend5.axisSet;
CPXYAxis *x = axisSet.xAxis;
x.majorIntervalLength = CPDecimalFromFloat(100);
//x.constantCoordinateValue = CPDecimalFromFloat(2);
x.minorTicksPerInterval = 2;
x.borderWidth = 0;
x.labelExclusionRanges = [NSArray arrayWithObjects:
[CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-1)
length:CPDecimalFromFloat(800)],
nil];;
CPXYAxis *y = axisSet.yAxis;
y.majorIntervalLength = CPDecimalFromFloat(100);
y.minorTicksPerInterval = 1;
//y.constantCoordinateValue = length:CPDecimalFromFloat(2);
y.labelExclusionRanges = [NSArray arrayWithObjects:
[CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-26)
length:CPDecimalFromFloat(100)],
nil];
CPScatterPlot *dataSourceLinePlot = [[[CPScatterPlot alloc] init] autorelease];
dataSourceLinePlot.identifier = #"TrendChart";
dataSourceLinePlot.dataLineStyle.lineWidth = 2.f;
dataSourceLinePlot.dataLineStyle.lineColor = [CPColor colorWithComponentRed:(16/255.f)
green:(101/255.f)
blue:(122/255.f)
alpha:1];
dataSourceLinePlot.dataSource = self;
[chartTrend5 addPlot:dataSourceLinePlot];
chartTrend5.fill = nil;
// Put an area gradient under the plot above
CPColor *areaColor = [CPColor colorWithComponentRed:(212/255.f)
green:(233/255.f)
blue:(216/255.f)
alpha:1];
CPGradient *areaGradient = [CPGradient gradientWithBeginningColor:areaColor
endingColor:areaColor];
areaGradient.angle = -90.0f;
CPFill *areaGradientFill = [CPFill fillWithGradient:areaGradient];
dataSourceLinePlot.areaFill = areaGradientFill;
dataSourceLinePlot.areaBaseValue = CPDecimalFromString(#"5.25");
here I set the the fill property of CPXYGraph *chartTrend5 and *CPXYPlotSpace *chartTrend5PlotSpace to nil.
In addition to what Eric suggests, you can also try setting the fill to a clear color. For example, I've used this in the past to provide a transparent background to graphs:
CPTTheme *theme = [CPTTheme themeNamed:kCPPlainWhiteTheme];
graph = (CPTXYGraph *)[theme newGraph];
graph.fill = [CPTFill fillWithColor:[CPTColor clearColor]];
graph.plotAreaFrame.fill = [CPTFill fillWithColor:[CPTColor clearColor]];
Themes are just a convenient way to set a lot of the style properties at once. You can set any of them individually to customize the look. Any time you want an area to be transparent, you can set its fill to nil. Same with line styles--set them to nil to prevent a line from being drawn.
There are two "background" areas that you might be concerned with. The graph has a fill as does the plot area. The plot area is the region where the plots are drawn. Set the fill property on both of these to nil to make the background transparent.
I tried this & it works for me:
// Here 'hostingView' is your CPTGraphHostingView to
// which you add your graph
UIImageView *backgroundImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background.png"]];
[hostingView addSubview:backgorundImage];
[hostingView sendSubviewToBack:backgroundImage];
I used the .fill and .plot.AreaFrame.fill properties :
plot = [[CPTXYGraph alloc] initWithFrame:CGRectZero];
CPTTheme *theme = [CPTTheme themeNamed:kCPTSlateTheme];
[plot applyTheme:theme];
self.graph.collapsesLayers = NO;
self.graph.hostedGraph = plot;
plot.paddingLeft = 1.0;
plot.paddingTop = 1.0;
plot.paddingRight = 1.0;
plot.paddingBottom = 1.0;
plot.fill = [CPTFill fillWithColor:[CPTColor clearColor]];
plot.plotAreaFrame.fill = [CPTFill fillWithColor:[CPTColor clearColor]];
This works for me.
I really don't know a solution or even an idea to get around the
following failure. It only happens in Release Configuration on the
Device - Simulator and Debug Configuration work fine. It also only
appears on the second launch. So if I have the phone connected to my
mac, build the application and run it, everything works fine. If I
then close the app and restart, it crashes.
After long search, it seems that the error comes from the following
line:
x.majorIntervalLength = CPDecimalFromFloat(2.0f);
The code before:
CPLayerHostingView *chartView = [[CPLayerHostingView
alloc] initWithFrame:CGRectMake(0, 0, 320, 160)];
[self addSubview:chartView];
// create an CPXYGraph and host it inside the view
CPTheme *theme = [CPTheme themeNamed:kCPPlainWhiteTheme];
CPXYGraph *graph = (CPXYGraph *)[theme newGraph];
chartView.hostedLayer = graph;
graph.paddingLeft = 20.0;
graph.paddingTop = 10.0;
graph.paddingRight = 10.0;
graph.paddingBottom = 20.0;
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPPlotRange
plotRangeWithLocation:CPDecimalFromFloat(0)
length:CPDecimalFromFloat(100)];
plotSpace.yRange = [CPPlotRange
plotRangeWithLocation:CPDecimalFromFloat(0)
length:CPDecimalFromFloat(10)];
CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
CPXYAxis *x = axisSet.xAxis;
x.majorIntervalLength = CPDecimalFromFloat(2.0f);
If I comment the last line, everything works fine (off course the
interval length is not correct).
I would appreciate any help!
Thanks in advance!
Any chance CPXYAxis *x = axisSet.xAxis; is an x that is nil or not retained? It is not being checked for.
I have created a CPScatterPlot using Core Plot and have several lines on the graph:
for(int i=0; i<nLines; ++i){
CPScatterPlot *xSquaredPlot = [[[CPScatterPlot alloc] initWithFrame:graph.frame] autorelease];
xSquaredPlot.identifier = [NSString stringWithFormat:#"%d",i];
xSquaredPlot.dataLineStyle.lineWidth = 1.0f;
xSquaredPlot.name = #"dd";
if(i==0)
xSquaredPlot.dataLineStyle.lineColor = [CPColor redColor];
else if (i ==1)
xSquaredPlot.dataLineStyle.lineColor = [CPColor blueColor];
else
xSquaredPlot.dataLineStyle.lineColor = [CPColor greenColor];
xSquaredPlot.dataSource = self;
[graph addPlot:xSquaredPlot];
CPPlotSymbol *greenCirclePlotSymbol = [CPPlotSymbol ellipsePlotSymbol];
if(i==0)
greenCirclePlotSymbol.fill = [CPFill fillWithColor:[CPColor blueColor]];
else if (i ==1)
greenCirclePlotSymbol.fill = [CPFill fillWithColor:[CPColor greenColor]];
else
greenCirclePlotSymbol.fill = [CPFill fillWithColor:[CPColor redColor]];
greenCirclePlotSymbol.size = CGSizeMake(2.0, 2.0);
xSquaredPlot.plotSymbol = greenCirclePlotSymbol;
}
The lines show up great, but I can't seem to find a way to label each line with it's title, or provide a legend.
Any ideas on this?
Thanks in advance!
Update: CorePlot 0.4 has the class CPTLegend:
_graph.legend = [CPTLegend legendWithGraph:_graph];
_graph.legend.textStyle = x.titleTextStyle;
_graph.legend.fill = [CPTFill fillWithColor:[CPTColor darkGrayColor]];
_graph.legend.borderLineStyle = x.axisLineStyle;
_graph.legend.cornerRadius = 5.0;
_graph.legend.swatchSize = CGSizeMake(25.0, 25.0);
_graph.legendAnchor = CPTRectAnchorBottom;
_graph.legendDisplacement = CGPointMake(0.0, 12.0);
See CorePlot_0.4/Source/examples/CorePlotGallery/src/plots/SimpleScatterPlot.m.
Legends have not yet been implemented in Core Plot. You're more than welcome to contribute an implementation of them to the framework.
In the meantime, you could construct a custom UIView with UILabels and colored lines to act as the legend for the graph, then add it as a sibling to the graph (not a subview, or it will not be rendered properly) and order it to show above the graph.
EDIT: I think my question is better phrased as: How can I have a Y-axis that doesn't start at zero? It seems like the x-axis always gets placed at the y=0, but I would like the x-axis to be at some positive number on the y-axis.
Here's a graph with more regular data... I just wish the x-axis was placed at the minimum y-value for the plot (about 77), instead of at 0.
Here is the function I use to create the graph.
It's a whole bunch of code, and I'm not quite sure which piece might be off to not display the x-axis.
Could the x-axis not showing have something to do with my data?
- (void) showGraph:(SavedDetailScreen*)dataSource {
// create the graph and add it to the view
CPXYGraph *graph = [[CPXYGraph alloc] initWithFrame: CGRectZero];
graph.plotArea.masksToBorder = NO;
CPLayerHostingView *graphView = [[CPLayerHostingView alloc] initWithFrame:CGRectMake(0,0, 280, 240)];
[self addSubview:graphView];
graphView.hostedLayer = graph;
graph.paddingLeft = 50.0;
graph.paddingTop = 20.0;
graph.paddingRight = 10.0;
graph.paddingBottom = 40.0;
// set up the ranges for the graph axis
float minElevation = dataSource.track.tbStats.minAlt;
float maxElevation = dataSource.track.tbStats.maxAlt-dataSource.track.tbStats.minAlt;
float minDistance = 0.0f;
float maxDistance = dataSource.track.tbStats.totalDistance;
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(minDistance)
length:CPDecimalFromFloat(maxDistance)];
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(minElevation)
length:CPDecimalFromFloat(maxElevation)];
// style the graph with white text and lines
CPTextStyle *whiteText = [CPTextStyle textStyle];
whiteText.color = [CPColor whiteColor];
CPLineStyle *whiteStyle = [CPLineStyle lineStyle];
whiteStyle.lineColor = [CPColor whiteColor];
whiteStyle.lineWidth = 2.0f;
// set up the axis
CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
CPXYAxis *x = axisSet.xAxis;
CPXYAxis *y = axisSet.yAxis;
x.majorIntervalLength = CPDecimalFromFloat(maxDistance/10.0f);
x.minorTicksPerInterval = 0;
x.majorTickLineStyle = whiteStyle;
x.minorTickLineStyle = whiteStyle;
x.axisLineStyle = whiteStyle;
x.minorTickLength = 5.0f;
x.majorTickLength = 10.0f;
x.labelOffset = 3.0f;
x.labelTextStyle = whiteText;
y.majorIntervalLength = CPDecimalFromFloat(maxElevation/5.0f);
y.minorTicksPerInterval = 0;
y.majorTickLineStyle = whiteStyle;
y.minorTickLineStyle = whiteStyle;
y.axisLineStyle = whiteStyle;
y.minorTickLength = 5.0f;
y.majorTickLength = 10.0f;
y.labelOffset = 3.0f;
y.labelTextStyle = whiteText;
CPScatterPlot *plot = [[[CPScatterPlot alloc] initWithFrame:graph.bounds] autorelease];
plot.dataLineStyle.lineWidth = 2.0f;
plot.dataLineStyle.lineColor = [CPColor blueColor];
plot.dataSource = dataSource;
[graph addPlot:plot];
CPPlotSymbol *greenCirclePlotSymbol = [CPPlotSymbol ellipsePlotSymbol];
greenCirclePlotSymbol.fill = [CPFill fillWithColor:[CPColor greenColor]];
greenCirclePlotSymbol.size = CGSizeMake(2.0, 2.0);
plot.plotSymbol = greenCirclePlotSymbol;
}
I've had the same problem yesterday/today and the solution seems to be using the orthogonalCoordinateDecimal property on the axis. For example:
graph.axisSet.xAxis.orthogonalCoordinateDecimal = CPDecimalFromFloat(minHeight);
You set the position of an axis on the orthogonal axis using the constantCoordinateValue property of the axis. Just set that property on the x axis to a positive value of y, and the axis should move up.
https://github.com/djw/core-plot/tree/9282845bddbb8c40ff314bbfa158beff797c91f7/examples
This states that the isFloatingAxis property has been removed from at least version 0.9.
I also found this in the discussion group as well http://code.google.com/p/core-plot/issues/detail?id=125
After some hunting, it looks like the new way to float an axis looks like this:
x.axisConstraints = [CPTConstraints constraintWithUpperOffset:132];
this framework really needs a better way to configure itself. I don't see any problem jumping out. Maybe just try simplifying the method to the point where debugging becomes manageable. Check the data that you are passing in to make sure it is what you expect it to be. Better yet, create some dummy data that you know will produce the plot you expect.