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:
commit
f4d75d838f
33 changed files with 3236 additions and 708 deletions
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>();
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
@ -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>>();
|
||||
}
|
|
@ -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>>();
|
||||
}
|
|
@ -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>>();
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
@ -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 .";
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,6 +54,12 @@ display:EventsMenuItem
|
|||
display:linkText "Events";
|
||||
display:toPage display:Events .
|
||||
|
||||
display:CapabilityMapMenuItem
|
||||
a display:NavigationElement ;
|
||||
display:menuPosition 6;
|
||||
display:linkText "Capability Map";
|
||||
display:toPage display:CapabilityMap .
|
||||
|
||||
display:Home
|
||||
a display:HomePage ;
|
||||
a display:Page ;
|
||||
|
@ -93,7 +100,11 @@ 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
|
||||
|
@ -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" .
|
||||
|
|
5
pom.xml
5
pom.xml
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
355
webapp/src/main/webapp/css/visualization/capabilitymap/graph.css
Executable file
355
webapp/src/main/webapp/css/visualization/capabilitymap/graph.css
Executable 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 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -7,13 +7,16 @@ $(document).ready(function(){
|
|||
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");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -44,11 +47,32 @@ $(document).ready(function(){
|
|||
$('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");
|
||||
|
@ -59,49 +83,66 @@ $(document).ready(function(){
|
|||
});
|
||||
}
|
||||
|
||||
// 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
|
||||
// this ensures both possibilities are covered
|
||||
|
@ -153,7 +194,7 @@ $(document).ready(function(){
|
|||
}
|
||||
}
|
||||
|
||||
function retrieveLocalStorage() {
|
||||
function retrieveLocalStorage(currentTab) {
|
||||
|
||||
var localName = this.individualLocalName;
|
||||
var selectedTab = amplify.store(individualLocalName);
|
||||
|
@ -186,6 +227,12 @@ $(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
|
||||
//prevent wrapping
|
||||
|
@ -231,6 +278,5 @@ $(document).ready(function(){
|
|||
$('ul.propertyTabsList li:last-child').css('width', newDiff + 'px');
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
|
1128
webapp/src/main/webapp/js/visualization/capabilitymap/graph_new.js
Executable file
1128
webapp/src/main/webapp/js/visualization/capabilitymap/graph_new.js
Executable file
File diff suppressed because it is too large
Load diff
663
webapp/src/main/webapp/js/visualization/capabilitymap/jquery.color.js
Executable file
663
webapp/src/main/webapp/js/visualization/capabilitymap/jquery.color.js
Executable 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 );
|
82
webapp/src/main/webapp/js/visualization/capabilitymap/jsr_class.js
Executable file
82
webapp/src/main/webapp/js/visualization/capabilitymap/jsr_class.js
Executable 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);
|
||||
};
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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 ‘first pass’ 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 ‘search and expand’.
|
||||
</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>
|
||||
|
|
@ -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"> </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>
|
||||
<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>
|
||||
<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> <span>${i18n().first_publication}</span></div>
|
||||
<div class="author_stats" id="lPub" style="visibility:hidden"><span class="numbers" style="width:40px;" id="lastPublication"></span>
|
||||
<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>
|
|
@ -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"> </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>
|
||||
<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>
|
||||
<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> <span>${i18n().first_grant}</span></div>
|
||||
<div class="investigator_stats" id="lGrant" style="visibility:hidden"><span class="numbers" style="width:40px;" id="lastGrant"></span>
|
||||
<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} <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>
|
|
@ -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>
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue