JSF & Highcharts (Javascript Chart Library)

Since a while, I've been interested and looking out for technologies related to web-based visualization techniques/tools/frameworks/libraries...not the image rendering techniques, but the dynamic and interactive ones. Lately, I've been researching into Javascript Chart Libraries, as I was planning to work on some pet projects and also implement it in one of my work projects. After the resurrection of AJAX techniques and with all the Javascript frameworks that are available, we have a good number of options to generate dynamic and interactive charts/graphs. Among all the libraries, I found Highcharts to be the best and the most suitable charting library for my projects. Also, I took a special interest in Highcharts after seeing the way it's implemented on Stackoverflow.com's User Reputation Graph page.

To understand how it works, I worked on a sample project which displays JVM's Heap memory usage, in a chart generated by Highcharts Javascript framework. Below are the technical details of this demo project:

Technology Stack: Java, JSF, Facelets, Maven, Richfaces, Gson, Highcharts

This web application 'polls' the server every 5 seconds (This configuration can be changed) and asks for heap memory usage statistics, gets back the data in JSON format, which is then used by the Highcharts, to generate and display the chart. Google's Gson framework is used to convert Java objects into JSON format.

Below is the Sample Javascript code for Highcharts, for generating the chart:



Here are other jsFiddle links for this script:

1) jsFiddle Link
2) jsFiddle - Result


Below is the code for XHTML file, which is the home page for this application, where the chart is displayed:





    
        
        
        
        
        
    

    
        
            

            


Below is the code for Series.java class, which holds the 'series' data for Highcharts' chart data:

import java.util.List;

/**
 *
 * @author Babji Prashanth, Chetty
 */
public class Series {
    private String name;
    private List<Long> data;

    public Series() {}

    public Series(String name, List<Long> data) {
        this.name = name;
        this.data = data;
    }
}


Below is the code for ChartController.java. This contains the server side running code, which is polled from the client side, to get JVM's heap memory usage statistics:

package com.bchetty.charts.controller;

import com.bchetty.charts.model.Series;
import com.google.gson.Gson;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Chart Controller
 *
 * @author Babji Prashanth, Chetty
 */
public class ChartController {
    private String chartData;
    private String categories;
    private List<String> categoryList = new ArrayList<String>();
    private List<Long> heapSizeList = new ArrayList<Long>();
    private List<Long> usedHeapSizeList = new ArrayList<Long>();
    SimpleDateFormat sdfDate = new SimpleDateFormat("HH:mm:ss");//dd/MM/yyyy
    private static final long MB = 1024*1024;
    int index = 0;
    private Long[] longs;
    
    /**
     * Load Chart Data
     */
    public void loadChartData() {
        if(heapSizeList.size() > 10) {
            heapSizeList.remove(0);
            usedHeapSizeList.remove(0);
            categoryList.remove(0);
        }
        List<Series> series = new ArrayList<Series>();
        
        malloc();
        long heapSize = Runtime.getRuntime().maxMemory();
        heapSizeList.add(heapSize/MB);
        usedHeapSizeList.add((heapSize - Runtime.getRuntime().freeMemory())/MB);
        
        series.add(new Series("Heap Size", heapSizeList));
        series.add(new Series("Used Heap", usedHeapSizeList));

        setChartData(new Gson().toJson(series));
        
        categoryList.add(sdfDate.format(new Date()));
        
        setCategories(new Gson().toJson(categoryList));
    }

    /**
     * @return the chartData
     */
    public String getChartData() {
        return chartData;
    }

    /**
     * @param chartData the chartData to set
     */
    public void setChartData(String chartData) {
        this.chartData = chartData;
    }

    /**
     * @return the categories
     */
    public String getCategories() {
        return categories;
    }
    
    /**
     * @param categories the categories to set
     */
    public void setCategories(String categories) {
        this.categories = categories;
    }
    
    private void malloc() {
        if(index%2 == 0) {
            longs = new Long[100000];
            for(int i=0;i<1000;i++) {
                longs[i] = Long.valueOf(i);
            }
        } else {
            longs = null;
        }
        index++;
    }
}


As you see in the above code, the heap memory usage is calculated and stored in Series objects, which is then deserialized into JSON format, for further use by Highcharts framework on the client side. Also, note that apart from 'Series' data, 'categories' data used on the X-Axis of chart, is also dynamically provided, by calculating time data (HH:MM:SS format) and converting it into JSON format.

All source code for this project is available in my Github Repository: richCharts Github Repo (Feel free to clone or fork it).

Below is a video, which shows the demo project in action (JVM's Heap Memory Usage):






6 comments:

  1. Hi, great post !
    I like Highcharts too. What do you think about my JSF wrapper :
    https://github.com/yanLanglois/jsfcharts

    with the demo here :
    http://showcase-jsfcharts.rhcloud.com/home.jsf

    ReplyDelete
  2. Hi Yan,

    If the charts had been different from the ones that are used for demo on Highcharts, it would have been great...Anyways, it's good to know that you already tried building a JSF wrapper, as I'd a similar idea of building JSF custom components for some charting library. I will take a look into your source code on Github and follow that. Thanks for the comment. :)

    ReplyDelete
    Replies
    1. Thank you, you are right ! Thank you for this good idea.
      I will try to show others charts for the demo.

      Delete
  3. Above code for Internal memory status of CUP,so how can we add real time data ie such as from list of data or database ,would you please give another example so bar chart.

    ReplyDelete
  4. Hi, thanks for this tutorial.
    I have one question, if is possible remove "" and call just one time? What a component pure jsf or hichfaces i can use?

    Thaks.

    ReplyDelete
  5. Hi,

    as an alternative, you can also use highfaces (http://www.highfaces.org). It supports turning any List (or several ones) into charts. You won't have to manually write any JavaScript or JSON and gain full integration into JSF (e.g. AJAX click events on points).

    ReplyDelete

Note: Only a member of this blog may post a comment.