committing persongrantcount related files,new Egocentric swf file, CoPIVisCodeGenerator, person_level.js (to include co-author and co-pi vis).
This commit is contained in:
parent
31dbc619a4
commit
313a2da5da
23 changed files with 1900 additions and 240 deletions
|
@ -21,6 +21,9 @@
|
|||
class="edu.cornell.mannlib.vitro.webapp.visualization.entitycomparison.EntityPublicationCountRequestHandler" />
|
||||
<bean id="coprincipalinvestigator"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.coprincipalinvestigator.CoPIGrantCountRequestHandler" />
|
||||
<bean id="person_grant_count"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.persongrantcount.PersonGrantCountRequestHandler" />
|
||||
|
||||
|
||||
<bean id="visualizationInjector"
|
||||
class="edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationInjector">
|
||||
|
@ -44,6 +47,9 @@
|
|||
<entry key="coprincipalinvestigator">
|
||||
<ref bean="coprincipalinvestigator"></ref>
|
||||
</entry>
|
||||
<entry key="person_grant_count">
|
||||
<ref bean="person_grant_count"></ref>
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
|
||||
|
|
|
@ -173,10 +173,6 @@
|
|||
</listener-class>
|
||||
</listener>
|
||||
|
||||
<listener>
|
||||
<listener-class>edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache</listener-class>
|
||||
</listener>
|
||||
|
||||
<!--
|
||||
<listener>
|
||||
<listener-class>
|
||||
|
@ -351,16 +347,6 @@
|
|||
<url-pattern>/N3EditForm</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>MenuN3EditController</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.MenuN3EditController</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>MenuN3EditController</servlet-name>
|
||||
<url-pattern>/MenuN3EditController</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
|
||||
<!-- This is the new navigation controller. It is not ready for the 1.1 release
|
||||
see http://issues.library.cornell.edu/browse/NIHVIVO-597
|
||||
<servlet>
|
||||
|
@ -509,7 +495,6 @@
|
|||
<url-pattern>/csv2rdf</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
|
||||
<servlet>
|
||||
<servlet-name>JenaExportController</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.jena.JenaExportController</servlet-class>
|
||||
|
@ -1264,17 +1249,25 @@
|
|||
</servlet-mapping>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>DummyVisClient</servlet-name>
|
||||
<servlet-name>DummyVisClientFM</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.DummyVisClientController</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>DummyVisClientFM</servlet-name>
|
||||
<url-pattern>/admin/dummyVisClientfm</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>DummyVisClient</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.visualization.DummyVisClientController</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>DummyVisClient</servlet-name>
|
||||
<url-pattern>/admin/dummyVisClient</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
|
||||
|
||||
<servlet>
|
||||
<servlet-name>VisualizationController</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationController</servlet-class>
|
||||
|
@ -1334,15 +1327,6 @@
|
|||
</servlet-mapping>
|
||||
-->
|
||||
|
||||
<servlet>
|
||||
<servlet-name>ajaxSparqlQuery</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.ajax.SparqlQueryAjaxController</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>ajaxSparqlQuery</servlet-name>
|
||||
<url-pattern>/ajax/sparqlQuery</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- ============================== servlet-mappings ======================== -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>fetch</servlet-name>
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -29,7 +29,21 @@ function getWellFormedURLs(given_uri, type) {
|
|||
return finalURL;
|
||||
|
||||
|
||||
} else if (type == "profile") {
|
||||
} else if (type == "copi") {
|
||||
|
||||
finalURL = $.ajax({
|
||||
url: contextPath + "/visualization",
|
||||
data: ({vis: "utilities", vis_mode: "COPI_URL", uri: given_uri}),
|
||||
dataType: "text",
|
||||
async: false,
|
||||
success:function(data){
|
||||
}
|
||||
}).responseText;
|
||||
|
||||
return finalURL;
|
||||
|
||||
|
||||
}else if (type == "profile") {
|
||||
|
||||
finalURL = $.ajax({
|
||||
url: contextPath + "/visualization",
|
||||
|
@ -213,29 +227,54 @@ function processProfileInformation(nameContainerID,
|
|||
function visLoaded(nodes){
|
||||
|
||||
var jsonedNodes = jQuery.parseJSON(nodes);
|
||||
var tableID = "";
|
||||
var tableContainer = "";
|
||||
|
||||
if(visMode == "coauthorship"){
|
||||
tableID = "coauthorships_table";
|
||||
tableContainer = "coauth_table_container";
|
||||
} else{
|
||||
tableID = "copis_table";
|
||||
tableContainer = "copi_table_container";
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
createTable("coauthorships_table", "coauth_table_container", jsonedNodes.slice(1));
|
||||
createTable("coauthorships_table" , "coauth_table_container" , jsonedNodes.slice(1));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function createTable(tableID, tableContainer, tableData) {
|
||||
|
||||
var number_of_works = "";
|
||||
var tableCaption = "";
|
||||
var tableColumnTitle1 = "";
|
||||
var tableColumnTitle2 = "";
|
||||
|
||||
if(visMode == "coauthorship"){
|
||||
tableCaption = "Co-authors ";
|
||||
tableColumnTitle1 = "Author";
|
||||
tableColumnTitle2 = "Publications with <br />";
|
||||
}else{
|
||||
tableCaption = "Co-pis ";
|
||||
tableColumnTitle1 = "Principal Investigator";
|
||||
tableColumnTitle2 = "Grants with <br />";
|
||||
}
|
||||
|
||||
var table = $('<table>');
|
||||
table.attr('id', tableID);
|
||||
|
||||
table.append($('<caption>').html("Co-authors <a href=\"" + egoCoAuthorsListDataFileURL + "\">(.CSV File)</a>"));
|
||||
table.append($('<caption>').html(tableCaption + "<a href=\"" + egoCoAuthorsListDataFileURL + "\">(.CSV File)</a>"));
|
||||
|
||||
var header = $('<thead>');
|
||||
|
||||
var row = $('<tr>');
|
||||
|
||||
var authorTH = $('<th>');
|
||||
authorTH.html("Author");
|
||||
authorTH.html(tableColumnTitle1);
|
||||
row.append(authorTH);
|
||||
|
||||
row.append($('<th>').html("Publications with <br />" + $('#ego_label').text()));
|
||||
row.append($('<th>').html(tableColumnTitle2 + "" + $('#ego_label').text()));
|
||||
|
||||
header.append(row);
|
||||
|
||||
|
@ -243,10 +282,15 @@ function createTable(tableID, tableContainer, tableData) {
|
|||
|
||||
$.each(tableData, function(i, item){
|
||||
|
||||
if(visMode == "coauthorship"){
|
||||
number_of_works = item.number_of_authored_works;
|
||||
}else{
|
||||
number_of_works = item.number_of_investigated_grants;
|
||||
}
|
||||
var row = $('<tr>');
|
||||
|
||||
row.append($('<td>').html(item.label));
|
||||
row.append($('<td>').html(item.number_of_authored_works));
|
||||
row.append($('<td>').html(number_of_works));
|
||||
|
||||
table.append(row);
|
||||
|
||||
|
@ -259,10 +303,38 @@ function createTable(tableID, tableContainer, tableData) {
|
|||
//renderStatsOnNodeClicked, CoRelations, noOfCoRelations
|
||||
//function nodeClickedJS(json){
|
||||
function renderStatsOnNodeClicked(json){
|
||||
|
||||
//console.log(json);
|
||||
var obj = jQuery.parseJSON(json);
|
||||
|
||||
var works = "";
|
||||
var persons = "";
|
||||
var relation = "";
|
||||
var earliest_work = "";
|
||||
var latest_work = "";
|
||||
var number_of_works = "";
|
||||
|
||||
if(visMode == "coauthorship"){
|
||||
works = "Publication(s)";
|
||||
persons = "Co-author(s)";
|
||||
relation = "coauthorship"
|
||||
earliest_work = obj.earliest_publication;
|
||||
latest_work = obj.latest_publication;
|
||||
number_of_works = obj.number_of_authored_works;
|
||||
}else{
|
||||
works = "Grant(s)";
|
||||
persons = "Co-PI(s)";
|
||||
relation = "copi";
|
||||
earliest_work = obj.earliest_grant;
|
||||
latest_work = obj.latest_grant;
|
||||
number_of_works = obj.number_of_investigated_grants;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$("#dataPanel").attr("style","visibility:visible");
|
||||
$("#works").empty().append(obj.number_of_authored_works);
|
||||
$("#works").empty().append(number_of_works);
|
||||
|
||||
/*
|
||||
* Here obj.url points to the uri of that individual
|
||||
|
@ -272,19 +344,19 @@ function renderStatsOnNodeClicked(json){
|
|||
if (obj.url == egoURI) {
|
||||
|
||||
$("#authorName").addClass('author_name').removeClass('neutral_author_name');
|
||||
$('#num_works > .author_stats_text').text('Publication(s)');
|
||||
$('#num_authors > .author_stats_text').text('Co-author(s)');
|
||||
$('#num_works > .author_stats_text').text(works);
|
||||
$('#num_authors > .author_stats_text').text(persons);
|
||||
|
||||
} else {
|
||||
|
||||
$("#authorName").addClass('neutral_author_name').removeClass('author_name');
|
||||
$('#num_works > .author_stats_text').text('Joint Publication(s)');
|
||||
$('#num_authors > .author_stats_text').text('Joint Co-author(s)');
|
||||
$('#num_works > .author_stats_text').text('Joint ' + works);
|
||||
$('#num_authors > .author_stats_text').text('Joint ' + persons);
|
||||
|
||||
}
|
||||
|
||||
$("#profileUrl").attr("href", getWellFormedURLs(obj.url, "profile"));
|
||||
$("#coAuthorshipVisUrl").attr("href", getWellFormedURLs(obj.url, "coauthorship"));
|
||||
$("#coAuthorshipVisUrl").attr("href", getWellFormedURLs(obj.url, relation));
|
||||
processProfileInformation("authorName",
|
||||
"profileMoniker",
|
||||
"profileImage",
|
||||
|
@ -299,12 +371,12 @@ function renderStatsOnNodeClicked(json){
|
|||
$("#coAuthorshipVisUrl").attr("href","#");
|
||||
}
|
||||
|
||||
$("#coAuthors").empty().append(obj.num_coauthors);
|
||||
$("#coAuthors").empty().append(obj.noOfCorelations);
|
||||
|
||||
$("#firstPublication").empty().append(obj.earliest_publication);
|
||||
(obj.earliest_publication)?$("#fPub").attr("style","visibility:visible"):$("#fPub").attr("style","visibility:hidden");
|
||||
$("#lastPublication").empty().append(obj.latest_publication);
|
||||
(obj.latest_publication)?$("#lPub").attr("style","visibility:visible"):$("#lPub").attr("style","visibility:hidden");
|
||||
$("#firstPublication").empty().append(earliest_work);
|
||||
(earliest_work)?$("#fPub").attr("style","visibility:visible"):$("#fPub").attr("style","visibility:hidden");
|
||||
$("#lastPublication").empty().append(latest_work);
|
||||
(latest_work)?$("#lPub").attr("style","visibility:visible"):$("#lPub").attr("style","visibility:hidden");
|
||||
|
||||
// obj.url:the url parameter for node
|
||||
|
||||
|
@ -333,6 +405,18 @@ function getEncodedCoPIURL(){
|
|||
|
||||
function renderCoAuthorshipVisualization() {
|
||||
|
||||
var visualization = "";
|
||||
var encodedURL = "";
|
||||
|
||||
if(visMode == "coauthorship"){
|
||||
visualization = "CoAuthor";
|
||||
encodedURL = getEncodedCoAuthorURL();
|
||||
} else {
|
||||
visualization = "CoPI";
|
||||
encodedURL = getEncodedCoPIURL();
|
||||
}
|
||||
|
||||
// console.log('visualization is ' + visualization + ' and encodedURL is '+ encodedURL);
|
||||
// Version check for the Flash Player that has the ability to start Player
|
||||
// Product Install (6.0r65)
|
||||
var hasProductInstall = DetectFlashVer(6, 0, 65);
|
||||
|
@ -371,7 +455,8 @@ function renderCoAuthorshipVisualization() {
|
|||
"src", swfLink,
|
||||
// "flashVars", 'coAuthorUrl='+ encodeURL(egoCoAuthorshipDataFeederURL) + '&coPIUrl=' + encodeURL(egoCoPIDataFeederURL) ,
|
||||
// "flashVars", 'coAuthorUrl='+ getEncodedCoAuthorURL() + '&coPIUrl=' + getEncodedCoPIURL() ,
|
||||
"flashVars", 'graphmlUrl=' + getEncodedCoAuthorURL() + '&labelField=label&visType=CoAuthor',
|
||||
// "flashVars", 'graphmlUrl=' + getEncodedCoAuthorURL() + '&labelField=label&visType=CoAuthor',
|
||||
"flashVars", 'graphmlUrl=' + encodedURL + '&labelField=label&visType='+visualization,
|
||||
"width", "800",
|
||||
"height", "850",
|
||||
"align", "top",
|
||||
|
|
17
productMods/templates/visualization/grant_count.jsp
Normal file
17
productMods/templates/visualization/grant_count.jsp
Normal file
|
@ -0,0 +1,17 @@
|
|||
<%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%>
|
||||
|
||||
<%@ page import="edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineData" %>
|
||||
|
||||
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
|
||||
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
|
||||
|
||||
<c:set var='sparkline' value='${requestScope.sparklineVO}'/>
|
||||
|
||||
<div class="staticPageBackground">
|
||||
|
||||
|
||||
<div id="pub_count_vis_container">
|
||||
${sparkline.sparklineContent}
|
||||
</div>
|
||||
${sparkline.sparklineContext}
|
||||
</div>
|
|
@ -10,7 +10,10 @@
|
|||
<c:url var="loadingImageLink" value="/${themeDir}site_icons/visualization/ajax-loader.gif"></c:url>
|
||||
|
||||
<c:set var='egoPubSparkline' value='${requestScope.egoPubSparklineVO}' />
|
||||
<c:set var='egoGrantSparkline' value='${requestScope.egoGrantSparklineVO}' />
|
||||
<c:set var='uniqueCoauthorsSparkline' value='${requestScope.uniqueCoauthorsSparklineVO}' />
|
||||
<c:set var='uniqueCopisSparkline' value='${requestScope.uniqueCopisSparklineVO}' />
|
||||
|
||||
|
||||
<c:set var='egoPubSparklineContainerID' value='${requestScope.egoPubSparklineContainerID}' />
|
||||
<c:set var='uniqueCoauthorsSparklineVisContainerID' value='${requestScope.uniqueCoauthorsSparklineVisContainerID}' />
|
||||
|
@ -18,6 +21,10 @@
|
|||
<c:set var='numOfAuthors' value='${requestScope.numOfAuthors}' />
|
||||
<c:set var='numOfCoAuthorShips' value='${requestScope.numOfCoAuthorShips}' />
|
||||
|
||||
<c:set var='numOfInvestigators' value='${requestScope.numOfInvestigators}' />
|
||||
<c:set var='numOfCoPIs' value='${requestScope.numOfCoPIs}' />
|
||||
|
||||
|
||||
<c:url var="egoVivoProfileURL" value="/individual">
|
||||
<c:param name="uri" value="${requestScope.egoURIParam}" />
|
||||
</c:url>
|
||||
|
@ -34,10 +41,18 @@
|
|||
<c:param name="uri" value="${requestScope.egoURIParam}" />
|
||||
</c:url>
|
||||
|
||||
<c:url var="coprincipalinvestigator" value="/visualization">
|
||||
<c:param name="vis" value="coprincipalinvestigator"/>
|
||||
<c:url var="coprincipalinvestigatorURL" value="/visualization">
|
||||
<c:param name="vis" value="person_level"/>
|
||||
<c:param name="render_mode" value="standalone"/>
|
||||
<c:param name="uri" value="${requestScope.egoURIParam}"/>
|
||||
<c:param name = "vis_mode" value = "copi"/>
|
||||
</c:url>
|
||||
|
||||
<c:url var="coauthorshipURL" value="/visualization">
|
||||
<c:param name="vis" value="person_level"/>
|
||||
<c:param name="render_mode" value="standalone"/>
|
||||
<c:param name="uri" value="${requestScope.egoURIParam}"/>
|
||||
<c:param name = "vis_mode" value = "coauthorship"/>
|
||||
</c:url>
|
||||
|
||||
<script language="JavaScript" type="text/javascript">
|
||||
|
@ -103,22 +118,41 @@ $(document).ready(function(){
|
|||
|
||||
<%-- Sparkline --%>
|
||||
<h2 class="sub_headings">General Statistics</h2>
|
||||
<div id="${egoPubSparklineContainerID}">
|
||||
${egoPubSparkline.sparklineContent}
|
||||
</div>
|
||||
<c:choose>
|
||||
<c:when test='${visMode == "coauthorship"}'>
|
||||
<div id="${egoPubSparklineContainerID}">
|
||||
${egoPubSparkline.sparklineContent}
|
||||
</div>
|
||||
|
||||
<div id="${uniqueCoauthorsSparklineVisContainerID}">
|
||||
${uniqueCoauthorsSparkline.sparklineContent}
|
||||
</div>
|
||||
<div id="${uniqueCoauthorsSparklineVisContainerID}">
|
||||
${uniqueCoauthorsSparkline.sparklineContent}
|
||||
</div>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<div id="${egoPubSparklineContainerID}">
|
||||
${egoGrantSparkline.sparklineContent}
|
||||
</div>
|
||||
|
||||
<h2 class="sub_headings">Co-Author Network
|
||||
<div id="${uniqueCoauthorsSparklineVisContainerID}">
|
||||
${uniqueCopisSparkline.sparklineContent}
|
||||
</div>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
|
||||
|
||||
<c:choose>
|
||||
<c:when test='${visMode == "coauthorship"}'>
|
||||
<h2 class="sub_headings">Co-Author Network </h2>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<h2 class="sub_headings">Co-PI Network </h2>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
<c:choose>
|
||||
<c:when test="${numOfCoAuthorShips > 0 || numOfAuthors > 0}">
|
||||
<a href="${coAuthorshipDownloadFile}">(GraphML File)</a></h2>
|
||||
<a href="${coAuthorshipDownloadFile}">(GraphML File)</a>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
</h2>
|
||||
|
||||
<c:if test='${numOfAuthors > 0}'>
|
||||
<c:set var='authorsText' value='multi-author' />
|
||||
</c:if>
|
||||
|
@ -149,55 +183,118 @@ $(document).ready(function(){
|
|||
//-->
|
||||
</script>
|
||||
</div>
|
||||
<c:choose>
|
||||
<c:when test='${visMode == "coauthorship"}'>
|
||||
<div id="dataPanel">
|
||||
|
||||
<div id="dataPanel">
|
||||
<br />
|
||||
<br />
|
||||
<div id="profileImage" class="thumbnail"></div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div id="profileImage" class="thumbnail"></div>
|
||||
<div class="bold"><strong><span id="authorName" class="neutral_author_name"> </span></strong></div>
|
||||
|
||||
<div class="bold"><strong><span id="authorName" class="neutral_author_name"> </span></strong></div>
|
||||
<div class="italicize"><span id="profileMoniker" class="author_moniker"></span></div>
|
||||
<div><a href="#" id="profileUrl">VIVO profile</a> | <a href="#" id="coAuthorshipVisUrl">Co-author network</a></div>
|
||||
<br />
|
||||
<div class="author_stats" id="num_works"><span class="numbers" style="width: 40px;" id="works"></span> <span class="author_stats_text">Publication(s)</span></div>
|
||||
<div class="author_stats" id="num_authors"><span class="numbers" style="width: 40px;" id="coAuthors"></span> <span class="author_stats_text">Co-author(s)</span></div>
|
||||
|
||||
<div class="italicize"><span id="profileMoniker" class="author_moniker"></span></div>
|
||||
<div><a href="#" id="profileUrl">VIVO profile</a> | <a href="#" id="coAuthorshipVisUrl">Co-author network</a></div>
|
||||
<br />
|
||||
<div class="author_stats" id="num_works"><span class="numbers" style="width: 40px;" id="works"></span> <span class="author_stats_text">Publication(s)</span></div>
|
||||
<div class="author_stats" id="num_authors"><span class="numbers" style="width: 40px;" id="coAuthors"></span> <span class="author_stats_text">Co-author(s)</span></div>
|
||||
<div class="author_stats" id="fPub" style="visibility:hidden"><span class="numbers" style="width:40px;" id="firstPublication"></span> <span>First Publication</span></div>
|
||||
<div class="author_stats" id="lPub" style="visibility:hidden"><span class="numbers" style="width:40px;" id="lastPublication"></span> <span>Last Publication</span></div>
|
||||
|
||||
<div class="author_stats" id="fPub" style="visibility:hidden"><span class="numbers" style="width:40px;" id="firstPublication"></span> <span>First Publication</span></div>
|
||||
<div class="author_stats" id="lPub" style="visibility:hidden"><span class="numbers" style="width:40px;" id="lastPublication"></span> <span>Last Publication</span></div>
|
||||
</div>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<div id="dataPanel">
|
||||
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<div id="profileImage" class="thumbnail"></div>
|
||||
|
||||
<div class="bold"><strong><span id="authorName" class="neutral_author_name"> </span></strong></div>
|
||||
|
||||
<div class="italicize"><span id="profileMoniker" class="author_moniker"></span></div>
|
||||
<div><a href="#" id="profileUrl">VIVO profile</a> | <a href="#" id="coAuthorshipVisUrl">Co-PI network</a></div>
|
||||
<br />
|
||||
<div class="author_stats" id="num_works"><span class="numbers" style="width: 40px;" id="works"></span> <span class="author_stats_text">Grant(s)</span></div>
|
||||
<div class="author_stats" id="num_authors"><span class="numbers" style="width: 40px;" id="coAuthors"></span> <span class="author_stats_text">Co-PI(s)</span></div>
|
||||
|
||||
<div class="author_stats" id="fPub" style="visibility:hidden"><span class="numbers" style="width:40px;" id="firstPublication"></span> <span>First Grant</span></div>
|
||||
<div class="author_stats" id="lPub" style="visibility:hidden"><span class="numbers" style="width:40px;" id="lastPublication"></span> <span>Last Grant</span></div>
|
||||
|
||||
</div>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</div>
|
||||
|
||||
</c:if>
|
||||
<div style="text-align:center; clear: left;">
|
||||
<a href='<c:out value="${coprincipalinvestigator}"/>'> View all grants and corresponding co-pi network for this author</a>
|
||||
</div>
|
||||
<c:if test='${numOfAuthors > 0}'>
|
||||
|
||||
<div class="vis_stats">
|
||||
|
||||
<h2 class="sub_headings">Tables</h2>
|
||||
|
||||
<div class="vis-tables">
|
||||
<p id="publications_table_container" class="datatable">
|
||||
${egoPubSparkline.table}
|
||||
</p>
|
||||
<c:choose>
|
||||
<c:when test='${visMode == "coauthorship"}'>
|
||||
<div style="text-align:center; clear: left;">
|
||||
<a href='<c:out value="${coprincipalinvestigatorURL}"/>'> View all grants and corresponding co-pi network for this person</a>
|
||||
</div>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<div style="text-align:center; clear: left;">
|
||||
<a href='<c:out value="${coauthorshipURL}"/>'> View all publications and corresponding co-author network for this person</a>
|
||||
</div>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
|
||||
<c:if test='${numOfCoAuthorShips > 0}'>
|
||||
<c:choose>
|
||||
<c:when test='${visMode == "coauthorship"}'>
|
||||
<c:if test='${numOfAuthors > 0}'>
|
||||
|
||||
<div class="vis_stats">
|
||||
|
||||
<h2 class="sub_headings">Tables</h2>
|
||||
|
||||
<div class="vis-tables">
|
||||
<p id="publications_table_container" class="datatable">
|
||||
${egoPubSparkline.table}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<c:if test='${numOfCoAuthorShips > 0}'>
|
||||
|
||||
<div class="vis-tables">
|
||||
<p id="coauth_table_container" class="datatable"></p>
|
||||
</div>
|
||||
|
||||
</c:if>
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
|
||||
<div class="vis-tables">
|
||||
<p id="coauth_table_container" class="datatable"></p>
|
||||
</div>
|
||||
</c:if>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<c:if test='${numOfInvestigators > 0}'>
|
||||
|
||||
<div class="vis_stats">
|
||||
|
||||
<h2 class="sub_headings">Tables</h2>
|
||||
|
||||
<div class="vis-tables">
|
||||
<p id="publications_table_container" class="datatable">
|
||||
${egoGrantSparkline.table}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<c:if test='${numOfCoPIs > 0}'>
|
||||
|
||||
<div class="vis-tables">
|
||||
<p id="coauth_table_container" class="datatable"></p>
|
||||
</div>
|
||||
|
||||
</c:if>
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
|
||||
</div>
|
||||
</c:if>
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
|
||||
</div>
|
||||
</c:if>
|
||||
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</div>
|
|
@ -59,6 +59,7 @@ var egoCoAuthorsListDataFileURL = "${egoCoAuthorsListDataFileURL}";
|
|||
var egoCoPIDataFeederURL = "${egoCoPIDataFeederURL}";
|
||||
var contextPath = "${contextPath}";
|
||||
var domainParam = "${requestScope.completeURL}";
|
||||
var visMode = "${requestScope.visMode}";
|
||||
|
||||
// -->
|
||||
</script>
|
||||
|
|
|
@ -65,6 +65,7 @@ public class VisualizationFrameworkConstants {
|
|||
public static final String PROFILE_UTILS_VIS_MODE = "PROFILE_URL";
|
||||
public static final String COAUTHOR_UTILS_VIS_MODE = "COAUTHORSHIP_URL";
|
||||
public static final String PERSON_LEVEL_UTILS_VIS_MODE = "PERSON_LEVEL_URL";
|
||||
public static final String COPI_UTILS_VIS_MODE = "COPI_URL";
|
||||
public static final String IMAGE_UTILS_VIS_MODE = "IMAGE_URL";
|
||||
public static final String UNIVERSITY_COMPARISON_VIS_MODE = "UNIVERSITY";
|
||||
public static final String SCHOOL_COMPARISON_VIS_MODE = "SCHOOL";
|
||||
|
@ -75,6 +76,7 @@ public class VisualizationFrameworkConstants {
|
|||
* These values represent possible visualizations provided as values to the "vis" url key.
|
||||
* */
|
||||
public static final String PERSON_PUBLICATION_COUNT_VIS = "person_pub_count";
|
||||
public static final String PERSON_GRANT_COUNT_VIS = "person_grant_count";
|
||||
public static final String PDF_REPORT_VIS = "pdf_report";
|
||||
public static final String COLLEGE_PUBLICATION_COUNT_VIS = "college_pub_count";
|
||||
public static final String COAUTHORSHIP_VIS = "coauthorship";
|
||||
|
@ -84,4 +86,5 @@ public class VisualizationFrameworkConstants {
|
|||
public static final String CO_PI_VIS = "coprincipalinvestigator";
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -455,7 +455,7 @@ public class CoAuthorshipQueryRunner implements QueryRunner<CoAuthorshipData> {
|
|||
+ "} "
|
||||
+ "ORDER BY ?document ?coAuthorPerson";
|
||||
|
||||
// System.out.println("COAUTHORSHIP QUERY - " + sparqlQuery);
|
||||
System.out.println("COAUTHORSHIP QUERY - " + sparqlQuery);
|
||||
|
||||
return sparqlQuery;
|
||||
}
|
||||
|
|
|
@ -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.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;
|
||||
}
|
||||
}
|
|
@ -49,7 +49,7 @@ public class PersonGrantCountQueryRunner implements QueryRunner<Set<Grant>>{
|
|||
private Log log;
|
||||
|
||||
private static final String SPARQL_QUERY_COMMON_SELECT_CLAUSE = ""
|
||||
+ "SELECT (str(?PILabel)) as ?PILabelLit) "
|
||||
+ "SELECT (str(?PILabel) as ?PILabelLit) "
|
||||
+ "(str(?Grant) as ?grantLit)"
|
||||
+ "(str(?GrantLabel) as ?grantLabelLit)"
|
||||
+ "(str(?GrantStartDate) as ?grantStartDateLit)"
|
||||
|
@ -120,7 +120,7 @@ public class PersonGrantCountQueryRunner implements QueryRunner<Set<Grant>>{
|
|||
|
||||
String sparqlQuery = QueryConstants.getSparqlPrefixQuery()
|
||||
+ SPARQL_QUERY_COMMON_SELECT_CLAUSE
|
||||
+ "(str(<" + queryURI + ">) as ?PILit "
|
||||
+ "(str(<" + queryURI + ">) as ?PILit) "
|
||||
+ "WHERE {"
|
||||
+ "<" + queryURI + "> rdfs:label ?PILabel;"
|
||||
+ "core:hasCo-PrincipalInvestigatorRole ?Role ."
|
||||
|
|
|
@ -80,27 +80,27 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
|||
QueryRunner<Set<Grant>> queryManager =
|
||||
new PersonGrantCountQueryRunner(personURI, dataSource, log);
|
||||
|
||||
// try {
|
||||
// Set<Grant> authorDocuments = queryManager.getQueryResult();
|
||||
try {
|
||||
Set<Grant> PIGrants = queryManager.getQueryResult();
|
||||
|
||||
/*
|
||||
* Create a map from the year to number of publications. Use the BiboDocument's
|
||||
* Create a map from the year to number of grants. Use the Grant's
|
||||
* parsedPublicationYear to populate the data.
|
||||
* */
|
||||
// Map<String, Integer> yearToPublicationCount =
|
||||
// UtilityFunctions.getYearToPublicationCount(authorDocuments);
|
||||
//
|
||||
// Individual author = ((PersonGrantCountQueryRunner) queryManager).getAuthor();
|
||||
//
|
||||
// if (VisualizationFrameworkConstants.DATA_RENDER_MODE
|
||||
// .equalsIgnoreCase(renderMode)) {
|
||||
//
|
||||
// prepareDataResponse(author,
|
||||
// authorDocuments,
|
||||
// yearToPublicationCount,
|
||||
// response);
|
||||
// return;
|
||||
// }
|
||||
Map<String, Integer> yearToGrantCount =
|
||||
UtilityFunctions.getYearToGrantCount(PIGrants);
|
||||
|
||||
Individual investigator = ((PersonGrantCountQueryRunner) queryManager).getPrincipalInvestigator();
|
||||
|
||||
if (VisualizationFrameworkConstants.DATA_RENDER_MODE
|
||||
.equalsIgnoreCase(renderMode)) {
|
||||
|
||||
prepareDataResponse(investigator,
|
||||
PIGrants,
|
||||
yearToGrantCount,
|
||||
response);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
@ -121,77 +121,77 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
|||
/*
|
||||
* Computations required to generate HTML for the sparkline & related context.
|
||||
* */
|
||||
// PersonGrantCountVisCodeGenerator visualizationCodeGenerator =
|
||||
// new PersonGrantCountVisCodeGenerator(vitroRequest.getContextPath(),
|
||||
// personURI,
|
||||
// visMode,
|
||||
// visContainer,
|
||||
// authorDocuments,
|
||||
// yearToPublicationCount,
|
||||
// log);
|
||||
//
|
||||
// SparklineData sparklineData = visualizationCodeGenerator
|
||||
// .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)) {
|
||||
//
|
||||
// prepareDynamicResponse(request,
|
||||
// response,
|
||||
// vitroRequest,
|
||||
// sparklineData,
|
||||
// yearToPublicationCount);
|
||||
// requestDispatcher = request.getRequestDispatcher("/templates/page/blankPage.jsp");
|
||||
//
|
||||
// } else {
|
||||
// prepareStandaloneResponse(request,
|
||||
// response,
|
||||
// vitroRequest,
|
||||
// sparklineData);
|
||||
// requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||
// }
|
||||
//
|
||||
// try {
|
||||
// requestDispatcher.forward(request, response);
|
||||
// } catch (Exception e) {
|
||||
// log.error("EntityEditController could not forward to view.");
|
||||
// log.error(e.getMessage());
|
||||
// log.error(e.getStackTrace());
|
||||
// }
|
||||
//
|
||||
// } catch (MalformedQueryParametersException e) {
|
||||
// try {
|
||||
// UtilityFunctions.handleMalformedParameters(
|
||||
// e.getMessage(),
|
||||
// "Visualization Query Error - Individual Publication Count",
|
||||
// vitroRequest,
|
||||
// request,
|
||||
// response,
|
||||
// log);
|
||||
// } catch (ServletException e1) {
|
||||
// log.error(e1.getStackTrace());
|
||||
// } catch (IOException e1) {
|
||||
// log.error(e1.getStackTrace());
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
PersonGrantCountVisCodeGenerator visualizationCodeGenerator =
|
||||
new PersonGrantCountVisCodeGenerator(vitroRequest.getContextPath(),
|
||||
personURI,
|
||||
visMode,
|
||||
visContainer,
|
||||
PIGrants,
|
||||
yearToGrantCount,
|
||||
log);
|
||||
|
||||
SparklineData sparklineData = visualizationCodeGenerator
|
||||
.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)) {
|
||||
|
||||
prepareDynamicResponse(request,
|
||||
response,
|
||||
vitroRequest,
|
||||
sparklineData,
|
||||
yearToGrantCount);
|
||||
requestDispatcher = request.getRequestDispatcher("/templates/page/blankPage.jsp");
|
||||
|
||||
} else {
|
||||
prepareStandaloneResponse(request,
|
||||
response,
|
||||
vitroRequest,
|
||||
sparklineData);
|
||||
requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||
}
|
||||
|
||||
try {
|
||||
requestDispatcher.forward(request, response);
|
||||
} catch (Exception e) {
|
||||
log.error("EntityEditController could not forward to view.");
|
||||
log.error(e.getMessage());
|
||||
log.error(e.getStackTrace());
|
||||
}
|
||||
|
||||
} catch (MalformedQueryParametersException e) {
|
||||
try {
|
||||
UtilityFunctions.handleMalformedParameters(
|
||||
e.getMessage(),
|
||||
"Visualization Query Error - Individual Publication Count",
|
||||
vitroRequest,
|
||||
request,
|
||||
response,
|
||||
log);
|
||||
} catch (ServletException e1) {
|
||||
log.error(e1.getStackTrace());
|
||||
} catch (IOException e1) {
|
||||
log.error(e1.getStackTrace());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void writePublicationsOverTimeCSV(
|
||||
Map<String, Integer> yearToPublicationCount,
|
||||
private void writeGrantsOverTimeCSV(
|
||||
Map<String, Integer> yearToGrantCount,
|
||||
PrintWriter responseWriter) {
|
||||
|
||||
CSVWriter csvWriter = new SimpleWriter(responseWriter);
|
||||
|
||||
try {
|
||||
csvWriter.append(new String[] { "Year", "Publications" });
|
||||
for (Entry<String, Integer> currentEntry : yearToPublicationCount
|
||||
csvWriter.append(new String[] { "Year", "Grants" });
|
||||
for (Entry<String, Integer> currentEntry : yearToGrantCount
|
||||
.entrySet()) {
|
||||
csvWriter.append(new Object[] { currentEntry.getKey(),
|
||||
currentEntry.getValue() });
|
||||
|
@ -205,38 +205,38 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
|||
}
|
||||
|
||||
/**
|
||||
* Provides response when csv file containing the publication count over the years
|
||||
* Provides response when csv file containing the grant count over the years
|
||||
* is requested.
|
||||
* @param author
|
||||
* @param authorDocuments
|
||||
* @param yearToPublicationCount
|
||||
* @param investigator
|
||||
* @param piGrants
|
||||
* @param yearToGrantCount
|
||||
* @param response
|
||||
*/
|
||||
private void prepareDataResponse(
|
||||
Individual author,
|
||||
Set<Grant> authorDocuments,
|
||||
Map<String, Integer> yearToPublicationCount,
|
||||
Individual investigator,
|
||||
Set<Grant> piGrants,
|
||||
Map<String, Integer> yearToGrantCount,
|
||||
HttpServletResponse response) {
|
||||
|
||||
String authorName = null;
|
||||
String investigatorName = null;
|
||||
|
||||
/*
|
||||
* To protect against cases where there are no author documents associated with the
|
||||
* To protect against cases where there are no grants associated with the
|
||||
* individual.
|
||||
* */
|
||||
if (authorDocuments.size() > 0) {
|
||||
authorName = author.getIndividualLabel();
|
||||
if (piGrants.size() > 0) {
|
||||
investigatorName = investigator.getIndividualLabel();
|
||||
}
|
||||
|
||||
/*
|
||||
* To make sure that null/empty records for author names do not cause any mischief.
|
||||
* To make sure that null/empty records for investigator names do not cause any mischief.
|
||||
* */
|
||||
if (StringUtils.isBlank(authorName)) {
|
||||
authorName = "no-author";
|
||||
if (StringUtils.isBlank(investigatorName)) {
|
||||
investigatorName = "no-investigator";
|
||||
}
|
||||
|
||||
String outputFileName = UtilityFunctions.slugify(authorName)
|
||||
+ "_publications-per-year" + ".csv";
|
||||
String outputFileName = UtilityFunctions.slugify(investigatorName)
|
||||
+ "_grants-per-year" + ".csv";
|
||||
|
||||
response.setContentType("application/octet-stream");
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName);
|
||||
|
@ -249,7 +249,7 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
|||
* We are side-effecting responseWriter since we are directly manipulating the response
|
||||
* object of the servlet.
|
||||
* */
|
||||
writePublicationsOverTimeCSV(yearToPublicationCount, responseWriter);
|
||||
writeGrantsOverTimeCSV(yearToGrantCount, responseWriter);
|
||||
|
||||
responseWriter.close();
|
||||
|
||||
|
@ -273,34 +273,34 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
|||
|
||||
request.setAttribute("sparklineVO", valueObjectContainer);
|
||||
|
||||
request.setAttribute("bodyJsp", "/templates/visualization/publication_count.jsp");
|
||||
request.setAttribute("bodyJsp", "/templates/visualization/grant_count.jsp");
|
||||
request.setAttribute("portalBean", portal);
|
||||
request.setAttribute("title", "Individual Publication Count visualization");
|
||||
request.setAttribute("title", "Individual Grant Count visualization");
|
||||
request.setAttribute("scripts", "/templates/visualization/visualization_scripts.jsp");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides response when the publication sparkline has to be rendered in already existing
|
||||
* Provides response when the grant sparkline has to be rendered in already existing
|
||||
* page, e.g. profile page.
|
||||
* @param request
|
||||
* @param response
|
||||
* @param vreq
|
||||
* @param valueObjectContainer
|
||||
* @param yearToPublicationCount
|
||||
* @param yearToGrantCount
|
||||
*/
|
||||
private void prepareDynamicResponse(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
VitroRequest vreq,
|
||||
SparklineData valueObjectContainer,
|
||||
Map<String, Integer> yearToPublicationCount) {
|
||||
Map<String, Integer> yearToGrantCount) {
|
||||
|
||||
Portal portal = vreq.getPortal();
|
||||
|
||||
request.setAttribute("sparklineVO", valueObjectContainer);
|
||||
|
||||
if (yearToPublicationCount.size() > 0) {
|
||||
if (yearToGrantCount.size() > 0) {
|
||||
request.setAttribute("shouldVIVOrenderVis", true);
|
||||
} else {
|
||||
request.setAttribute("shouldVIVOrenderVis", false);
|
||||
|
@ -310,30 +310,30 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
|||
request.setAttribute("bodyJsp", "/templates/visualization/ajax_vis_content.jsp");
|
||||
}
|
||||
|
||||
private void preparePDFResponse(Individual author,
|
||||
Set<Grant> authorDocuments,
|
||||
Map<String, Integer> yearToPublicationCount,
|
||||
private void preparePDFResponse(Individual investigator,
|
||||
Set<Grant> piGrants,
|
||||
Map<String, Integer> yearToGrantCount,
|
||||
HttpServletResponse response) {
|
||||
|
||||
String authorName = null;
|
||||
String investigatorName = null;
|
||||
|
||||
/*
|
||||
* To protect against cases where there are no author documents
|
||||
* To protect against cases where there are no PI Grants
|
||||
* associated with the individual.
|
||||
*/
|
||||
if (authorDocuments.size() > 0) {
|
||||
authorName = author.getIndividualLabel();
|
||||
if (piGrants.size() > 0) {
|
||||
investigatorName = investigator.getIndividualLabel();
|
||||
}
|
||||
|
||||
/*
|
||||
* To make sure that null/empty records for author names do not cause
|
||||
* To make sure that null/empty records for PI names do not cause
|
||||
* any mischief.
|
||||
*/
|
||||
if (StringUtils.isBlank(authorName)) {
|
||||
authorName = "no-author";
|
||||
if (StringUtils.isBlank(investigatorName)) {
|
||||
investigatorName = "no-investigator";
|
||||
}
|
||||
|
||||
String outputFileName = UtilityFunctions.slugify(authorName)
|
||||
String outputFileName = UtilityFunctions.slugify(investigatorName)
|
||||
+ "_report" + ".pdf";
|
||||
|
||||
response.setContentType("application/pdf");
|
||||
|
@ -349,8 +349,8 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
|||
PdfWriter pdfWriter = PdfWriter.getInstance(document, baos);
|
||||
document.open();
|
||||
|
||||
PDFDocument pdfDocument = new PDFDocument(authorName,
|
||||
yearToPublicationCount, document, pdfWriter);
|
||||
PDFDocument pdfDocument = new PDFDocument(investigatorName,
|
||||
yearToGrantCount, document, pdfWriter);
|
||||
|
||||
document.close();
|
||||
|
||||
|
|
|
@ -2,6 +2,674 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.persongrantcount;
|
||||
|
||||
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.Grant;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineData;
|
||||
|
||||
/**
|
||||
* Class for rendering sparklines of grants over time for a person
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class PersonGrantCountVisCodeGenerator {
|
||||
|
||||
/*
|
||||
* 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 grants 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", "grant_count_short_sparkline_vis");
|
||||
put("FULL_SPARK", "grant_count_full_sparkline_vis");
|
||||
|
||||
} };
|
||||
|
||||
private static final String VISUALIZATION_STYLE_CLASS = "sparkline_style";
|
||||
|
||||
private static final String DEFAULT_VIS_CONTAINER_DIV_ID = "grant_count_vis_container";
|
||||
|
||||
private Map<String, Integer> yearToGrantCount;
|
||||
|
||||
private Log log;
|
||||
|
||||
private SparklineData sparklineData;
|
||||
|
||||
private String contextPath;
|
||||
|
||||
private String individualURI;
|
||||
|
||||
public PersonGrantCountVisCodeGenerator(String contextPath,
|
||||
String individualURIParam, String visMode, String visContainer,
|
||||
Set<Grant> piGrants,
|
||||
Map<String, Integer> yearToGrantCount, Log log) {
|
||||
|
||||
this.contextPath = contextPath;
|
||||
this.individualURI = individualURIParam;
|
||||
|
||||
this.yearToGrantCount = yearToGrantCount;
|
||||
this.sparklineData = new SparklineData();
|
||||
|
||||
this.log = log;
|
||||
|
||||
generateVisualizationCode(visMode, visContainer, piGrants);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param piGrants
|
||||
*/
|
||||
private void generateVisualizationCode(String visMode,
|
||||
String visContainer,
|
||||
Set<Grant> piGrants) {
|
||||
|
||||
sparklineData.setSparklineContent(getMainVisualizationCode(piGrants,
|
||||
visMode,
|
||||
visContainer));
|
||||
|
||||
|
||||
sparklineData.setSparklineContext(getVisualizationContextCode(visMode));
|
||||
|
||||
}
|
||||
|
||||
private String getMainVisualizationCode(Set<Grant> piGrants,
|
||||
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>(yearToGrantCount
|
||||
.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 minInvestigatedYear = shortSparkMinYear;
|
||||
|
||||
String visContainerID = null;
|
||||
|
||||
StringBuilder visualizationCode = new StringBuilder();
|
||||
|
||||
if (yearToGrantCount.size() > 0) {
|
||||
try {
|
||||
minInvestigatedYear = Integer.parseInt(Collections
|
||||
.min(investigatedYears));
|
||||
} catch (NoSuchElementException e1) {
|
||||
log.debug("vis: " + e1.getMessage() + " error occurred for "
|
||||
+ yearToGrantCount.toString());
|
||||
} catch (NumberFormatException e2) {
|
||||
log.debug("vis: " + e2.getMessage() + " error occurred for "
|
||||
+ yearToGrantCount.toString());
|
||||
}
|
||||
}
|
||||
|
||||
int minInvestigatedYearConsidered = 0;
|
||||
|
||||
/*
|
||||
* There might be a case that the author has 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
|
||||
* minInvestigatedYearConsidered to "currentYear - 10" which is also given by
|
||||
* "shortSparkMinYear".
|
||||
*/
|
||||
if (minInvestigatedYear > shortSparkMinYear) {
|
||||
minInvestigatedYearConsidered = shortSparkMinYear;
|
||||
} else {
|
||||
minInvestigatedYearConsidered = minInvestigatedYear;
|
||||
}
|
||||
|
||||
numOfYearsToBeRendered = currentYear - minInvestigatedYearConsidered + 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;" + "}"
|
||||
+ "table.sparkline_wrapper_table td, th {"
|
||||
+ " vertical-align: bottom;" + "}" + ".vis_link a{"
|
||||
+ " padding-top: 5px;" + "}"
|
||||
+ "td.sparkline_number { text-align:right; "
|
||||
+ "padding-right:5px; }"
|
||||
+ "td.sparkline_text {text-align:left;}"
|
||||
+ ".incomplete-data-holder {" + "" + "}" + "</style>\n");
|
||||
|
||||
visualizationCode.append("<script type=\"text/javascript\">\n"
|
||||
+ "function drawGrantCountVisualization(providedSparklineImgTD) "
|
||||
+ "{\n" + "var data = new google.visualization.DataTable();\n"
|
||||
+ "data.addColumn('string', 'Year');\n"
|
||||
+ "data.addColumn('number', 'Publications');\n"
|
||||
+ "data.addRows(" + numOfYearsToBeRendered + ");\n");
|
||||
|
||||
int grantCounter = 0;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
int renderedFullSparks = 0;
|
||||
|
||||
for (int grantYear = minInvestigatedYearConsidered; grantYear <= currentYear; grantYear++) {
|
||||
|
||||
String stringInvestigatedYear = String.valueOf(grantYear);
|
||||
Integer currentGrants = yearToGrantCount
|
||||
.get(stringInvestigatedYear);
|
||||
|
||||
if (currentGrants == null) {
|
||||
currentGrants = 0;
|
||||
}
|
||||
|
||||
visualizationCode.append("data.setValue(" + grantCounter
|
||||
+ ", 0, '" + stringInvestigatedYear + "');\n");
|
||||
|
||||
visualizationCode.append("data.setValue(" + grantCounter
|
||||
+ ", 1, " + currentGrants + ");\n");
|
||||
|
||||
/*
|
||||
* Sparks that will be rendered in full mode will always be the
|
||||
* one's which has any year associated with it. Hence.
|
||||
*/
|
||||
renderedFullSparks += currentGrants;
|
||||
grantCounter++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Total grants will also consider grants that have no year
|
||||
* associated with it. Hence.
|
||||
*/
|
||||
Integer unknownYearGrants = 0;
|
||||
if (yearToGrantCount.get(VOConstants.DEFAULT_GRANT_YEAR) != null) {
|
||||
unknownYearGrants = yearToGrantCount
|
||||
.get(VOConstants.DEFAULT_GRANT_YEAR);
|
||||
}
|
||||
|
||||
String sparklineDisplayOptions = "{width: 65, height: 30, showAxisLines: false, "
|
||||
+ "showValueLabels: false, labelPosition: 'none'}";
|
||||
|
||||
if (providedVisContainerID != null) {
|
||||
visContainerID = providedVisContainerID;
|
||||
} else {
|
||||
visContainerID = DEFAULT_VIS_CONTAINER_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(minInvestigatedYear);
|
||||
sparklineData.setLatestRenderedGrantYear(currentYear);
|
||||
|
||||
/*
|
||||
* The Full Sparkline will be rendered by default. Only if the url has
|
||||
* specific mention of SHORT_SPARKLINE_MODE_URL_HANDLE 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,
|
||||
unknownYearGrants, sparklineDisplayOptions);
|
||||
} else {
|
||||
generateFullSparklineVisualizationContent(currentYear,
|
||||
minInvestigatedYearConsidered, visContainerID, visualizationCode,
|
||||
unknownYearGrants, 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 drawGrantCountVisualization 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 = ''"
|
||||
+ "+ ' grant(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
|
||||
+ "}"
|
||||
+ "drawGrantCountVisualization(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 (yearToGrantCount.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 (yearToGrantCount.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.PERSON_GRANT_COUNT_VIS,
|
||||
VisualizationController.URL_ENCODING_SCHEME)
|
||||
.toString()
|
||||
+ "&"
|
||||
+ VisualizationFrameworkConstants.RENDER_MODE_KEY
|
||||
+ "="
|
||||
+ URLEncoder.encode(
|
||||
VisualizationFrameworkConstants.DATA_RENDER_MODE,
|
||||
VisualizationController.URL_ENCODING_SCHEME)
|
||||
.toString()
|
||||
+ "&"
|
||||
+ VisualizationFrameworkConstants.VIS_MODE_KEY
|
||||
+ "="
|
||||
+ URLEncoder.encode("copi",
|
||||
VisualizationController.URL_ENCODING_SCHEME)
|
||||
.toString();
|
||||
return downloadURL;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String generateShortVisContext() {
|
||||
|
||||
StringBuilder divContextCode = new StringBuilder();
|
||||
|
||||
try {
|
||||
|
||||
String fullTimelineLink, fullTimelineCoPILink;
|
||||
if (yearToGrantCount.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.RENDER_MODE_KEY
|
||||
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
|
||||
.STANDALONE_RENDER_MODE,
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&"
|
||||
+ VisualizationFrameworkConstants.VIS_MODE_KEY
|
||||
+ "=" + URLEncoder.encode("copi",
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||
|
||||
fullTimelineLink = "<a href='" + fullTimelineNetworkURL + "'>View all VIVO "
|
||||
+ "grants and corresponding co-pi network.</a>";
|
||||
|
||||
sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL);
|
||||
|
||||
String fullTimelineCoPINetworkURL = 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.RENDER_MODE_KEY
|
||||
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
|
||||
.STANDALONE_RENDER_MODE,
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&"
|
||||
+ VisualizationFrameworkConstants.VIS_MODE_KEY
|
||||
+ "=" + URLEncoder.encode("copi",
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||
|
||||
fullTimelineCoPILink = "<a href='" + fullTimelineCoPINetworkURL + "'>View all "
|
||||
+ "grants and corresponding co-pi network.</a>";
|
||||
|
||||
sparklineData.setFullTimelineCoPINetworkLink(fullTimelineCoPINetworkURL);
|
||||
|
||||
} else {
|
||||
fullTimelineLink = "No data available to render full timeline.<br />";
|
||||
fullTimelineCoPILink = "No data available to render full timeline.<br />";
|
||||
|
||||
}
|
||||
|
||||
divContextCode.append("<span class=\"vis_link\">" + fullTimelineLink + "</span>");
|
||||
divContextCode.append("<br/><br/><span class=\"vis_link_copi\">" + fullTimelineCoPILink + "</span>");
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error(e);
|
||||
}
|
||||
return divContextCode.toString();
|
||||
}
|
||||
|
||||
private String generateDataTable() {
|
||||
|
||||
String csvDownloadURLHref = "";
|
||||
|
||||
try {
|
||||
if (getCSVDownloadURL() != null) {
|
||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL() + "\">(.CSV File)</a>";
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
StringBuilder dataTable = new StringBuilder();
|
||||
|
||||
dataTable.append("<table id='sparkline_data_table'>"
|
||||
+ "<caption>Grants per year " + csvDownloadURLHref + "</caption>"
|
||||
+ "<thead>"
|
||||
+ "<tr>"
|
||||
+ "<th>Year</th>"
|
||||
+ "<th>Grants</th>"
|
||||
+ "</tr>"
|
||||
+ "</thead>"
|
||||
+ "<tbody>");
|
||||
|
||||
for (Entry<String, Integer> currentEntry : yearToGrantCount.entrySet()) {
|
||||
dataTable.append("<tr>"
|
||||
+ "<td>" + currentEntry.getKey() + "</td>"
|
||||
+ "<td>" + currentEntry.getValue() + "</td>"
|
||||
+ "</tr>");
|
||||
}
|
||||
|
||||
dataTable.append("</tbody>\n </table>\n");
|
||||
|
||||
return dataTable.toString();
|
||||
}
|
||||
|
||||
public SparklineData getValueObjectContainer() {
|
||||
return sparklineData;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,10 +28,16 @@ import edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.CoAuthorshipG
|
|||
import edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.CoAuthorshipQueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.CoAuthorshipVisCodeGenerator;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.persongrantcount.PersonGrantCountQueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.persongrantcount.PersonGrantCountVisCodeGenerator;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.coprincipalinvestigator.CoPIGrantCountQueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.coprincipalinvestigator.CoPIVisCodeGenerator;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.PersonPublicationCountQueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.PersonPublicationCountVisCodeGenerator;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoAuthorshipData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPIData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Grant;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Node;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
|
||||
|
@ -53,6 +59,10 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
|
|||
private static final String EGO_PUB_SPARKLINE_VIS_CONTAINER_ID = "ego_pub_sparkline";
|
||||
private static final String UNIQUE_COAUTHORS_SPARKLINE_VIS_CONTAINER_ID =
|
||||
"unique_coauthors_sparkline";
|
||||
private static final String EGO_GRANT_SPARKLINE_VIS_CONTAINER_ID = "ego_grant_sparkline";
|
||||
private static final String UNIQUE_COPIS_SPARKLINE_VIS_CONTAINER_ID =
|
||||
"unique_copis_sparkline";
|
||||
|
||||
|
||||
public void generateVisualization(VitroRequest vitroRequest,
|
||||
HttpServletRequest request,
|
||||
|
@ -75,10 +85,18 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
|
|||
QueryRunner<Set<BiboDocument>> publicationQueryManager =
|
||||
new PersonPublicationCountQueryRunner(egoURI, dataSource, log);
|
||||
|
||||
QueryRunner<CoPIData> coPIQueryManager = new CoPIGrantCountQueryRunner(egoURI, dataSource, log);
|
||||
|
||||
|
||||
QueryRunner<Set<Grant>> grantQueryManager =
|
||||
new PersonGrantCountQueryRunner(egoURI, dataSource, log);
|
||||
|
||||
try {
|
||||
|
||||
CoAuthorshipData coAuthorshipData = coAuthorshipQueryManager.getQueryResult();
|
||||
|
||||
CoPIData coPIData = coPIQueryManager.getQueryResult();
|
||||
|
||||
if (VisualizationFrameworkConstants.DATA_RENDER_MODE
|
||||
.equalsIgnoreCase(renderMode)) {
|
||||
|
||||
|
@ -154,6 +172,48 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
|
|||
SparklineData uniqueCoauthorsSparklineVO = uniqueCoauthorsVisCodeGenerator
|
||||
.getValueObjectContainer();
|
||||
|
||||
/*
|
||||
* grants over time sparkline
|
||||
*/
|
||||
|
||||
Set<Grant> piGrants = grantQueryManager.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);
|
||||
|
||||
PersonGrantCountVisCodeGenerator personGrantCountVisCodeGenerator =
|
||||
new PersonGrantCountVisCodeGenerator(
|
||||
vitroRequest.getRequestURI(),
|
||||
egoURI,
|
||||
VisualizationFrameworkConstants.FULL_SPARKLINE_VIS_MODE,
|
||||
EGO_PUB_SPARKLINE_VIS_CONTAINER_ID,
|
||||
piGrants,
|
||||
yearToGrantCount,
|
||||
log);
|
||||
|
||||
SparklineData grantSparklineVO = personGrantCountVisCodeGenerator
|
||||
.getValueObjectContainer();
|
||||
|
||||
|
||||
/*
|
||||
* Co-PI's over time sparkline
|
||||
*/
|
||||
CoPIVisCodeGenerator uniqueCopisVisCodeGenerator =
|
||||
new CoPIVisCodeGenerator(
|
||||
vitroRequest.getRequestURI(),
|
||||
egoURI,
|
||||
VisualizationFrameworkConstants.FULL_SPARKLINE_VIS_MODE,
|
||||
UNIQUE_COAUTHORS_SPARKLINE_VIS_CONTAINER_ID,
|
||||
UtilityFunctions.getGrantYearToCoPI(coPIData),
|
||||
log);
|
||||
|
||||
SparklineData uniqueCopisSparklineVO = uniqueCopisVisCodeGenerator
|
||||
.getValueObjectContainer();
|
||||
|
||||
|
||||
RequestDispatcher requestDispatcher = null;
|
||||
|
||||
|
@ -161,11 +221,14 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
|
|||
egoURI,
|
||||
publicationSparklineVO,
|
||||
uniqueCoauthorsSparklineVO,
|
||||
grantSparklineVO,
|
||||
uniqueCopisSparklineVO,
|
||||
coAuthorshipData,
|
||||
coPIData,
|
||||
EGO_PUB_SPARKLINE_VIS_CONTAINER_ID,
|
||||
UNIQUE_COAUTHORS_SPARKLINE_VIS_CONTAINER_ID,
|
||||
vitroRequest,
|
||||
request);
|
||||
request, visMode);
|
||||
|
||||
requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||
|
||||
|
@ -319,21 +382,25 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
|
|||
* @param egoURI
|
||||
* @param egoPubSparklineVO
|
||||
* @param uniqueCoauthorsSparklineVO
|
||||
* @param uniqueCopisSparklineVO
|
||||
* @param grantSparklineVO
|
||||
* @param coAuthorshipVO
|
||||
* @param coPIVO
|
||||
* @param egoPubSparklineVisContainer
|
||||
* @param uniqueCoauthorsSparklineVisContainer
|
||||
* @param vitroRequest
|
||||
* @param request
|
||||
* @param visMode
|
||||
*/
|
||||
private void prepareStandaloneResponse (
|
||||
String egoURI,
|
||||
SparklineData egoPubSparklineVO,
|
||||
SparklineData uniqueCoauthorsSparklineVO,
|
||||
CoAuthorshipData coAuthorshipVO,
|
||||
String egoPubSparklineVisContainer,
|
||||
SparklineData egoGrantSparklineVO, SparklineData uniqueCopisSparklineVO, CoAuthorshipData coAuthorshipVO,
|
||||
CoPIData coPIVO, String egoPubSparklineVisContainer,
|
||||
String uniqueCoauthorsSparklineVisContainer,
|
||||
VitroRequest vitroRequest,
|
||||
HttpServletRequest request) {
|
||||
HttpServletRequest request, String visMode) {
|
||||
|
||||
String completeURL = "";
|
||||
Portal portal = vitroRequest.getPortal();
|
||||
|
@ -350,6 +417,15 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
|
|||
request.setAttribute("numOfCoAuthorShips", coAuthorshipVO.getEdges().size());
|
||||
}
|
||||
|
||||
if (coPIVO.getNodes() != null && coPIVO.getNodes().size() > 0) {
|
||||
request.setAttribute("numOfInvestigators", coPIVO.getNodes().size());
|
||||
//title = coPIVO.getEgoNode().getNodeName() + " - ";
|
||||
}
|
||||
|
||||
if (coPIVO.getEdges() != null && coPIVO.getEdges().size() > 0) {
|
||||
request.setAttribute("numOfCoPIs", coPIVO.getEdges().size());
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
completeURL = getCompleteURL(request);
|
||||
|
@ -357,9 +433,12 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
|
|||
e.printStackTrace();
|
||||
}
|
||||
|
||||
request.setAttribute("visMode", visMode);
|
||||
request.setAttribute("completeURL", completeURL);
|
||||
request.setAttribute("egoPubSparklineVO", egoPubSparklineVO);
|
||||
request.setAttribute("egoGrantSparklineVO", egoGrantSparklineVO);
|
||||
request.setAttribute("uniqueCoauthorsSparklineVO", uniqueCoauthorsSparklineVO);
|
||||
request.setAttribute("uniqueCopisSparklineVO", uniqueCopisSparklineVO);
|
||||
|
||||
request.setAttribute("egoPubSparklineContainerID", egoPubSparklineVisContainer);
|
||||
request.setAttribute("uniqueCoauthorsSparklineVisContainerID",
|
||||
|
|
|
@ -186,7 +186,7 @@ public class PersonPublicationCountQueryRunner implements QueryRunner<Set<BiboDo
|
|||
+ SPARQL_QUERY_COMMON_WHERE_CLAUSE
|
||||
+ "}";
|
||||
|
||||
// System.out.println("SPARQL query for person pub count -> \n" + sparqlQuery);
|
||||
System.out.println("SPARQL query for person pub count -> \n" + sparqlQuery);
|
||||
return sparqlQuery;
|
||||
}
|
||||
|
||||
|
|
|
@ -567,7 +567,7 @@ public class PersonPublicationCountVisCodeGenerator {
|
|||
|
||||
try {
|
||||
|
||||
String fullTimelineLink;
|
||||
String fullTimelineLink, fullTimelineCoPILink;
|
||||
if (yearToPublicationCount.size() > 0) {
|
||||
|
||||
String secondaryContextPath = "";
|
||||
|
@ -600,11 +600,39 @@ public class PersonPublicationCountVisCodeGenerator {
|
|||
|
||||
sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL);
|
||||
|
||||
String fullTimelineCoPINetworkURL = 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.RENDER_MODE_KEY
|
||||
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
|
||||
.STANDALONE_RENDER_MODE,
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&"
|
||||
+ VisualizationFrameworkConstants.VIS_MODE_KEY
|
||||
+ "=" + URLEncoder.encode("copi",
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||
|
||||
fullTimelineCoPILink = "<a href='" + fullTimelineCoPINetworkURL + "'>View all "
|
||||
+ "grants and corresponding co-pi network.</a>";
|
||||
|
||||
sparklineData.setFullTimelineCoPINetworkLink(fullTimelineCoPINetworkURL);
|
||||
|
||||
} else {
|
||||
fullTimelineLink = "No data available to render full timeline.<br />";
|
||||
fullTimelineCoPILink = "No data available to render full timeline.<br />";
|
||||
|
||||
}
|
||||
|
||||
divContextCode.append("<span class=\"vis_link\">" + fullTimelineLink + "</span>");
|
||||
divContextCode.append("<br/><br/><span class=\"vis_link_copi\">" + fullTimelineCoPILink + "</span>");
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error(e);
|
||||
|
|
|
@ -213,7 +213,36 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler {
|
|||
+ VisualizationFrameworkConstants.RENDER_MODE_KEY
|
||||
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
|
||||
.STANDALONE_RENDER_MODE,
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&"
|
||||
+ VisualizationFrameworkConstants.VIS_MODE_KEY
|
||||
+ "=" + URLEncoder.encode("coauthorship",
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||
|
||||
prepareUtilitiesResponse(preparedURL, response);
|
||||
return;
|
||||
} else if (VisualizationFrameworkConstants.COPI_UTILS_VIS_MODE
|
||||
.equalsIgnoreCase(visMode)) {
|
||||
|
||||
preparedURL += request.getContextPath()
|
||||
+ VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX
|
||||
+ "?"
|
||||
+ 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.RENDER_MODE_KEY
|
||||
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
|
||||
.STANDALONE_RENDER_MODE,
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&"
|
||||
+ VisualizationFrameworkConstants.VIS_MODE_KEY
|
||||
+ "=" + URLEncoder.encode("copi",
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||
|
||||
prepareUtilitiesResponse(preparedURL, response);
|
||||
return;
|
||||
|
|
|
@ -15,11 +15,17 @@ public class SparklineData {
|
|||
private Integer earliestRenderedPublicationYear;
|
||||
private Integer latestRenderedPublicationYear;
|
||||
|
||||
private Integer earliestRenderedGrantYear;
|
||||
private Integer latestRenderedGrantYear;
|
||||
|
||||
private String table = "";
|
||||
|
||||
private String downloadDataLink = "";
|
||||
private String fullTimelineNetworkLink = "";
|
||||
|
||||
private String downloadCoPIDataLink = "";
|
||||
private String fullTimelineCoPINetworkLink = "";
|
||||
|
||||
private String sparklineContent;
|
||||
private String sparklineContext;
|
||||
|
||||
|
@ -97,4 +103,38 @@ public class SparklineData {
|
|||
public void setSparklineContext(String shortSparklineContext) {
|
||||
this.sparklineContext = shortSparklineContext;
|
||||
}
|
||||
|
||||
public String getDownloadCoPIDataLink() {
|
||||
return downloadCoPIDataLink;
|
||||
}
|
||||
|
||||
public void setDownloadCoPIDataLink(String downloadCoPIDataLink) {
|
||||
this.downloadCoPIDataLink = downloadCoPIDataLink;
|
||||
}
|
||||
|
||||
public String getFullTimelineCoPINetworkLink() {
|
||||
return fullTimelineCoPINetworkLink;
|
||||
}
|
||||
|
||||
public void setFullTimelineCoPINetworkLink(String fullTimelineCoPINetworkLink) {
|
||||
this.fullTimelineCoPINetworkLink = fullTimelineCoPINetworkLink;
|
||||
}
|
||||
|
||||
public Integer getEarliestRenderedGrantYear() {
|
||||
return earliestRenderedGrantYear;
|
||||
}
|
||||
|
||||
public void setEarliestRenderedGrantYear(Integer earliestRenderedGrantYear) {
|
||||
this.earliestRenderedGrantYear = earliestRenderedGrantYear;
|
||||
}
|
||||
|
||||
public Integer getLatestRenderedGrantYear() {
|
||||
return latestRenderedGrantYear;
|
||||
}
|
||||
|
||||
public void setLatestRenderedGrantYear(Integer latestRenderedGrantYear) {
|
||||
this.latestRenderedGrantYear = latestRenderedGrantYear;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Binary file not shown.
Loading…
Add table
Reference in a new issue