PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

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

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