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"); + } }