From 6a499d164fd3eb0a0ae3d83bd3fbf2088aef4d63 Mon Sep 17 00:00:00 2001 From: cdtank Date: Tue, 6 Jul 2010 20:35:29 +0000 Subject: [PATCH] 1. Added handler for unique coauthors in csv data format for coauthorship visualization. 2. Added another method for nodes to get yearToPublicationsCouts directly. 3. Changed styling of person level vis. 4. Cleaned up code --- .../VisualizationRequestHandler.java | 150 ++++++++++++++++-- .../VisualizationCodeGenerator.java | 9 +- .../visualization/valueobjects/Node.java | 8 +- .../templates/visualization/person_level.jsp | 22 ++- 4 files changed, 164 insertions(+), 25 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/visualization/coauthorship/VisualizationRequestHandler.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/visualization/coauthorship/VisualizationRequestHandler.java index 9bc6efbe5..fb64bfb4f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/visualization/coauthorship/VisualizationRequestHandler.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/visualization/coauthorship/VisualizationRequestHandler.java @@ -2,6 +2,12 @@ package edu.cornell.mannlib.vitro.webapp.visualization.coauthorship; import java.io.IOException; import java.io.PrintWriter; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.Map.Entry; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; @@ -9,6 +15,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; +import org.skife.csv.CSVWriter; +import org.skife.csv.SimpleWriter; import com.hp.hpl.jena.query.DataSource; @@ -17,6 +25,10 @@ import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants; import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException; +import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Node; +import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoCollegeOrSchool; +import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoDepartmentOrDivision; +import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions; public class VisualizationRequestHandler { @@ -48,6 +60,8 @@ public class VisualizationRequestHandler { String visContainer = vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_CONTAINER_URL_HANDLE); + String sparklineVisMode = "sparkline"; + QueryHandler queryManager = new QueryHandler(egoURIParam, resultFormatParam, @@ -64,19 +78,36 @@ public class VisualizationRequestHandler { * In order to avoid unneeded computations we have pushed this "if" condition up. * This case arises when the render mode is data. In that case we dont want to generate * HTML code to render sparkline, tables etc. Ideally I would want to avoid this flow. - * It is ugly! + * It is ugly! * */ - if (VisualizationFrameworkConstants.DATA_RENDER_MODE_URL_VALUE.equalsIgnoreCase(renderMode)) { - + + if (VisualizationFrameworkConstants.DATA_RENDER_MODE_URL_VALUE.equalsIgnoreCase(renderMode)) { + + /* + * We will be using the same visualization package for both sparkline & coauthorship flash + * vis. We will use "VIS_MODE_URL_HANDLE" as a modifier to differentiate between these two. + * The defualt will be to render the coauthorship network vis. + * */ + + if (sparklineVisMode.equalsIgnoreCase(visMode)) { /* - * When just the graphML file is required - based on which actual visualization will + * When the csv file is required - based on which sparkline visualization will * be rendered. * */ - prepareVisualizationQueryDataResponse(authorNodesAndEdges); - return; - - + prepareVisualizationQuerySparklineDataResponse(authorNodesAndEdges); + return; + + } else { + /* + * When the graphML file is required - based on which coauthorship network visualization + * will be rendered. + * */ + prepareVisualizationQueryNetworkDataResponse(authorNodesAndEdges); + return; + } } + + /* * Computations required to generate HTML for the sparklines & related context. @@ -137,7 +168,7 @@ public class VisualizationRequestHandler { } - private void prepareVisualizationQueryDataResponse(VisVOContainer authorNodesAndEdges) { + private void prepareVisualizationQueryNetworkDataResponse(VisVOContainer authorNodesAndEdges) { response.setContentType("text/xml"); @@ -161,6 +192,107 @@ public class VisualizationRequestHandler { } } + private void prepareVisualizationQuerySparklineDataResponse(VisVOContainer authorNodesAndEdges) { + + + Map> yearToCoauthors = getCoAuthorsStats(authorNodesAndEdges); + + String outputFileName = UtilityFunctions.slugify(authorNodesAndEdges.getEgoNode().getNodeName()) + + "-coauthors" + ".csv"; + + response.setContentType("application/octet-stream"); + response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName); + + try { + + PrintWriter responseWriter = response.getWriter(); + + /* + * We are side-effecting responseWriter since we are directly manipulating the response + * object of the servlet. + * */ + generateCsvFileBuffer(yearToCoauthors, + responseWriter); + + responseWriter.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void generateCsvFileBuffer(Map> yearToCoauthors, PrintWriter printWriter) { + + CSVWriter csvWriter = new SimpleWriter(printWriter); + + try { + csvWriter.append(new String[]{"Year", "Number of Authors", "Authors"}); + + for (Entry> currentEntry : yearToCoauthors.entrySet()) { + + csvWriter.append(new Object[]{currentEntry.getKey(), + currentEntry.getValue().size(), + getCoauthorsString(currentEntry.getValue())}); + } + + + } catch (IOException e) { + e.printStackTrace(); + } + + printWriter.flush(); + + } + + private String getCoauthorsString(Set coAuthors) { + + StringBuilder coAuthorsMerged = new StringBuilder(); + + for (Node currCoAuthor : coAuthors) { + coAuthorsMerged.append(currCoAuthor.getNodeName() + ", "); + } + + return coAuthorsMerged.toString(); + } + + private Map> getCoAuthorsStats(VisVOContainer authorNodesAndEdges) { + + Map> yearToCoAuthors = new TreeMap>(); + + Node egoNode = authorNodesAndEdges.getEgoNode(); + + for (Node currNode : authorNodesAndEdges.getNodes()) { + + /* + * We have already printed the Ego Node info. + * */ + if (currNode != egoNode) { + + for (String year : currNode.getYearToPublicationCount().keySet()) { + + Set coAuthorNodes; + + if (yearToCoAuthors.containsKey(year)) { + + coAuthorNodes = yearToCoAuthors.get(year); + coAuthorNodes.add(currNode); + + } else { + + coAuthorNodes = new HashSet(); + coAuthorNodes.add(currNode); + yearToCoAuthors.put(year, coAuthorNodes); + } + + } + + } + } + + + return yearToCoAuthors; + } + private void prepareVisualizationQueryStandaloneResponse(String egoURIParam, HttpServletRequest request, HttpServletResponse response, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/visualization/personpubcount/VisualizationCodeGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/visualization/personpubcount/VisualizationCodeGenerator.java index c09837f28..223a632d3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/visualization/personpubcount/VisualizationCodeGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/visualization/personpubcount/VisualizationCodeGenerator.java @@ -82,13 +82,6 @@ public class VisualizationCodeGenerator { } -// public VisVOContainer getValueObjectContainer() { -// -// -// -// return valueObjectContainer; -// } - private String getMainVisualizationCode(List authorDocuments, String visMode, String providedVisContainerID) { @@ -514,7 +507,7 @@ public class VisualizationCodeGenerator { + "=" + URLEncoder.encode(VisualizationFrameworkConstants.STANDALONE_RENDER_MODE_URL_VALUE, VisualizationController.URL_ENCODING_SCHEME).toString(); - fullTimelineLink = "View full timeline and network.
"; + fullTimelineLink = "View full timeline and co-author network
"; valueObjectContainer.setFullTimelineNetworkLink(fullTimelineNetworkURL); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/visualization/valueobjects/Node.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/visualization/valueobjects/Node.java index 63be5ac4c..d8811773f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/visualization/valueobjects/Node.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/visualization/valueobjects/Node.java @@ -20,6 +20,7 @@ public class Node extends Individual { private int nodeID; private Map yearToPublicationCount; + private Set authorDocuments = new HashSet(); public Node(String nodeURL, @@ -57,6 +58,12 @@ public class Node extends Individual { } + public Map getYearToPublicationCount() { + if (yearToPublicationCount == null) { + yearToPublicationCount = UtilityFunctions.getYearToPublicationCount(authorDocuments); + } + return yearToPublicationCount; + } /* * getEarliest, Latest & Unknown Publication YearCount should only be used after * the parsing of the entire sparql is done. Else it will give results based on @@ -66,7 +73,6 @@ public class Node extends Individual { public Map getEarliestPublicationYearCount() { if (yearToPublicationCount == null) { yearToPublicationCount = UtilityFunctions.getYearToPublicationCount(authorDocuments); - System.out.println("early - " + yearToPublicationCount); } /* diff --git a/webapp/web/templates/visualization/person_level.jsp b/webapp/web/templates/visualization/person_level.jsp index bee69e677..216f89944 100644 --- a/webapp/web/templates/visualization/person_level.jsp +++ b/webapp/web/templates/visualization/person_level.jsp @@ -28,7 +28,7 @@ #ego_profile { padding: 10px; - height: 100px; + min-height: 100px; } #ego_label { @@ -51,12 +51,20 @@ #ego_sparkline { cursor:pointer; height:36px; + /* margin-left:10px; margin-top:69px; - position:absolute; + position:absolute;*/ width:471px; } +#dataPanel { + /* + float: left; + width: 150px; + visibility:hidden;*/ +} + .thumbnail { width: 100px; } @@ -74,8 +82,9 @@ <%-- Image --%> + <%-- Sparkline --%> - ${sparkline.sparklineContent} +
${sparkline.sparklineContent}
@@ -93,8 +102,7 @@ -
-





+
@@ -116,8 +124,8 @@
- - + +