1. Removed SOPs from the visualization codebase. Switched it with log.debugs.

2. Added person grant count & coauthorship to the freemarker version of dependency inhection bean.
3. Fixed a bug in garnt count freemarker.
4. Made use of urlbuilder instead of making urls by just encoding/appending parameters.
5. Add co-pi to the freemarker package. Completed the back-end conversion.
This commit is contained in:
cdtank 2010-12-17 22:05:53 +00:00
parent 209c9b6a7b
commit 81855eddc2
22 changed files with 1845 additions and 415 deletions

View file

@ -15,12 +15,18 @@
<bean id="utilities" <bean id="utilities"
class="edu.cornell.mannlib.vitro.webapp.visualization.freemarker.utilities.UtilitiesRequestHandler" /> class="edu.cornell.mannlib.vitro.webapp.visualization.freemarker.utilities.UtilitiesRequestHandler" />
<!--
<bean id="coauthorship" <bean id="coauthorship"
class="edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.CoAuthorshipRequestHandler" /> class="edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coauthorship.CoAuthorshipRequestHandler" />
<bean id="person_grant_count"
class="edu.cornell.mannlib.vitro.webapp.visualization.freemarker.persongrantcount.PersonGrantCountRequestHandler" />
<!--
<bean id="person_level" <bean id="person_level"
class="edu.cornell.mannlib.vitro.webapp.visualization.personlevel.PersonLevelRequestHandler" /> class="edu.cornell.mannlib.vitro.webapp.visualization.personlevel.PersonLevelRequestHandler" />
<bean id="entity_comparison" <bean id="entity_comparison"
class="edu.cornell.mannlib.vitro.webapp.visualization.entitycomparison.EntityPublicationCountRequestHandler" /> class="edu.cornell.mannlib.vitro.webapp.visualization.entitycomparison.EntityPublicationCountRequestHandler" />
<bean id="coprincipalinvestigator" <bean id="coprincipalinvestigator"
@ -38,10 +44,16 @@
<entry key="utilities"> <entry key="utilities">
<ref bean="utilities"></ref> <ref bean="utilities"></ref>
</entry> </entry>
<!--
<entry key="coauthorship"> <entry key="coauthorship">
<ref bean="coauthorship"></ref> <ref bean="coauthorship"></ref>
</entry> </entry>
<entry key="person_grant_count">
<ref bean="person_grant_count"></ref>
</entry>
<!--
<entry key="person_level"> <entry key="person_level">
<ref bean="person_level"></ref> <ref bean="person_level"></ref>
</entry> </entry>

View file

@ -69,8 +69,6 @@
<#if sparklineVO.shortVisMode> <#if sparklineVO.shortVisMode>
console.log("Yay! Short Vis Mode!");
<#-- For the short view we only want the last 10 year's view of grant count, hence we filter <#-- For the short view we only want the last 10 year's view of grant count, hence we filter
the data we actually want to use for render. --> the data we actually want to use for render. -->
@ -78,14 +76,10 @@
column: 0, column: 0,
minValue: '${sparklineVO.earliestRenderedGrantYear?c}', minValue: '${sparklineVO.earliestRenderedGrantYear?c}',
maxValue: '${sparklineVO.latestRenderedGrantYear?c}' maxValue: '${sparklineVO.latestRenderedGrantYear?c}'
/*minValue: '2001',
maxValue: '2011'*/
}])); }]));
<#else> <#else>
console.log("Yay! Full Vis Mode!");
</#if> </#if>
<#-- Create the vis object and draw it in the div pertaining to sparkline. --> <#-- Create the vis object and draw it in the div pertaining to sparkline. -->
@ -130,6 +124,7 @@
$('#${sparklineContainerID} td.sparkline_text').html(sparksText); $('#${sparklineContainerID} td.sparkline_text').html(sparksText);
}
/* /*
* This will activate the visualization. It takes care of creating * This will activate the visualization. It takes care of creating

View file

@ -399,23 +399,10 @@ public class CoAuthorshipQueryRunner implements QueryRunner<CoAuthorshipData> {
DataSource dataSource) { DataSource dataSource) {
QueryExecution queryExecution = null; QueryExecution queryExecution = null;
// try {
Query query = QueryFactory.create(queryText, SYNTAX); Query query = QueryFactory.create(queryText, SYNTAX);
// QuerySolutionMap qs = new QuerySolutionMap();
// qs.add("authPerson", queryParam); // bind resource to s
queryExecution = QueryExecutionFactory.create(query, dataSource); queryExecution = QueryExecutionFactory.create(query, dataSource);
System.out.println("\n\nquery.isSelectType() is "+ query.isSelectType()+ " \n\n");
// if (query.isSelectType()) {
return queryExecution.execSelect(); return queryExecution.execSelect();
// }
// } finally {
// if (queryExecution != null) {
// queryExecution.close();
// }
// }
// return null;
} }
private String generateEgoCoAuthorshipSparqlQuery(String queryURI) { private String generateEgoCoAuthorshipSparqlQuery(String queryURI) {
@ -455,7 +442,7 @@ public class CoAuthorshipQueryRunner implements QueryRunner<CoAuthorshipData> {
+ "} " + "} "
+ "ORDER BY ?document ?coAuthorPerson"; + "ORDER BY ?document ?coAuthorPerson";
System.out.println("COAUTHORSHIP QUERY - " + sparqlQuery); log.debug("COAUTHORSHIP QUERY - " + sparqlQuery);
return sparqlQuery; return sparqlQuery;
} }

View file

@ -92,7 +92,7 @@ public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
+ "?CoPI rdfs:label ?CoPILabel . " + "?CoPI rdfs:label ?CoPILabel . "
+ " }"; + " }";
System.out.println("COPI QUERY - " + sparqlQuery); log.debug("COPI QUERY - " + sparqlQuery);
return sparqlQuery; return sparqlQuery;
} }
@ -100,20 +100,10 @@ public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
private ResultSet executeQuery(String queryText, DataSource dataSource) { private ResultSet executeQuery(String queryText, DataSource dataSource) {
QueryExecution queryExecution = null; QueryExecution queryExecution = null;
// try {
Query query = QueryFactory.create(queryText, SYNTAX); Query query = QueryFactory.create(queryText, SYNTAX);
queryExecution = QueryExecutionFactory.create(query, dataSource); queryExecution = QueryExecutionFactory.create(query, dataSource);
System.out.println("\n\nquery.isSelectType() is "+ query.isSelectType()+ " \n\n");
// if (query.isSelectType()) {
return queryExecution.execSelect(); return queryExecution.execSelect();
// }
// } finally {
// if (queryExecution != null) {
// queryExecution.close();
// }
// }
// return null;
} }
public CoPIData getQueryResult() public CoPIData getQueryResult()
@ -137,7 +127,6 @@ public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
ResultSet resultSet = executeQuery(generateEgoCoPIquery(this.egoURI), ResultSet resultSet = executeQuery(generateEgoCoPIquery(this.egoURI),
this.dataSource); this.dataSource);
System.out.println("ResultSet ");
return createQueryResult(resultSet); return createQueryResult(resultSet);
} }
@ -202,8 +191,7 @@ public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
egoNode.setNodeName(authorLabelNode.toString()); egoNode.setNodeName(authorLabelNode.toString());
} }
} }
System.out.println("\n----------------------------------"); log.debug("PI: "+ egoNode.getIndividualLabel());
System.out.println("PI: "+ egoNode.getIndividualLabel());
RDFNode grantNode = solution.get(QueryFieldLabels.GRANT_URL); RDFNode grantNode = solution.get(QueryFieldLabels.GRANT_URL);
Grant grant; Grant grant;
@ -216,7 +204,7 @@ public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
} }
egoNode.addGrant(grant); egoNode.addGrant(grant);
System.out.println("Adding grant: "+ grant.getIndividualLabel()); log.debug("Adding grant: "+ grant.getIndividualLabel());
/* /*
* After some discussion we concluded that for the purpose of this visualization * After some discussion we concluded that for the purpose of this visualization
@ -247,7 +235,7 @@ public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
} }
} }
System.out.println("Adding CO-PI: "+ coPINode.getIndividualLabel()); log.debug("Adding CO-PI: "+ coPINode.getIndividualLabel());
coPINode.addGrant(grant); coPINode.addGrant(grant);
Set<CoPINode> coPIsForCurrentGrant; Set<CoPINode> coPIsForCurrentGrant;
@ -262,10 +250,9 @@ public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
} }
coPIsForCurrentGrant.add(coPINode); coPIsForCurrentGrant.add(coPINode);
System.out.println("Co-PI for current grant : "+ coPINode.getIndividualLabel()); log.debug("Co-PI for current grant : "+ coPINode.getIndividualLabel());
CoPIEdge egoCoPIEdge = getExistingEdge(egoNode, coPINode, edgeUniqueIdentifierToVO); CoPIEdge egoCoPIEdge = getExistingEdge(egoNode, coPINode, edgeUniqueIdentifierToVO);
System.out.println("\n----------------------------------");
/* /*
* If "egoCoPIEdge" is null it means that no edge exists in between the egoNode * If "egoCoPIEdge" is null it means that no edge exists in between the egoNode
* & current coPINode. Else create a new edge, add it to the edges set & add * & current coPINode. Else create a new edge, add it to the edges set & add

View file

@ -166,21 +166,10 @@ public class EntityPublicationCountQueryRunner implements QueryRunner<Entity> {
private ResultSet executeQuery(String queryURI, DataSource dataSource) { private ResultSet executeQuery(String queryURI, DataSource dataSource) {
QueryExecution queryExecution = null; QueryExecution queryExecution = null;
// try {
Query query = QueryFactory.create( Query query = QueryFactory.create(
getSparqlQuery(queryURI, this.visMode), SYNTAX); getSparqlQuery(queryURI, this.visMode), SYNTAX);
queryExecution = QueryExecutionFactory.create(query, dataSource); queryExecution = QueryExecutionFactory.create(query, dataSource);
System.out.println("\n\nquery.isSelectType() is "+ query.isSelectType()+ " \n\n");
return queryExecution.execSelect(); return queryExecution.execSelect();
// if (query.isSelectType()) {
// return queryExecution.execSelect();
// }
// } finally {
// if (queryExecution != null) {
// queryExecution.close();
// }
// }
// return null;
} }
private String getSparqlQuery(String queryURI, String visMode) { private String getSparqlQuery(String queryURI, String visMode) {
@ -281,7 +270,7 @@ public class EntityPublicationCountQueryRunner implements QueryRunner<Entity> {
+ SPARQL_QUERY_COMMON_WHERE_CLAUSE + "}" + SPARQL_QUERY_COMMON_WHERE_CLAUSE + "}"
+ "}"; + "}";
System.out.println("\nThe sparql query is :\n" + sparqlQuery); log.debug("\nThe sparql query is :\n" + sparqlQuery);
return sparqlQuery; return sparqlQuery;

View file

@ -5,10 +5,10 @@ package edu.cornell.mannlib.vitro.webapp.visualization.entitycomparison;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.HashSet;
import javax.servlet.RequestDispatcher; import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException; import javax.servlet.ServletException;
@ -16,17 +16,16 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import com.google.gson.Gson;
import com.google.gson.Gson;
import com.hp.hpl.jena.query.DataSource; import com.hp.hpl.jena.query.DataSource;
import edu.cornell.mannlib.vitro.webapp.beans.Portal; import edu.cornell.mannlib.vitro.webapp.beans.Portal;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants; import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException; import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Entity; import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Entity;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.JsonObject; import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.JsonObject;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SubEntity; import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SubEntity;
@ -45,7 +44,6 @@ public class EntityPublicationCountRequestHandler implements
public static String SUB_ENTITY_VIS_MODE; public static String SUB_ENTITY_VIS_MODE;
@SuppressWarnings("null")
public void generateVisualization(VitroRequest vitroRequest, public void generateVisualization(VitroRequest vitroRequest,
HttpServletRequest request, HttpServletResponse response, Log log, HttpServletRequest request, HttpServletResponse response, Log log,
DataSource dataSource) { DataSource dataSource) {
@ -91,13 +89,13 @@ public class EntityPublicationCountRequestHandler implements
if (VisualizationFrameworkConstants.DATA_RENDER_MODE if (VisualizationFrameworkConstants.DATA_RENDER_MODE
.equalsIgnoreCase(renderMode)) { .equalsIgnoreCase(renderMode)) {
prepareDataResponse(entity, entity.getSubEntities(),subOrganizationTypesResult, response); prepareDataResponse(entity, entity.getSubEntities(),subOrganizationTypesResult, response, log);
} else if (VisualizationFrameworkConstants.STANDALONE_RENDER_MODE } else if (VisualizationFrameworkConstants.STANDALONE_RENDER_MODE
.equalsIgnoreCase(renderMode)) { .equalsIgnoreCase(renderMode)) {
prepareStandaloneResponse(request, response, vitroRequest, prepareStandaloneResponse(request, response, vitroRequest,
entity, subOrganizationTypesResult); entity, subOrganizationTypesResult, log);
requestDispatcher = request requestDispatcher = request
.getRequestDispatcher(Controllers.BASIC_JSP); .getRequestDispatcher(Controllers.BASIC_JSP);
} }
@ -135,9 +133,10 @@ public class EntityPublicationCountRequestHandler implements
* @param subOrganizationTypesResult * @param subOrganizationTypesResult
* @param yearToPublicationCount * @param yearToPublicationCount
* @param response * @param response
* @param log
*/ */
private void prepareDataResponse(Entity entity, Set<SubEntity> subentities, private void prepareDataResponse(Entity entity, Set<SubEntity> subentities,
Map<String, Set<String>> subOrganizationTypesResult, HttpServletResponse response) { Map<String, Set<String>> subOrganizationTypesResult, HttpServletResponse response, Log log) {
String entityLabel = entity.getEntityLabel(); String entityLabel = entity.getEntityLabel();
@ -156,7 +155,7 @@ public class EntityPublicationCountRequestHandler implements
* We are side-effecting responseWriter since we are directly * We are side-effecting responseWriter since we are directly
* manipulating the response object of the servlet. * manipulating the response object of the servlet.
*/ */
responseWriter.append(writePublicationsOverTimeJSON(subentities, subOrganizationTypesResult)); responseWriter.append(writePublicationsOverTimeJSON(subentities, subOrganizationTypesResult, log));
responseWriter.flush(); responseWriter.flush();
responseWriter.close(); responseWriter.close();
@ -175,9 +174,10 @@ public class EntityPublicationCountRequestHandler implements
* @param vreq * @param vreq
* @param entity * @param entity
* @param subOrganizationTypesResult * @param subOrganizationTypesResult
* @param log
*/ */
private void prepareStandaloneResponse(HttpServletRequest request, private void prepareStandaloneResponse(HttpServletRequest request,
HttpServletResponse response, VitroRequest vreq, Entity entity, Map<String, Set<String>> subOrganizationTypesResult) { HttpServletResponse response, VitroRequest vreq, Entity entity, Map<String, Set<String>> subOrganizationTypesResult, Log log) {
Portal portal = vreq.getPortal(); Portal portal = vreq.getPortal();
String jsonContent = ""; String jsonContent = "";
@ -185,7 +185,7 @@ public class EntityPublicationCountRequestHandler implements
* We are side-effecting responseWriter since we are directly * We are side-effecting responseWriter since we are directly
* manipulating the response object of the servlet. * manipulating the response object of the servlet.
*/ */
jsonContent = writePublicationsOverTimeJSON(entity.getSubEntities(), subOrganizationTypesResult); jsonContent = writePublicationsOverTimeJSON(entity.getSubEntities(), subOrganizationTypesResult, log);
request.setAttribute("JsonContent", jsonContent); request.setAttribute("JsonContent", jsonContent);
@ -201,15 +201,16 @@ public class EntityPublicationCountRequestHandler implements
/** /**
* function to generate a json file for year <-> publication count mapping * function to generate a json file for year <-> publication count mapping
* @param subOrganizationTypesResult * @param subOrganizationTypesResult
* @param log
* *
* @param yearToPublicationCount * @param yearToPublicationCount
* @param responseWriter * @param responseWriter
* @param visMode * @param visMode
*/ */
private String writePublicationsOverTimeJSON(Set<SubEntity> subentities, Map<String, Set<String>> subOrganizationTypesResult) { private String writePublicationsOverTimeJSON(Set<SubEntity> subentities, Map<String, Set<String>> subOrganizationTypesResult, Log log) {
// System.out.println("\nsub entity vis mode ------>" // System.out.println("\nsub entity vis mode ------>"
// + SUB_ENTITY_VIS_MODE + "\n"); // + SUB_ENTITY_VIS_MODE + "\n");
System.out.println("Creating JSONObject \n-----------------------"); log.debug("Creating JSONObject \n-----------------------");
Gson json = new Gson(); Gson json = new Gson();
Set<JsonObject> subEntitiesJson = new HashSet<JsonObject>(); Set<JsonObject> subEntitiesJson = new HashSet<JsonObject>();
@ -239,7 +240,7 @@ public class EntityPublicationCountRequestHandler implements
entityJson.setEntityURI(subentity.getIndividualURI()); entityJson.setEntityURI(subentity.getIndividualURI());
setEntityVisMode(entityJson); setEntityVisMode(entityJson);
//entityJson.setVisMode(SUB_ENTITY_VIS_MODE); //entityJson.setVisMode(SUB_ENTITY_VIS_MODE);
System.out.println("Adding object with uri: " log.debug("Adding object with uri: "
+ entityJson.getEntityURI() + " vismode: " + entityJson.getEntityURI() + " vismode: "
+ entityJson.getVisMode() + " label: " + entityJson.getVisMode() + " label: "
+ entityJson.getLabel() + " type: " + entityJson.getLabel() + " type: "

View file

@ -74,20 +74,10 @@ public class EntitySubOrganizationTypesQueryRunner implements QueryRunner<Map<St
private ResultSet executeQuery(String queryURI, DataSource dataSource) { private ResultSet executeQuery(String queryURI, DataSource dataSource) {
QueryExecution queryExecution = null; QueryExecution queryExecution = null;
// try {
Query query = QueryFactory.create( Query query = QueryFactory.create(
getSparqlQuery(queryURI), SYNTAX); getSparqlQuery(queryURI), SYNTAX);
queryExecution = QueryExecutionFactory.create(query, dataSource); queryExecution = QueryExecutionFactory.create(query, dataSource);
System.out.println("\n\nquery.isSelectType() is "+ query.isSelectType()+ " \n\n");
// if (query.isSelectType()) {
return queryExecution.execSelect(); return queryExecution.execSelect();
// }
// } finally {
// if (queryExecution != null) {
// queryExecution.close();
// }
// }
// return null;
} }
private String getSparqlQuery(String queryURI) { private String getSparqlQuery(String queryURI) {
@ -133,7 +123,7 @@ public class EntitySubOrganizationTypesQueryRunner implements QueryRunner<Map<St
+ " ?personType rdfs:label ?personTypeLabel ." + " ?personType rdfs:label ?personTypeLabel ."
+ "}";; + "}";;
} }
System.out.println("\nThe sparql query is :\n" + sparqlQuery); log.debug("\nThe sparql query is :\n" + sparqlQuery);
return sparqlQuery; return sparqlQuery;
} }

View file

@ -2,15 +2,14 @@
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coauthorship; package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coauthorship;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.StandardVisualizationController; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants; import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoAuthorshipData; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoAuthorshipData;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Edge; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Edge;
@ -29,13 +28,7 @@ public class CoAuthorshipGraphMLWriter {
private final String GRAPHML_FOOTER = "</graphml>"; private final String GRAPHML_FOOTER = "</graphml>";
public CoAuthorshipGraphMLWriter(CoAuthorshipData visVOContainer) { public CoAuthorshipGraphMLWriter(CoAuthorshipData visVOContainer) {
coAuthorshipGraphMLContent = createCoAuthorshipGraphMLContent(visVOContainer); coAuthorshipGraphMLContent = createCoAuthorshipGraphMLContent(visVOContainer);
}
public StringBuilder getCoAuthorshipGraphMLContent() {
return coAuthorshipGraphMLContent;
} }
private StringBuilder createCoAuthorshipGraphMLContent( private StringBuilder createCoAuthorshipGraphMLContent(
@ -63,6 +56,10 @@ public class CoAuthorshipGraphMLWriter {
return graphMLContent; return graphMLContent;
} }
public StringBuilder getCoAuthorshipGraphMLContent() {
return coAuthorshipGraphMLContent;
}
private void generateGraphContent(CoAuthorshipData coAuthorshipData, private void generateGraphContent(CoAuthorshipData coAuthorshipData,
StringBuilder graphMLContent) { StringBuilder graphMLContent) {
@ -77,10 +74,6 @@ public class CoAuthorshipGraphMLWriter {
} }
graphMLContent.append("</graph>\n"); graphMLContent.append("</graph>\n");
} }
private void generateEdgeSectionContent(CoAuthorshipData coAuthorshipData, private void generateEdgeSectionContent(CoAuthorshipData coAuthorshipData,
@ -101,9 +94,7 @@ public class CoAuthorshipGraphMLWriter {
* is being side-effected. * is being side-effected.
* */ * */
getEdgeContent(graphMLContent, currentEdge); getEdgeContent(graphMLContent, currentEdge);
} }
} }
private void getEdgeContent(StringBuilder graphMLContent, Edge currentEdge) { private void getEdgeContent(StringBuilder graphMLContent, Edge currentEdge) {
@ -212,16 +203,11 @@ public class CoAuthorshipGraphMLWriter {
private void getNodeContent(StringBuilder graphMLContent, Node node) { private void getNodeContent(StringBuilder graphMLContent, Node node) {
String profileURL = null; ParamMap individualProfileURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
try { node.getNodeURI());
profileURL = VisualizationFrameworkConstants.INDIVIDUAL_URL_PREFIX + "?"
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY String profileURL = UrlBuilder.getUrl(VisualizationFrameworkConstants.INDIVIDUAL_URL_PREFIX,
+ "=" + URLEncoder.encode(node.getNodeURI(), individualProfileURLParams);
StandardVisualizationController
.URL_ENCODING_SCHEME).toString();
} catch (UnsupportedEncodingException e) {
System.err.println("URL Encoding ERRor. Move this to use log.error ASAP");
}
graphMLContent.append("<node id=\"" + node.getNodeID() + "\">\n"); graphMLContent.append("<node id=\"" + node.getNodeID() + "\">\n");
graphMLContent.append("\t<data key=\"url\">" + node.getNodeURI() + "</data>\n"); graphMLContent.append("\t<data key=\"url\">" + node.getNodeURI() + "</data>\n");

View file

@ -399,23 +399,10 @@ public class CoAuthorshipQueryRunner implements QueryRunner<CoAuthorshipData> {
DataSource dataSource) { DataSource dataSource) {
QueryExecution queryExecution = null; QueryExecution queryExecution = null;
// try {
Query query = QueryFactory.create(queryText, SYNTAX); Query query = QueryFactory.create(queryText, SYNTAX);
// QuerySolutionMap qs = new QuerySolutionMap();
// qs.add("authPerson", queryParam); // bind resource to s
queryExecution = QueryExecutionFactory.create(query, dataSource); queryExecution = QueryExecutionFactory.create(query, dataSource);
System.out.println("\n\nquery.isSelectType() is "+ query.isSelectType()+ " \n\n");
// if (query.isSelectType()) {
return queryExecution.execSelect(); return queryExecution.execSelect();
// }
// } finally {
// if (queryExecution != null) {
// queryExecution.close();
// }
// }
// return null;
} }
private String generateEgoCoAuthorshipSparqlQuery(String queryURI) { private String generateEgoCoAuthorshipSparqlQuery(String queryURI) {

View file

@ -190,10 +190,6 @@ public class CoAuthorshipRequestHandler implements VisualizationRequestHandler {
*/ */
private Map<String, String> prepareNetworkDataResponse(CoAuthorshipData authorNodesAndEdges) { private Map<String, String> prepareNetworkDataResponse(CoAuthorshipData authorNodesAndEdges) {
/*
* We are side-effecting responseWriter since we are directly manipulating the response
* object of the servlet.
* */
CoAuthorshipGraphMLWriter coAuthorshipGraphMLWriter = CoAuthorshipGraphMLWriter coAuthorshipGraphMLWriter =
new CoAuthorshipGraphMLWriter(authorNodesAndEdges); new CoAuthorshipGraphMLWriter(authorNodesAndEdges);

View file

@ -0,0 +1,22 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coprincipalinvestigator;
import java.util.Comparator;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPIEdge;
/**
* This Comparator is used to sort the edges based on their IDs in ascending order.
* @author bkoniden
*
*/
public class CoPIEdgeComparator implements Comparator<CoPIEdge> {
@Override
public int compare(CoPIEdge arg0, CoPIEdge arg1) {
return arg0.getEdgeID() - arg1.getEdgeID();
}
}

View file

@ -0,0 +1,437 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coprincipalinvestigator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import com.hp.hpl.jena.iri.IRI;
import com.hp.hpl.jena.iri.IRIFactory;
import com.hp.hpl.jena.iri.Violation;
import com.hp.hpl.jena.query.DataSource;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.RDFNode;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryFieldLabels;
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPIData;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPIEdge;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Grant;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPINode;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.QueryRunner;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UniqueIDGenerator;
/**
* @author bkoniden
* Deepak Konidena
*/
public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
private static final int MAX_PI_PER_GRANT_ALLOWED = 100;
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
private String egoURI;
private DataSource dataSource;
private Log log;
private UniqueIDGenerator nodeIDGenerator;
private UniqueIDGenerator edgeIDGenerator;
public CoPIGrantCountQueryRunner(String egoURI,
DataSource dataSource, Log log) {
this.egoURI = egoURI;
this.dataSource = dataSource;
this.log = log;
this.nodeIDGenerator = new UniqueIDGenerator();
this.edgeIDGenerator = new UniqueIDGenerator();
}
private String generateEgoCoPIquery(String queryURI) {
String sparqlQuery = QueryConstants.getSparqlPrefixQuery()
+ "SELECT "
+ " (str(<" + queryURI + ">) as ?" + QueryFieldLabels.PI_URL + ") "
+ " (str(?PILabel) as ?" + QueryFieldLabels.PI_LABEL + ") "
+ " (str(?Grant) as ?" + QueryFieldLabels.GRANT_URL + ") "
+ " (str(?GrantLabel) as ?" + QueryFieldLabels.GRANT_LABEL + ") "
+ " (str(?GrantStartDate) as ?" + QueryFieldLabels.GRANT_START_DATE + ") "
+ " (str(?GrantEndDate) as ?" + QueryFieldLabels.GRANT_END_DATE + ") "
+ " (str(?CoPI) as ?" + QueryFieldLabels.CO_PI_URL + ") "
+ " (str(?CoPILabel) as ?" + QueryFieldLabels.CO_PI_LABEL + ") "
+ "WHERE { "
+ "<" + queryURI + "> rdfs:label ?PILabel ;"
+ " core:hasCo-PrincipalInvestigatorRole ?Role . "
+ "?Role core:roleIn ?Grant . "
+ "?Grant rdfs:label ?GrantLabel ; "
+ "core:startDate ?GrantStartDate ; "
+ "core:endDate ?GrantEndDate ;"
+ "core:relatedRole ?RelatedRole . "
+ "?RelatedRole core:co-PrincipalInvestigatorRoleOf ?CoPI . "
+ "?CoPI rdfs:label ?CoPILabel . "
+ " }";
log.debug("COPI QUERY - " + sparqlQuery);
return sparqlQuery;
}
private ResultSet executeQuery(String queryText, DataSource dataSource) {
QueryExecution queryExecution = null;
Query query = QueryFactory.create(queryText, SYNTAX);
queryExecution = QueryExecutionFactory.create(query, dataSource);
return queryExecution.execSelect();
}
public CoPIData getQueryResult()
throws MalformedQueryParametersException {
if (StringUtils.isNotBlank(this.egoURI)) {
/*
* To test for the validity of the URI submitted.
* */
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
IRI iri = iRIFactory.create(this.egoURI);
if (iri.hasViolation(false)) {
String errorMsg = ((Violation) iri.violations(false).next()).getShortMessage();
log.error("Ego Co-PI Vis Query " + errorMsg);
throw new MalformedQueryParametersException(
"URI provided for an individual is malformed.");
}
} else {
throw new MalformedQueryParametersException("URI parameter is either null or empty.");
}
ResultSet resultSet = executeQuery(generateEgoCoPIquery(this.egoURI),
this.dataSource);
return createQueryResult(resultSet);
}
private CoPIEdge getExistingEdge(
CoPINode collaboratingNode1,
CoPINode collaboratingNode2,
Map<String, CoPIEdge> edgeUniqueIdentifierToVO) {
String edgeUniqueIdentifier = getEdgeUniqueIdentifier(collaboratingNode1.getNodeID(),
collaboratingNode2.getNodeID());
return edgeUniqueIdentifierToVO.get(edgeUniqueIdentifier);
}
private String getEdgeUniqueIdentifier(int nodeID1, int nodeID2) {
String separator = "*";
if (nodeID1 < nodeID2) {
return nodeID1 + separator + nodeID2;
} else {
return nodeID2 + separator + nodeID1;
}
}
private CoPIData createQueryResult(ResultSet resultSet) {
Set<CoPINode> nodes = new HashSet<CoPINode>();
Map<String, Grant> grantURLToVO = new HashMap<String, Grant>();
Map<String, Set<CoPINode>> grantURLToCoPIs = new HashMap<String, Set<CoPINode>>();
Map<String, CoPINode> nodeURLToVO = new HashMap<String, CoPINode>();
Map<String, CoPIEdge> edgeUniqueIdentifierToVO = new HashMap<String, CoPIEdge>();
CoPINode egoNode = null;
Set<CoPIEdge> edges = new HashSet<CoPIEdge>();
while (resultSet.hasNext()) {
QuerySolution solution = resultSet.nextSolution();
/*
* We only want to create only ONE ego node.
* */
RDFNode egoPIURLNode = solution.get(QueryFieldLabels.PI_URL);
if (nodeURLToVO.containsKey(egoPIURLNode.toString())) {
egoNode = nodeURLToVO.get(egoPIURLNode.toString());
} else {
egoNode = new CoPINode(egoPIURLNode.toString(), nodeIDGenerator);
nodes.add(egoNode);
nodeURLToVO.put(egoPIURLNode.toString(), egoNode);
RDFNode authorLabelNode = solution.get(QueryFieldLabels.PI_LABEL);
if (authorLabelNode != null) {
egoNode.setNodeName(authorLabelNode.toString());
}
}
log.debug("PI: "+ egoNode.getIndividualLabel());
RDFNode grantNode = solution.get(QueryFieldLabels.GRANT_URL);
Grant grant;
if (grantURLToVO.containsKey(grantNode.toString())) {
grant = grantURLToVO.get(grantNode.toString());
} else {
grant = createGrantVO(solution, grantNode.toString());
grantURLToVO.put(grantNode.toString(), grant);
}
egoNode.addGrant(grant);
log.debug("Adding grant: "+ grant.getIndividualLabel());
/*
* After some discussion we concluded that for the purpose of this visualization
* we do not want a co-pi node or edge if the grant has only one
* pi and that happens to be the ego.
* */
if (solution.get(QueryFieldLabels.PI_URL).toString().equalsIgnoreCase(
solution.get(QueryFieldLabels.CO_PI_URL).toString())) {
continue;
}
CoPINode coPINode;
RDFNode coPIURLNode = solution.get(QueryFieldLabels.CO_PI_URL);
if (nodeURLToVO.containsKey(coPIURLNode.toString())) {
coPINode = nodeURLToVO.get(coPIURLNode.toString());
} else {
coPINode = new CoPINode(coPIURLNode.toString(), nodeIDGenerator);
nodes.add(coPINode);
nodeURLToVO.put(coPIURLNode.toString(), coPINode);
RDFNode coPILabelNode = solution.get(QueryFieldLabels.CO_PI_LABEL);
if (coPILabelNode != null) {
coPINode.setNodeName(coPILabelNode.toString());
}
}
log.debug("Adding CO-PI: "+ coPINode.getIndividualLabel());
coPINode.addGrant(grant);
Set<CoPINode> coPIsForCurrentGrant;
if (grantURLToCoPIs.containsKey(grant.getGrantURL())) {
coPIsForCurrentGrant = grantURLToCoPIs
.get(grant.getGrantURL());
} else {
coPIsForCurrentGrant = new HashSet<CoPINode>();
grantURLToCoPIs.put(grant.getGrantURL(),
coPIsForCurrentGrant);
}
coPIsForCurrentGrant.add(coPINode);
log.debug("Co-PI for current grant : "+ coPINode.getIndividualLabel());
CoPIEdge egoCoPIEdge = getExistingEdge(egoNode, coPINode, edgeUniqueIdentifierToVO);
/*
* If "egoCoPIEdge" is null it means that no edge exists in between the egoNode
* & current coPINode. Else create a new edge, add it to the edges set & add
* the collaborator grant to it.
* */
if (egoCoPIEdge != null) {
egoCoPIEdge.addCollaboratorGrant(grant);
} else {
egoCoPIEdge = new CoPIEdge(egoNode, coPINode, grant, edgeIDGenerator);
edges.add(egoCoPIEdge);
edgeUniqueIdentifierToVO.put(
getEdgeUniqueIdentifier(egoNode.getNodeID(),
coPINode.getNodeID()),
egoCoPIEdge);
}
}
/*
* This method takes out all the PIs & edges between PIs that belong to grants
* that have more than 100 PIs. We conjecture that these grants do not provide much
* insight. However, we have left the grants be.
*
* This method side-effects "nodes" & "edges".
* */
removeLowQualityNodesAndEdges(nodes,
grantURLToVO,
grantURLToCoPIs,
edges);
/*
* We need to create edges between 2 co-PIs. E.g. On a grant there were 3 PI
* ego, A & B then we have already created edges like,
* ego - A
* ego - B
* The below sub-routine will take care of,
* A - B
*
* We are side-effecting "edges" here. The only reason to do this is because we are adding
* edges en masse for all the co-PIs on all the grants considered so far. The
* other reason being we dont want to compare against 2 sets of edges (edges created before
* & co-PI edges created during the course of this method) when we are creating a new
* edge.
* */
createCoPIEdges(grantURLToVO,
grantURLToCoPIs,
edges,
edgeUniqueIdentifierToVO);
return new CoPIData(egoNode, nodes, edges);
}
private void createCoPIEdges(Map<String, Grant> grantURLToVO,
Map<String, Set<CoPINode>> grantURLToCoPIs, Set<CoPIEdge> edges,
Map<String, CoPIEdge> edgeUniqueIdentifierToVO) {
for (Map.Entry<String, Set<CoPINode>> currentGrantEntry
: grantURLToCoPIs.entrySet()) {
/*
* If there was only one co-PI (other than ego) then we dont have to create any
* edges. so the below condition will take care of that.
*
* We are restricting edges between co-PI if a particular grant has more than
* 100 co-PIs. Our conjecture is that such edges do not provide any good insight
* & causes unnecessary computations causing the server to time-out.
* */
if (currentGrantEntry.getValue().size() > 1
&& currentGrantEntry.getValue().size()
<= MAX_PI_PER_GRANT_ALLOWED) {
Set<CoPIEdge> newlyAddedEdges = new HashSet<CoPIEdge>();
/*
* In order to leverage the nested "for loop" for making edges between all the
* co-PIs we need to create a list out of the set first.
* */
List<CoPINode> coPINodes = new ArrayList<CoPINode>(currentGrantEntry.getValue());
Collections.sort(coPINodes, new CoPINodeComparator());
int numOfCoPIs = coPINodes.size();
for (int ii = 0; ii < numOfCoPIs - 1; ii++) {
for (int jj = ii + 1; jj < numOfCoPIs; jj++) {
CoPINode coPI1 = coPINodes.get(ii);
CoPINode coPI2 = coPINodes.get(jj);
CoPIEdge coPI1_2Edge = getExistingEdge(coPI1,
coPI2,
edgeUniqueIdentifierToVO);
Grant currentGrant = grantURLToVO.get(currentGrantEntry.getKey());
if (coPI1_2Edge != null) {
coPI1_2Edge.addCollaboratorGrant(currentGrant);
} else {
coPI1_2Edge = new CoPIEdge(coPI1,
coPI2,
currentGrant,
edgeIDGenerator);
newlyAddedEdges.add(coPI1_2Edge);
edgeUniqueIdentifierToVO.put(
getEdgeUniqueIdentifier(coPI1.getNodeID(),
coPI2.getNodeID()),
coPI1_2Edge);
}
}
}
edges.addAll(newlyAddedEdges);
}
}
}
private void removeLowQualityNodesAndEdges(Set<CoPINode> nodes,
Map<String, Grant> grantURLToVO,
Map<String, Set<CoPINode>> grantURLToCoPIs, Set<CoPIEdge> edges) {
Set<CoPINode> nodesToBeRemoved = new HashSet<CoPINode>();
for (Map.Entry<String, Set<CoPINode>> currentGrantEntry
: grantURLToCoPIs.entrySet()) {
if (currentGrantEntry.getValue().size() > MAX_PI_PER_GRANT_ALLOWED) {
Grant currentGrant = grantURLToVO.get(currentGrantEntry.getKey());
Set<CoPIEdge> edgesToBeRemoved = new HashSet<CoPIEdge>();
for (CoPIEdge currentEdge : edges) {
Set<Grant> currentCollaboratorGrants =
currentEdge.getCollaboratorGrants();
if (currentCollaboratorGrants.contains(currentGrant)) {
currentCollaboratorGrants.remove(currentGrant);
if (currentCollaboratorGrants.isEmpty()) {
edgesToBeRemoved.add(currentEdge);
}
}
}
edges.removeAll(edgesToBeRemoved);
for (CoPINode currentCoPI : currentGrantEntry.getValue()) {
currentCoPI.getInvestigatedGrants().remove(currentGrant);
if (currentCoPI.getInvestigatedGrants().isEmpty()) {
nodesToBeRemoved.add(currentCoPI);
}
}
}
}
nodes.removeAll(nodesToBeRemoved);
}
private Grant createGrantVO(QuerySolution solution, String grantURL) {
Grant grant = new Grant(grantURL);
RDFNode grantLabelNode = solution.get(QueryFieldLabels.GRANT_LABEL);
if (grantLabelNode != null) {
grant.setIndividualLabel(grantLabelNode.toString());
}
RDFNode grantStartYear = solution.get(QueryFieldLabels.GRANT_START_DATE);
if (grantStartYear != null) {
grant.setGrantStartDate(grantStartYear.toString());
}
RDFNode grantEndDate = solution.get(QueryFieldLabels
.GRANT_END_DATE);
if (grantEndDate != null) {
grant.setGrantEndDate(grantEndDate.toString());
}
return grant;
}
}

View file

@ -0,0 +1,205 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coprincipalinvestigator;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import com.hp.hpl.jena.query.DataSource;
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.DataVisualizationController;
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPIData;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPINode;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.QueryRunner;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.VisualizationRequestHandler;
/**
* @author bkoniden
* Deepak Konidena
*/
public class CoPIGrantCountRequestHandler implements VisualizationRequestHandler{
@Override
public Object generateAjaxVisualization(VitroRequest vitroRequest, Log log,
DataSource dataSource) throws MalformedQueryParametersException {
// TODO Auto-generated method stub
return null;
}
@Override
public Map<String, String> generateDataVisualization(
VitroRequest vitroRequest, Log log, DataSource dataSource)
throws MalformedQueryParametersException {
String egoURI = vitroRequest.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
String visMode = vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY);
QueryRunner<CoPIData> queryManager = new CoPIGrantCountQueryRunner(egoURI, dataSource, log);
CoPIData PINodesAndEdges = queryManager.getQueryResult();
if (VisualizationFrameworkConstants.COPI_VIS_MODE
.equalsIgnoreCase(visMode)) {
return prepareCoPIDataResponse(PINodesAndEdges);
} else {
/*
* When the graphML file is required - based on which copi network
* visualization will be rendered.
* */
return prepareNetworkDataResponse(PINodesAndEdges);
}
}
@Override
public ResponseValues generateStandardVisualization(
VitroRequest vitroRequest, Log log, DataSource dataSource)
throws MalformedQueryParametersException {
String egoURI = vitroRequest.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
QueryRunner<CoPIData> queryManager = new CoPIGrantCountQueryRunner(egoURI, dataSource, log);
CoPIData PINodesAndEdges = queryManager.getQueryResult();
return prepareStandaloneResponse(egoURI,
PINodesAndEdges,
vitroRequest);
}
/**
* When the page for person level visualization is requested.
* @param egoURI
* @param vitroRequest
* @param coPIVO
*/
private TemplateResponseValues prepareStandaloneResponse(String egoURI,
CoPIData pINodesAndEdges, VitroRequest vitroRequest) {
Portal portal = vitroRequest.getPortal();
String title = "";
Map<String, Object> body = new HashMap<String, Object>();
if (pINodesAndEdges.getNodes() != null
&& pINodesAndEdges.getNodes().size() > 0) {
body.put("numOfAuthors", pINodesAndEdges.getNodes().size());
title = pINodesAndEdges.getEgoNode().getNodeName() + " - ";
}
if (pINodesAndEdges.getEdges() != null
&& pINodesAndEdges.getEdges().size() > 0) {
body.put("numOfCoPIs", pINodesAndEdges.getEdges().size());
}
String standaloneTemplate = "/visualization/coauthorship/coAuthorship.ftl";
body.put("portalBean", portal);
body.put("egoURIParam", egoURI);
body.put("title", title + "Co-PI Visualization");
return new TemplateResponseValues(standaloneTemplate, body);
}
/**
* Provides a response when graphml formatted co-pi network is requested, typically by
* the flash vis.
* @param pINodesAndEdges
*/
private Map<String, String> prepareNetworkDataResponse(CoPIData pINodesAndEdges) {
CoPIGraphMLWriter coPIGraphMLWriter =
new CoPIGraphMLWriter(pINodesAndEdges);
Map<String, String> fileData = new HashMap<String, String>();
fileData.put(DataVisualizationController.FILE_CONTENT_TYPE_KEY,
"text/xml");
fileData.put(DataVisualizationController.FILE_CONTENT_KEY,
coPIGraphMLWriter.getCoPIGraphMLContent().toString());
return fileData;
}
/**
* Provides response when a csv file containing number & names of unique co-pis per
* year is requested.
* @param pINodesAndEdges
*/
private Map<String, String> prepareCoPIDataResponse(CoPIData pINodesAndEdges) {
String outputFileName;
Map<String, Set<CoPINode>> yearToCoPI = new TreeMap<String, Set<CoPINode>>();
if (pINodesAndEdges.getNodes() != null && pINodesAndEdges.getNodes().size() > 0) {
outputFileName = UtilityFunctions.slugify(pINodesAndEdges
.getEgoNode().getNodeName())
+ "_copis-per-year" + ".csv";
yearToCoPI = UtilityFunctions.getGrantYearToCoPI(pINodesAndEdges);
} else {
outputFileName = "no_copis-per-year" + ".csv";
}
Map<String, String> fileData = new HashMap<String, String>();
fileData.put(DataVisualizationController.FILE_NAME_KEY,
outputFileName);
fileData.put(DataVisualizationController.FILE_CONTENT_TYPE_KEY,
"application/octet-stream");
fileData.put(DataVisualizationController.FILE_CONTENT_KEY,
getCoPIsPerYearCSVContent(yearToCoPI));
return fileData;
}
private String getCoPIsPerYearCSVContent(Map<String, Set<CoPINode>> yearToCoPI) {
StringBuilder csvFileContent = new StringBuilder();
csvFileContent.append("Year, Count, Co-PI(s)\n");
for (Map.Entry<String, Set<CoPINode>> currentEntry : yearToCoPI.entrySet()) {
csvFileContent.append(StringEscapeUtils.escapeCsv(currentEntry.getKey()));
csvFileContent.append(",");
csvFileContent.append(currentEntry.getValue().size());
csvFileContent.append(",");
csvFileContent.append(StringEscapeUtils.escapeCsv(getCoPINamesAsString(currentEntry.getValue())));
csvFileContent.append("\n");
}
return csvFileContent.toString();
}
private String getCoPINamesAsString(Set<CoPINode> CoPIs) {
StringBuilder coPIsMerged = new StringBuilder();
String coPISeparator = ";";
for(CoPINode currentCoPI : CoPIs){
coPIsMerged.append(currentCoPI.getNodeName() + coPISeparator);
}
return StringUtils.removeEnd(coPIsMerged.toString(), coPISeparator);
}
}

View file

@ -0,0 +1,319 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coprincipalinvestigator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPIData;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPIEdge;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPINode;
/**
* @author bkoniden
* Deepak Konidena
*/
public class CoPIGraphMLWriter {
private StringBuilder coPIGraphMLContent;
private final String GRAPHML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ " <graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"\n"
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
+ " xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns\n"
+ " http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">\n\n";
private final String GRAPHML_FOOTER = "</graphml>";
public CoPIGraphMLWriter(CoPIData coPIData){
coPIGraphMLContent = createCoPIGraphMLContent(coPIData);
}
private StringBuilder createCoPIGraphMLContent(CoPIData coPIData) {
StringBuilder graphMLContent = new StringBuilder();
graphMLContent.append(GRAPHML_HEADER);
/*
* We are side-effecting "graphMLContent" object in this method since creating
* another String object to hold key definition data will be redundant & will
* not serve the purpose.
* */
generateKeyDefinitionContent(coPIData, graphMLContent);
/*
* Used to generate graph content. It will contain both the nodes & edge information.
* We are side-effecting "graphMLContent".
* */
generateGraphContent(coPIData, graphMLContent);
graphMLContent.append(GRAPHML_FOOTER);
return graphMLContent;
}
public StringBuilder getCoPIGraphMLContent(){
return coPIGraphMLContent;
}
private void generateGraphContent(CoPIData coPIData,
StringBuilder graphMLContent) {
graphMLContent.append("\n<graph edgedefault=\"undirected\">\n");
if (coPIData.getNodes() != null & coPIData.getNodes().size() > 0) {
generateNodeSectionContent(coPIData, graphMLContent);
}
if (coPIData.getEdges() != null & coPIData.getEdges().size() > 0) {
generateEdgeSectionContent(coPIData, graphMLContent);
}
graphMLContent.append("</graph>\n");
}
private void generateEdgeSectionContent(CoPIData coPIData,
StringBuilder graphMLContent) {
graphMLContent.append("<!-- edges -->\n");
Set<CoPIEdge> edges = coPIData.getEdges();
List<CoPIEdge> orderedEdges = new ArrayList<CoPIEdge>(edges);
Collections.sort(orderedEdges, new CoPIEdgeComparator());
for (CoPIEdge currentEdge : orderedEdges) {
/*
* This method actually creates the XML code for a single edge. "graphMLContent"
* is being side-effected.
* */
getEdgeContent(graphMLContent, currentEdge);
}
}
private void getEdgeContent(StringBuilder graphMLContent, CoPIEdge currentEdge) {
graphMLContent.append("<edge "
+ "id=\"" + currentEdge.getEdgeID() + "\" "
+ "source=\"" + currentEdge.getSourceNode().getNodeID() + "\" "
+ "target=\"" + currentEdge.getTargetNode().getNodeID() + "\" "
+ ">\n");
graphMLContent.append("\t<data key=\"collaborator1\">"
+ currentEdge.getSourceNode().getNodeName()
+ "</data>\n");
graphMLContent.append("\t<data key=\"collaborator2\">"
+ currentEdge.getTargetNode().getNodeName()
+ "</data>\n");
graphMLContent.append("\t<data key=\"number_of_coinvestigated_grants\">"
+ currentEdge.getNumberOfCoInvestigatedGrants()
+ "</data>\n");
if (currentEdge.getEarliestCollaborationYearCount() != null) {
/*
* There is no clean way of getting the map contents in java even though
* we are sure to have only one entry on the map. So using the for loop.
* */
for (Map.Entry<String, Integer> publicationInfo
: currentEdge.getEarliestCollaborationYearCount().entrySet()) {
graphMLContent.append("\t<data key=\"earliest_collaboration\">"
+ publicationInfo.getKey()
+ "</data>\n");
graphMLContent.append("\t<data key=\"num_earliest_collaboration\">"
+ publicationInfo.getValue()
+ "</data>\n");
}
}
if (currentEdge.getLatestCollaborationYearCount() != null) {
for (Map.Entry<String, Integer> publicationInfo
: currentEdge.getLatestCollaborationYearCount().entrySet()) {
graphMLContent.append("\t<data key=\"latest_collaboration\">"
+ publicationInfo.getKey()
+ "</data>\n");
graphMLContent.append("\t<data key=\"num_latest_collaboration\">"
+ publicationInfo.getValue()
+ "</data>\n");
}
}
if (currentEdge.getUnknownCollaborationYearCount() != null) {
graphMLContent.append("\t<data key=\"num_unknown_collaboration\">"
+ currentEdge.getUnknownCollaborationYearCount()
+ "</data>\n");
}
graphMLContent.append("</edge>\n");
}
private void generateNodeSectionContent(CoPIData coPIData,
StringBuilder graphMLContent) {
graphMLContent.append("<!-- nodes -->\n");
CoPINode egoNode = coPIData.getEgoNode();
Set<CoPINode> piNodes = coPIData.getNodes();
/*
* This method actually creates the XML code for a single node. "graphMLContent"
* is being side-effected. The egoNode is added first because this is the "requirement"
* of the co-pi vis. Ego should always come first.
*
* */
getNodeContent(graphMLContent, egoNode);
List<CoPINode> orderedPINodes = new ArrayList<CoPINode>(piNodes);
orderedPINodes.remove(egoNode);
Collections.sort(orderedPINodes, new CoPINodeComparator());
for (CoPINode currNode : orderedPINodes) {
/*
* We have already printed the Ego Node info.
* */
if (currNode != egoNode) {
getNodeContent(graphMLContent, currNode);
}
}
}
private void getNodeContent(StringBuilder graphMLContent, CoPINode node) {
ParamMap individualProfileURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
node.getNodeURI());
String profileURL = UrlBuilder.getUrl(VisualizationFrameworkConstants.INDIVIDUAL_URL_PREFIX,
individualProfileURLParams);
graphMLContent.append("<node id=\"" + node.getNodeID() + "\">\n");
graphMLContent.append("\t<data key=\"url\">" + node.getNodeURI() + "</data>\n");
graphMLContent.append("\t<data key=\"label\">" + node.getNodeName() + "</data>\n");
if (profileURL != null) {
graphMLContent.append("\t<data key=\"profile_url\">" + profileURL + "</data>\n");
}
graphMLContent.append("\t<data key=\"number_of_investigated_grants\">"
+ node.getNumberOfInvestigatedGrants()
+ "</data>\n");
if (node.getEarliestGrantYearCount() != null) {
/*
* There is no clean way of getting the map contents in java even though
* we are sure to have only one entry on the map. So using the for loop.
* I am feeling dirty just about now.
* */
for (Map.Entry<String, Integer> publicationInfo
: node.getEarliestGrantYearCount().entrySet()) {
graphMLContent.append("\t<data key=\"earliest_grant\">"
+ publicationInfo.getKey()
+ "</data>\n");
graphMLContent.append("\t<data key=\"num_earliest_grant\">"
+ publicationInfo.getValue()
+ "</data>\n");
}
}
if (node.getLatestGrantYearCount() != null) {
for (Map.Entry<String, Integer> publicationInfo
: node.getLatestGrantYearCount().entrySet()) {
graphMLContent.append("\t<data key=\"latest_grant\">"
+ publicationInfo.getKey()
+ "</data>\n");
graphMLContent.append("\t<data key=\"num_latest_grant\">"
+ publicationInfo.getValue()
+ "</data>\n");
}
}
if (node.getUnknownGrantYearCount() != null) {
graphMLContent.append("\t<data key=\"num_unknown_grant\">"
+ node.getUnknownGrantYearCount()
+ "</data>\n");
}
graphMLContent.append("</node>\n");
}
private void generateKeyDefinitionContent(CoPIData coPIData,
StringBuilder graphMLContent) {
/*
* Generate the key definition content for node.
* */
getKeyDefinitionFromSchema(coPIData.getNodeSchema(), graphMLContent);
/*
* Generate the key definition content for edge.
* */
getKeyDefinitionFromSchema(coPIData.getEdgeSchema(), graphMLContent);
}
private void getKeyDefinitionFromSchema(Set<Map<String, String>> schema,
StringBuilder graphMLContent) {
for (Map<String, String> currentNodeSchemaAttribute : schema) {
graphMLContent.append("\n<key ");
for (Map.Entry<String, String> currentAttributeKey
: currentNodeSchemaAttribute.entrySet()) {
graphMLContent.append(currentAttributeKey.getKey()
+ "=\"" + currentAttributeKey.getValue()
+ "\" ");
}
if (currentNodeSchemaAttribute.containsKey("default")) {
graphMLContent.append(">\n");
graphMLContent.append("<default>");
graphMLContent.append(currentNodeSchemaAttribute.get("default"));
graphMLContent.append("</default>\n");
graphMLContent.append("</key>\n");
} else {
graphMLContent.append("/>\n");
}
}
}
}

View file

@ -0,0 +1,20 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coprincipalinvestigator;
import java.util.Comparator;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPINode;
/**
* This Comparator is used to sort the CoPINodes based on their IDs in ascending order.
* @author bkoniden
* Deepak Konidena
*/
public class CoPINodeComparator implements Comparator<CoPINode>{
@Override
public int compare(CoPINode arg0, CoPINode arg1) {
return arg0.getNodeID() - arg1.getNodeID();
}
}

View file

@ -0,0 +1,623 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coprincipalinvestigator;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.Map.Entry;
import org.apache.commons.logging.Log;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationController;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPINode;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineData;
/**
* This class contains code for rendering sparklines and displaying tables for
* Co-PI visualization.
* @author bkoniden
* Deepak Konidena
*/
@SuppressWarnings("serial")
public class CoPIVisCodeGenerator {
/*
* There are 2 modes of sparkline that are available via this visualization.
* 1. Short Sparkline - This sparkline will render all the data points (or sparks),
* which in this case are the copi(s) over the years, from the last 10 years.
*
* 2. Full Sparkline - This sparkline will render all the data points (or sparks)
* spanning the career of the person & last 10 years at the minimum, in case if
* the person started his career in the last 10 years.
* */
private static final Map<String, String> VIS_DIV_NAMES = new HashMap<String, String>() { {
put("SHORT_SPARK", "unique_copis_short_sparkline_vis");
put("FULL_SPARK", "unique_copis_full_sparkline_vis");
} };
private static final String VISUALIZATION_STYLE_CLASS = "sparkline_style";
private static final String DEFAULT_VISCONTAINER_DIV_ID = "unique_copis_vis_container";
private Map<String, Set<CoPINode>> yearToUniqueCoPIs;
private Log log;
private SparklineData sparklineData;
private String contextPath;
private String individualURI;
public CoPIVisCodeGenerator(String contextPath,
String individualURI,
String visMode,
String visContainer,
Map<String, Set<CoPINode>> yearToUniqueCoPIs,
Log log){
this.contextPath = contextPath;
this.individualURI = individualURI;
this.yearToUniqueCoPIs = yearToUniqueCoPIs;
this.sparklineData = new SparklineData();
this.log = log;
generateVisualizationCode(visMode, visContainer);
}
/**
* This method is used to generate the visualization code (HMTL, CSS &
* JavaScript). There 2 parts to it - 1. Actual Content Code & 2. Context
* Code. 1. Actual Content code in this case is the sparkline image, text
* related to data and the wrapping tables. This is generated via call to
* google vis API through JavaScript. 2. Context code is generally optional
* but contains code pertaining to tabulated data & links to download files
* etc.
*
* @param visMode
* @param visContainer
*/
private void generateVisualizationCode(String visMode, String visContainer) {
sparklineData.setSparklineContent(getMainVisualizationCode(visMode,
visContainer));
sparklineData.setSparklineContext(getVisualizationContextCode(visMode));
}
private String getMainVisualizationCode(String visMode,
String providedVisContainerID) {
int numOfYearsToBeRendered = 0;
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
int shortSparkMinYear = currentYear
- VisConstants.MINIMUM_YEARS_CONSIDERED_FOR_SPARKLINE + 1;
/*
* This is required because when deciding the range of years over which
* the vis was rendered we dont want to be influenced by the
* "DEFAULT_GRANT_YEAR".
*/
Set<String> investigatedYears = new HashSet<String>(yearToUniqueCoPIs
.keySet());
investigatedYears.remove(VOConstants.DEFAULT_GRANT_YEAR);
/*
* We are setting the default value of minGrantYear to be 10 years
* before the current year (which is suitably represented by the
* shortSparkMinYear), this in case we run into invalid set of investigated
* years.
*/
int minGrantYear = shortSparkMinYear;
String visContainerID = null;
StringBuilder visualizationCode = new StringBuilder();
if (yearToUniqueCoPIs.size() > 0) {
try {
minGrantYear = Integer.parseInt(Collections
.min(investigatedYears));
} catch (NoSuchElementException e1) {
log.debug("vis: " + e1.getMessage() + " error occurred for "
+ yearToUniqueCoPIs.toString());
} catch (NumberFormatException e2) {
log.debug("vis: " + e2.getMessage() + " error occurred for "
+ yearToUniqueCoPIs.toString());
}
}
int minGrantYearConsidered = 0;
/*
* There might be a case that the person investigated his first grant
* within the last 10 years but we want to make sure that the sparkline
* is representative of at least the last 10 years, so we will set the
* minGrantYearConsidered to "currentYear - 10" which is also given by
* "shortSparkMinYear".
*/
if (minGrantYear > shortSparkMinYear) {
minGrantYearConsidered = shortSparkMinYear;
} else {
minGrantYearConsidered = minGrantYear;
}
numOfYearsToBeRendered = currentYear - minGrantYearConsidered + 1;
visualizationCode.append("<style type='text/css'>" + "."
+ VISUALIZATION_STYLE_CLASS + " table{" + " margin: 0;"
+ " padding: 0;" + " width: auto;"
+ " border-collapse: collapse;" + " border-spacing: 0;"
+ " vertical-align: inherit;" + "}"
+ ".incomplete-data-holder {" + "" + "}"
+ "td.sparkline_number { text-align:right; "
+ "padding-right:5px; }"
+ "td.sparkline_text {text-align:left;}" + "</style>\n");
visualizationCode
.append("<script type=\"text/javascript\">\n"
+ "function drawUniqueCoPICountVisualization(providedSparklineImgTD) {\n"
+ "var data = new google.visualization.DataTable();\n"
+ "data.addColumn('string', 'Year');\n"
+ "data.addColumn('number', 'Unique Co-PI(s)');\n"
+ "data.addRows(" + numOfYearsToBeRendered + ");\n");
int uniqueCoPICounter = 0;
int renderedFullSparks = 0;
Set<CoPINode> allCoPIsWithKnownGrantShipYears = new HashSet<CoPINode>();
for (int grantYear = minGrantYearConsidered; grantYear <= currentYear; grantYear++) {
String grantYearAsString = String.valueOf(grantYear);
Set<CoPINode> currentCoPIs = yearToUniqueCoPIs
.get(grantYearAsString);
Integer currentUniqueCoPIs = null;
if (currentCoPIs != null) {
currentUniqueCoPIs = currentCoPIs.size();
allCoPIsWithKnownGrantShipYears.addAll(currentCoPIs);
} else {
currentUniqueCoPIs = 0;
}
visualizationCode.append("data.setValue(" + uniqueCoPICounter
+ ", 0, '" + grantYearAsString + "');\n");
visualizationCode.append("data.setValue(" + uniqueCoPICounter
+ ", 1, " + currentUniqueCoPIs + ");\n");
uniqueCoPICounter++;
}
/*
* For the purpose of this visualization I have come up with a term
* "Sparks" which essentially means data points. Sparks that will be
* rendered in full mode will always be the one's which have any year
* associated with it. Hence.
*/
renderedFullSparks = allCoPIsWithKnownGrantShipYears.size();
/*
* Total grants will also consider publications that have no year
* associated with them. Hence.
*/
Integer unknownYearCoPIs = 0;
if (yearToUniqueCoPIs.get(VOConstants.DEFAULT_GRANT_YEAR) != null) {
unknownYearCoPIs = yearToUniqueCoPIs.get(
VOConstants.DEFAULT_GRANT_YEAR).size();
}
String sparklineDisplayOptions = "{width: 65, height: 30, showAxisLines: false, "
+ "showValueLabels: false, labelPosition: 'none'}";
if (providedVisContainerID != null) {
visContainerID = providedVisContainerID;
} else {
visContainerID = DEFAULT_VISCONTAINER_DIV_ID;
}
/*
* By default these represents the range of the rendered sparks. Only in
* case of "short" sparkline mode we will set the Earliest
* RenderedGrant year to "currentYear - 10".
*/
sparklineData.setEarliestRenderedGrantYear(minGrantYear);
sparklineData.setLatestRenderedGrantYear(currentYear);
/*
* The Full Sparkline will be rendered by default. Only if the url has
* specific mention of SHORT_SPARKLINE_MODE_KEY then we render the short
* sparkline and not otherwise.
*/
/*
* Since building StringBuilder objects (which is being used to store
* the vis code) is essentially a side-effecting process, we have both
* the activators method as side-effecting. They both side-effect
* "visualizationCode"
*/
if (VisualizationFrameworkConstants.SHORT_SPARKLINE_VIS_MODE
.equalsIgnoreCase(visMode)) {
sparklineData.setEarliestRenderedGrantYear(shortSparkMinYear);
generateShortSparklineVisualizationContent(currentYear,
shortSparkMinYear, visContainerID, visualizationCode,
unknownYearCoPIs, sparklineDisplayOptions);
} else {
generateFullSparklineVisualizationContent(currentYear,
minGrantYearConsidered, visContainerID, visualizationCode,
unknownYearCoPIs, renderedFullSparks,
sparklineDisplayOptions);
}
log.debug(visualizationCode);
return visualizationCode.toString();
}
private void generateShortSparklineVisualizationContent(int currentYear,
int shortSparkMinYear, String visContainerID,
StringBuilder visualizationCode, int unknownYearGrants,
String sparklineDisplayOptions) {
/*
* Create a view of the data containing only the column pertaining to
* grant count.
*/
visualizationCode.append("var shortSparklineView = "
+ "new google.visualization.DataView(data);\n"
+ "shortSparklineView.setColumns([1]);\n");
/*
* For the short view we only want the last 10 year's view of
* grant count, hence we filter the data we actually want to use
* for render.
*/
visualizationCode.append("shortSparklineView.setRows("
+ "data.getFilteredRows([{column: 0, " + "minValue: '"
+ shortSparkMinYear + "', " + "maxValue: '" + currentYear
+ "'}])" + ");\n");
/*
* Create the vis object and draw it in the div pertaining to
* short-sparkline.
*/
visualizationCode
.append("var short_spark = new google.visualization.ImageSparkLine("
+ "providedSparklineImgTD[0]"
+ ");\n"
+ "short_spark.draw(shortSparklineView, "
+ sparklineDisplayOptions + ");\n");
/*
* We want to display how many grant counts were considered, so
* this is used to calculate this.
*/
visualizationCode
.append("var shortSparkRows = shortSparklineView.getViewRows();\n"
+ "var renderedShortSparks = 0;\n"
+ "$.each(shortSparkRows, function(index, value) {"
+ "renderedShortSparks += data.getValue(value, 1);"
+ "});\n");
/*
* Generate the text introducing the vis.
*/
String imcompleteDataText = "This information is based solely on grants which "
+ "have been loaded into the VIVO system. "
+ "This may only be a small sample of the person\\'s "
+ "total work.";
visualizationCode.append("$('#" + VIS_DIV_NAMES.get("SHORT_SPARK")
+ " td.sparkline_number').text("
+ "parseInt(renderedShortSparks) " + "+ parseInt("
+ unknownYearGrants + "));");
visualizationCode.append("var shortSparksText = ''"
+ "+ ' grant(s) within the last 10 years "
+ "<span class=\"incomplete-data-holder\" title=\""
+ imcompleteDataText + "\">incomplete data</span>'" + "+ '';"
+ "$('#" + VIS_DIV_NAMES.get("SHORT_SPARK") + " "
+ "td.sparkline_text').html(shortSparksText);");
visualizationCode.append("}\n ");
/*
* Generate the code that will activate the visualization. It takes care
* of creating div elements to hold the actual sparkline image and then
* calling the drawUniqueCoPICountVisualization function.
*/
visualizationCode.append(generateVisualizationActivator(VIS_DIV_NAMES
.get("SHORT_SPARK"), visContainerID));
}
private void generateFullSparklineVisualizationContent(
int currentYear,
int minGrantYearConsidered,
String visContainerID,
StringBuilder visualizationCode,
int unknownYearGrants,
int renderedFullSparks,
String sparklineDisplayOptions) {
String csvDownloadURLHref = "";
try {
if (getCSVDownloadURL() != null) {
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL()
+ "\" class=\"inline_href\">(.CSV File)</a>";
} else {
csvDownloadURLHref = "";
}
} catch (UnsupportedEncodingException e) {
csvDownloadURLHref = "";
}
visualizationCode.append("var fullSparklineView = "
+ "new google.visualization.DataView(data);\n"
+ "fullSparklineView.setColumns([1]);\n");
visualizationCode.append("var full_spark = new google.visualization.ImageSparkLine("
+ "providedSparklineImgTD[0]"
+ ");\n"
+ "full_spark.draw(fullSparklineView, "
+ sparklineDisplayOptions + ");\n");
visualizationCode.append("$('#" + VIS_DIV_NAMES.get("FULL_SPARK")
+ " td.sparkline_number').text('" + (renderedFullSparks
+ unknownYearGrants) + "');");
visualizationCode.append("var allSparksText = ''"
+ "+ ' Co-Principal Investigator(s) '"
+ "+ ' from "
+ "<span class=\"sparkline_range\">"
+ "" + minGrantYearConsidered + " to " + currentYear + ""
+ "</span> '"
+ "+ ' " + csvDownloadURLHref + " ';"
+ "$('#" + VIS_DIV_NAMES.get("FULL_SPARK")
+ " td.sparkline_text').html(allSparksText);");
visualizationCode.append("}\n ");
visualizationCode.append(generateVisualizationActivator(VIS_DIV_NAMES.get("FULL_SPARK"),
visContainerID));
}
private String generateVisualizationActivator(String sparklineID, String visContainerID) {
String sparklineTableWrapper = "\n"
+ "var table = $('<table>');"
+ "table.attr('class', 'sparkline_wrapper_table');"
+ "var row = $('<tr>');"
+ "sparklineImgTD = $('<td>');"
+ "sparklineImgTD.attr('id', '" + sparklineID + "_img');"
+ "sparklineImgTD.attr('width', '65');"
+ "sparklineImgTD.attr('align', 'right');"
+ "sparklineImgTD.attr('class', '" + VISUALIZATION_STYLE_CLASS + "');"
+ "row.append(sparklineImgTD);"
+ "var sparklineNumberTD = $('<td>');"
+ "sparklineNumberTD.attr('width', '30');"
+ "sparklineNumberTD.attr('align', 'right');"
+ "sparklineNumberTD.attr('class', 'sparkline_number');"
+ "row.append(sparklineNumberTD);"
+ "var sparklineTextTD = $('<td>');"
+ "sparklineTextTD.attr('width', '450');"
+ "sparklineTextTD.attr('class', 'sparkline_text');"
+ "row.append(sparklineTextTD);"
+ "table.append(row);"
+ "table.prependTo('#" + sparklineID + "');\n";
return "$(document).ready(function() {"
+ "var sparklineImgTD; "
/*
* This is a nuclear option (creating the container in which everything goes)
* the only reason this will be ever used is the API user never submitted a
* container ID in which everything goes. The alternative was to let the
* vis not appear in the calling page at all. So now atleast vis appears but
* appended at the bottom of the body.
* */
+ "if ($('#" + visContainerID + "').length === 0) {"
+ " $('<div/>', {'id': '" + visContainerID + "'"
+ " }).appendTo('body');"
+ "}"
+ "if ($('#" + sparklineID + "').length === 0) {"
+ "$('<div/>', {'id': '" + sparklineID + "',"
+ "'class': '" + VISUALIZATION_STYLE_CLASS + "'"
+ "}).prependTo('#" + visContainerID + "');"
+ sparklineTableWrapper
+ "}"
+ "drawUniqueCoPICountVisualization(sparklineImgTD);"
+ "});"
+ "</script>\n";
}
private String getVisualizationContextCode(String visMode) {
String visualizationContextCode = "";
if (VisualizationFrameworkConstants.SHORT_SPARKLINE_VIS_MODE.equalsIgnoreCase(visMode)) {
visualizationContextCode = generateShortVisContext();
} else {
visualizationContextCode = generateFullVisContext();
}
log.debug(visualizationContextCode);
return visualizationContextCode;
}
private String generateFullVisContext() {
StringBuilder divContextCode = new StringBuilder();
String csvDownloadURLHref = "";
if (yearToUniqueCoPIs.size() > 0) {
try {
if (getCSVDownloadURL() != null) {
csvDownloadURLHref = "Download data as <a href='"
+ getCSVDownloadURL() + "'>.csv</a> file.<br />";
sparklineData.setDownloadDataLink(getCSVDownloadURL());
} else {
csvDownloadURLHref = "";
}
} catch (UnsupportedEncodingException e) {
csvDownloadURLHref = "";
}
} else {
csvDownloadURLHref = "No data available to export.<br />";
}
String tableCode = generateDataTable();
divContextCode.append("<p>" + tableCode + csvDownloadURLHref + "</p>");
sparklineData.setTable(tableCode);
return divContextCode.toString();
}
private String getCSVDownloadURL() throws UnsupportedEncodingException {
if (yearToUniqueCoPIs.size() > 0) {
String secondaryContextPath = "";
if (!contextPath.contains(VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX)) {
secondaryContextPath = VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX;
}
String downloadURL = contextPath
+ secondaryContextPath
+ "?" + VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
+ "=" + URLEncoder.encode(individualURI,
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&" + VisualizationFrameworkConstants.VIS_TYPE_KEY
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
.CO_PI_VIS,
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&" + VisualizationFrameworkConstants.VIS_MODE_KEY
+ "=" + URLEncoder.encode("sparkline",
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&" + VisualizationFrameworkConstants.RENDER_MODE_KEY
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants.DATA_RENDER_MODE,
VisualizationController.URL_ENCODING_SCHEME).toString();
return downloadURL;
} else {
return null;
}
}
private String generateShortVisContext() {
StringBuilder divContextCode = new StringBuilder();
try {
String fullTimelineLink;
if (yearToUniqueCoPIs.size() > 0) {
String secondaryContextPath = "";
if (!contextPath.contains(VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX)) {
secondaryContextPath = VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX;
}
String fullTimelineNetworkURL = contextPath
+ secondaryContextPath
+ "?"
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
+ "=" + URLEncoder.encode(individualURI,
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&"
+ VisualizationFrameworkConstants.VIS_TYPE_KEY
+ "=" + URLEncoder.encode("person_level",
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&"
+ VisualizationFrameworkConstants.VIS_CONTAINER_KEY
+ "=" + URLEncoder.encode("ego_sparkline",
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&"
+ VisualizationFrameworkConstants.RENDER_MODE_KEY
+ "=" + URLEncoder.encode(
VisualizationFrameworkConstants
.STANDALONE_RENDER_MODE,
VisualizationController.URL_ENCODING_SCHEME).toString();
fullTimelineLink = "<a href='" + fullTimelineNetworkURL
+ "'>View full timeline and co-pi network.</a>";
sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL);
} else {
fullTimelineLink = "No data available to render full timeline.<br />";
}
divContextCode.append("<p>" + fullTimelineLink + "</p>");
} catch (UnsupportedEncodingException e) {
log.error(e);
}
return divContextCode.toString();
}
private String generateDataTable() {
StringBuilder dataTable = new StringBuilder();
dataTable.append("<table id='sparkline_data_table'>"
+ "<caption>Unique Co-PIs per year</caption>"
+ "<thead>"
+ "<tr>"
+ "<th>Year</th>"
+ "<th>Count</th>"
+ "</tr>"
+ "</thead>"
+ "<tbody>");
for (Entry<String, Set<CoPINode>> currentEntry : yearToUniqueCoPIs.entrySet()) {
dataTable.append("<tr>"
+ "<td>" + currentEntry.getKey() + "</td>"
+ "<td>" + currentEntry.getValue().size() + "</td>"
+ "</tr>");
}
dataTable.append("</tbody>\n </table>\n");
return dataTable.toString();
}
public SparklineData getValueObjectContainer() {
return sparklineData;
}
}

View file

@ -129,7 +129,7 @@ public class PersonGrantCountQueryRunner implements QueryRunner<Set<Grant>>{
+ "?Grant rdfs:label ?GrantLabel ; core:startDate ?GrantStartDate ; core:endDate ?GrantEndDate ." + "?Grant rdfs:label ?GrantLabel ; core:startDate ?GrantStartDate ; core:endDate ?GrantEndDate ."
+ "}"; + "}";
System.out.println("SPARQL query for person grant count -> \n"+ sparqlQuery); log.debug("SPARQL query for person grant count -> \n"+ sparqlQuery);
return sparqlQuery; return sparqlQuery;
} }

View file

@ -2,38 +2,29 @@
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.persongrantcount; package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.persongrantcount;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import com.hp.hpl.jena.query.DataSource; import com.hp.hpl.jena.query.DataSource;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfWriter;
import edu.cornell.mannlib.vitro.webapp.beans.Portal; import edu.cornell.mannlib.vitro.webapp.beans.Portal;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants; import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.DataVisualizationController;
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException; import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Grant; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Grant;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Individual; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Individual;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.SparklineData; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.SparklineData;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.VisualizationRequestHandler; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.VisualizationRequestHandler;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.PDFDocument;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner; import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
@ -54,24 +45,17 @@ import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
*/ */
public class PersonGrantCountRequestHandler implements VisualizationRequestHandler { public class PersonGrantCountRequestHandler implements VisualizationRequestHandler {
public ResponseValues generateVisualization(VitroRequest vitroRequest, @Override
Log log, DataSource dataSource) { public Map<String, String> generateDataVisualization(
VitroRequest vitroRequest, Log log, DataSource dataSource)
throws MalformedQueryParametersException {
String personURI = vitroRequest String personURI = vitroRequest
.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY); .getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
String renderMode = vitroRequest
.getParameter(VisualizationFrameworkConstants.RENDER_MODE_KEY);
String visMode = vitroRequest
.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY);
String visContainer = vitroRequest
.getParameter(VisualizationFrameworkConstants.VIS_CONTAINER_KEY);
QueryRunner<Set<Grant>> queryManager = new PersonGrantCountQueryRunner(personURI, dataSource, log ); QueryRunner<Set<Grant>> queryManager = new PersonGrantCountQueryRunner(personURI, dataSource, log );
try{
Set<Grant> piGrants = queryManager.getQueryResult(); Set<Grant> piGrants = queryManager.getQueryResult();
/* /*
@ -83,38 +67,94 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
Individual investigator = ((PersonGrantCountQueryRunner) queryManager).getPrincipalInvestigator(); Individual investigator = ((PersonGrantCountQueryRunner) queryManager).getPrincipalInvestigator();
if (VisualizationFrameworkConstants.DATA_RENDER_MODE
.equalsIgnoreCase(renderMode)) {
/*
return prepareDataResponse(investigator, return prepareDataResponse(investigator,
piGrants, piGrants,
yearToGrantCount); yearToGrantCount);
*/
} }
@Override
public Object generateAjaxVisualization(VitroRequest vitroRequest, Log log,
DataSource dataSource) throws MalformedQueryParametersException {
String personURI = vitroRequest
.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
String visMode = vitroRequest
.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY);
String visContainer = vitroRequest
.getParameter(VisualizationFrameworkConstants.VIS_CONTAINER_KEY);
QueryRunner<Set<Grant>> queryManager = new PersonGrantCountQueryRunner(personURI, dataSource, log );
Set<Grant> piGrants = queryManager.getQueryResult();
/* /*
* For now we are disabling the capability to render pdf file. * Create a map from the year to number of grants. Use the Grant's
* parsedGrantYear to populate the data.
* */ * */
/* Map<String, Integer> yearToGrantCount =
if (VisualizationFrameworkConstants.PDF_RENDER_MODE UtilityFunctions.getYearToGrantCount(piGrants);
.equalsIgnoreCase(renderMode)) {
preparePDFResponse(investigator,
piGrants, boolean shouldVIVOrenderVis =
yearToGrantCount, yearToGrantCount.size() > 0 ? true : false;
response);
return;
}
*/
/* /*
* Computations required to generate HTML for the sparkline & related context. * Computations required to generate HTML for the sparkline & related context.
* */ * */
PersonGrantCountVisCodeGenerator visualizationCodeGenerator = PersonGrantCountVisCodeGenerator visualizationCodeGenerator =
new PersonGrantCountVisCodeGenerator(vitroRequest.getContextPath(), new PersonGrantCountVisCodeGenerator(personURI,
personURI, visMode,
visContainer,
piGrants,
yearToGrantCount,
log);
SparklineData sparklineData = visualizationCodeGenerator
.getValueObjectContainer();
return prepareDynamicResponse(vitroRequest,
sparklineData,
shouldVIVOrenderVis);
}
@Override
public ResponseValues generateStandardVisualization(
VitroRequest vitroRequest, Log log, DataSource dataSource)
throws MalformedQueryParametersException {
String personURI = vitroRequest
.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
String visMode = vitroRequest
.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY);
String visContainer = vitroRequest
.getParameter(VisualizationFrameworkConstants.VIS_CONTAINER_KEY);
QueryRunner<Set<Grant>> queryManager = new PersonGrantCountQueryRunner(personURI, dataSource, log );
Set<Grant> piGrants = queryManager.getQueryResult();
/*
* Create a map from the year to number of grants. Use the Grant's
* parsedGrantYear to populate the data.
* */
Map<String, Integer> yearToGrantCount =
UtilityFunctions.getYearToGrantCount(piGrants);
/*
* Computations required to generate HTML for the sparkline & related context.
* */
PersonGrantCountVisCodeGenerator visualizationCodeGenerator =
new PersonGrantCountVisCodeGenerator(personURI,
visMode, visMode,
visContainer, visContainer,
piGrants, piGrants,
@ -124,30 +164,9 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
SparklineData sparklineData = visualizationCodeGenerator SparklineData sparklineData = visualizationCodeGenerator
.getValueObjectContainer(); .getValueObjectContainer();
/*
* This is side-effecting because the response of this method is just to redirect to
* a page with visualization on it.
* */
RequestDispatcher requestDispatcher = null;
if (VisualizationFrameworkConstants.DYNAMIC_RENDER_MODE
.equalsIgnoreCase(renderMode)) {
return prepareDynamicResponse(vitroRequest,
sparklineData,
yearToGrantCount);
} else {
return prepareStandaloneResponse(vitroRequest, return prepareStandaloneResponse(vitroRequest,
sparklineData); sparklineData);
} }
} catch (MalformedQueryParametersException e) {
return UtilityFunctions.handleMalformedParameters(
"Visualization Query Error - Individual Grant Count",
e.getMessage(),
vitroRequest);
}
}
private String getGrantsOverTimeCSVContent(Map<String, Integer> yearToGrantCount) { private String getGrantsOverTimeCSVContent(Map<String, Integer> yearToGrantCount) {
@ -199,13 +218,15 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
String outputFileName = UtilityFunctions.slugify(piName) String outputFileName = UtilityFunctions.slugify(piName)
+ "_grants-per-year" + ".csv"; + "_grants-per-year" + ".csv";
Map<String, String> fileData = new HashMap<String, String>();
fileData.put(DataVisualizationController.FILE_NAME_KEY,
outputFileName);
fileData.put(DataVisualizationController.FILE_CONTENT_TYPE_KEY,
"application/octet-stream");
fileData.put(DataVisualizationController.FILE_CONTENT_KEY,
getGrantsOverTimeCSVContent(yearToGrantCount));
Map<String, Object> fileContents = new HashMap<String, Object>(); return fileData;
fileContents.put("fileContent", getGrantsOverTimeCSVContent(yearToGrantCount));
// return new FileResponseValues(new ContentType(), outputFileName, fileContents);
return new HashMap<String, String>();
} }
/** /**
@ -226,11 +247,6 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
body.put("title", "Individual Grant Count visualization"); body.put("title", "Individual Grant Count visualization");
body.put("sparklineVO", valueObjectContainer); body.put("sparklineVO", valueObjectContainer);
/*
* DO NOT DO THIS HERE. Set stylesheets/scripts in the *.ftl instead using $(scripts.add)
* */
// body.put("scripts", "/templates/visualization/visualization_scripts.jsp");
return new TemplateResponseValues(standaloneTemplate, body); return new TemplateResponseValues(standaloneTemplate, body);
} }
@ -246,7 +262,7 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
private TemplateResponseValues prepareDynamicResponse( private TemplateResponseValues prepareDynamicResponse(
VitroRequest vreq, VitroRequest vreq,
SparklineData valueObjectContainer, SparklineData valueObjectContainer,
Map<String, Integer> yearToGrantCount) { boolean shouldVIVOrenderVis) {
Portal portal = vreq.getPortal(); Portal portal = vreq.getPortal();
@ -256,102 +272,10 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
Map<String, Object> body = new HashMap<String, Object>(); Map<String, Object> body = new HashMap<String, Object>();
body.put("portalBean", portal); body.put("portalBean", portal);
body.put("sparklineVO", valueObjectContainer); body.put("sparklineVO", valueObjectContainer);
body.put("shouldVIVOrenderVis", shouldVIVOrenderVis);
/*
* DO NOT DO THIS HERE. Set stylesheets/scripts in the *.ftl instead using $(scripts.add)
* */
// body.put("scripts", "/templates/visualization/visualization_scripts.jsp");
if (yearToGrantCount.size() > 0) {
body.put("shouldVIVOrenderVis", true);
} else {
body.put("shouldVIVOrenderVis", false);
}
return new TemplateResponseValues(dynamicTemplate, body); return new TemplateResponseValues(dynamicTemplate, body);
} }
private void preparePDFResponse(Individual investigator,
Set<Grant> piGrants,
Map<String, Integer> yearToGrantCount,
HttpServletResponse response) {
String piName = null;
// To protect against cases where there are no PI grants
// associated with the
// / individual.
if (piGrants.size() > 0) {
piName = investigator.getIndividualLabel();
}
// To make sure that null/empty records for PI names do not cause
// any mischief.
if (StringUtils.isBlank(piName)) {
piName = "no-principal-investigator";
}
String outputFileName = UtilityFunctions.slugify(piName)
+ "_report" + ".pdf";
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment;filename="
+ outputFileName);
ServletOutputStream responseOutputStream;
try {
responseOutputStream = response.getOutputStream();
Document document = new Document();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter pdfWriter = PdfWriter.getInstance(document, baos);
document.open();
PDFDocument pdfDocument = new PDFDocument(piName,
yearToGrantCount, document, pdfWriter);
document.close();
// setting some response headers & content type
response.setHeader("Expires", "0");
response.setHeader("Cache-Control",
"must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
response.setContentLength(baos.size());
// write ByteArrayOutputStream to the ServletOutputStream
baos.writeTo(responseOutputStream);
responseOutputStream.flush();
responseOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
}
@Override
public Object generateAjaxVisualization(VitroRequest vitroRequest, Log log,
DataSource dataSource) throws MalformedQueryParametersException {
// TODO Auto-generated method stub
return null;
}
@Override
public Map<String, String> generateDataVisualization(
VitroRequest vitroRequest, Log log, DataSource dataSource)
throws MalformedQueryParametersException {
// TODO Auto-generated method stub
return null;
}
@Override
public ResponseValues generateStandardVisualization(
VitroRequest vitroRequest, Log log, DataSource dataSource)
throws MalformedQueryParametersException {
// TODO Auto-generated method stub
return null;
}
} }

View file

@ -2,8 +2,6 @@
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.persongrantcount; package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.persongrantcount;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
@ -11,13 +9,14 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import java.util.Map.Entry;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.StandardVisualizationController; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants; import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants; import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants; import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants;
@ -26,7 +25,7 @@ import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Sp
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.YearGrantCountDataElement; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.YearGrantCountDataElement;
@SuppressWarnings("serial")
public class PersonGrantCountVisCodeGenerator { public class PersonGrantCountVisCodeGenerator {
/* /*
@ -38,6 +37,7 @@ public class PersonGrantCountVisCodeGenerator {
* spanning the career of the person & last 10 years at the minimum, in case if * spanning the career of the person & last 10 years at the minimum, in case if
* the person started his career in the last 10 yeras. * the person started his career in the last 10 yeras.
* */ * */
private static final Map<String, String> VIS_DIV_NAMES = new HashMap<String, String>() { { private static final Map<String, String> VIS_DIV_NAMES = new HashMap<String, String>() { {
put("SHORT_SPARK", "grant_count_short_sparkline_vis"); put("SHORT_SPARK", "grant_count_short_sparkline_vis");
@ -55,16 +55,13 @@ public class PersonGrantCountVisCodeGenerator {
private SparklineData sparklineData; private SparklineData sparklineData;
private String contextPath;
private String individualURI; private String individualURI;
public PersonGrantCountVisCodeGenerator(String contextPath, public PersonGrantCountVisCodeGenerator(String individualURIParam,
String individualURIParam, String visMode, String visContainer, String visMode, String visContainer, Set<Grant> piGrants,
Set<Grant> piGrants, Map<String, Integer> yearToGrantCount,
Map<String, Integer> yearToGrantCount, Log log) { Log log) {
this.contextPath = contextPath;
this.individualURI = individualURIParam; this.individualURI = individualURIParam;
this.yearToGrantCount = yearToGrantCount; this.yearToGrantCount = yearToGrantCount;
@ -198,8 +195,7 @@ public class PersonGrantCountVisCodeGenerator {
for (int grantYear = minGrantYearConsidered; grantYear <= currentYear; grantYear++) { for (int grantYear = minGrantYearConsidered; grantYear <= currentYear; grantYear++) {
String stringInvestigatedYear = String.valueOf(grantYear); String stringInvestigatedYear = String.valueOf(grantYear);
Integer currentGrants = yearToGrantCount Integer currentGrants = yearToGrantCount.get(stringInvestigatedYear);
.get(stringInvestigatedYear);
if (currentGrants == null) { if (currentGrants == null) {
currentGrants = 0; currentGrants = 0;
@ -385,7 +381,6 @@ public class PersonGrantCountVisCodeGenerator {
String csvDownloadURLHref = ""; String csvDownloadURLHref = "";
try {
if (getCSVDownloadURL() != null) { if (getCSVDownloadURL() != null) {
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL() csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL()
@ -395,10 +390,6 @@ public class PersonGrantCountVisCodeGenerator {
csvDownloadURLHref = ""; csvDownloadURLHref = "";
} }
} catch (UnsupportedEncodingException e) {
csvDownloadURLHref = "";
}
visualizationCode.append("var fullSparklineView = " visualizationCode.append("var fullSparklineView = "
+ "new google.visualization.DataView(data);\n" + "new google.visualization.DataView(data);\n"
@ -505,7 +496,6 @@ public class PersonGrantCountVisCodeGenerator {
if (yearToGrantCount.size() > 0) { if (yearToGrantCount.size() > 0) {
try {
if (getCSVDownloadURL() != null) { if (getCSVDownloadURL() != null) {
csvDownloadURLHref = "Download data as <a href='" csvDownloadURLHref = "Download data as <a href='"
@ -515,10 +505,6 @@ public class PersonGrantCountVisCodeGenerator {
} else { } else {
csvDownloadURLHref = ""; csvDownloadURLHref = "";
} }
} catch (UnsupportedEncodingException e) {
csvDownloadURLHref = "";
}
} else { } else {
csvDownloadURLHref = "No data available to export.<br />"; csvDownloadURLHref = "No data available to export.<br />";
} }
@ -533,34 +519,18 @@ public class PersonGrantCountVisCodeGenerator {
} }
private String getCSVDownloadURL() private String getCSVDownloadURL() {
throws UnsupportedEncodingException {
if (yearToGrantCount.size() > 0) { if (yearToGrantCount.size() > 0) {
String secondaryContextPath = ""; ParamMap CSVDownloadURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
if (!contextPath.contains(VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX)) { individualURI,
secondaryContextPath = VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX; VisualizationFrameworkConstants.VIS_TYPE_KEY,
} VisualizationFrameworkConstants.PERSON_GRANT_COUNT_VIS);
return UrlBuilder.getUrl(VisualizationFrameworkConstants.DATA_VISUALIZATION_SERVICE_URL_PREFIX,
CSVDownloadURLParams);
String downloadURL = contextPath
+ secondaryContextPath
+ "?" + VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
+ "=" + URLEncoder.encode(individualURI,
StandardVisualizationController.URL_ENCODING_SCHEME)
.toString()
+ "&" + VisualizationFrameworkConstants.VIS_TYPE_KEY
+ "=" + URLEncoder.encode(
VisualizationFrameworkConstants
.PERSON_GRANT_COUNT_VIS,
StandardVisualizationController.URL_ENCODING_SCHEME)
.toString()
+ "&" + VisualizationFrameworkConstants.RENDER_MODE_KEY
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
.DATA_RENDER_MODE,
StandardVisualizationController.URL_ENCODING_SCHEME)
.toString();
return downloadURL;
} else { } else {
return null; return null;
} }
@ -571,46 +541,30 @@ public class PersonGrantCountVisCodeGenerator {
StringBuilder divContextCode = new StringBuilder(); StringBuilder divContextCode = new StringBuilder();
try {
String fullTimelineLink; String fullTimelineLink;
if (yearToGrantCount.size() > 0) { if (yearToGrantCount.size() > 0) {
String secondaryContextPath = ""; ParamMap fullTimelineNetworkURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
if (!contextPath.contains(VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX)) { individualURI,
secondaryContextPath = VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX; VisualizationFrameworkConstants.VIS_TYPE_KEY,
} VisualizationFrameworkConstants.PERSON_LEVEL_VIS);
String fullTimelineNetworkURL = contextPath String fullTimelineNetworkURL = UrlBuilder.getUrl(
+ secondaryContextPath VisualizationFrameworkConstants.FREEMARKERIZED_VISUALIZATION_URL_PREFIX,
+ "?" fullTimelineNetworkURLParams);
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
+ "=" + URLEncoder.encode(individualURI,
StandardVisualizationController.URL_ENCODING_SCHEME).toString()
+ "&"
+ VisualizationFrameworkConstants.VIS_TYPE_KEY
+ "=" + URLEncoder.encode("person_level",
StandardVisualizationController.URL_ENCODING_SCHEME).toString()
+ "&"
+ VisualizationFrameworkConstants.RENDER_MODE_KEY
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
.STANDALONE_RENDER_MODE,
StandardVisualizationController.URL_ENCODING_SCHEME).toString();
fullTimelineLink = "<a href='" + fullTimelineNetworkURL + "'>View all VIVO " fullTimelineLink = "<a href='" + fullTimelineNetworkURL + "'>View all VIVO "
+ "grants and corresponding co-pi network.</a>"; + "grants and corresponding co-pi network.</a>";
sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL); sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL);
} else { } else {
fullTimelineLink = "No data available to render full timeline.<br />"; fullTimelineLink = "No data available to render full timeline.<br />";
} }
divContextCode.append("<span class=\"vis_link\">" + fullTimelineLink + "</span>"); divContextCode.append("<span class=\"vis_link\">" + fullTimelineLink + "</span>");
} catch (UnsupportedEncodingException e) {
log.error(e);
}
return divContextCode.toString(); return divContextCode.toString();
} }
@ -618,15 +572,11 @@ public class PersonGrantCountVisCodeGenerator {
String csvDownloadURLHref = ""; String csvDownloadURLHref = "";
try {
if (getCSVDownloadURL() != null) { if (getCSVDownloadURL() != null) {
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL() + "\">(.CSV File)</a>"; csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL() + "\">(.CSV File)</a>";
} else { } else {
csvDownloadURLHref = ""; csvDownloadURLHref = "";
} }
} catch (UnsupportedEncodingException e) {
csvDownloadURLHref = "";
}
StringBuilder dataTable = new StringBuilder(); StringBuilder dataTable = new StringBuilder();

View file

@ -8,7 +8,7 @@ import java.util.Set;
import java.util.HashSet; import java.util.HashSet;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants; import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UniqueIDGenerator; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UniqueIDGenerator;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
/** /**

View file

@ -128,7 +128,7 @@ public class PersonGrantCountQueryRunner implements QueryRunner<Set<Grant>>{
+ "?Grant rdfs:label ?GrantLabel ; core:startDate ?GrantStartDate ; core:endDate ?GrantEndDate ." + "?Grant rdfs:label ?GrantLabel ; core:startDate ?GrantStartDate ; core:endDate ?GrantEndDate ."
+ "}"; + "}";
System.out.println("SPARQL query for person grant count -> \n"+ sparqlQuery); log.debug("SPARQL query for person grant count -> \n"+ sparqlQuery);
return sparqlQuery; return sparqlQuery;
} }

View file

@ -186,7 +186,7 @@ public class PersonPublicationCountQueryRunner implements QueryRunner<Set<BiboDo
+ SPARQL_QUERY_COMMON_WHERE_CLAUSE + SPARQL_QUERY_COMMON_WHERE_CLAUSE
+ "}"; + "}";
System.out.println("SPARQL query for person pub count -> \n" + sparqlQuery); log.debug("SPARQL query for person pub count -> \n" + sparqlQuery);
return sparqlQuery; return sparqlQuery;
} }