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:
bkoniden 2010-12-15 17:20:57 +00:00
parent 31dbc619a4
commit 313a2da5da
23 changed files with 1900 additions and 240 deletions

View file

@ -21,6 +21,9 @@
class="edu.cornell.mannlib.vitro.webapp.visualization.entitycomparison.EntityPublicationCountRequestHandler" /> class="edu.cornell.mannlib.vitro.webapp.visualization.entitycomparison.EntityPublicationCountRequestHandler" />
<bean id="coprincipalinvestigator" <bean id="coprincipalinvestigator"
class="edu.cornell.mannlib.vitro.webapp.visualization.coprincipalinvestigator.CoPIGrantCountRequestHandler" /> 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" <bean id="visualizationInjector"
class="edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationInjector"> class="edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationInjector">
@ -44,6 +47,9 @@
<entry key="coprincipalinvestigator"> <entry key="coprincipalinvestigator">
<ref bean="coprincipalinvestigator"></ref> <ref bean="coprincipalinvestigator"></ref>
</entry> </entry>
<entry key="person_grant_count">
<ref bean="person_grant_count"></ref>
</entry>
</map> </map>
</property> </property>

View file

@ -173,10 +173,6 @@
</listener-class> </listener-class>
</listener> </listener>
<listener>
<listener-class>edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache</listener-class>
</listener>
<!-- <!--
<listener> <listener>
<listener-class> <listener-class>
@ -351,16 +347,6 @@
<url-pattern>/N3EditForm</url-pattern> <url-pattern>/N3EditForm</url-pattern>
</servlet-mapping> </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 <!-- This is the new navigation controller. It is not ready for the 1.1 release
see http://issues.library.cornell.edu/browse/NIHVIVO-597 see http://issues.library.cornell.edu/browse/NIHVIVO-597
<servlet> <servlet>
@ -509,7 +495,6 @@
<url-pattern>/csv2rdf</url-pattern> <url-pattern>/csv2rdf</url-pattern>
</servlet-mapping> </servlet-mapping>
<servlet> <servlet>
<servlet-name>JenaExportController</servlet-name> <servlet-name>JenaExportController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.jena.JenaExportController</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.controller.jena.JenaExportController</servlet-class>
@ -1264,17 +1249,25 @@
</servlet-mapping> </servlet-mapping>
<servlet> <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-class>edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.DummyVisClientController</servlet-class>
</servlet> </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-mapping>
<servlet-name>DummyVisClient</servlet-name> <servlet-name>DummyVisClient</servlet-name>
<url-pattern>/admin/dummyVisClient</url-pattern> <url-pattern>/admin/dummyVisClient</url-pattern>
</servlet-mapping> </servlet-mapping>
<servlet> <servlet>
<servlet-name>VisualizationController</servlet-name> <servlet-name>VisualizationController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationController</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationController</servlet-class>
@ -1334,15 +1327,6 @@
</servlet-mapping> </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-mappings ======================== -->
<servlet-mapping> <servlet-mapping>
<servlet-name>fetch</servlet-name> <servlet-name>fetch</servlet-name>

View file

@ -29,7 +29,21 @@ function getWellFormedURLs(given_uri, type) {
return finalURL; 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({ finalURL = $.ajax({
url: contextPath + "/visualization", url: contextPath + "/visualization",
@ -213,29 +227,54 @@ function processProfileInformation(nameContainerID,
function visLoaded(nodes){ function visLoaded(nodes){
var jsonedNodes = jQuery.parseJSON(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() { $(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) { 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>'); var table = $('<table>');
table.attr('id', tableID); 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 header = $('<thead>');
var row = $('<tr>'); var row = $('<tr>');
var authorTH = $('<th>'); var authorTH = $('<th>');
authorTH.html("Author"); authorTH.html(tableColumnTitle1);
row.append(authorTH); row.append(authorTH);
row.append($('<th>').html("Publications with <br />" + $('#ego_label').text())); row.append($('<th>').html(tableColumnTitle2 + "" + $('#ego_label').text()));
header.append(row); header.append(row);
@ -243,10 +282,15 @@ function createTable(tableID, tableContainer, tableData) {
$.each(tableData, function(i, item){ $.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>'); var row = $('<tr>');
row.append($('<td>').html(item.label)); 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); table.append(row);
@ -259,10 +303,38 @@ function createTable(tableID, tableContainer, tableData) {
//renderStatsOnNodeClicked, CoRelations, noOfCoRelations //renderStatsOnNodeClicked, CoRelations, noOfCoRelations
//function nodeClickedJS(json){ //function nodeClickedJS(json){
function renderStatsOnNodeClicked(json){ function renderStatsOnNodeClicked(json){
//console.log(json);
var obj = jQuery.parseJSON(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"); $("#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 * Here obj.url points to the uri of that individual
@ -272,19 +344,19 @@ function renderStatsOnNodeClicked(json){
if (obj.url == egoURI) { if (obj.url == egoURI) {
$("#authorName").addClass('author_name').removeClass('neutral_author_name'); $("#authorName").addClass('author_name').removeClass('neutral_author_name');
$('#num_works > .author_stats_text').text('Publication(s)'); $('#num_works > .author_stats_text').text(works);
$('#num_authors > .author_stats_text').text('Co-author(s)'); $('#num_authors > .author_stats_text').text(persons);
} else { } else {
$("#authorName").addClass('neutral_author_name').removeClass('author_name'); $("#authorName").addClass('neutral_author_name').removeClass('author_name');
$('#num_works > .author_stats_text').text('Joint Publication(s)'); $('#num_works > .author_stats_text').text('Joint ' + works);
$('#num_authors > .author_stats_text').text('Joint Co-author(s)'); $('#num_authors > .author_stats_text').text('Joint ' + persons);
} }
$("#profileUrl").attr("href", getWellFormedURLs(obj.url, "profile")); $("#profileUrl").attr("href", getWellFormedURLs(obj.url, "profile"));
$("#coAuthorshipVisUrl").attr("href", getWellFormedURLs(obj.url, "coauthorship")); $("#coAuthorshipVisUrl").attr("href", getWellFormedURLs(obj.url, relation));
processProfileInformation("authorName", processProfileInformation("authorName",
"profileMoniker", "profileMoniker",
"profileImage", "profileImage",
@ -299,12 +371,12 @@ function renderStatsOnNodeClicked(json){
$("#coAuthorshipVisUrl").attr("href","#"); $("#coAuthorshipVisUrl").attr("href","#");
} }
$("#coAuthors").empty().append(obj.num_coauthors); $("#coAuthors").empty().append(obj.noOfCorelations);
$("#firstPublication").empty().append(obj.earliest_publication); $("#firstPublication").empty().append(earliest_work);
(obj.earliest_publication)?$("#fPub").attr("style","visibility:visible"):$("#fPub").attr("style","visibility:hidden"); (earliest_work)?$("#fPub").attr("style","visibility:visible"):$("#fPub").attr("style","visibility:hidden");
$("#lastPublication").empty().append(obj.latest_publication); $("#lastPublication").empty().append(latest_work);
(obj.latest_publication)?$("#lPub").attr("style","visibility:visible"):$("#lPub").attr("style","visibility:hidden"); (latest_work)?$("#lPub").attr("style","visibility:visible"):$("#lPub").attr("style","visibility:hidden");
// obj.url:the url parameter for node // obj.url:the url parameter for node
@ -333,6 +405,18 @@ function getEncodedCoPIURL(){
function renderCoAuthorshipVisualization() { 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 // Version check for the Flash Player that has the ability to start Player
// Product Install (6.0r65) // Product Install (6.0r65)
var hasProductInstall = DetectFlashVer(6, 0, 65); var hasProductInstall = DetectFlashVer(6, 0, 65);
@ -371,7 +455,8 @@ function renderCoAuthorshipVisualization() {
"src", swfLink, "src", swfLink,
// "flashVars", 'coAuthorUrl='+ encodeURL(egoCoAuthorshipDataFeederURL) + '&coPIUrl=' + encodeURL(egoCoPIDataFeederURL) , // "flashVars", 'coAuthorUrl='+ encodeURL(egoCoAuthorshipDataFeederURL) + '&coPIUrl=' + encodeURL(egoCoPIDataFeederURL) ,
// "flashVars", 'coAuthorUrl='+ getEncodedCoAuthorURL() + '&coPIUrl=' + getEncodedCoPIURL() , // "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", "width", "800",
"height", "850", "height", "850",
"align", "top", "align", "top",

View 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>

View file

@ -10,7 +10,10 @@
<c:url var="loadingImageLink" value="/${themeDir}site_icons/visualization/ajax-loader.gif"></c:url> <c:url var="loadingImageLink" value="/${themeDir}site_icons/visualization/ajax-loader.gif"></c:url>
<c:set var='egoPubSparkline' value='${requestScope.egoPubSparklineVO}' /> <c:set var='egoPubSparkline' value='${requestScope.egoPubSparklineVO}' />
<c:set var='egoGrantSparkline' value='${requestScope.egoGrantSparklineVO}' />
<c:set var='uniqueCoauthorsSparkline' value='${requestScope.uniqueCoauthorsSparklineVO}' /> <c:set var='uniqueCoauthorsSparkline' value='${requestScope.uniqueCoauthorsSparklineVO}' />
<c:set var='uniqueCopisSparkline' value='${requestScope.uniqueCopisSparklineVO}' />
<c:set var='egoPubSparklineContainerID' value='${requestScope.egoPubSparklineContainerID}' /> <c:set var='egoPubSparklineContainerID' value='${requestScope.egoPubSparklineContainerID}' />
<c:set var='uniqueCoauthorsSparklineVisContainerID' value='${requestScope.uniqueCoauthorsSparklineVisContainerID}' /> <c:set var='uniqueCoauthorsSparklineVisContainerID' value='${requestScope.uniqueCoauthorsSparklineVisContainerID}' />
@ -18,6 +21,10 @@
<c:set var='numOfAuthors' value='${requestScope.numOfAuthors}' /> <c:set var='numOfAuthors' value='${requestScope.numOfAuthors}' />
<c:set var='numOfCoAuthorShips' value='${requestScope.numOfCoAuthorShips}' /> <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:url var="egoVivoProfileURL" value="/individual">
<c:param name="uri" value="${requestScope.egoURIParam}" /> <c:param name="uri" value="${requestScope.egoURIParam}" />
</c:url> </c:url>
@ -34,10 +41,18 @@
<c:param name="uri" value="${requestScope.egoURIParam}" /> <c:param name="uri" value="${requestScope.egoURIParam}" />
</c:url> </c:url>
<c:url var="coprincipalinvestigator" value="/visualization"> <c:url var="coprincipalinvestigatorURL" value="/visualization">
<c:param name="vis" value="coprincipalinvestigator"/> <c:param name="vis" value="person_level"/>
<c:param name="render_mode" value="standalone"/> <c:param name="render_mode" value="standalone"/>
<c:param name="uri" value="${requestScope.egoURIParam}"/> <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> </c:url>
<script language="JavaScript" type="text/javascript"> <script language="JavaScript" type="text/javascript">
@ -103,22 +118,41 @@ $(document).ready(function(){
<%-- Sparkline --%> <%-- Sparkline --%>
<h2 class="sub_headings">General Statistics</h2> <h2 class="sub_headings">General Statistics</h2>
<div id="${egoPubSparklineContainerID}"> <c:choose>
${egoPubSparkline.sparklineContent} <c:when test='${visMode == "coauthorship"}'>
</div> <div id="${egoPubSparklineContainerID}">
${egoPubSparkline.sparklineContent}
</div>
<div id="${uniqueCoauthorsSparklineVisContainerID}"> <div id="${uniqueCoauthorsSparklineVisContainerID}">
${uniqueCoauthorsSparkline.sparklineContent} ${uniqueCoauthorsSparkline.sparklineContent}
</div> </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:choose>
<c:when test="${numOfCoAuthorShips > 0 || numOfAuthors > 0}"> <c:when test="${numOfCoAuthorShips > 0 || numOfAuthors > 0}">
<a href="${coAuthorshipDownloadFile}">(GraphML File)</a></h2> <a href="${coAuthorshipDownloadFile}">(GraphML File)</a>
</c:when> </c:when>
<c:otherwise> <c:otherwise>
</h2>
<c:if test='${numOfAuthors > 0}'> <c:if test='${numOfAuthors > 0}'>
<c:set var='authorsText' value='multi-author' /> <c:set var='authorsText' value='multi-author' />
</c:if> </c:if>
@ -149,55 +183,118 @@ $(document).ready(function(){
//--> //-->
</script> </script>
</div> </div>
<c:choose>
<c:when test='${visMode == "coauthorship"}'>
<div id="dataPanel">
<div id="dataPanel"> <br />
<br />
<div id="profileImage" class="thumbnail"></div>
<br /> <div class="bold"><strong><span id="authorName" class="neutral_author_name">&nbsp;</span></strong></div>
<br />
<div id="profileImage" class="thumbnail"></div>
<div class="bold"><strong><span id="authorName" class="neutral_author_name">&nbsp;</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>&nbsp;&nbsp;<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>&nbsp;&nbsp;<span class="author_stats_text">Co-author(s)</span></div>
<div class="italicize"><span id="profileMoniker" class="author_moniker"></span></div> <div class="author_stats" id="fPub" style="visibility:hidden"><span class="numbers" style="width:40px;" id="firstPublication"></span>&nbsp;&nbsp;<span>First Publication</span></div>
<div><a href="#" id="profileUrl">VIVO profile</a> | <a href="#" id="coAuthorshipVisUrl">Co-author network</a></div> <div class="author_stats" id="lPub" style="visibility:hidden"><span class="numbers" style="width:40px;" id="lastPublication"></span>&nbsp;&nbsp;<span>Last Publication</span></div>
<br />
<div class="author_stats" id="num_works"><span class="numbers" style="width: 40px;" id="works"></span>&nbsp;&nbsp;<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>&nbsp;&nbsp;<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>&nbsp;&nbsp;<span>First Publication</span></div> </div>
<div class="author_stats" id="lPub" style="visibility:hidden"><span class="numbers" style="width:40px;" id="lastPublication"></span>&nbsp;&nbsp;<span>Last Publication</span></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">&nbsp;</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>&nbsp;&nbsp;<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>&nbsp;&nbsp;<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>&nbsp;&nbsp;<span>First Grant</span></div>
<div class="author_stats" id="lPub" style="visibility:hidden"><span class="numbers" style="width:40px;" id="lastPublication"></span>&nbsp;&nbsp;<span>Last Grant</span></div>
</div>
</c:otherwise>
</c:choose>
</div> </div>
</c:if> </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"> <c:choose>
<c:when test='${visMode == "coauthorship"}'>
<h2 class="sub_headings">Tables</h2> <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 class="vis-tables">
<p id="publications_table_container" class="datatable">
${egoPubSparkline.table}
</p>
</div> </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> </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> </c:if>
<div style="clear:both;"></div> </c:otherwise>
</c:choose>
</div>
</c:if>
</div> </div>

View file

@ -59,6 +59,7 @@ var egoCoAuthorsListDataFileURL = "${egoCoAuthorsListDataFileURL}";
var egoCoPIDataFeederURL = "${egoCoPIDataFeederURL}"; var egoCoPIDataFeederURL = "${egoCoPIDataFeederURL}";
var contextPath = "${contextPath}"; var contextPath = "${contextPath}";
var domainParam = "${requestScope.completeURL}"; var domainParam = "${requestScope.completeURL}";
var visMode = "${requestScope.visMode}";
// --> // -->
</script> </script>

View file

@ -65,6 +65,7 @@ public class VisualizationFrameworkConstants {
public static final String PROFILE_UTILS_VIS_MODE = "PROFILE_URL"; public static final String PROFILE_UTILS_VIS_MODE = "PROFILE_URL";
public static final String COAUTHOR_UTILS_VIS_MODE = "COAUTHORSHIP_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 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 IMAGE_UTILS_VIS_MODE = "IMAGE_URL";
public static final String UNIVERSITY_COMPARISON_VIS_MODE = "UNIVERSITY"; public static final String UNIVERSITY_COMPARISON_VIS_MODE = "UNIVERSITY";
public static final String SCHOOL_COMPARISON_VIS_MODE = "SCHOOL"; 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. * 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_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 PDF_REPORT_VIS = "pdf_report";
public static final String COLLEGE_PUBLICATION_COUNT_VIS = "college_pub_count"; public static final String COLLEGE_PUBLICATION_COUNT_VIS = "college_pub_count";
public static final String COAUTHORSHIP_VIS = "coauthorship"; public static final String COAUTHORSHIP_VIS = "coauthorship";
@ -84,4 +86,5 @@ public class VisualizationFrameworkConstants {
public static final String CO_PI_VIS = "coprincipalinvestigator"; public static final String CO_PI_VIS = "coprincipalinvestigator";
} }

View file

@ -455,7 +455,7 @@ public class CoAuthorshipQueryRunner implements QueryRunner<CoAuthorshipData> {
+ "} " + "} "
+ "ORDER BY ?document ?coAuthorPerson"; + "ORDER BY ?document ?coAuthorPerson";
// System.out.println("COAUTHORSHIP QUERY - " + sparqlQuery); System.out.println("COAUTHORSHIP QUERY - " + sparqlQuery);
return sparqlQuery; return sparqlQuery;
} }

View file

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

View file

@ -49,7 +49,7 @@ public class PersonGrantCountQueryRunner implements QueryRunner<Set<Grant>>{
private Log log; private Log log;
private static final String SPARQL_QUERY_COMMON_SELECT_CLAUSE = "" private static final String SPARQL_QUERY_COMMON_SELECT_CLAUSE = ""
+ "SELECT (str(?PILabel)) as ?PILabelLit) " + "SELECT (str(?PILabel) as ?PILabelLit) "
+ "(str(?Grant) as ?grantLit)" + "(str(?Grant) as ?grantLit)"
+ "(str(?GrantLabel) as ?grantLabelLit)" + "(str(?GrantLabel) as ?grantLabelLit)"
+ "(str(?GrantStartDate) as ?grantStartDateLit)" + "(str(?GrantStartDate) as ?grantStartDateLit)"
@ -120,7 +120,7 @@ public class PersonGrantCountQueryRunner implements QueryRunner<Set<Grant>>{
String sparqlQuery = QueryConstants.getSparqlPrefixQuery() String sparqlQuery = QueryConstants.getSparqlPrefixQuery()
+ SPARQL_QUERY_COMMON_SELECT_CLAUSE + SPARQL_QUERY_COMMON_SELECT_CLAUSE
+ "(str(<" + queryURI + ">) as ?PILit " + "(str(<" + queryURI + ">) as ?PILit) "
+ "WHERE {" + "WHERE {"
+ "<" + queryURI + "> rdfs:label ?PILabel;" + "<" + queryURI + "> rdfs:label ?PILabel;"
+ "core:hasCo-PrincipalInvestigatorRole ?Role ." + "core:hasCo-PrincipalInvestigatorRole ?Role ."

View file

@ -80,27 +80,27 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
QueryRunner<Set<Grant>> queryManager = QueryRunner<Set<Grant>> queryManager =
new PersonGrantCountQueryRunner(personURI, dataSource, log); new PersonGrantCountQueryRunner(personURI, dataSource, log);
// try { try {
// Set<Grant> authorDocuments = queryManager.getQueryResult(); 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. * parsedPublicationYear to populate the data.
* */ * */
// Map<String, Integer> yearToPublicationCount = Map<String, Integer> yearToGrantCount =
// UtilityFunctions.getYearToPublicationCount(authorDocuments); UtilityFunctions.getYearToGrantCount(PIGrants);
//
// Individual author = ((PersonGrantCountQueryRunner) queryManager).getAuthor(); Individual investigator = ((PersonGrantCountQueryRunner) queryManager).getPrincipalInvestigator();
//
// if (VisualizationFrameworkConstants.DATA_RENDER_MODE if (VisualizationFrameworkConstants.DATA_RENDER_MODE
// .equalsIgnoreCase(renderMode)) { .equalsIgnoreCase(renderMode)) {
//
// prepareDataResponse(author, prepareDataResponse(investigator,
// authorDocuments, PIGrants,
// yearToPublicationCount, yearToGrantCount,
// response); response);
// return; return;
// } }
/* /*
@ -121,77 +121,77 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
/* /*
* Computations required to generate HTML for the sparkline & related context. * Computations required to generate HTML for the sparkline & related context.
* */ * */
// PersonGrantCountVisCodeGenerator visualizationCodeGenerator = PersonGrantCountVisCodeGenerator visualizationCodeGenerator =
// new PersonGrantCountVisCodeGenerator(vitroRequest.getContextPath(), new PersonGrantCountVisCodeGenerator(vitroRequest.getContextPath(),
// personURI, personURI,
// visMode, visMode,
// visContainer, visContainer,
// authorDocuments, PIGrants,
// yearToPublicationCount, yearToGrantCount,
// log); log);
//
// SparklineData sparklineData = visualizationCodeGenerator SparklineData sparklineData = visualizationCodeGenerator
// .getValueObjectContainer(); .getValueObjectContainer();
//
// /* /*
// * This is side-effecting because the response of this method is just to redirect to * This is side-effecting because the response of this method is just to redirect to
// * a page with visualization on it. * a page with visualization on it.
// * */ * */
// RequestDispatcher requestDispatcher = null; RequestDispatcher requestDispatcher = null;
//
// if (VisualizationFrameworkConstants.DYNAMIC_RENDER_MODE if (VisualizationFrameworkConstants.DYNAMIC_RENDER_MODE
// .equalsIgnoreCase(renderMode)) { .equalsIgnoreCase(renderMode)) {
//
// prepareDynamicResponse(request, prepareDynamicResponse(request,
// response, response,
// vitroRequest, vitroRequest,
// sparklineData, sparklineData,
// yearToPublicationCount); yearToGrantCount);
// requestDispatcher = request.getRequestDispatcher("/templates/page/blankPage.jsp"); requestDispatcher = request.getRequestDispatcher("/templates/page/blankPage.jsp");
//
// } else { } else {
// prepareStandaloneResponse(request, prepareStandaloneResponse(request,
// response, response,
// vitroRequest, vitroRequest,
// sparklineData); sparklineData);
// requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP); requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
// } }
//
// try { try {
// requestDispatcher.forward(request, response); requestDispatcher.forward(request, response);
// } catch (Exception e) { } catch (Exception e) {
// log.error("EntityEditController could not forward to view."); log.error("EntityEditController could not forward to view.");
// log.error(e.getMessage()); log.error(e.getMessage());
// log.error(e.getStackTrace()); log.error(e.getStackTrace());
// } }
//
// } catch (MalformedQueryParametersException e) { } catch (MalformedQueryParametersException e) {
// try { try {
// UtilityFunctions.handleMalformedParameters( UtilityFunctions.handleMalformedParameters(
// e.getMessage(), e.getMessage(),
// "Visualization Query Error - Individual Publication Count", "Visualization Query Error - Individual Publication Count",
// vitroRequest, vitroRequest,
// request, request,
// response, response,
// log); log);
// } catch (ServletException e1) { } catch (ServletException e1) {
// log.error(e1.getStackTrace()); log.error(e1.getStackTrace());
// } catch (IOException e1) { } catch (IOException e1) {
// log.error(e1.getStackTrace()); log.error(e1.getStackTrace());
// } }
// return; return;
// } }
} }
private void writePublicationsOverTimeCSV( private void writeGrantsOverTimeCSV(
Map<String, Integer> yearToPublicationCount, Map<String, Integer> yearToGrantCount,
PrintWriter responseWriter) { PrintWriter responseWriter) {
CSVWriter csvWriter = new SimpleWriter(responseWriter); CSVWriter csvWriter = new SimpleWriter(responseWriter);
try { try {
csvWriter.append(new String[] { "Year", "Publications" }); csvWriter.append(new String[] { "Year", "Grants" });
for (Entry<String, Integer> currentEntry : yearToPublicationCount for (Entry<String, Integer> currentEntry : yearToGrantCount
.entrySet()) { .entrySet()) {
csvWriter.append(new Object[] { currentEntry.getKey(), csvWriter.append(new Object[] { currentEntry.getKey(),
currentEntry.getValue() }); 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. * is requested.
* @param author * @param investigator
* @param authorDocuments * @param piGrants
* @param yearToPublicationCount * @param yearToGrantCount
* @param response * @param response
*/ */
private void prepareDataResponse( private void prepareDataResponse(
Individual author, Individual investigator,
Set<Grant> authorDocuments, Set<Grant> piGrants,
Map<String, Integer> yearToPublicationCount, Map<String, Integer> yearToGrantCount,
HttpServletResponse response) { 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. * individual.
* */ * */
if (authorDocuments.size() > 0) { if (piGrants.size() > 0) {
authorName = author.getIndividualLabel(); 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)) { if (StringUtils.isBlank(investigatorName)) {
authorName = "no-author"; investigatorName = "no-investigator";
} }
String outputFileName = UtilityFunctions.slugify(authorName) String outputFileName = UtilityFunctions.slugify(investigatorName)
+ "_publications-per-year" + ".csv"; + "_grants-per-year" + ".csv";
response.setContentType("application/octet-stream"); response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName); 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 * We are side-effecting responseWriter since we are directly manipulating the response
* object of the servlet. * object of the servlet.
* */ * */
writePublicationsOverTimeCSV(yearToPublicationCount, responseWriter); writeGrantsOverTimeCSV(yearToGrantCount, responseWriter);
responseWriter.close(); responseWriter.close();
@ -273,34 +273,34 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
request.setAttribute("sparklineVO", valueObjectContainer); 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("portalBean", portal);
request.setAttribute("title", "Individual Publication Count visualization"); request.setAttribute("title", "Individual Grant Count visualization");
request.setAttribute("scripts", "/templates/visualization/visualization_scripts.jsp"); 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. * page, e.g. profile page.
* @param request * @param request
* @param response * @param response
* @param vreq * @param vreq
* @param valueObjectContainer * @param valueObjectContainer
* @param yearToPublicationCount * @param yearToGrantCount
*/ */
private void prepareDynamicResponse( private void prepareDynamicResponse(
HttpServletRequest request, HttpServletRequest request,
HttpServletResponse response, HttpServletResponse response,
VitroRequest vreq, VitroRequest vreq,
SparklineData valueObjectContainer, SparklineData valueObjectContainer,
Map<String, Integer> yearToPublicationCount) { Map<String, Integer> yearToGrantCount) {
Portal portal = vreq.getPortal(); Portal portal = vreq.getPortal();
request.setAttribute("sparklineVO", valueObjectContainer); request.setAttribute("sparklineVO", valueObjectContainer);
if (yearToPublicationCount.size() > 0) { if (yearToGrantCount.size() > 0) {
request.setAttribute("shouldVIVOrenderVis", true); request.setAttribute("shouldVIVOrenderVis", true);
} else { } else {
request.setAttribute("shouldVIVOrenderVis", false); request.setAttribute("shouldVIVOrenderVis", false);
@ -310,30 +310,30 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
request.setAttribute("bodyJsp", "/templates/visualization/ajax_vis_content.jsp"); request.setAttribute("bodyJsp", "/templates/visualization/ajax_vis_content.jsp");
} }
private void preparePDFResponse(Individual author, private void preparePDFResponse(Individual investigator,
Set<Grant> authorDocuments, Set<Grant> piGrants,
Map<String, Integer> yearToPublicationCount, Map<String, Integer> yearToGrantCount,
HttpServletResponse response) { 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. * associated with the individual.
*/ */
if (authorDocuments.size() > 0) { if (piGrants.size() > 0) {
authorName = author.getIndividualLabel(); 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. * any mischief.
*/ */
if (StringUtils.isBlank(authorName)) { if (StringUtils.isBlank(investigatorName)) {
authorName = "no-author"; investigatorName = "no-investigator";
} }
String outputFileName = UtilityFunctions.slugify(authorName) String outputFileName = UtilityFunctions.slugify(investigatorName)
+ "_report" + ".pdf"; + "_report" + ".pdf";
response.setContentType("application/pdf"); response.setContentType("application/pdf");
@ -349,8 +349,8 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
PdfWriter pdfWriter = PdfWriter.getInstance(document, baos); PdfWriter pdfWriter = PdfWriter.getInstance(document, baos);
document.open(); document.open();
PDFDocument pdfDocument = new PDFDocument(authorName, PDFDocument pdfDocument = new PDFDocument(investigatorName,
yearToPublicationCount, document, pdfWriter); yearToGrantCount, document, pdfWriter);
document.close(); document.close();

View file

@ -2,6 +2,674 @@
package edu.cornell.mannlib.vitro.webapp.visualization.persongrantcount; 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 { 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;
}
} }

View file

@ -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.CoAuthorshipQueryRunner;
import edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.CoAuthorshipVisCodeGenerator; 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.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.PersonPublicationCountQueryRunner;
import edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.PersonPublicationCountVisCodeGenerator; 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.BiboDocument;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoAuthorshipData; 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.Node;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineData; import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineData;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner; 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 EGO_PUB_SPARKLINE_VIS_CONTAINER_ID = "ego_pub_sparkline";
private static final String UNIQUE_COAUTHORS_SPARKLINE_VIS_CONTAINER_ID = private static final String UNIQUE_COAUTHORS_SPARKLINE_VIS_CONTAINER_ID =
"unique_coauthors_sparkline"; "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, public void generateVisualization(VitroRequest vitroRequest,
HttpServletRequest request, HttpServletRequest request,
@ -75,10 +85,18 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
QueryRunner<Set<BiboDocument>> publicationQueryManager = QueryRunner<Set<BiboDocument>> publicationQueryManager =
new PersonPublicationCountQueryRunner(egoURI, dataSource, log); new PersonPublicationCountQueryRunner(egoURI, dataSource, log);
QueryRunner<CoPIData> coPIQueryManager = new CoPIGrantCountQueryRunner(egoURI, dataSource, log);
QueryRunner<Set<Grant>> grantQueryManager =
new PersonGrantCountQueryRunner(egoURI, dataSource, log);
try { try {
CoAuthorshipData coAuthorshipData = coAuthorshipQueryManager.getQueryResult(); CoAuthorshipData coAuthorshipData = coAuthorshipQueryManager.getQueryResult();
CoPIData coPIData = coPIQueryManager.getQueryResult();
if (VisualizationFrameworkConstants.DATA_RENDER_MODE if (VisualizationFrameworkConstants.DATA_RENDER_MODE
.equalsIgnoreCase(renderMode)) { .equalsIgnoreCase(renderMode)) {
@ -154,6 +172,48 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
SparklineData uniqueCoauthorsSparklineVO = uniqueCoauthorsVisCodeGenerator SparklineData uniqueCoauthorsSparklineVO = uniqueCoauthorsVisCodeGenerator
.getValueObjectContainer(); .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; RequestDispatcher requestDispatcher = null;
@ -161,11 +221,14 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
egoURI, egoURI,
publicationSparklineVO, publicationSparklineVO,
uniqueCoauthorsSparklineVO, uniqueCoauthorsSparklineVO,
grantSparklineVO,
uniqueCopisSparklineVO,
coAuthorshipData, coAuthorshipData,
coPIData,
EGO_PUB_SPARKLINE_VIS_CONTAINER_ID, EGO_PUB_SPARKLINE_VIS_CONTAINER_ID,
UNIQUE_COAUTHORS_SPARKLINE_VIS_CONTAINER_ID, UNIQUE_COAUTHORS_SPARKLINE_VIS_CONTAINER_ID,
vitroRequest, vitroRequest,
request); request, visMode);
requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP); requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
@ -319,21 +382,25 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
* @param egoURI * @param egoURI
* @param egoPubSparklineVO * @param egoPubSparklineVO
* @param uniqueCoauthorsSparklineVO * @param uniqueCoauthorsSparklineVO
* @param uniqueCopisSparklineVO
* @param grantSparklineVO
* @param coAuthorshipVO * @param coAuthorshipVO
* @param coPIVO
* @param egoPubSparklineVisContainer * @param egoPubSparklineVisContainer
* @param uniqueCoauthorsSparklineVisContainer * @param uniqueCoauthorsSparklineVisContainer
* @param vitroRequest * @param vitroRequest
* @param request * @param request
* @param visMode
*/ */
private void prepareStandaloneResponse ( private void prepareStandaloneResponse (
String egoURI, String egoURI,
SparklineData egoPubSparklineVO, SparklineData egoPubSparklineVO,
SparklineData uniqueCoauthorsSparklineVO, SparklineData uniqueCoauthorsSparklineVO,
CoAuthorshipData coAuthorshipVO, SparklineData egoGrantSparklineVO, SparklineData uniqueCopisSparklineVO, CoAuthorshipData coAuthorshipVO,
String egoPubSparklineVisContainer, CoPIData coPIVO, String egoPubSparklineVisContainer,
String uniqueCoauthorsSparklineVisContainer, String uniqueCoauthorsSparklineVisContainer,
VitroRequest vitroRequest, VitroRequest vitroRequest,
HttpServletRequest request) { HttpServletRequest request, String visMode) {
String completeURL = ""; String completeURL = "";
Portal portal = vitroRequest.getPortal(); Portal portal = vitroRequest.getPortal();
@ -350,6 +417,15 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
request.setAttribute("numOfCoAuthorShips", coAuthorshipVO.getEdges().size()); 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 { try {
completeURL = getCompleteURL(request); completeURL = getCompleteURL(request);
@ -357,9 +433,12 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
e.printStackTrace(); e.printStackTrace();
} }
request.setAttribute("visMode", visMode);
request.setAttribute("completeURL", completeURL); request.setAttribute("completeURL", completeURL);
request.setAttribute("egoPubSparklineVO", egoPubSparklineVO); request.setAttribute("egoPubSparklineVO", egoPubSparklineVO);
request.setAttribute("egoGrantSparklineVO", egoGrantSparklineVO);
request.setAttribute("uniqueCoauthorsSparklineVO", uniqueCoauthorsSparklineVO); request.setAttribute("uniqueCoauthorsSparklineVO", uniqueCoauthorsSparklineVO);
request.setAttribute("uniqueCopisSparklineVO", uniqueCopisSparklineVO);
request.setAttribute("egoPubSparklineContainerID", egoPubSparklineVisContainer); request.setAttribute("egoPubSparklineContainerID", egoPubSparklineVisContainer);
request.setAttribute("uniqueCoauthorsSparklineVisContainerID", request.setAttribute("uniqueCoauthorsSparklineVisContainerID",

View file

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

View file

@ -567,7 +567,7 @@ public class PersonPublicationCountVisCodeGenerator {
try { try {
String fullTimelineLink; String fullTimelineLink, fullTimelineCoPILink;
if (yearToPublicationCount.size() > 0) { if (yearToPublicationCount.size() > 0) {
String secondaryContextPath = ""; String secondaryContextPath = "";
@ -600,11 +600,39 @@ public class PersonPublicationCountVisCodeGenerator {
sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL); 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 { } else {
fullTimelineLink = "No data available to render full timeline.<br />"; 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("<span class=\"vis_link\">" + fullTimelineLink + "</span>");
divContextCode.append("<br/><br/><span class=\"vis_link_copi\">" + fullTimelineCoPILink + "</span>");
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
log.error(e); log.error(e);

View file

@ -213,7 +213,36 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler {
+ VisualizationFrameworkConstants.RENDER_MODE_KEY + VisualizationFrameworkConstants.RENDER_MODE_KEY
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants + "=" + URLEncoder.encode(VisualizationFrameworkConstants
.STANDALONE_RENDER_MODE, .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); prepareUtilitiesResponse(preparedURL, response);
return; return;

View file

@ -15,11 +15,17 @@ public class SparklineData {
private Integer earliestRenderedPublicationYear; private Integer earliestRenderedPublicationYear;
private Integer latestRenderedPublicationYear; private Integer latestRenderedPublicationYear;
private Integer earliestRenderedGrantYear;
private Integer latestRenderedGrantYear;
private String table = ""; private String table = "";
private String downloadDataLink = ""; private String downloadDataLink = "";
private String fullTimelineNetworkLink = ""; private String fullTimelineNetworkLink = "";
private String downloadCoPIDataLink = "";
private String fullTimelineCoPINetworkLink = "";
private String sparklineContent; private String sparklineContent;
private String sparklineContext; private String sparklineContext;
@ -97,4 +103,38 @@ public class SparklineData {
public void setSparklineContext(String shortSparklineContext) { public void setSparklineContext(String shortSparklineContext) {
this.sparklineContext = 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;
}
} }