package onlinefrontlines.profiler.web;
import onlinefrontlines.profiler.Profiler;
import onlinefrontlines.profiler.TimeSeries;
import onlinefrontlines.web.*;
import java.net.URLEncoder;
import java.text.DecimalFormat;
/**
* View currently accumulated profiling time series
*
* @author jorrit
*
* Copyright (C) 2009-2013 Jorrit Rouwe
*
* This file is part of Online Frontlines.
*
* Online Frontlines is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Online Frontlines is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Online Frontlines. If not, see <http://www.gnu.org/licenses/>.
*/
public class ViewTimeSeriesAction extends WebAction
{
/**
* Resulting html
*/
public String html;
/**
* Encoding table
*/
private static final char[] encodingTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.".toCharArray();
/**
* Encode value for google charts
*/
private char[] encode(double value, double minValue, double maxValue)
{
// Quantize value
int quantized = (int)Math.round(4095.0 * (value - minValue) / (maxValue - minValue));
if (quantized < 0)
quantized = 0;
if (quantized > 4095)
quantized = 4095;
// Encode value
char[] encoded = new char[2];
encoded[0] = encodingTable[quantized / 64];
encoded[1] = encodingTable[quantized % 64];
return encoded;
}
/**
* Execute action
*
* @return The path to the JSP page to execute
*/
protected WebView execute() throws Exception
{
Profiler a = Profiler.getInstance();
StringBuilder b = new StringBuilder();
DecimalFormat f = new DecimalFormat("#.#");
for (String n : a.getTimeSeriesNames())
{
// Get values
double[] values = a.getTimeSeries(n).getValues();
// Get min and max value
double minValue = Double.MAX_VALUE;
double maxValue = 0;
for (Double v : values)
{
minValue = Math.min(v, minValue);
maxValue = Math.max(v, maxValue);
}
if (minValue >= maxValue)
maxValue = minValue + 1;
// Start image
b.append("<img style=\"margin: 5px 0px 0px 0px;\" src=\"");
// Remember length
int lengthAtUrlStart = b.length();
// Add url
b.append("http://chart.apis.google.com/chart?");
// Size
b.append("chs=600x300");
// Data
b.append("&chd=e:");
for (Double v : values)
b.append(encode(v, minValue, maxValue));
// Type
b.append("&cht=lc");
// Title
b.append("&chtt=");
b.append(URLEncoder.encode(n, "UTF-8"));
// X and Y axis
b.append("&chxt=x,y");
// X and Y axis range
b.append("&chxr=0,0,");
b.append(values.length * TimeSeries.MS_PER_SAMPLE / (60 * 1000));
b.append("|1,");
b.append(f.format(minValue));
b.append(",");
b.append(f.format(maxValue));
// Color
b.append("&chco=0000FF");
// URL cannot be bigger than 2048
assert(b.length() - lengthAtUrlStart < 2048);
// End image
b.append("\" alt=\"chart\"/>");
}
html = b.toString();
return getSuccessView();
}
}