diff --git a/productMods/css/visualization/mapofscience/layout.css b/productMods/css/visualization/mapofscience/layout.css index 7e660c5a..cbdb7737 100644 --- a/productMods/css/visualization/mapofscience/layout.css +++ b/productMods/css/visualization/mapofscience/layout.css @@ -99,36 +99,36 @@ a.clear-selected-entities { /* filter */ -.filter-option { +.filter-option, .comparison-filter-option { color: #2485AE; cursor: pointer; /*padding-right: 5px;*/ text-decoration: underline; } -.active-filter { +.active-filter, .comparison-active-filter { color: #595B5B; text-decoration: none; } -.filterInfoIcon { +.filterInfoIcon, .comparisonFilterInfoIcon { /*vertical-align:top;*/ width:15px; margin-left: 9px; } -#science-areas-filter { +.science-areas-filter { margin-bottom: 10px; } /* search in table */ -.sDomSearchBar { +.sDomSearchBar, .sDomComparisonSearchBar { margin-bottom: -10px; margin-left: 41%; } -#reset-search { +#reset-search, #comparison-reset-search { color: #2485AE; cursor: pointer; margin-left: 10px; @@ -253,4 +253,4 @@ a.map-of-science-links { ul.error-list li { font-size: 0.81em; list-style: disc inside none; -} \ No newline at end of file +} diff --git a/productMods/js/visualization/mapofscience/ComparisonDataTableWidget.js b/productMods/js/visualization/mapofscience/ComparisonDataTableWidget.js new file mode 100644 index 00000000..45ee7510 --- /dev/null +++ b/productMods/js/visualization/mapofscience/ComparisonDataTableWidget.js @@ -0,0 +1,267 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +var ComparisonDataTableWidget = Class.extend({ + + dom: { + searchBarParentContainerClass : "comparisonSearchbar", + paginationContainerClass : "paginatedtabs", + containerID: "main-science-areas-table-container", + footerID: "main-science-areas-table-footer", + firstFilterID: "comparison-first-filter", + secondFilterID: "comparison-second-filter", + filterOptionClass: "comparison-filter-option", + activeFilterClass: "comparison-active-filter", + filterInfoIconClass: "comparisonFilterInfoIcon" + }, + init: function(sciMapWidget) { + var me = this; + me.sciMapWidget = sciMapWidget; + me.widgetType = "COMPARISON_SCIENCE_AREAS"; + me.currentSelectedFilter = COMPARISON_TYPE.ORGANIZATION; + me.widget = ''; + me.tableDiv = $('
'); + $("#" + me.dom.containerID).append(this.tableDiv); + }, + loadJsonData: function(data) { + + var me = this; + me.uri = data.uri; + me.label = data.label; + me.pubsWithNoJournals = data.pubsWithNoJournals; + me.pubsWithInvalidJournals = data.pubsWithInvalidJournals; + me.pubsMapped = data.pubsMapped; + me.type = data.type; + me.subEntities = data.subEntities; + + me.setupView(); + }, + hasKey: function(key) { + return (this.keyToMarkerManagers.hasOwnProperty(key)); + }, + show: function(key) { + this.tableDiv.show(); + }, + hide: function(key) { + this.tableDiv.hide(); + }, + cleanView: function() { + this.hide(); + }, + initView: function() { + this.show(); + this.changeFilter(this.currentSelectedFilter); + }, + setupView: function() { + + var me = this; + + /* Create filter */ + var dom = me.dom; + var filter = $('
' + + 'Organizations | ' + + 'People' + + 'information icon
'); + me.tableDiv.append(filter); + createToolTip($("#comparisonImageIconTwo"), $("#comparisonToolTipTwo").html(), "topLeft"); + initFilter(dom); + + /* Create table */ + var table = $(''); + table.attr('id', 'comparisonDatatable'); + table.addClass('datatable-table'); + + var thead = $(''); + var tr = $(''); + + var levelOfScienceAreaTH = $(''); + + var rowsToInsert = []; + var i = 0; + + $.each(me.subEntities, function(index, item) { + rowsToInsert[i++] = ''; + rowsToInsert[i++] = ''; + rowsToInsert[i++] = ''; + rowsToInsert[i++] = ''; + }); + + tbody.append(rowsToInsert.join('')); + + table.append(tbody); + me.tableDiv.append(table); + + table.children("tbody").children("tr").mouseenter(function() { + + var item = me.subEntities[$(this).attr("id")]; + me.sciMapWidget.mouseIn(item.type, item.label); + }); + + table.children("tbody").children("tr").mouseleave(function() { + + var item = me.subEntities[$(this).attr("id")]; + me.sciMapWidget.mouseOut(item.type, item.label); + }); + + $('.chk').click(function() { + var element = $(this); + var index = element.attr("value"); + var item = me.subEntities[index]; + var color = "grey"; + if (element.attr('checked')) { + if ($("input:checkbox[class=chk]:checked").length > 3) { + element.attr('checked', false); + alert("The maximum number of items for comparison is 3."); + } else { + me.loadEntity(item.uri, index); + } + } else { + me.unloadEntity(item.type, item.label, index); + } + }); + + /* + * GMAIL_STYLE_PAGINATION_CONTAINER_CLASS, ACTIVE_DISCIPLINE_SUBDISCIPLINE_FILTER has to be declared + * for the filter & pagination to work properly. + * */ + GMAIL_STYLE_PAGINATION_CONTAINER_CLASS = me.dom.paginationContainerClass; + ACTIVE_DISCIPLINE_SUBDISCIPLINE_FILTER = me.currentSelectedFilter; + + if($.inArray(disciplineOrSubdisciplineDataTableFilter, $.fn.dataTableExt.afnFiltering) < 0) { + $.fn.dataTableExt.afnFiltering.push(disciplineOrSubdisciplineDataTableFilter); + } + + me.widget = table.dataTable({ + "sDom": '<"' + me.dom.searchBarParentContainerClass + + '"f><"filterInfo"i><"' + + me.dom.paginationContainerClass + '"p><"table-separator"><"datatablewrapper"t>', + "aaSorting": [ + [3, "desc"], [2,'asc'] + ], + "asStripClasses": [], + "aoColumns": [{ "bVisible": false, "bSearchable": false }, + null, + null, + null], + "iDisplayLength": 10, + "bInfo": true, + "oLanguage": { + "sInfo": "_START_ - _END_ of _TOTAL_", + "sInfoEmpty": "No matching science areas found", + "sInfoFiltered": "" + }, + "sPaginationType": "gmail_style", + "fnDrawCallback": function () { + + /* We check whether max number of allowed comparisions (currently 10) is reached + * here as well becasue the only function that is guaranteed to be called during + * page navigation is this. No need to bind it to the nav-buttons becuase 1. It is over-ridden + * by built-in navigation events & this is much cleaner. + * */ +// checkIfColorLimitIsReached(); + } + }); + + /* Create search box */ + var searchInputBox = $("." + me.dom.searchBarParentContainerClass).find("input[type=text]"); + searchInputBox.css("width", "140px"); + searchInputBox.after("X" + + "information icon"); + $("#comparison-reset-search").live('click', function() { + me.widget.fnFilter(""); + }); + createToolTip($("#comparisonSearchInfoIcon"), $("#comparisonSearchInfoTooltipText").html(), "topLeft"); + + /* Create csv download button */ + var csvButton = '
'; + me.tableDiv.append(csvButton); + + /* Create mapping statistic result */ + var totalPublications = me.pubsWithNoJournals + me.pubsWithInvalidJournals + me.pubsMapped; + $("#mapped-publications").text(addCommasToNumber(me.pubsMapped)); + $("#percent-mapped-info").show(); + $("#percent-mapped").text((100 * me.pubsMapped / totalPublications).toFixed(2)); + $("#total-publications").text(addCommasToNumber(totalPublications)); + + }, + changeFilter: function(filterType) { + var me = this; + if (filterType === COMPARISON_TYPE.ORGANIZATION) { + + $("#comparison-science-areas-th").html("Organization"); + me.currentSelectedFilter = COMPARISON_TYPE.ORGANIZATION; + $("a#csv").attr("href", entityMapOfScienceSubDisciplineCSVURL); + } else { + + $("#comparison-science-areas-th").html("Person"); + me.currentSelectedFilter = COMPARISON_TYPE.PERSON; + $("a#csv").attr("href", entityMapOfScienceDisciplineCSVURL); + + } + + ACTIVE_DISCIPLINE_SUBDISCIPLINE_FILTER = me.currentSelectedFilter; + + if (me.widget) { + me.widget.fnSettings()._iDisplayLength = 10; + me.widget.fnDraw(); + // load one item if no item is selected. Need to be improved + if ($("input:checkbox[class=chk]:checked").length == 0) { + $("input:checkbox[class=chk]").each(function(){ + var item = me.subEntities[$(this).attr("value")]; + if (item.type == me.currentSelectedFilter) { + // click event didn't work at this point??? + $(this).click(); + me.loadEntity(item.uri, $(this).attr("value")); + return false; + } + }); + } + } + }, + loadEntity: function(uri, index) { + + // Download data from server and add to markerManager if not gotten already + var me = this; + var url = scienceMapDataPrefix + uri; + downloader.download(url, function(data) { + me.sciMapWidget.loadEntity(data[0]); + + // This is ugly, need fix!!! + $("#comparisonTbody > tr[id=" + index + "]").css("color", me.sciMapWidget.getColor(me.currentSelectedFilter, me.subEntities[index].label)); + }); + }, + unloadEntity: function(key, childKey, index) { + this.sciMapWidget.unloadEntity(key, childKey); + + // This is ugly, need fix!!! + $("#comparisonTbody > tr[id=" + index + "]").css("color", "grey"); + } +}); \ No newline at end of file diff --git a/productMods/js/visualization/mapofscience/ComparisonScimapWidget.js b/productMods/js/visualization/mapofscience/ComparisonScimapWidget.js new file mode 100644 index 00000000..df925e2c --- /dev/null +++ b/productMods/js/visualization/mapofscience/ComparisonScimapWidget.js @@ -0,0 +1,249 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ +COMPARISON = { + "one":{ "name": "one", "color": "#1e90ff"}, + "two":{ "name": "two", "color": "#ff69b4"}, + "three":{ "name": "three", "color": "#32cd32"} +} + +COMPARISON_TYPE = { + "ORGANIZATION": "ORGANIZATION", + "PERSON": "PERSON" +} + +var ManagerRegistry = Class.extend({ + init: function(itemArray) { + this.occupied = {}; + this.availability = itemArray; + }, + register: function(key) { + var me = this; + if (me.occupied[key] == null && me.isAvailable()) { + me.occupied[key] = me.availability.pop(); + } + + return me.occupied[key]; + }, + unregister: function(key) { + var me = this; + var item = me.occupied[key]; + if (item) { + me.availability.push(me.occupied[key]); + delete me.occupied[key]; + } + + return item; + }, + isAvailable: function() { + return (this.availability.length != 0); + } +}); + +var ComparisonScimapWidget = Class.extend({ + init: function(map) { + var me = this; + me.activeCompositeManager = null; + me.map = map; + me.initView(); + }, + initView: function(){ + var me = this; + me.initControlPanels(); + me.initMarkerManagers(); + me.show(COMPARISON_TYPE.ORGANIZATION); + this.activeCompositeManager.addManagersToMap(); + this.updateDisplayedMarkers(); + }, + cleanView: function() { + var me = this; + me._cleanUpManagers(); + me.sliderControl.removeFromMap(); + me.disciplineLabelsControl.removeFromMap(); + me.labelsMarkerManager.removeMarkersFromMap(); + }, + initControlPanels: function() { + var me = this; + + /* Create slider control panel */ + if (me.sliderControl == null) { + me.sliderControl = new SliderControlPanel({ + map:me.map, + controlPositions: google.maps.ControlPosition.RIGHT_BOTTOM + }); + } + + /* Register event */ + me.sliderControl.addToMap(); + me.sliderControl.setChangeEventHandler(function(event, ui) { + if (me.keyToCompositeManager) { + me.updateDisplayedMarkers(); + } + }); + + /* create */ + if (me.disciplineLabelsControl == null) { + me.labelsMarkerManager = new DisciplineLabelsMarkerManager(map); + me.disciplineLabelsControl = new CheckBoxPanel({ + map: map, + checked: true, + text: "Show discipline labels", + click: function() { + if($(this).attr('checked')) { + me.labelsMarkerManager.showMarkers(); + } else { + me.labelsMarkerManager.hideMarkers(); + } + } + }); + } + + /* Display labels if checked */ + me.disciplineLabelsControl.addToMap(); + me.labelsMarkerManager.addMarkersToMap(); + if (me.disciplineLabelsControl.isChecked()) { + me.labelsMarkerManager.showMarkers(); + } + }, + initMarkerManagers: function() { + if (this.keyToCompositeManager == null) { + + // Create all the marker managers + var me = this; + me.keyToCompositeManager = {}; + $.each(COMPARISON_TYPE, function(type, value) { + var managerArray = []; + + $.each(COMPARISON, function(key, attrs) { + var manager = new SubdisciplineMarkerManager( + me.map, + new SingleColorStrategy(attrs.color), + null + ); + manager.color = attrs.color; + managerArray.push(manager); + }); + me.keyToCompositeManager[type] = new CompositeMarkerManager(); + me.keyToCompositeManager[type].registry = new ManagerRegistry(managerArray); + }); + } + }, + loadJsonData: function(data) { + this.isUnloaded = false; + }, + loadEntity: function(data) { + var me = this; + me.uri = data.uri; + me.label = data.label; + me.pubsWithNoJournals = data.pubsWithNoJournals; + me.pubsWithInvalidJournals = data.pubsWithInvalidJournals; + me.pubsMapped = data.pubsMapped; + + var scienceActivities = data.subdisciplineActivity; + + var childKey = data.label; + var compositeManager = me.getCompositeManager(data.type); + // Avoid reload if data was loaded + if (compositeManager.hasKey(childKey)) { + me.updateMap(); + } else { + var manager = compositeManager.registry.register(childKey); + if (manager) { + // clean previous markers + manager.removeAll(); + + // Need to create the AreaSizeCoding function + manager.setSizeCoder(new CircleSizeCoder({ + scaler: new Scaler({ maxValue: me.pubsMapped }) + })); + + $.each(scienceActivities, function(science, density) { + + // Create marker and add it to manager + manager.createMarker(science, density); + + }); // end each scienceActivity + manager.sort(); + + compositeManager.addManager(childKey, manager); + me.updateMap(); + } + } + }, + unloadEntity: function(key, childKey) { + this.removeManager(key, childKey); + }, + getCompositeManager: function(key) { + return this.keyToCompositeManager[key]; + }, + mouseIn: function(key, childKey) { + var compositeManager = this.getCompositeManager(key); + + // Focus if only it is a valid manager + if (compositeManager == this.activeCompositeManager) { + // Focus all + compositeManager.mouseIn(childKey); + } + }, + mouseOut: function(key, childKey) { + var compositeManager = this.getCompositeManager(key); + + // Unfocus if only it is a valid manager + if (compositeManager == this.activeCompositeManager) { + // Unfocus all + compositeManager.mouseOut(childKey); + } + }, + removeManager: function(key, childKey) { + var compositeManager = this.getCompositeManager(key); + + // Remove manager + if (compositeManager == this.activeCompositeManager) { + this.activeCompositeManager.removeManager(childKey); + this.activeCompositeManager.registry.unregister(childKey); + } + }, + show: function(key) { + var compositeManager = this.getCompositeManager(key); + if (compositeManager) { + this._switchActiveCompositeManager(compositeManager); + } + }, + hide: function(key) { + var compositeManager = this.getCompositeManager(key); + if (this.activeCompositeManager == compositeManager) { + this._cleanupMarkers(); + } + }, + _switchActiveCompositeManager: function(compositeManager) { + if (this.activeCompositeManager != compositeManager) { + this._cleanUpManagers(); + compositeManager.addManagersToMap(); + this.activeCompositeManager = compositeManager; + this.updateMap(); + } + }, + _cleanUpManagers: function() { + if (this.activeCompositeManager) { + this.activeCompositeManager.removeManagersFromMap(); + INFO_WINDOW.close(); + } + }, + updateDisplayedMarkers: function() { + this.activeCompositeManager.display(this.sliderControl.getValue()); + }, + updateMap: function() { + var compositeManager = this.activeCompositeManager; + if (compositeManager) { + var length = compositeManager.length(); + var slider = this.sliderControl; + slider.setMin(Math.min(1, length)); + slider.setMax(length); + slider.setValue(length); + } + }, + changeFilter: function(filterType) { + this.show(filterType); + }, + getColor: function(key, childKey) { + return this.getCompositeManager(key).registry.register(childKey).color; + } +}); diff --git a/productMods/js/visualization/mapofscience/CustomMarker.js b/productMods/js/visualization/mapofscience/CustomMarker.js index 29b74dfc..c2f6a675 100644 --- a/productMods/js/visualization/mapofscience/CustomMarker.js +++ b/productMods/js/visualization/mapofscience/CustomMarker.js @@ -26,19 +26,20 @@ var ScinodePolygon = CirclePolygon.extend({ registerEvents : function() { var me = this; var polygon = me.polygon; - this._super(); - this.registerEvent(addClickListener(polygon, function() { + me._super(); + + me.registerEvent(addClickListener(polygon, function() { INFO_WINDOW.setPosition(this.center); var content = this.content; INFO_WINDOW.setContent(content); INFO_WINDOW.open(this.map); })); - this.registerEvent(addMouseOverListener(polygon, function() { + me.registerEvent(addMouseOverListener(polygon, function() { me.focus(); })); - this.registerEvent(addMouseOutListener(polygon, function() { + me.registerEvent(addMouseOutListener(polygon, function() { me.unfocus(); })); } diff --git a/productMods/js/visualization/mapofscience/DataTableWidget.js b/productMods/js/visualization/mapofscience/DataTableWidget.js index 4471eecb..58b8d57c 100644 --- a/productMods/js/visualization/mapofscience/DataTableWidget.js +++ b/productMods/js/visualization/mapofscience/DataTableWidget.js @@ -2,30 +2,27 @@ var DataTableWidget = Class.extend({ - widgetType: "MAIN_SCIENCE_AREAS", - - currentSelectedFilter: SCIMAP_TYPE.DISCIPLINE, - dom: { searchBarParentContainerClass : "searchbar", paginationContainerClass : "paginatedtabs", containerID: "main-science-areas-table-container", footerID: "main-science-areas-table-footer", - disciplineFilterID: "discipline-filter", - subdisciplinesFilterID: "subdisciplines-filter", + firstFilterID: "first-filter", + secondFilterID: "second-filter", filterOptionClass: "filter-option", - activeFilterClass: "active-filter" + activeFilterClass: "active-filter", + filterInfoIconClass: "filterInfoIcon" }, - - widget: '', - init: function(sciMapWidget) { - this.sciMapWidget = sciMapWidget; - - this.subdisciplineInfo = {}; - this.disciplineInfo = {}; - var me = this; + me.sciMapWidget = sciMapWidget; + me.widgetType = "MAIN_SCIENCE_AREAS"; + me.currentSelectedFilter = SCIMAP_TYPE.SUBDISCIPLINE; + me.subdisciplineInfo = {}; + me.disciplineInfo = {}; + me.widget = ''; + me.tableDiv = $('
'); + $("#" + me.dom.containerID).append(this.tableDiv); $.each(DISCIPLINES, function(index, item) { var emptyScienceAreaElement = { @@ -42,7 +39,6 @@ var DataTableWidget = Class.extend({ }; me.subdisciplineInfo[index] = emptyScienceAreaElement; }); - }, loadJsonData: function(data) { @@ -74,12 +70,17 @@ var DataTableWidget = Class.extend({ return (this.keyToMarkerManagers.hasOwnProperty(key)); }, show: function(key) { + this.tableDiv.show(); }, hide: function(key) { + this.tableDiv.hide(); }, - cleanUp: function() { + cleanView: function() { + this.hide(); }, initView: function() { + this.show(); + this.changeFilter(me.currentSelectedFilter); }, parseIDIntoScienceTypeAreaID: function(rawID) { @@ -92,6 +93,15 @@ var DataTableWidget = Class.extend({ var me = this; + var dom = me.dom; + var filter = $('
' + + 'Sub-Disciplines | ' + + 'Disciplines' + + 'information icon
'); + me.tableDiv.append(filter); + createToolTip($("#imageIconTwo"), $('#toolTipTwo').html(), "topLeft"); + initFilter(dom); + var table = $('
'); + levelOfScienceAreaTH.html('Entity Type'); + + var checkBoxTH = $(''); + checkBoxTH.html(''); + + var scienceAreasTH = $(''); + scienceAreasTH.attr("id", "comparison-science-areas-th"); + if (this.currentSelectedFilter === COMPARISON_TYPE.ORGANIZATION ) { + scienceAreasTH.html('Organization'); + } else { + scienceAreasTH.html('Person'); + } + + var activityCountTH = $(''); + activityCountTH.html('# of pubs.'); + activityCountTH.attr("id", "activity-count-column"); + + tr.append(levelOfScienceAreaTH); + tr.append(checkBoxTH); + tr.append(scienceAreasTH); + tr.append(activityCountTH); + + thead.append(tr); + + table.append(thead); + + var tbody = $('
' + item.type + '' + item.label + '' + item.pubs.toFixed(2) + '
'); table.attr('id', 'datatable'); table.addClass('datatable-table'); @@ -150,7 +160,7 @@ var DataTableWidget = Class.extend({ tbody.append(rowsToInsert.join('')); table.append(tbody); - $("#" + me.dom.containerID).append(table); + me.tableDiv.append(table); table.children("tbody").children("tr").mouseenter(function() { @@ -208,16 +218,18 @@ var DataTableWidget = Class.extend({ var searchInputBox = $("." + me.dom.searchBarParentContainerClass).find("input[type=text]"); - searchInputBox.css("width", "140px"); - searchInputBox.after("X" - + "information icon"); - + + "information icon"); $("#reset-search").live('click', function() { me.widget.fnFilter(""); }); + createToolTip($("#searchInfoIcon"), $('#searchInfoTooltipText').html(), "topLeft"); + var csvButton = '
'; + this.tableDiv.append(csvButton); var totalPublications = me.pubsWithNoJournals + me.pubsWithInvalidJournals + me.pubsMapped; $("#mapped-publications").text(addCommasToNumber(me.pubsMapped)); @@ -228,7 +240,6 @@ var DataTableWidget = Class.extend({ }, changeFilter: function(filterType) { var me = this; - if (filterType === SCIMAP_TYPE.SUBDISCIPLINE) { $("#science-areas-th").html("Sub-Disciplines"); @@ -250,6 +261,7 @@ var DataTableWidget = Class.extend({ } ACTIVE_DISCIPLINE_SUBDISCIPLINE_FILTER = me.currentSelectedFilter; + if (me.widget) { me.widget.fnDraw(); } diff --git a/productMods/js/visualization/mapofscience/InitializeMap.js b/productMods/js/visualization/mapofscience/InitializeMap.js index 96a421ac..30f57ae7 100644 --- a/productMods/js/visualization/mapofscience/InitializeMap.js +++ b/productMods/js/visualization/mapofscience/InitializeMap.js @@ -68,9 +68,10 @@ function initMap() { } function initVisModeController() { - var controller = new EntityVisModeController(map); - visModeControllers[controller.visMode] = controller; + var controller = getVisModeController(ENTITY_VIS_MODE); switchVisMode(controller.visMode); + initVisModeTypeButton(); + initGlobalToolTips(); currentController.loadData(scienceMapDataURL, false); } diff --git a/productMods/js/visualization/mapofscience/Marker.js b/productMods/js/visualization/mapofscience/Marker.js index e66b0729..d40e0acf 100644 --- a/productMods/js/visualization/mapofscience/Marker.js +++ b/productMods/js/visualization/mapofscience/Marker.js @@ -50,7 +50,11 @@ var Marker = Class.extend({ this.handlers = handlers; }, unregisterEvents : function() { - removeListeners(this.handlers); - this.handlers = null; + if (this.handlers) { + $.each(this.handlers, function(i, handler) { + removeListener(handler); + }); + this.handlers = null; + } } }); diff --git a/productMods/js/visualization/mapofscience/MarkerManager.js b/productMods/js/visualization/mapofscience/MarkerManager.js index 5f6ceff3..34d983f0 100644 --- a/productMods/js/visualization/mapofscience/MarkerManager.js +++ b/productMods/js/visualization/mapofscience/MarkerManager.js @@ -47,6 +47,10 @@ var MarkerManager = Class.extend({ $.each(this.keyToMarker, function(i, marker) { marker.removeFromMap(); }); + }, + removeAll: function() { + this.removeMarkersFromMap(); + this.keyToMarker = {}; } }); @@ -204,3 +208,95 @@ var SubdisciplineMarkerManager = ScimapMarkerManager.extend({ return marker; } }); + +var CompositeMarkerManager = Class.extend({ + init: function() { + this.keyToManager = {}; + }, + addManager: function(key, manager) { + this.keyToManager[key] = manager; + }, + length: function() { + var size = 0; + + $.each(this.keyToManager, function(i, manager) { + msize = manager.length(); + if (size < msize) { + size = msize; + } + }); + return size; + }, + getManager: function(key) { + return this.keyToManager[key]; + }, + getManagerArray: function() { + var array = []; + $.each(this.keyToManager, function(i, e){ + array.push(e); + }); + return array; + }, + hasKey: function(key) { + return (this.keyToManager.hasOwnProperty(key)); + }, + showManager: function() { + $.each(this.keyToManager, function(i, manager) { + manager.showMarkers(); + }); + }, + hideManager: function() { + $.each(this.keyToManager, function(i, manager) { + manager.hideMarkers(); + }); + }, + addManagersToMap: function() { + $.each(this.keyToManager, function(i, manager) { + manager.addMarkersToMap(); + }); + }, + removeManagersFromMap: function() { + $.each(this.keyToManager, function(i, manager) { + manager.removeMarkersFromMap(); + }); + }, + removeManager: function(key) { + if (this.hasKey(key)) { + this.getManager(key).removeAll(); + delete this.keyToManager[key]; + } + }, + removeAll: function() { + $.each(this.keyToManager, function(i, manager) { + manager.removeAll(); + }); + this.keyToManager = {}; + }, + mouseIn: function(key) { + var manager = this.getManager(key); + if (manager) { + manager.mouseInAll(); + } + }, + mouseInAll: function() { + $.each(this.keyToManager, function(i, manager) { + manager.mouseInAll(); + }); + }, + mouseOut: function(key) { + var manager = this.getManager(key); + if (manager) { + manager.mouseOutAll(); + } + }, + mouseOutAll: function() { + $.each(this.keyToManager, function(i, manager) { + manager.mouseOutAll(); + }); + }, + display: function(numberOfMarkers) { + $.each(this.keyToManager, function(i, manager) { + manager.display(numberOfMarkers); + }); + } +}); diff --git a/productMods/js/visualization/mapofscience/Polygon.js b/productMods/js/visualization/mapofscience/Polygon.js index c49ea2f0..cc1c5e8c 100644 --- a/productMods/js/visualization/mapofscience/Polygon.js +++ b/productMods/js/visualization/mapofscience/Polygon.js @@ -58,10 +58,12 @@ var Polygon = Class.extend({ registerEvents : function() { }, unregisterEvents : function() { - $.each(this.handlers, function(){ - removeListener(this); - }); - this.handlers = null; + if (this.handlers) { + $.each(this.handlers, function(i, handler) { + removeListener(handler); + }); + this.handlers = null; + } } }); @@ -92,7 +94,6 @@ var CirclePolygon = Polygon.extend({ if (!this.isPointsCreated()) { this.initCirclePoints(); } - this._super(); }, isPointsCreated: function() { diff --git a/productMods/js/visualization/mapofscience/ScimapWidget.js b/productMods/js/visualization/mapofscience/ScimapWidget.js index 85611105..f0fd524f 100644 --- a/productMods/js/visualization/mapofscience/ScimapWidget.js +++ b/productMods/js/visualization/mapofscience/ScimapWidget.js @@ -13,7 +13,15 @@ var ScimapWidget = Class.extend({ var me = this; me.initControlPanels(); me.initMarkerManagers(); - me.show(SCIMAP_TYPE.SUBDISCIPLINE); + me.activeManager.addMarkersToMap(); + me.updateDisplayedMarkers(); + }, + cleanView: function() { + var me = this; + me._cleanUpMarkers(); + me.sliderControl.removeFromMap(); + me.disciplineLabelsControl.removeFromMap(); + me.labelsMarkerManager.removeMarkersFromMap(); }, initControlPanels: function() { var me = this; @@ -30,7 +38,7 @@ var ScimapWidget = Class.extend({ me.sliderControl.addToMap(); me.sliderControl.setChangeEventHandler(function(event, ui) { if (me.keyToMarkerManagers) { - me.updateDisplayedMarkers(ui.value); + me.updateDisplayedMarkers(); } }); @@ -53,6 +61,7 @@ var ScimapWidget = Class.extend({ /* Display labels if checked */ me.disciplineLabelsControl.addToMap(); + me.labelsMarkerManager.addMarkersToMap(); if (me.disciplineLabelsControl.isChecked()) { me.labelsMarkerManager.showMarkers(); } @@ -75,6 +84,7 @@ var ScimapWidget = Class.extend({ null ); this.keyToMarkerManagers = managers; + this.show(SCIMAP_TYPE.SUBDISCIPLINE); } }, needLoaded: function(){ @@ -185,14 +195,8 @@ var ScimapWidget = Class.extend({ INFO_WINDOW.close(); } }, - cleanup: function() { - var me = this; - me._cleanUpMarkers(); - me.sliderControl.RemoveFromMap(); - me.disciplineLabelsControl.RemoveFromMap(); - }, - updateDisplayedMarkers: function(numberOfMarkers) { - this.activeManager.display(numberOfMarkers); + updateDisplayedMarkers: function() { + this.activeManager.display(this.sliderControl.getValue()); }, updateMap: function() { var manager = this.activeManager; diff --git a/productMods/js/visualization/mapofscience/VisCommonControl.js b/productMods/js/visualization/mapofscience/VisCommonControl.js index 648ecad0..6cef9a81 100644 --- a/productMods/js/visualization/mapofscience/VisCommonControl.js +++ b/productMods/js/visualization/mapofscience/VisCommonControl.js @@ -14,22 +14,110 @@ function switchMarkerManager(id) { } } +function createVisModeController(visMode) { + if (visMode === ENTITY_VIS_MODE) { + var controller = new EntityVisModeController(map); + visModeControllers[controller.visMode] = controller; + } + + if (visMode === COMPARISON_VIS_MODE) { + var controller = new ComparisonVisModeController(map); + visModeControllers[controller.visMode] = controller; + controller.loadData(scienceMapDataURL, false); + } +} + function isActiveVisMode(visMode) { - return (currentVisMode == visMode); + return (currentVisMode === visMode); } function getVisModeController(visMode){ + if (visModeControllers[visMode] == null) { + createVisModeController(visMode); + } return visModeControllers[visMode]; } function switchVisMode(visMode) { - if (currentVisMode != visMode) { - currentVisMode = visMode; + if (!isActiveVisMode(visMode)) { if (currentController) { currentController.cleanView(); } currentController = getVisModeController(visMode); + currentVisMode = visMode; currentController.initView(); } - return } + +function initFilter(dom) { + + // Switch filter handling + $("." + dom.filterOptionClass).live('click', function() { + var obj = $(this); + if (!obj.hasClass(dom.activeFilterClass)) { + var checked = obj.attr('id'); + if (checked === dom.secondFilterID) { + $("#" + dom.firstFilterID).removeClass(dom.activeFilterClass); + currentController.changeFilter(2); + + } else if (checked === dom.firstFilterID) { + $("#" + dom.secondFilterID).removeClass(dom.activeFilterClass); + currentController.changeFilter(1); + } + + obj.addClass(dom.activeFilterClass); + } + }); + + $("#" + dom.firstFilterID).trigger('click'); +} + +function initVisModeTypeButton() { + // Switch vis mode handling + var viewTypeRadio = "input[name='view-type']"; + $(viewTypeRadio).change( function() { + var visMode = $(viewTypeRadio+ ":checked").val(); + switchVisMode(visMode); + }); + + /* Init default filter */ + $(viewTypeRadio+ ":eq(0)").click(); +} + +function initGlobalToolTips() { + + createToolTip($("#imageIconOne"), $('#toolTipOne').html(), "topLeft"); + createToolTip($("#imageIconThree"), $('#toolTipThree').html(), "topRight"); +} + +function createToolTip(target, tipText, tipLocation) { + target.qtip({ + content: { + text: tipText + }, + position: { + corner: { + target: 'center', + tooltip: tipLocation + } + }, + show: { + when: { + event: 'mouseover' + } + }, + hide: { + fixed: true // Make it fixed so it can be hovered over + }, + style: { + padding: '6px 6px', + // Give it some extra padding + width: 500, + textAlign: 'left', + backgroundColor: '#ffffc0', + fontSize: '.7em', + padding: '6px 10px 6px 10px', + lineHeight: '14px' + } + }); +} \ No newline at end of file diff --git a/productMods/js/visualization/mapofscience/VisModeControllers.js b/productMods/js/visualization/mapofscience/VisModeControllers.js index e6d8d059..4da364f9 100644 --- a/productMods/js/visualization/mapofscience/VisModeControllers.js +++ b/productMods/js/visualization/mapofscience/VisModeControllers.js @@ -2,6 +2,8 @@ var ENTITY_VIS_MODE = "ENTITY"; var COMPARISON_VIS_MODE = "COMPARISON"; +var dataMarket = {}; + var VisModeController = Class.extend({ init: function(map) { this.visMode = ENTITY_VIS_MODE; @@ -14,6 +16,47 @@ var VisModeController = Class.extend({ needLoaded: function() { return this.isUnloaded; }, + loadData: function(url, sync) { + + // Download data from server and add to markerManager if not gotten already + var me = this; + if (me.isUnloaded) { + // Lazy loading + if (!dataMarket[url]) { + if (sync) { + downloader.downloadAndWait(url, function(data) { + dataMarket[url] = data; + me.loadJsonData(me, data); + }); + } else { + downloader.download(url, function(data) { + dataMarket[url] = data; + me.loadJsonData(me, data); + }); + } + } else { + me.loadJsonData(me, dataMarket[url]); + } + } // end if + }, + loadJsonData: function(me, data) { + + $("#" + responseContainerID).unblock(); + + if (ERROR_DISPLAY_WIDGET.isErrorConditionTriggered(data)) { + $("#map-of-science-response").hide(); + ERROR_DISPLAY_WIDGET.show(ENTITY_TYPE, data); + return; + } + + data = data[0]; + + $.each(me.widgets, function(i, widget) { + widget.loadJsonData(data); + }); + //me.initToolTipInfo(); + me.isUnloaded = false; + }, initView: function() { $.each(this.widgets, function(i, widget) { widget.initView(); @@ -30,49 +73,32 @@ var VisModeController = Class.extend({ widget.hide(key); }); }, - cleanUp: function() { + cleanView: function() { $.each(this.widgets, function(i, widget) { - widget.cleanUp(key); + widget.cleanView(); }); - } + }, + changeFilter: function(value) { + var type = this.getFilterType(value); + + $.each(this.widgets, function(i, widget) { + widget.changeFilter(type); + }); + }, }); var EntityVisModeController = VisModeController.extend({ init: function(map) { this._super(map); this.visMode = ENTITY_VIS_MODE; - this.initFilter(); + this.firstFilterLabel = "554 Sub-Disciplines"; + this.secondFilterLabel = "13 Disciplines"; }, - initFilter: function() { - var widgets = this.widgets; - var dom = { - disciplineFilterID: "discipline-filter", - subdisciplinesFilterID: "subdisciplines-filter", - filterOptionClass: "filter-option", - activeFilterClass: "active-filter" - }; - - $("." + dom.filterOptionClass).live('click', function() { - if (!$(this).hasClass(dom.activeFilterClass)) { - if ($(this).attr('id') === dom.subdisciplinesFilterID) { - $("#" + dom.disciplineFilterID).removeClass(dom.activeFilterClass); - $.each(widgets, function(i, widget) { - widget.changeFilter(SCIMAP_TYPE.SUBDISCIPLINE); - }); - - } else if ($(this).attr('id') === dom.disciplineFilterID) { - $("#" + dom.subdisciplinesFilterID).removeClass(dom.activeFilterClass); - $.each(widgets, function(i, widget) { - widget.changeFilter(SCIMAP_TYPE.DISCIPLINE); - }); - } - - $(this).addClass('active-filter'); - } - }); - - /* Init default filter */ - $("#" + dom.subdisciplinesFilterID).trigger('click'); + getFilterType: function(value) { + if (value === 1) { + return SCIMAP_TYPE.SUBDISCIPLINE; + } + return SCIMAP_TYPE.DISCIPLINE; }, initWidgets: function(map) { var widgets = {}; @@ -80,223 +106,27 @@ var EntityVisModeController = VisModeController.extend({ widgets['sci_area_table'] = new DataTableWidget(widgets['scimap']); this.widgets = widgets; - }, - loadData: function(url, sync) { - - // Download data from server and add to markerManager if not gotten already - var me = this; - if (me.isUnloaded) { - if (sync) { - downloader.downloadAndWait(url, function(data) { - me.loadJsonData(me, data); - }); - } else { - downloader.download(url, function(data) { - me.loadJsonData(me, data); - }); - } - } // end if - }, - loadJsonData: function(me, data) { - - $("#" + responseContainerID).unblock(); - - if (ERROR_DISPLAY_WIDGET.isErrorConditionTriggered(data)) { - $("#map-of-science-response").hide(); - ERROR_DISPLAY_WIDGET.show(ENTITY_TYPE, data); - return; - } - - data = data[0]; - - $.each(me.widgets, function(i, widget) { - widget.loadJsonData(data); - }); - me.isUnloaded = false; - me.initToolTipInfo(); - - }, - initToolTipInfo: function() { - - $('.filterInfoIcon').each(function () { - - var me = $(this); - - var tipText; - var tipLocation = "topLeft"; - - if (me.attr('id') == 'imageIconOne') { - tipText = $('#toolTipOne').html(); - } else if (me.attr('id') == 'imageIconTwo') { - tipText = $('#toolTipTwo').html(); - } else if (me.attr('id') == 'searchInfoIcon') { - tipText = $('#searchInfoTooltipText').html(); - } else { - tipText = $('#toolTipThree').html(); - tipLocation = "topRight"; - } - - me.qtip({ - content: { - text: tipText - }, - position: { - corner: { - target: 'center', - tooltip: tipLocation - } - }, - show: { - when: { - event: 'mouseover' - } - }, - hide: { - fixed: true // Make it fixed so it can be hovered over - }, - style: { - padding: '6px 6px', - // Give it some extra padding - width: 500, - textAlign: 'left', - backgroundColor: '#ffffc0', - fontSize: '.7em', - padding: '6px 10px 6px 10px', - lineHeight: '14px' - } - }); - }); } }); -var ComparisonVisModeController = Class.extend({ +var ComparisonVisModeController = VisModeController.extend({ init: function(map) { this._super(map); this.visMode = COMPARISON_VIS_MODE; - this.initFilter(); + this.firstFilterLabel = "Organizations"; + this.secondFilterLabel = "People"; }, - initFilter: function() { - var widgets = this.widgets; - var dom = { - disciplineFilterID: "discipline-filter", - subdisciplinesFilterID: "subdisciplines-filter", - filterOptionClass: "filter-option", - activeFilterClass: "active-filter" - }; - - $("." + dom.filterOptionClass).live('click', function() { - if (!$(this).hasClass(dom.activeFilterClass)) { - if ($(this).attr('id') === dom.subdisciplinesFilterID) { - $("#" + dom.disciplineFilterID).removeClass(dom.activeFilterClass); - $.each(widgets, function(i, widget) { - widget.changeFilter(SCIMAP_TYPE.SUBDISCIPLINE); - }); - - } else if ($(this).attr('id') === dom.disciplineFilterID) { - $("#" + dom.subdisciplinesFilterID).removeClass(dom.activeFilterClass); - $.each(widgets, function(i, widget) { - widget.changeFilter(SCIMAP_TYPE.DISCIPLINE); - }); - } - - $(this).addClass('active-filter'); - } - }); - - /* Init default filter */ - $("#" + dom.subdisciplinesFilterID).trigger('click'); + getFilterType: function(value) { + if (value === 1) { + return COMPARISON_TYPE.ORGANIZATION; + } + return COMPARISON_TYPE.PERSON; }, initWidgets: function(map) { var widgets = {}; - widgets['scimap'] = new ScimapWidget(map); - widgets['sci_area_table'] = new DataTableWidget(widgets['scimap']); + widgets['scimap'] = new ComparisonScimapWidget(map); + widgets['sci_area_table'] = new ComparisonDataTableWidget(widgets['scimap']); this.widgets = widgets; - }, - loadData: function(url, sync) { - - // Download data from server and add to markerManager if not gotten already - var me = this; - if (me.isUnloaded) { - if (sync) { - downloader.downloadAndWait(url, function(data) { - me.loadJsonData(me, data); - }); - } else { - downloader.download(url, function(data) { - me.loadJsonData(me, data); - }); - } - } // end if - }, - loadJsonData: function(me, data) { - - $("#" + responseContainerID).unblock(); - - if (ERROR_DISPLAY_WIDGET.isErrorConditionTriggered(data)) { - $("#map-of-science-response").hide(); - ERROR_DISPLAY_WIDGET.show(ENTITY_TYPE, data); - return; - } - - data = data[0]; - - $.each(me.widgets, function(i, widget) { - widget.loadJsonData(data); - }); - me.isUnloaded = false; - me.initToolTipInfo(); - - }, - initToolTipInfo: function() { - - $('.filterInfoIcon').each(function () { - - var me = $(this); - - var tipText; - var tipLocation = "topLeft"; - - if (me.attr('id') == 'imageIconOne') { - tipText = $('#toolTipOne').html(); - } else if (me.attr('id') == 'imageIconTwo') { - tipText = $('#toolTipTwo').html(); - } else if (me.attr('id') == 'searchInfoIcon') { - tipText = $('#searchInfoTooltipText').html(); - } else { - tipText = $('#toolTipThree').html(); - tipLocation = "topRight"; - } - - me.qtip({ - content: { - text: tipText - }, - position: { - corner: { - target: 'center', - tooltip: tipLocation - } - }, - show: { - when: { - event: 'mouseover' - } - }, - hide: { - fixed: true // Make it fixed so it can be hovered over - }, - style: { - padding: '6px 6px', - // Give it some extra padding - width: 500, - textAlign: 'left', - backgroundColor: '#ffffc0', - fontSize: '.7em', - padding: '6px 10px 6px 10px', - lineHeight: '14px' - } - }); - }); } }); \ No newline at end of file diff --git a/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceSetup.ftl b/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceSetup.ftl index 5dd0c164..15e8ac99 100644 --- a/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceSetup.ftl +++ b/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceSetup.ftl @@ -36,18 +36,23 @@ ', '', '', + '', + '', '', '', '')} diff --git a/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceStandalone.ftl b/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceStandalone.ftl index be19c58b..22fc7c3b 100644 --- a/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceStandalone.ftl +++ b/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceStandalone.ftl @@ -39,26 +39,18 @@ corresponding changes in the included Templates. -->

#{title}

#{text}

+ + <#-- VIEW TYPE FILTER --> +
+ Explore ${entityLabel}
+ Compare organizations (or people)

-
- 13 Disciplines | - 554 Sub-Disciplines - information icon -
- -
- - +
@@ -78,6 +70,9 @@ mapped % of
+ +<#-- START TOOLTIP TEXT --> + + +<#-- COMPARISON TOOLTIP TEXT --> + + + + +<#-- END TOOLTIP TEXT --> +

${entityLabel}