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