Skip to main content

Draw graphs in Java webapp with Plotly - Tutorial [Part 2]

Plotly Javascript library supports generating various charts. Java Servlet & JSP based web applications can use it to display graphical representations of data.

In this tutorial, you will learn to include graphs into a simple Java web application. Image above shows the graph generated at the end of the tutorial. Complete project is already moved to github for your references.

This tutorial consists of two parts.

Part 1

First step is to create a simple web application with index.jsp that can submit a user entered parameter to a Servlet which is redirecting the user back to original index.jsp.

Part 2

Here the servlet is modified to return some data (collection of Customer objects) and index.jsp is modified to draw a chart using that data.

Note: If you are not that familiar with Java web applications, I recommend you to start with previous Part 1 of this tutorial before moving further.

Part 2

Java web application project structure in Part 1 must be modified as shown in below image.

Servlet Changes

Servlet class must return a list of Customers to the index.jsp. For that, a simple Customer class and a modification to Servlet is needed.

1. Create a Customer class

This class is used to represent the data send to index.jsp from CustomerServlet. It has an id as well as age & salesCount.
package com.digizol.webapp.plotly;

public class Customer {

    private String id;
    private int age;
    private int salesCount;

    public Customer(String id, int age, int salesCount) {
        this.id = id;
        this.age = age;
        this.salesCount = salesCount;
    }

    public String getId() {
        return id;
    }
    public int getAge() {
        return age;
    }
    public int getSalesCount() {
        return salesCount;
    }
}

2. CustomerServlet returning Customer object list

doGet() method is modified to return a list of Customer objects. This class has 10 Customer objects. Size of returned list will be based on the 'size' request parameter submitted via index.jsp. This Servlet will return that list as "customersList" to index.jsp.
package com.digizol.webapp.plotly;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
import java.util.*;

public class CustomerServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        System.out.println("Parameter [size] value = " + request.getParameter("size"));
        // return a customers list to index.jsp
        request.setAttribute("customersList",
                getCustomers(resultSize(request.getParameter("size"))));
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    }

    private List<Customer> customers = new ArrayList<Customer>();

    public CustomerServlet() {
        initCustomersList();
    }

    private int resultSize(String sizeParam) {
        return sizeParam==null?customers.size():Integer.parseInt(sizeParam);
    }

    private List<Customer> getCustomers(int size) {
        return customers.subList(0, size);
    }

    private void initCustomersList() {
        customers.add(new Customer("cust-1", 25, 17));
        customers.add(new Customer("cust-2", 36, 99));
        customers.add(new Customer("cust-3", 17, 0));
        customers.add(new Customer("cust-4", 58, 10));
        customers.add(new Customer("cust-5", 49, 32));
        customers.add(new Customer("cust-6", 80, 14));
        customers.add(new Customer("cust-7", 31, 78));
        customers.add(new Customer("cust-8", 22, 89));
        customers.add(new Customer("cust-9", 43, 21));
        customers.add(new Customer("cust-10", 74, 45));
    }
}

3. Get plotly javascript

Download the plotly-latest.min.js Javascript file from here. Place this file under src/main/webapp/plotly/js directory as shown in image.

4. index.js Changes

index.js file needs below changes.

1. Add plotly javascript file to index.jsp
2. Javascript function to draw chart
3. Add a DIV for chart
4. Update index.jsp to organize data for Javascript
5. Update index.jsp to draw chart

Fully completed index.jsp page code looks as below, do not worry. Each change is explained in details after the code.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>

<head>
    <title>Customer Information Center</title>
    <script src="plotly/js/plotly-latest.min.js" type="text/javascript"></script>

    <script type="text/javascript">
        function plotChart(elementId, data, layout) {
            Plotly.newPlot(document.getElementById(elementId), 
                           data, layout, {displayModeBar: false});
        }
    </script>
</head>

<body>

<div style="background:#ffffee; text-align:center; padding-bottom:2px">
<h1>Customer Information Center</h1>

Draw customer information graph.<p/>

<form action="customers" method="get">

    Results size:
    <select name="size">
      <option value="5">5</option>
      <option value="10">10</option>
    </select>
    <p/>
    <button style="padding:5px">Draw Chart</button>
</form>
</div>

<c:if test="${not empty customersList}">

<h2>Age and Sales Count Chart</h2>

<div id="customersChart" ></div>

<script>

    var customerAges = {
          name: 'Age',
          type: 'lines+markers',
          line: { width: 6},
          marker: { size: 8}
        };
    var customerSalesCount = {
          name: 'Sales Count',
          type: 'lines+markers',
          line: { width: 3},
          marker: { size: 4}
        };
    var age_X = new Array();
    var age_Y = new Array();
    var sales_count_X = new Array();
    var sales_count_Y = new Array();

    <c:forEach items="${customersList}" var="customer" varStatus="i">
        age_X[${i.index}] = "${customer.id}";
        age_Y[${i.index}] = "${customer.age}";

        sales_count_X[${i.index}] = "${customer.id}";
        sales_count_Y[${i.index}] = "${customer.salesCount}";
    </c:forEach>

    customerAges.x = age_X;
    customerAges.y = age_Y;

    customerSalesCount.x = sales_count_X;
    customerSalesCount.y = sales_count_Y;

    var data = [customerAges, customerSalesCount];
    var layout = {
        xaxis: {
            title: 'ID',
            showgrid: true,
            zeroline: true,
        },
        yaxis: {
            showgrid: true,
            showline: true,
            zeroline: true,
        }
    };

plotChart("customersChart", data, layout);
</script>
</c:if>

</body>
</html>
Each change has a specific reason.

1. Add plotly javascript file to index.jsp

A reference to plotly Javascript file is placed within <head> tags of index.jsp as below.
<head>
    <title>Customer Information Center</title>
    <script src="plotly/js/plotly-latest.min.js" type="text/javascript"></script>
</head>
2. Javascript function to draw chart
Write a simple function named "plotChart" to draw graphs using plotly as follows inside <head> tag of index.jsp
<head>
    <title>Customer Information Center</title>
    <script src="plotly/js/plotly-latest.min.js" type="text/javascript"></script>

    <script type="text/javascript">
        function plotChart(elementId, data, layout) {
            Plotly.newPlot(document.getElementById(elementId), 
                           data, layout, {displayModeBar: false});
        }
    </script>
</head>
3. Add a DIV for chart

It is required to provide an empty DIV element for plotly to generate the chart.
<div id="customersChart" ></div>
4. Update index.jsp to organize data for Javascript
index.jsp page must iterate through the list of Customer objects returns from CustomerServlet as "customersList". Then, Javascript objects must be populated using that data in order to generate the graphs.

As Customer has two attributes age & salesCount, it is possible to draw two lines in one chart. As shown below, x & y properties of customerAges and customerSalesCount must be populated correctly.
    var customerAges = {
          name: 'Age',
          type: 'lines+markers'
        };
    var customerSalesCount = {
          name: 'Sales Count',
          type: 'lines+markers',
        };
    var age_X = new Array();
    var age_Y = new Array();
    var sales_count_X = new Array();
    var sales_count_Y = new Array();

    
        age_X[${i.index}] = "${customer.id}";
        age_Y[${i.index}] = "${customer.age}";

        sales_count_X[${i.index}] = "${customer.id}";
        sales_count_Y[${i.index}] = "${customer.salesCount}";
    

    customerAges.x = age_X;
    customerAges.y = age_Y;

    customerSalesCount.x = sales_count_X;
    customerSalesCount.y = sales_count_Y;
5. Update index.jsp to draw chart

Using customerAges & customerSalesCount Javascript objects, invoke plotChart() method to generate a chart inside "customersChart" div.
    var data = [customerAges, customerSalesCount];
    var layout = {
        xaxis: {
            title: 'ID'
        },
        yaxis: {
            showgrid: true
        }
    };

    plotChart("customersChart", data, layout);

Final Result

Below is the final outcome of the application after building & deploying. It shows two line graphs, for age and sales count.



Hope this helps.

Comments

Popular posts from this blog

Java Sorting: Comparator vs Comparable Tutorial

Web Services with Apache Axis 1.4 Tutorial: server and client sides

Creative Commons License Digizol by Kamal Mettananda is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 License .
URL of this page must be supplied in attribution
© 2004-2017