Visual Mining contact us | site map | search

Products Solutions Resource Library Services Customers Partners Developers Company
Developers

NetCharts® Pro and a Java Performance Dashboard

This example shows a performance dashboard - a page containing a collection of charts that provides an "at-a-glance" summary of the state of some complex system or organization. The source code is below.

Netcharts Pro Java Performance Dashboard

Source Code

// Copyright 2002 by Visual Mining, Inc, Rockville, MD USA
// Permission to use, copy, modify, and to distribute this software
// and its documentation for any purpose is hereby granted
// without notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Visual Mining Inc. disclaims all warranties with regard to this software,
// including all implied warranties of merchantability and fitness.
// In no event shall Visual Mining Inc. be liable for any special, indirect
// or consequential damages or any damages whatsoever resulting from
// loss of use, data or profits, whether in an action of contract,
// negligence or other tortuous action, arising out of or in
// connection with the use or performance of this software
//

package ncpro.examples.servlet;

import java.io.*;
import java.awt.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import netcharts.pro.common.*;
import netcharts.pro.util.*;
import netcharts.pro.charts.bar.NFBarchart;
import netcharts.pro.common.barset.*;
import netcharts.pro.charts.line.NFLinechart;
import netcharts.pro.common.lineset.*;
import netcharts.pro.common.rectangular.*;
import netcharts.pro.charts.dial.*;
import netcharts.pro.charts.bubble.*;
import ncpro.examples.datamodel.CSV1DDataModel;

/**
*
* This servlet produces an HTML page that contains an image of a
* chart generated by NetCharts Pro.
*
* This servlet gets called twice in order to completely render a page
* containing a chart image. The first pass fetches the chart and
* builds an HTML page that contains a reference to that chart. The
* second pass provides the actual image data.
*
* Pass 1:
* Gets the name of the chart template to use.
* Creates an instance of the appropriate chart using the given template.
* Generates an image and image map
* delivers the image map and HTML page to the client.
*
* Pass 2:
* extract the image data from the servlet session.
* deliver the image data to the client.
*
* This servlet takes an optional parameters during pass 1:
* "chartTemplateFile" - the chart template file to load.
* if unspecified, a hardcoded barchart is used.
*/

public class PerformanceDashboard extends HttpServlet {
protected String RED_COLOR = "xcc8888";
protected String YELLOW_COLOR = "xcccc88";
protected String GREEN_COLOR = "x88cc88";

public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
if(NFServletUtil.isSecondPass(req)) {
// The request contains a session variable referencing the image.
// write the image to the output.
NFServletUtil.writeImage(req, res);
} else {
res.setContentType("text/html");
java.net.URL cdlFile = null;
// First create the various charts to include in the page.
cdlFile = PerformanceDashboard.class.getResource("/cdltemplates/CustSat.cdl");
NFGraph chart = null;
String barchart = "";
try {
// Create the chart object from the template.
chart = NFGraph.getGraphFromTemplate(cdlFile, HttpUtils.getRequestURL(req).toString(), null);
// We now have to set some dynamic information from the data source.
loadCustomerSatisfactionData(chart);
// Generate an image and image map.
barchart = NFServletUtil.getDrillDownPage(chart, req, null, false);
chart.stop();
} catch (Exception ex){
writeOutputError(res.getOutputStream(), "Customer Satisfaction Chart creation failed", ex);
return;
}

cdlFile = PerformanceDashboard.class.getResource("/cdltemplates/MissedTrips.cdl");
String linechart = "";
try {
// Create the chart object from the template.
chart = NFGraph.getGraphFromTemplate(cdlFile, HttpUtils.getRequestURL(req).toString(), null);
// We now have to set some dynamic information from the data source.
loadMissedTripData(chart);
// Generate an image and image map.
linechart = NFServletUtil.getDrillDownPage(chart, req, null, false);
chart.stop();
} catch (Exception ex){
writeOutputError(res.getOutputStream(), "Missed Trips Chart creation failed", ex);
return;
}

cdlFile = PerformanceDashboard.class.getResource("/cdltemplates/FuelUse.cdl");
String dialchart = "";
try {
// Create the chart object from the template.
chart = NFGraph.getGraphFromTemplate(cdlFile, HttpUtils.getRequestURL(req).toString(), null);
// We now have to set some dynamic information from the data source.
loadFuelUseData(chart);
// Generate an image and image map.
dialchart = NFServletUtil.getDrillDownPage(chart, req, null, false);
chart.stop();
} catch (Exception ex){
writeOutputError(res.getOutputStream(), "Fuel Use Chart creation failed", ex);
return;
}

cdlFile = PerformanceDashboard.class.getResource("/cdltemplates/Ridership.cdl");
String riderchart = "";
try {
// Create the chart object from the template.
chart = NFGraph.getGraphFromTemplate(cdlFile, HttpUtils.getRequestURL(req).toString(), null);
// We now have to set some dynamic information from the data source.
loadRidershipData(chart);
// Generate an image and image map.
riderchart = NFServletUtil.getDrillDownPage(chart, req, null, false);
chart.stop();
} catch (Exception ex){
writeOutputError(res.getOutputStream(), "Cost vs. Revenue Chart creation failed", ex);
return;
}

cdlFile = PerformanceDashboard.class.getResource("/cdltemplates/CostVsRevenue.cdl");
String bubblechart = "";
try {
// Create the chart object from the template.
chart = NFGraph.getGraphFromTemplate(cdlFile, HttpUtils.getRequestURL(req).toString(), null);
// We now have to set some dynamic information from the data source.
loadCostData(chart);
// Generate an image and image map.
bubblechart = NFServletUtil.getDrillDownPage(chart, req, null, false);
chart.stop();
} catch (Exception ex){
writeOutputError(res.getOutputStream(), "Chart creation failed", ex);
return;
}

// Release for collection.
chart = null;

// Create the web page and embed the charts.
ServletOutputStream os = res.getOutputStream();
os.println("<html>");
os.println("<head>");
os.println("<title>Springfield Transit System</title>");
os.println("<style>");
os.println(".myh3 { font-family: Arial; }");
os.println("</style>");
os.println("</head>");
os.println("<body>");
os.println(NFServletUtil.getRolloverJavaScript());
os.println("<center>");
os.println("<h3 class=\"myh3\">Springfield Transit System - Dashboard View</h3>");
os.println("");
os.println("<table>");
os.println("<tr>");
os.println("<td align=\"center\" valign=\"top\" colspan=\"3\">");
// Add the CostVsRevenue chart
os.println(bubblechart);
os.println("</td>");
os.println("</tr>");
os.println("<tr>");
os.println("<td align=\"center\" valign=\"top\">");
// Add the Customer Satisfaction chart
os.println(barchart);
os.println("</td>");
os.println("<td align=\"center\">");
// Add the Missed Trips chart
os.println(linechart);
os.println("</td>");
os.println("<td align=\"center\">");
// Add the Fuel Use chart
os.println(dialchart);
os.println("</td>");
os.println("</tr>");
os.println("<tr>");
os.println("<td align=\"center\" valign=\"top\" colspan=\"3\">");
// Add the Ridership chart
os.println(riderchart);
os.println("</td>");
os.println("</tr>");
os.println("</table>");
os.println("</center>");
os.println("</body>");
os.println("</html>");
}
}

public void loadCustomerSatisfactionData(NFGraph theChart) throws Exception {
NFBarchart chart = (NFBarchart)theChart;

InputStream csvInput = PerformanceDashboard.class.getResourceAsStream("/exampledata/TransitDataSummary.txt");
CSV1DDataModel csm = null;
String colFilter = "";
String rowFilter = "";

// Set the bar labels from the months in the data set.
colFilter = "0";
rowFilter = "1*";
csm = new CSV1DDataModel(csvInput, colFilter, rowFilter, ",");
NFVector barLabels = new NFVector();
barLabels.loadDataModel(csm);
chart.setDataLabels(barLabels);

// Retrieve the BarSeries of the chart.
NFBarSeries bs = chart.getBarSeries();
NFBarSet set = (NFBarSet)bs.elementAt(0);
// Create the data values for the data set.
csvInput.reset();
colFilter = "12";
rowFilter = "1*";
csm = new CSV1DDataModel(csvInput, colFilter, rowFilter, ",");
set.loadDataModel(csm);
// Set the BarSeries of the chart.
bs.setElementAt(set, 0);
chart.setBarSeries(bs);

NFVector colorTable = new NFVector();
int green = 90;
int yellow = 80;
int red = 70;
for (int i=0; i < csm.getNumPoints(); i++){
Object v = csm.elementAt(i);
try {
int val = Integer.parseInt(v.toString());
if (val >= green)
colorTable.addElement(GREEN_COLOR);
else if (val >= yellow)
colorTable.addElement(YELLOW_COLOR);
else
colorTable.addElement(RED_COLOR);
} catch (Exception ex){
colorTable.addElement("black");
}
}
chart.setColorTable(colorTable);
csvInput.close();
csvInput = null;
}

public void loadMissedTripData(NFGraph theChart) throws Exception {
NFLinechart chart = (NFLinechart)theChart;

InputStream csvInput = PerformanceDashboard.class.getResourceAsStream("/exampledata/TransitDataSummary.txt");
CSV1DDataModel csm = null;
String colFilter = "";
String rowFilter = "";
int green = 500;
int yellow = 600;
int red = 650;

// Set the bottom labels from the months in the data set.
colFilter = "0";
rowFilter = "1*";
csm = new CSV1DDataModel(csvInput, colFilter, rowFilter, ",");
NFAxis bottomAxis = chart.getBottomAxis();
NFVector bottomLabels = new NFVector();
bottomLabels.loadDataModel(csm);
bottomAxis.setTicLabels(bottomLabels);
chart.setBottomAxis(bottomAxis);

// Retrieve the LineSeries of the chart, reset and set the colors.
NFLineSeries ls = chart.getLineSeries();
NFLineSet greenSet = (NFLineSet)ls.elementAt(0);
greenSet.setColor(new Color(136, 204, 136));
greenSet.addElement("null"); // Padding
NFLineSet yellowSet = (NFLineSet)ls.elementAt(1);
yellowSet.setColor(new Color(204, 204, 136));
yellowSet.addElement("null"); // Padding
NFLineSet redSet = (NFLineSet)ls.elementAt(2);
redSet.setColor(new Color(204, 136, 136));
redSet.addElement("null"); // Padding
// Retrieve the full set of values.
csvInput.reset();
colFilter = "7";
rowFilter = "1*";
csm = new CSV1DDataModel(csvInput, colFilter, rowFilter, ",");
// Iterate through the set and add the values to the appropriate line.
for (int i=0; i < csm.getNumPoints(); i++) {
int v = Integer.parseInt((String)csm.getData(i));
try {
if (v <= green){
greenSet.addElement(v+"");
yellowSet.addElement("null");
redSet.addElement("null");
} else if (v < red){
greenSet.addElement("null");
yellowSet.addElement(v+"");
redSet.addElement("null");
} else {
greenSet.addElement("null");
yellowSet.addElement("null");
redSet.addElement(v+"");
}
} catch (Exception ex){
greenSet.addElement("null");
yellowSet.addElement("null");
redSet.addElement("null");
}
}
// Set the LineSets of the chart.
ls.setElementAt(greenSet, 0);
ls.setElementAt(yellowSet, 1);
ls.setElementAt(redSet, 2);
chart.setLineSeries(ls);

// Set the left axis tic locations.
NFAxis leftAxis = chart.getLeftAxis();
NFVector leftTicLocations = new NFVector();
leftTicLocations.addElement(new Integer(green));
leftTicLocations.addElement(new Integer(red));
leftAxis.setTicLocations(leftTicLocations);
chart.setLeftAxis(leftAxis);

csvInput.close();
csvInput = null;
}

public void loadRidershipData(NFGraph theChart) throws Exception {
NFLinechart chart = (NFLinechart)theChart;

InputStream csvInput = null;
CSV1DDataModel csm = null;
String colFilter = "";
String rowFilter = "";

// Set the line data and bottom labels.
NFAxisSeries as = chart.getBottomAxisSeries();
NFLineSeries ls = chart.getLineSeries();
NFAxis axis = null;
NFLineSet set = null;
NFVector bottomLabels = null;
int i=0;

// Get the 10 year data.
colFilter = "0,1";
rowFilter = "1*";
csvInput = PerformanceDashboard.class.getResourceAsStream("/exampledata/Ridership10Yr.txt");
csm = new CSV1DDataModel(csvInput, colFilter, rowFilter, ",");
// Set the 10 year data and labels.
set = (NFLineSet)ls.elementAt(0);
axis = (NFAxis)as.elementAt(0);
bottomLabels = new NFVector();
while (i < csm.getNumPoints()) {
bottomLabels.addElement(csm.elementAt(i));
i++;
set.addElement(csm.elementAt(i));
i++;
}
axis.setTicLabels(bottomLabels);
as.setElementAt(axis, 0);
ls.setElementAt(set, 0);

// Get the current year data. (same filters)
csvInput = PerformanceDashboard.class.getResourceAsStream("/exampledata/RidershipCurrYear.txt");
csm = new CSV1DDataModel(csvInput, colFilter, rowFilter, ",");
// Set the current year data and labels.
set = (NFLineSet)ls.elementAt(1);
axis = (NFAxis)as.elementAt(1);
bottomLabels = new NFVector();
i = 0;
while (i < csm.getNumPoints()) {
bottomLabels.addElement(csm.elementAt(i));
i++;
set.addElement(csm.elementAt(i));
i++;
}
axis.setTicLabels(bottomLabels);
as.setElementAt(axis, 1);
ls.setElementAt(set, 1);

// Get the monthly data. (same filters)
// A better strategy would be to create a 2-D DataModel to load the data as a two-dimensional
// representation of the data. This would be easier to parse to create the labels. But this
// example is intended to show the use of the CSV1DDataModel.
csvInput = PerformanceDashboard.class.getResourceAsStream("/exampledata/RidershipMonth.txt");
csm = new CSV1DDataModel(csvInput, colFilter, rowFilter, ",");
// Set the current year data and labels.
set = (NFLineSet)ls.elementAt(2);
axis = (NFAxis)as.elementAt(2);
bottomLabels = new NFVector();
i = 0;
while (i < csm.getNumPoints()) {
bottomLabels.addElement(csm.elementAt(i));
i++;
set.addElement(csm.elementAt(i));
i++;
}
axis.setTicLabels(bottomLabels);
as.setElementAt(axis, 2);
ls.setElementAt(set, 2);

chart.setLineSeries(ls);
chart.setBottomAxisSeries(as);

csvInput.close();
csvInput = null;
}

public void loadCostData(NFGraph theChart) throws Exception {
NFBubblechart chart = (NFBubblechart)theChart;

InputStream csvInput = PerformanceDashboard.class.getResourceAsStream("/exampledata/TransitDataSummary.txt");
CSV1DDataModel csm = null;
String colFilter = "";
String rowFilter = "";
int i = 0;

// Get the cost/revenue data.
colFilter = "0";
rowFilter = "1*";
csm = new CSV1DDataModel(csvInput, colFilter, rowFilter, ",");

// Set the bottom labels.
NFAxis bottomAxis = chart.getBottomAxis();
NFVector bottomLabels = new NFVector();
bottomLabels.loadDataModel(csm);
bottomAxis.setTicLabels(bottomLabels);
chart.setBottomAxis(bottomAxis);

// Set the bubble data.
// A better strategy would be to create a 2-D DataModel to load the data as a two-dimensional
// representation of the data. This would be easier to parse to create the sets. But this
// example is intended to show the use of the CSV1DDataModel.
NFBubbleSeries bs = chart.getBubbleSeries();
NFBubbleSet set1 = (NFBubbleSet)bs.elementAt(0);
NFBubbleSet set2 = (NFBubbleSet)bs.elementAt(1);

double x = 1.0;
String y = "50";
i = 0;
colFilter = "10,11";
csvInput.reset();
csm = new CSV1DDataModel(csvInput, colFilter, rowFilter, ",");
while (i < csm.getNumPoints()) {
set2.addElement(x+"",y,(String)csm.elementAt(i));
set2.addActiveLabel(new NFActiveLabel((String)csm.elementAt(i), null, null));
i++;
set1.addElement(x+"",y,(String)csm.elementAt(i));
set1.addActiveLabel(new NFActiveLabel((String)csm.elementAt(i), null, null));
i++;
x++;
}
bs.setElementAt(set1, 0);
bs.setElementAt(set2, 1);
chart.setBubbleSeries(bs);

csvInput.close();
csvInput = null;
}

public void loadFuelUseData(NFGraph theChart) throws Exception {
NFDialchart chart = (NFDialchart)theChart;

InputStream csvInput = PerformanceDashboard.class.getResourceAsStream("/exampledata/TransitDataSummary.txt");
CSV1DDataModel csm = null;
String colFilter = "";
String rowFilter = "";

// Get the fuel use data.
colFilter = "0,9";
rowFilter = "5";
csm = new CSV1DDataModel(csvInput, colFilter, rowFilter, ",");

// Set the header with the appropriate info.
NFTitle header = new NFTitle(new NFLabel("Fuel Use ("+csm.getData(0)+")", Color.black, new Font("Helvetica", Font.BOLD, 12), 0),null);
chart.setHeader(header);

// Set the dial hand value.
NFDial dial = chart.getDial();
NFVector hands = dial.getHands();
NFDialHand hand = (NFDialHand)hands.elementAt(0);
hand.setValue(Double.parseDouble((String)csm.getData(1)));
hands.setElementAt(hand, 0);
dial.setHands(hands);
chart.setDial(dial);

csvInput.close();
csvInput = null;
}

public void writeOutputError(ServletOutputStream os, String message, Exception ex) throws ServletException {
Throwable t = ex;
System.out.println("ex is "+ex);
if (ex instanceof java.lang.reflect.InvocationTargetException)
t = ((java.lang.reflect.InvocationTargetException)ex).getTargetException();
try {
os.println("<html>");
os.println("<h2>Dashboard generation failed</h2>");
os.println("<hr>"+message+"<hr>");
os.println("<pre>"+t.getMessage()+"</pre>");
os.println("</html>");
t.printStackTrace();
} catch (Exception d){
throw new ServletException ("Can't write error message "+message);
}
}

}



© 2008 Visual Mining, Inc. All rights reserved.
1-800-308-0731 | info@visualmining.com | privacy statement | legal
15825 Shady Grove Rd., Suite 20, Rockville, MD 20850 USA


Quote: MRO Software

Additional Dashboard Information:
Whitepaper:
A Dashboard Data Methodology
Whitepaper:
The Art of Analysis
On-demand webinar: Adding AJAX functionality to your Dashboards
On-demand webinar:
Add Analytics to Your Dashboard Applications
On-Demand Tour: Health Care Dashboard
On-Demand Demo:
Creating a Basic Dashboard Page
On-Demand Demo:
Adding Drilldown Functionality to Your Dashboards
Corporate Dashboards: Real ROI? (whitepaper)
Dashboards: Another Look at Data Visualization (whitepaper)
For Pricing & Licensing - contact sales