1. Refactored the vis code geenrators for publication, coauthor, coinvestigator, grants sparklines to remove unused code.
2. Changed logic to not to generate link to csv downloads if there is 0 publication/grant for an individual.
This commit is contained in:
parent
4f7d3b8302
commit
c2a0816ec1
10 changed files with 189 additions and 1687 deletions
|
@ -188,7 +188,9 @@
|
|||
sparksText += ' (' + totalPublicationCount + ' total)';
|
||||
}
|
||||
|
||||
if (totalPublicationCount) {
|
||||
sparksText += ' <br /><a href="${sparklineVO.downloadDataLink}">(.CSV File)</a> ';
|
||||
}
|
||||
|
||||
</#if>
|
||||
|
||||
|
|
|
@ -189,7 +189,10 @@
|
|||
sparksText += ' (' + totalGrantCount + ' total)';
|
||||
}
|
||||
|
||||
if (totalGrantCount) {
|
||||
sparksText += '<br /> <a href="${sparklineVO.downloadDataLink}">(.CSV File)</a> ';
|
||||
}
|
||||
|
||||
</#if>
|
||||
|
||||
if (!onlyUnknownYearGrants) {
|
||||
|
|
|
@ -189,8 +189,9 @@
|
|||
sparksText += ' (' + totalGrantCount + ' total)';
|
||||
}
|
||||
|
||||
|
||||
if (totalGrantCount) {
|
||||
sparksText += '<br /> <a href="${sparklineVO.downloadDataLink}" >(.CSV File)</a> ';
|
||||
}
|
||||
|
||||
</#if>
|
||||
|
||||
|
|
|
@ -190,7 +190,10 @@
|
|||
sparksText += ' (' + totalPublicationCount + ' total)';
|
||||
}
|
||||
|
||||
if (totalPublicationCount) {
|
||||
sparksText += ' <br /><a href="${sparklineVO.downloadDataLink}">(.CSV File)</a> ';
|
||||
}
|
||||
|
||||
</#if>
|
||||
|
||||
if (!onlyUnknownYearPublications) {
|
||||
|
|
|
@ -11,21 +11,18 @@ import java.util.List;
|
|||
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.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.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.freemarker.valueobjects.Node;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.SparklineData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.YearToEntityCountDataElement;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class CoAuthorshipVisCodeGenerator {
|
||||
|
||||
/*
|
||||
|
@ -37,22 +34,13 @@ public class CoAuthorshipVisCodeGenerator {
|
|||
* spanning the career of the person & last 10 years at the minimum, in case if
|
||||
* the person started his career in the last 10 yeras.
|
||||
* */
|
||||
private static final Map<String, String> VIS_DIV_NAMES = new HashMap<String, String>() { {
|
||||
|
||||
put("SHORT_SPARK", "unique_coauthors_short_sparkline_vis");
|
||||
put("FULL_SPARK", "unique_coauthors_full_sparkline_vis");
|
||||
|
||||
} };
|
||||
|
||||
private static final String VISUALIZATION_STYLE_CLASS = "sparkline_style";
|
||||
|
||||
private static final String DEFAULT_VISCONTAINER_DIV_ID = "unique_coauthors_vis_container";
|
||||
|
||||
private Map<String, Set<Node>> yearToUniqueCoauthors;
|
||||
|
||||
private Log log;
|
||||
|
||||
private SparklineData sparklineData;
|
||||
private SparklineData sparklineParameterVO;
|
||||
|
||||
private String individualURI;
|
||||
|
||||
|
@ -65,37 +53,23 @@ public class CoAuthorshipVisCodeGenerator {
|
|||
this.individualURI = individualURI;
|
||||
|
||||
this.yearToUniqueCoauthors = yearToUniqueCoauthors;
|
||||
this.sparklineData = new SparklineData();
|
||||
|
||||
this.log = log;
|
||||
|
||||
generateVisualizationCode(visMode, visContainer);
|
||||
this.sparklineParameterVO = setupSparklineParameters(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.
|
||||
* This method is used to setup parameters for the sparkline value object. These parameters
|
||||
* will be used in the template to construct the actual html/javascript code.
|
||||
* @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,
|
||||
private SparklineData setupSparklineParameters(String visMode,
|
||||
String providedVisContainerID) {
|
||||
|
||||
SparklineData sparklineData = new SparklineData();
|
||||
|
||||
int numOfYearsToBeRendered = 0;
|
||||
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
|
||||
int shortSparkMinYear = currentYear
|
||||
|
@ -118,8 +92,6 @@ public class CoAuthorshipVisCodeGenerator {
|
|||
|
||||
String visContainerID = null;
|
||||
|
||||
StringBuilder visualizationCode = new StringBuilder();
|
||||
|
||||
if (yearToUniqueCoauthors.size() > 0) {
|
||||
try {
|
||||
minPublishedYear = Integer.parseInt(Collections.min(publishedYears));
|
||||
|
@ -150,30 +122,6 @@ public class CoAuthorshipVisCodeGenerator {
|
|||
|
||||
sparklineData.setNumOfYearsToBeRendered(numOfYearsToBeRendered);
|
||||
|
||||
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 drawUniqueCoauthorCountVisualization(providedSparklineImgTD) {\n"
|
||||
+ "var data = new google.visualization.DataTable();\n"
|
||||
+ "data.addColumn('string', 'Year');\n"
|
||||
+ "data.addColumn('number', 'Unique co-authors');\n"
|
||||
+ "data.addRows(" + numOfYearsToBeRendered + ");\n");
|
||||
|
||||
int uniqueCoAuthorCounter = 0;
|
||||
int renderedFullSparks = 0;
|
||||
Set<Node> allCoAuthorsWithKnownAuthorshipYears = new HashSet<Node>();
|
||||
|
@ -195,18 +143,6 @@ public class CoAuthorshipVisCodeGenerator {
|
|||
currentUniqueCoAuthors = 0;
|
||||
}
|
||||
|
||||
visualizationCode.append("data.setValue("
|
||||
+ uniqueCoAuthorCounter
|
||||
+ ", 0, '"
|
||||
+ publicationYearAsString
|
||||
+ "');\n");
|
||||
|
||||
visualizationCode.append("data.setValue("
|
||||
+ uniqueCoAuthorCounter
|
||||
+ ", 1, "
|
||||
+ currentUniqueCoAuthors
|
||||
+ ");\n");
|
||||
|
||||
yearToUniqueCoauthorsCountDataTable.add(new YearToEntityCountDataElement(uniqueCoAuthorCounter,
|
||||
publicationYearAsString,
|
||||
currentUniqueCoAuthors));
|
||||
|
@ -238,9 +174,6 @@ public class CoAuthorshipVisCodeGenerator {
|
|||
|
||||
sparklineData.setUnknownYearPublications(unknownYearCoauthors);
|
||||
|
||||
String sparklineDisplayOptions = "{width: 65, height: 30, showAxisLines: false, "
|
||||
+ "showValueLabels: false, labelPosition: 'none'}";
|
||||
|
||||
if (providedVisContainerID != null) {
|
||||
visContainerID = providedVisContainerID;
|
||||
} else {
|
||||
|
@ -262,351 +195,41 @@ public class CoAuthorshipVisCodeGenerator {
|
|||
* 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.setEarliestRenderedPublicationYear(shortSparkMinYear);
|
||||
|
||||
sparklineData.setShortVisMode(true);
|
||||
|
||||
generateShortSparklineVisualizationContent(currentYear,
|
||||
shortSparkMinYear,
|
||||
visContainerID,
|
||||
visualizationCode,
|
||||
unknownYearCoauthors,
|
||||
sparklineDisplayOptions);
|
||||
} else {
|
||||
sparklineData.setShortVisMode(false);
|
||||
|
||||
generateFullSparklineVisualizationContent(currentYear,
|
||||
minPubYearConsidered,
|
||||
visContainerID,
|
||||
visualizationCode,
|
||||
unknownYearCoauthors,
|
||||
renderedFullSparks,
|
||||
sparklineDisplayOptions);
|
||||
}
|
||||
|
||||
log.debug(visualizationCode);
|
||||
|
||||
return visualizationCode.toString();
|
||||
}
|
||||
|
||||
private void generateShortSparklineVisualizationContent(int currentYear,
|
||||
int shortSparkMinYear,
|
||||
String visContainerID,
|
||||
StringBuilder visualizationCode,
|
||||
int unknownYearCoauthors,
|
||||
String sparklineDisplayOptions) {
|
||||
|
||||
/*
|
||||
* Create a view of the data containing only the column pertaining to publication 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 publication 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 publication 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 publications 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(" + unknownYearCoauthors + "));");
|
||||
|
||||
visualizationCode.append("var shortSparksText = ''"
|
||||
+ "+ ' co-author(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
|
||||
* drawUniqueCoauthorCountVisualization function.
|
||||
* */
|
||||
visualizationCode.append(generateVisualizationActivator(VIS_DIV_NAMES.get("SHORT_SPARK"),
|
||||
visContainerID));
|
||||
|
||||
}
|
||||
|
||||
private void generateFullSparklineVisualizationContent(int currentYear,
|
||||
int minPubYearConsidered,
|
||||
String visContainerID,
|
||||
StringBuilder visualizationCode,
|
||||
int unknownYearCoauthors,
|
||||
int renderedFullSparks,
|
||||
String sparklineDisplayOptions) {
|
||||
|
||||
String csvDownloadURLHref = "";
|
||||
|
||||
if (getCSVDownloadURL() != null) {
|
||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL()
|
||||
+ "\" class=\"inline_href\">(.CSV File)</a>";
|
||||
} else {
|
||||
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
|
||||
+ unknownYearCoauthors) + "');");
|
||||
|
||||
visualizationCode.append("var allSparksText = ''"
|
||||
+ "+ ' co-author(s) from '"
|
||||
+ "+ ' <span class=\"sparkline_range\">"
|
||||
+ "" + minPubYearConsidered + " 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', '350');"
|
||||
+ "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
|
||||
+ "}"
|
||||
+ "drawUniqueCoauthorCountVisualization(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 (yearToUniqueCoauthors.size() > 0) {
|
||||
|
||||
if (getCSVDownloadURL() != null) {
|
||||
|
||||
csvDownloadURLHref = "Download data as <a href='"
|
||||
+ getCSVDownloadURL() + "'>.csv</a> file.<br />";
|
||||
sparklineData.setDownloadDataLink(getCSVDownloadURL());
|
||||
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
} else {
|
||||
csvDownloadURLHref = "No data available to export.<br />";
|
||||
}
|
||||
|
||||
String tableCode = generateDataTable();
|
||||
|
||||
divContextCode.append("<p>" + tableCode + csvDownloadURLHref + "</p>");
|
||||
|
||||
sparklineData.setTable(tableCode);
|
||||
sparklineData.setFullTimelineNetworkLink(UtilityFunctions.getCollaboratorshipNetworkLink(individualURI,
|
||||
VisualizationFrameworkConstants.PERSON_LEVEL_VIS,
|
||||
VisualizationFrameworkConstants.COAUTHOR_VIS_MODE));
|
||||
|
||||
sparklineData.setDownloadDataLink(UtilityFunctions
|
||||
.getCSVDownloadURL(
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.COAUTHORSHIP_VIS,
|
||||
VisualizationFrameworkConstants.COAUTHORS_COUNT_PER_YEAR_VIS_MODE));
|
||||
|
||||
Map<String, Integer> yearToUniqueCoauthorsCount = new HashMap<String, Integer>();
|
||||
for (Map.Entry<String, Set<Node>> currentYear : yearToUniqueCoauthors.entrySet()) {
|
||||
yearToUniqueCoauthorsCount.put(currentYear.getKey(), currentYear.getValue().size());
|
||||
|
||||
for (Map.Entry<String, Set<Node>> currentYearToCoAuthors : yearToUniqueCoauthors.entrySet()) {
|
||||
yearToUniqueCoauthorsCount.put(currentYearToCoAuthors.getKey(),
|
||||
currentYearToCoAuthors.getValue().size());
|
||||
}
|
||||
|
||||
sparklineData.setYearToActivityCount(yearToUniqueCoauthorsCount);
|
||||
|
||||
return divContextCode.toString();
|
||||
}
|
||||
|
||||
private String getCSVDownloadURL(){
|
||||
|
||||
if (yearToUniqueCoauthors.size() > 0) {
|
||||
|
||||
ParamMap CSVDownloadURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.VIS_TYPE_KEY,
|
||||
VisualizationFrameworkConstants.COAUTHORSHIP_VIS,
|
||||
VisualizationFrameworkConstants.VIS_MODE_KEY,
|
||||
VisualizationFrameworkConstants.COAUTHORS_COUNT_PER_YEAR_VIS_MODE);
|
||||
|
||||
return UrlBuilder.getUrl(VisualizationFrameworkConstants.DATA_VISUALIZATION_SERVICE_URL_PREFIX,
|
||||
CSVDownloadURLParams);
|
||||
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String generateShortVisContext() {
|
||||
|
||||
StringBuilder divContextCode = new StringBuilder();
|
||||
|
||||
String fullTimelineLink;
|
||||
if (yearToUniqueCoauthors.size() > 0) {
|
||||
|
||||
ParamMap fullTimelineNetworkURLParams = new ParamMap(
|
||||
VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.VIS_TYPE_KEY,
|
||||
VisualizationFrameworkConstants.PERSON_LEVEL_VIS,
|
||||
VisualizationFrameworkConstants.VIS_MODE_KEY,
|
||||
VisualizationFrameworkConstants.COAUTHOR_VIS_MODE);
|
||||
|
||||
String fullTimelineNetworkURL = UrlBuilder.getUrl(
|
||||
VisualizationFrameworkConstants.FREEMARKERIZED_VISUALIZATION_URL_PREFIX,
|
||||
fullTimelineNetworkURLParams);
|
||||
|
||||
fullTimelineLink = "<a href='" + fullTimelineNetworkURL
|
||||
+ "'>View full timeline and co-author network.</a>";
|
||||
|
||||
sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL);
|
||||
|
||||
} else {
|
||||
fullTimelineLink = "No data available to render full timeline.<br />";
|
||||
}
|
||||
|
||||
divContextCode.append("<p>" + fullTimelineLink + "</p>");
|
||||
|
||||
return divContextCode.toString();
|
||||
}
|
||||
|
||||
|
||||
private String generateDataTable() {
|
||||
|
||||
StringBuilder dataTable = new StringBuilder();
|
||||
|
||||
dataTable.append("<table id='sparkline_data_table'>"
|
||||
+ "<caption>Unique Co-Authors per year</caption>"
|
||||
+ "<thead>"
|
||||
+ "<tr>"
|
||||
+ "<th>Year</th>"
|
||||
+ "<th>Count</th>"
|
||||
+ "</tr>"
|
||||
+ "</thead>"
|
||||
+ "<tbody>");
|
||||
|
||||
for (Entry<String, Set<Node>> currentEntry : yearToUniqueCoauthors.entrySet()) {
|
||||
dataTable.append("<tr>"
|
||||
+ "<td>" + currentEntry.getKey() + "</td>"
|
||||
+ "<td>" + currentEntry.getValue().size() + "</td>"
|
||||
+ "</tr>");
|
||||
}
|
||||
|
||||
dataTable.append("</tbody>\n </table>\n");
|
||||
|
||||
return dataTable.toString();
|
||||
return sparklineData;
|
||||
}
|
||||
|
||||
public SparklineData getValueObjectContainer() {
|
||||
return sparklineData;
|
||||
return this.sparklineParameterVO;
|
||||
}
|
||||
}
|
|
@ -9,20 +9,18 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.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.freemarker.valueobjects.CoPINode;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.SparklineData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.YearToEntityCountDataElement;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
|
||||
|
||||
/**
|
||||
* This class contains code for rendering sparklines and displaying tables for
|
||||
|
@ -30,7 +28,6 @@ import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Ye
|
|||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class CoPIVisCodeGenerator {
|
||||
|
||||
/*
|
||||
|
@ -42,22 +39,13 @@ public class CoPIVisCodeGenerator {
|
|||
* 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_coinvestigators_vis_container";
|
||||
|
||||
private Map<String, Set<CoPINode>> yearToUniqueCoPIs;
|
||||
|
||||
private Log log;
|
||||
|
||||
private SparklineData sparklineData;
|
||||
private SparklineData sparklineParameterVO;
|
||||
|
||||
private String individualURI;
|
||||
|
||||
|
@ -70,38 +58,24 @@ public class CoPIVisCodeGenerator {
|
|||
this.individualURI = individualURI;
|
||||
|
||||
this.yearToUniqueCoPIs = yearToUniqueCoPIs;
|
||||
this.sparklineData = new SparklineData();
|
||||
|
||||
this.log = log;
|
||||
|
||||
generateVisualizationCode(visMode, visContainer);
|
||||
this.sparklineParameterVO = setupSparklineParameters(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.
|
||||
*
|
||||
* This method is used to setup parameters for the sparkline value object. These parameters
|
||||
* will be used in the template to construct the actual html/javascript code.
|
||||
* @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,
|
||||
private SparklineData setupSparklineParameters(String visMode,
|
||||
String providedVisContainerID) {
|
||||
|
||||
SparklineData sparklineData = new SparklineData();
|
||||
|
||||
int numOfYearsToBeRendered = 0;
|
||||
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
|
||||
int shortSparkMinYear = currentYear
|
||||
|
@ -126,8 +100,6 @@ public class CoPIVisCodeGenerator {
|
|||
|
||||
String visContainerID = null;
|
||||
|
||||
StringBuilder visualizationCode = new StringBuilder();
|
||||
|
||||
if (yearToUniqueCoPIs.size() > 0) {
|
||||
try {
|
||||
minGrantYear = Integer.parseInt(Collections
|
||||
|
@ -160,24 +132,6 @@ public class CoPIVisCodeGenerator {
|
|||
|
||||
sparklineData.setNumOfYearsToBeRendered(numOfYearsToBeRendered);
|
||||
|
||||
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>();
|
||||
|
@ -198,12 +152,6 @@ public class CoPIVisCodeGenerator {
|
|||
currentUniqueCoPIs = 0;
|
||||
}
|
||||
|
||||
visualizationCode.append("data.setValue(" + uniqueCoPICounter
|
||||
+ ", 0, '" + grantYearAsString + "');\n");
|
||||
|
||||
visualizationCode.append("data.setValue(" + uniqueCoPICounter
|
||||
+ ", 1, " + currentUniqueCoPIs + ");\n");
|
||||
|
||||
yearToUniqueInvestigatorsCountDataTable.add(new YearToEntityCountDataElement(uniqueCoPICounter,
|
||||
grantYearAsString,
|
||||
currentUniqueCoPIs));
|
||||
|
@ -234,9 +182,6 @@ public class CoPIVisCodeGenerator {
|
|||
|
||||
sparklineData.setUnknownYearGrants(unknownYearGrants);
|
||||
|
||||
String sparklineDisplayOptions = "{width: 65, height: 30, showAxisLines: false, "
|
||||
+ "showValueLabels: false, labelPosition: 'none'}";
|
||||
|
||||
if (providedVisContainerID != null) {
|
||||
visContainerID = providedVisContainerID;
|
||||
} else {
|
||||
|
@ -259,348 +204,42 @@ public class CoPIVisCodeGenerator {
|
|||
* 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);
|
||||
|
||||
sparklineData.setShortVisMode(true);
|
||||
|
||||
generateShortSparklineVisualizationContent(currentYear,
|
||||
shortSparkMinYear, visContainerID, visualizationCode,
|
||||
unknownYearGrants, sparklineDisplayOptions);
|
||||
} else {
|
||||
|
||||
sparklineData.setShortVisMode(false);
|
||||
|
||||
generateFullSparklineVisualizationContent(currentYear,
|
||||
minGrantYearConsidered, 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 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 = "";
|
||||
|
||||
if (getCSVDownloadURL() != null) {
|
||||
|
||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL()
|
||||
+ "\" class=\"inline_href\">(.CSV File)</a>";
|
||||
|
||||
} else {
|
||||
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) {
|
||||
|
||||
if (getCSVDownloadURL() != null) {
|
||||
sparklineData.setFullTimelineNetworkLink(UtilityFunctions.getCollaboratorshipNetworkLink(individualURI,
|
||||
VisualizationFrameworkConstants.PERSON_LEVEL_VIS,
|
||||
VisualizationFrameworkConstants.COPI_VIS_MODE));
|
||||
|
||||
csvDownloadURLHref = "Download data as <a href='"
|
||||
+ getCSVDownloadURL() + "'>.csv</a> file.<br />";
|
||||
sparklineData.setDownloadDataLink(getCSVDownloadURL());
|
||||
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
} else {
|
||||
csvDownloadURLHref = "No data available to export.<br />";
|
||||
}
|
||||
|
||||
String tableCode = generateDataTable();
|
||||
|
||||
divContextCode.append("<p>" + tableCode + csvDownloadURLHref + "</p>");
|
||||
|
||||
sparklineData.setTable(tableCode);
|
||||
sparklineData.setDownloadDataLink(UtilityFunctions
|
||||
.getCSVDownloadURL(
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.CO_PI_VIS,
|
||||
VisualizationFrameworkConstants.COPIS_COUNT_PER_YEAR_VIS_MODE));
|
||||
|
||||
Map<String, Integer> yearToUniqueCoPIsCount = new HashMap<String, Integer>();
|
||||
for (Map.Entry<String, Set<CoPINode>> currentYear : yearToUniqueCoPIs.entrySet()) {
|
||||
yearToUniqueCoPIsCount.put(currentYear.getKey(), currentYear.getValue().size());
|
||||
for (Map.Entry<String, Set<CoPINode>> currentYearToUniqueCoPIsCount : yearToUniqueCoPIs.entrySet()) {
|
||||
yearToUniqueCoPIsCount.put(currentYearToUniqueCoPIsCount.getKey(),
|
||||
currentYearToUniqueCoPIsCount.getValue().size());
|
||||
}
|
||||
|
||||
sparklineData.setYearToActivityCount(yearToUniqueCoPIsCount);
|
||||
|
||||
return divContextCode.toString();
|
||||
}
|
||||
|
||||
private String getCSVDownloadURL() {
|
||||
|
||||
if (yearToUniqueCoPIs.size() > 0) {
|
||||
|
||||
ParamMap CSVDownloadURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.VIS_TYPE_KEY,
|
||||
VisualizationFrameworkConstants.CO_PI_VIS,
|
||||
VisualizationFrameworkConstants.VIS_MODE_KEY,
|
||||
VisualizationFrameworkConstants.COPIS_COUNT_PER_YEAR_VIS_MODE);
|
||||
|
||||
return UrlBuilder.getUrl(VisualizationFrameworkConstants.DATA_VISUALIZATION_SERVICE_URL_PREFIX,
|
||||
CSVDownloadURLParams);
|
||||
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private String generateShortVisContext() {
|
||||
|
||||
StringBuilder divContextCode = new StringBuilder();
|
||||
|
||||
String fullTimelineLink;
|
||||
if (yearToUniqueCoPIs.size() > 0) {
|
||||
|
||||
ParamMap fullTimelineNetworkURLParams = new ParamMap(
|
||||
VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.VIS_TYPE_KEY,
|
||||
VisualizationFrameworkConstants.PERSON_LEVEL_VIS,
|
||||
VisualizationFrameworkConstants.VIS_MODE_KEY,
|
||||
VisualizationFrameworkConstants.COPI_VIS_MODE);
|
||||
|
||||
String fullTimelineNetworkURL = UrlBuilder.getUrl(
|
||||
VisualizationFrameworkConstants.FREEMARKERIZED_VISUALIZATION_URL_PREFIX,
|
||||
fullTimelineNetworkURLParams);
|
||||
|
||||
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>");
|
||||
|
||||
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();
|
||||
return sparklineData;
|
||||
}
|
||||
|
||||
public SparklineData getValueObjectContainer() {
|
||||
return sparklineData;
|
||||
return this.sparklineParameterVO;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,27 +5,23 @@ package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.persongrantcou
|
|||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.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.freemarker.valueobjects.Grant;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.SparklineData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.YearToEntityCountDataElement;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class PersonGrantCountVisCodeGenerator {
|
||||
|
||||
/*
|
||||
|
@ -38,22 +34,13 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
* the person started his career in the last 10 yeras.
|
||||
* */
|
||||
|
||||
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 SparklineData sparklineParameterVO;
|
||||
|
||||
private String individualURI;
|
||||
|
||||
|
@ -65,42 +52,27 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
this.individualURI = individualURIParam;
|
||||
|
||||
this.yearToGrantCount = yearToGrantCount;
|
||||
this.sparklineData = new SparklineData();
|
||||
|
||||
sparklineData.setYearToActivityCount(yearToGrantCount);
|
||||
|
||||
this.log = log;
|
||||
|
||||
generateVisualizationCode(visMode, visContainer, piGrants);
|
||||
this.sparklineParameterVO = setupSparklineParameters(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.
|
||||
* This method is used to setup parameters for the sparkline value object. These parameters
|
||||
* will be used in the template to construct the actual html/javascript code.
|
||||
* @param visMode
|
||||
* @param visContainer
|
||||
* @param piGrants
|
||||
* @param authorDocuments
|
||||
* @return
|
||||
*/
|
||||
private void generateVisualizationCode(String visMode,
|
||||
String visContainer,
|
||||
private SparklineData setupSparklineParameters(String visMode,
|
||||
String providedVisContainerID,
|
||||
Set<Grant> piGrants) {
|
||||
|
||||
sparklineData.setSparklineContent(getMainVisualizationCode(piGrants,
|
||||
visMode,
|
||||
visContainer));
|
||||
|
||||
|
||||
sparklineData.setSparklineContext(getVisualizationContextCode(visMode));
|
||||
|
||||
}
|
||||
|
||||
private String getMainVisualizationCode(Set<Grant> piGrants,
|
||||
String visMode, String providedVisContainerID) {
|
||||
SparklineData sparklineData = new SparklineData();
|
||||
sparklineData.setYearToActivityCount(yearToGrantCount);
|
||||
|
||||
int numOfYearsToBeRendered = 0;
|
||||
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
|
||||
|
@ -112,8 +84,7 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
* the vis was rendered we dont want to be influenced by the
|
||||
* "DEFAULT_GRANT_YEAR".
|
||||
*/
|
||||
Set<String> grantYears = new HashSet<String>(yearToGrantCount
|
||||
.keySet());
|
||||
Set<String> grantYears = new HashSet<String>(yearToGrantCount.keySet());
|
||||
grantYears.remove(VOConstants.DEFAULT_GRANT_YEAR);
|
||||
|
||||
/*
|
||||
|
@ -126,8 +97,6 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
|
||||
String visContainerID = null;
|
||||
|
||||
StringBuilder visualizationCode = new StringBuilder();
|
||||
|
||||
if (yearToGrantCount.size() > 0) {
|
||||
try {
|
||||
minGrantYear = Integer.parseInt(Collections
|
||||
|
@ -160,26 +129,6 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
|
||||
sparklineData.setNumOfYearsToBeRendered(numOfYearsToBeRendered);
|
||||
|
||||
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', 'Grants');\n"
|
||||
+ "data.addRows(" + numOfYearsToBeRendered + ");\n");
|
||||
|
||||
int grantCounter = 0;
|
||||
|
||||
/*
|
||||
|
@ -201,12 +150,6 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
currentGrants = 0;
|
||||
}
|
||||
|
||||
visualizationCode.append("data.setValue(" + grantCounter
|
||||
+ ", 0, '" + stringInvestigatedYear + "');\n");
|
||||
|
||||
visualizationCode.append("data.setValue(" + grantCounter
|
||||
+ ", 1, " + currentGrants + ");\n");
|
||||
|
||||
yearToGrantCountDataTable
|
||||
.add(new YearToEntityCountDataElement(
|
||||
grantCounter, stringInvestigatedYear,
|
||||
|
@ -221,9 +164,7 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
|
||||
}
|
||||
|
||||
sparklineData
|
||||
.setYearToEntityCountDataTable(yearToGrantCountDataTable);
|
||||
|
||||
sparklineData.setYearToEntityCountDataTable(yearToGrantCountDataTable);
|
||||
sparklineData.setRenderedSparks(renderedFullSparks);
|
||||
|
||||
/*
|
||||
|
@ -238,9 +179,6 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
|
||||
sparklineData.setUnknownYearGrants(unknownYearGrants);
|
||||
|
||||
String sparklineDisplayOptions = "{width: 65, height: 30, showAxisLines: false, "
|
||||
+ "showValueLabels: false, labelPosition: 'none'}";
|
||||
|
||||
if (providedVisContainerID != null) {
|
||||
visContainerID = providedVisContainerID;
|
||||
} else {
|
||||
|
@ -263,347 +201,35 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
* 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);
|
||||
|
||||
sparklineData.setShortVisMode(true);
|
||||
|
||||
generateShortSparklineVisualizationContent(currentYear,
|
||||
shortSparkMinYear, visContainerID, visualizationCode,
|
||||
unknownYearGrants, sparklineDisplayOptions);
|
||||
} else {
|
||||
|
||||
sparklineData.setShortVisMode(false);
|
||||
generateFullSparklineVisualizationContent(currentYear,
|
||||
minGrantYearConsidered, 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 = "";
|
||||
|
||||
if (getCSVDownloadURL() != null) {
|
||||
|
||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL()
|
||||
+ "\" class=\"inline_href\">(.CSV File)</a>";
|
||||
|
||||
} else {
|
||||
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
|
||||
+ "}"
|
||||
+ "drawPubCountVisualization(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) {
|
||||
|
||||
if (getCSVDownloadURL() != null) {
|
||||
sparklineData.setFullTimelineNetworkLink(UtilityFunctions.getCollaboratorshipNetworkLink(individualURI,
|
||||
VisualizationFrameworkConstants.PERSON_LEVEL_VIS,
|
||||
VisualizationFrameworkConstants.COPI_VIS_MODE));
|
||||
|
||||
csvDownloadURLHref = "Download data as <a href='"
|
||||
+ getCSVDownloadURL() + "'>.csv</a> file.<br />";
|
||||
sparklineData.setDownloadDataLink(getCSVDownloadURL());
|
||||
|
||||
} else {
|
||||
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() {
|
||||
|
||||
if (yearToGrantCount.size() > 0) {
|
||||
|
||||
ParamMap CSVDownloadURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
sparklineData.setDownloadDataLink(UtilityFunctions
|
||||
.getCSVDownloadURL(
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.VIS_TYPE_KEY,
|
||||
VisualizationFrameworkConstants.PERSON_GRANT_COUNT_VIS);
|
||||
VisualizationFrameworkConstants.PERSON_GRANT_COUNT_VIS,
|
||||
""));
|
||||
|
||||
return UrlBuilder.getUrl(VisualizationFrameworkConstants.DATA_VISUALIZATION_SERVICE_URL_PREFIX,
|
||||
CSVDownloadURLParams);
|
||||
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String generateShortVisContext() {
|
||||
|
||||
StringBuilder divContextCode = new StringBuilder();
|
||||
|
||||
String fullTimelineLink;
|
||||
if (yearToGrantCount.size() > 0) {
|
||||
|
||||
// add another parameter for vis_mode
|
||||
ParamMap fullTimelineNetworkURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.VIS_TYPE_KEY,
|
||||
VisualizationFrameworkConstants.PERSON_LEVEL_VIS);
|
||||
|
||||
String fullTimelineNetworkURL = UrlBuilder.getUrl(
|
||||
VisualizationFrameworkConstants.FREEMARKERIZED_VISUALIZATION_URL_PREFIX,
|
||||
fullTimelineNetworkURLParams);
|
||||
|
||||
fullTimelineLink = "<a href='" + fullTimelineNetworkURL + "'>View all VIVO "
|
||||
+ "grants and corresponding co-pi network.</a>";
|
||||
|
||||
sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL);
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
fullTimelineLink = "No data available to render full timeline.<br />";
|
||||
}
|
||||
|
||||
divContextCode.append("<span class=\"vis_link\">" + fullTimelineLink + "</span>");
|
||||
return divContextCode.toString();
|
||||
}
|
||||
|
||||
private String generateDataTable() {
|
||||
|
||||
String csvDownloadURLHref = "";
|
||||
|
||||
if (getCSVDownloadURL() != null) {
|
||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL() + "\">(.CSV File)</a>";
|
||||
} else {
|
||||
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();
|
||||
return sparklineData;
|
||||
}
|
||||
|
||||
public SparklineData getValueObjectContainer() {
|
||||
return sparklineData;
|
||||
return this.sparklineParameterVO;
|
||||
}
|
||||
}
|
|
@ -5,27 +5,23 @@ package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.personpubcount
|
|||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
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.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.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.freemarker.valueobjects.BiboDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.SparklineData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.YearToEntityCountDataElement;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class PersonPublicationCountVisCodeGenerator {
|
||||
|
||||
/*
|
||||
|
@ -37,14 +33,6 @@ public class PersonPublicationCountVisCodeGenerator {
|
|||
* spanning the career of the person & last 10 years at the minimum, in case if
|
||||
* the person started his career in the last 10 yeras.
|
||||
* */
|
||||
private static final Map<String, String> VIS_DIV_NAMES = new HashMap<String, String>() { {
|
||||
|
||||
put("SHORT_SPARK", "pub_count_short_sparkline_vis");
|
||||
put("FULL_SPARK", "pub_count_full_sparkline_vis");
|
||||
|
||||
} };
|
||||
|
||||
private static final String VISUALIZATION_STYLE_CLASS = "sparkline_style";
|
||||
|
||||
private static final String DEFAULT_VIS_CONTAINER_DIV_ID = "pub_count_vis_container";
|
||||
|
||||
|
@ -52,10 +40,10 @@ public class PersonPublicationCountVisCodeGenerator {
|
|||
|
||||
private Log log;
|
||||
|
||||
private SparklineData sparklineData;
|
||||
|
||||
private String individualURI;
|
||||
|
||||
private SparklineData sparklineParameterVO;
|
||||
|
||||
public PersonPublicationCountVisCodeGenerator(String individualURIParam,
|
||||
String visMode,
|
||||
String visContainer,
|
||||
|
@ -66,45 +54,29 @@ public class PersonPublicationCountVisCodeGenerator {
|
|||
this.individualURI = individualURIParam;
|
||||
|
||||
this.yearToPublicationCount = yearToPublicationCount;
|
||||
this.sparklineData = new SparklineData();
|
||||
|
||||
sparklineData.setYearToActivityCount(yearToPublicationCount);
|
||||
|
||||
|
||||
this.log = log;
|
||||
|
||||
generateVisualizationCode(visMode, visContainer, authorDocuments);
|
||||
this.sparklineParameterVO = setupSparklineParameters(visMode, visContainer, authorDocuments);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* This method is used to setup parameters for the sparkline value object. These parameters
|
||||
* will be used in the template to construct the actual html/javascript code.
|
||||
* @param visMode
|
||||
* @param visContainer
|
||||
* @param authorDocuments
|
||||
* @return
|
||||
*/
|
||||
private void generateVisualizationCode(String visMode,
|
||||
String visContainer,
|
||||
private SparklineData setupSparklineParameters(String visMode,
|
||||
String providedVisContainerID,
|
||||
Set<BiboDocument> authorDocuments) {
|
||||
|
||||
sparklineData.setSparklineContent(getMainVisualizationCode(authorDocuments,
|
||||
visMode,
|
||||
visContainer));
|
||||
SparklineData sparklineData = new SparklineData();
|
||||
sparklineData.setYearToActivityCount(yearToPublicationCount);
|
||||
|
||||
|
||||
sparklineData.setSparklineContext(getVisualizationContextCode(visMode));
|
||||
|
||||
}
|
||||
|
||||
private String getMainVisualizationCode(Set<BiboDocument> authorDocuments,
|
||||
String visMode,
|
||||
String providedVisContainerID) {
|
||||
|
||||
int numOfYearsToBeRendered = 0;
|
||||
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
|
||||
int shortSparkMinYear = currentYear
|
||||
|
@ -127,8 +99,6 @@ public class PersonPublicationCountVisCodeGenerator {
|
|||
|
||||
String visContainerID = null;
|
||||
|
||||
StringBuilder visualizationCode = new StringBuilder();
|
||||
|
||||
if (yearToPublicationCount.size() > 0) {
|
||||
try {
|
||||
minPublishedYear = Integer.parseInt(Collections.min(publishedYears));
|
||||
|
@ -159,37 +129,6 @@ public class PersonPublicationCountVisCodeGenerator {
|
|||
|
||||
sparklineData.setNumOfYearsToBeRendered(numOfYearsToBeRendered);
|
||||
|
||||
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 drawPubCountVisualization(providedSparklineImgTD) "
|
||||
+ "{\n"
|
||||
+ "var data = new google.visualization.DataTable();\n"
|
||||
+ "data.addColumn('string', 'Year');\n"
|
||||
+ "data.addColumn('number', 'Publications');\n"
|
||||
+ "data.addRows(" + numOfYearsToBeRendered + ");\n");
|
||||
|
||||
int publicationCounter = 0;
|
||||
|
||||
/*
|
||||
|
@ -213,19 +152,10 @@ public class PersonPublicationCountVisCodeGenerator {
|
|||
currentPublications = 0;
|
||||
}
|
||||
|
||||
visualizationCode.append("data.setValue("
|
||||
+ publicationCounter
|
||||
+ ", 0, '"
|
||||
+ stringPublishedYear
|
||||
+ "');\n");
|
||||
|
||||
visualizationCode.append("data.setValue("
|
||||
+ publicationCounter
|
||||
+ ", 1, "
|
||||
+ currentPublications
|
||||
+ ");\n");
|
||||
|
||||
yearToPublicationCountDataTable.add(new YearToEntityCountDataElement(publicationCounter, stringPublishedYear, currentPublications));
|
||||
yearToPublicationCountDataTable.add(new YearToEntityCountDataElement(
|
||||
publicationCounter,
|
||||
stringPublishedYear,
|
||||
currentPublications));
|
||||
|
||||
/*
|
||||
* Sparks that will be rendered will always be the one's which has
|
||||
|
@ -237,8 +167,6 @@ public class PersonPublicationCountVisCodeGenerator {
|
|||
}
|
||||
|
||||
sparklineData.setYearToEntityCountDataTable(yearToPublicationCountDataTable);
|
||||
|
||||
|
||||
sparklineData.setRenderedSparks(renderedFullSparks);
|
||||
|
||||
|
||||
|
@ -255,9 +183,6 @@ public class PersonPublicationCountVisCodeGenerator {
|
|||
|
||||
sparklineData.setUnknownYearPublications(unknownYearPublications);
|
||||
|
||||
String sparklineDisplayOptions = "{width: 65, height: 30, showAxisLines: false, "
|
||||
+ "showValueLabels: false, labelPosition: 'none'}";
|
||||
|
||||
if (providedVisContainerID != null) {
|
||||
visContainerID = providedVisContainerID;
|
||||
} else {
|
||||
|
@ -275,350 +200,39 @@ public class PersonPublicationCountVisCodeGenerator {
|
|||
sparklineData.setEarliestRenderedPublicationYear(minPublishedYear);
|
||||
sparklineData.setLatestRenderedPublicationYear(currentYear);
|
||||
|
||||
|
||||
if (yearToPublicationCount.size() > 0) {
|
||||
|
||||
sparklineData.setFullTimelineNetworkLink(UtilityFunctions.getCollaboratorshipNetworkLink(individualURI,
|
||||
VisualizationFrameworkConstants.PERSON_LEVEL_VIS,
|
||||
VisualizationFrameworkConstants.COAUTHOR_VIS_MODE));
|
||||
|
||||
sparklineData.setDownloadDataLink(UtilityFunctions
|
||||
.getCSVDownloadURL(
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.PERSON_PUBLICATION_COUNT_VIS,
|
||||
""));
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.setEarliestRenderedPublicationYear(shortSparkMinYear);
|
||||
|
||||
sparklineData.setShortVisMode(true);
|
||||
|
||||
generateShortSparklineVisualizationContent(currentYear,
|
||||
shortSparkMinYear,
|
||||
visContainerID,
|
||||
visualizationCode,
|
||||
unknownYearPublications,
|
||||
sparklineDisplayOptions);
|
||||
} else {
|
||||
|
||||
sparklineData.setShortVisMode(false);
|
||||
generateFullSparklineVisualizationContent(currentYear,
|
||||
minPubYearConsidered,
|
||||
visContainerID,
|
||||
visualizationCode,
|
||||
unknownYearPublications,
|
||||
renderedFullSparks,
|
||||
sparklineDisplayOptions);
|
||||
}
|
||||
log.debug(visualizationCode);
|
||||
return visualizationCode.toString();
|
||||
}
|
||||
|
||||
private void generateShortSparklineVisualizationContent(int currentYear,
|
||||
int shortSparkMinYear,
|
||||
String visContainerID,
|
||||
StringBuilder visualizationCode,
|
||||
int unknownYearPublications,
|
||||
String sparklineDisplayOptions) {
|
||||
|
||||
/*
|
||||
* Create a view of the data containing only the column pertaining to publication 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 publication 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 publication 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 publications 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(" + unknownYearPublications + "));");
|
||||
|
||||
visualizationCode.append("var shortSparksText = ''"
|
||||
+ "+ ' publication(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
|
||||
* drawPubCountVisualization function.
|
||||
* */
|
||||
visualizationCode.append(generateVisualizationActivator(VIS_DIV_NAMES.get("SHORT_SPARK"),
|
||||
visContainerID));
|
||||
|
||||
}
|
||||
|
||||
private void generateFullSparklineVisualizationContent(
|
||||
int currentYear,
|
||||
int minPubYearConsidered,
|
||||
String visContainerID,
|
||||
StringBuilder visualizationCode,
|
||||
int unknownYearPublications,
|
||||
int renderedFullSparks,
|
||||
String sparklineDisplayOptions) {
|
||||
|
||||
String csvDownloadURLHref = "";
|
||||
|
||||
if (getCSVDownloadURL() != null) {
|
||||
|
||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL()
|
||||
+ "\" class=\"inline_href\">(.CSV File)</a>";
|
||||
|
||||
} else {
|
||||
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
|
||||
+ unknownYearPublications) + "');");
|
||||
|
||||
visualizationCode.append("var allSparksText = ''"
|
||||
+ "+ ' publication(s) '"
|
||||
+ "+ ' from "
|
||||
+ "<span class=\"sparkline_range\">"
|
||||
+ "" + minPubYearConsidered + " 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
|
||||
+ "}"
|
||||
+ "drawPubCountVisualization(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 (yearToPublicationCount.size() > 0) {
|
||||
|
||||
if (getCSVDownloadURL() != null) {
|
||||
|
||||
csvDownloadURLHref = "Download data as <a href='"
|
||||
+ getCSVDownloadURL() + "'>.csv</a> file.<br />";
|
||||
sparklineData.setDownloadDataLink(getCSVDownloadURL());
|
||||
|
||||
} else {
|
||||
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() {
|
||||
|
||||
if (yearToPublicationCount.size() > 0) {
|
||||
|
||||
ParamMap CSVDownloadURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.VIS_TYPE_KEY,
|
||||
VisualizationFrameworkConstants.PERSON_PUBLICATION_COUNT_VIS);
|
||||
|
||||
return UrlBuilder.getUrl(VisualizationFrameworkConstants.DATA_VISUALIZATION_SERVICE_URL_PREFIX,
|
||||
CSVDownloadURLParams);
|
||||
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String generateShortVisContext() {
|
||||
|
||||
StringBuilder divContextCode = new StringBuilder();
|
||||
|
||||
String fullTimelineLink;
|
||||
if (yearToPublicationCount.size() > 0) {
|
||||
|
||||
ParamMap fullTimelineNetworkURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.VIS_TYPE_KEY,
|
||||
VisualizationFrameworkConstants.PERSON_LEVEL_VIS);
|
||||
|
||||
String fullTimelineNetworkURL = UrlBuilder.getUrl(
|
||||
VisualizationFrameworkConstants.FREEMARKERIZED_VISUALIZATION_URL_PREFIX,
|
||||
fullTimelineNetworkURLParams);
|
||||
|
||||
|
||||
fullTimelineLink = "<a href='" + fullTimelineNetworkURL + "'>View all VIVO "
|
||||
+ "publications and corresponding co-author network.</a>";
|
||||
|
||||
sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL);
|
||||
|
||||
} else {
|
||||
fullTimelineLink = "No data available to render full timeline.<br />";
|
||||
}
|
||||
|
||||
divContextCode.append("<span class=\"vis_link\">" + fullTimelineLink + "</span>");
|
||||
return divContextCode.toString();
|
||||
}
|
||||
|
||||
private String generateDataTable() {
|
||||
|
||||
String csvDownloadURLHref = "";
|
||||
|
||||
if (getCSVDownloadURL() != null) {
|
||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL() + "\">(.CSV File)</a>";
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
StringBuilder dataTable = new StringBuilder();
|
||||
|
||||
dataTable.append("<table id='sparkline_data_table'>"
|
||||
+ "<caption>Publications per year " + csvDownloadURLHref + "</caption>"
|
||||
+ "<thead>"
|
||||
+ "<tr>"
|
||||
+ "<th>Year</th>"
|
||||
+ "<th>Publications</th>"
|
||||
+ "</tr>"
|
||||
+ "</thead>"
|
||||
+ "<tbody>");
|
||||
|
||||
for (Entry<String, Integer> currentEntry : yearToPublicationCount.entrySet()) {
|
||||
dataTable.append("<tr>"
|
||||
+ "<td>" + currentEntry.getKey() + "</td>"
|
||||
+ "<td>" + currentEntry.getValue() + "</td>"
|
||||
+ "</tr>");
|
||||
}
|
||||
|
||||
dataTable.append("</tbody>\n </table>\n");
|
||||
|
||||
return dataTable.toString();
|
||||
return sparklineData;
|
||||
}
|
||||
|
||||
public SparklineData getValueObjectContainer() {
|
||||
return sparklineData;
|
||||
return this.sparklineParameterVO;
|
||||
}
|
||||
}
|
|
@ -7,14 +7,6 @@ import java.util.Map;
|
|||
|
||||
public class SparklineData {
|
||||
|
||||
/*
|
||||
* For now sparklineNumPublicationsText & sparklinePublicationRangeText is left
|
||||
* as empty but later on we would want to leverage the granularity that this
|
||||
* provides.
|
||||
* */
|
||||
private String sparklineNumPublicationsText = "";
|
||||
private String sparklinePublicationRangeText = "";
|
||||
|
||||
private Integer earliestYearConsidered;
|
||||
private Integer earliestRenderedPublicationYear;
|
||||
private Integer latestRenderedPublicationYear;
|
||||
|
@ -25,17 +17,12 @@ public class SparklineData {
|
|||
private Integer unknownYearPublications;
|
||||
private Integer unknownYearGrants;
|
||||
|
||||
|
||||
private Map<String, Integer> yearToActivityCount;
|
||||
|
||||
private String table = "";
|
||||
|
||||
private String downloadDataLink = "";
|
||||
private String fullTimelineNetworkLink = "";
|
||||
|
||||
private String visContainerDivID = "pub_count_vis_container";
|
||||
private String sparklineContent;
|
||||
private String sparklineContext;
|
||||
|
||||
private boolean isShortVisMode = true;
|
||||
|
||||
|
@ -43,23 +30,6 @@ public class SparklineData {
|
|||
|
||||
private int numOfYearsToBeRendered;
|
||||
|
||||
public String getSparklineNumPublicationsText() {
|
||||
return sparklineNumPublicationsText;
|
||||
}
|
||||
|
||||
public void setSparklineNumPublicationsText(String sparklineNumPublicationsText) {
|
||||
this.sparklineNumPublicationsText = sparklineNumPublicationsText;
|
||||
}
|
||||
|
||||
public String getSparklinePublicationRangeText() {
|
||||
return sparklinePublicationRangeText;
|
||||
}
|
||||
|
||||
public void setSparklinePublicationRangeText(
|
||||
String sparklinePublicationRangeText) {
|
||||
this.sparklinePublicationRangeText = sparklinePublicationRangeText;
|
||||
}
|
||||
|
||||
public Integer getEarliestRenderedGrantYear() {
|
||||
return earliestRenderedGrantYear;
|
||||
}
|
||||
|
@ -151,14 +121,6 @@ public class SparklineData {
|
|||
return renderedSparks;
|
||||
}
|
||||
|
||||
public String getTable() {
|
||||
return table;
|
||||
}
|
||||
|
||||
public void setTable(String table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
public String getDownloadDataLink() {
|
||||
return downloadDataLink;
|
||||
}
|
||||
|
@ -183,14 +145,6 @@ public class SparklineData {
|
|||
return visContainerDivID;
|
||||
}
|
||||
|
||||
public String getSparklineContent() {
|
||||
return sparklineContent;
|
||||
}
|
||||
|
||||
public void setSparklineContent(String shortSparklineContent) {
|
||||
this.sparklineContent = shortSparklineContent;
|
||||
}
|
||||
|
||||
public void setShortVisMode(boolean isShortVisMode) {
|
||||
this.isShortVisMode = isShortVisMode;
|
||||
}
|
||||
|
@ -199,11 +153,4 @@ public class SparklineData {
|
|||
return isShortVisMode;
|
||||
}
|
||||
|
||||
public String getSparklineContext() {
|
||||
return sparklineContext;
|
||||
}
|
||||
|
||||
public void setSparklineContext(String shortSparklineContext) {
|
||||
this.sparklineContext = shortSparklineContext;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,8 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
@ -20,11 +18,12 @@ import org.apache.commons.lang.StringUtils;
|
|||
import org.apache.commons.logging.Log;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.joda.time.format.ISODateTimeFormat;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.VisualizationFrameworkConstants;
|
||||
|
@ -33,8 +32,8 @@ import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants;
|
|||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.BiboDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoAuthorshipData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPIData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Grant;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPINode;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Grant;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Node;
|
||||
|
||||
public class UtilityFunctions {
|
||||
|
@ -277,4 +276,49 @@ public class UtilityFunctions {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static String getCSVDownloadURL(String individualURI, String visType, String visMode) {
|
||||
|
||||
ParamMap CSVDownloadURLParams = null;
|
||||
|
||||
if (StringUtils.isBlank(visMode)) {
|
||||
|
||||
CSVDownloadURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.VIS_TYPE_KEY,
|
||||
visType);
|
||||
|
||||
} else {
|
||||
|
||||
CSVDownloadURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.VIS_TYPE_KEY,
|
||||
visType,
|
||||
VisualizationFrameworkConstants.VIS_MODE_KEY,
|
||||
visMode);
|
||||
|
||||
}
|
||||
|
||||
String csvDownloadLink = UrlBuilder.getUrl(VisualizationFrameworkConstants.DATA_VISUALIZATION_SERVICE_URL_PREFIX,
|
||||
CSVDownloadURLParams);
|
||||
|
||||
return csvDownloadLink != null ? csvDownloadLink : "" ;
|
||||
|
||||
}
|
||||
|
||||
public static String getCollaboratorshipNetworkLink(String individualURI, String visType, String visMode) {
|
||||
|
||||
ParamMap collaboratorshipNetworkURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.VIS_TYPE_KEY,
|
||||
visType,
|
||||
VisualizationFrameworkConstants.VIS_MODE_KEY,
|
||||
visMode);
|
||||
|
||||
String collaboratorshipNetworkURL = UrlBuilder.getUrl(
|
||||
VisualizationFrameworkConstants.FREEMARKERIZED_VISUALIZATION_URL_PREFIX,
|
||||
collaboratorshipNetworkURLParams);
|
||||
|
||||
return collaboratorshipNetworkURL != null ? collaboratorshipNetworkURL : "" ;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue