/*==========================================================================*\
| $Id: MiniBarGraph.java,v 1.4 2011/10/25 15:32:06 stedwar2 Exp $
|*-------------------------------------------------------------------------*|
| Copyright (C) 2006-2011 Virginia Tech
|
| This file is part of Web-CAT.
|
| Web-CAT is free software; you can redistribute it and/or modify
| it under the terms of the GNU Affero General Public License as published
| by the Free Software Foundation; either version 3 of the License, or
| (at your option) any later version.
|
| Web-CAT 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 Affero General Public License
| along with Web-CAT; if not, see <http://www.gnu.org/licenses/>.
\*==========================================================================*/
package org.webcat.grader.graphs;
import com.webobjects.appserver.*;
import com.webobjects.appserver._private.WODynamicElementCreationException;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSNumberFormatter;
import org.webcat.core.*;
import org.webcat.woextensions.DynamicElement;
import org.webcat.woextensions.WCResourceManager;
// -------------------------------------------------------------------------
/**
* A dynamic element used to generate tiny bar graphs.
*
* @author Stephen Edwards
* @author Last changed by $Author: stedwar2 $
* @version $Revision: 1.4 $, $Date: 2011/10/25 15:32:06 $
*/
public class MiniBarGraph
extends DynamicElement
{
//~ Constructors ..........................................................
// ----------------------------------------------------------
/**
* Construct a new object.
* @param name the component instance's name
* @param associations this instance's parameter bindings
* @param children this instance's child elements
*/
public MiniBarGraph(
String name,
NSDictionary<String, WOAssociation> associations,
WOElement children )
{
super( name, associations, children );
// Validate bindings
if ( !hasAssociationForKey( GRAPH_SUMMARY_KEY ) )
{
throw new WODynamicElementCreationException(
"<" + getClass().getName()
+ "> Must specify '" + GRAPH_SUMMARY_KEY + "'" );
}
}
//~ Constants (for key names) .............................................
public static final String GRAPH_SUMMARY_KEY = "graphSummary";
public static final String MARK_SCORE_KEY = "markScore";
public static final String MAX_VALUE_KEY = "maxValue";
//~ Public Methods ........................................................
// ----------------------------------------------------------
/**
* Add the HTML rendering of the graph.
* @param aResponse the response being built
* @param aContext the request context
*/
public void appendToResponse( WOResponse aResponse, WOContext aContext )
{
WOComponent c = aContext.component();
aResponse.appendContentString( "<table class=\"distchart\"><tr>\n" );
float[] values = dataValues( c );
float scaleFactor = scaleFactor( c );
float largest = 0.0f;
for ( int i = 0; i < values.length; i++ )
{
if ( scaleFactor != 0.0f && scaleFactor != 1.0f )
{
values[i] /= scaleFactor;
}
if ( values[i] > largest )
{
largest = values[i];
}
}
float zoomFactor = 1.0f;
if ( largest < 0.1 ) { zoomFactor = 5.0f; }
else if ( largest < 0.2 ) { zoomFactor = 4.0f; }
else if ( largest < 0.3 ) { zoomFactor = 3.0f; }
else if ( largest < 0.4 ) { zoomFactor = 2.0f; }
else if ( largest < 0.6 ) { zoomFactor = 1.5f; }
Object markScoreObject =
associationValueForKey( MARK_SCORE_KEY, c );
if ( markScoreObject != null && !( markScoreObject instanceof Number ) )
{
throw new WODynamicElementCreationException(
"<" + getClass().getName()
+ "> '" + MARK_SCORE_KEY + "' must be bound to a number" );
}
Number markScoreNumber = (Number)markScoreObject;
float markScore = 0.0f;
int markBin = 0;
int markOffset = 0;
if ( markScoreNumber != null )
{
AssignmentSummary summary =
(AssignmentSummary)associationValueForKey(
GRAPH_SUMMARY_KEY, c );
markScore = markScoreNumber.floatValue();
markBin = summary.binFor( markScore );
markOffset = summary.interpolateInBin( markScore, markBin, 10 );
}
for ( int i = 0; i < values.length; i++ )
{
int height = Math.round( values[i] * zoomFactor * 10.0f );
aResponse.appendContentString(
"<td class=\"b" + height + "\">");
if ( markScoreNumber != null && markBin == i )
{
StringBuffer buf = new StringBuffer();
buf.append( "Your score: " );
formatter.format( markScoreNumber, buf, null );
String msg = buf.toString();
aResponse.appendContentString(
"<img class=\"bar\" src=\"" + markerUrlPrefix()
+ markOffset + ".gif\" title=\"" + msg + "\" alt=\""
+ msg + "\"/>");
}
aResponse.appendContentString( "</td>\n" );
}
aResponse.appendContentString( "</tr></table>" );
}
// ----------------------------------------------------------
/**
* Get the array of values to be plotted.
* @param aComponent the current component
* @return the array of data values
*/
public float[] dataValues( WOComponent aComponent )
{
AssignmentSummary summary = (AssignmentSummary)associationValueForKey(
GRAPH_SUMMARY_KEY, aComponent );
return summary.percentageDistribution();
}
// ----------------------------------------------------------
/**
* Get the array of values to be plotted.
* @param aComponent the current component
* @return the array of data values
*/
public float scaleFactor( WOComponent aComponent )
{
return associationFloatValueForKey( MAX_VALUE_KEY, aComponent );
}
//~ Private Methods .......................................................
// ----------------------------------------------------------
private String markerUrlPrefix()
{
if ( _markerUrlPrefix == null )
{
_markerUrlPrefix = WCResourceManager.versionlessResourceURLFor(
"images/marker0.gif", "Grader", null, null );
if ( _markerUrlPrefix != null )
{
_markerUrlPrefix = _markerUrlPrefix.substring( 0,
_markerUrlPrefix.length() - "0.gif".length() );
}
else
{
_markerUrlPrefix = "http://web-cat.cs.vt.edu/wcstatic/"
+ "Grader.framework/WebServerResources/images/marker";
}
}
return _markerUrlPrefix;
}
//~ Instance/static variables .............................................
private static String _markerUrlPrefix;
private static NSNumberFormatter formatter = new NSNumberFormatter("0.0");
}