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:
parent
209c9b6a7b
commit
81855eddc2
22 changed files with 1845 additions and 415 deletions
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||||
// qs.add("authPerson", queryParam); // bind resource to s
|
return queryExecution.execSelect();
|
||||||
|
|
||||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
|
||||||
System.out.println("\n\nquery.isSelectType() is "+ query.isSelectType()+ " \n\n");
|
|
||||||
// if (query.isSelectType()) {
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
return queryExecution.execSelect();
|
||||||
// if (query.isSelectType()) {
|
|
||||||
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
|
||||||
|
|
|
@ -166,22 +166,11 @@ 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);
|
return queryExecution.execSelect();
|
||||||
System.out.println("\n\nquery.isSelectType() is "+ query.isSelectType()+ " \n\n");
|
}
|
||||||
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) {
|
||||||
String result = "";
|
String result = "";
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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: "
|
||||||
|
|
|
@ -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);
|
return queryExecution.execSelect();
|
||||||
System.out.println("\n\nquery.isSelectType() is "+ query.isSelectType()+ " \n\n");
|
|
||||||
// if (query.isSelectType()) {
|
|
||||||
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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();
|
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||||
// qs.add("authPerson", queryParam); // bind resource to s
|
return queryExecution.execSelect();
|
||||||
|
|
||||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
|
||||||
System.out.println("\n\nquery.isSelectType() is "+ query.isSelectType()+ " \n\n");
|
|
||||||
// if (query.isSelectType()) {
|
|
||||||
return queryExecution.execSelect();
|
|
||||||
// }
|
|
||||||
// } finally {
|
|
||||||
// if (queryExecution != null) {
|
|
||||||
// queryExecution.close();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateEgoCoAuthorshipSparqlQuery(String queryURI) {
|
private String generateEgoCoAuthorshipSparqlQuery(String queryURI) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,14 +45,42 @@ 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
|
QueryRunner<Set<Grant>> queryManager = new PersonGrantCountQueryRunner(personURI, dataSource, log );
|
||||||
.getParameter(VisualizationFrameworkConstants.RENDER_MODE_KEY);
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
Individual investigator = ((PersonGrantCountQueryRunner) queryManager).getPrincipalInvestigator();
|
||||||
|
|
||||||
|
return prepareDataResponse(investigator,
|
||||||
|
piGrants,
|
||||||
|
yearToGrantCount);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object generateAjaxVisualization(VitroRequest vitroRequest, Log log,
|
||||||
|
DataSource dataSource) throws MalformedQueryParametersException {
|
||||||
|
|
||||||
|
String personURI = vitroRequest
|
||||||
|
.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
|
||||||
|
|
||||||
String visMode = vitroRequest
|
String visMode = vitroRequest
|
||||||
.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY);
|
.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY);
|
||||||
|
@ -69,9 +88,8 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
||||||
String visContainer = vitroRequest
|
String visContainer = vitroRequest
|
||||||
.getParameter(VisualizationFrameworkConstants.VIS_CONTAINER_KEY);
|
.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();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -81,40 +99,62 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
||||||
Map<String, Integer> yearToGrantCount =
|
Map<String, Integer> yearToGrantCount =
|
||||||
UtilityFunctions.getYearToGrantCount(piGrants);
|
UtilityFunctions.getYearToGrantCount(piGrants);
|
||||||
|
|
||||||
Individual investigator = ((PersonGrantCountQueryRunner) queryManager).getPrincipalInvestigator();
|
|
||||||
|
|
||||||
if (VisualizationFrameworkConstants.DATA_RENDER_MODE
|
boolean shouldVIVOrenderVis =
|
||||||
.equalsIgnoreCase(renderMode)) {
|
yearToGrantCount.size() > 0 ? true : false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Computations required to generate HTML for the sparkline & related context.
|
||||||
|
* */
|
||||||
|
PersonGrantCountVisCodeGenerator visualizationCodeGenerator =
|
||||||
|
new PersonGrantCountVisCodeGenerator(personURI,
|
||||||
|
visMode,
|
||||||
|
visContainer,
|
||||||
|
piGrants,
|
||||||
|
yearToGrantCount,
|
||||||
|
log);
|
||||||
|
|
||||||
|
|
||||||
/*
|
SparklineData sparklineData = visualizationCodeGenerator
|
||||||
return prepareDataResponse(investigator,
|
.getValueObjectContainer();
|
||||||
piGrants,
|
|
||||||
yearToGrantCount);
|
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();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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,
|
|
||||||
yearToGrantCount,
|
|
||||||
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,
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -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,17 +381,12 @@ public class PersonGrantCountVisCodeGenerator {
|
||||||
|
|
||||||
String csvDownloadURLHref = "";
|
String csvDownloadURLHref = "";
|
||||||
|
|
||||||
try {
|
if (getCSVDownloadURL() != null) {
|
||||||
if (getCSVDownloadURL() != null) {
|
|
||||||
|
|
||||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL()
|
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL()
|
||||||
+ "\" class=\"inline_href\">(.CSV File)</a>";
|
+ "\" class=\"inline_href\">(.CSV File)</a>";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
csvDownloadURLHref = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
csvDownloadURLHref = "";
|
csvDownloadURLHref = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,18 +496,13 @@ 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='"
|
||||||
+ getCSVDownloadURL() + "'>.csv</a> file.<br />";
|
+ getCSVDownloadURL() + "'>.csv</a> file.<br />";
|
||||||
sparklineData.setDownloadDataLink(getCSVDownloadURL());
|
sparklineData.setDownloadDataLink(getCSVDownloadURL());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
csvDownloadURLHref = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
csvDownloadURLHref = "";
|
csvDownloadURLHref = "";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -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,13 +572,9 @@ 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 = "";
|
|
||||||
}
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
csvDownloadURLHref = "";
|
csvDownloadURLHref = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue