Build a graph visualization iPad Application

6th May, 2015

`One of the great things about HTML5 canvas – the rendering engine at the heart of KeyLines  – is its compatibility with all modern browsers. Any graph visualization application you build with the KeyLines toolkit can be easily made available to users through mobile devices like smartphones and tablets.

Many KeyLines developers choose to simply direct their mobile users to a URL where the KeyLines app is hosted. This allows a central control of the application and a consistent experience to users across all devices.

However, if you’re planning on integrating KeyLines into applications targeted at specific mobile device users, an alternative approach could be to package KeyLines into your mobile app. This would give you the opportunity to utilise native controls and make the KeyLines application look and feel like a native mobile application.

Let’s look at how you can get started with one of these mobile apps by building a graph visualization app for iPad, using the KeyLines toolkit.

We’re going to just use a very simple graph visualization example to demonstrate the core aspects of embedding KeyLines into the App and then communicating between the native interface controller to the KeyLine JavaScript API.

Step 1: Create the KeyLines JavaScript Controller

Once you have your login details for the KeyLines SDK (contact us to get access), we recommend taking some time to read the Getting Started documentation and downloading the relevant files.

We’re going to be using the iOS WebView control, which supports HTML5 Canvas, so we only need to download our JavaScript files.

This code snippet shows a very simple KeyLines “hello world” graph visualization example.


<html>
  <head>
    <link rel='stylesheet' type='text/css' href='css/keylines.css'/>
    <script type="text/javascript" src="js/keylines.js"></script>
    <script type="text/javascript">
      var chart;

      function klReady(err, charts) {
        chart = charts
        
        chart.load({
          type: 'LinkChart',
          items: [
            {id:'id1', type: 'node', x:100, y: 150, t:'hello', c: '#B9121B'},
            {id:'id2', type: 'node', x:400, y: 150, t:'world', c: '#B9121B'},
            {id:'id1-id2', id1: 'id1', id2:'id2', type: 'link', d: { count: 20} , a2: true, c: '#4c1b1b'}
          ]
        });
      } 

      window.onload = function () {
        KeyLines.paths({assets: 'assets/'});
        KeyLines.create('kl', klReady);
      };

    </script>
  </head>
  <body>
    // The HTML element that will be used to render the KeyLines component 
    <div id="kl" style="width: 1024px; height: 768px;" ></div>
  </body>
</html>

Step 2: Create the Xcode Project for your iPad app

Next, let’s start Xcode and create an iOS Single View Application project for our KeyLines graph visualization application. For this project we have chosen Swift as the development language and we’re going to target the application just for the iPad.


Once the project is created, let’s move the KeyLines files to the project directory and use the Xcode File ‘Add Files To menu’ option to add them to the project. So, our project should now look something like this:


Now lets add the WebView control and load up our JavaScript file. Add the following to the ViewController.swift file.

import UIKit
import WebKit

class ViewController: UIViewController {

    var myWebView = WKWebView()
    var myParamView = UIView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        initialise()
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func initialise() {
        addWebView()
    }
    
    func addWebView(){
        myWebView = WKWebView(frame: self.view.frame)
        // Loading the index.htm file into the webview
        let localfilePath = NSBundle.mainBundle().pathForResource("index", ofType: "htm", inDirectory: "keylines")
        let myRequest = NSURLRequest(URL: NSURL(fileURLWithPath: localfilePath!)!)
        myWebView.loadRequest(myRequest)
        self.view.addSubview(myWebView)
    }
}

Things to note from the above:

  • We’re going to use the WKWebView from the new WebKit (this was introduced with iOS 8) as it offers a significant performance improvement over the old UIWebView in UIKit
  • We’ll load the index.htm from the local bundle directly into the WKWebView, so should be able to see our KeyLines visualization straight away.

If you build and run this in the “iPad 2” simulator you should see the following:


That was easy!

Step 3: Add Some iOS Native Controls

Now lets add a native iOS control and manage the communication to our KeyLines JavaScript controller.

First, we’re going to add a new function to our KeyLines JavaScript (add this into the HTML page within the script tag), which will enable us to toggle link widths.

function showLinkWidth(show) {
   var links = [];
   chart.each({type: 'link'}, function(item){
       links.push({id: item.id, w: show ? item.d.count : 1})
   });
   chart.animateProperties(links, {time:300} );
}

Now we need to add a native control to Xcode project and hook that up to calling this invoking this new JavaScript function.

Let’s start by adding a UIView onto our WKWebView and then adding a UISegmentedControl. You could do this through the Xcode’s Interface Builder but as it’s only one control we’re going to do this programmatically. Add the following method to your ViewController.

func addOnOffToggle(){
        // Our container for the toggle
        var containerView = UIView(frame: CGRectMake(10.0 , self.view.bounds.height - 50.0, 120.0, 50.0))
        self.view.addSubview(containerView)
        
        // Add toggle segmented controls
        myToggle = UISegmentedControl(items: ["Off", "On"])
        myToggle.frame = CGRectMake(10.0, 10.0, 100.0, 30.0)
        myToggle.selectedSegmentIndex = 0
        myToggle.backgroundColor = UIColor.whiteColor()
        myToggle.addTarget(self, action: "callToggleChange:", forControlEvents: .ValueChanged)
        containerView.addSubview(myToggle)
    }

When the UISegmentedControl is actioned it will call the callToggleChange method, so let’s add that as well.

func callToggleChange(sender:UISegmentedControl!)
    {
        var title = myToggle.titleForSegmentAtIndex(sender.selectedSegmentIndex)!
        var val = title == "On"
        // Here we’re calling the JS function from Swift!
        var js = "showLinkWidth((val));"
        myWebView.evaluateJavaScript(js, completionHandler: nil)
    }

You will see here that we are creating a string that represents a call to the JavaScript showLinkWidth function we defined above. Then using the evaluateJavaScript method on our WKWebView, we can evaluate that JavaScript, which will then toggle the display of line widths.


That’s it. We now have an iOS App with native controls that controls our KeyLine JavaScript controller.

Step 4: Two-way communication

One of the natural extensions that you may also want to make, would be to allow communication the other way. WKWebView has significantly improved the communication from the web to the app with message handlers. So, if you want to implement two-way communication (between your web and app) then you’ll need to look there.

Build your own graph visualization web application

Obviously, this is just a starting point. There’s still work to do to design our graph visualization, but in a short space of time we have successfully build an iOS App containing a KeyLines chart.

To give it a go for yourself, or to trial the KeyLines graph visualization SDK, Contact the team!

Read more blog posts about Integrations.