Play framework, Uncategorized

Create Good Looking Charts With Play, Flot and JQuery

Oftentimes, web sites need to display different kinds of data in web charts. As always, there are a bunch of different frameworks and libraries to choose from. After some investigation I decided to try out the Flot library together with Play.

Flot is an easy to use Javascript plotting library for JQuery producing nice looking charts on the client side. We’ll see how we can use Flot together with Play to create good looking charts with very little effort. There are a few things that makes this an especially smooth ride:

  • The Flot library is really easy to use.
  • The high usability of the Play framework
  • JSON and JQuery


Post update


A while back Nico at Learn To Play was kind enough to put together a minimalistic working version based on the code in this post. If you’re going to use this in a project or similar I recommend that you download the code and give it a try. You’ll find the link to the zip in the comments section.

Getting started

In the following it is assumed that you already have the Play framework installed and have some basic understanding of how the framework works (if not you should take the time to read up, the documentation is really good)

Download the Flot library from Flot and import the the script in the page where you want to use it:

<script src="@{'/public/javascripts/jquery.flot.js'}"></script>

In my case I put the import in the main.html page that all the pages inherit from.

Take a look at the examples and documentation to get a basic understanding of how the library works. You don’t need to understand it all, but as a minimum you need to know how the plot function works and the basics around formatting the series.

Example: Displaying the number of visitors

The chart below shows the number of visitors on a make believe web site for March.

Views per day for a fictive web site
Views per day

The chart was of course created with Flot. In my opinion the chart has an attractive look and best of all, it was created with only a few lines of code. Let’s see how…

Presentation Layer Code

As you probably know, a Play application follows the MVC architectural pattern. We’ll now look at the code for the View and the Controller.

#{extends 'main.html' /}
#{set title:'Dashboard' /}

<div id="mainContent">
<section id="comments">
<center><h1>Stats</h1></center>
<article>

<div id="placeholder" style="width: 800px; height: 400px;"></div>

<script id="source" language="javascript" type="text/javascript">
$(function () {
	var options = {
			grid: {
				hoverable: true, clickable: true, backgroundColor: { colors: ["#000", "#999"] }
			},
	        series: {
	            lines: {show: true}
	        },
	        legend: { noColumns: 2, position: "ne" },
	        yaxis: { min: 0 },
	        xaxis: {mode: "time", timeformat: "%d/%m"}
	    };
    
	var data = [];
    var placeholder = $("#placeholder");
    $.getJSON("@{Dashboard.getViewsPerDay(3)}", function(views){
        $.each(views, function(index, view){
            data.push([view.dayInMillis,view.totalViews]);
        });
        $.plot(placeholder, [ { label: "Views per day March", data: data } ], options);
    });        
});
</script>
 
</article>
 </section>
</div>

The code should be fairly easy to understand. A couple of things worth noticing though. First of all the placeholder div is where the graph is going to end up, you need to specify the height and width. Next thing worth noticing is the declaration of the options variable. Here we define the the properties of the graph. You can learn more about the various possibilities by reading the Flot API description and examples.

Flot needs to get the data to plot as an array of points. So you can easily specify the data points directly in an array on the client side. Oftentimes though, you need to get the data from the server side. The JQuery $.getJSON method is a perfect fit for this. The method loads JSON encoded data from a server using a GET HTTP request. It takes an URL as input and if the request to the URL succeeds, a callback function is executed.

On line 27 we do the $.getJSON method call, getting view data from the server by calling the method getViewsPerDay(int month) on the Dashboard controller class. The result of the request is passed to the callback function. On lines 28 – 30 we loop through the list. For each object in the list we push the data to plot into the variable data. Notice that we must add the date in milliseconds as this is required by the flot library. Finally, on line 31 we do the plot. That’s it! Time to take a look at the Controller class


import models.*;

public class Dashboard extends Controller{

   public static void views(){
      render();
   }

  public static void getViewsPerDay(int month){
	renderJSON(DailyView.findViewsForMonth(month));
  }
}

Not much to explain. We get a List of DailyView objects for a month from the model object. This list is then passed to the built-in Play Controller method renderJSON which renders a 200 OK JSON response. No logic here, the controller class is just responsible for getting data and rendering it.

Model

Our example contains only one model class, the DailyView JPA model object. It contains a find method which gets the DailyView objects for the requested month. Here’s what it looks like.

package models;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.Entity;
import play.db.jpa.Model;

@Entity
public class DailyView extends Model{

	public Date day;
	public long totalViews;
	public long dayInMillis;

	public static List<DailyView> findViewsForMonth(int month) {
		return find("select d from DailyView d where MONTH(d.day) =? ", month).fetch();
	}
}

Next steps

With only a few lines of code we are able to create good looking charts displaying data we retrieve from the server. There are many ways to configure your charts with Flot, in this example we’ve only scratched the surface. I highly recommend looking at the Flot examples to learn more about how you can further customize your charts.

Advertisements

30 thoughts on “Create Good Looking Charts With Play, Flot and JQuery

  1. Hi,

    Interesting article, Any chance you could also add the output of your server side call. I’m having troubles getting ‘time’ data to display correctly. Everything else works and I really hoped the information I needed was here, even using your options don’t seem to do it. My x-axis just keep showing me integers. Have you had the same issues with the time feature while developping?

  2. Hi, thank you for your feedback.

    I did have a few problems during development with regards to displaying the dates correctly, the Flot library requires it to be in ms to display it. I did the conversion to milliseconds server side. I see that the code in the post does not show this explicitly. What I did was simply to loop through the dates and convert to milliseconds (server side). Not a very elegant solutiion but it worked.

    So, check that you are returning the date as milliseconds. If you still can’t display the dates properly, please let me know and I will try to help as best as I can.

  3. Hi again,

    I’m actually tried this as well and it just doesn’t seem to do it, for some reason it just totally disregards all the time stuff. It keeps showing me the millisecond timestamps. I’m starting to think this is a bug, I mean, it’s not THAT hard to grasp imho still it doesn’t seem to work. Your post here was like the closest I could find with some real information I could use, the time examples on the flot page all use years which is just a integer and not a real date string. I stopped messing about once I noticed nothing really changed when I play with : tickFormatter, xaxis: {mode: “time”, timeformat: “%m/%d” } etc. It just keeps showing me the milliseconds numbers. Thanks a lot for your thoughts on the matter. (I use the API docs, the thing about milliseconds I knew already, I’m only so desperate since what I read and try doesn’t seem to work out as intented).

  4. Ok, I understand. I know I had this working when posting this. Unfortunately I no longer have a running example, but I will try to get it up running again. I’ll let you know once I have something running.

  5. Hi Ketil and all,

    Since I wanted to give your flot demo using Play! a try, I played around and put together the minimalistic working solution based on your published code, it simply uses the in-memory store to put some sample data on startup and provides the flot graph using the default index action, just visit http://localhost:9000/ to see the graph.

    You can download this mini play app (53K, using Play 1.0.3.2 and Flot 0.6) here.

    Hope this will be a bit of help for other coming by your post.

    Cheers,
    Niko

  6. Just looking at your sample code, the Controller seems to have more { than }, so probably won’t compile, and I think it is missing the keyword “class” on line 3 as well.

  7. Your absolutely right, thanks for pointing that out 🙂 Probably a copy paste error. The sample code is now corrected.

  8. Hello, back again.

    You might notice that this post is some hours after my previous post, well I finally got your code working.

    You might also like to change line 15 in your model from

    public long dayInMilles;

    to

    public long dayInMillis;

    to match up with the rest of the references. I spent quite some time trying to find that bug.

    Sorry if I am not quite as friendly / polite as I usually would be, but I had gone into this side project thinking that getting the demo code up and running would be a simple case of c+p and a little hacking. Little did I know i would have been far better off just following the documentation and never laying eyes on this post other than to know that flot exists.

    Please at least run your demo code before you blog about how awesome it is and quick it is to get up and running..

    1. Hi again,

      I’m very sorry that I’ve wasted your time, my apologies.

      About a year ago, Niko posted a comment where he shared a minimalistic version based on my sample code. Did you try that sample code? I tried it and at that time it worked at least on Play 1.1

      I will link to this comment, or the code at the top of the post.

      Wish you could have posted your comment before wasting too much time. Then I could have pointed you to the zip Nico created.

      Thanks,
      Ketil

  9. With havin so much content and articles do you ever run into any
    issues of plagorism or copyright infringement? My website has a lot of unique content I’ve either created myself or outsourced but it appears a lot of it is popping it up all over the web without my authorization. Do you know any solutions to help protect against content from being ripped off? I’d truly appreciate it.

    1. I have seen some of my material pop up on different sites, but it hasn’t been a huge problem. I don’t know how to prevent that from happening, sorry.

  10. Unfortunately, Niko’s version doesnt work on the newest Play 2.2.1 framework! Do you know what I need to change for it to run on the new play?

    1. Hi Ashley. No, I don’t know what it takes to make it run on 2.2.1. Play 2 is quite different from 1.2 so I think it basically needs to be re-written.

  11. I don’t leave a response, however after looking at through a few of the responses on this page Create Good Looking Charts With Play, Flot and JQuery | Walk the walk. I actually do have a couple of questions for you if you tend not to mind. Is it only me or do some of the comments appear as if they are written by brain dead visitors? 😛 And, if you are posting on additional social sites, I would like to keep up with everything fresh you have to post. Could you make a list of all of your social networking sites like your Facebook page, twitter feed, or linkedin profile?

  12. Most computers employed in business, and many employed in the
    home, no more operate inside old self contained
    fashion. They separate themselves using their company fund mangers by personally investing their particular money
    side-by-side with their investors inside fund, creating an utter structure of accountability.
    When I ask why, they reply with, ‘Well I just lack time.

  13. Hey there! This is kind of off topic but I need some help from an established blog.
    Is it tough to set up your own blog? I’m not very techincal but I can figure things out pretty fast. I’m thinking about making my own but I’m not sure where to start. Do you have any points or suggestions? Cheers

  14. Digital radio is promoting the offering that radio companies can offer and these can be categorised into some from the following genres:.
    Some with the facts to support exactly the same are illustrated
    under:. The biggest flaws with grease traps and grease
    interceptors are sizing, pumping, and odors.

  15. Hello! Someone in my Facebook group shared this website with us so I came to look it over.

    I’m definitely enjoying the information. I’m book-marking
    and will be tweeting this to my followers! Wonderful blog and superb design and style.

  16. I truly love your website.. Very nice colors & theme.

    Did you develop this site yourself? Please reply back as I’m attempting to create my very own
    site and want to find out where you got this from or just what the theme is called.
    Thank you!

  17. I’m not that much of a internet reader to be honest but your sites really nice, keep it up!
    I’ll go ahead and bookmark your website to come back down the road.
    Many thanks

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