PageRenderTime 75ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/config/plugins/visualizations/charts/static/library/datasets.js

https://bitbucket.org/remy_d1/galaxy-central-manageapi
JavaScript | 384 lines | 238 code | 60 blank | 86 comment | 53 complexity | 4ffa347441933569926cdff3a36d5e00 MD5 | raw file
Possible License(s): CC-BY-3.0
  1. // dependencies
  2. define(['utils/utils'], function(Utils) {
  3. /**
  4. * This class handles, formats and caches datasets.
  5. */
  6. return Backbone.Collection.extend(
  7. {
  8. // list of datasets
  9. list: {},
  10. // cache for datablocks
  11. cache: {},
  12. // initialize
  13. initialize: function(app, options){
  14. // link app
  15. this.app = app;
  16. // configure options
  17. this.options = Utils.merge(options, this.optionsDefault);
  18. },
  19. // request handler
  20. request: function(request_dictionary) {
  21. if (request_dictionary.groups) {
  22. this._get_blocks(request_dictionary);
  23. } else {
  24. this._get_dataset(request_dictionary.id, request_dictionary.success, request_dictionary.error)
  25. }
  26. },
  27. // multiple request handler
  28. _get_blocks: function(request_dictionary) {
  29. // get callbacks
  30. var success = request_dictionary.success;
  31. var progress = request_dictionary.progress;
  32. // query block size
  33. var query_size = this.app.config.get('query_limit');
  34. // set range
  35. var query_start = request_dictionary.start || 0;
  36. var query_end = query_start + request_dictionary.query_limit || query_start + this.app.config.get('query_limit');
  37. // get query limit
  38. var query_range = Math.abs(query_end - query_start);
  39. if (query_range <= 0) {
  40. console.debug('FAILED - Datasets::request() - Invalid query range.');
  41. return;
  42. }
  43. // get number of required queries
  44. var query_number = Math.ceil(query_range / query_size) || 1;
  45. // get query dictionary template
  46. var query_dictionary_template = $.extend(true, {}, request_dictionary);
  47. // reset query counter
  48. var query_counter = 0;
  49. // fetch blocks
  50. var self = this;
  51. function fetch_blocks (query) {
  52. self._get(query, function() {
  53. // copy values from query into request_dictionary
  54. var done = false;
  55. for (var group_index in request_dictionary.groups) {
  56. // get source/destination
  57. destination_group = request_dictionary.groups[group_index];
  58. source_group = query.groups[group_index];
  59. // check if value fields already exist
  60. if (!destination_group.values) {
  61. destination_group.values = [];
  62. }
  63. // concat values
  64. destination_group.values = destination_group.values.concat(source_group.values);
  65. // validate
  66. if (source_group.values.length == 0) {
  67. done = true;
  68. break;
  69. }
  70. }
  71. // check if for remaining queries
  72. if (++query_counter < query_number && !done) {
  73. // report progress
  74. if (progress) {
  75. progress(parseInt((query_counter / query_number) * 100));
  76. }
  77. // next query
  78. var start = query.start + query_size;
  79. query = $.extend(true, query_dictionary_template, {start: start});
  80. fetch_blocks(query);
  81. } else {
  82. success();
  83. }
  84. });
  85. };
  86. // prepare query
  87. var query = $.extend(true, query_dictionary_template, {start: query_start});
  88. // get dataset meta data
  89. this._get_dataset(request_dictionary.id, function() {
  90. fetch_blocks(query);
  91. });
  92. },
  93. // get dataset
  94. _get_dataset: function(id, success, error) {
  95. // check if dataset is available from cache
  96. var dataset = this.list[id];
  97. if (dataset) {
  98. success(dataset);
  99. return;
  100. }
  101. // request dataset
  102. var self = this;
  103. Utils.request({
  104. type : 'GET',
  105. url : config.root + 'api/datasets/' + id,
  106. success : function(dataset) {
  107. switch (dataset.state) {
  108. case 'error':
  109. if (error) {
  110. error(dataset);
  111. }
  112. break;
  113. default:
  114. self.list[id] = dataset;
  115. success(dataset);
  116. }
  117. }
  118. });
  119. },
  120. // get block id
  121. _block_id: function (options, column) {
  122. return options.id + '_' + options.start + '_' + options.start + this.app.config.get('query_limit') + '_' + column;
  123. },
  124. // fills request dictionary with data from cache/response
  125. _get: function(request_dictionary, callback) {
  126. // set start
  127. request_dictionary.start = request_dictionary.start || 0;
  128. // get column indices
  129. var column_list = [];
  130. var column_map = {};
  131. var column_count = 0;
  132. for (var i in request_dictionary.groups) {
  133. var group = request_dictionary.groups[i];
  134. for (var key in group.columns) {
  135. // identify column
  136. var column = group.columns[key].index;
  137. // check if column is in cache
  138. var block_id = this._block_id(request_dictionary, column);
  139. if (this.cache[block_id] || column === 'auto' || column === 'zero') {
  140. continue;
  141. }
  142. // add to dictionary
  143. if (!column_map[column] && column !== undefined) {
  144. column_map[column] = column_count;
  145. column_list.push(column);
  146. column_count++;
  147. }
  148. }
  149. }
  150. // check length of blocks not available in cache
  151. if (column_list.length == 0) {
  152. // fill dictionary from cache
  153. this._fill_from_cache(request_dictionary);
  154. // parse requested data
  155. callback(request_dictionary);
  156. // return
  157. return;
  158. }
  159. // configure dataset request dictionary
  160. var dataset_request = {
  161. dataset_id : request_dictionary.id,
  162. start : request_dictionary.start,
  163. columns : column_list
  164. }
  165. // fetch data
  166. var self = this;
  167. this._fetch(dataset_request, function(results) {
  168. // add results to cache
  169. for (var i in results) {
  170. var column = column_list[i];
  171. var block_id = self._block_id(request_dictionary, column);
  172. self.cache[block_id] = results[i];
  173. }
  174. // fill dictionary from cache
  175. self._fill_from_cache(request_dictionary);
  176. // trigger callback
  177. callback(request_dictionary);
  178. });
  179. },
  180. // convert
  181. _fill_from_cache: function(request_dictionary) {
  182. // identify start of request
  183. var start = request_dictionary.start;
  184. // log
  185. console.debug('Datasets::_fill_from_cache() - Filling request from cache at ' + start + '.');
  186. // identify end of request
  187. var limit = 0;
  188. for (var i in request_dictionary.groups) {
  189. var group = request_dictionary.groups[i];
  190. for (var key in group.columns) {
  191. var column = group.columns[key];
  192. var block_id = this._block_id(request_dictionary, column.index);
  193. var column_data = this.cache[block_id];
  194. if (column_data) {
  195. limit = Math.max(limit, column_data.length);
  196. }
  197. }
  198. }
  199. // check length
  200. if (limit == 0) {
  201. console.debug('Datasets::_fill_from_cache() - Reached data range limit.');
  202. }
  203. // initialize group values
  204. for (var i in request_dictionary.groups) {
  205. // get group
  206. var group = request_dictionary.groups[i];
  207. // reset group
  208. group.values = [];
  209. // add values
  210. for (var j = 0; j < limit; j++) {
  211. // add default x values
  212. group.values[j] = {
  213. x : parseInt(j) + start
  214. };
  215. }
  216. }
  217. // collect all data into the defined groups
  218. for (var i in request_dictionary.groups) {
  219. // get group
  220. var group = request_dictionary.groups[i];
  221. // fill value
  222. for (var key in group.columns) {
  223. // get column
  224. var column = group.columns[key];
  225. // check if auto block is requested
  226. switch (column.index) {
  227. case 'auto':
  228. for (var j = 0; j < limit; j++) {
  229. // get value dictionary
  230. var value = group.values[j];
  231. // add auto value
  232. value[key] = parseInt(j) + start;
  233. }
  234. break;
  235. case 'zero':
  236. for (var j = 0; j < limit; j++) {
  237. // get value dictionary
  238. var value = group.values[j];
  239. // add zero value
  240. value[key] = 0;
  241. }
  242. break;
  243. default:
  244. // get block
  245. var block_id = this._block_id(request_dictionary, column.index);
  246. var column_data = this.cache[block_id];
  247. // go through column
  248. for (var j = 0; j < limit; j++) {
  249. // get value dictionary
  250. var value = group.values[j];
  251. // get/fix value
  252. var v = column_data[j];
  253. if (isNaN(v) && !column.is_label) {
  254. v = 0;
  255. }
  256. // add to dict
  257. value[key] = v;
  258. }
  259. }
  260. }
  261. }
  262. },
  263. // fetch data columns into dataset object
  264. _fetch: function(dataset_request, callback) {
  265. // set offset
  266. var offset = dataset_request.start ? dataset_request.start : 0;
  267. // set limit
  268. var limit = this.app.config.get('query_limit');
  269. // check length
  270. var n_columns = 0;
  271. if (dataset_request.columns) {
  272. n_columns = dataset_request.columns.length;
  273. console.debug('Datasets::_fetch() - Fetching ' + n_columns + ' column(s) at ' + offset + '.');
  274. }
  275. if (n_columns == 0) {
  276. console.debug('Datasets::_fetch() - No columns requested');
  277. }
  278. // get column indices
  279. var column_string = '';
  280. for (var i in dataset_request.columns) {
  281. column_string += dataset_request.columns[i] + ',';
  282. }
  283. column_string = column_string.substring(0, column_string.length - 1);
  284. // make request
  285. var self = this;
  286. Utils.request({
  287. type : 'GET',
  288. url : config.root + 'api/datasets/' + dataset_request.dataset_id,
  289. data : {
  290. data_type : 'raw_data',
  291. provider : 'dataset-column',
  292. limit : limit,
  293. offset : offset,
  294. indeces : column_string
  295. },
  296. success : function(response) {
  297. // initialize result dictionary
  298. var result = new Array(n_columns);
  299. for (var i = 0; i < n_columns; i++) {
  300. result[i] = [];
  301. }
  302. // loop through rows
  303. for (var i in response.data) {
  304. // get row
  305. var row = response.data[i];
  306. // collect all data into the defined groups
  307. for (var j in row) {
  308. // get group
  309. var v = row[j];
  310. if (v !== undefined && v != 2147483647) {
  311. // add to result
  312. result[j].push(v);
  313. }
  314. }
  315. }
  316. // log
  317. console.debug('Datasets::_fetch() - Fetching complete.');
  318. // callback
  319. callback(result);
  320. }
  321. });
  322. }
  323. });
  324. });