1 /* 2 * Copyright (c) 2012-2016 LabKey Corporation 3 * 4 * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 5 */ 6 7 if(!LABKEY.vis.Geom){ 8 /** 9 * @namespace The Geom namespace. Used for all geoms, such as {@link LABKEY.vis.Geom.Point}, 10 * {@link LABKEY.vis.Geom.Path}, etc. 11 */ 12 LABKEY.vis.Geom = {}; 13 } 14 15 /** 16 * @class The base XY geom. Extended by all geoms that will be plotted on a grid using a Cartesian [X,Y] coordinate system. 17 * This is a base class meant to be used internally only. 18 */ 19 LABKEY.vis.Geom.XY = function(){ 20 this.type = "XY"; 21 this.xAes = null; 22 this.yAes = null; 23 this.typeSubtypeAes = null; 24 this.parentNameAes = null; 25 this.childNameAes = null; 26 this.xScale = null; 27 this.yScale = null; 28 this.colorAes = null; 29 this.colorScale = null; 30 return this; 31 }; 32 LABKEY.vis.Geom.XY.prototype.initAesthetics = function(scales, layerAes, parentAes, layerName, index){ 33 this.layerName = layerName; 34 this.index = index; 35 36 if(layerAes.x){ 37 this.xAes = layerAes.x; 38 this.xScale = scales.x; 39 } else if(layerAes.xTop){ 40 this.xAes = layerAes.xTop; 41 this.xScale = scales.xTop; 42 } else if(parentAes.x){ 43 this.xAes = parentAes.x; 44 this.xScale = scales.x; 45 } else if(parentAes.xTop){ 46 this.xAes = parentAes.xTop; 47 this.xScale = scales.xTop; 48 } 49 50 if (parentAes.xSub && scales.xSub) { 51 this.xSubAes = parentAes.xSub; 52 this.xSubScale = scales.xSub; 53 } 54 55 if(!this.xAes){ 56 console.error('x aesthetic is required for ' + this.type + ' geom to render.'); 57 return false; 58 } 59 60 if(layerAes.yLeft){ 61 this.yAes = layerAes.yLeft; 62 this.yScale = scales.yLeft; 63 } else if(layerAes.yRight){ 64 this.yAes = layerAes.yRight; 65 this.yScale = scales.yRight; 66 } else if(parentAes.yLeft){ 67 this.yAes = parentAes.yLeft; 68 this.yScale = scales.yLeft; 69 } else if(parentAes.yRight){ 70 this.yAes = parentAes.yRight; 71 this.yScale = scales.yRight; 72 } 73 74 this.colorAes = layerAes.color ? layerAes.color : parentAes.color; 75 this.colorScale = scales.color ? scales.color : null; 76 77 if(!this.yAes){ 78 console.error('y aesthetic is required for ' + this.type + ' geom to render.'); 79 return false; 80 } 81 82 if (parentAes.typeSubtype) { 83 this.typeSubtypeAes = parentAes.typeSubtype; 84 } 85 86 if (parentAes.parentName) { 87 this.parentNameAes = parentAes.parentName; 88 } 89 90 if (parentAes.childName) { 91 this.childNameAes = parentAes.childName; 92 } 93 94 return true; 95 }; 96 97 LABKEY.vis.Geom.XY.prototype.getVal = function(scale, map, row, isY){ 98 // Takes a row, returns the scaled y value. 99 var value = map.getValue(row); 100 101 if(!LABKEY.vis.isValid(value)){ 102 if(this.plotNullPoints){ 103 return isY ? scale(scale.domain()[0]) + 5 : scale(scale.domain()[0]) - 5; 104 } else { 105 return null; 106 } 107 } else { 108 return scale(value); 109 } 110 }; 111 112 LABKEY.vis.Geom.XY.prototype.getXSub = function(row) { 113 //Takes a row, returns the scaled x subcategory value. 114 return this.getVal(this.xSubScale.scale, this.xSubAes, row, false); 115 }; 116 117 LABKEY.vis.Geom.XY.prototype.getX = function(row){ 118 // Takes a row, returns the scaled x value. 119 return this.getVal(this.xScale.scale, this.xAes, row, false); 120 }; 121 122 LABKEY.vis.Geom.XY.prototype.getY = function(row){ 123 // Takes a row, returns the scaled y value. 124 return this.getVal(this.yScale.scale, this.yAes, row, true); 125 }; 126 127 LABKEY.vis.Geom.XY.prototype.getTypeSubtype = function(row){ 128 // Takes a row, returns the scaled y value. 129 return this.getVal(this.yScale.scale, this.typeSubtypeAes, row, true); 130 }; 131 132 LABKEY.vis.Geom.XY.prototype.getParentY = function(row){ 133 // Takes a row, returns the scaled parent name value. 134 return this.getVal(this.yScale.scale, this.parentNameAes, row, true); 135 }; 136 137 /** 138 * @class The Point geom, used to generate points of data on a plot such as points on a line or points in a scatter plot. 139 * This geom supports the use of size, color, shape, hoverText, and pointClickFn aesthetics from the 140 * {@link LABKEY.vis.Layer} and/or {@link LABKEY.vis.Plot} objects. 141 * @param {Object} config An object with the following properties: 142 * @param {String} [config.color] (Optional) String used to determine the color of all points. Defaults to black (#000000). 143 * @param {Number} [config.size] (Optional) Number used to determine the size of all points. Defaults to 5. 144 * @param {Number} [config.opacity] (Optional) Number between 0 and 1, used to determine the opacity of all points. Useful if 145 * there are overlapping points in the data. Defaults to 1. 146 * @param {Boolean} [config.plotNullPoints] (Optional) Used to toggle whether or not a row of data with the value of null will be 147 * plotted. If true null or undefined values will be plotted just outside the axis with data. For example if a 148 * row of data looks like {x: 50, y: null} the point would appear at 50 on the x-axis, and just below the x axis. 149 * If both x and y values are null the point will be drawn to the bottom left of the origin. Defaults to false. 150 * @param {String} [config.position] (Optional) String with possible value "jitter". If config.position is "jitter" and the 151 * x or y scale is discrete it will be moved just before or after the position on the grid by a random amount. 152 * Useful if there is overlapping data. Defaults to undefined. 153 */ 154 LABKEY.vis.Geom.Point = function(config){ 155 this.type = "Point"; 156 157 if(!config){ 158 config = {}; 159 } 160 this.color = ('color' in config && config.color != null && config.color != undefined) ? config.color : '#000000'; 161 this.size = ('size' in config && config.size != null && config.size != undefined) ? config.size : 5; 162 this.opacity = ('opacity' in config && config.opacity != null && config.opacity != undefined) ? config.opacity : 1; 163 this.plotNullPoints = ('plotNullPoints' in config && config.plotNullPoints != null && config.plotNullPoints != undefined) ? config.plotNullPoints : false; 164 this.position = ('position' in config && config.position != null && config.position != undefined) ? config.position : null; 165 166 return this; 167 }; 168 LABKEY.vis.Geom.Point.prototype = new LABKEY.vis.Geom.XY(); 169 LABKEY.vis.Geom.Point.prototype.render = function(renderer, grid, scales, data, layerAes, parentAes, name, index){ 170 if(!this.initAesthetics(scales, layerAes, parentAes, name, index)){ 171 return false; 172 } 173 174 this.shapeAes = layerAes.shape ? layerAes.shape : parentAes.shape; 175 this.shapeScale = scales.shape; 176 this.sizeAes = layerAes.size ? layerAes.size : parentAes.size; 177 this.sizeScale = scales.size; 178 this.hoverTextAes = layerAes.hoverText ? layerAes.hoverText : parentAes.hoverText; 179 this.pointClickFnAes = layerAes.pointClickFn ? layerAes.pointClickFn : parentAes.pointClickFn; 180 this.mouseOverFnAes = layerAes.mouseOverFn ? layerAes.mouseOverFn : parentAes.mouseOverFn; 181 this.mouseOutFnAes = layerAes.mouseOutFn ? layerAes.mouseOutFn : parentAes.mouseOutFn; 182 this.mouseUpFnAes = layerAes.mouseUpFn ? layerAes.mouseUpFn : parentAes.mouseUpFn; 183 184 renderer.renderPointGeom(data, this); 185 return true; 186 }; 187 188 /** 189 * @private 190 * @class The Bin geom, used to bin a set of data and generate a plot of binned points. Currently, under development and not for external use. Normally, this is used for scatter x-y based data. 191 * @param config 192 * @returns {LABKEY.vis.Geom.Bin} 193 * @constructor 194 */ 195 LABKEY.vis.Geom.Bin = function(config) { 196 this.type = "Bin"; 197 198 if (!config) { 199 config = {}; 200 } 201 202 this.shape = ('shape' in config && config.shape != null && config.shape != undefined) ? config.shape : 'hex'; 203 this.colorDomain = ('colorDomain' in config && config.colorDomain != null && config.colorDomain != undefined) ? config.colorDomain : undefined; 204 this.colorRange = ('colorRange' in config && config.colorRange != null && config.colorRange != undefined) ? config.colorRange : ["#e6e6e6", "#085D90"]; // lightish-gray -> labkey blue 205 this.size = ('size' in config && config.size != null && config.size != undefined) ? config.size : 5; 206 this.plotNullPoints = ('plotNullPoints' in config && config.plotNullPoints != null && config.plotNullPoints != undefined) ? config.plotNullPoints : false; 207 208 return this; 209 }; 210 LABKEY.vis.Geom.Bin.prototype = new LABKEY.vis.Geom.XY(); 211 LABKEY.vis.Geom.Bin.prototype.render = function(renderer, grid, scales, data, layerAes, parentAes, name, index){ 212 if(!this.initAesthetics(scales, layerAes, parentAes, name, index)){ 213 return false; 214 } 215 216 this.mouseOverFnAes = layerAes.mouseOverFn ? layerAes.mouseOverFn : parentAes.mouseOverFn; 217 this.mouseOutFnAes = layerAes.mouseOutFn ? layerAes.mouseOutFn : parentAes.mouseOutFn; 218 this.mouseUpFnAes = layerAes.mouseUpFn ? layerAes.mouseUpFn : parentAes.mouseUpFn; 219 220 renderer.renderBinGeom(data, this); 221 return true; 222 }; 223 224 /** 225 * @class The path geom, used to draw paths in a plot. In order to get multiple lines for a set of data the user must define an 226 * accessor with the name "group" in the config.aes object of the {LABKEY.vis.Plot} or {LABKEY.vis.Layer} object. For 227 * example if the data looked like {x: 12, y: 35, name: "Alan"} the config.aes.group accessor could be "Alan", or a 228 * function: function(row){return row.name}. Each unique name would get a separate line. The geom also supports color 229 * and size aesthetics from the {LABKEY.vis.Plot} and/or {LABKEY.vis.Layer} objects. 230 * @param {Object} config An object with the following properties: 231 * @param {String} [config.color] (Optional) String used to determine the color of all paths. Defaults to black (#000000). 232 * @param {Number} [config.size] (Optional) Number used to determine the size of all paths. Defaults to 3. 233 * @param {Number} [config.opacity] (Optional) Number between 0 and 1, used to determine the opacity of all paths. Useful 234 * @param {boolean} [config.dashed] (Optional) True for dashed path, false for solid path. Defaults to false. 235 * if there are many overlapping paths. Defaults to 1. 236 */ 237 LABKEY.vis.Geom.Path = function(config){ 238 this.type = "Path"; 239 240 if(!config){ 241 config = {}; 242 } 243 this.color = ('color' in config && config.color != null && config.color != undefined) ? config.color : '#000000'; 244 this.size = ('size' in config && config.size != null && config.size != undefined) ? config.size : 3; 245 this.opacity = ('opacity' in config && config.opacity != null && config.opacity != undefined) ? config.opacity : 1; 246 this.dashed = ('dashed' in config && config.dashed != null && config.dashed != undefined) ? config.dashed : false; 247 248 return this; 249 }; 250 LABKEY.vis.Geom.Path.prototype = new LABKEY.vis.Geom.XY(); 251 LABKEY.vis.Geom.Path.prototype.render = function(renderer, grid, scales, data, layerAes, parentAes, name, index){ 252 if(!this.initAesthetics(scales, layerAes, parentAes, name, index)){ 253 return false; 254 } 255 256 this.groupAes = layerAes.group ? layerAes.group : parentAes.group; 257 this.sizeAes = layerAes.size ? layerAes.size : parentAes.size; 258 this.pathColorAes = layerAes.pathColor ? layerAes.pathColor : parentAes.pathColor; 259 this.sizeScale = scales.size; 260 261 renderer.renderPathGeom(data, this); 262 return true; 263 }; 264 265 /** 266 * @class Control range geom. Generally used in conjunction with a {@link LABKEY.vis.Geom.Point} and/or {@link LABKEY.vis.Geom.Path} 267 * geom to show upper and lower control range for a given point. In order to work the user must specify an upper or lower accessor 268 * in the config.aes object of the {LABKEY.vis.Plot} or {LABKEY.vis.Layer} object. This Geom also supports the color 269 * aesthetic from the {LABKEY.vis.Plot} and/or {LABKEY.vis.Layer} objects. 270 * @param config An object with the following properties: 271 * @param {String} [config.color] (Optional) String used to determine the color of all paths. Defaults to black (#000000). 272 * @param {Number} [config.size] (Optional) Number used to determine the size of all paths. Defaults to 2. 273 * @param {Boolean} [config.dashed] (Optional) Whether or not to use dashed lines for path. Defaults to false. 274 * @param {Number} [config.width] (Optional) Number used to determine the length of all paths. Defaults to 6. 275 */ 276 LABKEY.vis.Geom.ControlRange = function(config){ 277 this.type = "ControlRange"; 278 279 if(!config){ 280 config = {}; 281 } 282 this.color = ('color' in config && config.color != null && config.color != undefined) ? config.color : '#000000'; 283 this.size = ('size' in config && config.size != null && config.size != undefined) ? config.size : 2; 284 this.dashed = ('dashed' in config && config.dashed != null && config.dashed != undefined) ? config.dashed : false; 285 this.width = ('width' in config && config.width != null && config.width != undefined) ? config.width : 6; 286 287 return this; 288 }; 289 LABKEY.vis.Geom.ControlRange.prototype = new LABKEY.vis.Geom.XY(); 290 LABKEY.vis.Geom.ControlRange.prototype.render = function(renderer, grid, scales, data, layerAes, parentAes, name, index){ 291 if(!this.initAesthetics(scales, layerAes, parentAes, name, index)){ 292 return false; 293 } 294 295 this.upperAes = layerAes.upper ? layerAes.upper : parentAes.upper; 296 this.lowerAes = layerAes.lower ? layerAes.lower : parentAes.lower; 297 298 if (!this.upperAes || !this.lowerAes) { 299 console.error("The upperAes or lowerAes aesthetic is required for the ControlRange geom."); 300 return false; 301 } 302 303 renderer.renderControlRangeGeom(data, this); 304 return true; 305 }; 306 307 /** 308 * @class Error bar geom. Generally used in conjunction with a {@link LABKEY.vis.Geom.Point} and/or {@link LABKEY.vis.Geom.Path} 309 * geom to show the known amount of error for a given point. In order to work the user must specify an error accessor 310 * in the config.aes object of the {LABKEY.vis.Plot} or {LABKEY.vis.Layer} object. This Geom also supports the color 311 * aesthetic from the {LABKEY.vis.Plot} and/or {LABKEY.vis.Layer} objects. 312 * @param config An object with the following properties: 313 * @param {String} [config.color] (Optional) String used to determine the color of all paths. Defaults to black (#000000). 314 * @param {Number} [config.size] (Optional) Number used to determine the size of all paths. Defaults to 2. 315 * @param {Boolean} [config.dashed] (Optional) Whether or not to use dashed lines for top and bottom bars. Defaults to false. 316 * @param {String} [config.altColor] (Optional) String used to determine the color of the vertical bar. Defaults to config.color. 317 */ 318 LABKEY.vis.Geom.ErrorBar = function(config){ 319 this.type = "ErrorBar"; 320 321 if(!config){ 322 config = {}; 323 } 324 this.color = ('color' in config && config.color != null && config.color != undefined) ? config.color : '#000000'; 325 this.size = ('size' in config && config.size != null && config.size != undefined) ? config.size : 2; 326 this.dashed = ('dashed' in config && config.dashed != null && config.dashed != undefined) ? config.dashed : false; 327 this.altColor = ('altColor' in config && config.altColor != null && config.altColor != undefined) ? config.altColor : null; 328 this.width = ('width' in config && config.width != null && config.width != undefined) ? config.width : 6; 329 330 return this; 331 }; 332 LABKEY.vis.Geom.ErrorBar.prototype = new LABKEY.vis.Geom.XY(); 333 LABKEY.vis.Geom.ErrorBar.prototype.render = function(renderer, grid, scales, data, layerAes, parentAes, name, index){ 334 if(!this.initAesthetics(scales, layerAes, parentAes, name, index)){ 335 return false; 336 } 337 338 this.errorAes = layerAes.error ? layerAes.error : parentAes.error; 339 340 if (!this.errorAes) { 341 console.error("The error aesthetic is required for the ErrorBar geom."); 342 return false; 343 } 344 345 renderer.renderErrorBarGeom(data, this); 346 return true; 347 }; 348 349 350 /** 351 * @class The Boxplot Geom, used to generate box plots for a given set of data. In order to get multiple box plots for a set of 352 * data with a continuous x-axis scale, the user must define an accessor with the name "group" in the config.aes object 353 * of the {LABKEY.vis.Plot} or {LABKEY.vis.Layer} object. For example if the data looked like {x: 12, y: 35, name: "Alan"} 354 * the config.aes.group accessor could be "Alan", or a function: function(row){return row.name}. Each unique name would 355 * get a separate box plot. If aes.group is not present one boxplot will be generated for all of the data. This geom 356 * also supports the outlierColor, outlierShape, hoverText, outlierHoverText, and pointClickFn aesthetics from the 357 * {LABKEY.vis.Plot} and/or {LABKEY.vis.Layer} objects. 358 * 359 * Boxplots are drawn as follows: 360 * <ul> 361 * <li>The top line of the box is the first quartile (Q1)</li> 362 * <li>The middle like is the second quartile (Q2, aka median)</li> 363 * <li>The bottom line is the third quartile (Q3)</li> 364 * <li>The whiskers extend to 3/2 times the inner quartile range (Q3 - Q1, aka IQR)</li> 365 * <li>All data points that are greater than 3/2 times the IQR are drawn as outliers</li> 366 * </ul> 367 * 368 * @param {Object} config An object with the following properties: 369 * @param {String} [config.color] (Optional) A string value used for the line colors in the box plot. Defaults to black 370 * (#000000) 371 * @param {String} [config.fill] (Optional) A string value used for the fill color in the box plot. Defaults to white 372 * (#ffffff) 373 * @param {Number} [config.lineWidth] (Optional) A used to set the width of the lines used in the box plot. Defaults to 1. 374 * @param {Number} [config.opacity] (Optional) A number between 0 and 1 used to set the opacity of the box plot. Defaults 375 * to 1. 376 * @param {String} [config.position] (Optional) A string used to determine how to position the outliers. Currently the 377 * only possible value is "jitter", which will move the points to the left or right of the center of the box plot by 378 * a random amount. Defaults to undefined. 379 * @param {Boolean} [config.showOutliers] (Optional) Used to toggle whether or not outliers are rendered. Defaults to true. 380 * @param {String} [config.outlierFill] (Optional) A string value used to set the fill color of the outliers. Defaults 381 * to black (#000000). 382 * @param {Number} [config.outlierOpacity] (Optional) A number between 0 and 1 used to set the opacity of the outliers. 383 * Defaults to 1. 384 * @param {Number} [config.outlierSize] (Optional) A used to set the size of outliers. Defaults to 3. 385 */ 386 LABKEY.vis.Geom.Boxplot = function(config){ 387 this.type = "Boxplot"; 388 389 if(!config){ 390 config = {}; 391 } 392 this.color = ('color' in config && config.color != null && config.color != undefined) ? config.color : '#000000'; // line color 393 this.fill = ('fill' in config && config.fill != null && config.fill != undefined) ? config.fill : '#ffffff'; // fill color 394 this.lineWidth = ('lineWidth' in config && config.lineWidth != null && config.lineWidth != undefined) ? config.lineWidth : 1; 395 this.opacity = ('opacity' in config && config.opacity != null && config.opacity != undefined) ? config.opacity : 1; 396 this.position = ('position' in config && config.position != null && config.position != undefined) ? config.position : null; 397 this.showOutliers = ('showOutliers' in config && config.showOutliers != null && config.showOutliers != undefined) ? config.showOutliers : true; 398 this.outlierFill = ('outlierFill' in config && config.outlierFill != null && config.outlierFill != undefined) ? config.outlierFill : '#000000'; 399 this.outlierOpacity = ('outlierOpacity' in config && config.outlierOpacity != null && config.outlierOpacity != undefined) ? config.outlierOpacity : .5; 400 this.outlierSize = ('outlierSize' in config && config.outlierSize != null && config.outlierSize != undefined) ? config.outlierSize : 3; 401 402 return this; 403 }; 404 LABKEY.vis.Geom.Boxplot.prototype = new LABKEY.vis.Geom.XY(); 405 LABKEY.vis.Geom.Boxplot.prototype.render = function(renderer, grid, scales, data, layerAes, parentAes, name, index){ 406 if(!this.initAesthetics(scales, layerAes, parentAes, name, index)){ 407 return false; 408 } 409 this.hoverTextAes = layerAes.hoverText ? layerAes.hoverText : parentAes.hoverText; 410 this.pointClickFnAes = layerAes.pointClickFn ? layerAes.pointClickFn : parentAes.pointClickFn; 411 this.groupAes = layerAes.group ? layerAes.group : parentAes.group; 412 this.outlierHoverTextAes = layerAes.outlierHoverText ? layerAes.outlierHoverText : parentAes.outlierHoverText; 413 this.outlierColorAes = layerAes.outlierColor ? layerAes.outlierColor : parentAes.outlierColor; 414 this.outlierShapeAes = layerAes.outlierShape ? layerAes.outlierShape : parentAes.outlierShape; 415 this.shapeScale = scales.shape; 416 417 renderer.renderBoxPlotGeom(data, this); 418 return true; 419 }; 420 421 LABKEY.vis.Geom.DataspaceBoxPlot = function(config){ 422 this.type = "DataspaceBoxplot"; 423 424 if(!config){ 425 config = {}; 426 } 427 428 this.color = ('color' in config && config.color != null && config.color != undefined) ? config.color : '#000000'; // line color 429 this.fill = ('fill' in config && config.fill != null && config.fill != undefined) ? config.fill : '#ffffff'; // fill color 430 this.lineWidth = ('lineWidth' in config && config.lineWidth != null && config.lineWidth != undefined) ? config.lineWidth : 1; 431 this.opacity = ('opacity' in config && config.opacity != null && config.opacity != undefined) ? config.opacity : 1; 432 this.showOutliers = ('showOutliers' in config && config.showOutliers != null && config.showOutliers != undefined) ? config.showOutliers : true; 433 this.outlierFill = ('outlierFill' in config && config.outlierFill != null && config.outlierFill != undefined) ? config.outlierFill : '#000000'; 434 this.pointOpacity = ('outlierOpacity' in config && config.outlierOpacity != null && config.outlierOpacity != undefined) ? config.outlierOpacity : .5; 435 this.pointSize = ('outlierSize' in config && config.outlierSize != null && config.outlierSize != undefined) ? config.outlierSize : 3; 436 this.size = ('binSize' in config && config.binSize != null && config.binSize != undefined) ? config.binSize : 5; 437 438 // binning geom specific 439 this.binRowLimit = ('binRowLimit' in config && config.binRowLimit != null && config.binRowLimit != undefined) ? config.binRowLimit : 5000; 440 this.colorRange = ('colorRange' in config && config.colorRange != null && config.colorRange != undefined) ? config.colorRange : ["#e6e6e6", "#000000"]; // lightish-gray -> black 441 442 return this; 443 }; 444 LABKEY.vis.Geom.DataspaceBoxPlot.prototype = new LABKEY.vis.Geom.XY(); 445 LABKEY.vis.Geom.DataspaceBoxPlot.prototype.render = function(renderer, grid, scales, data, layerAes, parentAes, name, index){ 446 if(!this.initAesthetics(scales, layerAes, parentAes, name, index)){ 447 return false; 448 } 449 450 this.hoverTextAes = layerAes.hoverText ? layerAes.hoverText : parentAes.hoverText; 451 this.groupAes = layerAes.group ? layerAes.group : parentAes.group; 452 this.pointClickFnAes = layerAes.pointClickFn ? layerAes.pointClickFn : parentAes.pointClickFn; 453 this.pointHoverTextAes = layerAes.pointHoverText ? layerAes.pointHoverText : parentAes.pointHoverText; 454 this.shapeAes = layerAes.shape ? layerAes.shape : parentAes.shape; 455 this.shapeScale = scales.shape; 456 this.sizeAes = layerAes.size ? layerAes.size : parentAes.size; 457 this.sizeScale = scales.size; 458 this.mouseOverFnAes = layerAes.mouseOverFn ? layerAes.mouseOverFn : parentAes.mouseOverFn; 459 this.mouseOutFnAes = layerAes.mouseOutFn ? layerAes.mouseOutFn : parentAes.mouseOutFn; 460 this.mouseUpFnAes = layerAes.mouseUpFn ? layerAes.mouseUpFn : parentAes.mouseUpFn; 461 this.boxMouseOverFnAes = layerAes.boxMouseOverFn ? layerAes.boxMouseOverFn : parentAes.boxMouseOverFn; 462 this.boxMouseOutFnAes = layerAes.boxMouseOutFn ? layerAes.boxMouseOutFn : parentAes.boxMouseOutFn; 463 this.boxMouseUpFnAes = layerAes.boxMouseUpFn ? layerAes.boxMouseUpFn : parentAes.boxMouseUpFn; 464 465 renderer.renderDataspaceBoxPlotGeom(data, this); 466 return true; 467 }; 468 469 /** 470 * @class Bar plot geom, used to generate bar plots for a given set of data. 471 * @param config An object with the following properties: 472 * @param {Function} [config.clickFn] (Optional) A click function 473 * @param {Function} [config.hoverFn] (Optional) A hover function 474 * @param {String} [config.color] (Optional) A string value used for the line colors in the bar plot. Defaults to black (#000000) 475 * @param {String} [config.fill] (Optional) A string value used for the fill color in the bar plot. Defaults to white (#ffffff) 476 * @param {Number} [config.lineWidth] (Optional) A used to set the width of the lines used in the bar plot. Defaults to 1. 477 * @param {Number} [config.opacity] (Optional) A number between 0 and 1 used to set the opacity of the bar plot. Defaults to 1. 478 * @param {Boolean} [config.showCumulativeTotals] (Optional) True to show cumulative totals next to the individual bars. 479 * @param {String} [config.colorTotal] (Optional) A string value used for the line colors in the cumulative bar plot. Defaults to black (#000000) 480 * @param {String} [config.fillTotal] (Optional) A string value used for the fill color in the cumulative bar plot. Defaults to black (#000000) 481 * @param {Number} [config.lineWidthTotal] (Optional) A used to set the width of the lines used in the cumulative bar plot. Defaults to 1. 482 * @param {Number} [config.opacityTotal] (Optional) A number between 0 and 1 used to set the opacity of the cumulative bar plot. Defaults to 1. 483 * @param {Boolean} [config.showValues] (Optional) True to show the bar height values as text above the rendered bar. 484 */ 485 LABKEY.vis.Geom.BarPlot = function(config){ 486 this.type = "Barplot"; 487 488 if(!config){ 489 config = {}; 490 } 491 this.clickFn = ('clickFn' in config && config.clickFn != null && config.clickFn != undefined) ? config.clickFn : undefined; 492 this.hoverFn = ('hoverFn' in config && config.hoverFn != null && config.hoverFn != undefined) ? config.hoverFn : undefined; 493 this.color = ('color' in config && config.color != null && config.color != undefined) ? config.color : '#000000'; 494 this.colorTotal = ('colorTotal' in config && config.colorTotal != null && config.colorTotal != undefined) ? config.colorTotal : '#000000'; 495 this.fill = ('fill' in config && config.fill != null && config.fill != undefined) ? config.fill : '#c0c0c0'; 496 this.fillTotal = ('fillTotal' in config && config.fillTotal != null && config.fillTotal != undefined) ? config.fillTotal : '#000000'; 497 this.lineWidth = ('lineWidth' in config && config.lineWidth != null && config.lineWidth != undefined) ? config.lineWidth : 1; 498 this.lineWidthTotal = ('lineWidthTotal' in config && config.lineWidthTotal != null && config.lineWidthTotal != undefined) ? config.lineWidthTotal : 1; 499 this.opacity = ('opacity' in config && config.opacity != null && config.opacity != undefined) ? config.opacity : 1; 500 this.opacityTotal = ('opacityTotal' in config && config.opacityTotal != null && config.opacityTotal != undefined) ? config.opacityTotal : 1; 501 this.showCumulativeTotals = ('showCumulativeTotals' in config && config.showCumulativeTotals != null && config.showCumulativeTotals != undefined) ? config.showCumulativeTotals : false; 502 this.showValues = ('showValues' in config && config.showValues != null && config.showValues != undefined) ? config.showValues : false; 503 504 return this; 505 }; 506 LABKEY.vis.Geom.BarPlot.prototype = new LABKEY.vis.Geom.XY(); 507 LABKEY.vis.Geom.BarPlot.prototype.render = function(renderer, grid, scales, data, layerAes, parentAes, name, index){ 508 509 if(!this.initAesthetics(scales, layerAes, parentAes, name, index)){ 510 return false; 511 } 512 513 renderer.renderBarPlotGeom(data, this); 514 return true; 515 }; 516 517 /** 518 * @class Timeline plot geom, used to generate a timeline plot for a given set of data. 519 * @param config An object with the following properties: 520 * @param {String} [config.size] (Optional) A numeric value used for the timeline event icon size in pixels. Defaults to 10. 521 * @param {String} [config.color] (Optional) A string value used for the timeline event icon border color. Defaults to black (#000000). 522 * @param {String} [config.fill] (Optional) A string value used for the timeline event icon fill color. Defaults to black (#000000). 523 * @param {String} [config.dateKey] (Optional) property name of the date value that data objects contain. Used to create 524 * tooltips on hover. Defaults to 'date'. 525 * @param {Boolean} [config.isCollapsed] (Optional) If true, the timeline collapses subtypes into their parent rows. Defaults to True. 526 * @param {Number} [config.rowHeight] (Optional) The height of individual rows in pixels. For expanded timelines, row height 527 * will resize to 75% of this value. Defaults to 40px. 528 * @param {Object} [config.highlight] (Optional) Special Data object containing information to highlight a specific row 529 * in the timeline. Must have the same shape & properties as all other input data. 530 * @param {String} [config.highlightRowColor] (Optional) Hex color to specifiy what color the highlighted row will be if, 531 * found in the data. Defaults to #74B0C4. 532 * @param {String} [config.activeEventKey] (Optional) Name of property that is paired with @param config.activeEventIdentifier to 533 * identify a unique event in the data. 534 * @param {String} [config.activeEventIdentifier] (Optional) Name of value that is paired with @param config.activeEventKey 535 * to identify a unique event in the data. 536 * @param {String} [config.activeEventStrokeColor] (Optional) Hex color to specifiy what color the active event rect's 537 * stroke will be, if found in the data. Defaults to red. 538 * @param {Object} [config.emphasisEvents] (Optional) Object containing key:[value] pairs whose keys are property names 539 * of a data object and whose value is an array of possible values that should have a highlight line drawn 540 * on the chart when found. Example: {'type': ['death', 'Withdrawal']} 541 * @param {String} [config.tickColor] (Optional) Hex color to specifiy the color of Axis ticks. Defaults to #DDDDDD. 542 * @param {String} [config.emphasisTickColor] (Optional) Hex color to specify the color of emphasis event ticks, if 543 * found in the data. Defaults to #1a969d. 544 * @param {String} [config.timeUnit] (Optional) Unit of time to use when calculating how far an event's date is from 545 * the start date. Default is years. Valid string values include minutes, hours, days, years, and decades. 546 * @param {Number} [config.eventIconSize] (Optional) Size of event square width/height dimensions. 547 * @param {String} [config.eventIconColor] (Optional) Hex color of event square stroke. 548 * @param {String} [config.eventIconFill] (Optional) Hex color of event square inner fill. Defaults to black (#000000). 549 * @param {Number} [config.eventIconOpacity] (Optional) Float between 0 - 1 (inclusive) to specify how transparent the 550 * fill of event icons will be. Defaults to 1. 551 * @param {Array} [config.rowColorDomain] (Optional) Array of length 2 containing string Hex values for the two 552 * alternating colors of timeline row rectangles. Defaults to ['#f2f2f2', '#ffffff']. 553 */ 554 LABKEY.vis.Geom.TimelinePlot = function(config){ 555 this.type = "TimelinePlot"; 556 557 if(!config){ 558 config = {}; 559 } 560 561 this.dateKey = ('dateKey' in config && config.dateKey != null && config.dateKey != undefined) ? config.dateKey : 'date'; 562 this.timeUnit = ('timeUnit' in config && config.timeUnit != null && config.timeUnit != undefined) ? config.timeUnit : 'years'; 563 this.highlight = ('highlight' in config && config.highlight != null && config.highlight != undefined) ? config.highlight : null; 564 this.highlightRowColor = ('highlightRowColor' in config && config.highlightRowColor != null && config.highlightRowColor != undefined) ? config.highlightRowColor : '#74B0C4'; 565 this.activeEventKey = ('activeEventKey' in config && config.activeEventKey != null && config.activeEventKey != undefined) ? config.activeEventKey : null; 566 this.activeEventIdentifier = ('activeEventIdentifier' in config && config.activeEventIdentifier != null && config.activeEventIdentifier != undefined) ? config.activeEventIdentifier : null; 567 this.activeEventStrokeColor = ('activeEventStrokeColor' in config && config.activeEventStrokeColor != null && config.activeEventStrokeColor != undefined) ? config.activeEventStrokeColor : 'red'; 568 this.marginLeft = ('marginLeft' in config && config.marginLeft != null && config.marginLeft != undefined) ? config.marginLeft : 200; 569 this.parentName = ('parentName' in config && config.parentName != null && config.parentName != undefined) ? config.parentName : 'type'; 570 this.childName = ('childName' in config && config.childName != null && config.childName != undefined) ? config.childName : 'subtype'; 571 this.width = ('width' in config && config.width != null && config.width != undefined) ? config.width : 900; 572 this.height = ('height' in config && config.height != null && config.height != undefined) ? config.height : 500; 573 this.rowHeight = ('rowHeight' in config && config.rowHeight != null && config.rowHeight != undefined) ? config.rowHeight : 40; 574 this.eventIconSize = ('eventIconSize' in config && config.eventIconSize != null && config.eventIconSize != undefined) ? config.eventIconSize : 10; 575 this.eventIconColor = ('eventIconColor' in config && config.eventIconColor != null && config.eventIconColor != undefined) ? config.eventIconColor : '#000000'; 576 this.eventIconFill = ('eventIconFill' in config && config.eventIconFill != null && config.eventIconFill != undefined) ? config.eventIconFill : '#000000'; 577 this.rowColorDomain = ('rowColorDomain' in config && config.rowColorDomain != null && config.rowColorDomain != undefined) ? config.rowColorDomain : ['#f2f2f2', '#ffffff']; 578 this.eventIconOpacity = ('eventIconOpacity' in config && config.eventIconOpacity != null && config.eventIconOpacity != undefined) ? config.eventIconOpacity : 1; 579 this.emphasisEvents = ('emphasisEvents' in config && config.emphasisEvents != null && config.emphasisEvents != undefined) ? config.emphasisEvents : null; 580 this.tickColor = ('tickColor' in config && config.tickColor != null && config.tickColor != undefined) ? config.tickColor : '#DDDDDD'; 581 this.emphasisTickColor = ('emphasisTickColor' in config && config.emphasisTickColor != null && config.emphasisTickColor != undefined) ? config.emphasisTickColor : '#1a969d'; 582 this.isCollapsed = ('isCollapsed' in config && config.isCollapsed != null && config.isCollapsed != undefined) ? config.isCollapsed : true; 583 return this; 584 }; 585 LABKEY.vis.Geom.TimelinePlot.prototype = new LABKEY.vis.Geom.XY(); 586 LABKEY.vis.Geom.TimelinePlot.prototype.render = function(renderer, grid, scales, data, layerAes, parentAes, name, index){ 587 588 if(!this.initAesthetics(scales, layerAes, parentAes, name, index)){ 589 return false; 590 } 591 592 this.mouseOverRowFnAes = layerAes.mouseOverRowFn ? layerAes.mouseOverRowFn : parentAes.mouseOverRowFn; 593 this.mouseOutRowFnAes = layerAes.mouseOutRowFn ? layerAes.mouseOutRowFn : parentAes.mouseOutRowFn; 594 this.rowClickFnAes = layerAes.rowClickFn ? layerAes.rowClickFn : parentAes.rowClickFn; 595 this.eventClickFnAes = layerAes.eventIconClickFn ? layerAes.eventIconClickFn : parentAes.eventIconClickFn; 596 this.mouseOverFnAes = layerAes.mouseOverEventIconFn ? layerAes.mouseOverEventIconFn : parentAes.mouseOverEventIconFn; 597 this.mouseOutFnAes = layerAes.mouseOutEventIconFn ? layerAes.mouseOutEventIconFn : parentAes.mouseOutEventIconFn; 598 599 if (renderer.renderTimelinePlotGeom) 600 { 601 renderer.renderTimelinePlotGeom(data, this); 602 return true; 603 } 604 else 605 { 606 return false; 607 } 608 };