From dd9b880a1a242800ad4fe151c4c1e9cd88545a7b Mon Sep 17 00:00:00 2001 From: felmer <felmer> Date: Thu, 2 Apr 2015 05:49:30 +0000 Subject: [PATCH] SSDM-1683: hierarchy and type filter added SVN: 33773 --- .../1/as/webapps/newbrowser/html/index.html | 1 + .../newbrowser/html/js/util/HierarchyUtil.js | 168 ++++++++++++++++++ .../SampleHierarchyTableModel.js | 1 + .../SampleHierarchyTableView.js | 27 ++- .../html/js/views/legacy/SampleHierarchy.js | 147 +-------------- 5 files changed, 202 insertions(+), 142 deletions(-) create mode 100644 plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/util/HierarchyUtil.js diff --git a/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/index.html b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/index.html index b9a631f01ab..5ea79bf4a76 100644 --- a/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/index.html +++ b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/index.html @@ -96,6 +96,7 @@ <script type="text/javascript" src="./js/util/BlockScrollUtil.js"></script> <script type="text/javascript" src="./js/util/PrintUtil.js"></script> <script type="text/javascript" src="./js/util/AnnotationUtil.js"></script> + <script type="text/javascript" src="./js/util/HierarchyUtil.js"></script> <script type="text/javascript" src="./js/views/TrashManager/TrashManagerController.js"></script> <script type="text/javascript" src="./js/views/TrashManager/TrashManagerModel.js"></script> diff --git a/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/util/HierarchyUtil.js b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/util/HierarchyUtil.js new file mode 100644 index 00000000000..870cf7a7070 --- /dev/null +++ b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/util/HierarchyUtil.js @@ -0,0 +1,168 @@ +/* + * Copyright 2015 ETH Zuerich, Scientific IT Services + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var HierarchyUtil = new function() { + var getSampleTypes = function(sample) { + var sampleTypes = {}; + + var getSampleTypesWithQueueRecursion = function(sample, sampleTypes) { + if(!sampleTypes[sample.sampleTypeCode]) { + sampleTypes[sample.sampleTypeCode] = true; + } + + if(sample.parents) { + for(var i = 0; i < sample.parents.length; i++) { + getSampleTypesWithQueueRecursion(sample.parents[i], sampleTypes); + } + } + + if(sample.children) { + for(var i = 0; i < sample.children.length; i++) { + getSampleTypesWithQueueRecursion(sample.children[i], sampleTypes); + } + } + } + + getSampleTypesWithQueueRecursion(sample, sampleTypes); + return sampleTypes; + } + + var getMaxChildrenDepth = function(sample) { + var getMaxChildrenDepthWithQueueRecurion = function(sample, max) { + if(sample.children) { + var posibleNextMax = []; + + for(var i = 0; i < sample.children.length; i++) { + var nextMax = getMaxChildrenDepthWithQueueRecurion(sample.children[i], (max + 1)); + posibleNextMax.push(nextMax); + } + + for(var i = 0; i < posibleNextMax.length; i++) { + if(posibleNextMax[i] > max) { + max = posibleNextMax[i]; + } + } + } + + return max; + } + + var result = getMaxChildrenDepthWithQueueRecurion(sample, 0); + return result; + } + + var getMaxParentsDepth = function(sample) { + var getMaxParentsDepthWithQueueRecurion = function(sample, max) { + if(sample.parents) { + var posibleNextMax = []; + + for(var i = 0; i < sample.parents.length; i++) { + var nextMax = getMaxParentsDepthWithQueueRecurion(sample.parents[i], (max + 1)); + posibleNextMax.push(nextMax); + } + + for(var i = 0; i < posibleNextMax.length; i++) { + if(posibleNextMax[i] > max) { + max = posibleNextMax[i]; + } + } + } + + return max; + } + + var result = getMaxParentsDepthWithQueueRecurion(sample, 0); + return result; + } + + var getSliderValue = function(id) { + var element = $('#' + id) + return element.length > 0 ? element.data('slider').getValue() : 0; + } + + this.getParentsLimit = function() { + return getSliderValue("parentsLimit"); + } + + this.getChildrenLimit = function() { + return getSliderValue("childrenLimit"); + } + + this.getSelectedSampleTypes = function() { + var selectedSampleTypes = $('#sampleTypesSelector').val(); + if(selectedSampleTypes === null) { + selectedSampleTypes = []; + } + return selectedSampleTypes; + } + + /* + * Creates a hierarchy filter widget for the specified sample and adds it to the specified container. + * The specified updater object should have a function filterSampleAndUpdate(). + */ + this.addHierarchyFilterWidget = function(container, sample, updater) { + var $filtersForm = $('<form>' , { class : 'form-inline'}); + container.append($filtersForm); + $filtersForm.submit(function(event) {updater.filterSampleAndUpdate(); event.preventDefault();}); + + var maxChildren = getMaxChildrenDepth(sample); + var $filtersFormSliderChildren = null; + if(maxChildren > 0) { + $filtersFormSliderChildren = $('<input>' , { 'id' : 'childrenLimit' , 'type' : 'text' , 'class' : 'span2', 'value' : '' , 'data-slider-max' : maxChildren , 'data-slider-value' : maxChildren}); + } else { + $filtersFormSliderChildren = 'No Children'; + } + + var maxParents = getMaxParentsDepth(sample); + var $filtersFormSliderParents = null; + if(maxParents > 0) { + $filtersFormSliderParents = $('<input>' , { 'id' : 'parentsLimit' , 'type' : 'text' , 'class' : 'span2', 'value' : '' , 'data-slider-max' : maxParents , 'data-slider-value' : maxParents}); + } else { + $filtersFormSliderParents = 'No Parents'; + } + + var sampleTypes = getSampleTypes(sample); + var $filtersFormSampleTypes = $('<select>', { 'id' : 'sampleTypesSelector' , class : 'multiselect' , 'multiple' : 'multiple'}); + for (var sampleType in sampleTypes) { + $filtersFormSampleTypes.append($('<option>', { 'value' : sampleType , 'selected' : ''}).html(sampleType)); + } + + $filtersForm + .append('<b>Filters</b>') + .append("<span style='padding-right:15px;'></span>") + .append('Children: ') + .append($filtersFormSliderChildren) + .append("<span style='padding-right:15px;'></span>") + .append(' Parents: ') + .append($filtersFormSliderParents) + .append("<span style='padding-right:15px;'></span>") + .append(' Show Types: ') + .append($filtersFormSampleTypes) + .append("<span style='position:absolute; left:30px; top:80px;'><svg height='100' width='100'><g id='svgControls'/></svg></span>"); + + $('#childrenLimit').slider().on('slideStop', function(event){ + updater.filterSampleAndUpdate(); + }); + + $('#parentsLimit').slider().on('slideStop', function(event){ + updater.filterSampleAndUpdate(); + }); + + $('#sampleTypesSelector').multiselect(); + $('#sampleTypesSelector').change(function(event){ + updater.filterSampleAndUpdate(); + }); + } +} diff --git a/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/SampleHierarchyTable/SampleHierarchyTableModel.js b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/SampleHierarchyTable/SampleHierarchyTableModel.js index 578034f3b04..20411e8ec4b 100644 --- a/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/SampleHierarchyTable/SampleHierarchyTableModel.js +++ b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/SampleHierarchyTable/SampleHierarchyTableModel.js @@ -64,6 +64,7 @@ function SampleHierarchyTableModel(sample) { var annotations = FormUtil.getAnnotationsFromSample(sample); dataList.push({ level : level, + sampleType : sample.sampleTypeCode, identifier : sample.identifier, permId : sample.permId, path: path, diff --git a/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/SampleHierarchyTable/SampleHierarchyTableView.js b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/SampleHierarchyTable/SampleHierarchyTableView.js index ef8554efa44..3fb9933500c 100644 --- a/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/SampleHierarchyTable/SampleHierarchyTableView.js +++ b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/SampleHierarchyTable/SampleHierarchyTableView.js @@ -18,8 +18,10 @@ function SampleHierarchyTableView(controller, model) { this._model = model; this._controller = controller; this._container = $("<div>"); + this._dataGrid; this.repaint = function($container) { + var _this = this; $container.empty(); var $containerColumn = $("<form>", { "class" : FormUtil.formColumClass + " form-horizontal", @@ -27,11 +29,16 @@ function SampleHierarchyTableView(controller, model) { "action" : "javascript:void(0);", "onsubmit" : "" }); + $container.append($containerColumn); $containerColumn.append($("<h1>").append(this._model.title)); + HierarchyUtil.addHierarchyFilterWidget($containerColumn, this._model.sample, { + filterSampleAndUpdate : function() { + _this._dataGrid.refresh(); + } + }); this._showHierarchy(); $containerColumn.append(this._container); - $container.append($containerColumn); } this._showHierarchy = function() { @@ -70,15 +77,27 @@ function SampleHierarchyTableView(controller, model) { }]; var getDataList = function(callback) { - callback(_this._model.getData()); + var data = _this._model.getData(); + var parentsLimit = HierarchyUtil.getParentsLimit(); + var childrenLimit = HierarchyUtil.getChildrenLimit(); + var sampleTypes = HierarchyUtil.getSelectedSampleTypes(); + var filteredData = []; + for (var i = 0; i < data.length; i++) { + var row = data[i]; + if (row.level == 0 || ($.inArray(row.sampleType, sampleTypes) >= 0 + && row.level <= childrenLimit && row.level >= -parentsLimit)) { + filteredData.push(row); + } + } + callback(filteredData); } var rowClick = function(e) { mainController.changeView('showViewSamplePageFromPermId', e.data.permId); } - var dataGrid = new DataGridController(null, columns, getDataList, rowClick); - dataGrid.init(this._container); + this._dataGrid = new DataGridController(null, columns, getDataList, rowClick); + this._dataGrid.init(this._container); this._container.prepend($("<legend>").append(" Sample Hierarchy")); } diff --git a/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/legacy/SampleHierarchy.js b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/legacy/SampleHierarchy.js index 8c69262b200..3966955f63f 100644 --- a/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/legacy/SampleHierarchy.js +++ b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/legacy/SampleHierarchy.js @@ -25,146 +25,20 @@ function SampleHierarchy(serverFacade, containerId, profile, sample) { this.repaint(); } - this._getSampleTypes = function(sample) { - var sampleTypes = {}; - - var getSampleTypesWithQueueRecursion = function(sample, sampleTypes) { - if(!sampleTypes[sample.sampleTypeCode]) { - sampleTypes[sample.sampleTypeCode] = true; - } - - if(sample.parents) { - for(var i = 0; i < sample.parents.length; i++) { - getSampleTypesWithQueueRecursion(sample.parents[i], sampleTypes); - } - } - - if(sample.children) { - for(var i = 0; i < sample.children.length; i++) { - getSampleTypesWithQueueRecursion(sample.children[i], sampleTypes); - } - } - } - - getSampleTypesWithQueueRecursion(sample, sampleTypes); - return sampleTypes; - } - - this._getMaxChildrenDepth = function(sample) { - var getMaxChildrenDepthWithQueueRecurion = function(sample, max) { - if(sample.children) { - var posibleNextMax = []; - - for(var i = 0; i < sample.children.length; i++) { - var nextMax = getMaxChildrenDepthWithQueueRecurion(sample.children[i], (max + 1)); - posibleNextMax.push(nextMax); - } - - for(var i = 0; i < posibleNextMax.length; i++) { - if(posibleNextMax[i] > max) { - max = posibleNextMax[i]; - } - } - } - - return max; - } - - var result = getMaxChildrenDepthWithQueueRecurion(sample, 0); - return result; - } - - this._getMaxParentsDepth = function(sample) { - var getMaxParentsDepthWithQueueRecurion = function(sample, max) { - if(sample.parents) { - var posibleNextMax = []; - - for(var i = 0; i < sample.parents.length; i++) { - var nextMax = getMaxParentsDepthWithQueueRecurion(sample.parents[i], (max + 1)); - posibleNextMax.push(nextMax); - } - - for(var i = 0; i < posibleNextMax.length; i++) { - if(posibleNextMax[i] > max) { - max = posibleNextMax[i]; - } - } - } - - return max; - } - - var result = getMaxParentsDepthWithQueueRecurion(sample, 0); - return result; - } - this.repaint = function() { var localInstance = this; $('#'+this.containerId).empty(); - var $filtersForm = $('<form>' , { class : 'form-inline'}); - $filtersForm.submit(function(event) {localInstance._filterSampleAndUpdate(); event.preventDefault();}); - - var maxChildren = this._getMaxChildrenDepth(this.sample); - var $filtersFormSliderChildren = null; - if(maxChildren > 0) { - $filtersFormSliderChildren = $('<input>' , { 'id' : 'childrenLimit' , 'type' : 'text' , 'class' : 'span2', 'value' : '' , 'data-slider-max' : maxChildren , 'data-slider-value' : maxChildren}); - } else { - $filtersFormSliderChildren = 'No Children'; - } - - var maxParents = this._getMaxParentsDepth(this.sample); - var $filtersFormSliderParents = null; - if(maxParents > 0) { - $filtersFormSliderParents = $('<input>' , { 'id' : 'parentsLimit' , 'type' : 'text' , 'class' : 'span2', 'value' : '' , 'data-slider-max' : maxParents , 'data-slider-value' : maxParents}); - } else { - $filtersFormSliderParents = 'No Parents'; - } - - var sampleTypes = this._getSampleTypes(this.sample); - var $filtersFormSampleTypes = $('<select>', { 'id' : 'sampleTypesSelector' , class : 'multiselect' , 'multiple' : 'multiple'}); - for (var sampleType in sampleTypes) { - $filtersFormSampleTypes.append($('<option>', { 'value' : sampleType , 'selected' : ''}).html(sampleType)); - } - - $filtersForm - .append('<b>Filters</b>') - .append("<span style='padding-right:15px;'></span>") - .append('Children: ') - .append($filtersFormSliderChildren) - .append("<span style='padding-right:15px;'></span>") - .append(' Parents: ') - .append($filtersFormSliderParents) - .append("<span style='padding-right:15px;'></span>") - .append(' Show Types: ') - .append($filtersFormSampleTypes) - .append("<span style='position:absolute; left:30px; top:80px;'><svg height='100' width='100'><g id='svgControls'/></svg></span>"); - var $form = $("<div>", { "class" : "row", "style" : "margin-top: 20px;"}); + $('#'+this.containerId).append($form); var $formColumn = $("<div>", { "class" : "col-md-12"}); $form.append($formColumn); - $formColumn.append($filtersForm); + HierarchyUtil.addHierarchyFilterWidget($formColumn, this.sample, localInstance); $formColumn.append($('<div>', { 'id' : 'graphContainer' })); - $('#'+this.containerId).append($form); $('#graphContainer').append("<svg id='svgMapContainer'><g id='svgMap' transform='translate(20,20) scale(1)'/></svg>"); - $('#childrenLimit').slider(); - $('#childrenLimit').slider().on('slideStop', function(event){ - localInstance._filterSampleAndUpdate(); - }); - - $('#parentsLimit').slider(); - $('#parentsLimit').slider().on('slideStop', function(event){ - localInstance._filterSampleAndUpdate(); - }); - - $('#sampleTypesSelector').multiselect(); - $('#sampleTypesSelector').change(function(event){ - localInstance._filterSampleAndUpdate(); - }); - - this._filterSampleAndUpdate(); + this.filterSampleAndUpdate(); //Add SVG Map Controls var path1 = this._makeSVG('path', {'class' : 'svgButton', 'stroke-linecap':'round', 'stroke-miterlimit':'6', 'onclick':'javascript:mainController.currentView.pan( 0, 50);', 'd':'M50 10 l12 20 a40, 70 0 0,0 -24, 0z', 'stroke-width':'1.5', 'fill':'#0088CC', 'stroke': '#0088CC' }); @@ -201,16 +75,13 @@ function SampleHierarchy(serverFacade, containerId, profile, sample) { } } - this._filterSampleAndUpdate = function() { + this.filterSampleAndUpdate = function() { var newSample = jQuery.extend(true, {}, this.sample); // // Used to remove the type label when rendering // - var selectedSampleTypes = $('#sampleTypesSelector').val(); - if(selectedSampleTypes === null) { - selectedSampleTypes = []; - } + var selectedSampleTypes = HierarchyUtil.getSelectedSampleTypes(); var inArray = function(value, array) { for(var i = 0; i < array.length; i++) { if(array[i] === value) { @@ -240,7 +111,7 @@ function SampleHierarchy(serverFacade, containerId, profile, sample) { // // Used to cut the tree // - var parentsLimit = ($('#parentsLimit').length > 0)?$('#parentsLimit').data('slider').getValue():0; + var parentsLimit = HierarchyUtil.getParentsLimit(); var parentsLimitFilter = function(sample, depthLimit) { if(sample.parents) { if(depthLimit === 0) { @@ -257,7 +128,7 @@ function SampleHierarchy(serverFacade, containerId, profile, sample) { // // Used to cut the tree // - var childrenLimit = ($('#childrenLimit').length > 0)?$('#childrenLimit').data('slider').getValue():0; + var childrenLimit = HierarchyUtil.getChildrenLimit(); var childrenLimitFilter = function(sample, depthLimit) { if(sample.children) { if(depthLimit === 0) { @@ -340,7 +211,7 @@ function SampleHierarchy(serverFacade, containerId, profile, sample) { } searchAndUpdateData(show, permId, this.sample); - this._filterSampleAndUpdate(); + this.filterSampleAndUpdate(); this._glowNode(this.nodeIdPrefix + permId); } @@ -364,7 +235,7 @@ function SampleHierarchy(serverFacade, containerId, profile, sample) { } searchAndUpdateDisplayability(hide, permId, this.sample); - this._filterSampleAndUpdate(); + this.filterSampleAndUpdate(); this._glowNode(this.nodeIdPrefix + permId); } -- GitLab