XChart using AJAX, JSP and Servlet

We know that xchart basically displays different statistical data on different chart types such as column chart, bar chart, line chart, pie chart etc. You can have a look at the URL http://tenxer.github.io/xcharts/ for more information.

You can integrate xchart with any server side technology but here I will show you how to integrate xchart using AJAX, JSP and Servlet. This tutorial shows step by step so that we can understand how it happens. It displays the data for site visitors log in line chart. I have also put a calendar for date-picker so that you can pick a custom range of dates and get the visitor statistics in xchart. The calendar has more features like you can select Today, Yesterday, Last One week, Last One month etc. On mouse hover on the line chart you can see the visitors count on a particular date.
If you have any query please feel free to leave a comment.

Prerequisites
JDK 1.7
Eclipse 3.6
Maven 2.x
Tomcat Server 7.x
XChart API
Final Output

XChart using AJAX, JSP and Servlet

Now we will see steps how to implement it
Step 1. Create a maven based web project in Eclipse
Step 2. Modify pom.xml file as shown below

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.roytuts</groupId>
    <artifactId>test-webapp</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>test-webapp Maven Webapp</name>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.el</groupId>
            <artifactId>javax.el-api</artifactId>
            <version>2.2.4</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.2.4</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>test-webapp</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Step 3. Modify web.xml file as shown below

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
    <display-name>Archetype Created Web Application</display-name>
    <servlet>
        <servlet-name>XChartServlet</servlet-name>
        <display-name>XChartServlet</display-name>
        <description></description>
        <servlet-class>com.roytuts.servlets.XChartServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>XChartServlet</servlet-name>
        <url-pattern>/xChartServlet</url-pattern>
    </servlet-mapping>
    <!-- will be shown this page when application starts up -->
    <welcome-file-list>
        <welcome-file>chart.jsp</welcome-file>
    </welcome-file-list>
</web-app>

Step 4. Create a POJO class for XChart data model

package com.roytuts.pojo;
public class ChartModel {
  private String date;
  private Long visits;
  public ChartModel(String date, Long visits) {
    this.date = date;
    this.visits = visits;
  }
  public String getDate() {
    return date;
  }
  public void setDate(String date) {
    this.date = date;
  }
  public Long getVisits() {
    return visits;
  }
  public void setVisits(Long visits) {
    this.visits = visits;
  }
}

Step 5. Create sample static data for XChart. You will usually fetch dynamic data from your database and show your data onto XChart.

package com.roytuts.repository;
import java.util.ArrayList;
import java.util.List;
import com.roytuts.pojo.ChartModel;
public class XChartData {
  private static final List<ChartModel> CHART_MODELS;
  static {
    CHART_MODELS = new ArrayList<ChartModel>();
    CHART_MODELS.add(new ChartModel("06/01/2015", 99l));
    CHART_MODELS.add(new ChartModel("06/02/2015", 102l));
    CHART_MODELS.add(new ChartModel("06/03/2015", 130l));
    CHART_MODELS.add(new ChartModel("06/04/2015", 120l));
    CHART_MODELS.add(new ChartModel("06/05/2015", 109l));
    CHART_MODELS.add(new ChartModel("06/06/2015", 154l));
    CHART_MODELS.add(new ChartModel("06/07/2015", 127l));
    CHART_MODELS.add(new ChartModel("06/08/2015", 146l));
    CHART_MODELS.add(new ChartModel("06/09/2015", 93l));
    CHART_MODELS.add(new ChartModel("06/10/2015", 96l));
    CHART_MODELS.add(new ChartModel("06/11/2015", 115l));
    CHART_MODELS.add(new ChartModel("06/12/2015", 121l));
    CHART_MODELS.add(new ChartModel("06/13/2015", 165l));
    CHART_MODELS.add(new ChartModel("06/14/2015", 198l));
    CHART_MODELS.add(new ChartModel("06/15/2015", 176l));
    CHART_MODELS.add(new ChartModel("06/16/2015", 201l));
    CHART_MODELS.add(new ChartModel("06/17/2015", 187l));
    CHART_MODELS.add(new ChartModel("06/18/2015", 189l));
    CHART_MODELS.add(new ChartModel("06/19/2015", 147l));
    CHART_MODELS.add(new ChartModel("06/20/2015", 174l));
    CHART_MODELS.add(new ChartModel("06/21/2015", 159l));
  }
  public static List<ChartModel> getHighChartDataList() {
    return CHART_MODELS;
  }
}

Step 6. Create a data transfer object that will represent XChart data point for actual chart representation

package com.roytuts.dto;
public class ChartDto {
  private String label;
  private Long value;
  public ChartDto(String label, Long value) {
    this.label = label;
    this.value = value;
  }
  public String getLabel() {
    return label;
  }
  public void setLabel(String label) {
    this.label = label;
  }
  public Long getValue() {
    return value;
  }
  public void setValue(Long value) {
    this.value = value;
  }
}

Step 7. Create a servlet that will handle request and response from a user

package com.roytuts.servlets;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import com.roytuts.dto.ChartDto;
import com.roytuts.pojo.ChartModel;
import com.roytuts.repository.XChartData;
/**
 * Servlet implementation class HighChartServlet
 */
public class XChartServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
  List<ChartModel> chartModels;
  /**
   * @see Servlet#init(ServletConfig)
   */
  @Override
  public void init(ServletConfig config) throws ServletException {
    //get data for XChart
    chartModels = XChartData.getHighChartDataList();
  }
  /**
   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
   */
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request, response);
  }
  /**
   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
   */
  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Gson gson = new Gson();
    String json = "";
    //get start date from request parameter
    String sDate = request.getParameter("start");
    //get end date from request parameter
    String eDate = request.getParameter("end");
    if (sDate != null && eDate != null) {
      System.out.println("Start Date : " + sDate);
      System.out.println("End Date : " + eDate);
      //Actual data should come from database
      //select data from database based on start date and end date
      //here I am neither going to fetch data from database nor fetch data based on date range
      //you need to manipulate those things from database
      List<ChartDto> chartDtos = new ArrayList<ChartDto>();
      for (ChartModel chartModel : chartModels) {
        ChartDto chartDto = new ChartDto(chartModel.getDate(), chartModel.getVisits());
        chartDtos.add(chartDto);
      }
      if (!chartDtos.isEmpty()) {
        //convert list of pojo model to json for plotting on graph
        json = gson.toJson(chartDtos);
      } else {
        json = "No record found";
      }
    } else {
      json = "Date must be selected.";
    }
    System.out.println(json);
    //write to the response
    response.getWriter().write(json);
  }
}

Step 8. Create a JSP file for viewing the graph

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>XChart using JSP, Servlet</title>
<link rel="stylesheet"
    href="<%=request.getContextPath()%>/assets/css/charts/chart.css">
<link rel="stylesheet"
    href="<%=request.getContextPath()%>/assets/css/charts/xcharts.min.css">
<link rel="stylesheet"
    href="<%=request.getContextPath()%>/assets/css/charts/bootstrap.min.css">
<link rel="stylesheet"
    href="<%=request.getContextPath()%>/assets/css/daterangepicker.css">
<script type='text/javascript'
    src="<%=request.getContextPath()%>/assets/js/jquery-1.9.1.min.js"></script>
<script type='text/javascript'
    src="<%=request.getContextPath()%>/assets/js/jquery-migrate-1.2.1.js"></script>
<script type='text/javascript'
    src="<%=request.getContextPath()%>/assets/js/jquery-ui-1.10.3-custom.min.js"></script>
<script type='text/javascript'
    src='<%=request.getContextPath()%>/assets/js/charts/d3.min.js'></script>
<script type='text/javascript'
    src='<%=request.getContextPath()%>/assets/js/charts/sugar.min.js'></script>
<script type='text/javascript'
    src='<%=request.getContextPath()%>/assets/js/charts/xcharts.min.js'></script>
<script type='text/javascript'
    src='<%=request.getContextPath()%>/assets/js/charts/script.js'></script>
<script type='text/javascript'
    src='<%=request.getContextPath()%>/assets/js/daterangepicker.js'></script>
</head>
<body>
    <div style="margin: 10px 0 0 10px;">
        <h3>XChart Example using AJAX, JSP and Servlet</h3>
        <form class="form-horizontal">
            <fieldset>
                <div class="input-prepend">
                    <span class="add-on"><i class="icon-calendar"></i> </span> <input
                        type="text" name="range" id="range" />
                </div>
            </fieldset>
        </form>
        <div id="msg"></div>
        <div id="placeholder">
            <figure id="chart"></figure>
        </div>
    </div>
</body>
</html>

Step 9. AJAX call through jQuery and XChart API. This is part of script.js file

$(function() {
    // Set the default dates
    var startDate = Date.create().addDays(-6), // 7 days ago
    endDate = Date.create(); // today
    var range = $('#range');
    // Show the dates in the range input
    range.val(startDate.format('{MM}/{dd}/{yyyy}') + ' - '
            + endDate.format('{MM}/{dd}/{yyyy}'));
    // Load chart
    ajaxLoadChart(startDate, endDate);
    range.daterangepicker({
        startDate : startDate,
        endDate : endDate,
        ranges : {
            'Today' : [ 'today', 'today' ],
            'Yesterday' : [ 'yesterday', 'yesterday' ],
            'Last 7 Days' : [ Date.create().addDays(-6), 'today' ],
            'Last 30 Days' : [ Date.create().addDays(-29), 'today' ]
        }
    }, function(start, end) {
        ajaxLoadChart(start, end);
    });
    // The tooltip shown over the chart
    var tt = $('<div class="ex-tooltip">').appendTo('body'), topOffset = -32;
    var data = {
        "xScale" : "time",
        "yScale" : "linear",
        "main" : [ {
            className : ".stats",
            "data" : []
        } ]
    };
    var opts = {
        paddingLeft : 50,
        paddingTop : 20,
        paddingRight : 10,
        axisPaddingLeft : 25,
        tickHintX : 9, // How many ticks to show horizontally
        dataFormatX : function(x) {
            // This turns converts the timestamps coming from
            // ajax.php into a proper JavaScript Date object
            return Date.create(x);
        },
        tickFormatX : function(x) {
            // Provide formatting for the x-axis tick labels.
            // This uses sugar's format method of the date object.
            return x.format('{MM}/{dd}');
        },
        "mouseover" : function(d, i) {
            var pos = $(this).offset();
            tt.text(d.x.format('{Month} {ord}') + ', No. of visits: ' + d.y)
                    .css({
                        top : topOffset + pos.top,
                        left : pos.left
                    }).show();
        },
        "mouseout" : function(x) {
            tt.hide();
        }
    };
    // Create a new xChart instance, passing the type
    // of chart a data set and the options object
    var chart = new xChart('line-dotted', data, '#chart', opts);
    // Function for loading data via AJAX and showing it on the chart
    function ajaxLoadChart(startDate, endDate) {
        // If no data is passed (the chart was cleared)
        if (!startDate || !endDate) {
            chart.setData({
                "xScale" : "time",
                "yScale" : "linear",
                "main" : [ {
                    className : ".stats",
                    data : []
                } ]
            });
            return;
        }
        // Otherwise, issue an AJAX request
        //URL of the servlet with POST request
        $.post('http://localhost:8080/test-webapp/xChartServlet', {
            start : startDate.format('{MM}/{dd}/{yyyy}'),
            end : endDate.format('{MM}/{dd}/{yyyy}')
        }, function(data) {
            if ((data.indexOf("No record found") > -1)
                    || (data.indexOf("Date must be selected.") > -1)) {
                $('#msg').html('<span style="color:red;">' + data + '</span>');
                $('#placeholder').hide();
                chart.setData({
                    "xScale" : "time",
                    "yScale" : "linear",
                    "main" : [ {
                        className : ".stats",
                        data : []
                    } ]
                });
            } else {
                $('#msg').empty();
                $('#placeholder').show();
                var set = [];
                $.each(data, function() {
                    //build array of chart data
                    set.push({
                        x : this.label,
                        y : parseInt(this.value, 10)
                    });
                });
                chart.setData({
                    "xScale" : "time",
                    "yScale" : "linear",
                    "main" : [ {
                        className : ".stats",
                        data : set
                    } ]
                });
            }
        }, 'json');
    }
});

Step 10. Download below assets directory and put it under webapp directory

assets

Step 11. Run the application on Tomcat server. You will get the desired output in the browser.
That’s all. Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *