1 /** 2 * @fileOverview 3 * @author <a href="https://www.labkey.org">LabKey</a> (<a href="mailto:info@labkey.com">info@labkey.com</a>) 4 * @license Copyright (c) 2010-2018 LabKey Corporation 5 * <p/> 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * <p/> 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * <p/> 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * <p/> 18 */ 19 20 /** 21 * @namespace Visualization static class to programmatically retrieve visualization-ready data. Also allows 22 * persistence of various visualization types. 23 */ 24 LABKEY.Query.Visualization = new function() { 25 26 function formatParams(config) 27 { 28 var params = {}; 29 30 if (config.filters && config.filters.length) 31 { 32 params['filters'] = config.filters; 33 } 34 35 if (config.dateMeasures !== undefined) 36 params.dateMeasures = config.dateMeasures; 37 38 if (config.allColumns !== undefined) 39 params.allColumns = config.allColumns; 40 41 if (config.showHidden !== undefined) 42 params.showHidden = config.showHidden; 43 44 return params; 45 } 46 47 // Create a thin wrapper around the success callback capable of converting the persisted (string/JSON) visualization 48 // configuration into a native JavaScript object before handing it off to the caller: 49 function getVisualizatonConfigConverterCallback(successCallback, scope) 50 { 51 return function(data, response, options) 52 { 53 //ensure data is JSON before trying to decode 54 var json = null; 55 if (data && data.getResponseHeader && data.getResponseHeader('Content-Type') 56 && data.getResponseHeader('Content-Type').indexOf('application/json') >= 0) 57 { 58 json = LABKEY.Utils.decode(data.responseText); 59 if (json.visualizationConfig) 60 json.visualizationConfig = LABKEY.Utils.decode(json.visualizationConfig); 61 } 62 63 if(successCallback) 64 successCallback.call(scope || this, json, response, options); 65 } 66 } 67 68 /** 69 * This is used internally to automatically parse returned JSON and call another success function. It is based off of 70 * LABKEY.Utils.getCallbackWrapper, however, it will call the createMeasureFn function before calling the success function. 71 * @param createMeasureFn 72 * @param fn 73 * @param scope 74 */ 75 function getSuccessCallbackWrapper(createMeasureFn, fn, scope) 76 { 77 return function(response, options) 78 { 79 //ensure response is JSON before trying to decode 80 var json = null; 81 var measures = null; 82 if (response && response.getResponseHeader && response.getResponseHeader('Content-Type') 83 && response.getResponseHeader('Content-Type').indexOf('application/json') >= 0) 84 { 85 json = LABKEY.Utils.decode(response.responseText); 86 measures = createMeasureFn(json); 87 } 88 89 if(fn) 90 fn.call(scope || this, measures, response); 91 }; 92 } 93 94 /*-- public methods --*/ 95 /** @scope LABKEY.Query.Visualization */ 96 return { 97 getTypes : function(config) { 98 99 function createTypes(json) 100 { 101 if (json.types && json.types.length) 102 { 103 // for now just return the raw object array 104 return json.types; 105 } 106 return []; 107 } 108 109 110 LABKEY.Ajax.request( 111 { 112 url : LABKEY.ActionURL.buildURL("visualization", "getVisualizationTypes"), 113 method : 'GET', 114 success: getSuccessCallbackWrapper(createTypes, LABKEY.Utils.getOnSuccess(config), config.scope), 115 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 116 }); 117 }, 118 119 /** 120 * Returns the set of plottable measures found in the current container. 121 * @param config An object which contains the following configuration properties. 122 * @param {Array} config.filters An array of {@link LABKEY.Query.Visualization.Filter} objects. 123 * @param {Boolean} [config.dateMeasures] Indicates whether date measures should be returned instead of numeric measures. 124 * Defaults to false. 125 * @param {Function} config.success Function called when execution succeeds. Will be called with one argument: 126 * <ul><li><b>measures</b>: an array of {@link LABKEY.Query.Visualization.Measure} objects.</li> 127 * @param {Function} [config.failure] Function called when execution fails. Called with the following parameters: 128 * <ul> 129 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 130 * <li><b>response:</b> The XMLHttpResponse object</li> 131 * </ul> 132 */ 133 getMeasures : function(config) { 134 135 function createMeasures(json) 136 { 137 var measures = []; 138 if (json.measures && json.measures.length) 139 { 140 for (var i=0; i < json.measures.length; i++) 141 measures.push(new LABKEY.Query.Visualization.Measure(json.measures[i])); 142 } 143 return measures; 144 } 145 146 var params = formatParams(config); 147 148 LABKEY.Ajax.request( 149 { 150 url : config.endpoint || LABKEY.ActionURL.buildURL("visualization", "getMeasures"), 151 method : 'GET', 152 success: getSuccessCallbackWrapper(createMeasures, LABKEY.Utils.getOnSuccess(config), config.scope), 153 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 154 params : params 155 }); 156 }, 157 158 /** 159 * Returns a resultset suitable for visualization based on requested measures and dimensions. 160 * @param config An object which contains the following configuration properties. 161 * @param {Array} config.measures An array of objects with the following structure: 162 * <ul> 163 * <li><b>measure</b>: Generally an augmented {@link LABKEY.Query.Visualization.Measure}, but can be any object 164 * with the following properties: 165 * <ul> 166 * <li><b>schemaName</b>: The name of the schema containing the query that contains this measure.</li> 167 * <li><b>queryName</b>: The name of the query containing this measure.</li> 168 * <li><b>name</b>: The name of the column containing this measure.</li> 169 * <li><b>type</b>: The data type of this measure.</li> 170 * <li><b>isDemographic</b>: Boolean (default false). Indicates whether the measure is Demographic data.</li> 171 * <li><b>alias</b>: String. </li> 172 * <li><b>values</b>: Optional. If provided, results will be filtered to include only the provided values.</li> 173 * <li><b>allowNullResults</b>: Optional, defaults to true. If true, this measure will be joined to other measures via an outer join, which will allow results 174 * from other measures at timepoints not present for this measure (possibly resulting in null/blank values for this measure). If false, other measures will be inner joined 175 * to this measure, which will produce a dataset without null values for this measure, but which may not include all data from joined measures.</li> 176 * <li><b>aggregate</b>: See {@link LABKEY.Query.Visualization.Aggregate}. Required if a 'dimension' property is specified, ignored otherwise. Indicates 177 * what data should be returned if pivoting by dimension results in multiple underlying values 178 * per series data point.</li> 179 * </ul> 180 * </li> 181 * <li><b>dateOptions</b>: Optional if this measure's axis.timeAxis property is true, ignored otherwise. Has the following child properties. 182 * Either zeroDateCol or ZeroDayVisitTag may be specified, but not both. 183 * <ul> 184 * <li><b>dateCol</b>: A measure object (with properties for name, queryName, and 185 * schemaName) of type date specifying the measure date.</li> 186 * <li><b>zeroDateCol</b>: A measure object (with properties for name, queryName, and 187 * schemaName) of type date specifiying the zero date, used to align data points in terms of days, weeks, or months.</li> 188 * <li><b>zeroDayVisitTag</b>: String. A VisitTag that will be used to find the ParticipantVisit used to align data points. </li> 189 * <li><b>interval</b>: See {@link LABKEY.Query.Visualization.Interval}. The type of interval that should be 190 * calculated between the measure date and the zero date (if zeroDateCol is specified) 191 * or zero day (if zeroDayVisitTag is specified).</li> 192 * <li><b>useProtocolDay</b>: Boolean (default true). If true, zeroDayVisitTag uses ParticipantVisit.ProtocolDay to calculate offsets; 193 * if false ParticipantVisit.Day is used.</li> 194 * </ul> 195 * </li> 196 * <li><b>time</b>: 197 * String: "date" indicates this measure is date-based. "time" indicates it is time-based. 198 * </li> 199 * <li><b>dimension</b>: Used to pivot a resultset into multiple series. Generally an augmented 200 * {@link LABKEY.Query.Visualization.Dimension}, but can be any object with the following properties: 201 * <ul> 202 * <li><b>name</b>: The name of this dimension.</li> 203 * <li><b>schemaName</b>: The name of the schema containing the query that contains this dimension.</li> 204 * <li><b>queryName</b>: The name of the query containing this dimension.</li> 205 * <li><b>type</b>: The data type of this dimension.</li> 206 * <li><b>values</b>: Optional. If provided, results will be filtered to include only the named series.</li> 207 * </ul> 208 * </li> 209 * </ul> 210 * @param {Array} [config.sorts] Generally an array of augmented {@link LABKEY.Query.Visualization.Dimension} or {@link LABKEY.Query.Visualization.Measure} 211 * objects, but can be an array of any objects with the following properties: 212 * <ul> 213 * <li><b>name</b>: The name of this dimension.</li> 214 * <li><b>schemaName</b>: The name of the schema containing the query that contains this dimension.</li> 215 * <li><b>queryName</b>: The name of the query containing this dimension.</li> 216 * <li><b>values</b>: Optional. If provided, results will be filtered to include only the specified values.</li> 217 * </ul> 218 * @param {Boolean} [config.metaDataOnly] Default false. If true, response will no include the actual data rows, just metadata. 219 * @param {Boolean} [config.joinToFirst] Default false. If true, all measures will be joined to the first measure in the array instead of to the previous measure. 220 221 * @param {Function} config.success Function called when execution succeeds. Will be called with three arguments: 222 * <ul> 223 * <li><b>data</b>: the parsed response data ({@link LABKEY.Query.SelectRowsResults})</li> 224 * <li><b>request</b>: the XMLHttpRequest object</li> 225 * <li><b>options</b>: a request options object ({@link LABKEY.Query.SelectRowsOptions})</li> 226 * </ul> 227 * @param {Function} [config.failure] Function called when execution fails. Called with the following parameters: 228 * <ul> 229 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 230 * <li><b>response:</b> The XMLHttpResponse object</li> 231 * </ul> 232 */ 233 getData : function(config) { 234 235 var params = { 236 measures : [], 237 sorts : config.sorts, 238 239 // @deprecated -- created for issue 11627 240 // The filterUrl and filterQuery are used in tandem to apply a filter from a URL. Use the filterArray 241 // option on each measure to apply filters. 242 filterQuery: config.filterQuery, // e.g. 'study.Lab Results' 243 filterUrl: config.filterUrl, // e.g. '/labkey/study/StudyFolder/dataset.view?Dataset.Column%7Egt=value' 244 245 limit : config.limit, 246 groupBys: config.groupBys, 247 metaDataOnly: config.metaDataOnly, 248 249 // specify that all source queries should join back to the first measure 250 joinToFirst: config.joinToFirst === true 251 }; 252 253 // clone measures 254 var measure, filters, m, f, asURL, fa; 255 for (m=0; m < config.measures.length; m++) 256 { 257 var c = config.measures[m]; 258 259 measure = { 260 measure: c.measure, 261 time: c.time 262 }; 263 264 if (c.dimension) 265 { 266 measure.dimension = c.dimension; 267 } 268 269 if (c.dateOptions) 270 { 271 measure.dateOptions = c.dateOptions; 272 } 273 274 if (c.filterArray) 275 { 276 measure.filterArray = c.filterArray; 277 278 // assume it is an array of LABKEY.Filter instances, convert each filter to it's URL parameter equivalent 279 filters = []; 280 for (f=0; f < measure.filterArray.length; f++) 281 { 282 fa = measure.filterArray[f]; 283 if (fa && fa.getURLParameterName) 284 { 285 asURL = encodeURIComponent(fa.getURLParameterName()) + "=" + encodeURIComponent(fa.getURLParameterValue()); 286 filters.push(asURL); 287 } 288 } 289 measure['filterArray'] = filters; 290 } 291 292 params.measures.push(measure); 293 } 294 295 // issue 21418: support for parameterized queries 296 var urlParams = {}; 297 if (config.parameters) 298 { 299 for (var propName in config.parameters) 300 { 301 if (config.parameters.hasOwnProperty(propName)) 302 urlParams['visualization.param.' + propName] = config.parameters[propName]; 303 } 304 } 305 306 var endpoint = config.endpoint || LABKEY.ActionURL.buildURL("visualization", "getData", config.containerPath); 307 endpoint += '?' + LABKEY.ActionURL.queryString(urlParams); 308 309 LABKEY.Ajax.request( 310 { 311 url : endpoint, 312 method : 'POST', 313 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope, false), 314 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 315 jsonData : params, 316 headers : { 317 'Content-Type' : 'application/json' 318 } 319 }); 320 }, 321 322 /** 323 * Saves a visualization for future use. Saved visualizations appear in the study 'views' webpart. If the 324 * visualization is scoped to a specific query, it will also appear in the views menu for that query. 325 * @param config An object which contains the following configuration properties. 326 * @param {String} config.name The name this visualization should be saved under. 327 * @param {String} config.type The type of visualization being saved. Should be an instance of {@link LABKEY.Query.Visualization.Type}. 328 * @param {Object} config.visualizationConfig An arbitrarily complex JavaScript object that contains all information required to 329 * recreate the report. 330 * @param {Boolean} [config.replace] Whether this 'save' call should replace an existing report with the same name. 331 * If false, the call to 'save' will fail if another report with the same name exists. 332 * @param {String} [config.description] A description of the saved report. 333 * @param {String} [config.shared] Boolean indicating whether this report is viewable by all users with read 334 * permissions to the visualization's folder. If false, only the creating user can see the visualization. Defaults to true. 335 * @param {Boolean} [config.thumbnailType] String indicating whether a thumbnail should be auto-generated ('AUTO'), no thumbnail 336 * should be saved ('NONE'), or the existing custom thumbnail should be kept ('CUSTOM') 337 * @param {Boolean} [config.iconType] String indicating whether a icon should be auto-generated ('AUTO'), no icon 338 * should be saved ('NONE'), or the existing custom icon should be kept ('CUSTOM') 339 * @param {String} [config.svg] String svg to be used to generate a thumbnail 340 * @param {String} [config.schemaName] Optional, but required if config.queryName is provided. Allows the visualization to 341 * be scoped to a particular query. If scoped, this visualization will appear in the 'views' menu for that query. 342 * @param {String} [config.queryName] Optional, but required if config.schemaName is provided. Allows the visualization to 343 * be scoped to a particular query. If scoped, this visualization will appear in the 'views' menu for that query. 344 * @param {Function} config.success Function called when execution succeeds. Will be called with one arguments: 345 * <ul> 346 * <li><b>result</b>: an object with two properties: 347 * <ul> 348 * <li><b>name</b>: the name of the saved visualization</li> 349 * <li><b>visualizationId</b>: a unique integer identifier for this saved visualization</li> 350 * </ul> 351 * <li><b>request</b>: the XMLHttpRequest object</li> 352 * <li><b>options</b>: a request options object</li> 353 * </ul> 354 * @param {Function} [config.failure] Function called when execution fails. Called with the following parameters: 355 * <ul> 356 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 357 * <li><b>response:</b> The XMLHttpResponse object</li> 358 * </ul> 359 */ 360 save : function(config) 361 { 362 var params = { 363 name : config.name, 364 description : config.description, 365 json : LABKEY.Utils.encode(config.visualizationConfig), 366 replace: config.replace, 367 shared: config.shared, 368 thumbnailType: config.thumbnailType, 369 iconType: config.iconType, 370 svg : config.svg, 371 type : config.type, 372 schemaName: config.schemaName, 373 queryName: config.queryName 374 }; 375 376 LABKEY.Ajax.request( 377 { 378 url : LABKEY.ActionURL.buildURL("visualization", "saveVisualization"), 379 method : 'POST', 380 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope, false), 381 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 382 jsonData : params, 383 headers : { 384 'Content-Type' : 'application/json' 385 } 386 }); 387 }, 388 389 /** 390 * Retrieves a saved visualization. See {@link LABKEY.Query.Visualization.save}. 391 * @param config An object which contains the following configuration properties. 392 * @param {String} config.name The name this visualization to be retrieved. 393 * @param {String} [config.schemaName] Optional, but required if config.queryName is provided. Limits the search for 394 * the visualization to a specific schema and query. Note that visualization names are unique within a container 395 * (regardless of schema and query), so these additional optional parameters are only useful in a small number of circumstances. 396 * @param {String} [config.queryName] Optional, but required if config.schemaName is provided. Limits the search for 397 * the visualization to a specific schema and query. Note that visualization names are unique within a container 398 * (regardless of schema and query), so these additional optional parameters are only useful in a small number of circumstances. 399 * @param {Function} config.success Function called when execution succeeds. Will be called with one arguments: 400 * <ul> 401 * <li><b>result</b>: an object with two properties: 402 * <ul> 403 * <li><b>name</b>: The name of the saved visualization</li> 404 * <li><b>description</b>: The description of the saved visualization</li> 405 * <li><b>type</b>: The visualization type</li> 406 * <li><b>schemaName</b>: The schema to which this visualization has been scoped, if any</li> 407 * <li><b>queryName</b>: The query to which this visualization has been scoped, if any</li> 408 * <li><b>visualizationConfig</b>: The configuration object provided to {@link LABKEY.Query.Visualization.save}</li> 409 * </ul> 410 * </li> 411 * <li><b>request</b>: the XMLHttpRequest object</li> 412 * <li><b>options</b>: a request options object</li> 413 * </ul> 414 * @param {Function} [config.failure] Function called when execution fails. Called with the following parameters: 415 * <ul> 416 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 417 * <li><b>response:</b> The XMLHttpResponse object</li> 418 * </ul> 419 */ 420 get : function(config) 421 { 422 var params = { 423 reportId: config.reportId, 424 name : config.name, 425 schemaName: config.schemaName, 426 queryName: config.queryName 427 }; 428 429 // Get the standard callback function (last in the success callback chain): 430 var successCallback = LABKEY.Utils.getOnSuccess(config); 431 432 // wrap the callback to convert the visualizationConfig property from a JSON string into a native javascript object: 433 successCallback = getVisualizatonConfigConverterCallback(successCallback, config.scope); 434 435 LABKEY.Ajax.request( 436 { 437 url : LABKEY.ActionURL.buildURL("visualization", "getVisualization"), 438 method : 'POST', 439 initialConfig: config, 440 success: successCallback, 441 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 442 jsonData : params, 443 headers : { 444 'Content-Type' : 'application/json' 445 } 446 }); 447 }, 448 449 /** 450 * Retrieves a saved visualization based on identifying parameters found on the current URL. Method returns true or false, 451 * depending on whether the URL contains a saved visualization identifier. If true, the success or failure callback 452 * function will be called just as with {@link LABKEY.Query.Visualization.get}. If false, no callbacks will be called. 453 * This method allows callers to use a single method to retrieve saved visualizations, regardless of how they are identified on the URL. 454 * @param config An object which contains the following configuration properties. 455 * @param {Function} config.success Function called when the saved visualization was successfully retrieved. See {@link LABKEY.Query.Visualization.get} for details. 456 * @param {Function} [config.failure] Function called when the saved visualization could not be retrieved. See {@link LABKEY.Query.Visualization.get} for details. 457 * @return Boolean indicating whether the current URL includes parameters that identify a saved visualization. 458 */ 459 getFromUrl : function(config) 460 { 461 var params = config || {}; 462 463 params.success = LABKEY.Utils.getOnSuccess(config); 464 params.failure = LABKEY.Utils.getOnFailure(config); 465 466 var urlParams = LABKEY.ActionURL.getParameters(); 467 var valid = false; 468 if (params.reportId) 469 { 470 valid = true; 471 } 472 else 473 { 474 if (urlParams.name) 475 { 476 params.name = urlParams.name; 477 params.schemaName = urlParams.schemaName; 478 params.queryName = urlParams.queryName; 479 valid = true; 480 } 481 } 482 483 if (valid) 484 LABKEY.Query.Visualization.get(params); 485 return valid; 486 }, 487 488 getDataFilterFromURL : function() 489 { 490 var urlParams = LABKEY.ActionURL.getParameters(); 491 return urlParams['filterUrl']; 492 } 493 }; 494 }; 495 496 /** 497 * @deprecated Use {@link LABKEY.Query.Visualization} 498 */ 499 LABKEY.Visualization = LABKEY.Query.Visualization; 500 501 /** 502 * @namespace Visualization Measures are plottable data elements (columns). They may be of numeric or date types. 503 */ 504 LABKEY.Query.Visualization.Measure = function(config) { 505 506 LABKEY.Utils.apply(this, config); 507 }; 508 509 /** 510 * Returns the name of the query associated with this measure. 511 */ 512 LABKEY.Query.Visualization.Measure.prototype.getQueryName = function() { 513 return this.queryName; 514 }; 515 /** 516 * Returns the name of the schema associated with this measure. 517 */ 518 LABKEY.Query.Visualization.Measure.prototype.getSchemaName = function() { 519 return this.schemaName; 520 }; 521 /** 522 * Returns whether this measure is part of a user-defined query (versus a built-in/system-provided query). 523 */ 524 LABKEY.Query.Visualization.Measure.prototype.isUserDefined = function() { 525 return this.isUserDefined; 526 }; 527 /** 528 * Returns the column name of this measure. 529 */ 530 LABKEY.Query.Visualization.Measure.prototype.getName = function() { 531 return this.name; 532 }; 533 /** 534 * Returns the label of this measure. 535 */ 536 LABKEY.Query.Visualization.Measure.prototype.getLabel = function() { 537 return this.label; 538 }; 539 /** 540 * Returns the data types of this measure. 541 */ 542 LABKEY.Query.Visualization.Measure.prototype.getType = function() { 543 return this.type; 544 }; 545 /** 546 * Returns a description of this measure. 547 */ 548 LABKEY.Query.Visualization.Measure.prototype.getDescription = function() { 549 return this.description; 550 }; 551 /** 552 * Returns the set of available {@link LABKEY.Query.Visualization.Dimension} objects for this measure. 553 * @param config An object which contains the following configuration properties. 554 * @param config.includeDemographics {Boolean} Applies only to measures from study datasets. 555 * Indicates whether dimensions from demographic datasets should be included 556 * in the returned set. If false, only dimensions from the measure's query will be returned. 557 * @param {Function} config.success Function called when execution succeeds. Will be called with one argument: 558 <ul> 559 <li><b>values</b>: an array of unique dimension values</li> 560 </ul> 561 * @param {Function} [config.failure] Function called when execution fails. Called with the following parameters: 562 * <ul> 563 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 564 * <li><b>response:</b> The XMLHttpResponse object</li> 565 * </ul> 566 */ 567 LABKEY.Query.Visualization.Measure.prototype.getDimensions = function(config) { 568 569 var params = {queryName: this.queryName, schemaName: this.schemaName}; 570 571 if (config.includeDemographics) 572 params['includeDemographics'] = config.includeDemographics; 573 574 function createDimensions(json) 575 { 576 var dimensions = []; 577 if (json.dimensions && json.dimensions.length) 578 { 579 for (var i=0; i < json.dimensions.length; i++) 580 dimensions.push(new LABKEY.Query.Visualization.Dimension(json.dimensions[i])); 581 } 582 return dimensions; 583 } 584 585 LABKEY.Ajax.request( 586 { 587 url : LABKEY.ActionURL.buildURL("visualization", "getDimensions"), 588 method : 'GET', 589 params : params, 590 success: getSuccessCallbackWrapper(createDimensions, LABKEY.Utils.getOnSuccess(config), config.scope), 591 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 592 }); 593 }; 594 595 /** 596 * @deprecated Use {@link LABKEY.Query.Visualization.Measure} 597 */ 598 LABKEY.Visualization.Measure = LABKEY.Query.Visualization.Measure; 599 600 /** 601 * @namespace Visualization Dimensions are data elements (columns) on which {@link LABKEY.Query.Visualization.Measure} objects 602 * can be pivoted or transformed. For example, the 'Analyte Name' dimension may be used to pivit a single 'Result' measure 603 * into one series per Analyte. 604 */ 605 LABKEY.Query.Visualization.Dimension = function(config) { 606 LABKEY.Utils.apply(this, config); 607 }; 608 /** 609 * Returns the name of the query associated with this dimension. 610 */ 611 LABKEY.Query.Visualization.Dimension.getQueryName = function() { 612 return this.queryName; 613 }; 614 /** 615 * Returns the name of the schema assocated with this dimension. 616 */ 617 LABKEY.Query.Visualization.Dimension.getSchemaName = function() { 618 return this.schemaName; 619 }; 620 621 /** 622 * Returns whether this dimension is part of a user-defined query (versus a built-in/system-provided query). 623 */ 624 LABKEY.Query.Visualization.Dimension.isUserDefined = function() { 625 return this.isUserDefined; 626 }; 627 628 /** 629 * Returns the column name of this dimension. 630 */ 631 LABKEY.Query.Visualization.Dimension.getName = function() { 632 return this.name; 633 }; 634 635 /** 636 * Returns the label of this dimension. 637 */ 638 LABKEY.Query.Visualization.Dimension.getLabel = function() { 639 return this.label; 640 }; 641 642 /** 643 * Returns the data types of this dimension. 644 */ 645 LABKEY.Query.Visualization.Dimension.getType = function() { 646 return this.type; 647 }; 648 649 /** 650 * Returns a description of this dimension. 651 */ 652 LABKEY.Query.Visualization.Dimension.getDescription = function() { 653 return this.description; 654 }; 655 656 /** 657 * Returns the set of available unique values for this dimension. 658 * @param config An object which contains the following configuration properties. 659 * @param {Function} config.success Function called when execution succeeds. Will be called with one argument: 660 <ul> 661 <li><b>values</b>: an array of unique dimension values</li> 662 </ul> 663 * @param {Function} [config.failure] Function called when execution fails. Called with the following parameters: 664 * <ul> 665 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 666 * <li><b>response:</b> The XMLHttpResponse object</li> 667 * </ul> 668 */ 669 LABKEY.Query.Visualization.Dimension.getValues = function(config) { 670 671 var params = {queryName: this.queryName, schemaName: this.schemaName, name: this.name}; 672 function createValues(json) 673 { 674 if (json.success && json.values) 675 return json.values; 676 return []; 677 } 678 679 LABKEY.Ajax.request( 680 { 681 url : LABKEY.ActionURL.buildURL("visualization", "getDimensionValues"), 682 method : 'GET', 683 params : params, 684 success: getSuccessCallbackWrapper(createValues, LABKEY.Utils.getOnSuccess(config), config.scope), 685 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 686 }); 687 }; 688 689 /** 690 * @deprecated Use {@link LABKEY.Query.Visualization.Dimension} 691 */ 692 LABKEY.Visualization.Dimension = LABKEY.Query.Visualization.Dimension; 693 694 /** 695 * @namespace Visualization Helper class to allow filtering of the measures returned by the 696 * {@link LABKEY.Query.Visualization.getMeasures} method. 697 */ 698 LABKEY.Query.Visualization.Filter = new function() 699 { 700 function getURLParameterValue(config) 701 { 702 var params = [config.schemaName]; 703 704 if (config.queryName) 705 params.push(config.queryName); 706 else 707 params.push('~'); 708 709 if (config.queryType) 710 params.push(config.queryType); 711 712 return params.join('|'); 713 } 714 715 /** @scope LABKEY.Query.Visualization.Filter */ 716 return { 717 /** 718 * @namespace Visualization Possible query types for measure filters. See {@link LABKEY.Query.Visualization.Filter}. 719 */ 720 QueryType : { 721 /** Return only queries that are built-in to the server */ 722 BUILT_IN : 'builtIn', 723 /** Return only queries that are custom (user defined) */ 724 CUSTOM : 'custom', 725 /** Return only datasets */ 726 DATASETS : 'datasets', 727 /** Return all queries (both built-in and custom) */ 728 ALL : 'all' 729 }, 730 731 /** 732 * Creates a new filter object for use in {@link LABKEY.Query.Visualization.getMeasures}. 733 * @param config An object which contains the following configuration properties. 734 * @param {String} config.schemaName Required. Only measures from the specified schema will be returned. 735 * @param {String} [config.queryName] If specified, only measures from the specified query will be returned. 736 * @param {Object} [config.queryType] If specified, only measures from the specified query types will be returned 737 * Valid values for queryType are: {@link LABKEY.Query.Visualization.Filter.QueryType}.ALL, {@link LABKEY.Query.Visualization.Filter.QueryType}.BUILT_IN, 738 * and {@link LABKEY.Query.Visualization.Filter.QueryType}.CUSTOM. By default, all queries will be returned. 739 */ 740 create : function(config) 741 { 742 if (!config.schemaName) 743 throw new Error("Coding Error!", "You must supply a value for schemaName in your configuration object!"); 744 else 745 return getURLParameterValue(config); 746 } 747 }; 748 }; 749 750 /** 751 * @deprecated Use {@link LABKEY.Query.Visualization.Filter} 752 */ 753 LABKEY.Visualization.Filter = LABKEY.Query.Visualization.Filter; 754 755 /** 756 * @namespace Visualization Possible aggregates when pivoting a resultset by a dimension. See {@link LABKEY.Query.Visualization.getData}. 757 */ 758 LABKEY.Query.Visualization.Aggregate = { 759 /** Calculates a sum/total. */ 760 SUM: "SUM", 761 /** Calculates an average. */ 762 AVG: "AVG", 763 /** Returns the total number of data points. */ 764 COUNT: "COUNT", 765 /** Returns the minimum value. */ 766 MIN: "MIN", 767 /** Returns the maximum value. */ 768 MAX: "MAX" 769 }; 770 771 /** 772 * @deprecated Use {@link LABKEY.Query.Visualization.Aggregate} 773 */ 774 LABKEY.Visualization.Aggregate = LABKEY.Query.Visualization.Aggregate; 775 776 /** 777 * @namespace Visualization Possible intervals for aligning series in time plots. See {@link LABKEY.Query.Visualization.getData}. 778 */ 779 LABKEY.Query.Visualization.Interval = { 780 /** Align by the number of days since the zero date. */ 781 DAY : "DAY", 782 /** Align by the number of weeks since the zero date. */ 783 WEEK : "WEEK", 784 /** Align by the number of months since the zero date. */ 785 MONTH : "MONTH", 786 /** Align by the number of years since the zero date. */ 787 YEAR: "YEAR" 788 }; 789 790 /** 791 * @deprecated Use {@link LABKEY.Query.Visualization.Interval} 792 */ 793 LABKEY.Visualization.Interval = LABKEY.Query.Visualization.Interval; 794 795 /** 796 * @namespace Visualization A predefined set of visualization types, for use in the config.type property in the 797 * {@link LABKEY.Query.Visualization.save} method. 798 */ 799 LABKEY.Query.Visualization.Type = { 800 /** 801 * Plots data over time, aligning different series based on configurable start dates. 802 */ 803 TimeChart : 'ReportService.TimeChartReport', 804 /** 805 * Plot types that are not study specific (i.e. Bar, Box, Pie, and Scatter). 806 */ 807 GenericChart : 'ReportService.GenericChartReport' 808 }; 809 810 /** 811 * @deprecated Use {@link LABKEY.Query.Visualization.Type} 812 */ 813 LABKEY.Visualization.Type = LABKEY.Query.Visualization.Type; 814