Creating Android Charts with HTML/Javascript : JQuery Flot


As an alternative to creating Android charts in pure Java, an interesting possibility exists for creating charts using the handy old WebView and HTML/Javascript approach.

Initially, I know….most people would’nt prefer this approach…but if you give it some thought, it can open a whole range of other possibilities to explore!

NOTE to self:
RGraph uses the HTML5 Canvas component, which is NOT accommodated in the webkit packaged with Android 1.5. RGraph works nicely & tested with Android 2.1 and 2.2.


Example of the HTML/Javascript approach:

  1. Calendar using Epoch
  2. 3D-Rotating cube uses HTML/Javascript

Note: I know it silly but the RGraph version got its own: Android RGraph Charting

Download: TestAndroidGraphView

Steps involved:

  1. Create an assets directory for HTML files – Android internally maps it to file:///android_asset/ (note singular asset)
  2. Copy flot_graph.html into it: res/assets/flot_graph.html
  3. Create a javascript directory: res/assets/javascript/flot

Some notes:

  • Ability to interaction with the plot/chart via Javascript  by checking data series

Note: As you guys/gals may have noticed, the data values are hard-coded..(naughty naughty naughty). This was done to keep things simple as possible. Ideally the data would come from a data source/content provider such as SQLite or Web service. I like the Active Record approach and will provide some details in my next article on doing Active Record for Android android-active-record

Screen Orientation/Rotation Changes in Android .
Bumping my own Page/Thread – you cant get any more ridiculous than me:
Wanna do cheap tricks with your Android: Say you have a list of data values in a ListView
and upon device rotation change the view automatically changes to Landscape view with a graphical chart view plot. Passing parameters data values between Activity Views using
Intent “extras” Bundles.

Flot: http://www.filefactory.com/file/b3e8764/n/flot.tar.gz

Javascript Interaction – Select data set to display

Zoomable Controls:

Steps involved:

  1. Create the XML-Layout file wherein you declare the WebView holder
  2. Create the HTML and include the Javascript code
  3. Create the Android Activity

1. Create the XML-Layout file declaring the WebView
File: graphview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	android:background="#FFFFFF">

	<WebView
		android:id="@+id/webview"
		android:layout_width="fill_parent"
		android:layout_height="fill_parent">
	</WebView>
</LinearLayout>

2. Create the HTML and include the Javascript code
File: flot_graph.html

<html> 
 <head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
    <title>Flot Examples</title> 
    <link href="./javascript/flot/examples/layout.css" rel="stylesheet" type="text/css"></link> 
    <!--[if IE]><script language="javascript" type="text/javascript" src="./javascript/flot/excanvas.min.js"></script><![endif]--> 
    <script language="javascript" type="text/javascript" src="./javascript/flot/jquery.js"></script> 
    <script language="javascript" type="text/javascript" src="./javascript/flot/jquery.flot.js"></script> 
 </head> 
    <body> 
    <div id="placeholder" style="width:600px;height:300px;"></div> 
 
    <p id="choices">Show:</p> 
 
<script id="source" language="javascript" type="text/javascript"> 
$(function () {
    var datasets = {
        "Symptoms": {
            label: "Symptoms",
            data: [[1988, 10], [1989, 20], [1990, 10], [1991, 30], [1992, 40]]
        },        
        "Reactions": {
            label: "Reactions",
                        data: [[1988, 0], [1989, 0], [1990, 10], [1991, 30], [1992, 40]]
            
        },
        "Injections": {
            label: "Injections",
                        data: [[1988, 0], [1989, 0], [1990, 0], [1991, 30], [1992, 40]]
            
        },
      
    };
 
    // hard-code color indices to prevent them from shifting as
    // countries are turned on/off
    var i = 0;
    $.each(datasets, function(key, val) {
        val.color = i;
        ++i;
    });
    
    // insert checkboxes 
    var choiceContainer = $("#choices");
    $.each(datasets, function(key, val) {
        choiceContainer.append('<br/><input type="checkbox" name="' + key +
                               '" checked="checked" id="id' + key + '">' +
                               '<label for="id' + key + '">'
                                + val.label + '</label>');
    });
    choiceContainer.find("input").click(plotAccordingToChoices);
 
    
    // 
    function plotAccordingToChoices() {
        var data = [];
 
        choiceContainer.find("input:checked").each(function () {
            var key = $(this).attr("name");
            if (key && datasets[key])
                data.push(datasets[key]);
        });
 
        if (data.length > 0)
            $.plot($("#placeholder"), data, {
                yaxis: { min: 0 },
                xaxis: { tickDecimals: 0 }
            });
    }
 
    plotAccordingToChoices();
});
</script> 
 
 </body> 
</html> 

3. Create the Android Activity
File: Main.java


import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

/**
 * Test for Flot/Javascript for plotting on Android
 * 
 * @author wagied davids
 * 
 */
public class Main extends Activity
	{

		/** Called when the activity is first created. */
		@Override
		public void onCreate(Bundle savedInstanceState)
			{
				super.onCreate(savedInstanceState);
				setContentView(R.layout.graphview);

				// Get a reference to the declared WebView holder
				WebView webview = (WebView) this.findViewById(R.id.webview);

				// Get the settings
				WebSettings webSettings = webview.getSettings();

				// Enable Javascript for interaction
				webSettings.setJavaScriptEnabled(true);

				// Make the zoom controls visible
				webSettings.setBuiltInZoomControls(true);

				// Allow for touching selecting/deselecting data series
				webview.requestFocusFromTouch();

				// Set the client
				webview.setWebViewClient(new WebViewClient());
				webview.setWebChromeClient(new WebChromeClient());

				// Load the URL
				webview.loadUrl("file:///android_asset/flot_graph.html");
			}
	}

13 thoughts on “Creating Android Charts with HTML/Javascript : JQuery Flot

  1. Hi,

    Very good article, but rather than having hard-coded values, how could the javascript read data from the database to plot the graph?

    Thanks,
    db

  2. hi
    i am using also flot and for small charts it works perfect.
    but if i try to show a lots of measurement points android hangs.
    with a lot i mean mor than 2000 points.
    has anyone an a idea how to fix this?
    same chart showing on pc/firefox works perfect, just on android oened with the android browser it hangs :(

    • Hi Rainer,
      Using FLOT/JQuery for plotting on Android is good for small data sets as you may have found out, but for large data sets
      I would use android-charts- you will find it on my blog as well. Personally, I have plotted the 2000 data points in multiple data series plot for stress
      testing… works fine.
      The problem with the FLOT approach, is that it:
      1. Runs the WebView….
      2. Load the HTML/Javascript files
      3. Does the actual display plotting.

      So, it gonna be alot slower than Android-charts which uses JFreeCharts underneath.

      -W

  3. Hi
    Its a great graph
    but i want to draw x axis over dates
    Want to show graph of last six month… i tried so many date format but it only accepts values
    is there any solution?

  4. Hi..

    May I know the code to sign on the canvas for android.
    I have one working for iPhone but unfortunately android simulator is not supporting.
    Any suggestions are appreciated.

  5. Thanks for the excellent example you posted. It has helped me a grat deal with my app. Following the Flot examples of the official flot site, I learnt that I can apply Options in a FlotDraw object in order to apply color markings (that is, a horizontal colored zone of fixed width) in the xy grid.
    For example, the way to apply a horizontal blue zone between 20-40 in your example is :
    Options opt = new Options();
    Vector markings = new Vector();
    markings.add(new MarkingData(0xADFF2F, 0, null, new RangeData(80, 120)));
    opt.grid.markings = markings;
    FlotDraw fd = new FlotDraw(sds, opt, null);
    All methods above, derive from com.flotandroidchart.flot.

    Question: Is there a way to apply such markings to apply color in the grid in the jquery flot example you posted? Any help is more than valuable…. Thanks!

    • The solution was in front of my eyes all the time, so if you yell or laugh at me, I won’t bother :-)
      I should simply use the grid markings as it is clearly explained in the flot API.
      Keep up the good work!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s