Merge branch 'develop' of github.com:vivo-project/VIVO into develop

# By Graham Triggs (5) and grahamtriggs (1)
# Via Graham Triggs (1) and grahamtriggs (1)
* 'develop' of github.com:vivo-project/VIVO:
  [VIVO-1236] Remove parameter for determining Vitro location, which causes problems with Maven 3.0.3
  Fix issue with renamed prefix in SPARQL query for visualisations
  [VIVO-1121] Remove Flash visualisations
  [VIVO-1249] Add capability maps for research areas (#35)
  [VIVO-1232] Allow direct links to specific property tabs
  [VIVO-1243] Add generator tag to Wilma theme
This commit is contained in:
Jim Blake 2016-06-21 10:28:11 -04:00
commit f4d75d838f
33 changed files with 3236 additions and 708 deletions

View file

@ -0,0 +1,284 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.capabilitymap;
import com.google.gson.Gson;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
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.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ResultSetConsumer;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
import edu.cornell.mannlib.vitro.webapp.visualization.model.ConceptLabelMap;
import edu.cornell.mannlib.vitro.webapp.visualization.model.ConceptPeopleMap;
import edu.cornell.mannlib.vitro.webapp.visualization.model.OrganizationPeopleMap;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.VisualizationCaches;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.VisualizationRequestHandler;
import org.apache.axis.utils.StringUtils;
import org.apache.commons.logging.Log;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class CapabilityMapRequestHandler implements VisualizationRequestHandler {
@Override
public AuthorizationRequest getRequiredPrivileges() {
return null;
}
@Override
public ResponseValues generateStandardVisualization(VitroRequest vitroRequest, Log log, Dataset dataSource) throws MalformedQueryParametersException {
return null;
}
@Override
public ResponseValues generateVisualizationForShortURLRequests(Map<String, String> parameters, VitroRequest vitroRequest, Log log, Dataset dataSource) throws MalformedQueryParametersException {
return prepareMarkup(vitroRequest);
}
@Override
public Object generateAjaxVisualization(VitroRequest vitroRequest, Log log, Dataset dataSource) throws MalformedQueryParametersException {
ConceptLabelMap conceptLabelMap = VisualizationCaches.conceptToLabel.get(vitroRequest.getRDFService());
ConceptPeopleMap conceptPeopleMap = VisualizationCaches.conceptToPeopleMap.get(vitroRequest.getRDFService());
OrganizationPeopleMap organizationPeopleMap = VisualizationCaches.organisationToPeopleMap.get(vitroRequest.getRDFService());
Map<String, String> organizationLabels = VisualizationCaches.organizationLabels.get(vitroRequest.getRDFService());
String data = vitroRequest.getParameter("data");
if (!StringUtils.isEmpty(data)) {
if ("concepts".equalsIgnoreCase(data)) {
Set<String> concepts = new HashSet<String>();
for (String conceptKey : conceptPeopleMap.conceptToPeople.keySet()) {
String label = conceptLabelMap.conceptToLabel.get(conceptKey);
if (!StringUtils.isEmpty(label)) {
concepts.add(conceptLabelMap.conceptToLabel.get(conceptKey));
}
}
Gson gson = new Gson();
return gson.toJson(concepts);
}
return "";
}
String personParam = vitroRequest.getParameter("person");
if (!StringUtils.isEmpty(personParam)) {
CapabilityMapResponse response = new CapabilityMapResponse();
CapabilityMapResult result = new CapabilityMapResult();
fillPersonDetails(vitroRequest.getRDFService(), personParam, result);
if (StringUtils.isEmpty(result.firstName) && StringUtils.isEmpty(result.lastName)) {
result.lastName = "Missing Name";
}
Set<String> concepts = conceptPeopleMap.personToConcepts.get(personParam);
if (concepts != null) {
result.subjectArea = concepts.toArray(new String[concepts.size()]);
}
Set<String> organizations = organizationPeopleMap.organizationToPeople.get(personParam);
if (organizations != null) {
for (String org : organizations) {
result.department = organizationLabels.get(org);
if (!StringUtils.isEmpty(result.department)) {
break;
}
}
}
response.results.add(result);
Gson gson = new Gson();
String callback = vitroRequest.getParameter("callback");
if (!StringUtils.isEmpty(callback)) {
return callback + "(" + gson.toJson(response) + ");";
}
return gson.toJson(response);
}
String query = vitroRequest.getParameter("query");
if (!StringUtils.isEmpty(query)) {
CapabilityMapResponse response = new CapabilityMapResponse();
Set<String> matchedConcepts = conceptLabelMap.lowerLabelToConcepts.get(query.toLowerCase());
Set<String> people = new HashSet<String>();
if (matchedConcepts != null) {
for (String uri : matchedConcepts) {
Set<String> peopleSet = conceptPeopleMap.conceptToPeople.get(uri);
if (peopleSet != null) {
people.addAll(peopleSet);
}
}
}
Set<String> clusterConcepts = new HashSet<String>();
for (String person : people) {
if (conceptPeopleMap.personToConcepts.containsKey(person)) {
clusterConcepts.addAll(conceptPeopleMap.personToConcepts.get(person));
}
}
if (matchedConcepts != null) {
clusterConcepts.removeAll(matchedConcepts);
}
Set<String> clusterLabels = new HashSet<String>();
for (String clusterConcept : clusterConcepts) {
String label = conceptLabelMap.conceptToLabel.get(clusterConcept);
if (!StringUtils.isEmpty(label)) {
clusterLabels.add(label);
}
}
String[] clusters = clusterLabels.toArray(new String[clusterLabels.size()]);
for (String person : people) {
CapabilityMapResult result = new CapabilityMapResult();
result.profileId = person;
result.query = query;
result.clusters = clusters;
response.results.add(result);
}
Gson gson = new Gson();
String callback = vitroRequest.getParameter("callback");
if (!StringUtils.isEmpty(callback)) {
return callback + "(" + gson.toJson(response) + ");";
}
return gson.toJson(response);
}
return "";
}
@Override
public Map<String, String> generateDataVisualization(VitroRequest vitroRequest, Log log, Dataset dataset) throws MalformedQueryParametersException {
return null;
}
private ResponseValues prepareMarkup(VitroRequest vreq) {
String standaloneTemplate = "capabilityMap.ftl";
Map<String, Object> body = new HashMap<String, Object>();
body.put("title", "Capability Map");
body.put("vivoDefaultNamespace", vreq.getWebappDaoFactory().getDefaultNamespace());
return new TemplateResponseValues(standaloneTemplate, body);
}
private void fillPersonDetails(final RDFService rdfService, final String personUri, final CapabilityMapResult result) {
try {
String construct = QueryConstants.getSparqlPrefixQuery() +
"CONSTRUCT {\n" +
" <" + personUri + "> a foaf:Person .\n" +
" <" + personUri + "> foaf:lastName ?lastName .\n" +
" <" + personUri + "> foaf:firstName ?firstName .\n" +
" <" + personUri + "> obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" ?contactName vcard:familyName ?familyName .\n" +
" ?contactName vcard:givenName ?givenName .\n" +
" ?contactInfo vcard:hasTitle ?contactTitle .\n" +
" ?contactTitle vcard:title ?contactTitleLabel .\n" +
" <" + personUri + "> public:thumbnailImage ?directDownloadUrl .\n" +
"} WHERE {\n" +
" { \n" +
" <" + personUri + "> foaf:lastName ?lastName .\n" +
" } UNION { \n" +
" <" + personUri + "> foaf:firstName ?firstName .\n" +
" } UNION { \n" +
" <" + personUri + "> obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" ?contactName vcard:familyName ?familyName .\n" +
" } UNION { \n" +
" <" + personUri + "> obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" ?contactName vcard:givenName ?givenName .\n" +
" } UNION { \n" +
" <" + personUri + "> obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasTitle ?contactTitle .\n" +
" ?contactTitle vcard:title ?contactTitleLabel .\n" +
" } UNION { \n" +
" <" + personUri + "> public:mainImage ?mainImage .\n" +
" ?mainImage public:thumbnailImage ?thumbnailImage .\n" +
" ?thumbnailImage public:downloadLocation ?downloadLocation .\n" +
" ?downloadLocation public:directDownloadUrl ?directDownloadUrl .\n" +
" } \n" +
"}\n";
Model constructedModel = ModelFactory.createDefaultModel();
rdfService.sparqlConstructQuery(construct, constructedModel);
String nameQuery = QueryConstants.getSparqlPrefixQuery() +
"SELECT ?familyName ?givenName ?lastName ?firstName ?title ?thumbnailUrl\n" +
"WHERE\n" +
"{\n" +
" <" + personUri + "> a foaf:Person .\n" + // ?person
" OPTIONAL {\n" +
" <" + personUri + "> obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" OPTIONAL { ?contactName vcard:familyName ?familyName . }\n" +
" OPTIONAL { ?contactName vcard:givenName ?givenName . }\n" +
" }\n" +
" OPTIONAL {\n" +
" <" + personUri + "> obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasTitle ?contactTitle .\n" +
" ?contactTitle vcard:title ?title .\n" +
" }\n" +
" OPTIONAL { <" + personUri + "> foaf:lastName ?lastName . }\n" +
" OPTIONAL { <" + personUri + "> foaf:firstName ?firstName . }\n" +
" OPTIONAL { <" + personUri + "> public:thumbnailImage ?thumbnailUrl . }\n" +
"}\n";
QueryExecution qe = QueryExecutionFactory.create(nameQuery, constructedModel);
try {
new ResultSetConsumer() {
@Override
protected void processQuerySolution(QuerySolution qs) {
result.profileId = personUri;
result.firstName = null;
result.lastName = null;
result.thumbNail = null;
result.preferredTitle = null;
Literal familyNameNode = qs.getLiteral("familyName");
if (familyNameNode != null) {
result.lastName = familyNameNode.getString();
} else {
Literal lastNameNode = qs.getLiteral("lastName");
result.lastName = lastNameNode == null ? null : lastNameNode.getString();
}
Literal givenNameNode = qs.getLiteral("givenName");
if (givenNameNode != null) {
result.firstName = givenNameNode.getString();
} else {
Literal firstNameNode = qs.getLiteral("firstName");
result.firstName = firstNameNode == null ? null : firstNameNode.getString();
}
Literal thumbnailUrlNode = qs.getLiteral("thumbnailUrl");
result.thumbNail = thumbnailUrlNode == null ? null : thumbnailUrlNode.getString();
Literal titleNode = qs.getLiteral("title");
result.preferredTitle = titleNode == null ? null : titleNode.getString();
}
}.processResultSet(qe.execSelect());
} finally {
qe.close();
}
} catch (RDFServiceException e) {
}
}
}

View file

@ -0,0 +1,10 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.capabilitymap;
import java.util.ArrayList;
import java.util.List;
class CapabilityMapResponse {
List<CapabilityMapResult> results = new ArrayList<CapabilityMapResult>();
}

View file

@ -0,0 +1,68 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.capabilitymap;
import com.google.gson.annotations.SerializedName;
class CapabilityMapResult {
String[] clusters;
@SerializedName("md_1")
String profileId;
@SerializedName("md_2")
String description;
@SerializedName("md_3")
String thumbNail;
@SerializedName("md_4")
String department;
@SerializedName("md_5")
String overview;
@SerializedName("md_6")
String geographicFocus;
@SerializedName("md_7")
String geographicLocation;
@SerializedName("md_8")
String[] grants;
@SerializedName("md_A")
String firstName;
@SerializedName("md_B")
String lastName;
@SerializedName("md_F")
String fax;
@SerializedName("md_G")
String email;
@SerializedName("md_H")
String availableForSupervision;
@SerializedName("md_I")
String homepage;
@SerializedName("md_L")
String phoneNumber;
@SerializedName("md_U")
String[] publications;
@SerializedName("md_X")
String[] researchOverview;
@SerializedName("md_Y")
String[] subjectArea;
@SerializedName("md_Z")
String preferredTitle;
String query;
}

View file

@ -39,11 +39,12 @@ public class QueryConstants {
put("wos", "http://vivo.mannlib.cornell.edu/ns/ThomsonWOS/0.1#");
put("core", "http://vivoweb.org/ontology/core#");
put("vivo", "http://vivo.library.cornell.edu/ns/0.1#");
put("j.1", "http://aims.fao.org/aos/geopolitical.owl#");
put("j.2", "http://vitro.mannlib.cornell.edu/ns/vitro/public#");
put("geo", "http://aims.fao.org/aos/geopolitical.owl#");
put("public", "http://vitro.mannlib.cornell.edu/ns/vitro/public#");
put("afn", "http://jena.hpl.hp.com/ARQ/function#");
put("vivosocnet", "http://vivo.cns.iu.edu/ns/#");
put("obo", "http://purl.obolibrary.org/obo/");
put("vcard", "http://www.w3.org/2006/vcard/ns#");
} };
public static String getSparqlPrefixQuery() {

View file

@ -15,6 +15,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ResultSetConsumer;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.model.OrganizationPeopleMap;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.OrgUtils;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.VisualizationCaches;
import mapping.ScienceMapping;
@ -252,7 +253,7 @@ public class MapOfScienceVisualizationRequestHandler implements VisualizationReq
}
Map<String, Set<String>> subOrgMap = VisualizationCaches.organizationSubOrgs.get(rdfService);
Map<String, Set<String>> organisationToPeopleMap = VisualizationCaches.organisationToPeopleMap.get(rdfService);
OrganizationPeopleMap organisationToPeopleMap = VisualizationCaches.organisationToPeopleMap.get(rdfService);
Map<String, Set<String>> personToPublicationMap = VisualizationCaches.personToPublication.get(rdfService).personToPublication;
Map<String, String> publicationToJournalMap = VisualizationCaches.publicationToJournal.get(rdfService);
@ -267,7 +268,7 @@ public class MapOfScienceVisualizationRequestHandler implements VisualizationReq
orgPublicationsPeople,
subOrgPublicationsMap,
subOrgMap,
organisationToPeopleMap,
organisationToPeopleMap.organizationToPeople,
personToPublicationMap
);

View file

@ -0,0 +1,12 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.model;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class ConceptLabelMap {
public final Map<String, String> conceptToLabel = new HashMap<String, String>();
public final Map<String, Set<String>> lowerLabelToConcepts = new HashMap<String, Set<String>>();
}

View file

@ -0,0 +1,12 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.model;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class ConceptPeopleMap {
public final Map<String, Set<String>> conceptToPeople = new HashMap<String, Set<String>>();
public final Map<String, Set<String>> personToConcepts = new HashMap<String, Set<String>>();
}

View file

@ -0,0 +1,12 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.model;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class OrganizationPeopleMap {
public final Map<String, Set<String>> organizationToPeople = new HashMap<String, Set<String>>();
public final Map<String, Set<String>> personToOrganizations = new HashMap<String, Set<String>>();
}

View file

@ -0,0 +1,11 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.model;
public class Person {
public String uri;
public String preferredTitle;
public String firstName;
public String lastName;
public String thumbnailUrl;
}

View file

@ -202,13 +202,8 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
Map<String, Object> body = new HashMap<String, Object>();
String standaloneTemplate = "coAuthorPersonLevel.ftl";
String property = ConfigurationProperties.getBean(vitroRequest).getProperty("visualization.d3");
if (!"disabled".equalsIgnoreCase(property)) {
body.put("coAuthorshipData", new CollaborationDataViewHelper(coAuthorshipVO));
standaloneTemplate = "coAuthorPersonLevelD3.ftl";
}
String standaloneTemplate = "coAuthorPersonLevelD3.ftl";
body.put("coAuthorshipData", new CollaborationDataViewHelper(coAuthorshipVO));
body.put("egoURIParam", egoURI);
@ -264,13 +259,8 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
body.put("numOfCoInvestigations", coPIVO.getCollaborations().size());
}
String standaloneTemplate = "coPIPersonLevel.ftl";
String property = ConfigurationProperties.getBean(vitroRequest).getProperty("visualization.d3");
if (!"disabled".equalsIgnoreCase(property)) {
body.put("coInvestigatorData", new CollaborationDataViewHelper(coPIVO));
standaloneTemplate = "coPIPersonLevelD3.ftl";
}
String standaloneTemplate = "coPIPersonLevelD3.ftl";
body.put("coInvestigatorData", new CollaborationDataViewHelper(coPIVO));
body.put("egoGrantSparklineVO", egoGrantSparklineVO);
body.put("uniqueCoInvestigatorsSparklineVO", uniqueCopisSparklineVO);

View file

@ -11,6 +11,7 @@ import java.util.Map;
import java.util.Set;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.visualization.model.OrganizationPeopleMap;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.CounterUtils;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.OrgUtils;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.VisualizationCaches;
@ -152,7 +153,7 @@ public class TemporalGrantVisualizationRequestHandler implements
}
Map<String, Set<String>> subOrgMap = VisualizationCaches.organizationSubOrgs.get(rdfService);
Map<String, Set<String>> organisationToPeopleMap = VisualizationCaches.organisationToPeopleMap.get(rdfService);
OrganizationPeopleMap organisationToPeopleMap = VisualizationCaches.organisationToPeopleMap.get(rdfService);
Map<String, String> orgMostSpecificLabelMap = VisualizationCaches.organizationToMostSpecificLabel.get(rdfService);
Map<String, String> personMostSpecificLabelMap = VisualizationCaches.personToMostSpecificLabel.get(rdfService);
Map<String, Set<String>> personToGrantMap = VisualizationCaches.personToGrant.get(rdfService);
@ -169,7 +170,7 @@ public class TemporalGrantVisualizationRequestHandler implements
orgGrantsPeople,
subOrgGrantsMap,
subOrgMap,
organisationToPeopleMap,
organisationToPeopleMap.organizationToPeople,
personToGrantMap
);

View file

@ -11,6 +11,7 @@ import java.util.Map;
import java.util.Set;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.visualization.model.OrganizationPeopleMap;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.CounterUtils;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.OrgUtils;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.VisualizationCaches;
@ -91,7 +92,7 @@ public class TemporalPublicationVisualizationRequestHandler implements
Map<String, Set<String>> subOrgMap = VisualizationCaches.organizationSubOrgs.get(rdfService);
Map<String, String> orgMostSpecificLabelMap = VisualizationCaches.organizationToMostSpecificLabel.get(rdfService);
Map<String, String> personMostSpecificLabelMap = VisualizationCaches.personToMostSpecificLabel.get(rdfService);
Map<String, Set<String>> organisationToPeopleMap = VisualizationCaches.organisationToPeopleMap.get(rdfService);
OrganizationPeopleMap organisationToPeopleMap = VisualizationCaches.organisationToPeopleMap.get(rdfService);
Map<String, Set<String>> personToPublicationMap = VisualizationCaches.personToPublication.get(rdfService).personToPublication;
Map<String, String> publicationToYearMap = VisualizationCaches.publicationToYear.get(rdfService);
@ -106,7 +107,7 @@ public class TemporalPublicationVisualizationRequestHandler implements
orgPublicationsPeople,
subOrgPublicationsMap,
subOrgMap,
organisationToPeopleMap,
organisationToPeopleMap.organizationToPeople,
personToPublicationMap
);

View file

@ -69,7 +69,7 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler {
.equalsIgnoreCase(visMode)) {
String filterRule = "?predicate = j.2:mainImage "
String filterRule = "?predicate = public:mainImage "
+ " || ?predicate = rdfs:label "
+ " || ?predicate = <http://www.w3.org/2006/vcard/ns#title>";
@ -100,9 +100,9 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler {
fieldLabelToOutputFieldLabel.put("fileName", QueryFieldLabels.THUMBNAIL_FILENAME);
String whereClause = "<" + individualURI
+ "> j.2:thumbnailImage ?thumbnailImage . "
+ "?thumbnailImage j.2:downloadLocation "
+ "?downloadLocation ; j.2:filename ?fileName .";
+ "> public:thumbnailImage ?thumbnailImage . "
+ "?thumbnailImage public:downloadLocation "
+ "?downloadLocation ; public:filename ?fileName .";

View file

@ -2,11 +2,21 @@
package edu.cornell.mannlib.vitro.webapp.visualization.utilities;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ResultSetConsumer;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.model.ConceptLabelMap;
import edu.cornell.mannlib.vitro.webapp.visualization.model.ConceptPeopleMap;
import edu.cornell.mannlib.vitro.webapp.visualization.model.OrganizationPeopleMap;
import edu.cornell.mannlib.vitro.webapp.visualization.model.Person;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
import org.joda.time.DateTime;
@ -17,6 +27,11 @@ import java.util.Set;
/**
* Holder for the caches we are using in the visualizations
*
* String.intern() was a problem pre-Java 7, but has greater utility now.
* Please see the following guide for information on the implementation of String.intern()
*
* http://java-performance.info/string-intern-in-java-6-7-8/
*/
final public class VisualizationCaches {
// Affinity object to ensure that only one background thread can be running at once when updating the caches
@ -32,6 +47,8 @@ final public class VisualizationCaches {
* @param rdfService if not null, use this service in foreground, otherwise may use the background thread
*/
public static void rebuildAll(RDFService rdfService) {
conceptToLabel.build(rdfService);
conceptToPeopleMap.build(rdfService);
organizationLabels.build(rdfService);
organizationSubOrgs.build(rdfService);
organizationToMostSpecificLabel.build(rdfService);
@ -43,9 +60,12 @@ final public class VisualizationCaches {
publicationToYear.build(rdfService);
personToGrant.build(rdfService);
grantToYear.build(rdfService);
// people.build(rdfService);
}
public static void buildMissing() {
if (!conceptToLabel.isCached()) { conceptToLabel.build(null); }
if (!conceptToPeopleMap.isCached()) { conceptToPeopleMap.build(null); }
if (!organizationLabels.isCached()) { organizationLabels.build(null); }
if (!organizationSubOrgs.isCached()) { organizationSubOrgs.build(null); }
if (!organizationToMostSpecificLabel.isCached()) { organizationToMostSpecificLabel.build(null); }
@ -57,6 +77,7 @@ final public class VisualizationCaches {
if (!publicationToYear.isCached()) { publicationToYear.build(null); }
if (!personToGrant.isCached()) { personToGrant.build(null); }
if (!grantToYear.isCached()) { grantToYear.build(null); }
// if (!people.isCached()) { people.build(null); }
}
/**
@ -71,6 +92,139 @@ final public class VisualizationCaches {
}
}
/**
* Cache of people
*/
public static final CachingRDFServiceExecutor<Map<String, Person>> people =
new CachingRDFServiceExecutor<>(
new CachingRDFServiceExecutor.RDFServiceCallable<Map<String, Person>>(visualizationAffinity) {
@Override
protected Map<String, Person> callWithService(RDFService rdfService) throws Exception {
final Map<String, Person> map = new HashMap<String, Person>();
String construct = QueryConstants.getSparqlPrefixQuery() +
"CONSTRUCT {\n" +
" ?person a foaf:Person .\n" +
" ?person foaf:lastName ?lastName .\n" +
" ?person foaf:firstName ?firstName .\n" +
" ?person obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" ?contactName vcard:familyName ?familyName .\n" +
" ?contactName vcard:givenName ?givenName .\n" +
" ?contactInfo vcard:hasTitle ?contactTitle .\n" +
" ?contactTitle vcard:title ?contactTitleLabel .\n" +
" ?person public:thumbnailImage ?directDownloadUrl .\n" +
"} WHERE {\n" +
" { \n" +
" ?person a foaf:Person .\n" +
" } UNION { \n" +
" ?person a foaf:Person .\n" +
" ?person foaf:lastName ?lastName .\n" +
" } UNION { \n" +
" ?person a foaf:Person .\n" +
" ?person foaf:firstName ?firstName .\n" +
" } UNION { \n" +
" ?person a foaf:Person .\n" +
" ?person obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" ?contactName vcard:familyName ?familyName .\n" +
" } UNION { \n" +
" ?person a foaf:Person .\n" +
" ?person obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" ?contactName vcard:givenName ?givenName .\n" +
" } UNION { \n" +
" ?person a foaf:Person .\n" +
" ?person obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasTitle ?contactTitle .\n" +
" ?contactTitle vcard:title ?contactTitleLabel .\n" +
" } UNION { \n" +
" ?person a foaf:Person .\n" +
" ?person public:mainImage ?mainImage .\n" +
" ?mainImage public:thumbnailImage ?thumbnailImage .\n" +
" ?thumbnailImage public:downloadLocation ?downloadLocation .\n" +
" ?downloadLocation public:directDownloadUrl ?directDownloadUrl .\n" +
" } \n" +
"}\n";
Model constructedModel = ModelFactory.createDefaultModel();
rdfService.sparqlConstructQuery(construct, constructedModel);
String nameQuery = QueryConstants.getSparqlPrefixQuery() +
"SELECT ?person ?familyName ?givenName ?lastName ?firstName ?title ?thumbnailUrl\n" +
"WHERE\n" +
"{\n" +
" ?person a foaf:Person .\n" +
" OPTIONAL {\n" +
" ?person obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" OPTIONAL { ?contactName vcard:familyName ?familyName . }\n" +
" OPTIONAL { ?contactName vcard:givenName ?givenName . }\n" +
" }\n" +
" OPTIONAL {\n" +
" ?person obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasTitle ?contactTitle .\n" +
" ?contactTitle vcard:title ?title .\n" +
" }\n" +
" OPTIONAL { ?person foaf:lastName ?lastName . }\n" +
" OPTIONAL { ?person foaf:firstName ?firstName . }\n" +
" OPTIONAL { ?person public:thumbnailImage ?thumbnailUrl . }\n" +
"}\n";
QueryExecution qe = QueryExecutionFactory.create(nameQuery, constructedModel);
try {
new ResultSetConsumer() {
@Override
protected void processQuerySolution(QuerySolution qs) {
String personUri = qs.getResource("person").getURI();
String familyName = null;
String givenName = null;
String thumbnailUrl = null;
String title = null;
Literal familyNameNode = qs.getLiteral("familyName");
if (familyNameNode != null) {
familyName = familyNameNode.getString();
} else {
Literal lastNameNode = qs.getLiteral("lastName");
familyName = lastNameNode == null ? null : lastNameNode.getString();
}
Literal givenNameNode = qs.getLiteral("givenName");
if (givenNameNode != null) {
givenName = givenNameNode.getString();
} else {
Literal firstNameNode = qs.getLiteral("firstName");
givenName = firstNameNode == null ? null : firstNameNode.getString();
}
Literal thumbnailUrlNode = qs.getLiteral("thumbnailUrl");
thumbnailUrl = thumbnailUrlNode == null ? null : thumbnailUrlNode.getString();
Literal titleNode = qs.getLiteral("title");
title = titleNode == null ? null : titleNode.getString();
Person person = map.get(personUri);
if (person == null) {
person = new Person();
map.put(personUri.intern(), person);
}
person.firstName = givenName == null ? null : givenName.intern();
person.lastName = familyName == null ? null : familyName.intern();
person.preferredTitle = title == null ? null : title.intern();
person.thumbnailUrl = thumbnailUrl;
}
}.processResultSet(qe.execSelect());
} finally {
qe.close();
}
return map;
}
}
);
/**
* Cache of organization labels (uri -> label)
*/
@ -95,7 +249,7 @@ final public class VisualizationCaches {
String org = qs.getResource("org").getURI();
String orgLabel = qs.getLiteral("orgLabel").getString();
map.put(org, orgLabel);
map.put(org.intern(), orgLabel.intern());
}
});
@ -131,10 +285,10 @@ final public class VisualizationCaches {
Set<String> subOrgs = map.get(org);
if (subOrgs == null) {
subOrgs = new HashSet<String>();
subOrgs.add(subOrg);
map.put(org, subOrgs);
subOrgs.add(subOrg.intern());
map.put(org.intern(), subOrgs);
} else {
subOrgs.add(subOrg);
subOrgs.add(subOrg.intern());
}
}
});
@ -168,7 +322,7 @@ final public class VisualizationCaches {
protected void processQuerySolution(QuerySolution qs) {
String org = qs.getResource("org").getURI();
String typeLabel = qs.getLiteral("typeLabel").getString();
map.put(org, String.valueOf(typeLabel));
map.put(org.intern(), typeLabel.intern());
}
});
@ -180,11 +334,11 @@ final public class VisualizationCaches {
/**
* Map of people within an organisation (org uri -> list of person uri)
*/
public static final CachingRDFServiceExecutor<Map<String, Set<String>>> organisationToPeopleMap =
new CachingRDFServiceExecutor<Map<String, Set<String>>>(
new CachingRDFServiceExecutor.RDFServiceCallable<Map<String, Set<String>>>(visualizationAffinity) {
public static final CachingRDFServiceExecutor<OrganizationPeopleMap> organisationToPeopleMap =
new CachingRDFServiceExecutor<OrganizationPeopleMap>(
new CachingRDFServiceExecutor.RDFServiceCallable<OrganizationPeopleMap>(visualizationAffinity) {
@Override
protected Map<String, Set<String>> callWithService(RDFService rdfService) throws Exception {
protected OrganizationPeopleMap callWithService(RDFService rdfService) throws Exception {
String query = QueryConstants.getSparqlPrefixQuery() +
"SELECT ?organisation ?person\n" +
"WHERE\n" +
@ -196,22 +350,31 @@ final public class VisualizationCaches {
" ?person a foaf:Person .\n" +
"}\n";
final Map<String, Set<String>> orgToPeopleMap = new HashMap<String, Set<String>>();
final OrganizationPeopleMap orgToPeopleMap = new OrganizationPeopleMap();
rdfService.sparqlSelectQuery(query, new ResultSetConsumer() {
@Override
protected void processQuerySolution(QuerySolution qs) {
String org = qs.getResource("organisation").getURI();
String person = qs.getResource("person").getURI();
String org = qs.getResource("organisation").getURI().intern();
String person = qs.getResource("person").getURI().intern();
Set<String> people = orgToPeopleMap.get(org);
Set<String> people = orgToPeopleMap.organizationToPeople.get(org);
if (people == null) {
people = new HashSet<String>();
people.add(person);
orgToPeopleMap.put(org, people);
orgToPeopleMap.organizationToPeople.put(org, people);
} else {
people.add(person);
}
Set<String> organizations = orgToPeopleMap.personToOrganizations.get(org);
if (organizations == null) {
organizations = new HashSet<String>();
organizations.add(org);
orgToPeopleMap.organizationToPeople.put(person, organizations);
} else {
organizations.add(org);
}
}
});
@ -220,6 +383,103 @@ final public class VisualizationCaches {
}
);
/**
* Concept to label
*/
public static final CachingRDFServiceExecutor<ConceptLabelMap> conceptToLabel =
new CachingRDFServiceExecutor<>(
new CachingRDFServiceExecutor.RDFServiceCallable<ConceptLabelMap>() {
@Override
protected ConceptLabelMap callWithService(RDFService rdfService) throws Exception {
String query = QueryConstants.getSparqlPrefixQuery() +
"SELECT ?concept ?label\n" +
"WHERE\n" +
"{\n" +
" ?person a foaf:Person .\n" +
" ?person core:hasResearchArea ?concept .\n" +
" ?concept a skos:Concept .\n" +
" ?concept rdfs:label ?label .\n" +
"}\n";
// final Map<String, String> map = new HashMap<>();
final ConceptLabelMap map = new ConceptLabelMap();
rdfService.sparqlSelectQuery(query, new ResultSetConsumer() {
@Override
protected void processQuerySolution(QuerySolution qs) {
String conceptURI = qs.getResource("concept").getURI().intern();
String label = qs.getLiteral("label").getString().intern();
String labelLower = label.toLowerCase().intern();
map.conceptToLabel.put(conceptURI, label);
Set<String> conceptSet = map.lowerLabelToConcepts.get(labelLower);
if (conceptSet == null) {
conceptSet = new HashSet<String>();
conceptSet.add(conceptURI);
map.lowerLabelToConcepts.put(labelLower, conceptSet);
} else {
conceptSet.add(conceptURI);
}
}
});
return map;
}
}
);
/**
* Map of people associated with a concept
*/
public static final CachingRDFServiceExecutor<ConceptPeopleMap> conceptToPeopleMap =
new CachingRDFServiceExecutor<ConceptPeopleMap>(
new CachingRDFServiceExecutor.RDFServiceCallable<ConceptPeopleMap>(visualizationAffinity) {
@Override
protected ConceptPeopleMap callWithService(RDFService rdfService) throws Exception {
String query = QueryConstants.getSparqlPrefixQuery() +
"SELECT ?person ?concept\n" +
"WHERE\n" +
"{\n" +
" ?person a foaf:Person .\n" +
" ?person core:hasResearchArea ?concept .\n" +
" ?concept a skos:Concept .\n" +
"}\n";
final ConceptPeopleMap conceptPeopleMap = new ConceptPeopleMap();
rdfService.sparqlSelectQuery(query, new ResultSetConsumer() {
@Override
protected void processQuerySolution(QuerySolution qs) {
String concept = qs.getResource("concept").getURI().intern();
String person = qs.getResource("person").getURI().intern();
Set<String> people = conceptPeopleMap.conceptToPeople.get(concept);
if (people == null) {
people = new HashSet<String>();
people.add(person);
conceptPeopleMap.conceptToPeople.put(concept, people);
} else {
people.add(person);
}
Set<String> concepts = conceptPeopleMap.personToConcepts.get(person);
if (concepts == null) {
concepts = new HashSet<String>();
concepts.add(concept);
conceptPeopleMap.personToConcepts.put(person, concepts);
} else {
concepts.add(concept);
}
}
});
return conceptPeopleMap;
}
}
);
/**
* Display labels for people (uri -> label)
*/
@ -244,7 +504,7 @@ final public class VisualizationCaches {
String person = qs.getResource("person").getURI();
String personLabel = qs.getLiteral("personLabel").getString();
map.put(person, personLabel);
map.put(person.intern(), personLabel.intern());
}
});
@ -277,7 +537,7 @@ final public class VisualizationCaches {
protected void processQuerySolution(QuerySolution qs) {
String person = qs.getResource("person").getURI();
String typeLabel = qs.getLiteral("typeLabel").getString();
map.put(person, String.valueOf(typeLabel));
map.put(person.intern(), String.valueOf(typeLabel).intern());
}
});
@ -317,7 +577,7 @@ final public class VisualizationCaches {
String personURI = person.getURI();
String documentURI = document.getURI();
map.put(personURI, documentURI);
map.put(personURI.intern(), documentURI.intern());
}
}
});
@ -352,7 +612,7 @@ final public class VisualizationCaches {
String document = qs.getResource("document").getURI();
String journalLabel = qs.getLiteral("journalLabel").getString();
map.put(document, journalLabel);
map.put(document.intern(), journalLabel.intern());
}
});
@ -390,7 +650,7 @@ final public class VisualizationCaches {
.getValidParsedDateTimeObject(pubDate);
if (validParsedDateTimeObject != null) {
map.put(document, String.valueOf(validParsedDateTimeObject.getYear()));
map.put(document.intern(), String.valueOf(validParsedDateTimeObject.getYear()).intern());
}
}
}
@ -434,10 +694,10 @@ final public class VisualizationCaches {
Set<String> documents = map.get(personURI);
if (documents == null) {
documents = new HashSet<String>();
documents.add(grant.getURI());
map.put(personURI, documents);
documents.add(grant.getURI().intern());
map.put(personURI.intern(), documents);
} else {
documents.add(grant.getURI());
documents.add(grant.getURI().intern());
}
}
}
@ -478,7 +738,7 @@ final public class VisualizationCaches {
.getValidParsedDateTimeObject(startDate);
if (validParsedDateTimeObject != null) {
map.put(grant, String.valueOf(validParsedDateTimeObject.getYear()));
map.put(grant.intern(), String.valueOf(validParsedDateTimeObject.getYear()).intern());
}
}
}
@ -520,7 +780,7 @@ final public class VisualizationCaches {
.getValidParsedDateTimeObject(startDate);
if (validParsedDateTimeObject != null) {
map.put(grant, String.valueOf(validParsedDateTimeObject.getYear()));
map.put(grant.intern(), String.valueOf(validParsedDateTimeObject.getYear()).intern());
}
}
}

View file

@ -312,17 +312,6 @@ VitroConnection.DataSource.validationQuery = SELECT 1
#
visualization.temporal = enabled
#
# The co-authorship and co-investigator graphs have two variants - the traditional Flash based view,
# and views using D3.
# The traditional views require that users have Flash installed as a plugin, whereas D3 works on any
# modern browser.
# Currently, it is not possible to choose between them from the UI. You can choose to either have
# the Flash visualizations, OR the D3 visualizations.
# If this option is not present or set to enabled, then the D3 visualizations will be used.
# If this option is present and set to disabled, then the Flash visualizations will be used.
#visualization.d3 = disabled
#
# Types of individual for which we can create proxy editors.
# If this is omitted, defaults to http://www.w3.org/2002/07/owl#Thing

View file

@ -19,7 +19,8 @@ display:DefaultMenu
display:hasElement display:HomeMenuItem ;
display:hasElement display:OrganizationsMenuItem ;
display:hasElement display:PeopleMenuItem ;
display:hasElement display:ResearchMenuItem .
display:hasElement display:ResearchMenuItem ;
display:hasElement display:CapabilityMapMenuItem .
#### Menu Items for Default Menu ####
@ -53,7 +54,13 @@ display:EventsMenuItem
display:linkText "Events";
display:toPage display:Events .
display:Home
display:CapabilityMapMenuItem
a display:NavigationElement ;
display:menuPosition 6;
display:linkText "Capability Map";
display:toPage display:CapabilityMap .
display:Home
a display:HomePage ;
a display:Page ;
display:title "Home" ;
@ -93,8 +100,12 @@ display:Research
display:urlMapping "/research" ;
display:hasDataGetter display:researchDataGetter .
display:CapabilityMap
a display:Page ;
display:title "Capability Map" ;
display:urlMapping "/vis/capabilitymap" ;
display:hasDataGetter display:capabilityMapDataGetter .
#The data getter objects used above
display:peopleDataGetter
a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.ClassGroupPageData>;
@ -118,3 +129,8 @@ display:eventsDataGetter
display:homeDataGetter
a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.BrowseDataGetter> .
display:capabilityMapDataGetter
a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter>;
display:htmlValue """Capability Map"""@en ;
display:saveToVar "capabilityMap" .

View file

@ -11,7 +11,6 @@
<packaging>pom</packaging>
<properties>
<vitro-core>../Vitro</vitro-core>
<vitro-version>${project.version}</vitro-version>
<vivo-dir>${basedir}</vivo-dir>
<maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>
@ -31,11 +30,11 @@
<id>vitro</id>
<activation>
<file>
<exists>${vivo-dir}/${vitro-core}/pom.xml</exists>
<exists>../Vitro/pom.xml</exists>
</file>
</activation>
<modules>
<module>${vitro-core}</module>
<module>../Vitro</module>
</modules>
</profile>
<profile>

View file

@ -9,6 +9,8 @@
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean id="capability_map"
class="edu.cornell.mannlib.vitro.webapp.visualization.capabilitymap.CapabilityMapRequestHandler" />
<bean id="person_pub_count"
class="edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.PersonPublicationCountRequestHandler" />
@ -47,6 +49,10 @@
class="edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationInjector">
<property name="visualizations">
<map>
<entry key="capabilitymap">
<ref bean="capability_map"></ref>
</entry>
<entry key="person_pub_count">
<ref bean="person_pub_count"></ref>
</entry>

View file

@ -0,0 +1,355 @@
body {
background-position-y:60px;
}
.text {
margin: 7px;
}
.alert {
color: red;
font-size: large;
}
#queryform button, #queryform input[type=submit] {
border-radius: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-o-border-radius: 4px;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
-webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
-o-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.3);
-webkit-text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.3);
-moz-text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.3);
-o-text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.3);
background-color: #8BAB2E;
// background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#446791), to(#164682));
// background-image: -moz-linear-gradient(top, #446791, #164682);
width: auto;
padding: 9px 18px 8px;
// margin: 10px 10px 0 0;
color: #fff;
border: 0;
vertical-align: middle
}
#content {
width: 1200px;
max-width: 1200px;
}
/* Contains all the graphics. */
#container {
/*width: 1200px;*/width:940px;
height: auto;
/* margin:0 auto; */
/*margin-left:-130px;*/
position:relative;
/*box-shadow:0px 0px 20px -6px #000000;*/
margin-top:15px;
}
#left-container,
#right-container,
#center-container {
height:600px;
position:absolute;
top:0;
}
ul#log_printout {
display: block;
height: 330px;
overflow: scroll
}
#left-container, #right-container {
width: 300px;
color:#686c70;
text-align: left;
/*overflow: auto;*/
background-color:#fff;
background-repeat:no-repeat;
/*border-bottom:1px solid #ddd;*/
}
.result_body {
overflow:auto;
height:570px;
}
#left-container {
left:0;
}
#right-container {
right:0;
border-left:1px solid #ddd;
}
#right-container h4{
text-indent:8px;
}
#center-container {
width: 900px;
background-color:#FFFFFF;
color:#ccc;
}
.result_section {
/* width: 100%;*/
font-size: 12px;
list-style:none;
margin:7px;
}
#log {
position: absolute;
top: 10px;
right:10px;
font-size:1.0em;
}
#infovis {
width:100%;
height:600px;
/*margin:auto;*/
overflow:hidden;
}
span.close {
color:#FF5555;
cursor:pointer;
font-weight:bold;
margin-left:3px;
}
span.name {
cursor: pointer;
}
/*TOOLTIPS*/
.tip {
color: #111;
width: 139px;
background-color: white;
border:1px solid #ccc;
-moz-box-shadow:#555 2px 2px 8px;
-webkit-box-shadow:#555 2px 2px 8px;
-o-box-shadow:#555 2px 2px 8px;
box-shadow:#555 2px 2px 8px;
opacity:0.9;
filter:alpha(opacity=90);
font-size:10px;
font-family:Verdana, Geneva, Arial, Helvetica, sans-serif;
padding:7px;
text-align: left;
width:auto;
max-width:500px;
}
/* LIST OF EXPERTS */
.field {
font-style: italic;
margin: .4ex 1ex;
}
#graphDetails {
margin-bottom:0px;
margin-top:5px;
}
input[disabled] {
opacity:0.5;
box-shadow:none;
}
#resetButton {
background-color: #933;
background-image: -webkit-gradient(linear,0 0,0 100%,from(#B55),to(#933));
background-image: -moz-linear-gradient(center top , #B55, #933);
}
#helptext {
width:630px;
/*padding:5px;*/
}
#center-container {
display:none;
}
.bar {
height:15px;
display:block;
background-color:#EEE;
border:1px solid #CCC;
float:left;
margin-bottom:1px;
}
.barchart {
line-height:18px;
padding-top:5px;
}
h2 {
font-size:23px;
margin-top:0px;
padding-top:0px;
line-height:1.3em;
margin-bottom:20px;
}
.result_section h2 {
font-size:16px;
padding:10px 0px;
margin:0px;
}
.result_section ul li {
margin-top:3px;
}
li input[type=checkbox] {
vertical-align:middle;
}
.orange-square, .blue-circle {
display:block;
float:left;
height:15px;
width:15px;
margin-right:3px;
}
.orange-square {
background-color:#ffa500;
}
.blue-circle {
background-color:#23A4FF;
border-radius:7px;
}
ul.visible {
margin-bottom:1.3em;
margin-left:20px;
list-style-type:disc;
}
#cutofflabel {
display:inline-block;
width:0px;
overflow:visible;
position:relative;
left:10px;
top:2px;
foont-size: 14px;
}
#queryCutoff {
background:transparent;
text-align:right;
padding-left:40px;
}
#cutofflabel img {
vertical-align:middle;
position:relative;
top:-2px;
}
.progress, .progress div {
height:10px;
margin-bottom:-10px;
}
.progress {
position:absolute;
top:0px;
left:0px;
width:100%;
}
.progress div {
background-color:#9999FF;
width:0%;
white-space:nowrap;
color:#FFF;
font-size:10px;
line-height:10px;
}
hr {
background:#efefef;
}
.tabs {
width: auto;
margin-bottom: 15px;
border: 0;
z-index: 10;
}
.tabs ul.titles li {
background: transparent;
/*padding-right: 1px;*/
line-height: normal;
display:inline;
}
.tabs ul {
padding-left:0px;
}
.tabs ul.titles {
list-style: none;
height:30px;
color: #5e6363;
font-size: 13px;
}
.tabs ul.titles li a {
text-decoration: none;
background-color: #eeeeee;
outline: none;
display:block;
float:left;
// width:100px;
width:150px;
height:30px;
line-height:30px;
text-align:center;
color: #5e6363;
}
.tabs ul.titles li a:hover {
background-color: #dddddd;
color: #002b44;
}
.tabs ul.titles li.activeTab a,
.tabs ul.titles li.activeTab a:hover {
background-color: #fff;
}
.smalllogo {
margin-left:-5px;
vertical-align:middle;
}
.advanced label, input {
display:inline;
}
.advanced input[type=text] {
width:50px;
}
.advanced {
display:none;
}
.person_details {
margin-top:5px;
}
.person_details p {
margin-bottom:0px;
}
.person_details ul {
list-style:disc;
margin-left:20px;
}
.person_details li {
margin:0px;
margin-bottom:3px;
}
.ack {
padding-top:20px;
/*text-align:center;*/
color:#999;
margin:0px 20px;
/*font-size:8pt;*/
}
footer {
margin:0px 20px;
width:auto;
}
footer p.copyright {
margin-left:0px;
padding-left:0px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -1,19 +1,22 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
$(document).ready(function(){
$.extend(this, individualLocalName);
adjustFontSize();
padSectionBottoms();
checkLocationHash();
// prevents the page jumping down when loading a page with a requested tab in the url
removeHash();
// ensures that shorter property group sections don't cause the page to "jump around"
// when the tabs are clicked
function padSectionBottoms() {
$.each($('section.property-group'), function() {
var sectionHeight = $(this).height();
if ( sectionHeight < 1000 ) {
$(this).css('margin-bottom', 1000-sectionHeight + "px");
$(this).css('margin-bottom', 1000-sectionHeight + "px");
}
});
}
@ -22,9 +25,9 @@ $(document).ready(function(){
$.each($('li.clickable'), function() {
var groupName = $(this).attr("groupName");
var $propertyGroupLi = $(this);
$(this).click(function() {
if ( $propertyGroupLi.attr("class") == "nonSelectedGroupTab clickable" ) {
$.each($('li.selectedGroupTab'), function() {
$(this).removeClass("selectedGroupTab clickable");
@ -41,69 +44,107 @@ $(document).ready(function(){
var $visibleSection = $('section.property-group:visible');
$visibleSection.hide();
$('h2[pgroup=tabs]').addClass("hidden");
$('nav#scroller').addClass("hidden");
$('nav#scroller').addClass("hidden");
$('section#' + groupName).show();
}
manageLocalStorage();
return false;
});
});
function removeHash () {
if ( location.hash ) {
var scrollV, scrollH, loc = window.location;
if ("pushState" in history)
history.replaceState("", document.title, loc.pathname + loc.search);
else {
// Prevent scrolling by storing the page's current scroll offset
scrollV = document.body.scrollTop;
scrollH = document.body.scrollLeft;
loc.hash = "";
// Restore the scroll offset, should be flicker free
document.body.scrollTop = scrollV;
document.body.scrollLeft = scrollH;
}
}
}
function processViewAllTab() {
$.each($('section.property-group'), function() {
$(this).css("margin-bottom", "1px");
$(this).children('h2').css("margin-top", "-15px").css("border-bottom","1px solid #DFEBE5").css("padding","12px 25px 10px 20px");
$(this).show();
$(this).show();
$('h2[pgroup=tabs]').removeClass("hidden");
$('nav#scroller').removeClass("hidden");
});
$('nav#scroller').removeClass("hidden");
});
}
// If users click a marker on the home page map, they are taken to the profile
// page of the corresponding country. The url contains the word "Research" in
// the location hash. Use this to select the Research tab, which displays the
// researchers who have this countru as a geographic focus.
// If a page is requested with a hash this script will try to open a property
// group tab matching that hash value.
// The geographic focus map links to a county's page with a #map hash. This will
// select the research tab and expand the 'geographic focus of' property list.
function checkLocationHash() {
var currentTab = $('li.selectedGroupTab').attr('groupName')
if ( location.hash ) {
// remove the trailing white space
location.hash = location.hash.replace(/\s+/g, '');
if ( location.hash.indexOf("map") >= 0 ) {
// get the name of the group that contains the geographicFocusOf property.
// if it doesn't exist, don't do anything.
var tabExists = $("[groupname=" + location.hash.replace('#', '') + "]")
if ( tabExists.length > 0 ) {
tabName = location.hash.replace('#', '')
}
else if ( location.hash.indexOf("map") >= 0 ) {
if ( $('h3#geographicFocusOf').length ) {
var tabName = $('h3#geographicFocusOf').parent('article').parent('div').attr("id");
tabName = tabName.replace("Group","");
tabNameCapped = tabName.charAt(0).toUpperCase() + tabName.slice(1);
// if the name of the first tab section = tabName we don't have to do anything;
// otherwise, select the correct tab and deselect the first one
var $firstTab = $('li.clickable').first();
if ( $firstTab.text() != tabNameCapped ) {
// select the correct tab
$('li[groupName="' + tabName + '"]').removeClass("nonSelectedGroupTab clickable");
$('li[groupName="' + tabName + '"]').addClass("selectedGroupTab clickable");
// deselect the first tab
$firstTab.removeClass("selectedGroupTab clickable");
$firstTab.addClass("nonSelectedGroupTab clickable");
$('section.property-group:visible').hide();
// show the selected tab section
$('section#' + tabName).show();
}
}
// if there is a more link, "click" more to show all the researchers
// we need the timeout delay so that the more link can get rendered
setTimeout(geoFocusExpand,250);
}
if ( tabName ) {
if ( tabName != currentTab ) {
swapTabs(tabName, currentTab)
}
}
// the requested tab was gibberish, try the local storage
else {
retrieveLocalStorage();
}
retrieveLocalStorage(currentTab);
}
}
else {
retrieveLocalStorage();
retrieveLocalStorage(currentTab);
}
}
function swapTabs(tabName, currentTab) {
$('li[groupName="' + tabName + '"]').removeClass("nonSelectedGroupTab clickable");
$('li[groupName="' + tabName + '"]').addClass("selectedGroupTab clickable");
// deselect the first tab
$('li[groupName="' + currentTab + '"]').removeClass("selectedGroupTab clickable");
$('li[groupName="' + currentTab + '"]').addClass("nonSelectedGroupTab clickable");
if ( tabName == 'viewAll'){
processViewAllTab();
}
else {
padSectionBottoms();
$('section.property-group:visible').hide();
// show the selected tab section
$('section#' + tabName).show();
}
}
function geoFocusExpand() {
// if the ontology is set to collate by subclass, $list.length will be > 0
// if the ontology is set to collate by subclass, $list.length will be > 0
// this ensures both possibilities are covered
var $list = $('ul#geographicFocusOfList').find('ul');
if ( $list.length > 0 )
@ -116,7 +157,7 @@ $(document).ready(function(){
$more.click();
}
}
// Next two functions -- keep track of which property group tab was selected,
// so if we return from a custom form or a related individual, even via the back button,
// the same property group will be selected as before.
@ -153,20 +194,20 @@ $(document).ready(function(){
}
}
function retrieveLocalStorage() {
function retrieveLocalStorage(currentTab) {
var localName = this.individualLocalName;
var selectedTab = amplify.store(individualLocalName);
if ( selectedTab != undefined ) {
var groupName = selectedTab[0];
// unlikely, but it's possible a tab that was previously selected and stored won't be
// displayed because the object properties would have been deleted (in non-edit mode).
// So ensure that the tab in local storage has been rendered on the page.
if ( $("ul.propertyTabsList li[groupName='" + groupName + "']").length ) {
// unlikely, but it's possible a tab that was previously selected and stored won't be
// displayed because the object properties would have been deleted (in non-edit mode).
// So ensure that the tab in local storage has been rendered on the page.
if ( $("ul.propertyTabsList li[groupName='" + groupName + "']").length ) {
// if the selected tab is the default first one, don't do anything
if ( $('li.clickable').first().attr("groupName") != groupName ) {
if ( $('li.clickable').first().attr("groupName") != groupName ) {
// deselect the default first tab
var $firstTab = $('li.clickable').first();
$firstTab.removeClass("selectedGroupTab clickable");
@ -186,8 +227,14 @@ $(document).ready(function(){
}
}
}
// If you wish to default to the "all" tab for small profiles, uncomment the following lines
// -- Start view all mod
// else if ( $('article.property').length < 10 ) {
// swapTabs('viewAll', currentTab)
// }
// -- End view all mod
}
// if there are so many tabs that they wrap to a second line, adjust the font size to
// if there are so many tabs that they wrap to a second line, adjust the font size to
//prevent wrapping
function adjustFontSize() {
var width = 0;
@ -231,6 +278,5 @@ $(document).ready(function(){
$('ul.propertyTabsList li:last-child').css('width', newDiff + 'px');
}
}
});
});

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,663 @@
/*!
* jQuery Color Animations v@VERSION
* https://github.com/jquery/jquery-color
*
* Copyright 2013 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
* Date: @DATE
*/
(function( jQuery, undefined ) {
var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
// plusequals test for += 100 -= 100
rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
// a set of RE's that can match strings and generate color tuples.
stringParsers = [{
re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
parse: function( execResult ) {
return [
execResult[ 1 ],
execResult[ 2 ],
execResult[ 3 ],
execResult[ 4 ]
];
}
}, {
re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
parse: function( execResult ) {
return [
execResult[ 1 ] * 2.55,
execResult[ 2 ] * 2.55,
execResult[ 3 ] * 2.55,
execResult[ 4 ]
];
}
}, {
// this regex ignores A-F because it's compared against an already lowercased string
re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
parse: function( execResult ) {
return [
parseInt( execResult[ 1 ], 16 ),
parseInt( execResult[ 2 ], 16 ),
parseInt( execResult[ 3 ], 16 )
];
}
}, {
// this regex ignores A-F because it's compared against an already lowercased string
re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
parse: function( execResult ) {
return [
parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
];
}
}, {
re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
space: "hsla",
parse: function( execResult ) {
return [
execResult[ 1 ],
execResult[ 2 ] / 100,
execResult[ 3 ] / 100,
execResult[ 4 ]
];
}
}],
// jQuery.Color( )
color = jQuery.Color = function( color, green, blue, alpha ) {
return new jQuery.Color.fn.parse( color, green, blue, alpha );
},
spaces = {
rgba: {
props: {
red: {
idx: 0,
type: "byte"
},
green: {
idx: 1,
type: "byte"
},
blue: {
idx: 2,
type: "byte"
}
}
},
hsla: {
props: {
hue: {
idx: 0,
type: "degrees"
},
saturation: {
idx: 1,
type: "percent"
},
lightness: {
idx: 2,
type: "percent"
}
}
}
},
propTypes = {
"byte": {
floor: true,
max: 255
},
"percent": {
max: 1
},
"degrees": {
mod: 360,
floor: true
}
},
support = color.support = {},
// element for support tests
supportElem = jQuery( "<p>" )[ 0 ],
// colors = jQuery.Color.names
colors,
// local aliases of functions called often
each = jQuery.each;
// determine rgba support immediately
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
// define cache name and alpha properties
// for rgba and hsla spaces
each( spaces, function( spaceName, space ) {
space.cache = "_" + spaceName;
space.props.alpha = {
idx: 3,
type: "percent",
def: 1
};
});
function clamp( value, prop, allowEmpty ) {
var type = propTypes[ prop.type ] || {};
if ( value == null ) {
return (allowEmpty || !prop.def) ? null : prop.def;
}
// ~~ is an short way of doing floor for positive numbers
value = type.floor ? ~~value : parseFloat( value );
// IE will pass in empty strings as value for alpha,
// which will hit this case
if ( isNaN( value ) ) {
return prop.def;
}
if ( type.mod ) {
// we add mod before modding to make sure that negatives values
// get converted properly: -10 -> 350
return (value + type.mod) % type.mod;
}
// for now all property types without mod have min and max
return 0 > value ? 0 : type.max < value ? type.max : value;
}
function stringParse( string ) {
var inst = color(),
rgba = inst._rgba = [];
string = string.toLowerCase();
each( stringParsers, function( i, parser ) {
var parsed,
match = parser.re.exec( string ),
values = match && parser.parse( match ),
spaceName = parser.space || "rgba";
if ( values ) {
parsed = inst[ spaceName ]( values );
// if this was an rgba parse the assignment might happen twice
// oh well....
inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
rgba = inst._rgba = parsed._rgba;
// exit each( stringParsers ) here because we matched
return false;
}
});
// Found a stringParser that handled it
if ( rgba.length ) {
// if this came from a parsed string, force "transparent" when alpha is 0
// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
if ( rgba.join() === "0,0,0,0" ) {
jQuery.extend( rgba, colors.transparent );
}
return inst;
}
// named colors
return colors[ string ];
}
color.fn = jQuery.extend( color.prototype, {
parse: function( red, green, blue, alpha ) {
if ( red === undefined ) {
this._rgba = [ null, null, null, null ];
return this;
}
if ( red.jquery || red.nodeType ) {
red = jQuery( red ).css( green );
green = undefined;
}
var inst = this,
type = jQuery.type( red ),
rgba = this._rgba = [];
// more than 1 argument specified - assume ( red, green, blue, alpha )
if ( green !== undefined ) {
red = [ red, green, blue, alpha ];
type = "array";
}
if ( type === "string" ) {
return this.parse( stringParse( red ) || colors._default );
}
if ( type === "array" ) {
each( spaces.rgba.props, function( key, prop ) {
rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
});
return this;
}
if ( type === "object" ) {
if ( red instanceof color ) {
each( spaces, function( spaceName, space ) {
if ( red[ space.cache ] ) {
inst[ space.cache ] = red[ space.cache ].slice();
}
});
} else {
each( spaces, function( spaceName, space ) {
var cache = space.cache;
each( space.props, function( key, prop ) {
// if the cache doesn't exist, and we know how to convert
if ( !inst[ cache ] && space.to ) {
// if the value was null, we don't need to copy it
// if the key was alpha, we don't need to copy it either
if ( key === "alpha" || red[ key ] == null ) {
return;
}
inst[ cache ] = space.to( inst._rgba );
}
// this is the only case where we allow nulls for ALL properties.
// call clamp with alwaysAllowEmpty
inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
});
// everything defined but alpha?
if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
// use the default of 1
inst[ cache ][ 3 ] = 1;
if ( space.from ) {
inst._rgba = space.from( inst[ cache ] );
}
}
});
}
return this;
}
},
is: function( compare ) {
var is = color( compare ),
same = true,
inst = this;
each( spaces, function( _, space ) {
var localCache,
isCache = is[ space.cache ];
if (isCache) {
localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
each( space.props, function( _, prop ) {
if ( isCache[ prop.idx ] != null ) {
same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
return same;
}
});
}
return same;
});
return same;
},
_space: function() {
var used = [],
inst = this;
each( spaces, function( spaceName, space ) {
if ( inst[ space.cache ] ) {
used.push( spaceName );
}
});
return used.pop();
},
transition: function( other, distance ) {
var end = color( other ),
spaceName = end._space(),
space = spaces[ spaceName ],
startColor = this.alpha() === 0 ? color( "transparent" ) : this,
start = startColor[ space.cache ] || space.to( startColor._rgba ),
result = start.slice();
end = end[ space.cache ];
each( space.props, function( key, prop ) {
var index = prop.idx,
startValue = start[ index ],
endValue = end[ index ],
type = propTypes[ prop.type ] || {};
// if null, don't override start value
if ( endValue === null ) {
return;
}
// if null - use end
if ( startValue === null ) {
result[ index ] = endValue;
} else {
if ( type.mod ) {
if ( endValue - startValue > type.mod / 2 ) {
startValue += type.mod;
} else if ( startValue - endValue > type.mod / 2 ) {
startValue -= type.mod;
}
}
result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
}
});
return this[ spaceName ]( result );
},
blend: function( opaque ) {
// if we are already opaque - return ourself
if ( this._rgba[ 3 ] === 1 ) {
return this;
}
var rgb = this._rgba.slice(),
a = rgb.pop(),
blend = color( opaque )._rgba;
return color( jQuery.map( rgb, function( v, i ) {
return ( 1 - a ) * blend[ i ] + a * v;
}));
},
toRgbaString: function() {
var prefix = "rgba(",
rgba = jQuery.map( this._rgba, function( v, i ) {
return v == null ? ( i > 2 ? 1 : 0 ) : v;
});
if ( rgba[ 3 ] === 1 ) {
rgba.pop();
prefix = "rgb(";
}
return prefix + rgba.join() + ")";
},
toHslaString: function() {
var prefix = "hsla(",
hsla = jQuery.map( this.hsla(), function( v, i ) {
if ( v == null ) {
v = i > 2 ? 1 : 0;
}
// catch 1 and 2
if ( i && i < 3 ) {
v = Math.round( v * 100 ) + "%";
}
return v;
});
if ( hsla[ 3 ] === 1 ) {
hsla.pop();
prefix = "hsl(";
}
return prefix + hsla.join() + ")";
},
toHexString: function( includeAlpha ) {
var rgba = this._rgba.slice(),
alpha = rgba.pop();
if ( includeAlpha ) {
rgba.push( ~~( alpha * 255 ) );
}
return "#" + jQuery.map( rgba, function( v ) {
// default to 0 when nulls exist
v = ( v || 0 ).toString( 16 );
return v.length === 1 ? "0" + v : v;
}).join("");
},
toString: function() {
return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
}
});
color.fn.parse.prototype = color.fn;
// hsla conversions adapted from:
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
function hue2rgb( p, q, h ) {
h = ( h + 1 ) % 1;
if ( h * 6 < 1 ) {
return p + (q - p) * h * 6;
}
if ( h * 2 < 1) {
return q;
}
if ( h * 3 < 2 ) {
return p + (q - p) * ((2/3) - h) * 6;
}
return p;
}
spaces.hsla.to = function ( rgba ) {
if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
return [ null, null, null, rgba[ 3 ] ];
}
var r = rgba[ 0 ] / 255,
g = rgba[ 1 ] / 255,
b = rgba[ 2 ] / 255,
a = rgba[ 3 ],
max = Math.max( r, g, b ),
min = Math.min( r, g, b ),
diff = max - min,
add = max + min,
l = add * 0.5,
h, s;
if ( min === max ) {
h = 0;
} else if ( r === max ) {
h = ( 60 * ( g - b ) / diff ) + 360;
} else if ( g === max ) {
h = ( 60 * ( b - r ) / diff ) + 120;
} else {
h = ( 60 * ( r - g ) / diff ) + 240;
}
// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
if ( diff === 0 ) {
s = 0;
} else if ( l <= 0.5 ) {
s = diff / add;
} else {
s = diff / ( 2 - add );
}
return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
};
spaces.hsla.from = function ( hsla ) {
if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
return [ null, null, null, hsla[ 3 ] ];
}
var h = hsla[ 0 ] / 360,
s = hsla[ 1 ],
l = hsla[ 2 ],
a = hsla[ 3 ],
q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
p = 2 * l - q;
return [
Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
Math.round( hue2rgb( p, q, h ) * 255 ),
Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
a
];
};
each( spaces, function( spaceName, space ) {
var props = space.props,
cache = space.cache,
to = space.to,
from = space.from;
// makes rgba() and hsla()
color.fn[ spaceName ] = function( value ) {
// generate a cache for this space if it doesn't exist
if ( to && !this[ cache ] ) {
this[ cache ] = to( this._rgba );
}
if ( value === undefined ) {
return this[ cache ].slice();
}
var ret,
type = jQuery.type( value ),
arr = ( type === "array" || type === "object" ) ? value : arguments,
local = this[ cache ].slice();
each( props, function( key, prop ) {
var val = arr[ type === "object" ? key : prop.idx ];
if ( val == null ) {
val = local[ prop.idx ];
}
local[ prop.idx ] = clamp( val, prop );
});
if ( from ) {
ret = color( from( local ) );
ret[ cache ] = local;
return ret;
} else {
return color( local );
}
};
// makes red() green() blue() alpha() hue() saturation() lightness()
each( props, function( key, prop ) {
// alpha is included in more than one space
if ( color.fn[ key ] ) {
return;
}
color.fn[ key ] = function( value ) {
var vtype = jQuery.type( value ),
fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
local = this[ fn ](),
cur = local[ prop.idx ],
match;
if ( vtype === "undefined" ) {
return cur;
}
if ( vtype === "function" ) {
value = value.call( this, cur );
vtype = jQuery.type( value );
}
if ( value == null && prop.empty ) {
return this;
}
if ( vtype === "string" ) {
match = rplusequals.exec( value );
if ( match ) {
value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
}
}
local[ prop.idx ] = value;
return this[ fn ]( local );
};
});
});
// add cssHook and .fx.step function for each named hook.
// accept a space separated string of properties
color.hook = function( hook ) {
var hooks = hook.split( " " );
each( hooks, function( i, hook ) {
jQuery.cssHooks[ hook ] = {
set: function( elem, value ) {
var parsed, curElem,
backgroundColor = "";
if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
value = color( parsed || value );
if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
curElem = hook === "backgroundColor" ? elem.parentNode : elem;
while (
(backgroundColor === "" || backgroundColor === "transparent") &&
curElem && curElem.style
) {
try {
backgroundColor = jQuery.css( curElem, "backgroundColor" );
curElem = curElem.parentNode;
} catch ( e ) {
}
}
value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
backgroundColor :
"_default" );
}
value = value.toRgbaString();
}
try {
elem.style[ hook ] = value;
} catch( e ) {
// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
}
}
};
jQuery.fx.step[ hook ] = function( fx ) {
if ( !fx.colorInit ) {
fx.start = color( fx.elem, hook );
fx.end = color( fx.end );
fx.colorInit = true;
}
jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
};
});
};
color.hook( stepHooks );
jQuery.cssHooks.borderColor = {
expand: function( value ) {
var expanded = {};
each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
expanded[ "border" + part + "Color" ] = value;
});
return expanded;
}
};
// Basic color names only.
// Usage of any of the other color names requires adding yourself or including
// jquery.color.svg-names.js.
colors = jQuery.Color.names = {
// 4.1. Basic color keywords
aqua: "#00ffff",
black: "#000000",
blue: "#0000ff",
fuchsia: "#ff00ff",
gray: "#808080",
green: "#008000",
lime: "#00ff00",
maroon: "#800000",
navy: "#000080",
olive: "#808000",
purple: "#800080",
red: "#ff0000",
silver: "#c0c0c0",
teal: "#008080",
white: "#ffffff",
yellow: "#ffff00",
// 4.2.3. "transparent" color keyword
transparent: [ null, null, null, 0 ],
_default: "#ffffff"
};
})( jQuery );

View file

@ -0,0 +1,82 @@
// jsr_class.js
//
// JSONscriptRequest -- a simple class for making HTTP requests
// using dynamically generated script tags and JSON
//
// Author: Jason Levitt
// Date: December 7th, 2005
//
// A SECURITY WARNING FROM DOUGLAS CROCKFORD:
// "The dynamic <script> tag hack suffers from a problem. It allows a page
// to access data from any server in the web, which is really useful.
// Unfortunately, the data is returned in the form of a script. That script
// can deliver the data, but it runs with the same authority as scripts on
// the base page, so it is able to steal cookies or misuse the authorization
// of the user with the server. A rogue script can do destructive things to
// the relationship between the user and the base server."
//
// So, be extremely cautious in your use of this script.
//
//
// Sample Usage:
//
// <script type="text/javascript" src="jsr_class.js"></script>
//
// function callbackfunc(jsonData) {
// alert('Latitude = ' + jsonData.ResultSet.Result[0].Latitude +
// ' Longitude = ' + jsonData.ResultSet.Result[0].Longitude);
// aObj.removeScriptTag();
// }
//
// request = 'http://api.local.yahoo.com/MapsService/V1/geocode?appid=YahooDemo&
// output=json&callback=callbackfunc&location=78704';
// aObj = new JSONscriptRequest(request);
// aObj.buildScriptTag();
// aObj.addScriptTag();
//
//
// Constructor -- pass a REST request URL to the constructor
//
function JSONscriptRequest(fullUrl) {
// REST request path
this.fullUrl = fullUrl;
// Keep IE from caching requests
this.noCacheIE = '&noCacheIE=' + (new Date()).getTime();
// Get the DOM location to put the script tag
this.headLoc = document.getElementsByTagName("head").item(0);
// Generate a unique script tag id
this.scriptId = 'JscriptId' + JSONscriptRequest.scriptCounter++;
}
// Static script ID counter
JSONscriptRequest.scriptCounter = 1;
// buildScriptTag method
//
JSONscriptRequest.prototype.buildScriptTag = function () {
// Create the script tag
this.scriptObj = document.createElement("script");
// Add script object attributes
this.scriptObj.setAttribute("type", "text/javascript");
this.scriptObj.setAttribute("charset", "utf-8");
this.scriptObj.setAttribute("src", this.fullUrl + this.noCacheIE);
this.scriptObj.setAttribute("id", this.scriptId);
};
// removeScriptTag method
//
JSONscriptRequest.prototype.removeScriptTag = function () {
// Destroy the script tag
this.headLoc.removeChild(this.scriptObj);
};
// addScriptTag method
//
JSONscriptRequest.prototype.addScriptTag = function () {
// Create the script tag
this.headLoc.appendChild(this.scriptObj);
};

View file

@ -271,67 +271,3 @@ function getEncodedURLFor(visType){
var queryString = "uri="+ egoURI + "&vis=" + visType;
return location.protocol + "//" + location.host + contextPath + visualizationDataRoot + '?' + queryString.replace(/&/g, '%26');
}
function renderCollaborationshipVisualization() {
// console.log('visualization is ' + visualization + ' and encodedURL is '+ encodedURL);
// Version check for the Flash Player that has the ability to start Player
// Product Install (6.0r65)
var hasProductInstall = DetectFlashVer(6, 0, 65);
// Version check based upon the values defined in globals
var hasRequestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
if ( hasProductInstall && !hasRequestedVersion ) {
// DO NOT MODIFY THE FOLLOWING FOUR LINES
// Location visited after installation is complete if installation is
// required
var MMPlayerType = (isIE == true) ? "ActiveX" : "PlugIn";
var MMredirectURL = window.location;
document.title = document.title.slice(0, 47) + " - Flash Player Installation";
var MMdoctitle = document.title;
AC_FL_RunContent(
"src", "playerProductInstall",
"FlashVars", "MMredirectURL="+MMredirectURL+'&MMplayerType='+MMPlayerType+'&MMdoctitle='+MMdoctitle+"",
"width", "800",
"height", "840",
"align", "middle",
"id", "EgoCentric",
"quality", "high",
"bgcolor", "#ffffff",
"name", "EgoCentric",
"allowScriptAccess","sameDomain",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer"
);
} else if (hasRequestedVersion) {
// if we've detected an acceptable version
// embed the Flash Content SWF when all tests are passed
//coAuthorUrl=/vivo1/visualization?vis=coauthorship%26render_mode=data%26uri=http%3A%2F%2Fvivo.iu.edu%2Findividual%2FBrnerKaty&labelField=label&coPIUrl=/vivo1/visualization?vis=coprincipalinvestigator%26render_mode=data%26uri=http%3A%2F%2Fvivo.iu.edu%2Findividual%2FBrnerKaty&labelField=label
AC_FL_RunContent(
"src", swfLink,
// "flashVars", 'coAuthorUrl='+ encodeURL(egoCoAuthorshipDataFeederURL) + '&coPIUrl=' + encodeURL(egoCoPIDataFeederURL) ,
// "flashVars", 'coAuthorUrl='+ getEncodedCoAuthorURL() + '&coPIUrl=' + getEncodedCoPIURL() ,
// "flashVars", 'graphmlUrl=' + getEncodedCoAuthorURL() + '&labelField=label&visType=CoAuthor',
"flashVars", 'graphmlUrl=' + getEncodedURLFor(visType) + '&labelField=label&visType='+visKeyForFlash,
"width", "600",
"height", "850",
"align", "top",
"id", "EgoCentric",
"quality", "high",
"bgcolor", "#ffffff",
"name", "EgoCentric",
"allowScriptAccess","sameDomain",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer"
);
} else { // flash is too old or we can't detect the plugin
var alternateContent = '<br /><h3 style="color: red;">'
+ i18nStringsPersonLvl.contentRequiresFlash + ' '
+ '<a href=http://www.adobe.com/go/getflash/>' + i18nStringsPersonLvl.getFlashString + '</a></h3>';
document.write(alternateContent); // insert non-flash content
}
}

View file

@ -0,0 +1,167 @@
${scripts.add(
'<script type="text/javascript" src="${urls.base}/js/d3.min.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/visualization/capabilitymap/jquery.color.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/visualization/capabilitymap/jsr_class.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/visualization/capabilitymap/graph_new.js"></script>'
)}
${stylesheets.add(
'<link rel="stylesheet" href="${urls.base}/js/jquery-ui/css/smoothness/jquery-ui-1.8.9.custom.css" />',
'<link rel="stylesheet" type="text/css" href="${urls.base}/templates/freemarker/edit/forms/css/autocomplete.css" />',
'<link rel="stylesheet" type="text/css" href="${urls.base}/css/visualization/personlevel/page.css" />',
'<link rel="stylesheet" type="text/css" href="${urls.base}/css/visualization/visualization.css" />',
'<link rel="stylesheet" type="text/css" href="${urls.base}/css/visualization/capabilitymap/graph.css" />'
)}
<script language="JavaScript" type="text/javascript">
var contextPath = "${urls.base}";
$(document).ready(function() {
var loadedConcepts = $.ajax({
url: contextPath + "/visualizationAjax?vis=capabilitymap&data=concepts",
type: "GET",
async: false,
success: function(result) {
return result;
}
});
var conceptArray = $.parseJSON(loadedConcepts.responseText);
$("#query").autocomplete({
source: conceptArray
});
});
</script>
<div class="main" id="main-content" role="main">
<div class="col-8">
<h2>Capability Map</h2>
<p>Build a &lsquo;first pass&rsquo; capability map by typing in a<!-- set of--> search term<!--s--> that could be said to represent a broad research capability.</p>
</div>
<div id="queryform">
<p>
<span>
<input name="query" id="query" size="34" value="" onfocus="" accesskey="q" onblur="" type="text" onkeydown="queryKeyDown(event);">
<label id="cutofflabel" for="queryCutoff">Cutoff:</label>
<input id="queryCutoff" name="queryCutoff" type="text" title="Cutoff" size="4" value="10">
<input type="submit" value="Search" id="add" type="button" onclick="addKwd();">
<input value="Search and Expand" type="submit" id="sExpand" onclick="expandLastQuery = 1; addKwd();">
<input value="Reset" id="resetButton" type="submit" onclick="reset()" disabled>
<!-- a style="display:inline-block; float:right; line-height:32px; height:32px; cursor:pointer" onclick="showhideadvanced(this)">Show advanced</a -->
</span>
</p>
</div>
<hr style="clear:both;">
<div id="container">
<div id="helptext">
<p>
Welcome to the Capability Mapping tool.
This tool visualises how researchers relate to other
researchers via search terms.
</p>
<h3>Getting Started</h3>
<p>
Enter a research area into the search field above and press Search.
The resulting diagram displays the search term, rendered in orange,
connected to the blue group of researchers that are active in that area.
Enter another search term to see how researchers from both searches relate.
Keep adding search terms to build a capability map.
</p>
<p>
Tip: you can expand a broad search term into smaller concepts
by clicking &lsquo;search and expand&rsquo;.
</p>
<h3>Interacting with the visualisation</h3>
<p>
By clicking on any node in the visualisation,
additional information can be viewed in the
Info tab on the right-hand side.
For groups of people, the participants in the group
and their information can be viewed,
and individual researchers can be removed from the graph.
Selecting a search term will display all attached groups.
Under each group full information for each person is retrieved,
and the number of matching grants and publications
for each researcher within the mapped capabilities is shown.
Clicking on a researcher's name will lead to the original search
results.
</p>
<h4>Visual cues</h4>
<p>
To make the visualisation easier to read,
search terms and groups are scaled according
to the number of results returned.
Groups are also given different shades
according to the number of connected search terms.
The darker the shade, the more search terms a group is connected to.
</p>
<h3>Advanced features</h3>
<h4>Changing the cutoff value</h4>
<p>
The amount of researchers retrieved for each search term
for is limited by the cutoff value in the search form
(10 by default).
Increasing this cutoff will increase the likelihood
of an intersection between different search terms.
This will also increase the complexity of the graph,
however, and may make it difficult to identify patterns.
</p>
</div>
<div id="center-container">
<div id="log"></div>
<div id="infovis"></div>
<div class="progress"><div id="progressbar"></div></div>
</div>
<div id="right-container">
<div class="tabs">
<ul class="titles">
<li><a href="#demo">Search terms</a></li>
<li><a href="#logg">Info</a></li>
<!-- li><a href="#extractData">Data</a></li -->
</ul>
<div class="result_body">
<div class="result_section" id="demo">
<h2>Current search terms</h2>
<ul id="log_printout">
<li>This panel displays a list of the search terms currently
on the graph. Search for something to begin.</li>
</ul>
<p style="position:absolute; bottom:10px">
<img src="${urls.base}/images/visualization/capabilitymap/key.png" alt="Key">
</p>
</div>
<div class="result_section" id="logg">
<div id="inner-details">
<p>
This panel displays information about individual
search terms and groups. Click on a group to display
its information.
</p>
</div>
</div>
<!-- div class="result_section" id="extractData">
<h2>Extract Data</h2>
<p>
Import:
<button disabled>SVG</button>
<button onclick="importGraphDetails();">JSON</button>
<br>
Export:
<button onclick="generateGraphSVG();">SVG</button>
<button onclick="download(g.export(), 'json')">JSON</button>
<button onclick="download(g.toDOT(), 'gv')">DOT</button>
<button onclick="generateGraphPersonList();">MRW</button>
</p>
<textarea id="graphDetails" style="width:99%; height:450px; border:1px solid #EEE; padding:0px;"></textarea>
</div -->
</div>
</div>
</div>
</div>
</div>

View file

@ -1,262 +0,0 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#assign standardVisualizationURLRoot ="/visualization">
<#assign shortVisualizationURLRoot ="/vis">
<#assign ajaxVisualizationURLRoot ="/visualizationAjax">
<#assign dataVisualizationURLRoot ="/visualizationData">
<#assign egoURI ="${egoURIParam?url}">
<#assign egoCoAuthorshipDataFeederURL = '${urls.base}${dataVisualizationURLRoot}?vis=coauthorship&uri=${egoURI}&vis_mode=coauthor_network_stream&labelField=label'>
<#if egoLocalName?has_content >
<#assign coprincipalinvestigatorURL = '${urls.base}${shortVisualizationURLRoot}/investigator-network/${egoLocalName}'>
<#else>
<#assign coprincipalinvestigatorURL = '${urls.base}${shortVisualizationURLRoot}/investigator-network/?uri=${egoURI}'>
</#if>
<#assign egoCoAuthorsListDataFileURL = '${urls.base}${dataVisualizationURLRoot}?vis=coauthorship&uri=${egoURI}&vis_mode=coauthors'>
<#assign egoCoAuthorshipNetworkDataFileURL = '${urls.base}${dataVisualizationURLRoot}?vis=coauthorship&uri=${egoURI}&vis_mode=coauthor_network_download'>
<#assign swfLink = '${urls.images}/visualization/coauthorship/EgoCentric.swf'>
<#assign adobeFlashDetector = '${urls.base}/js/visualization/coauthorship/AC_OETags.js'>
<#assign googleVisualizationAPI = 'https://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22areachart%22%2C%22imagesparkline%22%5D%7D%5D%7D'>
<#assign coAuthorPersonLevelJavaScript = '${urls.base}/js/visualization/coauthorship/coauthorship-personlevel.js'>
<#assign commonPersonLevelJavaScript = '${urls.base}/js/visualization/personlevel/person-level.js'>
<#assign coInvestigatorIcon = '${urls.images}/visualization/coauthorship/co_investigator_icon.png'>
<script type="text/javascript" src="${adobeFlashDetector}"></script>
<script type="text/javascript" src="${googleVisualizationAPI}"></script>
<script language="JavaScript" type="text/javascript">
<!--
// -----------------------------------------------------------------------------
// Globals
// Major version of Flash required
var requiredMajorVersion = 10;
// Minor version of Flash required
var requiredMinorVersion = 0;
// Minor version of Flash required
var requiredRevision = 0;
// -----------------------------------------------------------------------------
var swfLink = "${swfLink}";
var egoURI = "${egoURI}";
var unEncodedEgoURI = "${egoURIParam}";
var egoCoAuthorshipDataFeederURL = "${egoCoAuthorshipDataFeederURL}";
var egoCoAuthorsListDataFileURL = "${egoCoAuthorsListDataFileURL}";
var contextPath = "${urls.base}";
var visualizationDataRoot = "${dataVisualizationURLRoot}";
// -->
var i18nStringsCoauthorship = {
coAuthorsString: '${i18n().co_authors_capitalized}',
authorString: '${i18n().author_capitalized}',
publicationsWith: '${i18n().publications_with}',
publicationsString: "${i18n().through_today}",
coauthorsString: '${i18n().co_author_s_capitalized}'
};
var i18nStringsPersonLvl = {
fileCapitalized: '${i18n().file_capitalized}',
contentRequiresFlash: '${i18n().content_requires_flash}',
getFlashString: '${i18n().get_flash}'
};
</script>
<script type="text/javascript" src="${coAuthorPersonLevelJavaScript}"></script>
<script type="text/javascript" src="${commonPersonLevelJavaScript}"></script>
${scripts.add('<script type="text/javascript" src="${urls.base}/js/visualization/visualization-helper-functions.js"></script>')}
${stylesheets.add('<link rel="stylesheet" type="text/css" href="${urls.base}/css/visualization/personlevel/page.css" />',
'<link rel="stylesheet" type="text/css" href="${urls.base}/css/visualization/visualization.css" />')}
<#assign loadingImageLink = "${urls.images}/visualization/ajax-loader.gif">
<#assign egoVivoProfileURL = "${urls.base}/individual?uri=${egoURI}" />
<script language="JavaScript" type="text/javascript">
$(document).ready(function(){
<#if (numOfCoAuthorShips?? && numOfCoAuthorShips > 0) >
$("#coauth_table_container").empty().html('<img id="loadingData" width="auto" src="${loadingImageLink}" alt="${i18n().loading_data}"/>');
</#if>
processProfileInformation("ego_label",
"ego_moniker",
"ego_profile_image",
jQuery.parseJSON(getWellFormedURLs("${egoURIParam}", "profile_info")));
<#if (numOfCoAuthorShips?? && numOfCoAuthorShips <= 0) || (numOfAuthors?? && numOfAuthors <= 0) >
if ($('#ego_label').text().length > 0) {
setProfileName('no_coauthorships_person', $('#ego_label').text());
}
</#if>
$.ajax({
url: "${urls.base}/visualizationAjax",
data: ({vis: "utilities", vis_mode: "SHOW_GRANTS_LINK", uri: '${egoURIParam}'}),
dataType: "json",
success:function(data){
/*
Collaboratorship links do not show up by default. They should show up only if there any data to
show on that page.
*/
if (data.numOfGrants !== undefined && data.numOfGrants > 0) {
$(".toggle_visualization").show();
}
}
});
});
</script>
<div id="body">
<div class="sub_headings"><h2><a href="${egoVivoProfileURL}" title="${i18n().author_name}"><span id="ego_label"></span></a><br />${i18n().co_author_network} </h2></div>
<#if (numOfCoAuthorShips?? && numOfCoAuthorShips > 0) || (numOfAuthors?? && numOfAuthors > 0) >
<div class = "graphml-file-link">(<a href="${egoCoAuthorshipNetworkDataFileURL}" title="GraphML ${i18n().file}">GraphML ${i18n().file}</a>)</div>
<#else>
<#if numOfAuthors?? && numOfAuthors <= 0 >
<#assign authorsText = "multi-author" />
</#if>
<div id="no_coauthorships">${i18n().currently_no_papers_for(authorsText!)}
<a href="${egoVivoProfileURL}" title="${i18n().co_authorship}"><span id="no_coauthorships_person" class="author_name">${i18n().this_author}</span></a> ${i18n().in_the_vivo_db}
</div>
</#if>
<div class = "toggle_visualization">
<div id="coinvestigator_link_container" class="collaboratorship-link-container">
<div class="collaboratorship-icon"><a href="${coprincipalinvestigatorURL}" title="${i18n().co_investigator}"><img src="${coInvestigatorIcon}" alt="${i18n().co_investigator_icon}"/></a></div>
<div class="collaboratorship-link">
<h3><a href="${coprincipalinvestigatorURL}" title="${i18n().co_investigator_network}">${i18n().co_investigator_network_capitalized}</a></h3>
</div>
</div>
</div>
<#if (builtFromCacheTime??) >
<div class="cache-info-small">${i18n().using_cache_time} ${builtFromCacheTime?time} (${builtFromCacheTime?date?string("MMM dd yyyy")})</div>
</#if>
<div style="clear:both;"></div>
<#if (numOfAuthors?? && numOfAuthors > 0) >
<#else>
<span id="no_coauthorships">${i18n().no_papers_for}
<a href="${egoVivoProfileURL}" title="${i18n().co_authorship}"><span id="no_coauthorships_person" class="author_name">${i18n().this_author}</span></a> ${i18n().in_the_vivo_db}
</span>
</#if>
<#if (numOfCoAuthorShips?? && numOfCoAuthorShips > 0) || (numOfAuthors?? && numOfAuthors > 0) >
<div id="bodyPannel">
<div id="visPanel">
<script language="JavaScript" type="text/javascript">
<!--
renderCollaborationshipVisualization();
//-->
</script>
</div>
<div id="dataPanel">
<h4 id ="profileTitle">${i18n().profile_capitalized}</h4>
<div id="data-panel-content">
<div id="profileImage" class="thumbnail"></div>
<h4><span id="authorName" class="neutral_author_name">&nbsp;</span></h4>
<em id="profileMoniker" class="moniker"></em>
<div id="profile-links"><a href="#" id="profileUrl" title="${i18n().vivo_profile}">${i18n().vivo_profile}</a></div>
<div class="author_stats" id="num_works"><span class="numbers" style="width: 40px;" id="works"></span>&nbsp;&nbsp;
<span class="author_stats_text">${i18n().publication_s_capitalized}</span></div>
<div class="author_stats" id="num_authors"><span class="numbers" style="width: 40px;" id="coAuthors"></span>
&nbsp;&nbsp;<span class="author_stats_text">${i18n().co_author_s_capitalized}</span></div>
<div class="author_stats" id="fPub" style="visibility:hidden">
<span class="numbers" style="width:40px;" id="firstPublication"></span>&nbsp;&nbsp;<span>${i18n().first_publication}</span></div>
<div class="author_stats" id="lPub" style="visibility:hidden"><span class="numbers" style="width:40px;" id="lastPublication"></span>
&nbsp;&nbsp;<span>${i18n().last_publication}</span></div>
<div id="incomplete-data">${i18n().incomplete_data_note1}<p></p><p></p>
<#if user.loggedIn >
${i18n().incomplete_data_note2}
<#else>
${i18n().incomplete_data_note3}
</#if>
</div>
</div>
</div>
</div>
</#if>
<#if (numOfAuthors?? && numOfAuthors > 0) >
<#-- Sparkline -->
<div id="sparkline-container">
<#assign displayTable = false />
<#assign sparklineVO = egoPubSparklineVO />
<div id="publication-count-sparkline-include"><#include "personPublicationSparklineContent.ftl"></div>
<#assign sparklineVO = uniqueCoauthorsSparklineVO />
<div id="coauthor-count-sparkline-include"><#include "coAuthorshipSparklineContent.ftl"></div>
</div>
<div class="vis_stats">
<div class="sub_headings" id="table_heading"><h3>${i18n().tables_capitalized}</h3></div>
<div class="vis-tables">
<p id="publications_table_container" class="datatable">
<#assign tableID = "publication_data_table" />
<#assign tableCaption = "${i18n().publications_per_year} " />
<#assign tableActivityColumnName = "${i18n().publications_capitalized}" />
<#assign tableContent = egoPubSparklineVO.yearToActivityCount />
<#assign fileDownloadLink = egoPubSparklineVO.downloadDataLink />
<#include "yearToActivityCountTable.ftl">
</p>
</div>
<#if (numOfCoAuthorShips?? && numOfCoAuthorShips > 0) >
<div class="vis-tables">
<p id="coauth_table_container" class="datatable"></p>
</div>
</#if>
<div style="clear:both"></div>
</div>
</#if>
</div>

View file

@ -1,261 +0,0 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#assign standardVisualizationURLRoot ="/visualization">
<#assign shortVisualizationURLRoot ="/vis">
<#assign ajaxVisualizationURLRoot ="/visualizationAjax">
<#assign dataVisualizationURLRoot ="/visualizationData">
<#assign egoURI ="${egoURIParam?url}">
<#assign egoCoInvestigationDataFeederURL = '${urls.base}${dataVisualizationURLRoot}?vis=coprincipalinvestigator&uri=${egoURI}&vis_mode=copi_network_stream&labelField=label'>
<#assign coauthorshipURL = '${urls.base}${shortVisualizationURLRoot}/author-network/?uri=${egoURI}'>
<#if egoLocalName?has_content >
<#assign coauthorshipURL = '${urls.base}${shortVisualizationURLRoot}/author-network/${egoLocalName}'>
<#else>
<#assign coauthorshipURL = '${urls.base}${shortVisualizationURLRoot}/author-network/?uri=${egoURI}'>
</#if>
<#assign egoCoInvestigatorsListDataFileURL = '${urls.base}${dataVisualizationURLRoot}?vis=coprincipalinvestigator&uri=${egoURI}&vis_mode=copis'>
<#assign egoCoInvestigationNetworkDataFileURL = '${urls.base}${dataVisualizationURLRoot}?vis=coprincipalinvestigator&uri=${egoURI}&vis_mode=copi_network_download'>
<#assign coAuthorIcon = '${urls.images}/visualization/coauthorship/co_author_icon.png'>
<#assign swfLink = '${urls.images}/visualization/coauthorship/EgoCentric.swf'>
<#assign adobeFlashDetector = '${urls.base}/js/visualization/coauthorship/AC_OETags.js'>
<#assign googleVisualizationAPI = 'https://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22areachart%22%2C%22imagesparkline%22%5D%7D%5D%7D'>
<#assign coInvestigatorPersonLevelJavaScript = '${urls.base}/js/visualization/coPIship/coPIship-person-level.js'>
<#assign commonPersonLevelJavaScript = '${urls.base}/js/visualization/personlevel/person-level.js'>
<script type="text/javascript" src="${adobeFlashDetector}"></script>
<script type="text/javascript" src="${googleVisualizationAPI}"></script>
<script language="JavaScript" type="text/javascript">
<!--
// -----------------------------------------------------------------------------
// Globals
// Major version of Flash required
var requiredMajorVersion = 10;
// Minor version of Flash required
var requiredMinorVersion = 0;
// Minor version of Flash required
var requiredRevision = 0;
// -----------------------------------------------------------------------------
var swfLink = "${swfLink}";
var egoURI = "${egoURI}";
var unEncodedEgoURI = "${egoURIParam}";
var egoCoInvestigationDataFeederURL = "${egoCoInvestigationDataFeederURL}";
var egoCoInvestigatorsListDataFileURL = "${egoCoInvestigatorsListDataFileURL}";
var contextPath = "${urls.base}";
var visualizationDataRoot = "${dataVisualizationURLRoot}";
// -->
var i18nStringsCoPi = {
coInvestigatorString: '${i18n().co_inestigators_capitalized}',
investigatorString: '${i18n().investigator_capitalized}',
grantsWithString: '${i18n().grants_with}',
grantsCapitalized: '${i18n().grant_s_capitalized}',
coInvestigatorCapitalized: '${i18n().co_investigator_s_capitalized}'
};
var i18nStringsPersonLvl = {
fileCapitalized: '${i18n().file_capitalized}',
contentRequiresFlash: '${i18n().content_requires_flash}',
getFlashString: '${i18n().get_flash}'
};
</script>
<script type="text/javascript" src="${coInvestigatorPersonLevelJavaScript}"></script>
<script type="text/javascript" src="${commonPersonLevelJavaScript}"></script>
${scripts.add('<script type="text/javascript" src="${urls.base}/js/visualization/visualization-helper-functions.js"></script>')}
${stylesheets.add('<link rel="stylesheet" type="text/css" href="${urls.base}/css/visualization/personlevel/page.css" />',
'<link rel="stylesheet" type="text/css" href="${urls.base}/css/visualization/visualization.css" />')}
<#assign loadingImageLink = "${urls.images}/visualization/ajax-loader.gif">
<#assign egoVivoProfileURL = "${urls.base}/individual?uri=${egoURI}" />
<script language="JavaScript" type="text/javascript">
$(document).ready(function(){
<#if (numOfCoInvestigations?? && numOfCoInvestigations > 0) >
$("#coinve_table_container").empty().html('<img id="loadingData" width="auto" src="${loadingImageLink}" alt="${i18n().loading_data}"/>');
</#if>
processProfileInformation("ego_label",
"ego_moniker",
"ego_profile_image",
jQuery.parseJSON(getWellFormedURLs("${egoURIParam}", "profile_info")));
<#if (numOfCoInvestigations?? && numOfCoInvestigations <= 0) || (numOfInvestigators?? && numOfInvestigators <= 0) >
if ($('#ego_label').text().length > 0) {
setProfileName('no_coinvestigations_person', $('#ego_label').text());
}
</#if>
$.ajax({
url: "${urls.base}/visualizationAjax",
data: ({vis: "utilities", vis_mode: "SHOW_AUTHORSHIP_LINK", uri: '${egoURIParam}'}),
dataType: "json",
success:function(data){
/*
Collaboratorship links do not show up by default. They should show up only if there any data to
show on that page.
*/
if (data.numOfPublications !== undefined && data.numOfPublications > 0) {
$(".toggle_visualization").show();
}
}
});
});
</script>
<div id="body">
<div class="sub_headings"><h2><a href="${egoVivoProfileURL}" title="${i18n().investigator_name}"><span id="ego_label"></span></a><br />${i18n().co_investigator_network_capitalized} </h2></div>
<#if (numOfInvestigators?? && numOfInvestigators > 0) >
<#if (numOfCoInvestigations?? && numOfCoInvestigations > 0) || (numOfInvestigators?? && numOfInvestigators > 0) >
<div class = "graphml-file-link"><a href="${egoCoInvestigationNetworkDataFileURL}" title="${i18n().co_investigator}">(GraphML ${i18n().file_capitalized})</a></div>
<#else>
<#if numOfInvestigators?? && numOfInvestigators <= 0 >
<#assign investigatorsText = "multi-investigator" />
</#if>
<span id="no_coinvestigations">${i18n().currently_no_grants_for(investigatorsText!)}
<a href="${egoVivoProfileURL}" title="${i18n().investigator_name}"><span id="no_coinvestigations_person" class="investigator_name">${i18n().this_investigator}</span></a> ${i18n().in_the_vivo_db}
</span>
</#if>
<#else>
<span id="no_coinvestigations">${i18n().no_grants_for}
<a href="${egoVivoProfileURL}" title="${i18n().co_investigator}"><span id="no_coinvestigations_person" class="investigator_name">${i18n().this_investigator}</span></a> ${i18n().in_the_vivo_db}
</span>
</#if>
<div class = "toggle_visualization">
<div id="coauthorship_link_container" class="collaboratorship-link-container">
<div class="collaboratorship-icon"><a href="${coauthorshipURL}" title="${i18n().co_author}"><img src="${coAuthorIcon}" alt="${i18n().co_author_icon}"/></a></div>
<div class="collaboratorship-link">
<h3><a href="${coauthorshipURL}" title="${i18n().co_author_network}">${i18n().co_author_network}</a></h3>
</div>
</div>
</div>
<div style="clear:both;"></div>
<#if (numOfCoInvestigations?? && numOfCoInvestigations > 0) || (numOfInvestigators?? && numOfInvestigators > 0) >
<div id="bodyPannel">
<div id="visPanel">
<script language="JavaScript" type="text/javascript">
<!--
renderCollaborationshipVisualization();
//-->
</script>
</div>
<div id="dataPanel">
<h4 id ="profileTitle">${i18n().profile_capitalized}</h4>
<div id="data-panel-content">
<div id="profileImage" class="thumbnail"></div>
<h4><span id="investigatorName" class="neutral_investigator_name">&nbsp;</span></h4>
<em id="profileMoniker" class="moniker"></em>
<div id="profile-links"><a href="#" id="profileUrl" title="${i18n().vivo_profile}">${i18n().vivo_profile}</a></div>
<div class="investigator_stats" id="num_works"><span class="numbers" style="width: 40px;" id="works"></span>&nbsp;&nbsp;
<span class="investigator_stats_text">${i18n().grant_s_capitalized}</span></div>
<div class="investigator_stats" id="num_investigators"><span class="numbers" style="width: 40px;" id="coInvestigators"></span>
&nbsp;&nbsp;<span class="investigator_stats_text">${i18n().co_investigator_s_capitalized}</span></div>
<div class="investigator_stats" id="fGrant" style="visibility:hidden">
<span class="numbers" style="width:40px;" id="firstGrant"></span>&nbsp;&nbsp;<span>${i18n().first_grant}</span></div>
<div class="investigator_stats" id="lGrant" style="visibility:hidden"><span class="numbers" style="width:40px;" id="lastGrant"></span>
&nbsp;&nbsp;<span>${i18n().last_grant}</span></div>
<div id="incomplete-data">${i18n().incomplete_grant_data_note1}<p></p><p></p>
<#if user.loggedIn >
${i18n().incomplete_grant_data_note2}
<#else>
${i18n().incomplete_grant_data_note3}
</#if>
</div>
</div>
</div>
</div>
</#if>
<#if (numOfInvestigators?? && numOfInvestigators > 0) >
<#-- Sparkline -->
<div id="sparkline-container">
<#assign displayTable = false />
<#assign sparklineVO = egoGrantSparklineVO />
<div id="grant-count-sparkline-include"><#include "personGrantSparklineContent.ftl"></div>
<#assign sparklineVO = uniqueCoInvestigatorsSparklineVO />
<div id="coinvestigator-count-sparkline-include"><#include "coInvestigationSparklineContent.ftl"></div>
</div>
<div class="vis_stats">
<div class="sub_headings" id="table_heading"><h3>${i18n().tables_capitalized}</h3></div>
<p style="float:left;font-size:.9em">${i18n().grant_info_for_all_years}&nbsp;<img class="filterInfoIcon" width="16px" height="16px" id="imageIconThree" src="${urls.images}/iconInfo.png" alt="${i18n().info_icon}" title="${i18n().grant_sparkline_note}" /></p>
<div class="vis-tables">
<p id="grants_table_container" class="datatable">
<#assign tableID = "grant_data_table" />
<#assign tableCaption = "${i18n().grants_per_year}" />
<#assign tableActivityColumnName = "${i18n().grants_capitalized}" />
<#assign tableContent = egoGrantSparklineVO.yearToActivityCount />
<#assign fileDownloadLink = egoGrantSparklineVO.downloadDataLink />
<#include "yearToActivityCountTable.ftl">
</p>
</div>
<#if (numOfCoInvestigations?? && numOfCoInvestigations > 0) >
<div class="vis-tables">
<p id="coinve_table_container" class="datatable"></p>
</div>
</#if>
<div style="clear:both"></div>
</div>
</#if>
</div>

View file

@ -3,6 +3,7 @@
<meta charset="utf-8" />
<!-- Google Chrome Frame open source plug-in brings Google Chrome's open web technologies and speedy JavaScript engine to Internet Explorer-->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="generator" content="VIVO ${version.label}" />
<title>${(title?html)!siteName!}</title>