1 define([ 2 'jquery', 3 'underscore', 4 'viewcontroller', 5 'shape-editor', 6 'shapes' 7 ], function($, _, ViewControllers, Shape, shapes) { 8 9 // we only use the base attribute class, no need to get the base class 10 var EmperorAttributeABC = ViewControllers.EmperorAttributeABC; 11 var ShapeEditor = Shape.ShapeEditor; 12 var ShapeFormatter = Shape.ShapeFormatter; 13 /** 14 * @class ShapeController 15 * 16 * Manipulates and displays the shape of objects on screen. 17 * 18 * @param {UIState} uiState The shared state 19 * @param {Node} container Container node to create the controller in. 20 * @param {Object} decompViewDict This is object is keyed by unique 21 * identifiers and the values are DecompositionView objects referring to a 22 * set of objects presented on screen. This dictionary will usually be shared 23 * by all the tabs in the application. This argument is passed by reference. 24 * Note that only the decompositions of type 'scatter' will be controlled, 25 * other types will be ignored. 26 * 27 * @return {ShapeController} An instance of ShapeController 28 * @constructs ShapeController 29 * @extends EmperorAttributeABC 30 */ 31 function ShapeController(uiState, container, decompViewDict) { 32 var helpmenu = 'Change the shapes representing groups of data on the plot'; 33 var title = 'Shape'; 34 35 // Constant for width in slick-grid 36 var SLICK_WIDTH = 100, scope = this; 37 var name, value, shapeItem; 38 39 // Build the options dictionary 40 var options = { 41 'valueUpdatedCallback': function(e, args) { 42 var val = args.item.category, shape = args.item.value; 43 var group = args.item.plottables; 44 var element = scope.getView(); 45 scope.setPlottableAttributes(element, shape, group); 46 }, 47 'categorySelectionCallback': function(evt, params) { 48 var category = scope.$select.val(); 49 50 var decompViewDict = scope.getView(); 51 52 // getting all unique values per categories 53 var uniqueVals = decompViewDict.decomp.getUniqueValuesByCategory( 54 category); 55 56 // Reset all to shapes to default 57 var attributes = {}; 58 for (var index in uniqueVals) { 59 attributes[uniqueVals[index]] = 'Sphere'; 60 } 61 // fetch the slickgrid-formatted data 62 var data = decompViewDict.setCategory( 63 attributes, scope.setPlottableAttributes, category); 64 65 scope.setSlickGridDataset(data); 66 }, 67 'slickGridColumn': { 68 id: 'title', name: '', field: 'value', 69 sortable: false, maxWidth: SLICK_WIDTH, minWidth: SLICK_WIDTH, 70 editor: ShapeEditor, 71 formatter: ShapeFormatter 72 } 73 }; 74 75 // shapes are only supported for scatter types 76 var reshapeable = {}; 77 for (var key in decompViewDict) { 78 if (decompViewDict[key].decomp.isScatterType()) { 79 reshapeable[key] = decompViewDict[key]; 80 } 81 } 82 83 EmperorAttributeABC.call(this, uiState, container, title, helpmenu, 84 reshapeable, options); 85 return this; 86 } 87 88 ShapeController.prototype = Object.create(EmperorAttributeABC.prototype); 89 ShapeController.prototype.constructor = EmperorAttributeABC; 90 91 /** 92 * 93 * Private method to reset the shape of all the objects to spheres. 94 * 95 * @extends EmperorAttributeABC 96 * @private 97 * 98 */ 99 ShapeController.prototype._resetAttribute = function() { 100 EmperorAttributeABC.prototype._resetAttribute.call(this); 101 var scope = this; 102 103 _.each(this.decompViewDict, function(view) { 104 scope.setPlottableAttributes(view, 'Sphere', view.decomp.plottable); 105 view.needsUpdate = true; 106 }); 107 }; 108 109 /** 110 * Helper function to set the shape of plottable 111 * 112 * @param {Object} scope The scope where the plottables exist 113 * @param {string} shape String representation of the shape to be applied 114 * to the plottables. 115 * @param {Object[]} group Array of objects that should be changed in scope 116 */ 117 ShapeController.prototype.setPlottableAttributes = 118 function(scope, shape, group) { 119 120 if (scope.UIState['view.viewType'] == 'parallel-plot') 121 return; 122 123 var idx, factor = scope.getGeometryFactor(); 124 125 // get the appropriately sized geometry 126 var geometry = shapes.getGeometry(shape, factor); 127 128 if (geometry === undefined) { 129 throw new Error('Unknown shape ' + shape); 130 } 131 132 _.each(group, function(element) { 133 idx = element.idx; 134 scope.markers[idx].geometry = geometry; 135 scope.markers[idx].userData.shape = shape; 136 }); 137 scope.needsUpdate = true; 138 }; 139 140 return ShapeController; 141 }); 142