This is a blog post by iOS Tutorial Team member Steve Baranski, the founder of komorka technology, a provider of iOS development and consulting services.
If you’ve ever wanted to include charts or graphs in your app, chances are you’ve considered the following two options:
- DIY. One option is to write all the drawing code yourself using Core Graphics/Quartz. Apple even has an example of this, in the SimpleStocks sample project.
- Buy it! Another option is to purchase a commercial framework like ShinobiControls.
But what if you don’t want to spend the time and effort to write it yourself, and don’t want to shell out a ton of money? That’s where a third option comes in handy: use the open-source Core Plot library!
Core Plot is an open-source plotting framework for both iOS and Mac OS X. It leverages Apple frameworks like Quartz and Core Animation, and even provides support for ARC. Perhaps more importantly, the framework has solid test coverage. Core Plot is distributed with a permissive BSD license, and Version 1.0 was released in February 2012.
In this 2-part tutorial series, we’ll show how you can use Core Plot to create pie charts, bar graphs, scatter plots, and more. We’ll even cover some cool stuff like theming the graphs and charts with different styles, interacting with charts, and more!
To go through this tutorial, you need to have Xcode 4 installed, and a working knowledge of Objective-C, Interface Builder and storyboards. If you are new to any of these topics, you should go through some of theother tutorials on this site first.
So without further ado, let’s get to work!
Getting Started: Project Configuration
Begin by launching Xcode and creating a new project – select the iOS\Application\Tabbed Application template.
Name the product CorePlotDemo; enter your company identifier; use CPD as the Class Prefix (or you can leave the Class Prefix blank); select iPhone as the Device Family; and check the boxes labeled Use Storyboards and Use Automatic Reference Counting. Click Next and select a location to create your project.
Note: In case you were wondering, the Class Prefix is simply a way to conveniently name all your source files. Every new class file that’s automatically generated by Xcode will have its name prefixed with the Class Prefix. This is a good practice because you don’t have to worry about your class names conflicting with class names from Apple or other third parties.
Now that your project is in place, proceed to add Core Plot. You can download it here. At the time of writing this tutorial, the latest release is CorePlot_1.0.zip, so download that and extract the contents of the ZIP file to a temporary folder. Core Plot can be used in a project in two different ways:
- Dependent Project: You can add the Core Plot Xcode project to your project so that the Core Plot source is compiled along with your project source.
- Static Library: You can build (or download) the Core Plot library separately, and then add the binary library to your Xcode project so that the Core Plot library is linked in when your app is built.
For this tutorial, you’ll use approach #2. Detailed instructions for this process can be found here, but the basic steps are as follows:
- Click on the project root class folder (CorePlotDemo) in the Project Navigator and select New Group. Name the new group “CorePlot.”
- Right-click on your newly-created group and select Add Files to “CorePlotDemo”… When the file dialog appears, navigate to the folder where you extracted the Core Plot ZIP file and drill down to the following location: CorePlot_1.0\Binaries\iOS. Select both CorePlotHeaders and the static library named libCorePlot-CocoaTouch.a. Make sure that the box labeled “Copy items into destination group’s folder (if needed)” is checked.
Now that you’ve added the framework, you need to wire it in. This involves the following steps:
- Click the CorePlotDemo root in the Project Navigator, select the CorePlotDemo target in the center pane, and then click Build Settings. Find the Other Linker Flags field and enter -ObjC into the field.
- Now change from Build Settings to Build Phases in the center pane. Expand the group named “Link Binary with Libraries.” Check to make sure that Xcode added the Core Plot static library when you added the Core Plot files to your project. If for some reason the Core Plot library is not listed, click the plus (+) button at the bottom of the section, click the “Add Other …” button, and navigate to your project folder to find the Core Plot library.
- Finally, click the plus (+) button and proceed to add the QuartzCore framework.
You should be able to Build (via Cmd-B) your project without errors at this point. Make sure that this is indeed the case.
Adding Resources
Now that you’ve incorporated Core Plot, download the resources for this project.
These resources include a few constants used throughout your app, as well as a singleton class that contains fictional stock price data for Apple (AAPL), Google (GOOG), and Microsoft (MSFT) stock.
Once you download and extract the archive, drag the “Starter Files” folder to the root of your Xcode project. Again, make sure that “Copy items into destination group’s folder (if needed)” is checked, as shown below.
If you check the new folder, you’ll see it contains two sets of source and header files:
- CPDConstants: This class is for a few constants that will be used throughout the project.
- CPDStockPriceStore: This class serves as the stock price data source for the project.
Now that you’ve added these files to the project, add a few import statements to CorePlotDemo-Prefix.pch. Navigate to the “Supporting Files” folder, open it and select CorePlotDemo-Prefix.pch. Add the following to the file right before the final #endif:
#import "CorePlot-CocoaTouch.h" #import "CPDConstants.h" #import "CPDStockPriceStore.h" |
Note: CorePlotDemo-Prefix.pch is the precompiled header file for this project. The precompiled header is automatically included for every source file in the project. So it’s a convenient location to add imports to that would need to be in almost every class file.
While you’ll add imports to CorePlotDemo-Prefix.pch in this tutorial for the sake of making things easier to follow, note that loading the prefix header with a lot of import statements is generally frowned upon, since it can lead to code which is not very portable.
Try building and running (Cmd-R) your code now. You’ll notice that the code compiles fine, but that you don’t see any graphs or charts. Instead, you simply see the standard screens from the tabbed application template. That’s because you haven’t set up the UI yet.
Storyboarding the App
You’ll now proceed to tailor the storyboard for your app to set up the initial UI. If you selectMainStoryboard.storybard in the Project navigator and show the Document Outline, you should see something like the following.
You’ll see that the Xcode template created a tab bar controller with two scenes corresponding to two separate view controllers. To modify the existing storyboard to accommodate your app’s intended design, do the following:
- Select First View Controller in the Document Outline (in the center panel).
- Drill down to the root view for First View Controller in the left sidebar (you might need to first expand the list of sub-components by using the triangle next to First View Controller), and delete the label and text view.
- Select the Tab Bar Item immediately below the view. Look for the Attributes Inspector on the right sidebar (if you don’t see it, you might need to enable it using the buttons at the top of the Xcode window, under the View section). In the Attributes Inspector, change the Title to “Pie Chart” and clear the Image name (it should be set to “first”).
Repeat the above steps for Second View Controller, but change the Title to “Bar Graph” instead of “Pie Chart” in step #3.
Now build and run your project again:
The app currently displays in portrait orientation, but you want it to be in landscape in order to use the available space optimally for the charts. To fix this, edit CorePlotDemo-Info.plist in the “Supporting Files” folder. Select the PLIST file, expand the bottom row that reads “Supported interface orientations,” and delete all but “Landscape (left home button).”
Next add a new entry to the file. First, collapse “Supported interface orientations” (if it’s expanded), and then right-click the bottom row and select “Add Row.” Enter “Initial interface orientation” as the key and select “Landscape (left home button)” as the corresponding value.
Now build and run the project again to make sure that the orientation changes took effect.
With the app running in landscape, it’s time to finish setting up the project.
- Select CPDFirstViewController.h in the Project Navigator.
- Double-click the word “CPDFirstViewController” in the editor pane so that the word is selected.
- Right-click, select Refactor\Rename…
- Change the class name to CPDPieChartViewController.
- Ensure that “Rename related files” remains checked, and click “Preview.”
- Verify the changes (if necessary), and then click “Save” to make the changes. You can opt to create a snapshot before the changes or disable the feature, your choice.
Repeat the above steps for CPDSecondViewController, but this time, name itCPDBarGraphViewController.
Next, create a third view controller. Note that although you won’t be doing much with the second and third view controllers for this tutorials, they will have a much bigger role to play in the second part of the tutorial, and it’s easiest to get them ready in advance now.
Create a new file with the iOS\Cocoa Touch\UIViewController subclass template. Leave the boxes unchecked and click Next. Name the class CPDScatterPlotViewController, and create/save it.
Now, switch back to MainStoryboard.storyboard and drag a view controller from the Object Library in Utilities (right sidebar) to the Document Outline, as shown.
Select your new view controller in the Document Outline, then select the Identity Inspector (third tab of the top half of the right sidebar) from Utilities and set the Class of the view controller to that of your new view controller: CPDScatterPlotViewController. You’ll also want to set the title in the Attributes Inspector (fourth tab of the right sidebar) to “Scatter Plot.”
Next, hook the new view controller up to the tab bar controller. Select the tab bar controller from the Tab Bar Controller scene, and open the Connections Inspector (last tab on the right sidebar) in Utilities.
You’ll notice that relationships are set up for other two view controllers. Click on that relationship node (the little black circle at the top right of the relationships list) and drag it to the Scatter Plot view controller. The relationship connection will now show three entries. Additionally, the primary storyboard pane will show a connection from the tab bar view controller to the new view controller.
Finally, select the Scatter Plot View Controller in the left sidebar, drill down to the Tab Bar item and change its title to “Scatter Plot.”
Now build and run the project once again to see the fruits of your labor.
Wait a minute! What’s going on? The app is displayed in landscape mode, but the tabs are placed on the left side of the screen rather than the bottom.
The answer might surprise you: the documentation for UIViewController states that YES is returned for every possible orientation, but the default Xcode templates override this method to return YES for every orientation except for UIInterfaceOrientationPortraitUpsideDown. This behavior interferes with your implementation. To fix, it you need to tidy up all three of the chart view controllers.
For each view controller (CPDPieChartViewController, CPDBarGraphViewController,CPDScatterPlotViewController), edit the .m file as follows:
- Delete the default implementation for viewDidLoad.
- Delete the default implementation for viewDidUnload.
- Replace the default implementation for shouldAutorotateToInterfaceOrientation: with the following:
#pragma mark - Rotation -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft); } |
Build and Run again, and you should see something similar to this:
Excellent! Now you can proceed to add your first chart.
The Pie Chart
Your first plot will be a pie chart that represents your portfolio as of close of trading on May 1, 2012.
Begin by making the necessary modifications to CPDPieChartViewController inMainStoryboard.storyboard. Drag a toolbar from the Object Library to the top of the view. Set its style in the Attributes Inspector to Default, as shown below.
Select the Bar Button Item in the Document Outline, switch to the Attributes Inspector, and change the “Title” value to Theme.
Next, create outlets for these elements in your view controller. Open CPDPieChartViewController.m and add the following lines at the top of the class continuation category (the section between the @interface and @end lines, right below the #import section):
@property (nonatomic, strong) IBOutlet UIToolbar *toolbar; @property (nonatomic, strong) IBOutlet UIBarButtonItem *themeButton; -(IBAction)themeTapped:(id)sender; |
You need to synthesize the properties declared above, so add the following lines just below the @implementation line:
@synthesize toolbar = toolbar_; @synthesize themeButton = themeButton_; |
Finally, add a blank implementation for themeTapped: to the end of the file, just before the @end:
#pragma mark - IBActions -(IBAction)themeTapped:(id)sender { } |
Now switch to CPDPieChartViewController.h and add the following to the end of the class declaration (the @interface line):
<CPTPlotDataSource, UIActionSheetDelegate> |
The above declares CPDPieChartViewController as a delegate for CPTPlotDataSource and UIActionSheetDelegate. The former notes that the view controller will serve as the data source for your plot-in-progress; the latter will allow you to handle the UIActionSheet you’ll need to present via thethemeTapped: action later on. This requires the addition of several delegate methods skeletons.
Add the following to the end of CPDPieChartViewController.m:
#pragma mark - CPTPlotDataSource methods -(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot { return 0; } -(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index { return 0; } -(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index { return nil; } -(NSString *)legendTitleForPieChart:(CPTPieChart *)pieChart recordIndex:(NSUInteger)index { return @""; } #pragma mark - UIActionSheetDelegate methods -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { } |
You’ll fill in the above skeleton methods as the tutorial continues.
Making Connections
Switch back to the storyboard and select CPDPieChartViewController in the Document Outline. You’re going to make three connections using the Connections inspector:
- Connect the “themeButton” outlet to the bar button item.
- Connect “toolbar” to the toolbar containing the bar button item.
- Connect themeTapped: to the bar button item as well.
Return to CPDPieChartController.m and add the following below the existing property declarations at the top of the file:
@property (nonatomic, strong) CPTGraphHostingView *hostView; @property (nonatomic, strong) CPTTheme *selectedTheme; |
Of the two properties added above, one is an instance of CPTGraphHostingView, the container for all Core Plot drawing. The second is for CPTTheme, a theming class used in modifying the look and feel of Core Plot graphs.
In the same class continuation category section, add the following method declarations below the one forthemeTapped::
-(void)initPlot; -(void)configureHost; -(void)configureGraph; -(void)configureChart; -(void)configureLegend; |
Next, synthesize the new properties in the @implementation section:
@synthesize hostView = hostView_; @synthesize selectedTheme = selectedTheme_; |
Then, add the following code just below the @synthesize lines you added above:
#pragma mark - UIViewController lifecycle methods -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // The plot is initialized here, since the view bounds have not transformed for landscape until now [self initPlot]; } |
To recap, you’ve done a few things:
- You’ve synthesized the host view and selected theme properties.
- You’ve declared that you’re going to initialize the plot.
- You’ve added the method declarations for a few private methods.
Now it’s time to add the private methods you declared above. Add the following code immediately below the themeTapped: implementation:
#pragma mark - Chart behavior -(void)initPlot { [self configureHost]; [self configureGraph]; [self configureChart]; [self configureLegend]; } -(void)configureHost { } -(void)configureGraph { } -(void)configureChart { } -(void)configureLegend { } |
You’ll flesh out these skeleton methods over the rest of the tutorial. As you can see from the above code, when you initialize the plot, you do the following:
- Configure the host.
- Configure the graph within that host.
- Configure the chart.
- And finally, configure the legend for the chart.
You’ll implement the code for each of these steps in turn, but first, compile and run the app to make sure everything’s okay up to this point. You should see something like the following:
Meet the Host
You will now configure the chart host view. Add the following lines to configureHost:
// 1 - Set up view frame CGRect parentRect = self.view.bounds; CGSize toolbarSize = self.toolbar.bounds.size; parentRect = CGRectMake(parentRect.origin.x, (parentRect.origin.y + toolbarSize.height), parentRect.size.width, (parentRect.size.height - toolbarSize.height)); // 2 - Create host view self.hostView = [(CPTGraphHostingView *) [CPTGraphHostingView alloc] initWithFrame:parentRect]; self.hostView.allowPinchScaling = NO; [self.view addSubview:self.hostView]; |
In section #1, you take the parent view bounds (its position and dimensions) and calculate the bounds for a smaller view. The new frame excludes the bounds of the toolbar so that the host view can reside within the parent view without obscuring/overlapping the toolbar.
In section #2, you instantiate a CPTGraphHostingView and add it to the parent view. As the Core Plot documentation notes, a CPTGraphHostingView is simply a container view for a CPTGraph instance. These views enable pinch zooming by default, but the code above disables pinch zooming for the chart in this example.
Now that your graph host has been configured, you need to add a graph to it. Do that by adding the following lines to configureGraph:
// 1 - Create and initialize graph CPTGraph *graph = [[CPTXYGraph alloc] initWithFrame:self.hostView.bounds]; self.hostView.hostedGraph = graph; graph.paddingLeft = 0.0f; graph.paddingTop = 0.0f; graph.paddingRight = 0.0f; graph.paddingBottom = 0.0f; graph.axisSet = nil; // 2 - Set up text style CPTMutableTextStyle *textStyle = [CPTMutableTextStyle textStyle]; textStyle.color = [CPTColor grayColor]; textStyle.fontName = @"Helvetica-Bold"; textStyle.fontSize = 16.0f; // 3 - Configure title NSString *title = @"Portfolio Prices: May 1, 2012"; graph.title = title; graph.titleTextStyle = textStyle; graph.titlePlotAreaFrameAnchor = CPTRectAnchorTop; graph.titleDisplacement = CGPointMake(0.0f, -12.0f); // 4 - Set theme self.selectedTheme = [CPTTheme themeNamed:kCPTPlainWhiteTheme]; [graph applyTheme:self.selectedTheme]; |
Let’s review each portion of the above code section-by-section:
-
Create an instance of CPTXYGraph and designate it as the hosted graph of the host view you created earlier. The CPTGraph is really where the magic happens. It’s important to note that CPTGraph encompasses everything you see in a standard chart or graph: the border, the title, the plotted data, axes, and legend.
In the detailed documentation for Core Plot found here, you’ll notice that the designated initializer for CPTXYGraph has a default padding of 20.0f on each side. In your method, you remov the extra padding by setting the padding to 0.0f .
- Set up the text style you want to use for your graph title. CPTMutableTextStyle allows you to configure the size, font, and weight of any text you wish to add to the graph.
- Set up the title for the graph and set its style to use the style you set up in step #2. You’ve also positioned the title of your graph 12 pixels from the top of the view’s bounding rectangle.
- Declare that the graph will use the “plain white” theme provided by Core Plot. A CPTTheme defines text styles (like the one you configured in step #2), line styles, and even the fills used by a graph. You can use one out of the five built-in themes offered by Core Plot, or alternately, create a customized theme for your app.
Build and run the app to see how you’re progressing. You should see the chart’s title displayed at the top of the screen:
Charting Your Progress
Time to add a pie chart to the graph you just instantiated! Add the following lines of code toconfigureChart:
// 1 - Get reference to graph CPTGraph *graph = self.hostView.hostedGraph; // 2 - Create chart CPTPieChart *pieChart = [[CPTPieChart alloc] init]; pieChart.dataSource = self; pieChart.delegate = self; pieChart.pieRadius = (self.hostView.bounds.size.height * 0.7) / 2; pieChart.identifier = graph.title; pieChart.startAngle = M_PI_4; pieChart.sliceDirection = CPTPieDirectionClockwise; // 3 - Create gradient CPTGradient *overlayGradient = [[CPTGradient alloc] init]; overlayGradient.gradientType = CPTGradientTypeRadial; overlayGradient = [overlayGradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.0] atPosition:0.9]; overlayGradient = [overlayGradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.4] atPosition:1.0]; pieChart.overlayFill = [CPTFill fillWithGradient:overlayGradient]; // 4 - Add chart to graph [graph addPlot:pieChart]; |
Let’s walk through the above code section-by-section:
- Obtain a reference to your graph instance via the host view.
- Instantiate and configure the pie chart, designating the view controller as the delegate and data source (more on this in a moment). You also define the radius for the pie chart (it is, after all, a circle), and give the chart an identifier. The identifier is similar to a view’s tag, but instead of an integer, it’s an NSString instance. You finish by noting the start angle for constructing the pie chart elements and declaring the direction in which new slices are added to the chart.
- Define a CPTGradient and use it to fill the chart. A radial gradient is well suited for a circular pie chart. The gradient is configured to have color stops toward the outside of the circle (between 0.9 and 1.0), adding a shadow to the edge of the pie chart. You can experiment with the colors, alpha values, and/or stop positions to create your own look.
- Add the pie chart to the graph.
If you compile and run the app right now, you’ll be disappointed to see that nothing appears to have changed. The reason is that you’ve designated the view controller as the chart data source, but the data source delegate methods are just stubs at the moment – they don’t return any relevant data.
To remedy this situation, turn your attention to numberOfRecordsForPlot:. As you’ve guessed from the name, this method simply informs the chart how many slices should be displayed. Replace the current placeholder code in numberOfRecordsForPlot: with the following:
return [[[CPDStockPriceStore sharedInstance] tickerSymbols] count]; |
The above line simply calls the CPDStockPriceStore singleton to get an array of ticker symbols, and then counts how many items are in the array to determine the number of slices for the pie chart.
Next, replace the placeholder code in numberForPlot:field:recordIndex: with the following:
if (CPTPieChartFieldSliceWidth == fieldEnum) { return [[[CPDStockPriceStore sharedInstance] dailyPortfolioPrices] objectAtIndex:index]; } return [NSDecimalNumber zero]; |
This method receives the plot to be drawn as well as an index for the record to be displayed. It also receives an enumeration value that differs based on the plot type. In the case of CPTPieChart, you usually look for CPTPieChartFieldSliceWidth and when you find it, you return the daily portfolio prices in the same order as the stock ticker symbols (i.e., 0 for AAPL, 1 for GOOG, 2 for MSFT).
Add data labels to the pie chart by replacing the placeholder code in dataLabelForPlot:recordIndex::
// 1 - Define label text style static CPTMutableTextStyle *labelText = nil; if (!labelText) { labelText= [[CPTMutableTextStyle alloc] init]; labelText.color = [CPTColor grayColor]; } // 2 - Calculate portfolio total value NSDecimalNumber *portfolioSum = [NSDecimalNumber zero]; for (NSDecimalNumber *price in [[CPDStockPriceStore sharedInstance] dailyPortfolioPrices]) { portfolioSum = [portfolioSum decimalNumberByAdding:price]; } // 3 - Calculate percentage value NSDecimalNumber *price = [[[CPDStockPriceStore sharedInstance] dailyPortfolioPrices] objectAtIndex:index]; NSDecimalNumber *percent = [price decimalNumberByDividingBy:portfolioSum]; // 4 - Set up display label NSString *labelValue = [NSString stringWithFormat:@"$%0.2f USD (%0.1f %%)", [price floatValue], ([percent floatValue] * 100.0f)]; // 5 - Create and return layer with label text return [[CPTTextLayer alloc] initWithText:labelValue style:labelText]; |
This method returns a CPTLayer, similar to a Core Animation layer. CPTLayers are abstracted to work on both Mac OS X and iOS, and they provide some other drawing niceties used by Core Plot.
In this instance, the method returns a CPTTextLayer. To construct that CPTTextLayer, you define another mutable text style and use it to create a string that represents each individual stock’s price and its percentage of the overall portfolio.
Now if you build and run, you’ll see a nifty-looking pie chart with a nice shadow gradient, and the text labels you just created. A lot simpler than writing all the Core Graphics rendering code yourself, eh? :]
Legen … Wait For It… dary!
The chart looks pretty nice, but a user will not know which pie slice corresponds to which stock by simply looking at it. So make things a bit more user-friendly by adding the following to configureLegend:
// 1 - Get graph instance CPTGraph *graph = self.hostView.hostedGraph; // 2 - Create legend CPTLegend *theLegend = [CPTLegend legendWithGraph:graph]; // 3 - Configure legend theLegend.numberOfColumns = 1; theLegend.fill = [CPTFill fillWithColor:[CPTColor whiteColor]]; theLegend.borderLineStyle = [CPTLineStyle lineStyle]; theLegend.cornerRadius = 5.0; // 4 - Add legend to graph graph.legend = theLegend; graph.legendAnchor = CPTRectAnchorRight; CGFloat legendPadding = -(self.view.bounds.size.width / 8); graph.legendDisplacement = CGPointMake(legendPadding, 0.0); |
The code simply instantiates and positions the legend. But how do you get the legend data for each slice? That’s handled by legendTitleForPieChart:recordIndex: – replace the existing method content with:
if (index < [[[CPDStockPriceStore sharedInstance] tickerSymbols] count]) { return [[[CPDStockPriceStore sharedInstance] tickerSymbols] objectAtIndex:index]; } return @"N/A"; |
The method simply returns the symbol corresponding to the specified pie slice index.
Build and run. What do you think? I bet Barney would know what to say! :]
One More Thing: Dynamic Theming
You may recall that you configured the app to use the “Plain White” theme that Core Plot offers by default. How about letting the user change the theme at will? To do so, you’re going to modify themeTapped: to present a UIActionSheet.
Add the following to themeTapped::
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Apply a Theme" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:CPDThemeNameDarkGradient, CPDThemeNamePlainBlack, CPDThemeNamePlainWhite, CPDThemeNameSlate, CPDThemeNameStocks, nil]; [actionSheet showFromTabBar:self.tabBarController.tabBar]; |
This method references values from the CPDConstants class that you added via the project’s starter resources. These are basically “human readable” names that correspond to the default Core Plot theme identifiers.
Now you need to implement the clickedButtonAtIndex: UIActionSheetDelegate method to change the graph theme based on the user’s selection. Add the following code toactionSheet:clickedButtonAtIndex::
// 1 - Get title of tapped button NSString *title = [actionSheet buttonTitleAtIndex:buttonIndex]; // 2 - Get theme identifier based on user tap NSString *themeName = kCPTPlainWhiteTheme; if ([title isEqualToString:CPDThemeNameDarkGradient] == YES) { themeName = kCPTDarkGradientTheme; } else if ([title isEqualToString:CPDThemeNamePlainBlack] == YES) { themeName = kCPTPlainBlackTheme; } else if ([title isEqualToString:CPDThemeNamePlainWhite] == YES) { themeName = kCPTPlainWhiteTheme; } else if ([title isEqualToString:CPDThemeNameSlate] == YES) { themeName = kCPTSlateTheme; } else if ([title isEqualToString:CPDThemeNameStocks] == YES) { themeName = kCPTStocksTheme; } // 3 - Apply new theme [self.hostView.hostedGraph applyTheme:[CPTTheme themeNamed:themeName]]; |
This method is fairly straightforward. First, it obtains the title for the UIActionSheet button tapped based on the clicked button index. Then it gets the theme identifier for the theme matching that theme name. Finally, it applies the selected theme to the graph.
Build and run, and try switching themes by tapping the “Theme” button. Here’s an example of the Plain Black theme.
Pretty cool, eh?
Where to Go From Here?
Here is an example project with the code from the tutorial so far.
Congrats, you’ve covered a lot of ground in this tutorial!
- First, you added the Core Plot framework as a static library and set up a simple iPhone app to display three charts.
- Then you proceeded to implement the pie chart, introducing some of the key framework abstractions along the way.
- You concluded by adding a dynamic theming mechanism to your app!
You’re ready for Part 2 of this series, where you’ll add a bar graph and a scatter plot to your “work-in-progress” app. You’ll also explore some options to make your plots interactive!
In the meantime, you might want to check out the Core Plot project site. It includes documentation, examples, and more. Also, if you have any questions or comments about this part of the tutorial, please join our forum discussion below!
相关推荐
7. **性能优化**:CorePlot使用Quartz 2D进行渲染,提供了良好的性能。但处理大量数据时,可能需要考虑数据缓存和异步加载策略,以确保图表的流畅显示。 8. **更新与兼容性**:确保保持CorePlot库的最新版本,因为...
2. **高性能图形渲染**:CorePlot 使用Core Graphics和OpenGL ES进行底层渲染,这保证了图表在各种屏幕分辨率下都能流畅地显示,同时保持良好的性能。 3. **丰富的图表类型**:CorePlot 提供了线图、柱状图、饼图、...
7. **优化性能**:对于大数据集,可以使用CorePlot的离屏渲染特性提高性能。同时,合理设置饼图的缓存策略也能提升绘制效率。 在"CorePlotPieTest"这个示例中,你可能会发现一个完整的代码实现,包括了上述所有步骤...
CocoaPods是Objective-C的依赖管理工具,通过在Podfile中添加`pod 'CorePlot'`然后运行`pod install`即可。如果选择手动导入,可以从GitHub下载Core Plot的源码并将其加入到项目中。 接下来,了解Core Plot的基本...
在实际项目中,可以结合CorePlot与JSON解析库(如JSONKit或NSJSONSerialization)一起使用,以方便地从网络或本地数据存储中加载和显示数据。 总之,CorePlot是iOS和Mac OS X开发中用于数据可视化的强大工具,其...
这个“coreplot example”很可能是某个开发者分享的一个示例项目,展示了如何在Xcode中使用CorePlot库来构建图表。下面将详细探讨CorePlot在iOS开发中的应用以及如何使用它。 1. **CorePlot库介绍** CorePlot是一...
#import <CorePlot/CorePlot.h> @interface BarChartViewController : UIViewController { @private CPXYGraph *barChart; } @property (readwrite, retain, nonatomic) NSTimer *timer; @end ``` 实现...
CorePlot_1.4这个压缩包内的文件列表可能包括以下内容: 1. 源代码文件:Core Plot的Objective-C或Swift实现,包含了各种图表类型的类和方法。 2. 示例项目:包含了一些展示如何使用Core Plot的实例应用,这些例子...
总之,CorePlot源码是一个宝贵的教育资源,它不仅让你能够直接使用这个强大的图表库,还能帮助你提升iOS和macOS平台上数据可视化开发的技能。通过深入研究,你将能够创建出更具吸引力和功能性的图表应用。
Core Plot是一款开源的图形库,专门用于iOS和Mac OS X平台,它提供了丰富的2D图形绘制功能,使得开发者能够方便地在应用中创建各种复杂的图表,如折线图、柱状图、饼图等。这款库的强大之处在于其灵活性和自定义性,...
1. **跨平台兼容性**:由于 Core Plot 需要在 macOS 和 iOS 上都能运行,因此它避免使用特定于某个平台的技术,例如 AppKit 绘图功能。相反,它利用底层的 Quartz 2D API 进行绘图,并通过 Core Animation Layers 来...
打包coreplot源代码,可在模拟器和真机上使用
在这个压缩包中,你将找到一个名为"CorePlotTest"的项目,它包含了使用CorePlot库制作的柱状图、曲线图和饼图的示例代码。 柱状图是数据可视化中常用的一种图表类型,它通过垂直或水平的柱子长度来表示数值大小。...
7. 示例项目:`CorePlotDemo`包含了一系列的示例代码,每个示例都展示了不同的图表类型和配置,开发者可以通过阅读和运行这些代码,快速理解和掌握CorePlot的使用。 总的来说,"CorePlot Demo"是一个实用的学习资源...
本示例工程是基于Xcode 6.0构建的,旨在教授如何将CorePlot库进行简单的封装,以便在项目中更方便地使用。Xcode 6.0是Apple开发的一款集成开发环境(IDE),它包含了编写、测试和调试iOS及macOS应用所需的所有工具。...
我正在使用Cocoapods管理CorePlot。 Pods目录包含在此git存储库中,因此该示例无论如何都应起作用。 从头开始工作的步骤如下: 安装自制软件 使用brew安装干净版本的Ruby 酿造安装Ruby 使用gem安装cocoapods 宝石...
Core Plot使用`CPTPlotSymbol`来表示数据点,你可以选择不同的符号类型,并自定义大小和颜色。对于折线图,通常使用无填充的圆形符号。 8. **交互性** 为了提升用户体验,可以添加手势识别,允许用户通过触摸拖动...
文献资料可以在以下位置找到Core Plot API和高级体系结构的文档:Mac的适用于iOS和tvOS的API文档,内置并在Xcode本地安装(参见在README文件夹查看详情) GitHub上的代码存储库中的文件夹在哪里寻求帮助问答网站...
下面我们将详细探讨CorePlot的核心概念和如何使用它来构建一个数据统计折线图。 1. **CorePlot框架介绍** CorePlot是一个开源的图形库,适用于iOS和macOS平台。它提供了丰富的图表类型和自定义选项,使得开发者...
在提供的"CorePlotDemo"中,你应该能找到一个实际的应用示例,展示如何使用CorePlot来创建和展示数据图表。"源码说明.htm"可能包含了关于这个示例应用的详细说明,包括如何配置项目、导入库、创建图表对象以及添加...