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");
			}
	}

15 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!

  6. graph is bot being displayed , am getting error as follows “Uncaught ReferenceError: $ is not defined at file:///android_asset/flot_graph.html:16
    “. can you help me to solve this issue ?

  7. hi,is it possible to modify the code so as to read from file..my file includes..”6215,12:56 02/09/2013″ i want to plot 6215 in y axis and time 12.56 in x axis..This file is in the tablets sd card and is updated automatically…any help to draw such dynamic graph please..Im new to jquery will you please help me to achieve this…

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 )

Google+ photo

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

Connecting to %s