From ad3497d0bc2996aabbdc175bcdc6149b3eb469f0 Mon Sep 17 00:00:00 2001 From: cdtank Date: Fri, 11 Feb 2011 19:06:49 +0000 Subject: [PATCH] 1. Partial fix for NIHVIVO-2130. Now the downloadable csv file properly prints out all the authors, with same name. The right hand side bar still prints wrong values in case of authors with duplicate names. 2. Solution for 2 stage loading for temporal graph where now when the intial call is made to it, it returns with the markup & js lib includes & then makes an ajax call to get the data file in json format which is the used to render the linegraph & the table. --- .../visualization/entitycomparison/layout.css | 5 + .../js/jquery_plugins/jquery.blockUI.js | 490 ++++++++++++++++++ .../js/jquery_plugins/jquery.blockUI.min.js | 66 +++ .../entitycomparison/gui-event-manager.js | 432 +++++++-------- .../entitycomparison/entityComparisonBody.ftl | 4 +- .../entityComparisonErrorCommonBody.ftl | 6 +- .../entityComparisonOnGrantsStandalone.ftl | 46 +- ...tityComparisonOnPublicationsStandalone.ftl | 54 +- .../entityComparisonSetup.ftl | 13 +- .../VisualizationFrameworkConstants.java | 7 +- .../CoAuthorshipRequestHandler.java | 54 +- .../CoPIGrantCountRequestHandler.java | 28 +- .../EntityComparisonUtilityFunctions.java | 50 ++ ...yPublicationCountConstructQueryRunner.java | 197 ++++--- .../EntityPublicationCountRequestHandler.java | 202 ++++---- .../EntityGrantCountRequestHandler.java | 180 +++---- .../freemarker/visutils/UtilityFunctions.java | 5 + 17 files changed, 1277 insertions(+), 562 deletions(-) create mode 100644 productMods/js/jquery_plugins/jquery.blockUI.js create mode 100644 productMods/js/jquery_plugins/jquery.blockUI.min.js diff --git a/productMods/css/visualization/entitycomparison/layout.css b/productMods/css/visualization/entitycomparison/layout.css index af9592ba..3b6921ee 100644 --- a/productMods/css/visualization/entitycomparison/layout.css +++ b/productMods/css/visualization/entitycomparison/layout.css @@ -8,6 +8,11 @@ margin: auto; overflow: hidden; } + +#error-container { + display: none; +} + .easy-deselect-label a.temporal-vis-url { float: right; } diff --git a/productMods/js/jquery_plugins/jquery.blockUI.js b/productMods/js/jquery_plugins/jquery.blockUI.js new file mode 100644 index 00000000..502a2e8d --- /dev/null +++ b/productMods/js/jquery_plugins/jquery.blockUI.js @@ -0,0 +1,490 @@ +/*! + * jQuery blockUI plugin + * Version 2.37 (29-JAN-2011) + * @requires jQuery v1.2.3 or later + * + * Examples at: http://malsup.com/jquery/block/ + * Copyright (c) 2007-2010 M. Alsup + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Thanks to Amir-Hossein Sobhi for some excellent contributions! + */ + +;(function($) { + +if (/1\.(0|1|2)\.(0|1|2)/.test($.fn.jquery) || /^1.1/.test($.fn.jquery)) { + alert('blockUI requires jQuery v1.2.3 or later! You are using v' + $.fn.jquery); + return; +} + +$.fn._fadeIn = $.fn.fadeIn; + +var noOp = function() {}; + +// this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle +// retarded userAgent strings on Vista) +var mode = document.documentMode || 0; +var setExpr = $.browser.msie && (($.browser.version < 8 && !mode) || mode < 8); +var ie6 = $.browser.msie && /MSIE 6.0/.test(navigator.userAgent) && !mode; + +// global $ methods for blocking/unblocking the entire page +$.blockUI = function(opts) { install(window, opts); }; +$.unblockUI = function(opts) { remove(window, opts); }; + +// convenience method for quick growl-like notifications (http://www.google.com/search?q=growl) +$.growlUI = function(title, message, timeout, onClose) { + var $m = $('
'); + if (title) $m.append('

'+title+'

'); + if (message) $m.append('

'+message+'

'); + if (timeout == undefined) timeout = 3000; + $.blockUI({ + message: $m, fadeIn: 700, fadeOut: 1000, centerY: false, + timeout: timeout, showOverlay: false, + onUnblock: onClose, + css: $.blockUI.defaults.growlCSS + }); +}; + +// plugin method for blocking element content +$.fn.block = function(opts) { + return this.unblock({ fadeOut: 0 }).each(function() { + if ($.css(this,'position') == 'static') + this.style.position = 'relative'; + if ($.browser.msie) + this.style.zoom = 1; // force 'hasLayout' + install(this, opts); + }); +}; + +// plugin method for unblocking element content +$.fn.unblock = function(opts) { + return this.each(function() { + remove(this, opts); + }); +}; + +$.blockUI.version = 2.37; // 2nd generation blocking at no extra cost! + +// override these in your code to change the default behavior and style +$.blockUI.defaults = { + // message displayed when blocking (use null for no message) + message: '

Please wait...

', + + title: null, // title string; only used when theme == true + draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded) + + theme: false, // set to true to use with jQuery UI themes + + // styles for the message when blocking; if you wish to disable + // these and use an external stylesheet then do this in your code: + // $.blockUI.defaults.css = {}; + css: { + padding: 0, + margin: 0, + width: '30%', + top: '40%', + left: '35%', + textAlign: 'center', + color: '#000', + border: '3px solid #aaa', + backgroundColor:'#fff', + cursor: 'wait' + }, + + // minimal style set used when themes are used + themedCSS: { + width: '30%', + top: '40%', + left: '35%' + }, + + // styles for the overlay + overlayCSS: { + backgroundColor: '#000', + opacity: 0.6, + cursor: 'wait' + }, + + // styles applied when using $.growlUI + growlCSS: { + width: '350px', + top: '10px', + left: '', + right: '10px', + border: 'none', + padding: '5px', + opacity: 0.6, + cursor: 'default', + color: '#fff', + backgroundColor: '#000', + '-webkit-border-radius': '10px', + '-moz-border-radius': '10px', + 'border-radius': '10px' + }, + + // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w + // (hat tip to Jorge H. N. de Vasconcelos) + iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank', + + // force usage of iframe in non-IE browsers (handy for blocking applets) + forceIframe: false, + + // z-index for the blocking overlay + baseZ: 1000, + + // set these to true to have the message automatically centered + centerX: true, // <-- only effects element blocking (page block controlled via css above) + centerY: true, + + // allow body element to be stetched in ie6; this makes blocking look better + // on "short" pages. disable if you wish to prevent changes to the body height + allowBodyStretch: true, + + // enable if you want key and mouse events to be disabled for content that is blocked + bindEvents: true, + + // be default blockUI will supress tab navigation from leaving blocking content + // (if bindEvents is true) + constrainTabKey: true, + + // fadeIn time in millis; set to 0 to disable fadeIn on block + fadeIn: 200, + + // fadeOut time in millis; set to 0 to disable fadeOut on unblock + fadeOut: 400, + + // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock + timeout: 0, + + // disable if you don't want to show the overlay + showOverlay: true, + + // if true, focus will be placed in the first available input field when + // page blocking + focusInput: true, + + // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity) + applyPlatformOpacityRules: true, + + // callback method invoked when fadeIn has completed and blocking message is visible + onBlock: null, + + // callback method invoked when unblocking has completed; the callback is + // passed the element that has been unblocked (which is the window object for page + // blocks) and the options that were passed to the unblock call: + // onUnblock(element, options) + onUnblock: null, + + // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493 + quirksmodeOffsetHack: 4, + + // class name of the message block + blockMsgClass: 'blockMsg' +}; + +// private data and functions follow... + +var pageBlock = null; +var pageBlockEls = []; + +function install(el, opts) { + var full = (el == window); + var msg = opts && opts.message !== undefined ? opts.message : undefined; + opts = $.extend({}, $.blockUI.defaults, opts || {}); + opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {}); + var css = $.extend({}, $.blockUI.defaults.css, opts.css || {}); + var themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {}); + msg = msg === undefined ? opts.message : msg; + + // remove the current block (if there is one) + if (full && pageBlock) + remove(window, {fadeOut:0}); + + // if an existing element is being used as the blocking content then we capture + // its current place in the DOM (and current display style) so we can restore + // it when we unblock + if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) { + var node = msg.jquery ? msg[0] : msg; + var data = {}; + $(el).data('blockUI.history', data); + data.el = node; + data.parent = node.parentNode; + data.display = node.style.display; + data.position = node.style.position; + if (data.parent) + data.parent.removeChild(node); + } + + var z = opts.baseZ; + + // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform; + // layer1 is the iframe layer which is used to supress bleed through of underlying content + // layer2 is the overlay layer which has opacity and a wait cursor (by default) + // layer3 is the message content that is displayed while blocking + + var lyr1 = ($.browser.msie || opts.forceIframe) + ? $('') + : $(''); + var lyr2 = $(''); + + var lyr3, s; + if (opts.theme && full) { + s = ''; + } + else if (opts.theme) { + s = ''; + } + else if (full) { + s = ''; + } + else { + s = ''; + } + lyr3 = $(s); + + // if we have a message, style it + if (msg) { + if (opts.theme) { + lyr3.css(themedCSS); + lyr3.addClass('ui-widget-content'); + } + else + lyr3.css(css); + } + + // style the overlay + if (!opts.applyPlatformOpacityRules || !($.browser.mozilla && /Linux/.test(navigator.platform))) + lyr2.css(opts.overlayCSS); + lyr2.css('position', full ? 'fixed' : 'absolute'); + + // make iframe layer transparent in IE + if ($.browser.msie || opts.forceIframe) + lyr1.css('opacity',0.0); + + //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el); + var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el); + $.each(layers, function() { + this.appendTo($par); + }); + + if (opts.theme && opts.draggable && $.fn.draggable) { + lyr3.draggable({ + handle: '.ui-dialog-titlebar', + cancel: 'li' + }); + } + + // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling) + var expr = setExpr && (!$.boxModel || $('object,embed', full ? null : el).length > 0); + if (ie6 || expr) { + // give body 100% height + if (full && opts.allowBodyStretch && $.boxModel) + $('html,body').css('height','100%'); + + // fix ie6 issue when blocked element has a border width + if ((ie6 || !$.boxModel) && !full) { + var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth'); + var fixT = t ? '(0 - '+t+')' : 0; + var fixL = l ? '(0 - '+l+')' : 0; + } + + // simulate fixed position + $.each([lyr1,lyr2,lyr3], function(i,o) { + var s = o[0].style; + s.position = 'absolute'; + if (i < 2) { + full ? s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"') + : s.setExpression('height','this.parentNode.offsetHeight + "px"'); + full ? s.setExpression('width','jQuery.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"') + : s.setExpression('width','this.parentNode.offsetWidth + "px"'); + if (fixL) s.setExpression('left', fixL); + if (fixT) s.setExpression('top', fixT); + } + else if (opts.centerY) { + if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'); + s.marginTop = 0; + } + else if (!opts.centerY && full) { + var top = (opts.css && opts.css.top) ? parseInt(opts.css.top) : 0; + var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"'; + s.setExpression('top',expression); + } + }); + } + + // show the message + if (msg) { + if (opts.theme) + lyr3.find('.ui-widget-content').append(msg); + else + lyr3.append(msg); + if (msg.jquery || msg.nodeType) + $(msg).show(); + } + + if (($.browser.msie || opts.forceIframe) && opts.showOverlay) + lyr1.show(); // opacity is zero + if (opts.fadeIn) { + var cb = opts.onBlock ? opts.onBlock : noOp; + var cb1 = (opts.showOverlay && !msg) ? cb : noOp; + var cb2 = msg ? cb : noOp; + if (opts.showOverlay) + lyr2._fadeIn(opts.fadeIn, cb1); + if (msg) + lyr3._fadeIn(opts.fadeIn, cb2); + } + else { + if (opts.showOverlay) + lyr2.show(); + if (msg) + lyr3.show(); + if (opts.onBlock) + opts.onBlock(); + } + + // bind key and mouse events + bind(1, el, opts); + + if (full) { + pageBlock = lyr3[0]; + pageBlockEls = $(':input:enabled:visible',pageBlock); + if (opts.focusInput) + setTimeout(focus, 20); + } + else + center(lyr3[0], opts.centerX, opts.centerY); + + if (opts.timeout) { + // auto-unblock + var to = setTimeout(function() { + full ? $.unblockUI(opts) : $(el).unblock(opts); + }, opts.timeout); + $(el).data('blockUI.timeout', to); + } +}; + +// remove the block +function remove(el, opts) { + var full = (el == window); + var $el = $(el); + var data = $el.data('blockUI.history'); + var to = $el.data('blockUI.timeout'); + if (to) { + clearTimeout(to); + $el.removeData('blockUI.timeout'); + } + opts = $.extend({}, $.blockUI.defaults, opts || {}); + bind(0, el, opts); // unbind events + + var els; + if (full) // crazy selector to handle odd field errors in ie6/7 + els = $('body').children().filter('.blockUI').add('body > .blockUI'); + else + els = $('.blockUI', el); + + if (full) + pageBlock = pageBlockEls = null; + + if (opts.fadeOut) { + els.fadeOut(opts.fadeOut); + setTimeout(function() { reset(els,data,opts,el); }, opts.fadeOut); + } + else + reset(els, data, opts, el); +}; + +// move blocking element back into the DOM where it started +function reset(els,data,opts,el) { + els.each(function(i,o) { + // remove via DOM calls so we don't lose event handlers + if (this.parentNode) + this.parentNode.removeChild(this); + }); + + if (data && data.el) { + data.el.style.display = data.display; + data.el.style.position = data.position; + if (data.parent) + data.parent.appendChild(data.el); + $(el).removeData('blockUI.history'); + } + + if (typeof opts.onUnblock == 'function') + opts.onUnblock(el,opts); +}; + +// bind/unbind the handler +function bind(b, el, opts) { + var full = el == window, $el = $(el); + + // don't bother unbinding if there is nothing to unbind + if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked'))) + return; + if (!full) + $el.data('blockUI.isBlocked', b); + + // don't bind events when overlay is not in use or if bindEvents is false + if (!opts.bindEvents || (b && !opts.showOverlay)) + return; + + // bind anchors and inputs for mouse and key events + var events = 'mousedown mouseup keydown keypress'; + b ? $(document).bind(events, opts, handler) : $(document).unbind(events, handler); + +// former impl... +// var $e = $('a,:input'); +// b ? $e.bind(events, opts, handler) : $e.unbind(events, handler); +}; + +// event handler to suppress keyboard/mouse events when blocking +function handler(e) { + // allow tab navigation (conditionally) + if (e.keyCode && e.keyCode == 9) { + if (pageBlock && e.data.constrainTabKey) { + var els = pageBlockEls; + var fwd = !e.shiftKey && e.target === els[els.length-1]; + var back = e.shiftKey && e.target === els[0]; + if (fwd || back) { + setTimeout(function(){focus(back)},10); + return false; + } + } + } + var opts = e.data; + // allow events within the message content + if ($(e.target).parents('div.' + opts.blockMsgClass).length > 0) + return true; + + // allow events for content that is not being blocked + return $(e.target).parents().children().filter('div.blockUI').length == 0; +}; + +function focus(back) { + if (!pageBlockEls) + return; + var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0]; + if (e) + e.focus(); +}; + +function center(el, x, y) { + var p = el.parentNode, s = el.style; + var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth'); + var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth'); + if (x) s.left = l > 0 ? (l+'px') : '0'; + if (y) s.top = t > 0 ? (t+'px') : '0'; +}; + +function sz(el, p) { + return parseInt($.css(el,p))||0; +}; + +})(jQuery); diff --git a/productMods/js/jquery_plugins/jquery.blockUI.min.js b/productMods/js/jquery_plugins/jquery.blockUI.min.js new file mode 100644 index 00000000..5bdbd1f2 --- /dev/null +++ b/productMods/js/jquery_plugins/jquery.blockUI.min.js @@ -0,0 +1,66 @@ +/*! + jQuery blockUI plugin + Version 2.37 (29-JAN-2011) + @requires jQuery v1.2.3 or later + + Examples at: http://malsup.com/jquery/block/ + Copyright (c) 2007-2010 M. Alsup + Dual licensed under the MIT and GPL licenses: + http://www.opensource.org/licenses/mit-license.php + http://www.gnu.org/licenses/gpl.html + + Thanks to Amir-Hossein Sobhi for some excellent contributions! + */;(function($){if(/1\.(0|1|2)\.(0|1|2)/.test($.fn.jquery)||/^1.1/.test($.fn.jquery)){alert('blockUI requires jQuery v1.2.3 or later! You are using v'+$.fn.jquery);return;} +$.fn._fadeIn=$.fn.fadeIn;var noOp=function(){};var mode=document.documentMode||0;var setExpr=$.browser.msie&&(($.browser.version<8&&!mode)||mode<8);var ie6=$.browser.msie&&/MSIE 6.0/.test(navigator.userAgent)&&!mode;$.blockUI=function(opts){install(window,opts);};$.unblockUI=function(opts){remove(window,opts);};$.growlUI=function(title,message,timeout,onClose){var $m=$('
');if(title)$m.append('

'+title+'

');if(message)$m.append('

'+message+'

');if(timeout==undefined)timeout=3000;$.blockUI({message:$m,fadeIn:700,fadeOut:1000,centerY:false,timeout:timeout,showOverlay:false,onUnblock:onClose,css:$.blockUI.defaults.growlCSS});};$.fn.block=function(opts){return this.unblock({fadeOut:0}).each(function(){if($.css(this,'position')=='static') +this.style.position='relative';if($.browser.msie) +this.style.zoom=1;install(this,opts);});};$.fn.unblock=function(opts){return this.each(function(){remove(this,opts);});};$.blockUI.version=2.37;$.blockUI.defaults={message:'

Please wait...

',title:null,draggable:true,theme:false,css:{padding:0,margin:0,width:'30%',top:'40%',left:'35%',textAlign:'center',color:'#000',border:'3px solid #aaa',backgroundColor:'#fff',cursor:'wait'},themedCSS:{width:'30%',top:'40%',left:'35%'},overlayCSS:{backgroundColor:'#000',opacity:0.6,cursor:'wait'},growlCSS:{width:'350px',top:'10px',left:'',right:'10px',border:'none',padding:'5px',opacity:0.6,cursor:'default',color:'#fff',backgroundColor:'#000','-webkit-border-radius':'10px','-moz-border-radius':'10px','border-radius':'10px'},iframeSrc:/^https/i.test(window.location.href||'')?'javascript:false':'about:blank',forceIframe:false,baseZ:1000,centerX:true,centerY:true,allowBodyStretch:true,bindEvents:true,constrainTabKey:true,fadeIn:200,fadeOut:400,timeout:0,showOverlay:true,focusInput:true,applyPlatformOpacityRules:true,onBlock:null,onUnblock:null,quirksmodeOffsetHack:4,blockMsgClass:'blockMsg'};var pageBlock=null;var pageBlockEls=[];function install(el,opts){var full=(el==window);var msg=opts&&opts.message!==undefined?opts.message:undefined;opts=$.extend({},$.blockUI.defaults,opts||{});opts.overlayCSS=$.extend({},$.blockUI.defaults.overlayCSS,opts.overlayCSS||{});var css=$.extend({},$.blockUI.defaults.css,opts.css||{});var themedCSS=$.extend({},$.blockUI.defaults.themedCSS,opts.themedCSS||{});msg=msg===undefined?opts.message:msg;if(full&&pageBlock) +remove(window,{fadeOut:0});if(msg&&typeof msg!='string'&&(msg.parentNode||msg.jquery)){var node=msg.jquery?msg[0]:msg;var data={};$(el).data('blockUI.history',data);data.el=node;data.parent=node.parentNode;data.display=node.style.display;data.position=node.style.position;if(data.parent) +data.parent.removeChild(node);} +var z=opts.baseZ;var lyr1=($.browser.msie||opts.forceIframe)?$(''):$('');var lyr2=$('');var lyr3,s;if(opts.theme&&full){s='';} +else if(opts.theme){s='';} +else if(full){s='';} +else{s='';} +lyr3=$(s);if(msg){if(opts.theme){lyr3.css(themedCSS);lyr3.addClass('ui-widget-content');} +else +lyr3.css(css);} +if(!opts.applyPlatformOpacityRules||!($.browser.mozilla&&/Linux/.test(navigator.platform))) +lyr2.css(opts.overlayCSS);lyr2.css('position',full?'fixed':'absolute');if($.browser.msie||opts.forceIframe) +lyr1.css('opacity',0.0);var layers=[lyr1,lyr2,lyr3],$par=full?$('body'):$(el);$.each(layers,function(){this.appendTo($par);});if(opts.theme&&opts.draggable&&$.fn.draggable){lyr3.draggable({handle:'.ui-dialog-titlebar',cancel:'li'});} +var expr=setExpr&&(!$.boxModel||$('object,embed',full?null:el).length>0);if(ie6||expr){if(full&&opts.allowBodyStretch&&$.boxModel) +$('html,body').css('height','100%');if((ie6||!$.boxModel)&&!full){var t=sz(el,'borderTopWidth'),l=sz(el,'borderLeftWidth');var fixT=t?'(0 - '+t+')':0;var fixL=l?'(0 - '+l+')':0;} +$.each([lyr1,lyr2,lyr3],function(i,o){var s=o[0].style;s.position='absolute';if(i<2){full?s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"'):s.setExpression('height','this.parentNode.offsetHeight + "px"');full?s.setExpression('width','jQuery.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'):s.setExpression('width','this.parentNode.offsetWidth + "px"');if(fixL)s.setExpression('left',fixL);if(fixT)s.setExpression('top',fixT);} +else if(opts.centerY){if(full)s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');s.marginTop=0;} +else if(!opts.centerY&&full){var top=(opts.css&&opts.css.top)?parseInt(opts.css.top):0;var expression='((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';s.setExpression('top',expression);}});} +if(msg){if(opts.theme) +lyr3.find('.ui-widget-content').append(msg);else +lyr3.append(msg);if(msg.jquery||msg.nodeType) +$(msg).show();} +if(($.browser.msie||opts.forceIframe)&&opts.showOverlay) +lyr1.show();if(opts.fadeIn){var cb=opts.onBlock?opts.onBlock:noOp;var cb1=(opts.showOverlay&&!msg)?cb:noOp;var cb2=msg?cb:noOp;if(opts.showOverlay) +lyr2._fadeIn(opts.fadeIn,cb1);if(msg) +lyr3._fadeIn(opts.fadeIn,cb2);} +else{if(opts.showOverlay) +lyr2.show();if(msg) +lyr3.show();if(opts.onBlock) +opts.onBlock();} +bind(1,el,opts);if(full){pageBlock=lyr3[0];pageBlockEls=$(':input:enabled:visible',pageBlock);if(opts.focusInput) +setTimeout(focus,20);} +else +center(lyr3[0],opts.centerX,opts.centerY);if(opts.timeout){var to=setTimeout(function(){full?$.unblockUI(opts):$(el).unblock(opts);},opts.timeout);$(el).data('blockUI.timeout',to);}};function remove(el,opts){var full=(el==window);var $el=$(el);var data=$el.data('blockUI.history');var to=$el.data('blockUI.timeout');if(to){clearTimeout(to);$el.removeData('blockUI.timeout');} +opts=$.extend({},$.blockUI.defaults,opts||{});bind(0,el,opts);var els;if(full) +els=$('body').children().filter('.blockUI').add('body > .blockUI');else +els=$('.blockUI',el);if(full) +pageBlock=pageBlockEls=null;if(opts.fadeOut){els.fadeOut(opts.fadeOut);setTimeout(function(){reset(els,data,opts,el);},opts.fadeOut);} +else +reset(els,data,opts,el);};function reset(els,data,opts,el){els.each(function(i,o){if(this.parentNode) +this.parentNode.removeChild(this);});if(data&&data.el){data.el.style.display=data.display;data.el.style.position=data.position;if(data.parent) +data.parent.appendChild(data.el);$(el).removeData('blockUI.history');} +if(typeof opts.onUnblock=='function') +opts.onUnblock(el,opts);};function bind(b,el,opts){var full=el==window,$el=$(el);if(!b&&(full&&!pageBlock||!full&&!$el.data('blockUI.isBlocked'))) +return;if(!full) +$el.data('blockUI.isBlocked',b);if(!opts.bindEvents||(b&&!opts.showOverlay)) +return;var events='mousedown mouseup keydown keypress';b?$(document).bind(events,opts,handler):$(document).unbind(events,handler);};function handler(e){if(e.keyCode&&e.keyCode==9){if(pageBlock&&e.data.constrainTabKey){var els=pageBlockEls;var fwd=!e.shiftKey&&e.target===els[els.length-1];var back=e.shiftKey&&e.target===els[0];if(fwd||back){setTimeout(function(){focus(back)},10);return false;}}} +var opts=e.data;if($(e.target).parents('div.'+opts.blockMsgClass).length>0) +return true;return $(e.target).parents().children().filter('div.blockUI').length==0;};function focus(back){if(!pageBlockEls) +return;var e=pageBlockEls[back===true?pageBlockEls.length-1:0];if(e) +e.focus();};function center(el,x,y){var p=el.parentNode,s=el.style;var l=((p.offsetWidth-el.offsetWidth)/2)-sz(p,'borderLeftWidth');var t=((p.offsetHeight-el.offsetHeight)/2)-sz(p,'borderTopWidth');if(x)s.left=l>0?(l+'px'):'0';if(y)s.top=t>0?(t+'px'):'0';};function sz(el,p){return parseInt($.css(el,p))||0;};})(jQuery); \ No newline at end of file diff --git a/productMods/js/visualization/entitycomparison/gui-event-manager.js b/productMods/js/visualization/entitycomparison/gui-event-manager.js index 938b41e1..fff1d041 100644 --- a/productMods/js/visualization/entitycomparison/gui-event-manager.js +++ b/productMods/js/visualization/entitycomparison/gui-event-manager.js @@ -1,220 +1,234 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ $(document).ready(function() { - - /* - * This will set intitial values of the constants present in constants.js - * */ - initConstants(); - - /* This is used to cache the current state whether the user is allowed to select more entities from - the datatable or not. Once Max number of entity selection is reached the user can no longer select - more & this variable will be set to false. */ - $("#datatable").data("isEntitySelectionAllowed", true); - - $("#organizationLabel").text(organizationLabel).css("color", "#2485ae"); - $("#organizationMoniker").text(organizationLabel); - $("#organizationMoniker").attr("href", organizationVIVOProfileURL); - - $notificationContainer = $("#notification-container").notify(); - - graphContainer = $("#graphContainer"); - tableDiv = $('#paginatedTable'); - //click event handler for clear button - $("a.clear-selected-entities").click(function(){ - clearRenderedObjects(); - }); + /* + * This will set intitial values of the constants present in constants.js + * */ + initConstants(); + /* This is used to cache the current state whether the user is allowed to select more entities from + the datatable or not. Once Max number of entity selection is reached the user can no longer select + more & this variable will be set to false. */ + $("#datatable").data("isEntitySelectionAllowed", true); + + $notificationContainer = $("#notification-container").notify(); + + graphContainer = $("#graphContainer"); + tableDiv = $('#paginatedTable'); + + //temporalGraphProcessor.initiateTemporalGraphRenderProcess(graphContainer, jsonString); + +}); + +//click event handler for clear button +$("a.clear-selected-entities").live('click', function(){ + clearRenderedObjects(); +}); + +/* + * When the intra-entity parameters are clicked, + * update the status accordingly. + */ + +$("select.comparisonValues").live('change', function(){ + + var selectedValue = $("select.comparisonValues option:selected").val(); + + var selectedParameter; + + $.each(COMPARISON_PARAMETERS_INFO, function(index, parameter) { + + if (parameter.value === selectedValue) { + selectedParameter = parameter; + window.location = parameter.viewLink; + } + + }); + + //$("#body").empty().html("
Loading " + selectedValue + "  
"); + + /* + * This piece of code is not executed at all because the redirect happens before there is a chance + * to render the below contents. + * */ + + /* + + $("#comparisonParameter").text("Total Number of " + selectedValue); + $('#yaxislabel').html("Number of " + selectedValue).mbFlipText(false); + $('#yaxislabel').css("color", "#595B5B"); + $('#comparisonHeader').html(selectedValue).css('font-weight', 'bold'); + + + */ + +}); + +$("input[type=checkbox].easyDeselectCheckbox").live('click', function(){ + + var checkbox = $(this); + var checkboxValue = $(this).attr("value"); + var linkedCheckbox = labelToCheckedEntities[checkboxValue]; + var entityToBeRemoved = labelToEntityRecord[checkboxValue]; + + if(!checkbox.is(':checked')){ + //console.log("Easy deselect checkbox is unclicked!"); + updateRowHighlighter(linkedCheckbox); + removeUsedColor(entityToBeRemoved); + removeEntityUnChecked(renderedObjects, entityToBeRemoved); + removeLegendRow(linkedCheckbox); + removeCheckBoxFromGlobalSet(linkedCheckbox); + $(linkedCheckbox).attr('checked', false); + checkIfColorLimitIsReached(); + displayLineGraphs(); + updateCounter(); + } +}); + + +$(".disabled-checkbox-event-receiver").live("click", function () { + + if ($(this).next().is(':disabled')) { + + createNotification("warning-notification", { + title: 'Error', + text: 'A Maximum 10 entities can be compared. Please remove some & try again.' + }, { + custom: true, + expires: false + }); + + } + +}); + +function performEntityCheckboxUnselectedActions(entity, checkboxValue, checkbox) { + + removeUsedColor(entity); + removeEntityUnChecked(renderedObjects, entity); + removeLegendRow(checkbox); + removeCheckBoxFromGlobalSet(checkbox); + + checkbox.closest("tr").removeClass('datatablerowhighlight'); + +} + +function performEntityCheckboxSelectedActions(entity, checkboxValue, checkbox) { + + getNextFreeColor(entity); + + //Generate the bar, checkbox and label for the legend. + createLegendRow(entity, $("#bottom")); + + renderLineGraph(renderedObjects, entity); + labelToCheckedEntities[checkboxValue] = checkbox; + labelToCheckedEntities[checkboxValue].entity = entity; + +// console.log(labelToCheckedEntities[checkboxValue], entity); + + /* + * To highlight the rows belonging to selected entities. + * */ + checkbox.closest("tr").addClass('datatablerowhighlight'); + +} + +function performEntityCheckboxClickedRedrawActions() { + + setTickSizeOfAxes(); + checkIfColorLimitIsReached(); + displayLineGraphs(); + updateCounter(); + +} + +/* + * function to populate the labelToEntityRecord object with the + * values from the json file and + * dynamically generate checkboxes + */ +function loadData(jsonData) { + + $.each(jsonData, function (index, val) { + setOfLabels.push(val.label); + labelToEntityRecord[val.label] = val; + }); + + prepareTableForDataTablePagination(jsonData); + setEntityLevel(getEntityVisMode(jsonData)); + + entityCheckboxOperatedOnEventListener(); + +} + +function entityCheckboxOperatedOnEventListener() { + + /* + * When the elements in the paginated div + * are clicked this event handler is called + */ + $("input." + entityCheckboxSelectorDOMClass).live('click', function () { + + var checkbox = $(this); + var checkboxValue = $(this).attr("value"); + var entity = labelToEntityRecord[checkboxValue]; + + if (checkbox.is(':checked')) { + + performEntityCheckboxSelectedActions(entity, checkboxValue, checkbox); + + } else { + + performEntityCheckboxUnselectedActions(entity, checkboxValue, checkbox); + + } + + performEntityCheckboxClickedRedrawActions(); + + }); + +} + +function getTemporalGraphDataFromServer() { + + + +} + +temporalGraphProcessor = { + + initiateTemporalGraphRenderProcess: function(givenGraphContainer, jsonData) { + + /* + * initial display of the grid when the page loads + * */ + init(givenGraphContainer); /* - * When the intra-entity parameters are clicked, - * update the status accordingly. - */ + * render the temporal graph per the sent content. + * */ + loadData(jsonData); - $("select.comparisonValues").change(function(){ - - var selectedValue = $("select.comparisonValues option:selected").val(); - - var selectedParameter; - - $.each(COMPARISON_PARAMETERS_INFO, function(index, parameter) { - - if (parameter.value === selectedValue) { - selectedParameter = parameter; - window.location = parameter.viewLink; - } - - }); - - //$("#body").empty().html("
Loading " + selectedValue + "  
"); - - /* - * This piece of code is not executed at all because the redirect happens before there is a chance - * to render the below contents. - * */ - - /* - - $("#comparisonParameter").text("Total Number of " + selectedValue); - $('#yaxislabel').html("Number of " + selectedValue).mbFlipText(false); - $('#yaxislabel').css("color", "#595B5B"); - $('#comparisonHeader').html(selectedValue).css('font-weight', 'bold'); - - - */ - - }); - - $("input[type=checkbox].easyDeselectCheckbox").live('click', function(){ - - var checkbox = $(this); - var checkboxValue = $(this).attr("value"); - var linkedCheckbox = labelToCheckedEntities[checkboxValue]; - var entityToBeRemoved = labelToEntityRecord[checkboxValue]; - - if(!checkbox.is(':checked')){ - //console.log("Easy deselect checkbox is unclicked!"); - updateRowHighlighter(linkedCheckbox); - removeUsedColor(entityToBeRemoved); - removeEntityUnChecked(renderedObjects, entityToBeRemoved); - removeLegendRow(linkedCheckbox); - removeCheckBoxFromGlobalSet(linkedCheckbox); - $(linkedCheckbox).attr('checked', false); - checkIfColorLimitIsReached(); - displayLineGraphs(); - updateCounter(); - } - }); - - function performEntityCheckboxUnselectedActions(entity, checkboxValue, checkbox) { - - removeUsedColor(entity); - removeEntityUnChecked(renderedObjects, entity); - removeLegendRow(checkbox); - removeCheckBoxFromGlobalSet(checkbox); - - checkbox.closest("tr").removeClass('datatablerowhighlight'); - - } - - function performEntityCheckboxSelectedActions(entity, checkboxValue, checkbox) { + /* + * This will make sure that top 3 entities are selected by default when the page loads. + */ + $.each($("input." + entityCheckboxSelectorDOMClass), function(index, checkbox) { + + if (index > 2) { + return false; + } + + $(this).attr('checked', true); - getNextFreeColor(entity); - - //Generate the bar, checkbox and label for the legend. - createLegendRow(entity, $("#bottom")); - - renderLineGraph(renderedObjects, entity); - labelToCheckedEntities[checkboxValue] = checkbox; - labelToCheckedEntities[checkboxValue].entity = entity; - -// console.log(labelToCheckedEntities[checkboxValue], entity); - - /* - * To highlight the rows belonging to selected entities. - * */ - checkbox.closest("tr").addClass('datatablerowhighlight'); + var checkboxValue = $(this).attr("value"); + var entity = labelToEntityRecord[checkboxValue]; - } - - function performEntityCheckboxClickedRedrawActions() { - - setTickSizeOfAxes(); - checkIfColorLimitIsReached(); - displayLineGraphs(); - updateCounter(); - - } - - /* - * function to populate the labelToEntityRecord object with the - * values from the json file and - * dynamically generate checkboxes - */ - function loadData(jsonData) { - - $.each(jsonData, function (index, val) { - setOfLabels.push(val.label); - labelToEntityRecord[val.label] = val; - }); - - prepareTableForDataTablePagination(jsonData); - setEntityLevel(getEntityVisMode(jsonData)); - - $(".disabled-checkbox-event-receiver").live("click", function () { - - if ($(this).next().is(':disabled')) { - - createNotification("warning-notification", { - title: 'Error', - text: 'A Maximum 10 entities can be compared. Please remove some & try again.' - }, { - custom: true, - expires: false - }); - - } - - }); - - /* - * When the elements in the paginated div - * are clicked this event handler is called - */ - $("input." + entityCheckboxSelectorDOMClass).live('click', function () { - - var checkbox = $(this); - var checkboxValue = $(this).attr("value"); - var entity = labelToEntityRecord[checkboxValue]; - - if (checkbox.is(':checked')) { - - performEntityCheckboxSelectedActions(entity, checkboxValue, checkbox); - - } else { - - performEntityCheckboxUnselectedActions(entity, checkboxValue, checkbox); - - } - - performEntityCheckboxClickedRedrawActions(); - - }); - } - - function initiateTemporalGraphRenderProcess(givenGraphContainer, jsonData) { - - /* - * initial display of the grid when the page loads - * */ - init(givenGraphContainer); - - /* - * render the temporal graph per the sent content. - * */ - loadData(jQuery.parseJSON(jsonData)); - - /* - * This will make sure that top 3 entities are selected by default when the page loads. - */ - $.each($("input." + entityCheckboxSelectorDOMClass), function(index, checkbox) { + performEntityCheckboxSelectedActions(entity, checkboxValue, $(this)); - if (index > 2) { - return false; - } + performEntityCheckboxClickedRedrawActions(); - $(this).attr('checked', true); - - var checkboxValue = $(this).attr("value"); - var entity = labelToEntityRecord[checkboxValue]; - - performEntityCheckboxSelectedActions(entity, checkboxValue, $(this)); - - performEntityCheckboxClickedRedrawActions(); - - }); - - } - - initiateTemporalGraphRenderProcess(graphContainer, jsonString); -}); \ No newline at end of file + }); + + } + +} \ No newline at end of file diff --git a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonBody.ftl b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonBody.ftl index 122483a1..931dd719 100644 --- a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonBody.ftl +++ b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonBody.ftl @@ -2,7 +2,7 @@
-

+

${organizationLabel}

@@ -65,7 +65,7 @@
-

Comparing ${currentParameterObject.value} of Institutions in

+

Comparing ${currentParameterObject.value} of Institutions in ${organizationLabel}

diff --git a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonErrorCommonBody.ftl b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonErrorCommonBody.ftl index 36194a1b..e5d9db32 100644 --- a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonErrorCommonBody.ftl +++ b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonErrorCommonBody.ftl @@ -5,11 +5,15 @@ <#assign organizationVivoProfileURL = "${urls.base}/individual?uri=${organizationURI?url}"> <#assign temporalGraphURL = '${urls.base}${standardVisualizationURLRoot}?vis=${otherVisType}&uri=${organizationURI}&labelField=label'> +
+

${organizationLabel}

${textForCurrentEntityComparisonType?capitalize} Temporal Graph view ${textForOtherEntityComparisonType} temporal graph

-

This organization has neither sub-organizations nor people with ${textForCurrentEntityComparisonType} in the system. Please visit the full ${organizationLabel} profile page for a more complete overview.

+

This organization has neither sub-organizations nor people with ${textForCurrentEntityComparisonType} in the system. Please visit the full ${organizationLabel} profile page for a more complete overview.

+ +
\ No newline at end of file diff --git a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonOnGrantsStandalone.ftl b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonOnGrantsStandalone.ftl index 027630a8..e699811e 100644 --- a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonOnGrantsStandalone.ftl +++ b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonOnGrantsStandalone.ftl @@ -8,17 +8,61 @@ corresponding changes in the included Templates. --> <#include "entityComparisonSetup.ftl"> <#assign temporalGraphDownloadFileLink = '${temporalGraphDownloadCSVCommonURL}&vis=entity_grant_count'> +<#assign temporalGraphDataURL = "${urls.base}${dataVisualizationURLRoot}?vis=entity_grant_count&uri=${organizationURI}&vis_mode=json"> <#-- variables passed from server-side code --> <#assign currentParameterObject = grantParameter> -<#include "entityComparisonBody.ftl"> \ No newline at end of file +<#include "entityComparisonBody.ftl"> + +<#-- +Right now we include the error message by default becuae currently I could not devise any more smarted solution. By default +the CSS of the #error-container is display:none; so it will be hidden unless explicitly commanded to be shown which we do in +via JavaScript. +--> +<#include "entityGrantComparisonError.ftl"> \ No newline at end of file diff --git a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonOnPublicationsStandalone.ftl b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonOnPublicationsStandalone.ftl index 403138ed..c23ec40f 100644 --- a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonOnPublicationsStandalone.ftl +++ b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonOnPublicationsStandalone.ftl @@ -8,17 +8,69 @@ corresponding changes in the included Templates. --> <#include "entityComparisonSetup.ftl"> <#assign temporalGraphDownloadFileLink = '${temporalGraphDownloadCSVCommonURL}&vis=entity_comparison'> +<#assign temporalGraphDataURL = "${urls.base}${dataVisualizationURLRoot}?vis=entity_comparison&uri=${organizationURI}&vis_mode=json"> <#-- variables passed from server-side code --> <#assign currentParameterObject = publicationParameter> -<#include "entityComparisonBody.ftl"> \ No newline at end of file +
+ +<#include "entityComparisonBody.ftl"> + +<#-- +Right now we include the error message by default becuae currently I could not devise any more smarted solution. By default +the CSS of the #error-container is display:none; so it will be hidden unless explicitly commanded to be shown which we do in +via JavaScript. +--> +<#include "entityPublicationComparisonError.ftl"> + +
\ No newline at end of file diff --git a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonSetup.ftl b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonSetup.ftl index 36851711..0d9735ec 100644 --- a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonSetup.ftl +++ b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonSetup.ftl @@ -5,8 +5,6 @@ <#assign dataVisualizationURLRoot ="/visualizationData"> <#assign organizationURI ="${organizationURI?url}"> -<#assign jsonContent ="${jsonContent}"> -<#assign organizationLabel = "${organizationLabel}"> <#assign organizationVivoProfileURL = "${urls.base}/individual?uri=${organizationURI}"> <#assign subOrganizationVivoProfileURL = "${urls.base}/individual?"> @@ -49,6 +47,7 @@ we will use rev 293 (dev build version) of the flot & excanvas files. <#assign fliptext = 'js/visualization/entitycomparison/jquery_plugins/fliptext/jquery.mb.flipText.js'> <#assign jqueryNotify = 'js/jquery_plugins/jquery.notify.min.js'> +<#assign jqueryBlockUI = 'js/jquery_plugins/jquery.blockUI.min.js'> <#assign jqueryUI = 'js/jquery-ui/js/jquery-ui-1.8.4.custom.min.js'> <#assign datatable = 'js/jquery_plugins/jquery.dataTables.min.js'> <#assign entityComparisonUtils = 'js/visualization/entitycomparison/util.js'> @@ -56,9 +55,11 @@ we will use rev 293 (dev build version) of the flot & excanvas files. <#assign guiEventManager = 'js/visualization/entitycomparison/gui-event-manager.js'> + ${scripts.add(flot)} ${scripts.add(fliptext)} +${scripts.add(jqueryBlockUI)} ${scripts.add(jqueryUI)} ${scripts.add(datatable)} ${scripts.add(entityComparisonUtils)} @@ -90,14 +91,16 @@ var contextPath = "${urls.base}"; var temporalGraphSmallIcon = "${temporalGraphSmallIcon}"; var subOrganizationVivoProfileURL = "${subOrganizationVivoProfileURL}"; -var jsonString = '${jsonContent}'; +var jsonString = '${jsonContent!}'; var organizationLabel = '${organizationLabel}'; var organizationVIVOProfileURL = "${organizationVivoProfileURL}"; -var loadingImageLink = contextPath + "/images/visualization/ajax-loader.gif"; +var loadingImageLink = contextPath + "/images/visualization/ajax-loader-indicator.gif"; var entityCheckboxSelectorDOMClass = "${entityCheckboxSelectorDOMClass}"; +var temporalGraphProcessor; + /* This has to be declared before making a call to GUI event manager JS. */ @@ -119,4 +122,4 @@ var COMPARISON_PARAMETERS_INFO = { -${scripts.add(guiEventManager)} \ No newline at end of file +${headScripts.add(guiEventManager)} \ No newline at end of file diff --git a/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/VisualizationFrameworkConstants.java b/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/VisualizationFrameworkConstants.java index 1b089de8..0910598a 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/VisualizationFrameworkConstants.java +++ b/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/VisualizationFrameworkConstants.java @@ -90,7 +90,6 @@ public class VisualizationFrameworkConstants { public static final String SCHOOL_COMPARISON_VIS_MODE = "SCHOOL"; public static final String DEPARTMENT_COMPARISON_VIS_MODE = "DEPARTMENT"; public static final String HIGHEST_LEVEL_ORGANIZATION_VIS_MODE = "HIGHEST_LEVEL_ORGANIZATION"; - /* * These values represent possible visualizations provided as values to the "vis" url key. @@ -105,5 +104,9 @@ public class VisualizationFrameworkConstants { public static final String ENTITY_COMPARISON_VIS = "entity_comparison"; public static final String CO_PI_VIS = "coprincipalinvestigator"; - + + /* + * These values represent possible vis-modes for temporal graph vis + * */ + public static final String TEMPORAL_GRAPH_JSON_DATA_VIS_MODE = "json"; } diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipRequestHandler.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipRequestHandler.java index 42d7cc9b..7cb30a4e 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipRequestHandler.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipRequestHandler.java @@ -18,8 +18,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.Portal; 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.controller.visualization.freemarker.VisualizationFrameworkConstants; import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.DataVisualizationController; +import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.VisualizationFrameworkConstants; import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoAuthorshipData; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Node; @@ -133,28 +133,40 @@ public class CoAuthorshipRequestHandler implements VisualizationRequestHandler { - private String getCoauthorsListCSVContent(Map coAuthorsToCount) { + private String getCoauthorsListCSVContent(CoAuthorshipData coAuthorshipData) { StringBuilder csvFileContent = new StringBuilder(); - csvFileContent.append("Year, Count\n"); + csvFileContent.append("Co-author, Count\n"); - for (Entry currentEntry : coAuthorsToCount.entrySet()) { - csvFileContent.append(StringEscapeUtils.escapeCsv(currentEntry.getKey())); + //for (Entry currentEntry : coAuthorsToCount.entrySet()) { + for (Node currNode : coAuthorshipData.getNodes()) { + + /* + * We have already printed the Ego Node info. + * */ + if (currNode != coAuthorshipData.getEgoNode()) { + + + csvFileContent.append(StringEscapeUtils.escapeCsv(currNode.getNodeName())); csvFileContent.append(","); - csvFileContent.append(currentEntry.getValue()); + csvFileContent.append(currNode.getNumOfAuthoredWorks()); csvFileContent.append("\n"); + + } + + } return csvFileContent.toString(); - + } private String getCoauthorsPerYearCSVContent(Map> yearToCoauthors) { StringBuilder csvFileContent = new StringBuilder(); - csvFileContent.append("Year, Count, Co-Author(s)\n"); + csvFileContent.append("Year, Count, Co-author(s)\n"); for (Entry> currentEntry : yearToCoauthors.entrySet()) { csvFileContent.append(StringEscapeUtils.escapeCsv(currentEntry.getKey())); @@ -225,15 +237,11 @@ public class CoAuthorshipRequestHandler implements VisualizationRequestHandler { private Map prepareCoauthorsListDataResponse(CoAuthorshipData coAuthorshipData) { String outputFileName = ""; - Map coAuthorsToCount = new TreeMap(); - + if (coAuthorshipData.getNodes() != null && coAuthorshipData.getNodes().size() > 0) { outputFileName = UtilityFunctions.slugify(coAuthorshipData.getEgoNode().getNodeName()) + "_co-authors" + ".csv"; - - coAuthorsToCount = getCoAuthorsList(coAuthorshipData); - } else { outputFileName = "no_co-authors" + ".csv"; } @@ -244,29 +252,11 @@ public class CoAuthorshipRequestHandler implements VisualizationRequestHandler { fileData.put(DataVisualizationController.FILE_CONTENT_TYPE_KEY, "application/octet-stream"); fileData.put(DataVisualizationController.FILE_CONTENT_KEY, - getCoauthorsListCSVContent(coAuthorsToCount)); + getCoauthorsListCSVContent(coAuthorshipData)); return fileData; } - private Map getCoAuthorsList(CoAuthorshipData coAuthorsipVO) { - - Map coAuthorsToCount = new TreeMap(); - - for (Node currNode : coAuthorsipVO.getNodes()) { - - /* - * We have already printed the Ego Node info. - * */ - if (currNode != coAuthorsipVO.getEgoNode()) { - - coAuthorsToCount.put(currNode.getNodeName(), currNode.getNumOfAuthoredWorks()); - - } - } - return coAuthorsToCount; - } - /** * Provides a response when graphml formatted co-authorship network is requested, typically by * the flash vis. diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIGrantCountRequestHandler.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIGrantCountRequestHandler.java index 7e73d080..2b635e2d 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIGrantCountRequestHandler.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIGrantCountRequestHandler.java @@ -153,21 +153,30 @@ public class CoPIGrantCountRequestHandler implements VisualizationRequestHandler } - private String getCoPIsListCSVContent(Map coPIsToCount) { + private String getCoPIsListCSVContent(CoPIData coPIData) { StringBuilder csvFileContent = new StringBuilder(); - csvFileContent.append("Year, Count\n"); + csvFileContent.append("Co-investigator, Count\n"); - for (Entry currentEntry : coPIsToCount.entrySet()) { - csvFileContent.append(StringEscapeUtils.escapeCsv(currentEntry.getKey())); +// for (Entry currentEntry : coPIData.entrySet()) { + for (CoPINode currNode : coPIData.getNodes()) { + + /* + * We have already printed the Ego Node info. + * */ + if (currNode != coPIData.getEgoNode()) { + + csvFileContent.append(StringEscapeUtils.escapeCsv(currNode.getNodeName())); csvFileContent.append(","); - csvFileContent.append(currentEntry.getValue()); + csvFileContent.append(currNode.getNumberOfInvestigatedGrants()); csvFileContent.append("\n"); + + } + } return csvFileContent.toString(); - } @@ -175,7 +184,7 @@ public class CoPIGrantCountRequestHandler implements VisualizationRequestHandler StringBuilder csvFileContent = new StringBuilder(); - csvFileContent.append("Year, Count, Co-PI(s)\n"); + csvFileContent.append("Year, Count, Co-investigator(s)\n"); for (Map.Entry> currentEntry : yearToCoPI.entrySet()) { @@ -247,15 +256,12 @@ public class CoPIGrantCountRequestHandler implements VisualizationRequestHandler private Map prepareCoPIsListDataResponse(CoPIData coPIData) { String outputFileName = ""; - Map coPIsToCount = new TreeMap(); if (coPIData.getNodes() != null && coPIData.getNodes().size() > 0) { outputFileName = UtilityFunctions.slugify(coPIData.getEgoNode().getNodeName()) + "_co-investigators" + ".csv"; - coPIsToCount = getCoPIsList(coPIData); - } else { outputFileName = "no_co-investigators" + ".csv"; } @@ -266,7 +272,7 @@ public class CoPIGrantCountRequestHandler implements VisualizationRequestHandler fileData.put(DataVisualizationController.FILE_CONTENT_TYPE_KEY, "application/octet-stream"); fileData.put(DataVisualizationController.FILE_CONTENT_KEY, - getCoPIsListCSVContent(coPIsToCount)); + getCoPIsListCSVContent(coPIData)); return fileData; } diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/EntityComparisonUtilityFunctions.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/EntityComparisonUtilityFunctions.java index 3a9cfd4a..354fe6be 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/EntityComparisonUtilityFunctions.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/EntityComparisonUtilityFunctions.java @@ -5,14 +5,21 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; +import com.hp.hpl.jena.iri.IRI; +import com.hp.hpl.jena.iri.IRIFactory; import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.RDFNode; +import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryFieldLabels; import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.GenericQueryMap; @@ -107,4 +114,47 @@ public class EntityComparisonUtilityFunctions { return subOrganizationTypesResult; } + public static String getEntityLabelFromDAO(VitroRequest vitroRequest, + String entityURI) { + + IndividualDao iDao = vitroRequest.getWebappDaoFactory().getIndividualDao(); + Individual ind = iDao.getIndividualByURI(entityURI); + + String organizationLabel = "Unknown Organization"; + + if (ind != null) { + organizationLabel = ind.getName(); + } + return organizationLabel; + } + + public static String getStaffProvidedOrComputedHighestLevelOrganization(Log log, + Dataset Dataset) + throws MalformedQueryParametersException { + + String finalHighestLevelOrganizationURI = ""; + + String staffProvidedHighestLevelOrganization = ConfigurationProperties.getProperty("visualization.topLevelOrg"); + + /* + * First checking if the staff has provided highest level organization in deploy.properties + * if so use to temporal graph vis. + */ + if (StringUtils.isNotBlank(staffProvidedHighestLevelOrganization)) { + + /* + * To test for the validity of the URI submitted. + */ + IRIFactory iRIFactory = IRIFactory.jenaImplementation(); + IRI iri = iRIFactory.create(staffProvidedHighestLevelOrganization); + + if (iri.hasViolation(false)) { + finalHighestLevelOrganizationURI = EntityComparisonUtilityFunctions.getHighestLevelOrganizationURI(log, Dataset); + } else { + finalHighestLevelOrganizationURI = staffProvidedHighestLevelOrganization; + } + } + return finalHighestLevelOrganizationURI; + } + } diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/EntityPublicationCountConstructQueryRunner.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/EntityPublicationCountConstructQueryRunner.java index c62c3c37..9700c5b1 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/EntityPublicationCountConstructQueryRunner.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/EntityPublicationCountConstructQueryRunner.java @@ -67,10 +67,7 @@ public class EntityPublicationCountConstructQueryRunner { + "?Person rdfs:label ?PersonLabel . " + "?Resource core:linkedInformationResource ?Document . " + "?Document rdf:type bibo:Document . " - + "?Document rdfs:label ?DocumentLabel . " - + "?Document core:dateTimeValue ?dateTimeValue . " - + "?dateTimeValue core:dateTime ?publicationDate . " - + "?Document core:year ?publicationYearUsing_1_1_property " + + "?Document rdfs:label ?DocumentLabel " +"}" + "WHERE { " + "<"+queryURI+ "> core:hasSubOrganization ?subOrganization . " @@ -80,18 +77,8 @@ public class EntityPublicationCountConstructQueryRunner { + "?Person core:authorInAuthorship ?Resource . " + "?Person rdfs:label ?PersonLabel . " + "?Resource core:linkedInformationResource ?Document . " -// + "?Document rdf:type bibo:Document . " - + "?Document rdfs:label ?DocumentLabel " - - + "{" - + "?Document core:dateTimeValue ?dateTimeValue . " - + "?dateTimeValue core:dateTime ?publicationDate " - + "}" - + "UNION " - + "{" - + "?Document core:year ?publicationYearUsing_1_1_property " - + "}" - + + "?Document rdf:type bibo:Document . " + + "?Document rdfs:label ?DocumentLabel " + "}" ; @@ -110,10 +97,7 @@ public class EntityPublicationCountConstructQueryRunner { + "?Person rdfs:label ?PersonLabel . " + "?Resource core:linkedInformationResource ?Document . " + "?Document rdf:type bibo:Document . " - + "?Document rdfs:label ?DocumentLabel . " - + "?Document core:dateTimeValue ?dateTimeValue . " - + "?dateTimeValue core:dateTime ?publicationDate . " - + "?Document core:year ?publicationYearUsing_1_1_property ." + + "?Document rdfs:label ?DocumentLabel " +"}" + "WHERE { " + "<"+queryURI+ "> core:organizationForPosition ?Position . " @@ -121,18 +105,8 @@ public class EntityPublicationCountConstructQueryRunner { + "?Person core:authorInAuthorship ?Resource . " + "?Person rdfs:label ?PersonLabel . " + "?Resource core:linkedInformationResource ?Document . " -// + "?Document rdf:type bibo:Document . " - + "?Document rdfs:label ?DocumentLabel " - - + "{" - + "?Document core:dateTimeValue ?dateTimeValue . " - + "?dateTimeValue core:dateTime ?publicationDate " - + "}" - + "UNION " - + "{" - + "?Document core:year ?publicationYearUsing_1_1_property " - + "}" - + + "?Document rdf:type bibo:Document . " + + "?Document rdfs:label ?DocumentLabel " + "}" ; @@ -140,90 +114,93 @@ public class EntityPublicationCountConstructQueryRunner { } -// private String generateConstructQueryForDocumentDateTimeValueOneLevelDeep(String queryURI){ -// -// String sparqlQuery = -// -// "CONSTRUCT { " -// + "<"+queryURI+ "> core:hasSubOrganization ?subOrganization . " -// + "?subOrganization core:organizationForPosition ?Position . " -// + "?Position core:positionForPerson ?Person . " -// + "?Person core:authorInAuthorship ?Resource . " -// + "?Resource core:linkedInformationResource ?Document . " -// + "?Document rdf:type bibo:Document . " -// + "?Document core:dateTimeValue ?dateTimeValue . " -// + "?dateTimeValue core:dateTime ?publicationDate . " -// + "?Document core:year ?publicationYearUsing_1_1_property " -// +"}" -// + "WHERE { " -// + "<"+queryURI+ "> core:hasSubOrganization ?subOrganization . " -// + "?subOrganization core:organizationForPosition ?Position . " -// + "?Position core:positionForPerson ?Person . " -// + "?Person core:authorInAuthorship ?Resource . " -// + "?Resource core:linkedInformationResource ?Document . " -// + "?Document rdf:type bibo:Document . " -// + "{" -// + "?Document core:dateTimeValue ?dateTimeValue . " -// + "?dateTimeValue core:dateTime ?publicationDate " -// + "}" -// + "UNION " -// + "{" -// + "?Document core:year ?publicationYearUsing_1_1_property " -// + "}" -// + "}" ; -// -// -// return sparqlQuery; -// -// } + private String generateConstructQueryForDocumentDateTimeValueOneLevelDeep(String queryURI){ + + String sparqlQuery = + + "CONSTRUCT { " + + "<"+queryURI+ "> core:hasSubOrganization ?subOrganization . " + + "?subOrganization core:organizationForPosition ?Position . " + + "?Position core:positionForPerson ?Person . " + + "?Person core:authorInAuthorship ?Resource . " + + "?Resource core:linkedInformationResource ?Document . " + + "?Document rdf:type bibo:Document . " + + "?Document core:dateTimeValue ?dateTimeValue . " + + "?dateTimeValue core:dateTime ?publicationDate . " + + "?Document core:year ?publicationYearUsing_1_1_property " + +"}" + + "WHERE { " + + "<"+queryURI+ "> core:hasSubOrganization ?subOrganization . " + + "?subOrganization core:organizationForPosition ?Position . " + + "?Position core:positionForPerson ?Person . " + + "?Person core:authorInAuthorship ?Resource . " + + "?Resource core:linkedInformationResource ?Document . " + + "?Document rdf:type bibo:Document . " + + "{" + + "?Document core:dateTimeValue ?dateTimeValue . " + + "?dateTimeValue core:dateTime ?publicationDate " + + "}" + + "UNION " + + "{" + + "?Document core:year ?publicationYearUsing_1_1_property " + + "}" + + "}" ; + + + return sparqlQuery; -// private String generateConstructQueryForDocumentDateTimeValue(String queryURI){ -// -// String sparqlQuery = -// -// "CONSTRUCT { " -// + "<"+queryURI+ "> core:organizationForPosition ?Position . " -// + "?Position core:positionForPerson ?Person . " -// + "?Person core:authorInAuthorship ?Resource . " -// + "?Resource core:linkedInformationResource ?Document . " -// + "?Document rdf:type bibo:Document . " -// + "?Document core:dateTimeValue ?dateTimeValue . " -// + "?dateTimeValue core:dateTime ?publicationDate . " -// + "?Document core:year ?publicationYearUsing_1_1_property " -// +"}" -// + "WHERE { " -// + "<"+queryURI+ "> core:organizationForPosition ?Position . " -// + "?Position core:positionForPerson ?Person . " -// + "?Person core:authorInAuthorship ?Resource . " -// + "?Resource core:linkedInformationResource ?Document . " -// + "?Document rdf:type bibo:Document . " -// + "{" -// + "?Document core:dateTimeValue ?dateTimeValue . " -// + "?dateTimeValue core:dateTime ?publicationDate " -// + "}" -// + "UNION " -// + "{" -// + "?Document core:year ?publicationYearUsing_1_1_property " -// + "}" -// + "}" ; -// -// -// return sparqlQuery; -// -// } + } + + private String generateConstructQueryForDocumentDateTimeValue(String queryURI){ + + String sparqlQuery = + + "CONSTRUCT { " + + "<"+queryURI+ "> core:organizationForPosition ?Position . " + + "?Position core:positionForPerson ?Person . " + + "?Person core:authorInAuthorship ?Resource . " + + "?Resource core:linkedInformationResource ?Document . " + + "?Document rdf:type bibo:Document . " + + "?Document core:dateTimeValue ?dateTimeValue . " + + "?dateTimeValue core:dateTime ?publicationDate . " + + "?Document core:year ?publicationYearUsing_1_1_property " + +"}" + + "WHERE { " + + "<"+queryURI+ "> core:organizationForPosition ?Position . " + + "?Position core:positionForPerson ?Person . " + + "?Person core:authorInAuthorship ?Resource . " + + "?Resource core:linkedInformationResource ?Document . " + + "?Document rdf:type bibo:Document . " + + "{" + + "?Document core:dateTimeValue ?dateTimeValue . " + + "?dateTimeValue core:dateTime ?publicationDate " + + "}" + + "UNION " + + "{" + + "?Document core:year ?publicationYearUsing_1_1_property " + + "}" + + "}" ; + + + return sparqlQuery; + + } private Model executeQuery(Set constructQueries, Dataset Dataset) { Model constructedModel = ModelFactory.createDefaultModel(); + + before = System.currentTimeMillis(); for (String queryString : constructQueries) { - before = System.currentTimeMillis(); + log.debug("CONSTRUCT query string : " + queryString); Query query = null; try{ - query = QueryFactory.create(QueryConstants.getSparqlPrefixQuery() + queryString, SYNTAX); + query = QueryFactory.create(QueryConstants.getSparqlPrefixQuery() + queryString, SYNTAX); + //log.info("query: "+ queryString); }catch(Throwable th){ log.error("Could not create CONSTRUCT SPARQL query for query " + "string. " + th.getMessage()); @@ -232,16 +209,16 @@ public class EntityPublicationCountConstructQueryRunner { QueryExecution qe = QueryExecutionFactory.create( query, Dataset); - try { qe.execConstruct(constructedModel); } finally { qe.close(); } - - after = System.currentTimeMillis(); - log.debug("Time taken to execute the CONSTRUCT queries is in milliseconds: " + (after - before) ); + } + + after = System.currentTimeMillis(); + log.info("Time taken to execute the CONSTRUCT queries is in milliseconds: " + (after - before) ); // constructedModel.write(System.out); return constructedModel; } @@ -281,8 +258,8 @@ public class EntityPublicationCountConstructQueryRunner { constructQueries.add(generateConstructQueryForOrganizationLabel(this.egoURI)); constructQueries.add(generateConstructQueryForSubOrganizations(this.egoURI)); constructQueries.add(generateConstructQueryForPersons(this.egoURI)); -// constructQueries.add(generateConstructQueryForDocumentDateTimeValueOneLevelDeep(this.egoURI)); -// constructQueries.add(generateConstructQueryForDocumentDateTimeValue(this.egoURI)); + constructQueries.add(generateConstructQueryForDocumentDateTimeValueOneLevelDeep(this.egoURI)); + constructQueries.add(generateConstructQueryForDocumentDateTimeValue(this.egoURI)); } } diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/EntityPublicationCountRequestHandler.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/EntityPublicationCountRequestHandler.java index 71237186..116212a2 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/EntityPublicationCountRequestHandler.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/EntityPublicationCountRequestHandler.java @@ -17,20 +17,16 @@ import org.apache.commons.logging.LogFactory; import com.google.gson.Gson; import com.hp.hpl.jena.iri.IRI; import com.hp.hpl.jena.iri.IRIFactory; -import com.hp.hpl.jena.iri.Violation; import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.rdf.model.Model; - import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Portal; 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.controller.visualization.freemarker.DataVisualizationController; import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.VisualizationFrameworkConstants; -import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants; import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Entity; @@ -40,6 +36,10 @@ import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.QueryR import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.VisualizationRequestHandler; +/** + * @author cdtank + * + */ public class EntityPublicationCountRequestHandler implements VisualizationRequestHandler { @@ -53,49 +53,15 @@ public class EntityPublicationCountRequestHandler implements String entityURI = vitroRequest .getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY); - if (StringUtils.isNotBlank(entityURI)){ - - return getSubjectEntityAndGenerateResponse(vitroRequest, log, - Dataset, entityURI); - } else { + if (StringUtils.isBlank(entityURI)){ - String staffProvidedHighestLevelOrganization = ConfigurationProperties.getProperty("visualization.topLevelOrg"); - - /* - * First checking if the staff has provided highest level organization in deploy.properties - * if so use to temporal graph vis. - */ - if (StringUtils.isNotBlank(staffProvidedHighestLevelOrganization)) { - - /* - * To test for the validity of the URI submitted. - */ - IRIFactory iRIFactory = IRIFactory.jenaImplementation(); - IRI iri = iRIFactory.create(staffProvidedHighestLevelOrganization); - - if (iri.hasViolation(false)) { - - String errorMsg = ((Violation) iri.violations(false).next()).getShortMessage(); - log.error("Highest Level Organization URI provided is invalid " + errorMsg); - - } else { - - return getSubjectEntityAndGenerateResponse(vitroRequest, - log, Dataset, - staffProvidedHighestLevelOrganization); - } - } - - String highestLevelOrgURI = EntityComparisonUtilityFunctions.getHighestLevelOrganizationURI(log, - Dataset); - - return getSubjectEntityAndGenerateResponse(vitroRequest, log, - Dataset, highestLevelOrgURI); + entityURI = EntityComparisonUtilityFunctions + .getStaffProvidedOrComputedHighestLevelOrganization(log, Dataset); } - + return prepareStandaloneMarkupResponse(vitroRequest, entityURI); } - - private ResponseValues getSubjectEntityAndGenerateResponse( + + private Map getSubjectEntityAndGenerateDataResponse( VitroRequest vitroRequest, Log log, Dataset Dataset, String subjectEntityURI) throws MalformedQueryParametersException { @@ -105,25 +71,33 @@ public class EntityPublicationCountRequestHandler implements QueryRunner queryManager = new EntityPublicationCountQueryRunner( subjectEntityURI, constructedModel, log); - Entity entity = queryManager.getQueryResult(); - if (entity.getEntityLabel().equals("no-label")) { - return prepareStandaloneErrorResponse(vitroRequest, subjectEntityURI); + return prepareStandaloneDataErrorResponse(vitroRequest, subjectEntityURI); } else { - return getSubEntityTypesAndRenderStandaloneResponse( + return getSubEntityTypesAndComputeDataResponse( vitroRequest, log, Dataset, subjectEntityURI, entity); } } + + private Map prepareStandaloneDataErrorResponse( + VitroRequest vitroRequest, String subjectEntityURI) { + Map fileData = new HashMap(); + + fileData.put(DataVisualizationController.FILE_CONTENT_TYPE_KEY, + "application/octet-stream"); + fileData.put(DataVisualizationController.FILE_CONTENT_KEY, "{\"error\" : \"No Publications for this Organization found in VIVO.\"}"); + return fileData; + } - private ResponseValues getSubEntityTypesAndRenderStandaloneResponse( + private Map getSubEntityTypesAndComputeDataResponse( VitroRequest vitroRequest, Log log, Dataset Dataset, String subjectEntityURI, Entity entity) throws MalformedQueryParametersException { @@ -131,10 +105,9 @@ public class EntityPublicationCountRequestHandler implements Map> subOrganizationTypesResult = EntityComparisonUtilityFunctions.getSubEntityTypes( log, Dataset, subjectEntityURI); - return prepareStandaloneResponse(vitroRequest, entity, subjectEntityURI, + return prepareStandaloneDataResponse(vitroRequest, entity, entity.getSubEntities(), subOrganizationTypesResult); } - @Override public Map generateDataVisualization( @@ -143,20 +116,52 @@ public class EntityPublicationCountRequestHandler implements String entityURI = vitroRequest .getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY); + + /* + * This will provide the data in json format mainly used for standalone tmeporal vis. + * */ + if (VisualizationFrameworkConstants.TEMPORAL_GRAPH_JSON_DATA_VIS_MODE + .equalsIgnoreCase(vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY))) { + + if (StringUtils.isNotBlank(entityURI)){ - EntityPublicationCountConstructQueryRunner constructQueryRunner = new EntityPublicationCountConstructQueryRunner(entityURI, Dataset, log); - Model constructedModel = constructQueryRunner.getConstructedModel(); + return getSubjectEntityAndGenerateDataResponse( + vitroRequest, + log, + Dataset, + entityURI); + } else { + + return getSubjectEntityAndGenerateDataResponse( + vitroRequest, + log, + Dataset, + EntityComparisonUtilityFunctions + .getStaffProvidedOrComputedHighestLevelOrganization( + log, + Dataset)); + } + + } else { + /* + * This provides csv download files for the content in the tables. + * */ + + EntityPublicationCountConstructQueryRunner constructQueryRunner = new EntityPublicationCountConstructQueryRunner(entityURI, Dataset, log); + Model constructedModel = constructQueryRunner.getConstructedModel(); + + QueryRunner queryManager = new EntityPublicationCountQueryRunner( + entityURI, constructedModel, log); + + Entity entity = queryManager.getQueryResult(); + + Map> subOrganizationTypesResult = EntityComparisonUtilityFunctions.getSubEntityTypes( + log, Dataset, entityURI); + + return prepareDataResponse(entity, entity.getSubEntities(),subOrganizationTypesResult); + + } - QueryRunner queryManager = new EntityPublicationCountQueryRunner( - entityURI, constructedModel, log); - - Entity entity = queryManager.getQueryResult(); - - Map> subOrganizationTypesResult = EntityComparisonUtilityFunctions.getSubEntityTypes( - log, Dataset, entityURI); - - return prepareDataResponse(entity, entity.getSubEntities(),subOrganizationTypesResult); - } @@ -199,41 +204,49 @@ public class EntityPublicationCountRequestHandler implements fileData.put(DataVisualizationController.FILE_CONTENT_KEY, getEntityPublicationsPerYearCSVContent(subentities, subOrganizationTypesResult)); return fileData; -} + } - /** - * - * @param vreq - * @param valueObjectContainer - * @return - */ - private TemplateResponseValues prepareStandaloneResponse(VitroRequest vreq, - Entity entity, String entityURI, Map> subOrganizationTypesResult) { + private Map prepareStandaloneDataResponse( + VitroRequest vitroRequest, + Entity entity, + Set subentities, + Map> subOrganizationTypesResult) { + + Map fileData = new HashMap(); + + fileData.put(DataVisualizationController.FILE_CONTENT_TYPE_KEY, + "application/octet-stream"); + fileData.put(DataVisualizationController.FILE_CONTENT_KEY, + writePublicationsOverTimeJSON(vitroRequest, entity.getSubEntities(), subOrganizationTypesResult)); + return fileData; + } + + private TemplateResponseValues prepareStandaloneMarkupResponse(VitroRequest vreq, + String entityURI) { Portal portal = vreq.getPortal(); String standaloneTemplate = "entityComparisonOnPublicationsStandalone.ftl"; - String jsonContent = ""; - jsonContent = writePublicationsOverTimeJSON(vreq, entity.getSubEntities(), subOrganizationTypesResult); - - String title = ""; - - if (StringUtils.isNotBlank(entity.getEntityLabel())) { - title = entity.getEntityLabel() + " - "; - } - + String organizationLabel = EntityComparisonUtilityFunctions.getEntityLabelFromDAO(vreq, + entityURI); + Map body = new HashMap(); body.put("portalBean", portal); - body.put("title", title + "Temporal Graph Visualization"); + body.put("title", organizationLabel + " - Temporal Graph Visualization"); body.put("organizationURI", entityURI); - body.put("organizationLabel", entity.getEntityLabel()); - body.put("jsonContent", jsonContent); + body.put("organizationLabel", organizationLabel); return new TemplateResponseValues(standaloneTemplate, body); - } + - + /** + * @deprecated This method should not be called anymore although the templates being + * called by this method are still in use, so we should not get rid of it. + * @param vitroRequest + * @param entityURI + * @return + */ private ResponseValues prepareStandaloneErrorResponse( VitroRequest vitroRequest, String entityURI) { @@ -241,14 +254,8 @@ public class EntityPublicationCountRequestHandler implements String standaloneTemplate = "entityPublicationComparisonError.ftl"; Map body = new HashMap(); - IndividualDao iDao = vitroRequest.getWebappDaoFactory().getIndividualDao(); - Individual ind = iDao.getIndividualByURI(entityURI); - - String organizationLabel = "Unknown Organization"; - - if (ind != null) { - organizationLabel = ind.getName(); - } + String organizationLabel = EntityComparisonUtilityFunctions.getEntityLabelFromDAO(vitroRequest, + entityURI); body.put("organizationLabel", organizationLabel); body.put("portalBean", portal); @@ -258,8 +265,7 @@ public class EntityPublicationCountRequestHandler implements return new TemplateResponseValues(standaloneTemplate, body); } - - + /** * function to generate a json file for year <-> publication count mapping * @param vreq @@ -302,7 +308,7 @@ public class EntityPublicationCountRequestHandler implements entityJson.setEntityURI(subentity.getIndividualURI()); - boolean isPerson = vreq.getWebappDaoFactory().getIndividualDao().getIndividualByURI(subentity.getIndividualURI()).isVClass("http://xmlns.com/foaf/0.1/Person"); + boolean isPerson = UtilityFunctions.isEntityAPerson(vreq, subentity); if(isPerson){ entityJson.setVisMode("PERSON"); @@ -316,7 +322,7 @@ public class EntityPublicationCountRequestHandler implements return json.toJson(subEntitiesJson); } - + private String getEntityPublicationsPerYearCSVContent(Set subentities, Map> subOrganizationTypesResult) { StringBuilder csvFileContent = new StringBuilder(); diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitygrantcount/EntityGrantCountRequestHandler.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitygrantcount/EntityGrantCountRequestHandler.java index eb2b8b5b..d873a21e 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitygrantcount/EntityGrantCountRequestHandler.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitygrantcount/EntityGrantCountRequestHandler.java @@ -15,21 +15,15 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.google.gson.Gson; -import com.hp.hpl.jena.iri.IRI; -import com.hp.hpl.jena.iri.IRIFactory; -import com.hp.hpl.jena.iri.Violation; import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.rdf.model.Model; -import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Portal; 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.controller.visualization.freemarker.DataVisualizationController; import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.VisualizationFrameworkConstants; -import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants; import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.entitycomparison.EntityComparisonUtilityFunctions; @@ -54,48 +48,13 @@ public class EntityGrantCountRequestHandler implements String entityURI = vitroRequest .getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY); - if (StringUtils.isNotBlank(entityURI)){ + if (StringUtils.isBlank(entityURI)){ - return getSubjectEntityAndGenerateResponse(vitroRequest, log, - Dataset, entityURI); + entityURI = EntityComparisonUtilityFunctions + .getStaffProvidedOrComputedHighestLevelOrganization(log, Dataset); - } else { - - String staffProvidedHighestLevelOrganization = ConfigurationProperties.getProperty("visualization.topLevelOrg"); - - /* - * First checking if the staff has provided highest level organization in deploy.properties - * if so use to temporal graph vis. - */ - if (StringUtils.isNotBlank(staffProvidedHighestLevelOrganization)) { - - /* - * To test for the validity of the URI submitted. - */ - IRIFactory iRIFactory = IRIFactory.jenaImplementation(); - IRI iri = iRIFactory.create(staffProvidedHighestLevelOrganization); - - if (iri.hasViolation(false)) { - - String errorMsg = ((Violation) iri.violations(false).next()).getShortMessage(); - log.error("Highest Level Organization URI provided is invalid " + errorMsg); - - } else { - - return getSubjectEntityAndGenerateResponse(vitroRequest, - log, Dataset, - staffProvidedHighestLevelOrganization); - } - } - - String highestLevelOrgURI = EntityComparisonUtilityFunctions.getHighestLevelOrganizationURI(log, - Dataset); - - return getSubjectEntityAndGenerateResponse(vitroRequest, log, - Dataset, highestLevelOrgURI); } - - + return prepareStandaloneMarkupResponse(vitroRequest, entityURI); } @Override @@ -105,6 +64,36 @@ public class EntityGrantCountRequestHandler implements String entityURI = vitroRequest .getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY); + + /* + * This will provide the data in json format mainly used for standalone tmeporal vis. + * */ + if (VisualizationFrameworkConstants.TEMPORAL_GRAPH_JSON_DATA_VIS_MODE + .equalsIgnoreCase(vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY))) { + + if (StringUtils.isNotBlank(entityURI)){ + + return getSubjectEntityAndGenerateDataResponse( + vitroRequest, + log, + Dataset, + entityURI); + } else { + + return getSubjectEntityAndGenerateDataResponse( + vitroRequest, + log, + Dataset, + EntityComparisonUtilityFunctions + .getStaffProvidedOrComputedHighestLevelOrganization( + log, + Dataset)); + } + + } else { + /* + * This provides csv download files for the content in the tables. + * */ EntityGrantCountConstructQueryRunner constructQueryRunner = new EntityGrantCountConstructQueryRunner(entityURI, Dataset, log); Model constructedModel = constructQueryRunner.getConstructedModel(); @@ -119,6 +108,8 @@ public class EntityGrantCountRequestHandler implements log, Dataset, entityURI); return prepareDataResponse(entity, entity.getSubEntities(),subOrganizationTypesResult); + + } } @@ -128,7 +119,7 @@ public class EntityGrantCountRequestHandler implements throw new UnsupportedOperationException("Entity Grant Count does not provide Ajax Response."); } - private ResponseValues getSubjectEntityAndGenerateResponse( + private Map getSubjectEntityAndGenerateDataResponse( VitroRequest vitroRequest, Log log, Dataset Dataset, String subjectEntityURI) throws MalformedQueryParametersException { @@ -142,18 +133,16 @@ public class EntityGrantCountRequestHandler implements Entity entity = queryManager.getQueryResult(); if (entity.getEntityLabel().equals("no-label")) { - - return prepareStandaloneErrorResponse(vitroRequest, subjectEntityURI); - + return prepareStandaloneDataErrorResponse(vitroRequest, subjectEntityURI); } else { - return getSubEntityTypesAndRenderStandaloneResponse( + return getSubEntityTypesAndComputeDataResponse( vitroRequest, log, Dataset, subjectEntityURI, entity); } } - private ResponseValues getSubEntityTypesAndRenderStandaloneResponse( + private Map getSubEntityTypesAndComputeDataResponse( VitroRequest vitroRequest, Log log, Dataset Dataset, String subjectOrganization, Entity entity) throws MalformedQueryParametersException { @@ -161,8 +150,34 @@ public class EntityGrantCountRequestHandler implements Map> subOrganizationTypesResult = EntityComparisonUtilityFunctions.getSubEntityTypes( log, Dataset, subjectOrganization); - return prepareStandaloneResponse(vitroRequest, entity, subjectOrganization, - subOrganizationTypesResult); + return prepareStandaloneDataResponse(vitroRequest, entity, subOrganizationTypesResult); + } + + + private Map prepareStandaloneDataErrorResponse( + VitroRequest vitroRequest, String subjectEntityURI) { + + Map fileData = new HashMap(); + + fileData.put(DataVisualizationController.FILE_CONTENT_TYPE_KEY, + "application/octet-stream"); + fileData.put(DataVisualizationController.FILE_CONTENT_KEY, "{\"error\" : \"No Grants for this Organization found in VIVO.\"}"); + return fileData; + } + + + private Map prepareStandaloneDataResponse( + VitroRequest vitroRequest, + Entity entity, + Map> subOrganizationTypesResult) { + + Map fileData = new HashMap(); + + fileData.put(DataVisualizationController.FILE_CONTENT_TYPE_KEY, + "application/octet-stream"); + fileData.put(DataVisualizationController.FILE_CONTENT_KEY, + writeGrantsOverTimeJSON(vitroRequest, entity.getSubEntities(), subOrganizationTypesResult)); + return fileData; } /** @@ -200,39 +215,30 @@ public class EntityGrantCountRequestHandler implements return fileData; } - /** - * - * @param vreq - * @param valueObjectContainer - * @return - */ - private TemplateResponseValues prepareStandaloneResponse(VitroRequest vreq, - Entity entity, String entityURI, Map> subOrganizationTypesResult) { - Portal portal = vreq.getPortal(); - String standaloneTemplate = "entityComparisonOnGrantsStandalone.ftl"; + private TemplateResponseValues prepareStandaloneMarkupResponse(VitroRequest vreq, + String entityURI) { + + Portal portal = vreq.getPortal(); + String standaloneTemplate = "entityComparisonOnGrantsStandalone.ftl"; - String jsonContent = ""; - jsonContent = writeGrantsOverTimeJSON(vreq, entity.getSubEntities(), subOrganizationTypesResult); - - String title = ""; + String organizationLabel = EntityComparisonUtilityFunctions.getEntityLabelFromDAO(vreq, + entityURI); - if (StringUtils.isNotBlank(entity.getEntityLabel())) { - title = entity.getEntityLabel() + " - "; - } - - - Map body = new HashMap(); - body.put("portalBean", portal); - body.put("title", title + "Temporal Graph Visualization"); - body.put("organizationURI", entityURI); - body.put("organizationLabel", entity.getEntityLabel()); - body.put("jsonContent", jsonContent); - - return new TemplateResponseValues(standaloneTemplate, body); - + Map body = new HashMap(); + body.put("portalBean", portal); + body.put("title", organizationLabel + " - Temporal Graph Visualization"); + body.put("organizationURI", entityURI); + body.put("organizationLabel", organizationLabel); + + return new TemplateResponseValues(standaloneTemplate, body); } + /** + * @deprecated This method should not be called anymore although the templates being + * called by this method are still in use, so we should not get rid of it. + * @return + */ private ResponseValues prepareStandaloneErrorResponse( VitroRequest vitroRequest, String entityURI) { @@ -240,14 +246,8 @@ public class EntityGrantCountRequestHandler implements String standaloneTemplate = "entityGrantComparisonError.ftl"; Map body = new HashMap(); - IndividualDao iDao = vitroRequest.getWebappDaoFactory().getIndividualDao(); - Individual ind = iDao.getIndividualByURI(entityURI); - - String organizationLabel = "Unknown Organization"; - - if (ind != null) { - organizationLabel = ind.getName(); - } + String organizationLabel = EntityComparisonUtilityFunctions.getEntityLabelFromDAO(vitroRequest, + entityURI); body.put("organizationLabel", organizationLabel); @@ -300,7 +300,7 @@ public class EntityGrantCountRequestHandler implements entityJson.setEntityURI(subentity.getIndividualURI()); - boolean isPerson = vreq.getWebappDaoFactory().getIndividualDao().getIndividualByURI(subentity.getIndividualURI()).isVClass("http://xmlns.com/foaf/0.1/Person"); + boolean isPerson = UtilityFunctions.isEntityAPerson(vreq, subentity); if(isPerson){ entityJson.setVisMode("PERSON"); diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/visutils/UtilityFunctions.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/visutils/UtilityFunctions.java index dd52e479..7fbb89eb 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/visutils/UtilityFunctions.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/visutils/UtilityFunctions.java @@ -35,6 +35,7 @@ import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Co import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPINode; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Grant; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Node; +import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.SubEntity; public class UtilityFunctions { @@ -320,5 +321,9 @@ public class UtilityFunctions { return collaboratorshipNetworkURL != null ? collaboratorshipNetworkURL : "" ; } + + public static boolean isEntityAPerson(VitroRequest vreq, SubEntity subentity) { + return vreq.getWebappDaoFactory().getIndividualDao().getIndividualByURI(subentity.getIndividualURI()).isVClass("http://xmlns.com/foaf/0.1/Person"); + } }