From f7452b1bcebf30f198ae11a82680da6340d47af5 Mon Sep 17 00:00:00 2001 From: cdtank Date: Thu, 31 Mar 2011 15:37:32 +0000 Subject: [PATCH] 1. Added dynamic reload of data instead of page refresh, for temporal graph vis. 2. Added link-textbox for viz of each parameter form the dropdown box in temporal vis. 3. Made sure that the choices are preserved when another option is selected from the dropdown box. 4. Refactor of some legacy front-end code for temporal vis. 5. Added legend for bars drawn below the graph. 6. Formatted the last cached at date time. --- .../visualization/entitycomparison/layout.css | 51 +++- productMods/images/iconInfo-small.png | Bin 0 -> 3033 bytes productMods/images/visualization/diagonal.png | Bin 0 -> 251 bytes .../visualization/legend-unknown-bar-dark.png | Bin 0 -> 311 bytes .../legend-unknown-bar-light.png | Bin 0 -> 312 bytes .../entitycomparison/constants.js | 10 +- .../entitycomparison/gui-event-manager.js | 280 +++++++++++++----- .../js/visualization/entitycomparison/util.js | 275 ++++++++++++----- .../visualization-helper-functions.js | 9 + .../entitycomparison/entityComparisonBody.ftl | 10 + .../entityComparisonOnGrantsStandalone.ftl | 6 + ...tityComparisonOnPublicationsStandalone.ftl | 6 + .../entityComparisonSetup.ftl | 21 +- ...ublicationVisualizationRequestHandler.java | 13 +- .../visutils/SelectOnModelUtilities.java | 8 +- 15 files changed, 519 insertions(+), 170 deletions(-) create mode 100644 productMods/images/iconInfo-small.png create mode 100644 productMods/images/visualization/diagonal.png create mode 100644 productMods/images/visualization/legend-unknown-bar-dark.png create mode 100644 productMods/images/visualization/legend-unknown-bar-light.png diff --git a/productMods/css/visualization/entitycomparison/layout.css b/productMods/css/visualization/entitycomparison/layout.css index 36f5746c..381646e6 100644 --- a/productMods/css/visualization/entitycomparison/layout.css +++ b/productMods/css/visualization/entitycomparison/layout.css @@ -20,6 +20,55 @@ .easy-deselect-label a.temporal-vis-url { float: right; } + +.known-bar { + display: inline-block; + cursor: help; +} + +.unknown-inner-bar { + opacity: 0.5; + filter:alpha(opacity=50); + display: inline-block; +} + +.bar-count-text { + padding-right: 3px; + vertical-align: super; +} + +img.bar-count-icon { + vertical-align: super; + cursor: help; +} + +.unknown-bar { + background: url("../../../images/visualization/diagonal.png") repeat scroll 50% 50% #666666; + cursor: help; +} + +.legend-bar { + margin-bottom: 3px; +} + +.unknown-legend-bar { + background: url("../../../images/visualization/legend-unknown-bar-dark.png") repeat #B7B7B7; +} + + +#legend-known-bar-text, +#legend-unknown-bar-text { + font-size: 0.75em; +} + +span#copy-vis-viewlink { + display: none; +} + +img#copy-vis-viewlink-icon { + cursor: pointer; +} + a.temporalGraphLinks { background-color: #2485AE; color: white; @@ -224,4 +273,4 @@ p.displayCounter{ #noPubsOrGrants-span a { color: #84a655; font-size:16px; -} +} \ No newline at end of file diff --git a/productMods/images/iconInfo-small.png b/productMods/images/iconInfo-small.png new file mode 100644 index 0000000000000000000000000000000000000000..cd825c43471787c344dbd5af5d1de6d92f1b8f7d GIT binary patch literal 3033 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 bz~ScrA}m~}GU7v@00000NkvXXu0mjfn-iFF literal 0 HcmV?d00001 diff --git a/productMods/images/visualization/diagonal.png b/productMods/images/visualization/diagonal.png new file mode 100644 index 0000000000000000000000000000000000000000..64ece5707d91a6edf9fad4bfcce0c4dbcafcf58d GIT binary patch literal 251 zcmVbvPcjKS|RKP(6sDcCAB(_QB%0978a<$Ah$!b|E zwn;|HO0i8cQj@~)s!ajF0S002ovPDHLkV1oEp BYH0uf literal 0 HcmV?d00001 diff --git a/productMods/images/visualization/legend-unknown-bar-dark.png b/productMods/images/visualization/legend-unknown-bar-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..91e19084470fdfd26b547079269cd1be69249179 GIT binary patch literal 311 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1|)m_?Z^dEk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XZhE>nhE&{obKQ~au!0CnfU&ir`>TbUK8Wo)naQ*_=5;*B z+7%NMUbF0bP*x#5dFIjT|3>%I`^$~rCO@t{_S@k3@|n-)7%R49$)!DdvZcWC!}}fc zYz!U?O%R*ju*Kpev$5X354>k~TuN`_3TIx|T=+UPhEpT)c*31R(do=D3+6jmOQgF$ z5SsAJ@k+zx0$W$6GayZVpAPh7|Mko`r9Gq2R3Y^3b>Bs^pYY92$+CBGzj1|&E$z-t zwS_O*6XbkU6=Ew{jrH!UOxYT5-kB$KS7n!H-JLb}nRpoFO0M`!6SsQ{^dy6)tDnm{ Hr-UW|PWXTQ literal 0 HcmV?d00001 diff --git a/productMods/images/visualization/legend-unknown-bar-light.png b/productMods/images/visualization/legend-unknown-bar-light.png new file mode 100644 index 0000000000000000000000000000000000000000..f545ae688eecb999b90b9f154a4dfeeaae772347 GIT binary patch literal 312 zcmV-80muG{P)#qK07WUr=y6d>e6Qvev%U=Xv_Os`AnPzWjZt`YGlaW0Z3)n>QuE zpW?3M2^n_;B5@Ij#YG?%7xHE@&cELoading " + 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'); - - - */ - + options = { + responseContainer: $("div#temporal-graph-response"), + bodyContainer: $("#body"), + errorContainer: $("#error-container"), + dataURL: selectedDataURL + }; + + setupLoadingScreen(options.responseContainer); + + $.ajax({ + url: options.dataURL, + dataType: "json", + timeout: 5 * 60 * 1000, + success: function (data) { + + if (data.error) { + options.bodyContainer.remove(); + options.errorContainer.show(); + options.responseContainer.unblock(); + } else { + options.bodyContainer.show(); + options.errorContainer.remove(); + temporalGraphProcessor.redoTemporalGraphRenderProcess(graphContainer, data); + options.responseContainer.unblock(); + } + } + }); }); }); @@ -68,8 +80,9 @@ $("input[type=checkbox].easyDeselectCheckbox").live('click', function(){ var checkbox = $(this); var checkboxValue = $(this).attr("value"); - var linkedCheckbox = labelToCheckedEntities[checkboxValue]; - var entityToBeRemoved = labelToEntityRecord[checkboxValue]; + var linkedCheckbox = URIToCheckedEntities[checkboxValue]; + + var entityToBeRemoved = URIToEntityRecord[checkboxValue]; if(!checkbox.is(':checked')){ //console.log("Easy deselect checkbox is unclicked!"); @@ -85,7 +98,6 @@ $("input[type=checkbox].easyDeselectCheckbox").live('click', function(){ } }); - $(".disabled-checkbox-event-receiver").live("click", function () { if ($(this).next().is(':disabled')) { @@ -97,11 +109,32 @@ $(".disabled-checkbox-event-receiver").live("click", function () { custom: true, expires: false }); - } - }); +$("#copy-vis-viewlink-icon").live('click', function() { + + if ($("#copy-vis-viewlink").is(':visible')) { + + $("#copy-vis-viewlink").hide(); + + } else { + + $("#copy-vis-viewlink").show(); + + var linkTextBox = $("#copy-vis-viewlink input[type='text']"); + + linkTextBox.val(getCurrentParameterVisViewLink()); + + linkTextBox.select(); + } + +}); + +function getCurrentParameterVisViewLink() { + return location.protocol + "//" + location.host + COMPARISON_PARAMETERS_INFO[currentParameter].viewLink; +} + function performEntityCheckboxUnselectedActions(entity, checkboxValue, checkbox) { removeUsedColor(entity); @@ -121,10 +154,10 @@ function performEntityCheckboxSelectedActions(entity, checkboxValue, checkbox) { createLegendRow(entity, $("#bottom")); renderLineGraph(renderedObjects, entity); - labelToCheckedEntities[checkboxValue] = checkbox; - labelToCheckedEntities[checkboxValue].entity = entity; -// console.log(labelToCheckedEntities[checkboxValue], entity); + URIToCheckedEntities[checkboxValue] = checkbox; + URIToCheckedEntities[checkboxValue].entity = entity; + /* * To highlight the rows belonging to selected entities. @@ -151,7 +184,7 @@ function loadData(jsonData, dataTableParams) { $.each(jsonData, function (index, val) { setOfLabels.push(val.label); - labelToEntityRecord[val.label] = val; + URIToEntityRecord[val.entityURI] = val; if (val.lastCachedAtDateTime) { lastCachedAtDateTimes[lastCachedAtDateTimes.length] = val.lastCachedAtDateTime; } @@ -164,6 +197,26 @@ function loadData(jsonData, dataTableParams) { } +/* + * function to populate the labelToEntityRecord object with the + * values from the json file and + * dynamically generate checkboxes + */ +function reloadData(preselectedEntityURIs, jsonData) { + + $.each(jsonData, function (index, val) { + setOfLabels.push(val.label); + URIToEntityRecord[val.entityURI] = val; + if (val.lastCachedAtDateTime) { + lastCachedAtDateTimes[lastCachedAtDateTimes.length] = val.lastCachedAtDateTime; + } + }); + + reloadDataTablePagination(preselectedEntityURIs, jsonData); + setEntityLevel(getEntityVisMode(jsonData)); +} + + function entityCheckboxOperatedOnEventListener() { /* @@ -174,7 +227,7 @@ function entityCheckboxOperatedOnEventListener() { var checkbox = $(this); var checkboxValue = $(this).attr("value"); - var entity = labelToEntityRecord[checkboxValue]; + var entity = URIToEntityRecord[checkboxValue]; if (checkbox.is(':checked')) { @@ -183,13 +236,10 @@ function entityCheckboxOperatedOnEventListener() { } else { performEntityCheckboxUnselectedActions(entity, checkboxValue, checkbox); - } performEntityCheckboxClickedRedrawActions(); - }); - } function renderTemporalGraphVisualization(parameters) { @@ -200,7 +250,6 @@ function renderTemporalGraphVisualization(parameters) { parameters.bodyContainer, parameters.errorContainer, parameters.responseContainer); - } /* @@ -216,7 +265,7 @@ function setupLoadingScreen(visContainerDIV) { $.blockUI.defaults.css.width = '500px'; $.blockUI.defaults.css.border = '0px'; - $.blockUI.defaults.css.top = '15%'; + $.blockUI.defaults.css.top = '1%'; visContainerDIV.block({ message: '

2) { - return false; - } - - $(this).attr('checked', true); - - var checkboxValue = $(this).attr("value"); - var entity = labelToEntityRecord[checkboxValue]; - - performEntityCheckboxSelectedActions(entity, checkboxValue, $(this)); - - performEntityCheckboxClickedRedrawActions(); + if (index > 2) { + return false; + } + + entitySelector.manuallyTriggerSelectOnDataTableCheckbox($(this)); }); if ($("#incomplete-data-disclaimer").length > 0 && lastCachedAtDateTimes.length > 0) { $("#incomplete-data-disclaimer").attr( "title", - $("#incomplete-data-disclaimer").attr("title") + " as of " + getReadableDateForLastCachedAtDate(parseXSDateTime(lastCachedAtDateTimes[0]))); + $("#incomplete-data-disclaimer").attr("title") + " as of " + + lastCachedAtDateTimeParser.getReadableDateString(lastCachedAtDateTimes[0])); } + }, + + redoTemporalGraphRenderProcess: function(givenGraphContainer, jsonData) { + + var currentSelectedEntityURIs = []; + + $.each(URIToCheckedEntities, function(index, entity){ + currentSelectedEntityURIs.push(index); + }); + + clearRenderedObjects(); + initConstants(); + + /* + * initial display of the grid when the page loads + * */ + init(givenGraphContainer); + + /* + * render the temporal graph per the sent content. + * */ + reloadData(currentSelectedEntityURIs, jsonData); + + lastCachedAtDateTimes.sort(lastCachedAtDateTimeParser.ascendingDateSorter); + + if (currentSelectedEntityURIs.length > 0) { + + $.each(currentSelectedEntityURIs, function(index, uri) { + + var targetPrevSelectedCheckbox = $('input.' + entityCheckboxSelectorDOMClass + '[value="' + uri + '"]'); + + if (targetPrevSelectedCheckbox.length > 0) { + + entitySelector.manuallyTriggerSelectOnDataTableCheckbox(targetPrevSelectedCheckbox); + } + }); + } else { + /* + * 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; + } + entitySelector.manuallyTriggerSelectOnDataTableCheckbox($(this)); + }); + } + + if ($("#incomplete-data-disclaimer").length > 0 && lastCachedAtDateTimes.length > 0) { + + var disclaimerText = "This information is based solely on " + + COMPARISON_PARAMETERS_INFO[currentParameter].value + + " which have been loaded into the VIVO system" + + " as of " + lastCachedAtDateTimeParser.getReadableDateString(lastCachedAtDateTimes[0]); + + $("#incomplete-data-disclaimer").attr( + "title", disclaimerText); + } + $("#copy-vis-viewlink input[type='text']").val(getCurrentParameterVisViewLink()); } } \ No newline at end of file diff --git a/productMods/js/visualization/entitycomparison/util.js b/productMods/js/visualization/entitycomparison/util.js index 9ff1662f..aafe6c20 100644 --- a/productMods/js/visualization/entitycomparison/util.js +++ b/productMods/js/visualization/entitycomparison/util.js @@ -221,9 +221,11 @@ function init(graphContainer) { var optionSelected = $("select.comparisonValues option:selected").val(); // TODO: make use of the id on the select field instead of a generic one. - $("#comparisonParameter").text("Total Number of " + $("select.comparisonValues option:selected").val()); + $("#comparisonParameter").text("Total Number of " + optionSelected); $('#yaxislabel').html("Number of " + optionSelected).mbFlipText(false); $('#comparisonHeader').html(optionSelected).css('font-weight', 'bold'); + $('#legend-known-bar-text').text("Known " + COMPARISON_PARAMETERS_INFO[currentParameter].name + " year"); + $('#legend-unknown-bar-text').text("Unknown " + COMPARISON_PARAMETERS_INFO[currentParameter].name + " year"); var defaultFlotOptions = { @@ -455,11 +457,8 @@ function calcMinandMaxYears(jsonObject, year) { } }); - - year.min = Math.min.apply(Math, validYearsInData); year.max = Math.max.apply(Math, validYearsInData); - } /** @@ -473,7 +472,8 @@ function calcMaxOfComparisonParameter(allEntities) { var validCountsInData = new Array(); $.each(allEntities, function(key, currentEntity) { - validCountsInData.push(calcSumOfComparisonParameter(currentEntity)); + combinedCount = calcSumOfComparisonParameter(currentEntity); + validCountsInData.push(combinedCount.knownYearCount + combinedCount.unknownYearCount); }); return Math.max.apply(Math, validCountsInData); @@ -510,12 +510,26 @@ function calcMaxWithinComparisonParameter(jsonObject){ */ function calcSumOfComparisonParameter(entity) { - var sum = 0; + var known = 0; + var unknown = 0; $.each(entity.data, function(index, data){ - sum += this[1]; + + if (this[0] === -1) { + unknown += this[1]; + } else { + known += this[1]; + } + + + }); + sum = { + knownYearCount: known, + unknownYearCount: unknown + }; + return sum; } @@ -539,47 +553,39 @@ function contains(objectArray, object) { return flag; } -/** - * Dynamically change the linewidth and ticksize based on input year range. - * - * @param {Object} - * yearRange - */ -function setLineWidthAndTickSize(yearRange, flotOptions) { +var LineWidth = { - if (yearRange > 0 && yearRange < 15) { - flotOptions.series.lines.lineWidth = 3; - flotOptions.xaxis.tickSize = 1; - } else if (yearRange > 15 && yearRange < 70) { - flotOptions.series.lines.lineWidth = 2; - flotOptions.xaxis.tickSize = 5; - } else if (yearRange == 0 ) { - flotOptions.series.lines.lineWidth = 3; - flotOptions.xaxis.tickSize = 1; - } else { - flotOptions.series.lines.lineWidth = 1; - flotOptions.xaxis.tickSize = 10; + getLineWidth: function(tickSize) { + if (tickSize >= 0 && tickSize < 10) { + return 3; + } else if (tickSize >= 10 && tickSize < 50) { + return 2; + } else { + return 1; + } } - -} + +}; var TickSize = { maxValue: 0.0, maxTicks: { - yAxis: 12.0 + yAxis: 12.0, + xAxis: 12.0 }, tickSizeUnits: { - yAxis: [1.0, 2.5, 5.0] + yAxis: [1.0, 2.5, 5.0], + xAxis: [1.0, 2, 5.0] }, getApproximateTickSize: function(allowedMaxTicks) { return Math.max(Math.ceil(parseFloat(this.maxValue) / allowedMaxTicks), 1.0); }, - getFinalTickSizeForYaxis: function(unitTickSizeGenerator) { + getFinalTickSize: function(unitTickSizeGenerator) { tickSizeMultiplier = 1.0; finalTickSize = 1.0; approximateTickSize = this.getApproximateTickSize(this.maxTicks.yAxis); @@ -599,14 +605,15 @@ var TickSize = { } tickSizeMultiplier *= 10.0; } - return finalTickSize; }, getTickSize: function(value, onAxis) { this.maxValue = value; if (onAxis.trim().toLowerCase() === 'y') { - return this.getFinalTickSizeForYaxis(this.tickSizeUnits.yAxis); + return this.getFinalTickSize(this.tickSizeUnits.yAxis); + } else if (onAxis.trim().toLowerCase() === 'x') { + return this.getFinalTickSize(this.tickSizeUnits.xAxis); } } }; @@ -622,7 +629,7 @@ var TickSize = { function createLegendRow(entity, bottomDiv) { var parentP = $('

'); - parentP.attr('id', slugify(entity.label)); + parentP.attr('id', slugify(entity.entityURI)); var labelDiv = $('

'); labelDiv.attr('class', 'easy-deselect-label'); @@ -650,17 +657,38 @@ function createLegendRow(entity, bottomDiv) { var barDiv = $('
'); barDiv.attr('id', 'bar'); + + var knownBar = $(''); + knownBar.attr('class', 'known-bar'); + var unknownBar = $(''); + unknownBar.attr('class', 'unknown-bar'); + + var unknownBarInnerSpan = $(''); + unknownBarInnerSpan.attr('class', 'unknown-inner-bar'); + unknownBarInnerSpan.html(' '); + + unknownBar.append(unknownBarInnerSpan); + + barDiv.append(knownBar); + barDiv.append(unknownBar); + var numAttributeText = $(''); - numAttributeText.attr('id', 'text'); + numAttributeText.attr('class', 'bar-count-text'); parentP.append(checkbox); parentP.append(labelDiv); parentP.append(hiddenLabel); parentP.append(barDiv); parentP.append(numAttributeText); - - bottomDiv.children('p.displayCounter').after(parentP); + + if (bottomDiv.children('p.displayCounter').nextAll().last().length > 0) { + bottomDiv.children('p.displayCounter').nextAll().last().after(parentP); + } else { + bottomDiv.children('p.displayCounter').after(parentP); + } + + renderBarAndLabel(entity, barDiv, labelDiv, numAttributeText); } @@ -672,19 +700,35 @@ function createLegendRow(entity, bottomDiv) { function renderBarAndLabel(entity, divBar, divLabel, spanElement) { - var sum = calcSumOfComparisonParameter(entity); + var combinedCount = calcSumOfComparisonParameter(entity); + + var sum = combinedCount.knownYearCount + combinedCount.unknownYearCount; + var normalizedWidth = getNormalizedWidth(entity, sum); - - divBar.css("background-color", colorToAssign); - divBar.css("width", normalizedWidth); + var knownNormalizedWidth = getNormalizedWidth(entity, combinedCount.knownYearCount); + + if (combinedCount.unknownYearCount) { + var unknownNormalizedWidth = getNormalizedWidth(entity, combinedCount.unknownYearCount); + } else { + var unknownNormalizedWidth = 0; + } + + divBar.css("width", normalizedWidth + 5); + divBar.children(".known-bar").html(" ").css("background-color", colorToAssign).css("width", knownNormalizedWidth); + divBar.children(".unknown-bar").children(".unknown-inner-bar").html(" ").css("background-color", colorToAssign).css("width", unknownNormalizedWidth); var entityLabelForLegend = divLabel.find(".entity-label-url"); entityLabelForLegend.html(entity.label); entityLabelForLegend.ellipsis(); entityLabelForLegend.wrap(""); + var countExplanation = 'VIVO knows the ' + COMPARISON_PARAMETERS_INFO[currentParameter].name + ' year for ' + + combinedCount.knownYearCount + ' out of ' + + sum + ' of these ' + COMPARISON_PARAMETERS_INFO[currentParameter].pluralName; + + divBar.attr("title", countExplanation); + spanElement.text(sum).css("font-size", "0.8em").css("color", "#595B5B"); - } function getVIVOURL(entity){ @@ -826,7 +870,7 @@ function getNextFreeColor(entity){ function getNormalizedWidth(entity, sum){ - var maxValueOfComparisonParameter = calcMaxOfComparisonParameter(labelToEntityRecord); + var maxValueOfComparisonParameter = calcMaxOfComparisonParameter(URIToEntityRecord); var normalizedWidth = 0; normalizedWidth = Math.floor(225 * (sum / maxValueOfComparisonParameter)); @@ -906,18 +950,19 @@ function generateCheckBoxes(label, checkedFlag, fontFlag){ function clearRenderedObjects(){ - $.each(labelToCheckedEntities, function(index, val){ + $.each(URIToCheckedEntities, function(index, val){ if($(val).is(':checked')){ $(val).attr("checked", false); updateRowHighlighter(val); - removeUsedColor(labelToEntityRecord[$(val).attr("value")]); - removeEntityUnChecked(renderedObjects, labelToEntityRecord[$(val).attr("value")]); + removeUsedColor(URIToEntityRecord[$(val).attr("value")]); + removeEntityUnChecked(renderedObjects, URIToEntityRecord[$(val).attr("value")]); removeLegendRow(val); displayLineGraphs(); } }); - labelToCheckedEntities = {}; + URIToCheckedEntities = {}; + checkIfColorLimitIsReached(); updateCounter(); @@ -948,17 +993,19 @@ function displayLineGraphs(){ } } - - function removeCheckBoxFromGlobalSet(checkbox){ //remove checkbox object from the globals var value = $(checkbox).attr("value"); - if(labelToCheckedEntities[value]){ + /*if (labelToCheckedEntities[value]) { delete labelToCheckedEntities[value]; + }*/ + + if (URIToCheckedEntities[value]) { + delete URIToCheckedEntities[value]; } + } - /* * function to create a table to be * used by jquery.dataTables. The JsonObject @@ -967,7 +1014,7 @@ function removeCheckBoxFromGlobalSet(checkbox){ function prepareTableForDataTablePagination(jsonData, dataTableParams){ resetStopWordCount(); - var checkboxCount = 0; + var table = $(''); table.attr('cellpadding', '0'); table.attr('cellspacing', '0'); @@ -985,19 +1032,20 @@ function prepareTableForDataTablePagination(jsonData, dataTableParams){ var entityLabelTH = $(''); + var checkboxCount = 0; - $.each(labelToEntityRecord, function(index, val){ + $.each(URIToEntityRecord, function(index, val) { var entityTypesWithoutStopWords = removeStopWords(val); var row = $(''); var checkboxTD = $('
'); entityLabelTH.html('Entity Name'); - var publicationCountTH = $(''); + var activityCountTH = $(''); if ($("select.comparisonValues option:selected").text() === "by Publications") { - publicationCountTH.html('Publication Count'); + activityCountTH.html('Publication Count'); } else { - publicationCountTH.html('Grant Count'); + activityCountTH.html('Grant Count'); } + activityCountTH.attr("id", "activity-count-column"); var entityTypeTH = $(''); entityTypeTH.html('Entity Type'); tr.append(checkboxTH); tr.append(entityLabelTH); - tr.append(publicationCountTH); + tr.append(activityCountTH); tr.append(entityTypeTH); thead.append(tr); @@ -1005,20 +1053,26 @@ function prepareTableForDataTablePagination(jsonData, dataTableParams){ table.append(thead); var tbody = $('
'); - checkboxTD.html('
 
'); + checkboxTD.html('
 
'); var labelTD = $('
'); labelTD.css("width", "100px"); - labelTD.html(index); + labelTD.html(val.label); var publicationCountTD = $(''); - publicationCountTD.html(calcSumOfComparisonParameter(val)); + + var combinedCount = calcSumOfComparisonParameter(val); + + publicationCountTD.html(combinedCount.knownYearCount + combinedCount.unknownYearCount); var entityTypeTD = $(''); entityTypeTD.html(entityTypesWithoutStopWords); @@ -1076,6 +1130,91 @@ function prepareTableForDataTablePagination(jsonData, dataTableParams){ } + +/* + * function to create a table to be + * used by jquery.dataTables. The JsonObject + * returned is used to populate the pagination table. + */ +function reloadDataTablePagination(preselectedEntityURIs, jsonData){ + + resetStopWordCount(); + + /* + * In case no entities are selected, we want that redraw should happen so that top entities are + * pre-selected. + * */ + var shouldRedraw = preselectedEntityURIs.length ? false : true; + + var currentDataTable = $('#datatable').dataTable(); + + currentDataTable.fnClearTable(); + + if ($("select.comparisonValues option:selected").text() === "by Publications") { + $("#activity-count-column").html('Publication Count'); + } else { + $("#activity-count-column").html('Grant Count'); + } + + function addNewRowAfterReload(entity) { + + var checkboxTD = '
 
'; + + var labelTD = entity.label; + + var combinedCount = calcSumOfComparisonParameter(entity); + var publicationCountTD = combinedCount.knownYearCount + combinedCount.unknownYearCount; + + var entityTypeTD = removeStopWords(entity); + + var newRow = [checkboxTD, + labelTD, + publicationCountTD, + entityTypeTD]; + + /* + * Dont redraw the table, so no sorting, no filtering. + * */ + currentDataTable.fnAddData(newRow, shouldRedraw); + + /* + * Dont redraw the table, so no sorting, no filtering. + * */ + currentDataTable.fnDraw(shouldRedraw); + + } + + /* + * This will ensure that currently selected entities are added first in the table, + * to make sure that they are "visible" in the DOM. This so that our manual trigger + * for selecting this checkboxes on page load, actually works. + * */ + $.each(preselectedEntityURIs, function(index, uri) { + if (URIToEntityRecord[uri]) { + addNewRowAfterReload(URIToEntityRecord[uri]); + } + }); + + + $.each(URIToEntityRecord, function(index, val) { + + /* + * Don't consider already added pre-selected entities. + * */ + if ($.inArray(index, preselectedEntityURIs) < 0) { + addNewRowAfterReload(val); + } + }); + + /* + * We should change to the first page so that checkboxes are selectable. + * */ + currentDataTable.fnPageChange('first'); +} + function updateRowHighlighter(linkedCheckBox){ linkedCheckBox.closest("tr").removeClass('datatablerowhighlight'); } @@ -1097,12 +1236,10 @@ function removeStopWords(val){ typeStringWithoutStopWords += ', '+ value; } }); - //console.log(stopWordsToCount["Person"],stopWordsToCount["Organization"]); return typeStringWithoutStopWords.substring(1, typeStringWithoutStopWords.length); } function setEntityLevel(entityLevel){ - //$('#entitylevelheading').text(' - ' + toCamelCase(entityLevel) + ' Level').css('font-style', 'italic'); $('#entityleveltext').text(' ' + entityLevel.toLowerCase()).css('font-style', 'italic'); $('#entityHeader').text(entityLevel).css('font-weight', 'bold'); $('#headerText').css("color", "#2485ae"); @@ -1195,7 +1332,7 @@ function enableUncheckedEntities(){ function checkIfColorLimitIsReached(){ - if (getSize(labelToCheckedEntities) >= 10) { + if (getSize(URIToCheckedEntities) >= 10) { disableUncheckedEntities(); } else { enableUncheckedEntities(); @@ -1207,15 +1344,17 @@ function setTickSizeOfAxes(){ var checkedLabelToEntityRecord = {}; var yearRange; - $.each(labelToCheckedEntities, function(index, val){ - checkedLabelToEntityRecord[index] = labelToEntityRecord[index]; + $.each(URIToCheckedEntities, function(index, val){ + checkedLabelToEntityRecord[index] = URIToEntityRecord[index]; }); var normalizedYearRange = getNormalizedYearRange(); - setLineWidthAndTickSize(normalizedYearRange.normalizedRange, FlotOptions); - + FlotOptions.xaxis.tickSize = + TickSize.getTickSize(normalizedYearRange.normalizedRange, 'x'); + + FlotOptions.series.lines.lineWidth = LineWidth.getLineWidth(FlotOptions.xaxis.tickSize); + FlotOptions.yaxis.tickSize = TickSize.getTickSize(calcMaxWithinComparisonParameter(checkedLabelToEntityRecord), 'y'); - } \ No newline at end of file diff --git a/productMods/js/visualization/visualization-helper-functions.js b/productMods/js/visualization/visualization-helper-functions.js index fff90383..316e8cda 100644 --- a/productMods/js/visualization/visualization-helper-functions.js +++ b/productMods/js/visualization/visualization-helper-functions.js @@ -94,4 +94,13 @@ function constructVisualizationURLForSparkline(dataString, visualizationOptions) + chartLabelPosition + parameterDifferentiator + chartColor + parameterDifferentiator + "chd=" + dataString +} + +/* + * In IE trim() is not supported. + * */ +if (typeof String.prototype.trim !== 'function') { + String.prototype.trim = function() { + return this.replace(/^\s+|\s+$/g, ''); + } } \ 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 6f9b89d3..bbe48759 100644 --- a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonBody.ftl +++ b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonBody.ftl @@ -13,10 +13,13 @@ + uri icon + + @@ -84,5 +90,9 @@

+ +

Legend

+   Known ${currentParameterObject.name} year
+   Unknown ${currentParameterObject.name} year \ 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 9a1de299..dd88f20d 100644 --- a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonOnGrantsStandalone.ftl +++ b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonOnGrantsStandalone.ftl @@ -5,6 +5,12 @@ corresponding changes in the included Templates. --> <#assign currentParameter = "grant"> + + <#include "entityComparisonSetup.ftl"> <#assign temporalGraphDownloadFileLink = '${temporalGraphDownloadCSVCommonURL}&vis=entity_grant_count'> diff --git a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonOnPublicationsStandalone.ftl b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonOnPublicationsStandalone.ftl index be1b6eb1..abd59d55 100644 --- a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonOnPublicationsStandalone.ftl +++ b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonOnPublicationsStandalone.ftl @@ -5,6 +5,12 @@ corresponding changes in the included Templates. --> <#assign currentParameter = "publication"> + + <#include "entityComparisonSetup.ftl"> <#assign temporalGraphDownloadFileLink = '${temporalGraphDownloadCSVCommonURL}&vis=entity_comparison'> diff --git a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonSetup.ftl b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonSetup.ftl index 799d6b93..c8a46376 100644 --- a/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonSetup.ftl +++ b/productMods/templates/freemarker/visualization/entitycomparison/entityComparisonSetup.ftl @@ -13,20 +13,27 @@ <#assign subOrganizationPublicationTemporalGraphCommonURL = "${urls.base}${standardVisualizationURLRoot}?vis=entity_comparison"> <#assign organizationPublicationTemporalGraphURL = "${urls.base}${standardVisualizationURLRoot}?vis=entity_comparison&uri=${organizationURI}"> +<#assign organizationPublicationTemporalGraphDataURL = "${urls.base}${dataVisualizationURLRoot}?vis=entity_comparison&uri=${organizationURI}&vis_mode=json"> + <#assign organizationGrantTemporalGraphURL = "${urls.base}${standardVisualizationURLRoot}?vis=entity_grant_count&uri=${organizationURI}"> +<#assign organizationGrantTemporalGraphDataURL = "${urls.base}${dataVisualizationURLRoot}?vis=entity_grant_count&uri=${organizationURI}&vis_mode=json"> <#assign temporalGraphSmallIcon = '${urls.images}/visualization/temporal_vis_small_icon.jpg'> <#assign temporalGraphDownloadCSVCommonURL = '${urls.base}${dataVisualizationURLRoot}?uri=${organizationURI}&labelField=label'> <#assign publicationParameter = { "name": "publication", + "pluralName": "publications", "dropDownText": "by Publications", - "viewLink": "${organizationPublicationTemporalGraphURL}", + "viewLink": "${organizationPublicationTemporalGraphURL}", + "dataLink": "${organizationPublicationTemporalGraphDataURL}", "value": "Publications" }> - + <#assign grantParameter = { "name": "grant", + "pluralName": "grants", "dropDownText": "by Grants", "viewLink": "${organizationGrantTemporalGraphURL}", + "dataLink": "${organizationGrantTemporalGraphDataURL}", "value": "Grants" }> <#assign parameterOptions = [publicationParameter, grantParameter]> @@ -42,6 +49,15 @@ we will default to using the stable version unless the request comes from IE 9 i we will use rev 293 (dev build version) of the flot & excanvas files. --> + + ${scripts.add('', '', '', @@ -50,6 +66,7 @@ ${scripts.add(' diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/cached/TemporalPublicationVisualizationRequestHandler.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/cached/TemporalPublicationVisualizationRequestHandler.java index 034ea98b..8179fd46 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/cached/TemporalPublicationVisualizationRequestHandler.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/entitycomparison/cached/TemporalPublicationVisualizationRequestHandler.java @@ -15,7 +15,6 @@ import org.apache.commons.logging.Log; import com.google.gson.Gson; import com.hp.hpl.jena.query.Dataset; -import com.hp.hpl.jena.rdf.model.Model; import edu.cornell.mannlib.vitro.webapp.beans.Portal; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; @@ -27,7 +26,6 @@ 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; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Activity; -import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.ConstructedModelTracker; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Entity; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.JsonObject; import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.SubEntity; @@ -58,11 +56,11 @@ public class TemporalPublicationVisualizationRequestHandler implements } - System.out.println("current models in the system are"); - for (Map.Entry entry : ConstructedModelTracker.getAllModels().entrySet()) { - System.out.println(entry.getKey() + " -> " + entry.getValue().size()); - } - +// System.out.println("current models in the system are"); +// for (Map.Entry entry : ConstructedModelTracker.getAllModels().entrySet()) { +// System.out.println(entry.getKey() + " -> " + entry.getValue().size()); +// } +// return prepareStandaloneMarkupResponse(vitroRequest, entityURI); } @@ -71,7 +69,6 @@ public class TemporalPublicationVisualizationRequestHandler implements String subjectEntityURI, EntityComparisonConstants.DataVisMode visMode) throws MalformedQueryParametersException { - Entity organizationEntity = SelectOnModelUtilities .getSubjectOrganizationHierarchy(dataset, subjectEntityURI); diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/visutils/SelectOnModelUtilities.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/visutils/SelectOnModelUtilities.java index 04561b97..63e46cf7 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/visutils/SelectOnModelUtilities.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/visutils/SelectOnModelUtilities.java @@ -205,7 +205,7 @@ public class SelectOnModelUtilities { OrganizationToPublicationsForSubOrganizationsModelConstructor.MODEL_TYPE, dataset); - System.out.println("getting publications for " + subOrganization.getIndividualLabel()); +// System.out.println("getting publications for " + subOrganization.getIndividualLabel()); Map fieldLabelToOutputFieldLabel = new HashMap(); fieldLabelToOutputFieldLabel.put("document", QueryFieldLabels.DOCUMENT_URL); @@ -352,7 +352,7 @@ public class SelectOnModelUtilities { for (SubEntity subOrganization : organizationEntity.getSubEntities()) { - System.out.println("constructing grants for " + subOrganization.getIndividualLabel() + " :: " + subOrganization.getIndividualURI()); +// System.out.println("constructing grants for " + subOrganization.getIndividualLabel() + " :: " + subOrganization.getIndividualURI()); long before = System.currentTimeMillis(); @@ -362,7 +362,7 @@ public class SelectOnModelUtilities { OrganizationToGrantsForSubOrganizationsModelConstructor.MODEL_TYPE, dataset); - System.out.println("\t construct -> " + (System.currentTimeMillis() - before)); +// System.out.println("\t construct -> " + (System.currentTimeMillis() - before)); before = System.currentTimeMillis(); @@ -419,7 +419,7 @@ public class SelectOnModelUtilities { subOrganization.setLastCachedAtDateTime(lastCachedAtForEntity); - System.out.println("\t select -> " + (System.currentTimeMillis() - before)); +// System.out.println("\t select -> " + (System.currentTimeMillis() - before)); } return allGrantURIToVO; }