Initial support for tag cloud

This commit is contained in:
Kostas Stamatis
2014-06-24 15:45:39 +03:00
committed by Ivan Masár
parent 43b4af88a6
commit 2bc6e63e45
8 changed files with 734 additions and 2 deletions

View File

@@ -140,6 +140,11 @@
<version>1.2.1</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.mcavallo</groupId>
<artifactId>opencloud</artifactId>
<version>0.3</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,328 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.webui.tagcloud;
/**
* @author kstamatis
*
*/
public class TagCloudParameters {
String cloudCase;
String width;
String colorLevel1;
String colorLevel2;
String colorLevel3;
String weightLevel1;
String weightLevel2;
String weightLevel3;
String fontFrom;
String fontTo;
String marginRight;
String cuttingLevel;
String totalTags;
boolean randomColors;
String ordering;
boolean displayScore;
boolean shouldCenter;
String locale;
/**
*
*/
public TagCloudParameters() {
//Default values;
width = "100%";
cloudCase = "Case.PRESERVE_CASE";
colorLevel1 = "D96C27";
colorLevel2 = "424242";
colorLevel3 = "818183";
weightLevel1 = "normal";
weightLevel2 = "normal";
weightLevel3 = "normal";
fontFrom = "1.1";//"15";
fontTo = "3.2";//"40";
marginRight = "5";
cuttingLevel = "0";
totalTags = "all";
randomColors = true;
ordering = "Tag.GreekNameComparatorAsc";
displayScore = false;
shouldCenter = true;
locale = "el";
}
/**
* @return the cloudCase
*/
public String getCloudCase() {
return cloudCase;
}
/**
* @param cloudCase the cloudCase to set
*/
public void setCloudCase(String cloudCase) {
this.cloudCase = cloudCase;
}
/**
* @return the width
*/
public String getWidth() {
return width;
}
/**
* @param width the width to set
*/
public void setWidth(String width) {
this.width = width;
}
/**
* @return the colorLevel1
*/
public String getColorLevel1() {
return colorLevel1;
}
/**
* @param colorLevel1 the colorLevel1 to set
*/
public void setColorLevel1(String colorLevel1) {
this.colorLevel1 = colorLevel1;
}
/**
* @return the colorLevel2
*/
public String getColorLevel2() {
return colorLevel2;
}
/**
* @param colorLevel2 the colorLevel2 to set
*/
public void setColorLevel2(String colorLevel2) {
this.colorLevel2 = colorLevel2;
}
/**
* @return the colorLevel3
*/
public String getColorLevel3() {
return colorLevel3;
}
/**
* @param colorLevel3 the colorLevel3 to set
*/
public void setColorLevel3(String colorLevel3) {
this.colorLevel3 = colorLevel3;
}
/**
* @return the weightLevel1
*/
public String getWeightLevel1() {
return weightLevel1;
}
/**
* @param weightLevel1 the weightLevel1 to set
*/
public void setWeightLevel1(String weightLevel1) {
this.weightLevel1 = weightLevel1;
}
/**
* @return the weightLevel2
*/
public String getWeightLevel2() {
return weightLevel2;
}
/**
* @param weightLevel2 the weightLevel2 to set
*/
public void setWeightLevel2(String weightLevel2) {
this.weightLevel2 = weightLevel2;
}
/**
* @return the weightLevel3
*/
public String getWeightLevel3() {
return weightLevel3;
}
/**
* @param weightLevel3 the weightLevel3 to set
*/
public void setWeightLevel3(String weightLevel3) {
this.weightLevel3 = weightLevel3;
}
/**
* @return the fontFrom
*/
public String getFontFrom() {
return fontFrom;
}
/**
* @param fontFrom the fontFrom to set
*/
public void setFontFrom(String fontFrom) {
this.fontFrom = fontFrom;
}
/**
* @return the fontTo
*/
public String getFontTo() {
return fontTo;
}
/**
* @param fontTo the fontTo to set
*/
public void setFontTo(String fontTo) {
this.fontTo = fontTo;
}
/**
* @return the marginRight
*/
public String getMarginRight() {
return marginRight;
}
/**
* @param marginRight the marginRight to set
*/
public void setMarginRight(String marginRight) {
this.marginRight = marginRight;
}
/**
* @return the cuttingLevel
*/
public String getCuttingLevel() {
return cuttingLevel;
}
/**
* @param cuttingLevel the cuttingLevel to set
*/
public void setCuttingLevel(String cuttingLevel) {
this.cuttingLevel = cuttingLevel;
}
/**
* @return the totalTags
*/
public String getTotalTags() {
return totalTags;
}
/**
* @param totalTags the totalTags to set
*/
public void setTotalTags(String totalTags) {
this.totalTags = totalTags;
}
/**
* @return the randomColors
*/
public boolean isRandomColors() {
return randomColors;
}
/**
* @param randomColors the randomColors to set
*/
public void setRandomColors(boolean randomColors) {
this.randomColors = randomColors;
}
/**
* @return the ordering
*/
public String getOrdering() {
return ordering;
}
/**
* @param ordering the ordering to set
*/
public void setOrdering(String ordering) {
this.ordering = ordering;
}
/**
* @return the displayScore
*/
public boolean isDisplayScore() {
return displayScore;
}
/**
* @param displayScore the displayScore to set
*/
public void setDisplayScore(boolean displayScore) {
this.displayScore = displayScore;
}
/**
* @return the shouldCenter
*/
public boolean isShouldCenter() {
return shouldCenter;
}
/**
* @param shouldCenter the shouldCenter to set
*/
public void setShouldCenter(boolean shouldCenter) {
this.shouldCenter = shouldCenter;
}
/**
* @return the locale
*/
public String getLocale() {
return locale;
}
/**
* @param ordering the locale to set
*/
public void setLocale(String locale) {
this.locale = locale;
}
}

View File

@@ -0,0 +1,119 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.webui.tagcloud;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.dspace.app.webui.discovery.DiscoverUtility;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.DSpaceObject;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.dspace.discovery.DiscoverQuery;
import org.dspace.discovery.DiscoverResult;
import org.dspace.discovery.SearchServiceException;
import org.dspace.discovery.SearchUtils;
import org.dspace.discovery.configuration.DiscoveryConfiguration;
import org.dspace.discovery.configuration.DiscoverySearchFilterFacet;
import org.dspace.plugin.CollectionHomeProcessor;
import org.dspace.plugin.CommunityHomeProcessor;
import org.dspace.plugin.PluginException;
import org.dspace.plugin.SiteHomeProcessor;
/**
* @author kstamatis
*
*/
public class TagCloudProcessor implements CollectionHomeProcessor,
CommunityHomeProcessor, SiteHomeProcessor {
/** log4j category */
private static Logger log = Logger.getLogger(TagCloudProcessor.class);
/**
*
*/
public TagCloudProcessor() {
// TODO Auto-generated constructor stub
}
/* (non-Javadoc)
* @see org.dspace.plugin.SiteHomeProcessor#process(org.dspace.core.Context, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public void process(Context context, HttpServletRequest request,
HttpServletResponse response) throws PluginException,
AuthorizeException {
process(context, request, response, (DSpaceObject) null);
}
/* (non-Javadoc)
* @see org.dspace.plugin.CommunityHomeProcessor#process(org.dspace.core.Context, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.dspace.content.Community)
*/
@Override
public void process(Context context, HttpServletRequest request,
HttpServletResponse response, Community community)
throws PluginException, AuthorizeException {
process(context, request, response, (DSpaceObject) community);
}
/* (non-Javadoc)
* @see org.dspace.plugin.CollectionHomeProcessor#process(org.dspace.core.Context, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.dspace.content.Collection)
*/
@Override
public void process(Context context, HttpServletRequest request,
HttpServletResponse response, Collection collection)
throws PluginException, AuthorizeException {
process(context, request, response, (DSpaceObject) collection);
}
private void process(Context context, HttpServletRequest request,
HttpServletResponse response, DSpaceObject scope)
{
DiscoverQuery queryArgs = DiscoverUtility.getDiscoverQuery(context,
request, scope, true);
queryArgs.setMaxResults(0);
DiscoverResult qResults;
try
{
qResults = SearchUtils.getSearchService().search(context, scope,
queryArgs);
request.setAttribute("tagcloud.fresults",
qResults.getFacetResults());
DiscoveryConfiguration discoveryConfiguration = SearchUtils
.getDiscoveryConfiguration(scope);
List<DiscoverySearchFilterFacet> availableFacet = discoveryConfiguration
.getSidebarFacets();
request.setAttribute("tagCloudFacetsConfig",
availableFacet != null ? availableFacet
: new ArrayList<DiscoverySearchFilterFacet>());
if (scope !=null)
{
request.setAttribute("tagcloud.searchScope",
"/handle/" + scope.getHandle());
}
}
catch (SearchServiceException e)
{
log.error(LogManager.getHeader(context,
"tagcloud-process", "scope=" + scope));
}
}
}

View File

@@ -0,0 +1,218 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.webui.tagcloud;
import java.io.IOException;
import java.sql.SQLException;
import java.text.Collator;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException;
import org.dspace.browse.BrowseException;
import org.dspace.content.DCValue;
import org.dspace.content.Item;
import org.mcavallo.opencloud.Cloud;
import org.mcavallo.opencloud.Tag;
import org.mcavallo.opencloud.Cloud.Case;
import org.mcavallo.opencloud.formatters.HTMLFormatter;
/**
* @author kstamatis
*
*/
public class TagCloudTag extends SimpleTagSupport{
private static Logger log = Logger.getLogger(TagCloudTag.class);
TagCloudParameters parameters;
Map<String, Integer> data;
String index;
String scope;
/**
*
*/
public TagCloudTag() {
// TODO Auto-generated constructor stub
}
public void doTag() throws JspException {
PageContext pageContext = (PageContext) getJspContext();
JspWriter out = pageContext.getOut();
if (parameters == null)
parameters = new TagCloudParameters();
try {
Cloud cloud = new Cloud(); // create cloud
if (parameters.getCloudCase().equals("Case.LOWER"))
cloud.setTagCase(Case.LOWER);
else if (parameters.getCloudCase().equals("Case.UPPER"))
cloud.setTagCase(Case.UPPER);
else if (parameters.getCloudCase().equals("Case.CAPITALIZATION"))
cloud.setTagCase(Case.CAPITALIZATION);
else if (parameters.getCloudCase().equals("Case.PRESERVE_CASE"))
cloud.setTagCase(Case.PRESERVE_CASE);
else if (parameters.getCloudCase().equals("Case.CASE_SENSITIVE"))
cloud.setTagCase(Case.CASE_SENSITIVE);
cloud.setMaxWeight(Double.parseDouble(parameters.fontTo)); // max font size
cloud.setMinWeight(Double.parseDouble(parameters.fontFrom));
if (parameters.getTotalTags().equals("all"))
cloud.setMaxTagsToDisplay(10000);
else
cloud.setMaxTagsToDisplay(Integer.parseInt(parameters.getTotalTags()));
//cloud.setNormThreshold(0.4);
for (String subject : data.keySet()){
if (data.get(subject).intValue() > Integer.parseInt(parameters.getCuttingLevel())){
for (int i=0; i<data.get(subject).intValue(); i++){
Tag tag2 = new Tag(subject, ((HttpServletRequest) pageContext.getRequest()).getContextPath()+(scope!=null?"/handle/"+scope+"/":"")+"/simple-search?filterquery="+subject+"&filtername="+index+"&filtertype=equals"); // creates a tag
//tag2.setScore(subjects.get(subject).doubleValue());
cloud.addTag(tag2);
}
}
}
out.println("<div class=\"tagcloud\" style=\"width:"+parameters.width+";"+(parameters.shouldCenter?"text-align:center":"")+"\">");
int counter = 0;
List<Tag> tagList = cloud.tags(new Tag.NameComparatorAsc());
if (parameters.ordering.equals("Tag.NameComparatorAsc"))
tagList = cloud.tags(new Tag.NameComparatorAsc());
else if (parameters.ordering.equals("Tag.NameComparatorDesc"))
tagList = cloud.tags(new Tag.NameComparatorDesc());
//else if (parameters.ordering.equals("Tag.GreekNameComparatorAsc"))
// tagList = cloud.tags(new GreekComparatorTagAsc());
//else if (parameters.ordering.equals("Tag.GreekNameComparatorDesc"))
// tagList = cloud.tags(new GreekComparatorTagDesc());
else if (parameters.ordering.equals("Tag.ScoreComparatorAsc"))
tagList = cloud.tags(new Tag.ScoreComparatorAsc());
else if (parameters.ordering.equals("Tag.ScoreComparatorDesc"))
tagList = cloud.tags(new Tag.ScoreComparatorDesc());
for (Tag tag : tagList) {
String colorPart = "";
String theColor = "";
String weightPart = "";
if (parameters.isRandomColors()){
if (counter==0){
colorPart = "color:#"+parameters.getColorLevel1();
theColor = parameters.getColorLevel1();
weightPart = "font-weight:"+parameters.getWeightLevel1();
}
else if (counter==1){
colorPart = "color:#"+parameters.getColorLevel2();
theColor = parameters.getColorLevel2();
weightPart = "font-weight:"+parameters.getWeightLevel2();
}
else if (counter==2){
colorPart = "color:#"+parameters.getColorLevel3();
theColor = parameters.getColorLevel3();
weightPart = "font-weight:"+parameters.getWeightLevel3();
}
}
else {
if (tag.getNormScore()>0.3f){
colorPart = "color:#"+parameters.getColorLevel1();
theColor = parameters.getColorLevel1();
weightPart = "font-weight:"+parameters.getWeightLevel1();
}
else if (tag.getNormScore()>0.2f){
colorPart = "color:#"+parameters.getColorLevel2();
theColor = parameters.getColorLevel2();
weightPart = "font-weight:"+parameters.getWeightLevel2();
}
else if (tag.getNormScore()>0.1f){
colorPart = "color:#"+parameters.getColorLevel3();
theColor = parameters.getColorLevel3();
weightPart = "font-weight:"+parameters.getWeightLevel3();
}
}
String scoreSup = "";
if (parameters.displayScore){
scoreSup = "<span style=\"font-size:1em\"><sup>("+tag.getScoreInt()+")</sup></span>";
}
out.println("<a class=\"tagcloud_"+counter+"\" href=\"" + tag.getLink().replace(" & ", " %26 ") +"\" style=\"font-size: "+ tag.getWeight() +"em;"+colorPart+";"+weightPart+"; margin-right:"+parameters.marginRight+"px\" onmouseout=\"this.style.color='#"+theColor+"'\" onmouseover=\"this.style.color='#0581a7'\">"+ tag.getName() + scoreSup +"</a>");
counter ++;
if (counter == 3)
counter = 0;
}
out.println("</div>");
/*out.println("<br/>");
out.println("<br/>");
out.println("<br/>");
out.println("<br/>");
out.println("<div>");
for (Tag tag : cloud.tags()) {
String classS;
if (tag.getNormScore()>0.3f)
classS = "tagcloud2_0";
else if (tag.getNormScore()>0.2f)
classS = "tagcloud2_1";
else if (tag.getNormScore()>0.1f)
classS = "tagcloud2_2";
else
classS = "tagcloud2_3";
String title = "Score = "+tag.getScore()+", Normalized score = "+tag.getNormScore()+", Weight = "+tag.getWeight()+", Category = "+classS.replace("tagcloud2_", "");
out.println("<a class=\""+classS+"\" title = \""+title+"\"href=\"" + tag.getLink() +"\" style=\"font-size: "+ tag.getWeight() +"px;\">"+ tag.getName() +"</a>");
}
out.println("</div>");*/
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @param parameters the parameters to set
*/
public void setParameters(TagCloudParameters parameters) {
this.parameters = parameters;
}
public void setData(Map<String, Integer> data) {
this.data = data;
}
public void setIndex(String index) {
this.index = index;
}
public void setScope(String scope) {
this.scope = scope;
}
}

View File

@@ -520,6 +520,35 @@
</attribute>
</tag>
<tag>
<name>tagcloud</name>
<tagclass>org.dspace.app.webui.tagcloud.TagCloudTag</tagclass>
<bodycontent>empty</bodycontent>
<info>
Tag for display tagcloud.
</info>
<attribute>
<name>parameters</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>index</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>scope</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>data</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>selectcollection</name>

View File

@@ -36,6 +36,12 @@
<%@ page import="org.dspace.browse.ItemCounter" %>
<%@ page import="org.dspace.content.DCValue" %>
<%@ page import="org.dspace.content.Item" %>
<%@page import="org.dspace.discovery.configuration.DiscoverySearchFilterFacet"%>
<%@ page import="java.util.HashMap"%>
<%@ page import="java.util.Set"%>
<%@ page import="java.util.Map"%>
<%@ page import="java.util.List"%>
<%@ page import="org.dspace.discovery.DiscoverResult.FacetResult"%>
<%
Community[] communities = (Community[]) request.getAttribute("communities");
@@ -208,4 +214,30 @@ if (communities != null && communities.length != 0)
%>
<%@ include file="discovery/static-sidebar-facet.jsp" %>
</div>
<div>
<%
Map<String, List<FacetResult>> tcMapFacetes = (Map<String, List<FacetResult>>) request.getAttribute("tagcloud.fresults");
List<DiscoverySearchFilterFacet> tcFacetsConf = (List<DiscoverySearchFilterFacet>) request.getAttribute("tagCloudFacetsConfig");
String tcSearchScope = (String) request.getAttribute("tagcloud.searchScope");
String index = "subject";
String scope = tcSearchScope;
Map<String, Integer> data = new HashMap<String, Integer>();
for (DiscoverySearchFilterFacet facetConf : facetsConf)
{
String f = facetConf.getIndexFieldName();
if (f.equals(index)){
List<FacetResult> facet = mapFacetes.get(f);
for (FacetResult fvalue : facet)
{
data.put(fvalue.getDisplayedValue(), (int)fvalue.getCount());
}
}
}
%>
<dspace:tagcloud index='<%= index %>' scope='<%= scope %>' data='<%= data %>'/><br/><br/>
</div>
</dspace:layout>

View File

@@ -1342,7 +1342,8 @@ plugin.sequence.org.dspace.plugin.CollectionHomeProcessor = \
plugin.sequence.org.dspace.plugin.SiteHomeProcessor = \
org.dspace.app.webui.components.TopCommunitiesSiteProcessor,\
org.dspace.app.webui.components.RecentSiteSubmissions,\
org.dspace.app.webui.discovery.SideBarFacetProcessor
org.dspace.app.webui.discovery.SideBarFacetProcessor,\
org.dspace.app.webui.tagcloud.TagCloudProcessor
#### JSON JSPUI Request Handler ####
# define any JSON handler here

View File

@@ -294,7 +294,7 @@
<value>dc.subject.*</value>
</list>
</property>
<property name="facetLimit" value="10"/>
<property name="facetLimit" value="15"/>
<property name="sortOrder" value="COUNT"/>
<property name="splitter" value="::"/>
</bean>