Create charts for iPhone and iPad apps using FusionCharts XT

To provide executives with access to business data on the go, enterprises are adopting iPhones and iPads in droves. Many of these applications have need for smart data visualizations, but are currently restricted by the limited capabilities of available charting libraries for iOS. Some have limited chart types, whereas others lack the visual appeal and interactivity. Open source libraries are not backed by proper technical support either. So what are your options?

Enter FusionCharts XT, which addresses all these concerns. Being a JavaScript charting library, it can easily render charts and widgets within the UIWebView control of an iOS application. With over 90 chart types that are animated and interactive, it augments the visual appeal and functionality of your iOS applications. In addition, dedicated tech support is there to answer any or all of your queries.

You can either obtain the data from a remote web service, or access the local data stores on the device. This data needs to be provided in XML or JSON format that the FusionCharts JavaScript graph object understands. In this blog post, we will show you how to use FusionCharts XT in an iOS app and power it using data from a web service. We will create the necessary XML and HTML required for the UIWebView to display our chart.

Example – An iOS app to plot Twitter data using FusionCharts XT

We will be plotting the count of mentions of ‘HTML5’ for each of the last 7 days in a UIWebView control using FusionCharts XT. This is how your chart will finally look like in an iPhone:

Requirements

You would need to have internet access too. We will be using the
searchhistogram query from the Topsy API. The exact query is
http://otter.topsy.com/searchhistogram.json?q=html5&slice=86400&period=7. You may run this query and see the JSON response, which returns the number of times ‘HTML5’ was mentioned everyday for the last 7 days.

Enable rotation of the chart according to the device’s orientation, so that the chart will fit the screen whether the device is in landscape or portrait mode

Creating the Xcode project

Let us open Xcode and create a View-based project, and save it as FusionChartsXTiOSDemo.

We now need to add FusionCharts XT’s JavaScript files to our project. Copy the JavaScript files present in
Download Package>Charts to the Xcode Resources project group. Make sure you select the
Copy items into destination group’sfolder(ifneeded) checkbox on the top. Doing so would ensure that you have a copy of all the JavaScript files local to your application. Click
Add to add your files to your project.

We need to modify Xcode’s compilation step a little bit. Xcode considers JavaScript files as code (rightfully so) and tries to compile them. However, we want these files to render charts inside our UIWebView and not compiled. Expand the
Targets group and your project target. Our target is called
FusionChartsXTiOSDemo. Also expand the
Copy Bundle Resources and
Compile Sources build phases. Select all the JavaScript files and drag them from the compile stage to the copy bundle build phase.

Add the JSONKit files, namely
JSONKit.h and
JSONKit.m to your project too. We have now prepared Xcode with all the files necessary. Let us begin designing and coding!

Designing and coding

In
FusionChartsXTiOSDemo.h, add an
IBOutlet for the WebView.@property(nonatomic,retain)IBOutlet UIWebView*webView;

Also
@synthesize, and
release this accordingly.

Open your project’s main view controller Interface Builder file (inside the Resources group). For our project this file is called
FusionChartsXTiOSDemoViewController.xib. To add a WebView control to your app, drag a UIWebView from Interface Builder’s library to our view.

We now need to connect the UIWebView outlet to this UIWebView. From the Document Window in Interface Builder, Ctrl+Drag from
File’sOwner to the
UIWebView. You should get a popup bubble, click
webView . Save your work and close Interface Builder.

Next, we will add the required properties needed to create the chart data and its configuration. We will write the following code in
FusionChartsXTiOSDemo.h:

1

2

3

4

5

6

7

8

9

10

// Chart properties.

@property(nonatomic,retain)NSMutableString*htmlContent;

@property(nonatomic,retain)NSMutableString*javascriptPath;

@property(nonatomic,retain)NSMutableString*chartData;

@property(nonatomic,retain)NSMutableString*chartType;

@property(nonatomic,assign)UIInterfaceOrientation currentOrientation;

@property(nonatomic,assign)CGFloat chartWidth;

@property(nonatomic,assign)CGFloat chartHeight;

@property(nonatomic,retain)NSMutableString*debugMode;

@property(nonatomic,retain)NSMutableString*registerWithJavaScript;

Let us also add the properties we require to perform the HTTP request and to handle the response data:

1

2

3

4

5

// Twitter data.

@property(nonatomic,retain)NSMutableString*twitterQuery;

@property(nonatomic,retain)NSMutableData*twitterData;

@property(nonatomic,retain)NSDictionary*twitterDataDictionary;

@property(nonatomic,assign)BOOLtwitterDataError;

Remember to
@synthesize and
release the above properties correctly.

Declare the following 4 methods here; we will define them later.

1

2

3

4

-(void)displayDataError;

-(void)createChartData:(UIInterfaceOrientation)interfaceOrientation;

-(void)plotChart;

-(void)removeChart;

As a best practice, let us keep our first task to handle any error that might crop up because of connectivity issues. For this, we need define the
displayDataError method. We need to create the HTML that displays the error in plain English to the user in his WebView.

We have created the HTML content to be shown in the WebView in case of a network error, or in case the Topsy API is unable to respond. For testing this method, we could simulate a network error either by unplugging the LAN cable or turning off the WiFi. When you’ve done either of these, run the project, and this is the error that you should see:

After this, let us concern ourselves with the HTTP query and handling it’s JSON response.

Uncomment the
viewDidLoad method, and create and execute the query to Topsy’s API:

Finally, using JSONKit, let us convert the data stored in
self.twitterData to a dictionary. Once the data has been converted, we call the
createChartData::(UIInterfaceOrientation)interfaceOrientation method.

1

2

3

4

5

6

7

8

9

-(void)connectionDidFinishLoading:(NSURLConnection*)connection

{

// Convert received JSON data to an Objective-C dictionary.

self.twitterDataDictionary=[self.twitterData objectFromJSONData];

// Create chart as per current orientation.

self.currentOrientation=self.interfaceOrientation;

[self createChartData:self.currentOrientation];

}

In the
createChartData::(UIInterfaceOrientation)interfaceOrientation method, we need to parse through the dictionary and form our XML. Note that the dictionary has two keys named
request and
response. Within
response, there is an array named
histogram, which holds the count of mentions of ‘HTML5’ for the last 7 days. We need to get hold of this array in
NSArray.

We continue the same code block to iterate through
histogramData and form the chart data in XML. Since the numbers in the array are for the previous 7 days, starting from yesterday, we need to calculate and format the date accordingly.

In the same code block, we create the HTML required to show the chart. Note the path of
FusionCharts.js in the
<script></script> tag. We will provide the base URL when we actually load the HTML in the WebView.

We need to dispose of the chart before we render it again according to the new orientation. To do this, we can can empty
chart_container of all the HTML. Let us write the
removeChart method to do this.

Next, we need to know exactly when the device begins to rotate. For this, we have the
)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration class method. In this method, we will first check if the data is valid; so that an error message will be displayed even upon rotation. Next, we store the orientation to which the device is rotating to. Then we remove the chart and render it again according to the new orientation.

In the
createChart method, we need to supply the new chart dimensions to the FusionCharts object according to the orientation. So let us add the following code just before the block where we create the chart XML:

Let us now run this project. Rotate your iPhone Simulator by ⌘+Left Arrow or ⌘+Right Arrow.

Download sample project

The sample project that we created is available for download. We used Xcode 3.2 and the target was iOS 4.2.

Taking it further

You can expand on this project by using the other chart types provided by FusionCharts. You can interface with a database on the backend, and provide a UI to create the SQL queries in the WebView itself. You could make use of the Spark Line charts provided in FusionWidgets XT and create a html5 dashboard for your iPhone and iPad users. Drill-down JavaScript charts are also super easy to create. The field is open for experimentation. Do share your implementations with us.

The FusionCharts constructor takes in parameters as follows:
– Chart’s SWF name: This is automatically mapped to the JavaScript alias when rendering in JavaScript mode.
– Unique ID for chart: All charts should have unique IDs
– Width and Height: Dimensions can be specified in pixels or in percentages. When specified in percentages, the chart will relate to the container element.
– Enable Debug Mode: This is a Boolean which controls the Debug Window when rendered in Flash. For debugging in JavaScript, please refer to the JavaScript Debugging Documentation.
– Register with JavaScript: This parameter allow the FusionCharts JavaScript Object to interact with the chart. This is always set to ‘1’ internally.

The points you illustrate about refactoring the code to follow MVC are correct.

We believe you can further refine your code in this way:

Model:
(1) Retrieve the data
(2) Check for its validity

Controller:(1) Setup chart size
(2) Setup the required XML and HTML
(3) Call the View from the Controller to draw the chart

View:(1) Display the chart

Essentially we’re are calling the View from the Controller itself. The code required to draw the chart should be in the Controller, while the View should simply interpret this code and render the chart.

Hi, this tutorial is awesome and you can understand it pretty good… but I am trying to put the graph as a extra view in a view controller… like a small chart in the bottom of the view linked to the variables given by some labels in the view controller, is there anyway you know a tutorial about this? or can you explain this please? I really need your help…
1… resizing the chart to look smaller and in a corner
2… link the bars (in the graph) with some label, so the user can type the numbers

When you want to configure the chart according to some variables, you would need to follow the same technique as we did to create chart data using Twitter API. Simply pick the variables and include them while constructing the XML string.

You could reduce the size of the chart by (a) reducing the dimensions of the UIWebView, or (b) by setting the chart dimensions in pixels. In this tutorial, we’ve specified the chart dimensions in percentages.

Can you please explain what you mean by “link the bars … so the user can type”?

I want two bars in the UIWebView… and the user will type a variable in a textfield, then the graph will shows the results… can you please give me a code example of how to do this? how to link the bars with some textfields or labels from a different view controller… I am new with Xcode and can’t find a way to connect this together with the graph…

I had tried the sample approcah and able to present the graphs on my ipad app.
But one area where I am confused about drill down charts. In the Web sample , I had seen when user clicks a chart it is getting redirected to particular page and the appropriate graphs are getting displayed.
So how to do the same using ios? I mean how to detect the click on a particular bar and render apprpriate graph in ios?

To render a Single series line chart, modify Column3D.swf to Line .swf using the following code:
[self.htmlContent appendFormat:@”var chart_object = new FusionCharts(‘Line.swf’, ‘twitter_data_chart’, ‘%f’, ‘%f’, ‘0’, ‘1’);”, self.chartWidth, self.chartHeight];

// Override to allow orientations other than the default portrait orientation.
– (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES since we support all orientations.
returnYES;
}

Hi Naveen,
“Chart will render here.” message appears when the FusionCharts JavaScript files are inaccessible.
Please check have you pasted the JavaScript files (FusionCharts.js, FusionCharts.HC.js, FusionCharts.HC.Charts.js and jquery.min.js) in the required folder?
You could also check if the HTML & XML strings are proper by writing them to the Xcode console.

Hi Elakya,
As mentioned earlier, the message appears when the FusionCharts JavaScript files are inaccessible.

Also, ensure there are any JavaScript syntax or runtime errors that might have halted the execution of FusionCharts APIs. To debug, you could check if the HTML & XML strings are proper by writing them to the Xcode console.

Thanks for responding. I was able to plot the Pie3D chart bys using the latest JS files from Fusion charts. Do you have any link with the capabilities of the current version of Fusion Charts XT. Because I am trying to plot a hlineargauge chart, but the chart says the “Chart type not supported”

Thanks for the good tutorial.
However I have been facing an issue where upon redrawing the chart maybe say on a button click, there is a flicker. Wanted to know if there is any way to remove this.
A possibility could be because the control is completely removed and the white background is shown in the short interval before it redraws again. Is there a way to retain the background of the control and only animate the bars when i wish to redraw the chart?

Yes, it is possible to get these type of data in iOS. The above XML data format is for Multi Series chart type. So while passing the chart type to the FusionCharts constructor, please specify the Multi Series chart type as per your requirement.

Is it possible to show multiple values within a single bar (base value in green, exceeded value in red etc within a single bar)? We have done this using using the Fusion charts in the browser but not sure if this capability exists now in the mobile version.

If it was possible to display multiple values within a single bar in the browser, the same can be achieved in the mobile version. Starting FusionCharts XT we support automatic fallback and the same code can be executed in both browser/mobile version without changing a single line of code.

Hi! I tried compiling your project, but what I receive is a “No data to display” where the graph is suppossed to be, I inserted a flag (actually a NSLog(“Here!”);) right after self.twitterDataError = YES; in order to know if there was a Twitter connection error, but no, is not a Twitter connection error, so I´m suspecting this has to see with the the Twitter API, as this was made with iOS 4.2 in mind and now we are in last iOS 6 version (next release will be 7), any idea what´s going on?? thanx i.a.

Thank you Swarnam, it worked great, just a misplaced “, the correct placement is right before the closing ]:
self.twitterQuery = [NSMutableString stringWithFormat:@”%@”, @”http://otter.topsy.com/searchhistogram.json?q=html5&slice=86400&period=7&apikey=SDLXOEYG5E5NQP6HQYLQAAAAAB3K5VL55NIQAAAAAAAFQGYA”];

How can we direct use JSON data with fusion ? I am trying to implement chart in IOS app, it`s working fine with XML data using “setXMLData“, but i tried with “setJSONData” and pass json string in it but i always get Message “Chart will render here.“

“Chart will render here.” message appears when the FusionCharts JavaScript files are inaccessible. Please ensure you’ve copied jquery.min.js, FusionCharts.HC.js and FusionCharts.HC.Widgets.js in the same folder as FusionCharts.js.

Also, ensure there are any JavaScript syntax or runtime errors that might have halted the execution of FusionCharts APIs. To debug, you could check if the HTML & XML strings are proper by writing them to the Xcode console.

Can somebody paste here the content of an example JSON file, which could be a replacement of the file from the following link: “http://otter.topsy.com/searchhistogram.json?q=html5&slice=86400&period=7”. The API id expired and the example app cannot display the chart (return a message like “no data to display”).

For those who don’t want to play with API key, here is an example definition of JSON for this app. Just place it somewhere on the web (or local server like MAMP), and modify the self.twitterQuery assignment. Looks pretty cool.

Fabulous work by fusioncharts team !
I’m trying to implement fusionchart to my iphone application. I have downloaded the sample code. When i run the application, it says ‘no data to display’ even though i changed the API key. When i executed the “http://otter.topsy.com/searchhistogram.json?q=html5&slice=86400&period=7&apikey=SDLXOEYG5E5NQP6HQYLQAAAAAB3K5VL55NIQAAAAAAAFQGYA” in address bar, it says error: invalid user. What could be the issue ? and also i would like to know how to pass locally stored data to the chart ?
Thanks,
Pradeep

If I use new FusionCharts(‘Pie3D’, ‘twitter_data_chart6′, ‘%f’, ‘%f’, ’0′, ’1′); in iPAD Webview I am not getting Pie chart in 3D format.
Also enablemultislicing is not working in recent version..how to perform that function?