[VIVO-1119] Add D3 based versions of the co-authorship / investigator visualisations, which can be used via the runtime.properties
This commit is contained in:
parent
ec29715259
commit
85ad30d611
12 changed files with 1039 additions and 59 deletions
|
@ -311,6 +311,17 @@ resource.altmetric=enabled
|
||||||
#
|
#
|
||||||
visualization.temporal = enabled
|
visualization.temporal = enabled
|
||||||
|
|
||||||
|
#
|
||||||
|
# The co-authorship and co-investigator graphs have two variants - the traditional Flash based view,
|
||||||
|
# and views using D3.
|
||||||
|
# The traditional views require that users have Flash installed as a plugin, whereas D3 works on any
|
||||||
|
# modern browser.
|
||||||
|
# Currently, it is not possible to choose between them from the UI. You can choose to either have
|
||||||
|
# the Flash visualizations, OR the D3 visualizations.
|
||||||
|
# If this option is not present or set to disabled, then the Flash visualizations will be used.
|
||||||
|
# If this option is present and set to enabled, then the D3 visualizations will be used.
|
||||||
|
visualization.d3 = enabled
|
||||||
|
|
||||||
#
|
#
|
||||||
# Types of individual for which we can create proxy editors.
|
# Types of individual for which we can create proxy editors.
|
||||||
# If this is omitted, defaults to http://www.w3.org/2002/07/owl#Thing
|
# If this is omitted, defaults to http://www.w3.org/2002/07/owl#Thing
|
||||||
|
|
|
@ -18,6 +18,11 @@ a.no_href_styles {
|
||||||
width: 67%;
|
width: 67%;
|
||||||
margin-left: 33%;
|
margin-left: 33%;
|
||||||
}
|
}
|
||||||
|
.vis_stats_full {
|
||||||
|
background: #fff;
|
||||||
|
clear: right;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
.vis-tables {
|
.vis-tables {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: #FFF;
|
background-color: #FFF;
|
||||||
|
@ -27,6 +32,12 @@ a.no_href_styles {
|
||||||
width: 44%;
|
width: 44%;
|
||||||
margin: 0 10px 10px 0;
|
margin: 0 10px 10px 0;
|
||||||
}
|
}
|
||||||
|
#chord-info-div {
|
||||||
|
border: 1px solid #000000;
|
||||||
|
background: #F5F5F5;
|
||||||
|
padding: 5px;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
p.datatable {
|
p.datatable {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -46,6 +57,10 @@ p.datatable {
|
||||||
width: 67%;
|
width: 67%;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
#sparkline-container-full {
|
||||||
|
clear: both;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
#body h1 {
|
#body h1 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
5
productMods/js/d3.min.js
vendored
Normal file
5
productMods/js/d3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -15,6 +15,23 @@
|
||||||
<div class="staticPageBackground">
|
<div class="staticPageBackground">
|
||||||
<div id="${visContainerID}">
|
<div id="${visContainerID}">
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
<#if sparklineVO.shortVisMode>
|
||||||
|
var visualizationOptions = {
|
||||||
|
width: 150,
|
||||||
|
height: 60,
|
||||||
|
color: '3399CC',
|
||||||
|
chartType: 'ls',
|
||||||
|
chartLabel: 'r'
|
||||||
|
};
|
||||||
|
<#else>
|
||||||
|
var visualizationOptions = {
|
||||||
|
width: 250,
|
||||||
|
height: 75,
|
||||||
|
color: '3399CC',
|
||||||
|
chartType: 'ls',
|
||||||
|
chartLabel: 'r'
|
||||||
|
};
|
||||||
|
</#if>
|
||||||
|
|
||||||
function drawCoauthorsSparklineVisualization(providedSparklineImgTD) {
|
function drawCoauthorsSparklineVisualization(providedSparklineImgTD) {
|
||||||
|
|
||||||
|
@ -49,22 +66,8 @@
|
||||||
maxValue: '${sparklineVO.latestRenderedPublicationYear?c}'
|
maxValue: '${sparklineVO.latestRenderedPublicationYear?c}'
|
||||||
}]));
|
}]));
|
||||||
|
|
||||||
var visualizationOptions = {
|
|
||||||
width: 150,
|
|
||||||
height: 60,
|
|
||||||
color: '3399CC',
|
|
||||||
chartType: 'ls',
|
|
||||||
chartLabel: 'r'
|
|
||||||
}
|
|
||||||
<#else>
|
<#else>
|
||||||
|
|
||||||
var visualizationOptions = {
|
|
||||||
width: 250,
|
|
||||||
height: 75,
|
|
||||||
color: '3399CC',
|
|
||||||
chartType: 'ls',
|
|
||||||
chartLabel: 'r'
|
|
||||||
}
|
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
|
|
||||||
|
@ -246,7 +249,7 @@
|
||||||
var row = $('<tr>');
|
var row = $('<tr>');
|
||||||
sparklineImgTD = $('<td>');
|
sparklineImgTD = $('<td>');
|
||||||
sparklineImgTD.attr('id', '${sparklineContainerID}_img');
|
sparklineImgTD.attr('id', '${sparklineContainerID}_img');
|
||||||
sparklineImgTD.attr('width', '150');
|
sparklineImgTD.attr('width', visualizationOptions.width);
|
||||||
sparklineImgTD.attr('class', 'sparkline_style');
|
sparklineImgTD.attr('class', 'sparkline_style');
|
||||||
|
|
||||||
row.append(sparklineImgTD);
|
row.append(sparklineImgTD);
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||||
|
|
||||||
|
<table id='${tableID}'>
|
||||||
|
<caption>
|
||||||
|
${tableCaption} <a href="${fileDownloadLink}">(.CSV ${i18n().file_capitalized})</a>
|
||||||
|
</caption>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
${tableCollaboratorColumnName}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
${tableActivityColumnName}
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<#list tableContent.collaborators as collaborator>
|
||||||
|
<#if collaborator_index gt 0>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
${collaborator.collaboratorName}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
${tableContent.collaborationMatrix[0][collaborator_index]}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
|
@ -15,6 +15,23 @@
|
||||||
<div class="staticPageBackground">
|
<div class="staticPageBackground">
|
||||||
<div id="${visContainerID}">
|
<div id="${visContainerID}">
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
<#if sparklineVO.shortVisMode>
|
||||||
|
var visualizationOptions = {
|
||||||
|
width: 150,
|
||||||
|
height: 60,
|
||||||
|
color: '3399CC',
|
||||||
|
chartType: 'ls',
|
||||||
|
chartLabel: 'r'
|
||||||
|
};
|
||||||
|
<#else>
|
||||||
|
var visualizationOptions = {
|
||||||
|
width: 250,
|
||||||
|
height: 75,
|
||||||
|
color: '3399CC',
|
||||||
|
chartType: 'ls',
|
||||||
|
chartLabel: 'r'
|
||||||
|
};
|
||||||
|
</#if>
|
||||||
|
|
||||||
function drawCoInvestigatorsSparklineVisualization(providedSparklineImgTD) {
|
function drawCoInvestigatorsSparklineVisualization(providedSparklineImgTD) {
|
||||||
|
|
||||||
|
@ -53,14 +70,6 @@
|
||||||
|
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
var visualizationOptions = {
|
|
||||||
width: 150,
|
|
||||||
height: 60,
|
|
||||||
color: '3399CC',
|
|
||||||
chartType: 'ls',
|
|
||||||
chartLabel: 'r'
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This means that all the publications have unknown years & we do not need to display
|
This means that all the publications have unknown years & we do not need to display
|
||||||
the sparkline.
|
the sparkline.
|
||||||
|
@ -243,7 +252,7 @@
|
||||||
var row = $('<tr>');
|
var row = $('<tr>');
|
||||||
sparklineImgTD = $('<td>');
|
sparklineImgTD = $('<td>');
|
||||||
sparklineImgTD.attr('id', '${sparklineContainerID}_img');
|
sparklineImgTD.attr('id', '${sparklineContainerID}_img');
|
||||||
sparklineImgTD.attr('width', '150');
|
sparklineImgTD.attr('width', visualizationOptions.width);
|
||||||
sparklineImgTD.attr('class', 'sparkline_style');
|
sparklineImgTD.attr('class', 'sparkline_style');
|
||||||
|
|
||||||
row.append(sparklineImgTD);
|
row.append(sparklineImgTD);
|
||||||
|
|
|
@ -15,6 +15,23 @@
|
||||||
<div class="staticPageBackground">
|
<div class="staticPageBackground">
|
||||||
<div id="${visContainerID}">
|
<div id="${visContainerID}">
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
<#if sparklineVO.shortVisMode>
|
||||||
|
var visualizationOptions = {
|
||||||
|
width: 150,
|
||||||
|
height: 60,
|
||||||
|
color: '3399CC',
|
||||||
|
chartType: 'ls',
|
||||||
|
chartLabel: 'r'
|
||||||
|
};
|
||||||
|
<#else>
|
||||||
|
var visualizationOptions = {
|
||||||
|
width: 250,
|
||||||
|
height: 75,
|
||||||
|
color: '3399CC',
|
||||||
|
chartType: 'ls',
|
||||||
|
chartLabel: 'r'
|
||||||
|
};
|
||||||
|
</#if>
|
||||||
|
|
||||||
function drawGrantCountVisualization(providedSparklineImgTD) {
|
function drawGrantCountVisualization(providedSparklineImgTD) {
|
||||||
|
|
||||||
|
@ -53,13 +70,6 @@
|
||||||
|
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
var visualizationOptions = {
|
|
||||||
width: 150,
|
|
||||||
height: 60,
|
|
||||||
color: '3399CC',
|
|
||||||
chartType: 'ls',
|
|
||||||
chartLabel: 'r'
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This means that all the publications have unknown years & we do not need to display
|
This means that all the publications have unknown years & we do not need to display
|
||||||
|
@ -236,7 +246,7 @@
|
||||||
var row = $('<tr>');
|
var row = $('<tr>');
|
||||||
sparklineImgTD = $('<td>');
|
sparklineImgTD = $('<td>');
|
||||||
sparklineImgTD.attr('id', '${sparklineContainerID}_img');
|
sparklineImgTD.attr('id', '${sparklineContainerID}_img');
|
||||||
sparklineImgTD.attr('width', '150');
|
sparklineImgTD.attr('width', visualizationOptions.width);
|
||||||
sparklineImgTD.attr('class', 'sparkline_style');
|
sparklineImgTD.attr('class', 'sparkline_style');
|
||||||
|
|
||||||
row.append(sparklineImgTD);
|
row.append(sparklineImgTD);
|
||||||
|
|
|
@ -0,0 +1,345 @@
|
||||||
|
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||||
|
|
||||||
|
<#assign standardVisualizationURLRoot ="/visualization">
|
||||||
|
<#assign shortVisualizationURLRoot ="/vis">
|
||||||
|
<#assign ajaxVisualizationURLRoot ="/visualizationAjax">
|
||||||
|
<#assign dataVisualizationURLRoot ="/visualizationData">
|
||||||
|
|
||||||
|
<#assign egoURI ="${egoURIParam?url}">
|
||||||
|
<#assign egoCoAuthorshipDataFeederURL = '${urls.base}${dataVisualizationURLRoot}?vis=coauthorship&uri=${egoURI}&vis_mode=coauthor_network_stream&labelField=label'>
|
||||||
|
|
||||||
|
<#if egoLocalName?has_content >
|
||||||
|
<#assign coprincipalinvestigatorURL = '${urls.base}${shortVisualizationURLRoot}/investigator-network/${egoLocalName}'>
|
||||||
|
<#else>
|
||||||
|
<#assign coprincipalinvestigatorURL = '${urls.base}${shortVisualizationURLRoot}/investigator-network/?uri=${egoURI}'>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#assign egoCoAuthorsListDataFileURL = '${urls.base}${dataVisualizationURLRoot}?vis=coauthorship&uri=${egoURI}&vis_mode=coauthors'>
|
||||||
|
<#assign egoCoAuthorshipNetworkDataFileURL = '${urls.base}${dataVisualizationURLRoot}?vis=coauthorship&uri=${egoURI}&vis_mode=coauthor_network_download'>
|
||||||
|
|
||||||
|
<#assign googleVisualizationAPI = 'https://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22areachart%22%2C%22imagesparkline%22%5D%7D%5D%7D'>
|
||||||
|
<#assign coAuthorPersonLevelJavaScript = '${urls.base}/js/visualization/coauthorship/coauthorship-personlevel.js'>
|
||||||
|
<#assign commonPersonLevelJavaScript = '${urls.base}/js/visualization/personlevel/person-level.js'>
|
||||||
|
|
||||||
|
<#assign coInvestigatorIcon = '${urls.images}/visualization/coauthorship/co_investigator_icon.png'>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="${googleVisualizationAPI}"></script>
|
||||||
|
|
||||||
|
<script language="JavaScript" type="text/javascript">
|
||||||
|
<!--
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Globals
|
||||||
|
var egoURI = "${egoURI}";
|
||||||
|
var unEncodedEgoURI = "${egoURIParam}";
|
||||||
|
var egoCoAuthorshipDataFeederURL = "${egoCoAuthorshipDataFeederURL}";
|
||||||
|
var egoCoAuthorsListDataFileURL = "${egoCoAuthorsListDataFileURL}";
|
||||||
|
var contextPath = "${urls.base}";
|
||||||
|
|
||||||
|
var visualizationDataRoot = "${dataVisualizationURLRoot}";
|
||||||
|
// -->
|
||||||
|
|
||||||
|
var i18nStringsCoauthorship = {
|
||||||
|
coAuthorsString: '${i18n().co_authors_capitalized}',
|
||||||
|
authorString: '${i18n().author_capitalized}',
|
||||||
|
publicationsWith: '${i18n().publications_with}',
|
||||||
|
publicationsString: "${i18n().through_today}",
|
||||||
|
coauthorsString: '${i18n().co_author_s_capitalized}'
|
||||||
|
};
|
||||||
|
var i18nStringsPersonLvl = {
|
||||||
|
fileCapitalized: '${i18n().file_capitalized}',
|
||||||
|
contentRequiresFlash: '${i18n().content_requires_flash}',
|
||||||
|
getFlashString: '${i18n().get_flash}'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="${coAuthorPersonLevelJavaScript}"></script>
|
||||||
|
<script type="text/javascript" src="${commonPersonLevelJavaScript}"></script>
|
||||||
|
|
||||||
|
${scripts.add('<script type="text/javascript" src="${urls.base}/js/visualization/visualization-helper-functions.js"></script>')}
|
||||||
|
${scripts.add('<script type="text/javascript" src="${urls.base}/js/d3.min.js"></script>')}
|
||||||
|
|
||||||
|
${stylesheets.add('<link rel="stylesheet" type="text/css" href="${urls.base}/css/visualization/personlevel/page.css" />',
|
||||||
|
'<link rel="stylesheet" type="text/css" href="${urls.base}/css/visualization/visualization.css" />')}
|
||||||
|
|
||||||
|
<#assign egoVivoProfileURL = "${urls.base}/individual?uri=${egoURI}" />
|
||||||
|
|
||||||
|
<script language="JavaScript" type="text/javascript">
|
||||||
|
|
||||||
|
$(document).ready(function(){
|
||||||
|
|
||||||
|
processProfileInformation("ego_label",
|
||||||
|
"ego_moniker",
|
||||||
|
"ego_profile_image",
|
||||||
|
jQuery.parseJSON(getWellFormedURLs("${egoURIParam}", "profile_info")));
|
||||||
|
|
||||||
|
<#if (numOfCoAuthorShips?? && numOfCoAuthorShips <= 0) || (numOfAuthors?? && numOfAuthors <= 0) >
|
||||||
|
if ($('#ego_label').text().length > 0) {
|
||||||
|
setProfileName('no_coauthorships_person', $('#ego_label').text());
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "${urls.base}/visualizationAjax",
|
||||||
|
data: ({vis: "utilities", vis_mode: "SHOW_GRANTS_LINK", uri: '${egoURIParam}'}),
|
||||||
|
dataType: "json",
|
||||||
|
success:function(data){
|
||||||
|
|
||||||
|
/*
|
||||||
|
Collaboratorship links do not show up by default. They should show up only if there any data to
|
||||||
|
show on that page.
|
||||||
|
*/
|
||||||
|
if (data.numOfGrants !== undefined && data.numOfGrants > 0) {
|
||||||
|
$(".toggle_visualization").show();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// RENDER CHORD
|
||||||
|
|
||||||
|
var labels = [];
|
||||||
|
var uris = [];
|
||||||
|
var matrix = [];
|
||||||
|
|
||||||
|
var matrixX = 0;
|
||||||
|
<#list coAuthorshipData.collaborationMatrix as row>
|
||||||
|
matrix[matrixX] = [];
|
||||||
|
<#list row as cell>
|
||||||
|
matrix[matrixX].push(${cell?c});
|
||||||
|
</#list>
|
||||||
|
matrixX++;
|
||||||
|
</#list>
|
||||||
|
<#list coAuthorshipData.collaborators as collaborator>
|
||||||
|
labels.push("${collaborator.collaboratorName}");
|
||||||
|
uris.push("${collaborator.collaboratorURI}");
|
||||||
|
</#list>
|
||||||
|
|
||||||
|
var chord = d3.layout.chord()
|
||||||
|
.padding(0.05)
|
||||||
|
.sortSubgroups(d3.descending)
|
||||||
|
.matrix(matrix);
|
||||||
|
|
||||||
|
var width = 725;
|
||||||
|
var height = 725;
|
||||||
|
var padding = 175;
|
||||||
|
var inner_radius = Math.min(width, height) * 0.37;
|
||||||
|
var outer_radius = Math.min(width, height) * 0.39;
|
||||||
|
|
||||||
|
var fill = d3.scale.category10();
|
||||||
|
|
||||||
|
var svg = d3.select('#chord').append('svg')
|
||||||
|
.attr('width', width+padding)
|
||||||
|
.attr('height', height+padding)
|
||||||
|
.append('g').attr('transform', 'translate(' + (width+padding) / 2 + ',' + (height+padding) / 2 +')');
|
||||||
|
|
||||||
|
svg.append('g').selectAll('path').data(chord.groups).enter()
|
||||||
|
.append('path').style('fill', function(val) { return val.index == 0 ? "#000000" : fill(val.index); })
|
||||||
|
.style('stroke', function(val) { return val.index == 0 ? "#000000" : fill(val.index); })
|
||||||
|
.attr('d', d3.svg.arc().innerRadius(inner_radius).outerRadius(outer_radius))
|
||||||
|
.on('click', chord_click())
|
||||||
|
.on("mouseover", chord_hover(.05))
|
||||||
|
.on("mouseout", chord_hover(.8));
|
||||||
|
|
||||||
|
var group_ticks = function (d) {
|
||||||
|
var k = (d.endAngle - d.startAngle) / d.value;
|
||||||
|
return d3.range(d.value / 2, d.value, d.value / 2).map(function (v) {
|
||||||
|
return {
|
||||||
|
angle: v * k + d.startAngle,
|
||||||
|
label: Math.round(d.value)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var chord_ticks = svg.append('g')
|
||||||
|
.selectAll('g')
|
||||||
|
.data(chord.groups)
|
||||||
|
.enter().append('g')
|
||||||
|
.selectAll('g')
|
||||||
|
.data(group_ticks)
|
||||||
|
.enter().append('g')
|
||||||
|
.attr('transform', function (d) {
|
||||||
|
return 'rotate(' + (d.angle * 180 / Math.PI - 90) + ') translate(' + outer_radius + ',0)';
|
||||||
|
});
|
||||||
|
|
||||||
|
svg.append('g')
|
||||||
|
.attr('class', 'chord')
|
||||||
|
.selectAll('path')
|
||||||
|
.data(chord.chords)
|
||||||
|
.enter().append('path')
|
||||||
|
.style('fill', function (d) { return fill(d.target.index); })
|
||||||
|
.attr('d', d3.svg.chord().radius(inner_radius))
|
||||||
|
.style('opacity', .8);
|
||||||
|
|
||||||
|
svg.append("g").selectAll(".arc")
|
||||||
|
.data(chord.groups)
|
||||||
|
.enter().append("svg:text")
|
||||||
|
.attr("dy", ".35em")
|
||||||
|
.attr("style", function(d) { return d.index == 0 ? "font-size: .75em; font-weight: bold;" : "font-size: .70em;"; } )
|
||||||
|
.attr("text-anchor", function(d) { return ((d.startAngle + d.endAngle) / 2) > Math.PI ? "end" : null; })
|
||||||
|
.attr("transform", function(d) {
|
||||||
|
return "rotate(" + (((d.startAngle + d.endAngle) / 2) * 180 / Math.PI - 90) + ")"
|
||||||
|
+ "translate(" + (height *.40) + ")"
|
||||||
|
+ (((d.startAngle + d.endAngle) / 2) > Math.PI ? "rotate(180)" : "");
|
||||||
|
})
|
||||||
|
.text(function(d) {
|
||||||
|
return labels[d.index];
|
||||||
|
})
|
||||||
|
.on('click', chord_click())
|
||||||
|
.on("mouseover", chord_hover(.05))
|
||||||
|
.on("mouseout", chord_hover(.8));
|
||||||
|
|
||||||
|
function chord_hover(opacity) {
|
||||||
|
return function(g, i) {
|
||||||
|
if (opacity > .5) {
|
||||||
|
var chordInfoDiv = d3.select('#chord-info-div');
|
||||||
|
chordInfoDiv.style('display', 'none');
|
||||||
|
} else {
|
||||||
|
var hoverEvent = d3.event;
|
||||||
|
var topPos = hoverEvent.pageY - 60;
|
||||||
|
var leftPos = hoverEvent.pageX + 10;
|
||||||
|
|
||||||
|
var chord = d3.select('#chord').node();
|
||||||
|
var chordInfoDiv = d3.select('#chord-info-div');
|
||||||
|
var hoverMsg = labels[i] + "<br/>";
|
||||||
|
if (i > 0) {
|
||||||
|
hoverMsg += matrix[i][0] + " Joint ${i18n().publication_s_capitalized}<br/>";
|
||||||
|
} else {
|
||||||
|
hoverMsg += "${coAuthorshipData.collaboratorsCount} ${i18n().co_author_s_capitalized}<br/>";
|
||||||
|
}
|
||||||
|
|
||||||
|
chordInfoDiv.html(hoverMsg);
|
||||||
|
chordInfoDiv.style('display', 'block');
|
||||||
|
chordInfoDiv.style('position', 'absolute');
|
||||||
|
|
||||||
|
if (d3.mouse(chord)[1] > height / 2) {
|
||||||
|
topPos += 80;
|
||||||
|
}
|
||||||
|
chordInfoDiv.style('top', topPos + 'px');
|
||||||
|
|
||||||
|
if (hoverEvent.pageX > document.body.clientWidth / 2) {
|
||||||
|
leftPos = hoverEvent.pageX + 10;
|
||||||
|
} else {
|
||||||
|
leftPos = hoverEvent.pageX - (10 + chordInfoDiv.node().getBoundingClientRect().width);
|
||||||
|
}
|
||||||
|
chordInfoDiv.style('left', leftPos + 'px');
|
||||||
|
}
|
||||||
|
|
||||||
|
svg.selectAll(".chord path")
|
||||||
|
.filter(function(d) { return d.source.index != i && d.target.index != i; })
|
||||||
|
.transition()
|
||||||
|
.style("opacity", opacity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function chord_click() {
|
||||||
|
return function (g, i) {
|
||||||
|
if (i > 0) {
|
||||||
|
window.location.href = getWellFormedURLs(uris[i], "profile");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div id="body">
|
||||||
|
<div class="sub_headings"><h2><a href="${egoVivoProfileURL}" title="${i18n().author_name}"><span id="ego_label"></span></a><br />${i18n().co_author_network} </h2></div>
|
||||||
|
<#if (numOfCoAuthorShips?? && numOfCoAuthorShips > 0) || (numOfAuthors?? && numOfAuthors > 0) >
|
||||||
|
<div class = "graphml-file-link">(<a href="${egoCoAuthorshipNetworkDataFileURL}" title="GraphML ${i18n().file}">GraphML ${i18n().file}</a>)</div>
|
||||||
|
<#else>
|
||||||
|
|
||||||
|
<#if numOfAuthors?? && numOfAuthors <= 0 >
|
||||||
|
<#assign authorsText = "multi-author" />
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<div id="no_coauthorships">${i18n().currently_no_papers_for(authorsText!)}
|
||||||
|
<a href="${egoVivoProfileURL}" title="${i18n().co_authorship}"><span id="no_coauthorships_person" class="author_name">${i18n().this_author}</span></a> ${i18n().in_the_vivo_db}
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<div class = "toggle_visualization">
|
||||||
|
<div id="coinvestigator_link_container" class="collaboratorship-link-container">
|
||||||
|
<div class="collaboratorship-icon"><a href="${coprincipalinvestigatorURL}" title="${i18n().co_investigator}"><img src="${coInvestigatorIcon}" alt="${i18n().co_investigator_icon}"/></a></div>
|
||||||
|
<div class="collaboratorship-link">
|
||||||
|
<h3><a href="${coprincipalinvestigatorURL}" title="${i18n().co_investigator_network}">${i18n().co_investigator_network_capitalized}</a></h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="clear:both;"></div>
|
||||||
|
|
||||||
|
<#if (numOfAuthors?? && numOfAuthors > 0) >
|
||||||
|
<#else>
|
||||||
|
|
||||||
|
<span id="no_coauthorships">${i18n().no_papers_for}
|
||||||
|
<a href="${egoVivoProfileURL}" title="${i18n().co_authorship}"><span id="no_coauthorships_person" class="author_name">${i18n().this_author}</span></a> ${i18n().in_the_vivo_db}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if (numOfCoAuthorShips?? && numOfCoAuthorShips > 0) || (numOfAuthors?? && numOfAuthors > 0) >
|
||||||
|
|
||||||
|
<div id="bodyPannel">
|
||||||
|
<div id="chord" style="float: right;"></div>
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if (numOfAuthors?? && numOfAuthors > 0) >
|
||||||
|
|
||||||
|
<#-- Sparkline -->
|
||||||
|
<div id="sparkline-container-full">
|
||||||
|
|
||||||
|
<#assign displayTable = false />
|
||||||
|
|
||||||
|
<#assign sparklineVO = egoPubSparklineVO />
|
||||||
|
<div id="publication-count-sparkline-include"><#include "personPublicationSparklineContent.ftl"></div>
|
||||||
|
|
||||||
|
<#assign sparklineVO = uniqueCoauthorsSparklineVO />
|
||||||
|
<div id="coauthor-count-sparkline-include"><#include "coAuthorshipSparklineContent.ftl"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="vis_stats_full">
|
||||||
|
|
||||||
|
<div class="sub_headings" id="table_heading"><h3>${i18n().tables_capitalized}</h3></div>
|
||||||
|
|
||||||
|
<div class="vis-tables">
|
||||||
|
|
||||||
|
<p id="publications_table_container" class="datatable">
|
||||||
|
|
||||||
|
<#assign tableID = "publication_data_table" />
|
||||||
|
<#assign tableCaption = "${i18n().publications_per_year} " />
|
||||||
|
<#assign tableActivityColumnName = "${i18n().publications_capitalized}" />
|
||||||
|
<#assign tableContent = egoPubSparklineVO.yearToActivityCount />
|
||||||
|
<#assign fileDownloadLink = egoPubSparklineVO.downloadDataLink />
|
||||||
|
|
||||||
|
<#include "yearToActivityCountTable.ftl">
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<#if (numOfCoAuthorShips?? && numOfCoAuthorShips > 0) >
|
||||||
|
|
||||||
|
<div class="vis-tables">
|
||||||
|
<p id="coauth_table_container" class="datatable">
|
||||||
|
<#assign tableID = "coauthorships_table" />
|
||||||
|
<#assign tableCaption = "${i18n().co_authors_capitalized} " />
|
||||||
|
<#assign tableCollaboratorColumnName = "${i18n().author_capitalized}" />
|
||||||
|
<#assign tableActivityColumnName = "${i18n().publications_with}" />
|
||||||
|
<#assign tableContent = coAuthorshipData />
|
||||||
|
<#assign fileDownloadLink = uniqueCoauthorsSparklineVO.downloadDataLink />
|
||||||
|
|
||||||
|
<#include "collaboratorToActivityCountTable.ftl">
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<div style="clear:both"></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div id="chord-info-div" style="display: none;"></div>
|
|
@ -0,0 +1,359 @@
|
||||||
|
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||||
|
|
||||||
|
<#assign standardVisualizationURLRoot ="/visualization">
|
||||||
|
<#assign shortVisualizationURLRoot ="/vis">
|
||||||
|
<#assign ajaxVisualizationURLRoot ="/visualizationAjax">
|
||||||
|
<#assign dataVisualizationURLRoot ="/visualizationData">
|
||||||
|
|
||||||
|
<#assign egoURI ="${egoURIParam?url}">
|
||||||
|
<#assign egoCoInvestigationDataFeederURL = '${urls.base}${dataVisualizationURLRoot}?vis=coprincipalinvestigator&uri=${egoURI}&vis_mode=copi_network_stream&labelField=label'>
|
||||||
|
|
||||||
|
<#assign coauthorshipURL = '${urls.base}${shortVisualizationURLRoot}/author-network/?uri=${egoURI}'>
|
||||||
|
|
||||||
|
<#if egoLocalName?has_content >
|
||||||
|
<#assign coauthorshipURL = '${urls.base}${shortVisualizationURLRoot}/author-network/${egoLocalName}'>
|
||||||
|
<#else>
|
||||||
|
<#assign coauthorshipURL = '${urls.base}${shortVisualizationURLRoot}/author-network/?uri=${egoURI}'>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#assign egoCoInvestigatorsListDataFileURL = '${urls.base}${dataVisualizationURLRoot}?vis=coprincipalinvestigator&uri=${egoURI}&vis_mode=copis'>
|
||||||
|
<#assign egoCoInvestigationNetworkDataFileURL = '${urls.base}${dataVisualizationURLRoot}?vis=coprincipalinvestigator&uri=${egoURI}&vis_mode=copi_network_download'>
|
||||||
|
|
||||||
|
<#assign coAuthorIcon = '${urls.images}/visualization/coauthorship/co_author_icon.png'>
|
||||||
|
|
||||||
|
<#assign googleVisualizationAPI = 'https://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22areachart%22%2C%22imagesparkline%22%5D%7D%5D%7D'>
|
||||||
|
<#assign coInvestigatorPersonLevelJavaScript = '${urls.base}/js/visualization/coPIship/coPIship-person-level.js'>
|
||||||
|
<#assign commonPersonLevelJavaScript = '${urls.base}/js/visualization/personlevel/person-level.js'>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="${googleVisualizationAPI}"></script>
|
||||||
|
|
||||||
|
<script language="JavaScript" type="text/javascript">
|
||||||
|
<!--
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Globals
|
||||||
|
var egoURI = "${egoURI}";
|
||||||
|
var unEncodedEgoURI = "${egoURIParam}";
|
||||||
|
var egoCoInvestigationDataFeederURL = "${egoCoInvestigationDataFeederURL}";
|
||||||
|
var egoCoInvestigatorsListDataFileURL = "${egoCoInvestigatorsListDataFileURL}";
|
||||||
|
|
||||||
|
var contextPath = "${urls.base}";
|
||||||
|
|
||||||
|
var visualizationDataRoot = "${dataVisualizationURLRoot}";
|
||||||
|
|
||||||
|
// -->
|
||||||
|
var i18nStringsCoPi = {
|
||||||
|
coInvestigatorString: '${i18n().co_inestigators_capitalized}',
|
||||||
|
investigatorString: '${i18n().investigator_capitalized}',
|
||||||
|
grantsWithString: '${i18n().grants_with}',
|
||||||
|
grantsCapitalized: '${i18n().grant_s_capitalized}',
|
||||||
|
coInvestigatorCapitalized: '${i18n().co_investigator_s_capitalized}'
|
||||||
|
};
|
||||||
|
var i18nStringsPersonLvl = {
|
||||||
|
fileCapitalized: '${i18n().file_capitalized}',
|
||||||
|
contentRequiresFlash: '${i18n().content_requires_flash}',
|
||||||
|
getFlashString: '${i18n().get_flash}'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="${coInvestigatorPersonLevelJavaScript}"></script>
|
||||||
|
<script type="text/javascript" src="${commonPersonLevelJavaScript}"></script>
|
||||||
|
|
||||||
|
${scripts.add('<script type="text/javascript" src="${urls.base}/js/visualization/visualization-helper-functions.js"></script>')}
|
||||||
|
${scripts.add('<script type="text/javascript" src="${urls.base}/js/d3.min.js"></script>')}
|
||||||
|
|
||||||
|
${stylesheets.add('<link rel="stylesheet" type="text/css" href="${urls.base}/css/visualization/personlevel/page.css" />',
|
||||||
|
'<link rel="stylesheet" type="text/css" href="${urls.base}/css/visualization/visualization.css" />')}
|
||||||
|
|
||||||
|
<#assign loadingImageLink = "${urls.images}/visualization/ajax-loader.gif">
|
||||||
|
|
||||||
|
<#assign egoVivoProfileURL = "${urls.base}/individual?uri=${egoURI}" />
|
||||||
|
|
||||||
|
<script language="JavaScript" type="text/javascript">
|
||||||
|
|
||||||
|
$(document).ready(function(){
|
||||||
|
|
||||||
|
processProfileInformation("ego_label",
|
||||||
|
"ego_moniker",
|
||||||
|
"ego_profile_image",
|
||||||
|
jQuery.parseJSON(getWellFormedURLs("${egoURIParam}", "profile_info")));
|
||||||
|
|
||||||
|
<#if (numOfCoInvestigations?? && numOfCoInvestigations <= 0) || (numOfInvestigators?? && numOfInvestigators <= 0) >
|
||||||
|
if ($('#ego_label').text().length > 0) {
|
||||||
|
setProfileName('no_coinvestigations_person', $('#ego_label').text());
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "${urls.base}/visualizationAjax",
|
||||||
|
data: ({vis: "utilities", vis_mode: "SHOW_AUTHORSHIP_LINK", uri: '${egoURIParam}'}),
|
||||||
|
dataType: "json",
|
||||||
|
success:function(data){
|
||||||
|
|
||||||
|
/*
|
||||||
|
Collaboratorship links do not show up by default. They should show up only if there any data to
|
||||||
|
show on that page.
|
||||||
|
*/
|
||||||
|
if (data.numOfPublications !== undefined && data.numOfPublications > 0) {
|
||||||
|
$(".toggle_visualization").show();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// RENDER CHORD
|
||||||
|
|
||||||
|
var labels = [];
|
||||||
|
var uris = [];
|
||||||
|
var matrix = [];
|
||||||
|
|
||||||
|
var matrixX = 0;
|
||||||
|
<#list coInvestigatorData.collaborationMatrix as row>
|
||||||
|
matrix[matrixX] = [];
|
||||||
|
<#list row as cell>
|
||||||
|
matrix[matrixX].push(${cell?c});
|
||||||
|
</#list>
|
||||||
|
matrixX++;
|
||||||
|
</#list>
|
||||||
|
<#list coInvestigatorData.collaborators as collaborator>
|
||||||
|
labels.push("${collaborator.collaboratorName}");
|
||||||
|
uris.push("${collaborator.collaboratorURI}");
|
||||||
|
</#list>
|
||||||
|
|
||||||
|
var chord = d3.layout.chord()
|
||||||
|
.padding(0.05)
|
||||||
|
.sortSubgroups(d3.descending)
|
||||||
|
.matrix(matrix);
|
||||||
|
|
||||||
|
var width = 725;
|
||||||
|
var height = 725;
|
||||||
|
var padding = 175;
|
||||||
|
var inner_radius = Math.min(width, height) * 0.37;
|
||||||
|
var outer_radius = Math.min(width, height) * 0.39;
|
||||||
|
|
||||||
|
var fill = d3.scale.category10();
|
||||||
|
|
||||||
|
var svg = d3.select('#chord').append('svg')
|
||||||
|
.attr('width', width+padding)
|
||||||
|
.attr('height', height+padding)
|
||||||
|
.append('g').attr('transform', 'translate(' + (width+padding) / 2 + ',' + (height+padding) / 2 +')');
|
||||||
|
|
||||||
|
svg.append('g').selectAll('path').data(chord.groups).enter()
|
||||||
|
.append('path').style('fill', function(val) { return val.index == 0 ? "#000000" : fill(val.index); })
|
||||||
|
.style('stroke', function(val) { return val.index == 0 ? "#000000" : fill(val.index); })
|
||||||
|
.attr('d', d3.svg.arc().innerRadius(inner_radius).outerRadius(outer_radius))
|
||||||
|
.on('click', chord_click())
|
||||||
|
.on("mouseover", chord_hover(.05))
|
||||||
|
.on("mouseout", chord_hover(.8));
|
||||||
|
|
||||||
|
var group_ticks = function (d) {
|
||||||
|
var k = (d.endAngle - d.startAngle) / d.value;
|
||||||
|
return d3.range(d.value / 2, d.value, d.value / 2).map(function (v) {
|
||||||
|
return {
|
||||||
|
angle: v * k + d.startAngle,
|
||||||
|
label: Math.round(d.value)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var chord_ticks = svg.append('g')
|
||||||
|
.selectAll('g')
|
||||||
|
.data(chord.groups)
|
||||||
|
.enter().append('g')
|
||||||
|
.selectAll('g')
|
||||||
|
.data(group_ticks)
|
||||||
|
.enter().append('g')
|
||||||
|
.attr('transform', function (d) {
|
||||||
|
return 'rotate(' + (d.angle * 180 / Math.PI - 90) + ') translate(' + outer_radius + ',0)';
|
||||||
|
});
|
||||||
|
|
||||||
|
svg.append('g')
|
||||||
|
.attr('class', 'chord')
|
||||||
|
.selectAll('path')
|
||||||
|
.data(chord.chords)
|
||||||
|
.enter().append('path')
|
||||||
|
.style('fill', function (d) { return fill(d.target.index); })
|
||||||
|
.attr('d', d3.svg.chord().radius(inner_radius))
|
||||||
|
.style('opacity', .8);
|
||||||
|
|
||||||
|
svg.append("g").selectAll(".arc")
|
||||||
|
.data(chord.groups)
|
||||||
|
.enter().append("svg:text")
|
||||||
|
.attr("dy", ".35em")
|
||||||
|
.attr("style", function(d) { return d.index == 0 ? "font-size: .75em; font-weight: bold;" : "font-size: .70em;"; } )
|
||||||
|
.attr("text-anchor", function(d) { return ((d.startAngle + d.endAngle) / 2) > Math.PI ? "end" : null; })
|
||||||
|
.attr("transform", function(d) {
|
||||||
|
return "rotate(" + (((d.startAngle + d.endAngle) / 2) * 180 / Math.PI - 90) + ")"
|
||||||
|
+ "translate(" + (height *.40) + ")"
|
||||||
|
+ (((d.startAngle + d.endAngle) / 2) > Math.PI ? "rotate(180)" : "");
|
||||||
|
})
|
||||||
|
.text(function(d) {
|
||||||
|
return labels[d.index];
|
||||||
|
})
|
||||||
|
.on('click', chord_click())
|
||||||
|
.on("mouseover", chord_hover(.05))
|
||||||
|
.on("mouseout", chord_hover(.8));
|
||||||
|
|
||||||
|
function chord_hover(opacity) {
|
||||||
|
return function(g, i) {
|
||||||
|
if (opacity > .5) {
|
||||||
|
var chordInfoDiv = d3.select('#chord-info-div');
|
||||||
|
chordInfoDiv.style('display', 'none');
|
||||||
|
} else {
|
||||||
|
var hoverEvent = d3.event;
|
||||||
|
var topPos = hoverEvent.pageY - 60;
|
||||||
|
var leftPos = hoverEvent.pageX + 10;
|
||||||
|
|
||||||
|
var chord = d3.select('#chord').node();
|
||||||
|
var chordInfoDiv = d3.select('#chord-info-div');
|
||||||
|
var hoverMsg = labels[i] + "<br/>";
|
||||||
|
if (i > 0) {
|
||||||
|
hoverMsg += matrix[i][0] + " Joint ${i18n().grant_s_capitalized}<br/>";
|
||||||
|
} else {
|
||||||
|
hoverMsg += "${coInvestigatorData.collaboratorsCount} ${i18n().co_investigator_s_capitalized}<br/>";
|
||||||
|
}
|
||||||
|
|
||||||
|
chordInfoDiv.html(hoverMsg);
|
||||||
|
chordInfoDiv.style('display', 'block');
|
||||||
|
chordInfoDiv.style('position', 'absolute');
|
||||||
|
|
||||||
|
if (d3.mouse(chord)[1] > height / 2) {
|
||||||
|
topPos += 80;
|
||||||
|
}
|
||||||
|
chordInfoDiv.style('top', topPos + 'px');
|
||||||
|
|
||||||
|
if (hoverEvent.pageX > document.body.clientWidth / 2) {
|
||||||
|
leftPos = hoverEvent.pageX + 10;
|
||||||
|
} else {
|
||||||
|
leftPos = hoverEvent.pageX - (10 + chordInfoDiv.node().getBoundingClientRect().width);
|
||||||
|
}
|
||||||
|
chordInfoDiv.style('left', leftPos + 'px');
|
||||||
|
}
|
||||||
|
|
||||||
|
svg.selectAll(".chord path")
|
||||||
|
.filter(function(d) { return d.source.index != i && d.target.index != i; })
|
||||||
|
.transition()
|
||||||
|
.style("opacity", opacity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function chord_click() {
|
||||||
|
return function (g, i) {
|
||||||
|
if (i > 0) {
|
||||||
|
window.location.href = getWellFormedURLs(uris[i], "profile");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="body">
|
||||||
|
<div class="sub_headings"><h2><a href="${egoVivoProfileURL}" title="${i18n().investigator_name}"><span id="ego_label"></span></a><br />${i18n().co_investigator_network_capitalized} </h2></div>
|
||||||
|
|
||||||
|
<#if (numOfInvestigators?? && numOfInvestigators > 0) >
|
||||||
|
|
||||||
|
<#if (numOfCoInvestigations?? && numOfCoInvestigations > 0) || (numOfInvestigators?? && numOfInvestigators > 0) >
|
||||||
|
<div class = "graphml-file-link"><a href="${egoCoInvestigationNetworkDataFileURL}" title="${i18n().co_investigator}">(GraphML ${i18n().file_capitalized})</a></div>
|
||||||
|
<#else>
|
||||||
|
|
||||||
|
<#if numOfInvestigators?? && numOfInvestigators <= 0 >
|
||||||
|
<#assign investigatorsText = "multi-investigator" />
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<span id="no_coinvestigations">${i18n().currently_no_grants_for(investigatorsText!)}
|
||||||
|
<a href="${egoVivoProfileURL}" title="${i18n().investigator_name}"><span id="no_coinvestigations_person" class="investigator_name">${i18n().this_investigator}</span></a> ${i18n().in_the_vivo_db}
|
||||||
|
</span>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#else>
|
||||||
|
|
||||||
|
<span id="no_coinvestigations">${i18n().no_grants_for}
|
||||||
|
<a href="${egoVivoProfileURL}" title="${i18n().co_investigator}"><span id="no_coinvestigations_person" class="investigator_name">${i18n().this_investigator}</span></a> ${i18n().in_the_vivo_db}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<div class = "toggle_visualization">
|
||||||
|
<div id="coauthorship_link_container" class="collaboratorship-link-container">
|
||||||
|
<div class="collaboratorship-icon"><a href="${coauthorshipURL}" title="${i18n().co_author}"><img src="${coAuthorIcon}" alt="${i18n().co_author_icon}"/></a></div>
|
||||||
|
<div class="collaboratorship-link">
|
||||||
|
<h3><a href="${coauthorshipURL}" title="${i18n().co_author_network}">${i18n().co_author_network}</a></h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="clear:both;"></div>
|
||||||
|
|
||||||
|
|
||||||
|
<#if (numOfCoInvestigations?? && numOfCoInvestigations > 0) || (numOfInvestigators?? && numOfInvestigators > 0) >
|
||||||
|
|
||||||
|
<div id="bodyPannel">
|
||||||
|
<div id="chord" style="float: right;"></div>
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
|
||||||
|
<#if (numOfInvestigators?? && numOfInvestigators > 0) >
|
||||||
|
|
||||||
|
<#-- Sparkline -->
|
||||||
|
<div id="sparkline-container-full">
|
||||||
|
|
||||||
|
<#assign displayTable = false />
|
||||||
|
|
||||||
|
<#assign sparklineVO = egoGrantSparklineVO />
|
||||||
|
<div id="grant-count-sparkline-include"><#include "personGrantSparklineContent.ftl"></div>
|
||||||
|
|
||||||
|
<#assign sparklineVO = uniqueCoInvestigatorsSparklineVO />
|
||||||
|
<div id="coinvestigator-count-sparkline-include"><#include "coInvestigationSparklineContent.ftl"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="vis_stats_full">
|
||||||
|
|
||||||
|
<div class="sub_headings" id="table_heading"><h3>${i18n().tables_capitalized}</h3></div>
|
||||||
|
<p style="float:left;font-size:.9em">${i18n().grant_info_for_all_years} <img class="filterInfoIcon" width="16px" height="16px" id="imageIconThree" src="${urls.images}/iconInfo.png" alt="${i18n().info_icon}" title="${i18n().grant_sparkline_note}" /></p>
|
||||||
|
|
||||||
|
<div style="clear:both"></div>
|
||||||
|
|
||||||
|
<div class="vis-tables">
|
||||||
|
|
||||||
|
<p id="grants_table_container" class="datatable">
|
||||||
|
|
||||||
|
<#assign tableID = "grant_data_table" />
|
||||||
|
<#assign tableCaption = "${i18n().grants_per_year}" />
|
||||||
|
<#assign tableActivityColumnName = "${i18n().grants_capitalized}" />
|
||||||
|
<#assign tableContent = egoGrantSparklineVO.yearToActivityCount />
|
||||||
|
<#assign fileDownloadLink = egoGrantSparklineVO.downloadDataLink />
|
||||||
|
|
||||||
|
<#include "yearToActivityCountTable.ftl">
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<#if (numOfCoInvestigations?? && numOfCoInvestigations > 0) >
|
||||||
|
|
||||||
|
<div class="vis-tables">
|
||||||
|
|
||||||
|
<p id="coinve_table_container" class="datatable">
|
||||||
|
<#assign tableID = "coinvestigations_table" />
|
||||||
|
<#assign tableCaption = "${i18n().co_investigator_s_capitalized} " />
|
||||||
|
<#assign tableCollaboratorColumnName = "${i18n().investigator_capitalized}" />
|
||||||
|
<#assign tableActivityColumnName = "${i18n().grants_with}" />
|
||||||
|
<#assign tableContent = coInvestigatorData />
|
||||||
|
<#assign fileDownloadLink = uniqueCoInvestigatorsSparklineVO.downloadDataLink />
|
||||||
|
|
||||||
|
<#include "collaboratorToActivityCountTable.ftl">
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<div style="clear:both"></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div id="chord-info-div" style="display: none;"></div>
|
|
@ -15,6 +15,23 @@
|
||||||
<div class="staticPageBackground">
|
<div class="staticPageBackground">
|
||||||
<div id="${visContainerID}">
|
<div id="${visContainerID}">
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
<#if sparklineVO.shortVisMode>
|
||||||
|
var visualizationOptions = {
|
||||||
|
width: 150,
|
||||||
|
height: 60,
|
||||||
|
color: '3399CC',
|
||||||
|
chartType: 'ls',
|
||||||
|
chartLabel: 'r'
|
||||||
|
};
|
||||||
|
<#else>
|
||||||
|
var visualizationOptions = {
|
||||||
|
width: 250,
|
||||||
|
height: 75,
|
||||||
|
color: '3399CC',
|
||||||
|
chartType: 'ls',
|
||||||
|
chartLabel: 'r'
|
||||||
|
};
|
||||||
|
</#if>
|
||||||
|
|
||||||
function drawPubCountVisualization(providedSparklineImgTD) {
|
function drawPubCountVisualization(providedSparklineImgTD) {
|
||||||
|
|
||||||
|
@ -50,21 +67,8 @@
|
||||||
maxValue: '${sparklineVO.latestRenderedPublicationYear?c}'
|
maxValue: '${sparklineVO.latestRenderedPublicationYear?c}'
|
||||||
}]));
|
}]));
|
||||||
|
|
||||||
var visualizationOptions = {
|
|
||||||
width: 150,
|
|
||||||
height: 60,
|
|
||||||
color: '3399CC',
|
|
||||||
chartType: 'ls',
|
|
||||||
chartLabel: 'r'
|
|
||||||
}
|
|
||||||
<#else>
|
<#else>
|
||||||
var visualizationOptions = {
|
|
||||||
width: 250,
|
|
||||||
height: 75,
|
|
||||||
color: '3399CC',
|
|
||||||
chartType: 'ls',
|
|
||||||
chartLabel: 'r'
|
|
||||||
}
|
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
|
|
||||||
|
@ -247,7 +251,7 @@
|
||||||
var row = $('<tr>');
|
var row = $('<tr>');
|
||||||
sparklineImgTD = $('<td>');
|
sparklineImgTD = $('<td>');
|
||||||
sparklineImgTD.attr('id', '${sparklineContainerID}_img');
|
sparklineImgTD.attr('id', '${sparklineContainerID}_img');
|
||||||
sparklineImgTD.attr('width', '150');
|
sparklineImgTD.attr('width', visualizationOptions.width);
|
||||||
sparklineImgTD.attr('class', 'sparkline_style');
|
sparklineImgTD.attr('class', 'sparkline_style');
|
||||||
|
|
||||||
row.append(sparklineImgTD);
|
row.append(sparklineImgTD);
|
||||||
|
|
|
@ -5,7 +5,10 @@ package edu.cornell.mannlib.vitro.webapp.visualization.personlevel;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
import edu.cornell.mannlib.vitro.webapp.visualization.collaborationutils.CoAuthorshipData;
|
import edu.cornell.mannlib.vitro.webapp.visualization.collaborationutils.CoAuthorshipData;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.CollaborationDataViewHelper;
|
||||||
|
import org.apache.axis.utils.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
import com.hp.hpl.jena.query.Dataset;
|
import com.hp.hpl.jena.query.Dataset;
|
||||||
|
@ -239,7 +242,13 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
|
||||||
|
|
||||||
String standaloneTemplate = "coAuthorPersonLevel.ftl";
|
String standaloneTemplate = "coAuthorPersonLevel.ftl";
|
||||||
|
|
||||||
body.put("egoURIParam", egoURI);
|
String property = ConfigurationProperties.getBean(vitroRequest).getProperty("visualization.d3");
|
||||||
|
if ("enabled".equalsIgnoreCase(property)) {
|
||||||
|
body.put("coAuthorshipData", new CollaborationDataViewHelper(coAuthorshipVO));
|
||||||
|
standaloneTemplate = "coAuthorPersonLevelD3.ftl";
|
||||||
|
}
|
||||||
|
|
||||||
|
body.put("egoURIParam", egoURI);
|
||||||
|
|
||||||
body.put("egoLocalName", UtilityFunctions.getIndividualLocalName(egoURI, vitroRequest));
|
body.put("egoLocalName", UtilityFunctions.getIndividualLocalName(egoURI, vitroRequest));
|
||||||
|
|
||||||
|
@ -291,6 +300,12 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
|
||||||
|
|
||||||
String standaloneTemplate = "coPIPersonLevel.ftl";
|
String standaloneTemplate = "coPIPersonLevel.ftl";
|
||||||
|
|
||||||
|
String property = ConfigurationProperties.getBean(vitroRequest).getProperty("visualization.d3");
|
||||||
|
if ("enabled".equalsIgnoreCase(property)) {
|
||||||
|
body.put("coInvestigatorData", new CollaborationDataViewHelper(coPIVO));
|
||||||
|
standaloneTemplate = "coPIPersonLevelD3.ftl";
|
||||||
|
}
|
||||||
|
|
||||||
body.put("egoGrantSparklineVO", egoGrantSparklineVO);
|
body.put("egoGrantSparklineVO", egoGrantSparklineVO);
|
||||||
body.put("uniqueCoInvestigatorsSparklineVO", uniqueCopisSparklineVO);
|
body.put("uniqueCoInvestigatorsSparklineVO", uniqueCopisSparklineVO);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.visutils;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.collaborationutils.CollaborationData;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Collaboration;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Collaborator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CollaborationDataViewHelper {
|
||||||
|
private static final int MAX_COLLABORATORS = 35;
|
||||||
|
private CollaborationData data;
|
||||||
|
|
||||||
|
private List<Collaborator> collaborators = null;
|
||||||
|
|
||||||
|
private int[][] collaborationMatrix = null;
|
||||||
|
|
||||||
|
public CollaborationDataViewHelper(CollaborationData data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCollaboratorsCount() {
|
||||||
|
init(MAX_COLLABORATORS);
|
||||||
|
return data.getCollaborators().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[][] getCollaborationMatrix() {
|
||||||
|
init(MAX_COLLABORATORS);
|
||||||
|
return collaborationMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Collaborator> getCollaborators() {
|
||||||
|
init(MAX_COLLABORATORS);
|
||||||
|
return collaborators;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void init(int max) {
|
||||||
|
if (collaborators != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
collaborators = new ArrayList<>(max);
|
||||||
|
|
||||||
|
// Find the top N collaborators
|
||||||
|
|
||||||
|
// Threshold is the lowest number of activities currently in the table
|
||||||
|
// Start at maximum possible value
|
||||||
|
int threshold = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
// Iterate through each collaborator
|
||||||
|
for (Collaborator collaborator : data.getCollaborators()) {
|
||||||
|
|
||||||
|
// Only include the collaborator if it isn't the focus of the view
|
||||||
|
if (collaborator.getCollaboratorID() != data.getEgoCollaborator().getCollaboratorID()) {
|
||||||
|
|
||||||
|
// If the number of activities exceeds the threshold, it needs to be included in the top N
|
||||||
|
if (collaborator.getNumOfActivities() > threshold) {
|
||||||
|
// If we've filled the Top N
|
||||||
|
if (collaborators.size() == max - 1) {
|
||||||
|
// Remove the last (lowest) entry of the Top N
|
||||||
|
collaborators.remove(collaborators.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the place to insert the new entry
|
||||||
|
int insert = collaborators.size();
|
||||||
|
while (insert > 0) {
|
||||||
|
insert--;
|
||||||
|
if (collaborators.get(insert).getNumOfActivities() > collaborator.getNumOfActivities()) {
|
||||||
|
insert++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (insert < 0) {
|
||||||
|
// If we didn't find a place to insert, insert it at the start
|
||||||
|
collaborators.add(0, collaborator);
|
||||||
|
} else if (insert < collaborators.size()) {
|
||||||
|
// If the insert position is before the end of the list, insert at that position
|
||||||
|
collaborators.add(insert, collaborator);
|
||||||
|
} else {
|
||||||
|
// Otherwise, add to the end of the list
|
||||||
|
collaborators.add(collaborator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the threshold with the new lowest position entry
|
||||||
|
threshold = collaborators.get(collaborators.size() - 1).getNumOfActivities();
|
||||||
|
} else {
|
||||||
|
// If we are below the threshold, check if the top N is full
|
||||||
|
if (collaborators.size() < max - 1) {
|
||||||
|
// Top N is incomplete, so add to the end of the list
|
||||||
|
collaborators.add(collaborator);
|
||||||
|
|
||||||
|
// And record the new collaboration as the threshold
|
||||||
|
threshold = collaborator.getNumOfActivities();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now add the person that is the focus to the start of the list
|
||||||
|
collaborators.add(0, data.getEgoCollaborator());
|
||||||
|
|
||||||
|
// Generate a list of collaborator IDs for use in filling the matrix
|
||||||
|
List<Integer> collabIDs = new ArrayList<Integer>(collaborators.size());
|
||||||
|
for (Collaborator collaborator : collaborators) {
|
||||||
|
collabIDs.add(collaborator.getCollaboratorID());
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we only want to visualize collaborations between the main focus and others, set this to false
|
||||||
|
boolean fullMatrix = true;
|
||||||
|
|
||||||
|
// Initialise the matrix
|
||||||
|
collaborationMatrix = new int[collaborators.size()][collaborators.size()];
|
||||||
|
|
||||||
|
// For every row in the matrix
|
||||||
|
for (int x = 0; x < collaborators.size(); x++) {
|
||||||
|
// Get the collaborator associated with this row
|
||||||
|
Collaborator collaboratorX = collaborators.get(x);
|
||||||
|
|
||||||
|
// Generate a list of possible collaborations for this row
|
||||||
|
List<Collaboration> possibleCollaborations = new ArrayList<>();
|
||||||
|
|
||||||
|
// Go through all of the collaborations
|
||||||
|
for (Collaboration collaboration : data.getCollaborations()) {
|
||||||
|
// Get the collaborators
|
||||||
|
Collaborator source = collaboration.getSourceCollaborator();
|
||||||
|
Collaborator target = collaboration.getTargetCollaborator();
|
||||||
|
|
||||||
|
// If the collaborator for this row is involved in the collaboration, add it to the list of possibles
|
||||||
|
if (source.getCollaboratorID() == collaboratorX.getCollaboratorID() || target.getCollaboratorID() == collaboratorX.getCollaboratorID()) {
|
||||||
|
possibleCollaborations.add(collaboration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For every column in the matrix
|
||||||
|
for (int y = 0; y < collaborators.size(); y++) {
|
||||||
|
// Get the collaborator associated with this column
|
||||||
|
Collaborator collaboratorY = collaborators.get(y);
|
||||||
|
|
||||||
|
// If this is the first row, first column, or we are creating a full matrix of all collaborations
|
||||||
|
if (x == 0 || y == 0 || fullMatrix) {
|
||||||
|
// Go through all of the possible collaborations
|
||||||
|
for (Collaboration collaboration : possibleCollaborations) {
|
||||||
|
// Get the collaborators
|
||||||
|
Collaborator source = collaboration.getSourceCollaborator();
|
||||||
|
Collaborator target = collaboration.getTargetCollaborator();
|
||||||
|
|
||||||
|
// If the source is the row collaborator and the target is the column collaborator
|
||||||
|
if (source.getCollaboratorID() == collaboratorX.getCollaboratorID() && target.getCollaboratorID() == collaboratorY.getCollaboratorID()) {
|
||||||
|
// Add the number of collaborations to the matrix, and stop processing collaborations
|
||||||
|
collaborationMatrix[x][y] = collaboration.getNumOfCollaborations();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the source is the column collaborator and the target is the row collaborator
|
||||||
|
if (source.getCollaboratorID() == collaboratorY.getCollaboratorID() && target.getCollaboratorID() == collaboratorX.getCollaboratorID()) {
|
||||||
|
// Add the number of collaborations to the matrix, and stop processing collaborations
|
||||||
|
collaborationMatrix[x][y] = collaboration.getNumOfCollaborations();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the activity count for the top left matrix entry (focus - focus collaboration)
|
||||||
|
collaborationMatrix[0][0] = 0;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue